def normalize_map(raster, output_name): """ Normalize all raster map cells by subtracting the raster map's minimum and dividing by the range. Parameters ---------- raster : Name of input raster map output_name : Name of output raster map Returns ------- Examples -------- ... """ # grass.debug(_("Input to normalize: {name}".format(name=raster))) # grass.debug(_("Ouput: {name}".format(name=output_name))) finding = grass.find_file(name=raster, element="cell") if not finding["file"]: grass.fatal("Raster map {name} not found".format(name=raster)) # else: # grass.debug("Raster map {name} found".format(name=raster)) # univar_string = grass.read_command('r.univar', flags='g', map=raster) # univar_string = univar_string.replace('\n', '| ').replace('\r', '| ') # msg = "Univariate statistics: {us}".format(us=univar_string) minimum = grass.raster_info(raster)["min"] grass.debug(_("Minimum: {m}".format(m=minimum))) maximum = grass.raster_info(raster)["max"] grass.debug(_("Maximum: {m}".format(m=maximum))) if minimum is None or maximum is None: msg = "Minimum and maximum values of the <{raster}> map are 'None'. " msg += "The {raster} map may be empty " msg += "OR the MASK opacifies all non-NULL cells." grass.fatal(_(msg.format(raster=raster))) normalisation = "float(({raster} - {minimum}) / ({maximum} - {minimum}))" normalisation = normalisation.format(raster=raster, minimum=minimum, maximum=maximum) # Maybe this can go in the parent function? 'raster' names are too long! # msg = "Normalization expression: " # msg += normalisation # grass.verbose(_(msg)) normalisation_equation = EQUATION.format(result=output_name, expression=normalisation) grass.mapcalc(normalisation_equation, overwrite=True) get_univariate_statistics(output_name)
def test_tiling_schemes(tmp_path, width, height): """Check that different shapes of tiles work""" location = "test" gs.core._create_location_xy(tmp_path, location) # pylint: disable=protected-access with grass_setup.init(tmp_path / location): gs.run_command("g.region", s=0, n=50, w=0, e=50, res=1) surface = "surface" gs.run_command("r.surf.fractal", output=surface) def run_grid_module(): # modules/shortcuts calls get_commands which requires GISBASE. # pylint: disable=import-outside-toplevel from grass.pygrass.modules.grid import GridModule grid = GridModule( "r.slope.aspect", width=width, height=height, overlap=2, processes=max_processes(), elevation=surface, slope="slope", aspect="aspect", ) grid.run() run_in_subprocess(run_grid_module) info = gs.raster_info("slope") assert info["min"] > 0
def _import_file(self, filename, module, args): mapname = self._map_name(filename) gs.message(_("Processing <{}>...").format(mapname)) if module == "r.import": self._args["resolution_value"] = self._raster_resolution(filename) try: gs.run_command(module, input=filename, output=mapname, **self._args) if gs.raster_info(mapname)["datatype"] in ("FCELL", "DCELL"): gs.message("Rounding to integer after reprojection") gs.use_temp_region() gs.run_command("g.region", raster=mapname) gs.run_command( "r.mapcalc", quiet=True, expression="tmp_%s = round(%s)" % (mapname, mapname), ) gs.run_command( "g.rename", quiet=True, overwrite=True, raster="tmp_%s,%s" % (mapname, mapname), ) gs.del_temp_region() gs.raster_history(mapname) except CalledModuleError as e: pass # error already printed
def adjust_coordinates(points, real_elev): info = gscript.raster_info(real_elev) orig_width = info['east'] - info['west'] orig_height = info['north'] - info['south'] orig_ratio = orig_width / orig_height width = abs(points[0][0] - points[1][0]) height = abs(points[0][1] - points[1][1]) ratio = width / height minx = min(points[0][0], points[1][0]) miny = min(points[0][1], points[1][1]) if orig_ratio > ratio: new_height = height new_width = new_height * orig_ratio minx = minx - (new_width - width) / 2 else: new_width = width new_height = new_width / orig_ratio miny = miny - (new_height - height) / 2 maxx = minx + new_width maxy = miny + new_height return ((minx, miny), (maxx, maxy))
def run_geomorphons(real_elev, scanned_elev, env, **kwargs): analyses.geomorphon(scanned_elev, new="geomorphon", search=12, skip=4, flat=1, dist=0, env=env) # convert peaks to points gs.mapcalc("peaks = if(geomorphon == 2, 1, null())", env=env) gs.run_command("r.clump", input="peaks", output="clumped_peaks", env=env) gs.run_command( "r.volume", input="clumped_peaks", clump="clumped_peaks", centroids="peaks", errors="exit", env=env, ) # contours info = gs.raster_info(scanned_elev) interval = (info["max"] - info["min"]) / 20.0 gs.run_command( "r.contour", input=scanned_elev, output="contours", step=interval, flags="t", env=env, )
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 import_raster(filename, module, args): mapname = _map_name(filename) gs.message(_("Processing <{}>...").format(mapname)) if module == "r.import": kv = gs.parse_command("g.proj", flags="j") if kv["+proj"] == "longlat": args["resolution"] = "estimated" else: args["resolution"] = "value" args["resolution_value"] = _raster_resolution(filename) try: gs.run_command(module, input=filename, output=mapname, **args) if gs.raster_info(mapname)["datatype"] in ("FCELL", "DCELL"): gs.message("Rounding to integer after reprojection") gs.use_temp_region() gs.run_command("g.region", raster=mapname) gs.run_command( "r.mapcalc", quiet=True, expression="tmp_%s = round(%s)" % (mapname, mapname), ) gs.run_command( "g.rename", quiet=True, overwrite=True, raster="tmp_%s,%s" % (mapname, mapname), ) gs.del_temp_region() gs.raster_history(mapname) except CalledModuleError as e: pass # error already printed
def createConfFile(res, inpumap, home): # set the name of conf file name = "conf_diversity_" + str(res) confilename = os.path.join(home, name) # start the text for the conf file outputLine = ["SAMPLINGFRAME 0|0|1|1\n"] # return r.info about input file rinfo = grass.raster_info(inpumap) # calculate number of lines rows = (rinfo["north"] - rinfo["south"]) / rinfo["nsres"] # calculate number of columns columns = (rinfo["east"] - rinfo["west"]) / rinfo["ewres"] # value for row rV = int(res) / rows # value for column cV = int(res) / columns # append the text for the conf file outputLine.append("SAMPLEAREA -1|-1|" + str(rV) + "|" + str(cV) + "\n") outputLine.append("MOVINGWINDOW\n") # open configuration file fileConf = open(confilename, "w") # write file fileConf.writelines(outputLine) # close file fileConf.close()
def InitRasterOpts(self, rasterList, plottype): """Initialize or update raster dictionary for plotting""" rdict = {} # initialize a dictionary self.properties["raster"] = UserSettings.Get(group=self.plottype, key="raster") for r in rasterList: idx = rasterList.index(r) try: ret = grass.raster_info(r) except: continue # if r.info cannot parse map, skip it self.raster[r] = self.properties["raster"] # some default settings rdict[r] = {} # initialize sub-dictionaries for each raster in the list rdict[r]["units"] = "" if ret["units"] not in ("(none)", '"none"', "", None): rdict[r]["units"] = ret["units"] rdict[r]["plegend"] = r # use fully-qualified names # list of cell value,frequency pairs for plotting histogram rdict[r]["datalist"] = [] rdict[r]["pline"] = None rdict[r]["datatype"] = ret["datatype"] # # initialize with saved values # if self.properties["raster"]["pwidth"] is not None: rdict[r]["pwidth"] = self.properties["raster"]["pwidth"] else: rdict[r]["pwidth"] = 1 if ( self.properties["raster"]["pstyle"] is not None and self.properties["raster"]["pstyle"] != "" ): rdict[r]["pstyle"] = self.properties["raster"]["pstyle"] else: rdict[r]["pstyle"] = "solid" if idx < len(self.colorList): if idx == 0: # use saved color for first plot if self.properties["raster"]["pcolor"] is not None: rdict[r]["pcolor"] = self.properties["raster"]["pcolor"] else: rdict[r]["pcolor"] = self.colorDict[self.colorList[idx]] else: rdict[r]["pcolor"] = self.colorDict[self.colorList[idx]] else: r = randint(0, 255) b = randint(0, 255) g = randint(0, 255) rdict[r]["pcolor"] = (r, g, b, 255) return rdict
def controlPoints(inputmap): """ This function serve to return the coordinates of the photo's four vertex :param str inpumap: the input raster map's name """ # return r.info about input file rinfo = grass.raster_info(inputmap) nsres = rinfo['nsres'] ewres = rinfo['ewres'] # create a dictionary for Nord East NE = [rinfo['east'] - 2 * ewres, rinfo["north"] - 2 * nsres] # create a dictionary for Nord West NW = [rinfo['west'] + 2 * ewres, rinfo["north"] - 2 * nsres] # create a dictionary for Sud East SE = [rinfo['east'] - 2 * ewres, rinfo["south"] + 2 * nsres] # create a dictionary for Sud West SW = [rinfo['west'] + 2 * ewres, rinfo["south"] + 2 * nsres] ## create a dictionary for Nord Center #NC = {'x':rinfo['east']-(rinfo['east']-rinfo['west'])/2, 'y':rinfo["north"]-2*nsres} ## create a dictionary for Sud Center #SC = {'x':rinfo['east']-(rinfo['east']-rinfo['west'])/2,'y':rinfo["south"]+2*nsres} ## create a dictionary for West Center #WC = {'x':rinfo['west']+2*ewres, 'y':rinfo["north"] - (rinfo["north"] - rinfo["south"]) / 2 } ## create a dictionary for East Center #EC = {'x':rinfo['east']-2*ewres, 'y':rinfo["north"]- (rinfo["north"] - rinfo["south"]) / 2} # create a dictionary to return the four point retDict = {'NE': NE, 'NW': NW, 'SE': SE, 'SW': SW} # 'NC' : NC,'SC' : SC, # 'WC' : WC, 'EC' : EC} # return the dictionary return retDict
def main(): #create a list for parallel mapcalc modules and a mapcalc module to act as template mapcalc_list = [] mapcalc = Module("r.mapcalc", overwrite=True, run_=False) #get number of tiles in each row and col from arguments tile_rows = int(sys.argv[1]) tile_cols = int(sys.argv[2]) #Create que for parallel processes queue = ParallelModuleQueue(nprocs=sys.argv[3]) #Use temporary region that will be reset after execution of this script gscript.use_temp_region() #Input raster (can be grass raster dataset or externally linked dataset such as tiff vrt etc.) input="input_raster" #Read raster boundaries and resolution into numeric variables info = gscript.raster_info(input) no = float(info['north']) so = float(info['south']) we = float(info['west']) ea = float(info['east']) ro = int(info['rows']) co = int(info['cols']) ewr = int(info['ewres']) nsr = int(info['nsres']) #Start mapcalc module for each tile k = 0 for i in xrange(tile_rows): for j in xrange(tile_cols): #Set processing region to specific part of the raster (column+row) gscript.run_command('g.region', n=so+(i+1)*ro/tile_rows*nsr, s=so+i*ro/tile_rows*nsr, e=we+(1+j)*co/tile_cols*ewr, w=we+j*co/tile_cols*ewr, rows=ro/tile_rows, cols=co/tile_cols, nsres=nsr, ewres=ewr) #Create a copy of mapcalc template, give it mapcalc expression and put it into parallel que where it will be executed when a process becomes available. new_mapcalc = copy.deepcopy(mapcalc) mapcalc_list.append(new_mapcalc) m = new_mapcalc(expression="test_pygrass_%i = %s * (%i+1)"%(k,input, k)) queue.put(m) k+=1 #wait for all mapcalc modules to have finished execution queue.wait() #print mapcalc returncodes to check that everything went as expected for mapcalc in mapcalc_list: print(mapcalc.popen.returncode) #delete temporary region to restore the region that was in use at the start of the script gscript.del_temp_region()
def InitRasterOpts(self, rasterList, plottype): """!Initialize or update raster dictionary for plotting """ rdict = {} # initialize a dictionary self.properties['raster'] = UserSettings.Get(group = self.plottype, key = 'raster') for r in rasterList: idx = rasterList.index(r) try: ret = grass.raster_info(r) except: continue # if r.info cannot parse map, skip it self.raster[r] = self.properties['raster'] # some default settings rdict[r] = {} # initialize sub-dictionaries for each raster in the list rdict[r]['units'] = '' if ret['units'] not in ('(none)', '"none"', '', None): rdict[r]['units'] = ret['units'] rdict[r]['plegend'] = r.split('@')[0] rdict[r]['datalist'] = [] # list of cell value,frequency pairs for plotting rdict[r]['pline'] = None rdict[r]['datatype'] = ret['datatype'] # #initialize with saved values # if self.properties['raster']['pwidth'] != None: rdict[r]['pwidth'] = self.properties['raster']['pwidth'] else: rdict[r]['pwidth'] = 1 if self.properties['raster']['pstyle'] != None and \ self.properties['raster']['pstyle'] != '': rdict[r]['pstyle'] = self.properties['raster']['pstyle'] else: rdict[r]['pstyle'] = 'solid' if idx <= len(self.colorList): if idx == 0: # use saved color for first plot if self.properties['raster']['pcolor'] != None: rdict[r]['pcolor'] = self.properties['raster']['pcolor'] else: rdict[r]['pcolor'] = self.colorDict[self.colorList[idx]] else: rdict[r]['pcolor'] = self.colorDict[self.colorList[idx]] else: r = randint(0, 255) b = randint(0, 255) g = randint(0, 255) rdict[r]['pcolor'] = ((r,g,b,255)) return rdict
def main(): #create a list for parallel mapcalc modules and a mapcalc module to act as template mapcalc_list = [] mapcalc = Module("r.mapcalc", overwrite=True, run_=False) #get number of tiles in each row and col from arguments tile_rows = int(sys.argv[1]) tile_cols = int(sys.argv[2]) #Create que for parallel processes queue = ParallelModuleQueue(nprocs=sys.argv[3]) #Use temporary region that will be reset after execution of this script gscript.use_temp_region() input = "input_raster" #Read raster boundaries and resolution into numeric variables info = gscript.raster_info(input) no = float(info['north']) so = float(info['south']) we = float(info['west']) ea = float(info['east']) ro = int(info['rows']) co = int(info['cols']) ewr = int(info['ewres']) nsr = int(info['nsres']) #Start mapcalc module for each tile k = 0 for i in xrange(tile_rows): for j in xrange(tile_cols): #Set processing region to specific part of the raster (column+row) gscript.run_command('g.region', n=so + (i + 1) * ro / tile_rows * nsr, s=so + i * ro / tile_rows * nsr, e=we + (1 + j) * co / tile_cols * ewr, w=we + j * co / tile_cols * ewr, rows=ro / tile_rows, cols=co / tile_cols, nsres=nsr, ewres=ewr) #Create a copy of mapcalc template, give it mapcalc expression and put it into parallel que where it will be executed when a process becomes available. new_mapcalc = copy.deepcopy(mapcalc) mapcalc_list.append(new_mapcalc) m = new_mapcalc(expression="test_pygrass_%i = %s * (%i+1)" % (k, input, k)) queue.put(m) k += 1 #wait for all mapcalc modules to have finished execution queue.wait() #print mapcalc returncodes to check that everything went as expected for mapcalc in mapcalc_list: print(mapcalc.popen.returncode) #delete temporary region to restore the region that was in use at the start of the script gscript.del_temp_region()
def adjust_futures_colors(raster): import grass.script as gs new_raster = raster + '_' info = gs.raster_info(raster) color = '0 200:200:200\n1 255:100:50\n{m} 255:255:0\n100 180:255:160'.format(m=info['max']) gs.mapcalc('{nr} = if({r} == -1, 100, {r})'.format(nr=new_raster, r=raster)) gs.write_command('r.colors', map=new_raster, stdin=color, rules='-') return new_raster
def main(): input = options['input'] maskcats = options['maskcats'] remove = flags['r'] invert = flags['i'] if not remove and not input: grass.fatal(_("Required parameter <input> not set")) #check if input file exists if not grass.find_file(input)['file'] and not remove: grass.fatal(_("<%s> does not exist.") % input) if not 'MASKCATS' in grass.gisenv() and not remove: ## beware: next check is made with != , not with 'is', otherwise: #>>> grass.raster_info("basin_50K")['datatype'] is "CELL" #False # even if: #>>> "CELL" is "CELL" #True if grass.raster_info(input)['datatype'] != "CELL": grass.fatal(_("Raster map %s must be integer for maskcats parameter") % input) mapset = grass.gisenv()['MAPSET'] exists = bool(grass.find_file('MASK', element = 'cell', mapset = mapset)['file']) if remove: if exists: grass.run_command('g.remove', rast = 'MASK') grass.message(_("Raster MASK removed")) else: grass.fatal(_("No existing MASK to remove")) else: if exists: if not grass.overwrite(): grass.fatal(_("MASK already found in current mapset. Delete first or overwrite.")) else: grass.warning(_("MASK already exists and will be overwritten")) p = grass.feed_command('r.reclass', input = input, output = 'MASK', overwrite = True, rules = '-') p.stdin.write("%s = 1" % maskcats) p.stdin.close() p.wait() if invert: global tmp tmp = "r_mask_%d" % os.getpid() grass.run_command('g.rename', rast = ('MASK',tmp), quiet = True) grass.mapcalc("MASK=if(isnull($tmp),1,null())", tmp = tmp) grass.run_command('g.remove', rast = tmp, quiet = True) grass.message(_("Inverted MASK created.")) else: grass.message(_("MASK created.")) grass.message(_("All subsequent raster operations will be limited to MASK area. ") + "Removing or renaming raster file named MASK will " + "restore raster operations to normal")
def calib_run(scanned_elev, env, **kwargs): info = gs.raster_info(scanned_elev) interval = (info["max"] - info["min"]) / 20.0 gs.run_command( "r.contour", input=scanned_elev, output="contours", step=interval, flags="t", env=env, )
def Data_prep(Land_cover): ''' Function that extracts informations from the Land Cover : resolution and classes ''' info = gscript.raster_info(Land_cover) nsres = info.nsres ewres = info.ewres L = [] L = [cl for cl in gscript.parse_command('r.category', map=Land_cover)] return nsres, ewres, L
def main(): rast1 = '/home/vitale232/Google\ Drive/UNR/UNR-Thesis/Data/GIS-Data/DEM/n39w114/imgn39w114_1.img' rast2 = '/home/vitale232/Google\ Drive/UNR/UNR-Thesis/Data/GIS-Data/DEM/n39w115/imgn39w115_1.img' rast3 = '/home/vitale232/Google\ Drive/UNR/UNR-Thesis/Data/GIS-Data/DEM/n40w114/imgn40w114_1.img' rast4 = '/home/vitale232/Google\ Drive/UNR/UNR-Thesis/Data/GIS-Data/DEM/n40w115/imgn40w115_1.img' a = garray.array() a.read(rast1) print(grass.raster_info(rast1))
def create_end_points(env): info = gs.raster_info("scan") y1 = info["south"] + 2 * (info["north"] - info["south"]) / 10.0 y2 = info["south"] + 8 * (info["north"] - info["south"]) / 10.0 x1 = info["west"] + 2 * (info["east"] - info["west"]) / 10.0 x2 = info["west"] + 8 * (info["east"] - info["west"]) / 10.0 gs.write_command( "v.in.ascii", input="-", stdin="{x1}|{y1}\n{x2}|{y2}".format(x1=x1, x2=x2, y1=y1, y2=y2), output="trail_points", env=env, ) return ((x1, y1), (x2, y2))
def render_raster(self, name): """Reprojects raster to Pseudo-Mercator and saves PNG in working directory. Return PNG filename and bounding box of WGS84. param str name: name of raster """ # Find full name of raster file_info = gs.find_file(name, element="cell", env=self._src_env) full_name = file_info["fullname"] name = file_info["name"] mapset = file_info["mapset"] self._region_manager.set_region_from_raster(full_name) # Reproject raster into WGS84/epsg3857 location env_info = gs.gisenv(env=self._src_env) tgt_name = full_name.replace("@", "_") gs.run_command( "r.proj", input=full_name, output=tgt_name, mapset=mapset, location=env_info["LOCATION_NAME"], dbase=env_info["GISDBASE"], resolution=self._region_manager.resolution, env=self._psmerc_env, ) # Write raster to png file with Map raster_info = gs.raster_info(tgt_name, env=self._psmerc_env) filename = os.path.join(self._tmp_dir.name, f"{tgt_name}.png") img = Map( width=int(raster_info["cols"]), height=int(raster_info["rows"]), env=self._psmerc_env, filename=filename, use_region=True, ) img.run("d.rast", map=tgt_name) # Reproject bounds of raster for overlaying png # Bounds need to be in WGS84 old_bounds = get_region(self._src_env) from_proj = get_location_proj_string(env=self._src_env) to_proj = get_location_proj_string(env=self._wgs84_env) bounds = reproject_region(old_bounds, from_proj, to_proj) new_bounds = [ [bounds["north"], bounds["west"]], [bounds["south"], bounds["east"]], ] return filename, new_bounds
def run_slope(real_elev, scanned_elev, env, **kwargs): gs.run_command("r.slope.aspect", elevation=scanned_elev, slope="slope", env=env) info = gs.raster_info(scanned_elev) interval = (info["max"] - info["min"]) / 20.0 gs.run_command( "r.contour", input=scanned_elev, output="contours", step=interval, flags="t", env=env, )
def run_dem(real_elev, scanned_elev, blender_path, eventHandler, env, **kwargs): gscript.run_command('g.copy', raster=[scanned_elev, 'topo_saved'], env=env) info = gscript.raster_info(map=scanned_elev) env2 = get_environment(raster=scanned_elev, res=(info['nsres'] + info['ewres']) / 4) gscript.run_command('r.resamp.interp', input=scanned_elev, output=scanned_elev + '_hires', method='bilinear', env=env2) blender_export_DEM(raster=scanned_elev + '_hires', name='terrain', time_suffix=False, path=blender_path, env=env2)
def Data_prep(categorical_raster): ''' Function that extracts resolution and sorted list of classes of a categorical raster (e.g., a land cover or a land use map). ''' info = gscript.raster_info(categorical_raster) nsres = info.nsres ewres = info.ewres L = [] L = [ cl.split(" ")[0] for cl in gscript.parse_command('r.category', map=categorical_raster) ] for i, x in enumerate(L): #Make sure the format is UTF8 and not Unicode L[i] = x.encode('UTF8') L.sort(key=float) #Sort the raster categories in ascending. return nsres, ewres, L
def rg_nonhier_worker(parms, parameter_queue, result_queue): """Launch parallel processes for non-hierarchical segmentation""" try: for threshold, minsize in iter(parameter_queue.get, "STOP"): mapname = rg_non_hierarchical_seg(parms, threshold, minsize) mapinfo = gscript.raster_info(mapname) if mapinfo["max"] > mapinfo["min"]: variance_per_raster = [] autocor_per_raster = [] neighbordict = get_nb_matrix(mapname) for raster in parms["rasters"]: # there seems to be some trouble in ms windows with qualified # map names raster = raster.split("@")[0] var = get_variance(mapname, raster) variance_per_raster.append(var) autocor = get_autocorrelation( mapname, raster, neighbordict, parms["indicator"] ) autocor_per_raster.append(autocor) mean_lv = sum(variance_per_raster) / len(variance_per_raster) mean_autocor = sum(autocor_per_raster) / len(autocor_per_raster) result_queue.put([mapname, mean_lv, mean_autocor, threshold, minsize]) else: # If resulting map contains only one segment, then give high # value of variance and 0 for spatial autocorrelation in order # to give this map a low priority result_queue.put([mapname, 999999, 0, threshold, minsize]) except: exc_info = sys.exc_info() result_queue.put( [ "%s: %s_%f_%d failed with message:\n\n %s" % ( current_process().name, parms["region"], threshold, minsize, exc_info, ) ] ) return True
def _import_file(self, filename, module, args): mapname = self._map_name(filename) gs.message(_('Processing <{}>...').format(mapname)) if module == 'r.import': args['resolution_value'] = self._raster_resolution(filename) try: gs.run_command(module, input=filename, output=mapname, **args) if gs.raster_info(mapname)['datatype'] in ('FCELL', 'DCELL'): gs.message('Rounding to integer after reprojection') gs.use_temp_region() gs.run_command('g.region', raster=mapname) gs.run_command('r.mapcalc', quiet=True, expression='tmp_%s = round(%s)' % (mapname, mapname)) gs.run_command('g.rename', quiet=True, overwrite=True, raster='tmp_%s,%s' % (mapname, mapname)) gs.del_temp_region() gs.raster_history(mapname) except CalledModuleError as e: pass # error already printed
def show_interactively(raster, opacity=0.8): import grass.script as gs info = gs.raster_info(raster) raster = raster.split('@')[0] gs.mapcalc( '{r}_processed = if({r} == 0, null(), int({r}))'.format(r=raster)) gs.run_command('r.colors', map=raster + '_processed', raster=raster) gs.run_command('r.out.gdal', input=raster + '_processed', output=raster + '_spm.tif', type='Byte') gs.run_command('g.remove', type='raster', name=raster + '_processed', flags='f') subprocess.call([ 'gdalwarp', '-t_srs', 'EPSG:3857', raster + '_spm.tif', raster + '_merc.tif', '-overwrite' ]) subprocess.call([ 'gdal_translate', '-of', 'png', raster + '_merc.tif', raster + '_merc.png' ]) info = subprocess.check_output( ['gdalinfo', '-json', '-noct', '-nomd', raster + '_merc.png'], universal_newlines=True) coors = json.loads(info)['wgs84Extent']['coordinates'][0] lon = [pt[0] for pt in coors] lat = [pt[1] for pt in coors] minlat = min(lat) minlon = min(lon) maxlat = max(lat) maxlon = max(lon) m = folium.Map(location=[(maxlat + minlat) / 2, (maxlon + minlon) / 2]) img = folium.raster_layers.ImageOverlay( name=raster, image=raster + '_merc.png', bounds=[[minlat, minlon], [maxlat, maxlon]], opacity=opacity, interactive=True, cross_origin=False, ) img.add_to(m) folium.LayerControl().add_to(m) return m
def parse(raster, values): info = gs.raster_info(raster) if info["datatype"] != "CELL": gs.fatal(_("Input raster map must be of type CELL")) rules = [] vals = values.split(",") for val in vals: if "-" in val: a, b = val.split("-") if not a: a = info["min"] if not b: b = info["max"] for i in range(int(a), int(b) + 1): rules.append("{v} = {v}".format(v=i)) else: rules.append("{v} = {v}".format(v=val)) return rules
def _maskOrBlank(self, name): '''Check if name option is given, if yes make a mask, if not make a blank map out of the default value.''' # if given, then it must be a raster, if not just make blank argv = getattr(self, name, None) if argv: # make mask for DCELL and FCELL if not grass.raster_info(argv)['datatype'] == 'CELL': outname = '%s__mask'%name grass.mapcalc(exp=outname+'=isnull(%s)' % argv) self.floatmaps[outname] = self.__dict__[name] else: # CELL is just passed on outname = self.__dict__[name] else: # not given, make default blank map outname = '%s__default'%name grass.mapcalc(exp=outname+'=%s'%self.DEFAULTS[name]) return outname
def run_futures(scanned_elev, env, update, giface, **kwargs): analyses.match_scan(base='scan_saved', scan=scanned_elev, matched='matched', env=env) threshold = 180 params = list() gscript.mapcalc(exp="{change} = if({new} - {old} > {thres}, {new} - {old}, null())".format( change='change', thres=threshold, new='matched', old='scan_saved'), env=env) change_info = gscript.raster_info('change') if not math.isnan(change_info['min']): max_change = change_info['max'] gscript.mapcalc(exp="{change} = if(change, 1, null())".format( change='change_bin'), env=env) gscript.run_command('r.clump', input='change_bin', output='clump', env=env) gscript.run_command('r.stats.zonal', base='clump', cover='color_r', output='red_mean', method='average', env=env) gscript.run_command('r.stats.zonal', base='clump', cover='color_g', output='green_mean', method='average', env=env) gscript.mapcalc('stimulus = if(isnull(red_mean), 0, if(red_mean > green_mean, graph(change, 0,0, {}, 0.9), 0))'.format(max_change), env=env) gscript.mapcalc('constrain = if(isnull(green_mean), 1, if(green_mean > red_mean, graph(change, 0,1, {},0.1), 1))'.format(max_change), env=env) gscript.mapcalc('stimulus_flat = if(red_mean > green_mean, 1, null())', env=env) gscript.mapcalc('constrain_flat = if(green_mean > red_mean, 1, null())', env=env) # try: # gscript.run_command('g.remove', flags='f', type='vector', name='constrain,stimulus', env=env) # except: # pass gscript.run_command('r.to.vect', input='stimulus_flat', output='stimulus', type='area', flags='s', env=env) gscript.run_command('r.to.vect', input='constrain_flat', output='constrain', type='area', flags='s', env=env) gscript.run_command('r.colors', map='stimulus', color='greens', env=env) gscript.run_command('r.colors', map='constrain', color='red', flags='n', env=env) # params['stimulus'] = 'stimulus' # params['constrain'] = 'constrain' params.append('constrain=constrain') params.append('stimulus=stimulus') else: gscript.run_command('v.edit', tool='create', map='stimulus', env=env) gscript.run_command('v.edit', tool='create', map='constrain', env=env) update() # ff = gscript.find_file(name='appended', element='vector') # if ff and ff['fullname'] and gscript.vector_info_topo('appended')['lines'] > 0: #roads = 'road_dens_perc_edit' # gscript.mapcalc('stimulus2 = stimulus + stimulus_roads', env=env2) # params[-1] = 'stimulus=stimulus2' futures(params, giface, update)
def run_aspect(real_elev, scanned_elev, env, **kwargs): gs.run_command("r.slope.aspect", elevation=scanned_elev, aspect="aspect", env=env) # reclassify using rules passed as a string to standard input # 0:45:2 means reclassify interval 0 to 45 degrees to category 2 # rules = ['225:315:3', '315:360:2', '0:45:2', '45:135:1', '135:225:4'] # gs.write_command('r.recode', input='aspect', output='aspect_class', # rules='-', stdin='\n'.join(rules), env=env) # contours info = gs.raster_info(scanned_elev) interval = (info["max"] - info["min"]) / 20.0 gs.run_command( "r.contour", input=scanned_elev, output="contours", step=interval, flags="t", env=env, )
def run_aspect(real_elev, scanned_elev, env, **kwargs): info = gs.raster_info(scanned_elev) interval = (info["max"] - info["min"]) / 20.0 # alternatively set fixed interval # interval = 10 gs.run_command( "r.contour", input=scanned_elev, output="contours_main", step=interval * 5, flags="t", env=env, ) gs.run_command( "r.contour", input=scanned_elev, output="contours", step=interval, flags="t", env=env, )
def pops_process_simulation(infected, money_spent, treated_area, baselineValues, pops, baseline): env = get_environment(raster=infected) res = gscript.raster_info(infected)['nsres'] # infected cells info = gscript.parse_command('r.univar', map=infected, flags='g', env=env) counts = gscript.read_command('r.stats', flags='c', input=infected, env=env).strip().splitlines() zero, cnts = counts[0].split(' ') if zero == '0': infected_cells = int(info['n']) - int(cnts) else: infected_cells = int(info['n']) # crops affected - overlay: # TODO: overlay with probability > 20% maybe? now it overlays with averaged scenario, which is larger than one run gscript.mapcalc("crop_affected = if(! isnull({c}) && {i} > 0, 1, null())".format(c=pops["crop"], i=infected), env=env) crop_info = gscript.parse_command('r.univar', map='crop_affected', flags='g', env=env) if crop_info: crop_affected_area = int(crop_info['n']) * res * res else: crop_affected_area = 0 # bar chart record = (infected_cells * res * res, money_spent, treated_area, crop_affected_area) # radar scaling max_money = 5000000. if baseline: infected_scaled = 10 else: infected_scaled = round(min(10 * record[0] / float(baselineValues[0]), 10)) money_scaled = round(min(10 * record[1] / max_money, 10)) treated_scaled = 0 # round(min(10 * record[2] / (max_money / 1.24), 10)) radar_values = (infected_scaled, money_scaled, treated_scaled, 0) # not sure why the condition here if baseline: gscript.run_command('r.colors', map=infected, env=env, rules=pops['color_trees']) return record, radar_values
def compare_points(new, old, real_elev, env): res = gscript.read_command('v.distance', flags='p', from_=new, from_type='point', to=old, to_type='point', upload='dist', separator='comma', env=env).strip() print(res) res = res.splitlines()[1:] total = 0 for line in res: cat, dist = line.split(',') total += float(dist) info = gscript.raster_info(real_elev) width = info['east'] - info['west'] print('compare') print(total / width) if total / width > 0.1: return False return True
def createConfFile(res,inpumap,home): # set the name of conf file confilename = home + '/.r.li/history/conf_diversity_' + str(res) # start the text for the conf file outputLine = ['SAMPLINGFRAME 0|0|1|1\n'] # return r.info about input file rinfo = grass.raster_info(inpumap) # calculate number of lines rows = (rinfo["north"]-rinfo["south"])/rinfo['nsres'] # calculate number of columns columns = (rinfo['east']-rinfo['west'])/rinfo['ewres'] # value for row rV = int(res)/rows # value for column cV = int(res)/columns # append the text for the conf file outputLine.append('SAMPLEAREA -1|-1|'+str(rV)+'|'+str(cV)+'\n') outputLine.append('MOVINGWINDOW\n') # open configuration file fileConf=open(confilename,'w') # write file fileConf.writelines(outputLine) # close file fileConf.close()
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 get_limit(map): return grass.raster_info(map)['max']
def main(): inr = options['input'] outr = options['output'] outp = options['points'] msize = options['msize'] msize = int(msize) global nuldev nuldev = None mmax = (msize-1)/2 mapcalc_str1 = "%s = if(%s == max(" % (outr, inr) mapcalc_list = [] i = 0 j = 0 for x in xrange(i, msize): for y in xrange(j, msize): mapcalc_list.append("%s[%d,%d]" % (inr, -(mmax)+x, -(mmax)+y)) mapcalc_str2 = ','.join(mapcalc_list) mapcalc_str3 = mapcalc_str1 + mapcalc_str2 + ("),%s,null())" % inr) grass.mapcalc(mapcalc_str3) if outp: vect1 = 'R_LOCALMAX_vect1' grass.run_command('r.to.vect', input_ = outr, output = vect1, type_ = 'point', quiet = True, stderr = nuldev) res = grass.raster_info(inr)['nsres'] vect2 = 'R_LOCALMAX_vect2' grass.run_command('v.buffer', input_ = vect1, output = vect2, dist = res*2, quiet = True, stderr = nuldev) vect3 = 'R_LOCALMAX_vect3' grass.run_command('v.type', input_ = vect2, output = vect3, from_type_ = 'centroid', to_type = 'point', quiet = True, stderr = nuldev) vect4 = 'R_LOCALMAX_vect4' grass.run_command('v.category', input_ = vect3, opt = 'del', output = vect4, quiet = True, stderr = nuldev) vect5 = 'R_LOCALMAX_vect5' grass.run_command('v.category', input_ = vect4, opt = 'add', output = vect5, quiet = True, stderr = nuldev) grass.run_command('v.db.addtable', map_ = vect5, columns = 'dist double', quiet = True, stderr = nuldev) vect6 = 'R_LOCALMAX_vect6' grass.run_command('v.distance', from_ = vect5, from_type = 'point', to = vect1, to_type = 'point', output = vect6, upload = 'dist', column = 'dist', quiet = True, stderr = nuldev) grass.run_command('v.select', ainput = vect1, binput = vect6, output = outp, quiet = True, stderr = nuldev) return 0
def test_raster_info(self): res = gscript.raster_info(self.raster) self.assertEquals(str(res['cols']), str(self.region['cols'])) self.assertEquals(str(res['north']), str(self.region['n']))
def main(): global tmp landsat = flags['l'] quickbird = flags['q'] spot = flags['s'] ms1 = options['ms1'] ms2 = options['ms2'] ms3 = options['ms3'] pan = options['pan'] out = options['output_prefix'] tmp = str(os.getpid()) if not landsat and not quickbird and not spot: grass.fatal(_("Please select a flag to specify the satellite sensor")) #get PAN resolution: kv = grass.raster_info(map = pan) nsres = kv['nsres'] ewres = kv['ewres'] panres = (nsres + ewres) / 2 # clone current region grass.use_temp_region() grass.verbose("Using resolution from PAN: %f" % panres) grass.run_command('g.region', flags = 'a', res = panres) grass.verbose("Performing Brovey transformation...") # The formula was originally developed for LANDSAT-TM5 and SPOT, # but it also works well with LANDSAT-TM7 # LANDSAT formula: # r.mapcalc "brov.red=1. * tm.5 / (tm.2 + tm.4 + tm.5) * etmpan" # r.mapcalc "brov.green=1. * tm.4 /(tm.2 + tm.4 + tm.5) * etmpan" # r.mapcalc "brov.blue=1. * tm.2 / (tm.2 + tm.4 + tm.5) * etmpan" # # SPOT formula: # r.mapcalc "brov.red= 1. * spot.ms.3 / (spot.ms.1 + spot.ms.2 + spot.ms.3) * spot.p" # r.mapcalc "brov.green=1. * spot.ms.2 / (spot.ms.1 + spot.ms.2 + spot.ms.3) * spot.p" # r.mapcalc "brov.blue= 1. * spot.ms.1 / (spot.ms.1 + spot.ms.2 + spot.ms.3) * spot.p" # note: for RGB composite then revert brov.red and brov.green! grass.message(_("Calculating %s.{red,green,blue}: ...") % out) e = '''eval(k = float("$pan") / ("$ms1" + "$ms2" + "$ms3")) "$out.red" = "$ms3" * k "$out.green" = "$ms2" * k "$out.blue" = "$ms1" * k''' grass.mapcalc(e, out = out, pan = pan, ms1 = ms1, ms2 = ms2, ms3 = ms3) # Maybe? #r.colors $GIS_OPT_OUTPUTPREFIX.red col=grey #r.colors $GIS_OPT_OUTPUTPREFIX.green col=grey #r.colors $GIS_OPT_OUTPUTPREFIX.blue col=grey #to blue-ish, therefore we modify #r.colors $GIS_OPT_OUTPUTPREFIX.blue col=rules << EOF #5 0 0 0 #20 200 200 200 #40 230 230 230 #67 255 255 255 #EOF if spot: #apect table is nice for SPOT: grass.message(_("Assigning color tables for SPOT...")) for ch in ['red', 'green', 'blue']: grass.run_command('r.colors', map = "%s.%s" % (out, ch), col = 'aspect') grass.message(_("Fixing output names...")) for s, d in [('green','tmp'),('red','green'),('tmp','red')]: src = "%s.%s" % (out, s) dst = "%s.%s" % (out, d) grass.run_command('g.rename', rast = (src, dst), quiet = True) else: #aspect table is nice for LANDSAT and QuickBird: grass.message(_("Assigning color tables for LANDSAT or QuickBird...")) for ch in ['red', 'green', 'blue']: grass.run_command('r.colors', map = "%s.%s" % (out, ch), col = 'aspect') grass.message(_("Following pan-sharpened output maps have been generated:")) for ch in ['red', 'green', 'blue']: grass.message(_("%s.%s") % (out, ch)) grass.verbose("To visualize output, run:") grass.verbose("g.region -p rast=%s.red" % out) grass.verbose("d.rgb r=%s.red g=%s.green b=%s.blue" % (out, out, out)) grass.verbose("If desired, combine channels with 'r.composite' to a single map.") # write cmd history: for ch in ['red', 'green', 'blue']: grass.raster_history("%s.%s" % (out, ch))
def main(): # Get user inputs friction_original = options['friction'] # Input friction map out = options['out'] # Output totalcost raster maxcost = options['maxcost'] # Max cost distance in cost units knight = "k" if flags["k"] else "" # Use Knight's move in r.cost instead Queen's move (a bit slower, but more accurate) mempercent = int(options['mempercent']) # Percent of map to keep in memory in r.cost calculation # Error if no valid friction surface is given if not grass.find_file(friction_original)['name']: grass.message(_("Friction surface <%s> not found") % friction_original) sys.exit() # Calculate cost distances / edge effect distances from the friction map. Result is in map units info = grass.raster_info(friction_original) # Read and get raster info edgeeffect_min = float(maxcost) / float(info['max']) # Minimum cost distance / edge effect distance edgeeffect_max = float(maxcost) / float(info['min']) # Maximum cost distance / edge effect distance # If "Only calculate edge effect" is selected if flags['e']: grass.message("Minimum distance / edge effect: " + str(edgeeffect_min)) grass.message("Maximum distance / edge effect: " + str(edgeeffect_max)) sys.exit() # If output file exists, but overwrite option isn't selected if not grass.overwrite(): if grass.find_file(out)['name']: grass.message(_("Output raster map <%s> already exists") % out) sys.exit() # Get raster calculation region information regiondata = grass.read_command("g.region", flags = 'p') regvalues = grass.parse_key_val(regiondata, sep= ':') # Assign variables for necessary region info bits nsres = float(regvalues['nsres']) ewres = float(regvalues['ewres']) # Calculate the mean resolution meanres = (nsres + ewres) / 2.0 # Create a list holding cell coordinates coordinatelist = [] # An empty list that will be populated with coordinates rasterdata = grass.read_command('r.stats', flags="1gn", input = friction_original) # Read input raster coordinates rastervalues = rasterdata.split() # Split the values from r.stats into list entries # rastervalues list is structured like that: [x1, y1, rastervalue1, x2, y2, rastervalue2 ... xn, yn, rastervaluen], so iterate through that list with step of 3 and write a new list that has coordinates in a string: ["x1,y1", "x2,y2" ... "xn,yn"] for val in xrange(0,len(rastervalues),3): coordinatelist.append(rastervalues[val] + "," + rastervalues[val+1]) # This is the number of cells (and hence cost surfaces) to be used n_coords = len(coordinatelist) # Create temporary filenames with unique process id in their name. Add each name to the tmp_layers list. pid = os.getpid() cost1 = str("tmp_totalcost_cost1_%d" % pid) tmp_layers.append(cost1) cost2 = str("tmp_totalcost_cost2_%d" % pid) tmp_layers.append(cost2) cost3 = str("tmp_totalcost_cost3_%d" % pid) tmp_layers.append(cost3) cost4 = str("tmp_totalcost_cost4_%d" % pid) tmp_layers.append(cost4) friction = str("tmp_friction_%d" % pid) tmp_layers.append(friction) calctemp = str("tmp_calctemp_%d" % pid) tmp_layers.append(calctemp) # Assuming the friction values are per map unit (not per cell), the raster should be multiplied with region resolution. This is because r.cost just uses cell values and adds them - slightly different approach compared to ArcGIS which compensates for the resolution automatically. The result is then divided by maxcost so that r.cost max_cost value can be fixed to 1 (it doesn't accept floating point values, hence the workaround). grass.mapcalc("$outmap = $inmap * $res / $mcost", outmap = friction, inmap = friction_original, res = meanres, mcost = maxcost) # Do the main loop for c in xrange(0, n_coords, 4): # Iterate through the numbers of cells with the step of 4 # Start four r.cost processes with different coordinates. The first process (costproc1) is always made, but the other 3 have the condition that there exists a successive coordinate in the list. This is because the used step of 4 in the loop. In case there are no coordinates left, assign the redundant cost outputs null-values so they wont be included in the map calc. try: costproc1 = grass.start_command('r.cost', overwrite = True, flags = knight, input = friction, output = cost1, start_coordinates = coordinatelist[c], max_cost = 1, percent_memory = mempercent) if c+1 < n_coords: costproc2 = grass.start_command('r.cost', overwrite = True, flags = knight, input = friction, output = cost2, start_coordinates = coordinatelist[c+1], max_cost = 1, percent_memory = mempercent) else: cost2 = "null()" if c+2 < n_coords: costproc3 = grass.start_command('r.cost', overwrite = True, flags = knight, input = friction, output = cost3, start_coordinates = coordinatelist[c+2], max_cost = 1, percent_memory = mempercent) else: cost3 = "null()" if c+3 < n_coords: costproc4 = grass.start_command('r.cost', overwrite = True, flags = knight, input = friction, output = cost4, start_coordinates = coordinatelist[c+3], max_cost = 1, percent_memory = mempercent) else: cost4 = "null()" except: grass.message("Error with r.cost: " + str(sys.exc_info()[0])) sys.exit() # For the very first iteration just add those first r.cost results together if c == 0: # Wait for the r.cost processes to stop before moving on costproc1.wait() costproc2.wait() costproc3.wait() costproc4.wait() # Do the map algebra: merge the cost surfaces try: grass.mapcalc("$outmap = if(isnull($tempmap1),0,1) + if(isnull($tempmap2),0,1) + if(isnull($tempmap3),0,1) + if(isnull($tempmap4),0,1)", outmap = out, tempmap1 = cost1, tempmap2 = cost2, tempmap3 = cost3, tempmap4 = cost4, overwrite=True) except: grass.message("Error with mapcalc: " + str(sys.exc_info()[0])) sys.exit() # If it's not the first iteration... else: # Rename the output of previous mapcalc iteration so that it can be used in the mapcalc expression (x = x + y logic doesn't work apparently) try: # If pygrass gets fixed, replace g.rename with those commented out pygrass-based lines as they seem to be a bit faster (are they really?) #map = pygrass.raster.RasterRow(out) #map.name = calctemp grass.run_command('g.rename', overwrite = True, rast = out + "," + calctemp) except: grass.message("Error: " + str(sys.exc_info()[0])) sys.exit() # Wait for the r.cost processes to stop before moving on costproc1.wait() costproc2.wait() costproc3.wait() costproc4.wait() # Merge the r.cost results and the cumulative map from previous iteration try: grass.mapcalc("$outmap = if(isnull($inmap),0,$inmap) + if(isnull($tempmap1),0,1) + if(isnull($tempmap2),0,1) + if(isnull($tempmap3),0,1) + if(isnull($tempmap4),0,1)", inmap = calctemp, outmap = out, tempmap1 = cost1, tempmap2 = cost2, tempmap3 = cost3, tempmap4 = cost4, overwrite=True) except: grass.message("Error with mapcalc: " + str(sys.exc_info()[0])) sys.exit() # Finally print the edge effect values grass.message("---------------------------------------------") grass.message("Minimum distance / edge effect: " + str(edgeeffect_min)) grass.message("Maximum distance / edge effect: " + str(edgeeffect_max))
def main(): if not hasNumPy: grass.fatal(_("Required dependency NumPy not found. Exiting.")) sharpen = options['method'] # sharpening algorithm ms1 = options['blue'] # blue channel ms2 = options['green'] # green channel ms3 = options['red'] # red channel pan = options['pan'] # high res pan channel out = options['output'] # prefix for output RGB maps bladjust = flags['l'] # adjust blue channel sproc = flags['s'] # serial processing outb = grass.core.find_file('%s_blue' % out) outg = grass.core.find_file('%s_green' % out) outr = grass.core.find_file('%s_red' % out) if (outb['name'] != '' or outg['name'] != '' or outr['name'] != '') and not grass.overwrite(): grass.warning(_('Maps with selected output prefix names already exist.' ' Delete them or use overwrite flag')) return pid = str(os.getpid()) # get PAN resolution: kv = grass.raster_info(map=pan) nsres = kv['nsres'] ewres = kv['ewres'] panres = (nsres + ewres) / 2 # clone current region grass.use_temp_region() grass.run_command('g.region', res=panres, align=pan) grass.message(_("Performing pan sharpening with hi res pan image: %f" % panres)) if sharpen == "brovey": grass.verbose(_("Using Brovey algorithm")) # pan/intensity histogram matching using linear regression outname = 'tmp%s_pan1' % pid panmatch1 = matchhist(pan, ms1, outname) outname = 'tmp%s_pan2' % pid panmatch2 = matchhist(pan, ms2, outname) outname = 'tmp%s_pan3' % pid panmatch3 = matchhist(pan, ms3, outname) outr = '%s_red' % out outg = '%s_green' % out outb = '%s_blue' % out # calculate brovey transformation grass.message(_("Calculating Brovey transformation...")) if sproc: # serial processing e = '''eval(k = "$ms1" + "$ms2" + "$ms3") "$outr" = 1.0 * "$ms3" * "$panmatch3" / k "$outg" = 1.0 * "$ms2" * "$panmatch2" / k "$outb" = 1.0 * "$ms1" * "$panmatch1" / k''' grass.mapcalc(e, outr=outr, outg=outg, outb=outb, panmatch1=panmatch1, panmatch2=panmatch2, panmatch3=panmatch3, ms1=ms1, ms2=ms2, ms3=ms3, overwrite=True) else: # parallel processing pb = grass.mapcalc_start('%s_blue = (1.0 * %s * %s) / (%s + %s + %s)' % (out, ms1, panmatch1, ms1, ms2, ms3), overwrite=True) pg = grass.mapcalc_start('%s_green = (1.0 * %s * %s) / (%s + %s + %s)' % (out, ms2, panmatch2, ms1, ms2, ms3), overwrite=True) pr = grass.mapcalc_start('%s_red = (1.0 * %s * %s) / (%s + %s + %s)' % (out, ms3, panmatch3, ms1, ms2, ms3), overwrite=True) pb.wait() pg.wait() pr.wait() # Cleanup grass.run_command('g.remove', flags='f', quiet=True, type='raster', name='%s,%s,%s' % (panmatch1, panmatch2, panmatch3)) elif sharpen == "ihs": grass.verbose(_("Using IHS<->RGB algorithm")) # transform RGB channels into IHS color space grass.message(_("Transforming to IHS color space...")) grass.run_command('i.rgb.his', overwrite=True, red=ms3, green=ms2, blue=ms1, hue="tmp%s_hue" % pid, intensity="tmp%s_int" % pid, saturation="tmp%s_sat" % pid) # pan/intensity histogram matching using linear regression target = "tmp%s_int" % pid outname = "tmp%s_pan_int" % pid panmatch = matchhist(pan, target, outname) # substitute pan for intensity channel and transform back to RGB color space grass.message(_("Transforming back to RGB color space and sharpening...")) grass.run_command('i.his.rgb', overwrite=True, hue="tmp%s_hue" % pid, intensity="%s" % panmatch, saturation="tmp%s_sat" % pid, red="%s_red" % out, green="%s_green" % out, blue="%s_blue" % out) # Cleanup grass.run_command('g.remove', flags='f', quiet=True, type='raster', name=panmatch) elif sharpen == "pca": grass.verbose(_("Using PCA/inverse PCA algorithm")) grass.message(_("Creating PCA images and calculating eigenvectors...")) # initial PCA with RGB channels pca_out = grass.read_command('i.pca', quiet=True, rescale='0,0', input='%s,%s,%s' % (ms1, ms2, ms3), output='tmp%s.pca' % pid) if len(pca_out) < 1: grass.fatal(_("Input has no data. Check region settings.")) b1evect = [] b2evect = [] b3evect = [] for l in pca_out.replace('(', ',').replace(')', ',').splitlines(): b1evect.append(float(l.split(',')[1])) b2evect.append(float(l.split(',')[2])) b3evect.append(float(l.split(',')[3])) # inverse PCA with hi res pan channel substituted for principal component 1 pca1 = 'tmp%s.pca.1' % pid pca2 = 'tmp%s.pca.2' % pid pca3 = 'tmp%s.pca.3' % pid b1evect1 = b1evect[0] b1evect2 = b1evect[1] b1evect3 = b1evect[2] b2evect1 = b2evect[0] b2evect2 = b2evect[1] b2evect3 = b2evect[2] b3evect1 = b3evect[0] b3evect2 = b3evect[1] b3evect3 = b3evect[2] outname = 'tmp%s_pan' % pid panmatch = matchhist(pan, ms1, outname) grass.message(_("Performing inverse PCA ...")) stats1 = grass.parse_command("r.univar", map=ms1, flags='g', parse=(grass.parse_key_val, {'sep': '='})) stats2 = grass.parse_command("r.univar", map=ms2, flags='g', parse=(grass.parse_key_val, {'sep': '='})) stats3 = grass.parse_command("r.univar", map=ms3, flags='g', parse=(grass.parse_key_val, {'sep': '='})) b1mean = float(stats1['mean']) b2mean = float(stats2['mean']) b3mean = float(stats3['mean']) if sproc: # serial processing e = '''eval(k = "$ms1" + "$ms2" + "$ms3") "$outr" = 1.0 * "$ms3" * "$panmatch3" / k "$outg" = 1.0 * "$ms2" * "$panmatch2" / k "$outb" = 1.0* "$ms1" * "$panmatch1" / k''' outr = '%s_red' % out outg = '%s_green' % out outb = '%s_blue' % out cmd1 = "$outb = (1.0 * $panmatch * $b1evect1) + ($pca2 * $b2evect1) + ($pca3 * $b3evect1) + $b1mean" cmd2 = "$outg = (1.0 * $panmatch * $b1evect2) + ($pca2 * $b2evect1) + ($pca3 * $b3evect2) + $b2mean" cmd3 = "$outr = (1.0 * $panmatch * $b1evect3) + ($pca2 * $b2evect3) + ($pca3 * $b3evect3) + $b3mean" cmd = '\n'.join([cmd1, cmd2, cmd3]) grass.mapcalc(cmd, outb=outb, outg=outg, outr=outr, panmatch=panmatch, pca2=pca2, pca3=pca3, b1evect1=b1evect1, b2evect1=b2evect1, b3evect1=b3evect1, b1evect2=b1evect2, b2evect2=b2evect2, b3evect2=b3evect2, b1evect3=b1evect3, b2evect3=b2evect3, b3evect3=b3evect3, b1mean=b1mean, b2mean=b2mean, b3mean=b3mean, overwrite=True) else: # parallel processing pb = grass.mapcalc_start('%s_blue = (%s * %f) + (%s * %f) + (%s * %f) + %f' % (out, panmatch, b1evect1, pca2, b2evect1, pca3, b3evect1, b1mean), overwrite=True) pg = grass.mapcalc_start('%s_green = (%s * %f) + (%s * %f) + (%s * %f) + %f' % (out, panmatch, b1evect2, pca2, b2evect2, pca3, b3evect2, b2mean), overwrite=True) pr = grass.mapcalc_start('%s_red = (%s * %f) + (%s * %f) + (%s * ''%f) + %f' % (out, panmatch, b1evect3, pca2, b2evect3, pca3, b3evect3, b3mean), overwrite=True) pr.wait() pg.wait() pb.wait() # Cleanup grass.run_command('g.remove', flags='f', quiet=True, type="raster", pattern='tmp%s*,%s' % (pid, panmatch)) # Could add other sharpening algorithms here, e.g. wavelet transformation grass.message(_("Assigning grey equalized color tables to output images...")) # equalized grey scales give best contrast for ch in ['red', 'green', 'blue']: grass.run_command('r.colors', quiet=True, map="%s_%s" % (out, ch), flags="e", color='grey') # Landsat too blue-ish because panchromatic band less sensitive to blue # light, so output blue channed can be modified if bladjust: grass.message(_("Adjusting blue channel color table...")) rules = grass.tempfile() colors = open(rules, 'w') colors.write('5 0 0 0\n20 200 200 200\n40 230 230 230\n67 255 255 255 \n') colors.close() grass.run_command('r.colors', map="%s_blue" % out, rules=rules) os.remove(rules) # output notice grass.verbose(_("The following pan-sharpened output maps have been generated:")) for ch in ['red', 'green', 'blue']: grass.verbose(_("%s_%s") % (out, ch)) grass.verbose(_("To visualize output, run: g.region -p raster=%s_red" % out)) grass.verbose(_("d.rgb r=%s_red g=%s_green b=%s_blue" % (out, out, out))) grass.verbose(_("If desired, combine channels into a single RGB map with 'r.composite'.")) grass.verbose(_("Channel colors can be rebalanced using i.colors.enhance.")) # write cmd history: for ch in ['red', 'green', 'blue']: grass.raster_history("%s_%s" % (out, ch)) # create a group with the three output grass.run_command('i.group', group=out, input="{n}_red,{n}_blue,{n}_green".format(n=out)) # Cleanup grass.run_command('g.remove', flags="f", type="raster", pattern="tmp%s*" % pid, quiet=True)
def main(): global tmpmap tmpmap = None map = options['map'] zero = flags['z'] bands = flags['b'] if not zero: s = gscript.read_command('r.univar', flags='g', map=map) kv = gscript.parse_key_val(s) global mean, stddev mean = float(kv['mean']) stddev = float(kv['stddev']) if not bands: # smooth free floating blue/white/red rules = '\n'.join(["0% blue", "%f blue" % z(-2), "%f white" % mean, "%f red" % z(+2), "100% red"]) else: # banded free floating black/red/yellow/green/yellow/red/black # reclass with labels only works for category (integer) based maps # r.reclass input="$GIS_OPT_MAP" output="${GIS_OPT_MAP}.stdevs" << # EOF # >3 S.D. outliers colored black so they show up in d.histogram w/ white background rules = '\n'.join(["0% black", "%f black" % z(-3), "%f red" % z(-3), "%f red" % z(-2), "%f yellow" % z(-2), "%f yellow" % z(-1), "%f green" % z(-1), "%f green" % z(+1), "%f yellow" % z(+1), "%f yellow" % z(+2), "%f red" % z(+2), "%f red" % z(+3), "%f black" % z(+3), "100% black"]) else: tmpmap = "r_col_stdev_abs_%d" % os.getpid() gscript.mapcalc("$tmp = abs($map)", tmp=tmpmap, map=map) # data centered on 0 (e.g. map of deviations) info = gscript.raster_info(tmpmap) maxv = info['max'] # current r.univar truncates percentage to the base integer s = gscript.read_command('r.univar', flags='eg', map=map, percentile=[95.45, 68.2689, 99.7300]) kv = gscript.parse_key_val(s) stddev1 = float(kv['percentile_68_2689']) stddev2 = float(kv['percentile_95_45']) stddev3 = float(kv['percentile_99_73']) if not bands: # zero centered smooth blue/white/red rules = '\n'.join(["%f blue" % -maxv, "%f blue" % -stddev2, "0 white", "%f red" % stddev2, "%f red" % maxv]) else: # zero centered banded black/red/yellow/green/yellow/red/black # >3 S.D. outliers colored black so they show up in d.histogram w/ white background rules = '\n'.join(["%f black" % -maxv, "%f black" % -stddev3, "%f red" % -stddev3, "%f red" % -stddev2, "%f yellow" % -stddev2, "%f yellow" % -stddev1, "%f green" % -stddev1, "%f green" % stddev1, "%f yellow" % stddev1, "%f yellow" % stddev2, "%f red" % stddev2, "%f red" % stddev3, "%f black" % stddev3, "%f black" % maxv, ]) gscript.write_command('r.colors', map=map, rules='-', stdin=rules)
def main(): raster = options['raster'] maskcats = options['maskcats'] vector = options['vector'] layer = options['layer'] cats = options['cats'] where = options['where'] remove = flags['r'] invert = flags['i'] if not remove and not raster and not vector: grass.fatal(_("Either parameter <raster> ot parameter <vector> is required")) mapset = grass.gisenv()['MAPSET'] exists = bool(grass.find_file('MASK', element='cell', mapset=mapset)['file']) if remove: # -> remove if exists: if sys.platform == 'win32': grass.run_command('g.remove', flags='if', quiet=True, type='raster', name='MASK') else: grass.run_command('g.remove', flags='f', quiet=True, type='raster', name='MASK') grass.message(_("Raster MASK removed")) else: grass.fatal(_("No existing MASK to remove")) else: # -> create if exists: if not grass.overwrite(): grass.fatal(_("MASK already found in current mapset. Delete first or overwrite.")) else: grass.warning(_("MASK already exists and will be overwritten")) grass.run_command('g.remove', flags='f', quiet=True, type='raster', name='MASK') if raster: # check if input raster exists if not grass.find_file(raster)['file']: grass.fatal(_("Raster map <%s> not found") % raster) if maskcats != '*' and not remove: if grass.raster_info(raster)['datatype'] != "CELL": grass.fatal(_("The raster map <%s> must be integer (CELL type) " " in order to use the 'maskcats' parameter") % raster) p = grass.feed_command( 'r.reclass', input=raster, output='MASK', overwrite=True, rules='-') p.stdin.write("%s = 1" % maskcats) p.stdin.close() p.wait() elif vector: vector_name = grass.find_file(vector, 'vector')['fullname'] if not vector_name: grass.fatal(_("Vector map <%s> not found") % vector) # parser bug? if len(cats) == 0: cats = None if len(where) == 0: where = None if grass.vector_info_topo(vector_name)['areas'] < 1: grass.warning(_("No area found in vector map <%s>. " "Creating a convex hull for MASK.") % vector_name) global tmp_hull tmp_hull = "tmp_hull_%d" % os.getpid() to_rast_input = tmp_hull # force 'flat' convex hull for 3D vector maps try: grass.run_command('v.hull', flags='f', quiet=True, input=vector_name, output=tmp_hull, layer=layer, cats=cats, where=where) except CalledModuleError: grass.fatal( _("Unable to create a convex hull for vector map <%s>") % vector_name) else: to_rast_input = vector_name env = os.environ.copy() if grass.verbosity() > 1: env['GRASS_VERBOSE'] = '1' grass.run_command('v.to.rast', input=to_rast_input, layer=layer, output='MASK', use='val', val='1', type='area', cats=cats, where=where, env=env) if invert: global tmp tmp = "r_mask_%d" % os.getpid() grass.run_command('g.rename', raster=('MASK', tmp), quiet=True) grass.message(_("Creating inverted raster MASK...")) grass.mapcalc("MASK = if(isnull($tmp), 1, null())", tmp=tmp) grass.verbose(_("Inverted raster MASK created")) else: grass.verbose(_("Raster MASK created")) grass.message(_("All subsequent raster operations will be limited to " "the MASK area. Removing or renaming raster map named " "'MASK' will restore raster operations to normal."))
def reclass(inf, outf, lim, clump, diag, les): infile = inf outfile = outf lesser = les limit = lim clumped = clump diagonal = diag s = grass.read_command("g.region", flags='p') kv = grass.parse_key_val(s, sep=':') s = kv['projection'].strip().split() if s == '0': grass.fatal(_("xy-locations are not supported")) grass.fatal(_("Need projected data with grids in meters")) if not grass.find_file(infile)['name']: grass.fatal(_("Raster map <%s> not found") % infile) if clumped and diagonal: grass.fatal(_("flags c and d are mutually exclusive")) if clumped: clumpfile = infile else: clumpfile = "%s.clump.%s" % (infile.split('@')[0], outfile) TMPRAST.append(clumpfile) if not grass.overwrite(): if grass.find_file(clumpfile)['name']: grass.fatal(_("Temporary raster map <%s> exists") % clumpfile) if diagonal: grass.message(_("Generating a clumped raster file including " "diagonal neighbors...")) grass.run_command('r.clump', flags='d', input=infile, output=clumpfile) else: grass.message(_("Generating a clumped raster file ...")) grass.run_command('r.clump', input=infile, output=clumpfile) if lesser: grass.message(_("Generating a reclass map with area size less than " "or equal to %f hectares...") % limit) else: grass.message(_("Generating a reclass map with area size greater " "than or equal to %f hectares...") % limit) recfile = outfile + '.recl' TMPRAST.append(recfile) sflags = 'aln' if grass.raster_info(infile)['datatype'] in ('FCELL', 'DCELL'): sflags += 'i' p1 = grass.pipe_command('r.stats', flags=sflags, input=(clumpfile, infile), sep=';') p2 = grass.feed_command('r.reclass', input=clumpfile, output=recfile, rules='-') rules = '' for line in p1.stdout: f = line.rstrip(os.linesep).split(';') if len(f) < 5: continue hectares = float(f[4]) * 0.0001 if lesser: test = hectares <= limit else: test = hectares >= limit if test: rules += "%s = %s %s\n" % (f[0], f[2], f[3]) if rules: p2.stdin.write(rules) p1.wait() p2.stdin.close() p2.wait() if p2.returncode != 0: if lesser: grass.fatal(_("No areas of size less than or equal to %f " "hectares found.") % limit) else: grass.fatal(_("No areas of size greater than or equal to %f " "hectares found.") % limit) grass.mapcalc("$outfile = $recfile", outfile=outfile, recfile=recfile)
oneoutletbasin = 'C:\Mystuff\grassgisdatabase\basin_out23.tif' print "r.water.outlet" print g.run_command('r.water.outlet',overwrite=True,\ input = 'dra1v23', output= 'oneoutletbasin',\ coordinates=[444470.550695,4397299.50548]) # read map a = garray.array() a.read(acc_v23) print a print g.raster_info(acc_v23)['datatype'] stop print g.run_command('r.out.gdal',overwrite=True,\ input = "oneoutletbasin",type='Float32', \ output='C:\Mystuff\grassgisdatabase\onebasinProg.tif',nodata=-9999) print g.read_command('g.list', _type = 'rast') ##stop print g.run_command('r.out.gdal',overwrite=True,\ input='acc_v23',type='Float64', \ output='C:\Mystuff\grassgisdatabase\missioncreek_fac23.tif', format='GTiff') print 'drainages' # We create a new array and read map2d_1 to modify it print g.run_command('r.out.gdal',overwrite=True, type='Float32',\
xy = [] for i in range(len(X_coordinateDAM)): xy.append(str(X_coordinateDAM[i]) + "," + str(Y_coordinateDAM[i])) # 1c. Input destination CSV-file g=open(r"#Specify the path and name.csv",'wb') writer=csv.writer(g,delimiter=',',quotechar='"',quoting=csv.QUOTE_MINIMAL) # 2a.GRASS -> open the DEM in GRASS DEM = grass.run_command("r.in.gdal",input=path_to_DEM,output="DEM",overwrite=True) # 2b.GRASS -> set region region = grass.run_command("g.region",flags="d",rast="DEM",overwrite=True) # 3.Write metadata for csv nsres = grass.raster_info('DEM')['nsres'] ewres = grass.raster_info('DEM')['ewres'] writer.writerow(["Estimating reservoir:",Reservoir_name]) writer.writerow(["Resolution (Nsres/ewres)",nsres,ewres]) writer.writerow(["Dam Locations (X1,Y1..Xn,Yn):",xy]) writer.writerow(["Waterlevel","Volume","Area"]) # 4.GRASS -> create drainage direction map and drainage accumulation map drain_dir_acc = grass.run_command("r.watershed",elevation="DEM",drainage="drain_dir",accumulation="drain_acc",overwrite=True) for i in range(len(X_coordinateDAM)): # 5. Get coordinates corresponding to DEM (instead of coordinates of the dam) circle = grass.run_command("r.circle",flags="b",coordinate=xy[i],min=0,max=VARIABLE,output="circle",overwrite=True) grass.mapcalc("$inter1=abs(if(isnull($circle),null(),drain_acc,drain_acc))",inter1="inter1",circle="circle",drain_acc="drain_acc",overwrite=True) univar = grass.read_command('r.info', map='inter1',flags="r") maximum = float(univar.split('\n')[1].split('=')[1]) grass.mapcalc("$inter2=if($inter1>$maximum-0.1,1,null())",inter2="inter2",inter1="inter1",maximum=maximum,overwrite=True)
def get_limit(map): return gscript.raster_info(map)['max']
def main(): # User inputs friction = options['friction'] # Input friction raster inpoints = options['points'] # Input point layer rastout = options['rastout'] # Output least cost path raster radius = int(options['radius']) # Point search radius n_closepoints = int(options['nearpoints']) # Number of closest points vectout = options['vectout'] # Vector layer output knight = "k" if flags['k'] else "" # Knight's move flag costatt = "e" if flags['c'] else "" # Calculate total cost values for paths and add them to attribute table # Check no vector or raster output is chosen, raise an error if (not vectout) and (not rastout): grass.message("No output chosen!") sys.exit() # Check overwrite settings # If output raster file exists, but overwrite option isn't selected if not grass.overwrite(): if grass.find_file(rastout)['name']: grass.message(_("Output raster map <%s> already exists") % rastout) sys.exit() # If output vector file exists, but overwrite option isn't selected if not grass.overwrite(): if grass.find_file(vectout, element = 'vector')['name']: grass.message(_("Output vector map <%s> already exists") % vectout) sys.exit() # If overwrite is chosen, remove the previous layers before any action (to lessen the probability of some random errors) if grass.overwrite(): grass.run_command("g.remove", rast = rastout, vect = vectout, quiet = True) # Get a region resolution to be used in cost attribute calculation, because the default will be in map units if vectout and (costatt == "e"): # Get raster calculation region information regiondata = grass.read_command("g.region", flags = 'p') regvalues = grass.parse_key_val(regiondata, sep= ':') # Assign variables for necessary region info bits nsres = float(regvalues['nsres']) ewres = float(regvalues['ewres']) regionres = (nsres + ewres) / 2.0 rescoefficient = regionres # Get process id (pid) and create temporary layer names which are also added to tmp_rlayers list pid = os.getpid() # Process ID, used for getting unique temporary filenames costmap1 = "tmp_cost_%d" % pid # Cost surface for point 1 tmp_rlayers.append(costmap1) costmap2 = "tmp_cost_%d_%i" % (pid, 2) # Cost surface from point 2 (parallel process) tmp_rlayers.append(costmap2) costdir1 = "tmp_costdir_%d" % pid # Temporary cost direction raster 1 tmp_rlayers.append(costdir1) costdir2 = "tmp_costdir_%d_%i" % (pid, 2) # Temporary cost direction raster 2 tmp_rlayers.append(costdir2) lcpmap1 = "tmp_lcp_%d" % pid # Least cost path map from costmap1 tmp_rlayers.append(lcpmap1) lcpmap2 = "tmp_lcp_%d_%i" % (pid, 2) # Least cost path map from costmap2 (parallel process) tmp_rlayers.append(lcpmap2) lcptemp = "tmp_lcptemp_%d" % pid # Temporary file for mapcalc tmp_rlayers.append(lcptemp) region = "tmp_region_%d" % pid # Temporary vector layer of computational region tmp_vlayers.append(region) points = "tmp_points_%d" % pid # Temporary point layer which holds points only inside the region tmp_vlayers.append(points) if vectout: # if vector output is needed, create the temporary vectorlayers too vectdrain1 = "tmp_vectdrain_%d" % pid tmp_vlayers.append(vectdrain1) vectdrain2 = "tmp_vectdrain2_%d" % pid tmp_vlayers.append(vectdrain2) # Make sure input data points are inside raster computational region: create a region polygon and select points that are inside it grass.run_command('v.in.region', overwrite = True, output = region) grass.run_command('v.select', overwrite = True, flags = "tc", ainput = inpoints, atype = 'point', binput = region, btype = 'area', output = points , operator = 'within') # Create a new PointLayerInfo class instance using input point layer and get the categories list as well as total feature count of the layer pointlayer = PointLayerInfo(points) points_cats = pointlayer.featcats # A list() of layer feature categories points_featcount = pointlayer.featcount # integer of feature count in point layer points_coordsdict = pointlayer.coordsdict # dict() of point coordinates as tuple (x,y) # Create an empty dictionaries for storing cost distances between points costdict1 = dict() costdict2 = dict() # Create the first mapcalc process, so that it can be checked and stopped in the loop without using more complicated ways mapcalc = grass.Popen("") lcp1 = grass.Popen("") lcp2 = grass.Popen("") # The main loop for least cost path creation. For each point a cost surface is created, least cost paths created and then added to the general output file. Loop uses a range which has as many items as there are points in the input point layer. To make use of parallel processing, the step is 2, although the "item" is always the first of the selected pair. for item in range(0,points_featcount,2): # Get category number of the point from the point_cats list cat1 = points_cats[item] # Set p2 (i.e. using second or parallel process) to be False by default and make it True if there are enough points left to do so. In that case set it to true and also get the category number of the point from the point_cats list p2 = False if item+1 < points_featcount: p2 = True cat2 = points_cats[item+1] # Create a new PointLayerInfo object from input point layer with centerpoint (from which distances area measured in the class) feature as currently selected point cat point1 = PointLayerInfo(points, cat1) if p2: # The same for p2 if needed point2 = PointLayerInfo(points, cat2) # begin cost surface process with the start coordinate of currently selected point. Do the same for second process costsurf1 = grass.start_command('r.cost', flags=knight, overwrite=True, input=friction, output=costmap1, outdir=costdir1, start_coordinates=point1.centercoord()) if p2: costsurf2 = grass.start_command('r.cost', flags=knight, overwrite=True, input=friction, output=costmap2, outdir=costdir2, start_coordinates=point2.centercoord()) # Create the drainlist (list of feature coordinates where lcp from current point is made to) depending on whether radius and/or n_closepoints are used. Drainlist point coordinates will be used for r.drain. See PointLayerInfo class below for explanation of the process. if radius and n_closepoints: # If radius and n_closepoints are used drainlist1 = point1.near_points_in_radius(n_closepoints, radius) if p2: drainlist2 = point2.near_points_in_radius(n_closepoints, radius) elif radius: # If radius is used drainlist1 = point1.points_in_radius(radius) if p2: drainlist2 = point2.points_in_radius(radius) elif n_closepoints: # If n_closepoints is used drainlist1 = point1.near_points(n_closepoints) if p2: drainlist2 = point2.near_points(n_closepoints) else: # If neither radius or n_closepoints are used drainlist1 = point1.cats_without_centerpoint() if p2: drainlist2 = point2.cats_without_centerpoint() # Do the least cost path calculation procedures drain_coords1 = "" # An empty string that will be populated with point coordinates which in turn will be used for r.drain start coordinates for drainpoint in drainlist1: # Iterate through all points in drainlist drain_x, drain_y = point1.coordsdict[drainpoint] # variables are assigned coordinate values from the coordinate dictionary drain_coords1 = drain_coords1 + str(drain_x) + "," + str(drain_y) + "," # Add those coordinates to the string that is usable by r.drain if p2: # The same thing for second process, see previous section for comments drain_coords2 = "" for drainpoint in drainlist2: drain_x, drain_y = point2.coordsdict[drainpoint] drain_coords2 = drain_coords2 + str(drain_x) + "," + str(drain_y) + "," # Wait for the previous processes to finish their processing costsurf1.wait() costsurf2.wait() mapcalc.wait() # If vector output is needed, do the r.drain for each point in the drainlist separately to get the cost values if vectout: if costatt == "e": for drainpoint in drainlist1: # Each point cat in the drainlist is being iterated drain_x, drain_y = point1.coordsdict[drainpoint] # Currently selected point's coordinates drain_onecoord = str(str(drain_x) + "," + str(drain_y)) # The coordinate to be used in r.drain on the next line grass.run_command('r.drain', overwrite=True, flags="ad", input=costmap1, indir=costdir1, output = lcpmap1, start_coordinates = drain_onecoord) # Get raster max value (=total cost value for one path) and store it in dictionary with point cat being its key rastinfo = grass.raster_info(lcpmap1) costdict1[drainpoint] = rescoefficient * rastinfo['min'] if p2: # Same procedure as in the previous section for parallel process for drainpoint in drainlist2: drain_x, drain_y = point2.coordsdict[drainpoint] drain_onecoord = str(str(drain_x) + "," + str(drain_y)) grass.run_command('r.drain', overwrite=True, flags="ad", input=costmap2, indir=costdir2, output = lcpmap2, start_coordinates = drain_onecoord) rastinfo = grass.raster_info(lcpmap2) costdict2[drainpoint] = rescoefficient * rastinfo['min'] # Finally create the vector layer with all paths from the current point. It also (whether we want it or not) creates a raster output if len(drainlist1) > 0: lcp1 = grass.start_command('r.drain', overwrite=True, flags="d", input=costmap1, indir=costdir1, output = lcpmap1, vector_output = vectdrain1,start_coordinates=drain_coords1) if p2 and (len(drainlist2) > 0): lcp2 = grass.start_command('r.drain', overwrite=True, flags="d", input=costmap2, indir=costdir2, output = lcpmap2, vector_output = vectdrain2,start_coordinates=drain_coords2) # If raster output is needed, but path maps have not been made yet (i.e. vectout must be False) then make those if not vectout and (len(drainlist1) > 0): lcp1 = grass.start_command('r.drain', overwrite=True, flags="d", input=costmap1, indir=costdir1, output = lcpmap1, start_coordinates=drain_coords1) if p2 and (len(drainlist2) > 0): lcp2 = grass.start_command('r.drain', overwrite=True, flags="d", input=costmap2, indir=costdir2, output = lcpmap2, start_coordinates=drain_coords2) # Wait for the lcp processes to finish lcp1.wait() lcp2.wait() # If raster output is needed, do the mapcalc stuff: merge the path rasters if rastout: if len(drainlist1) == 0: lcpmap1 = 0 if len(drainlist2) == 0: lcpmap2 = 0 if cat1 == points_cats[0]: # If it's the very first iteration if p2: # Technically this should not be False in any situation, but let it be here for additional safety # Add lcpmap1 and lcpmap2 together mapcalc = grass.mapcalc_start("$outmap = if(isnull($tempmap1),0,1) + if(isnull($tempmap2),0,1)", outmap = rastout, tempmap1 = lcpmap1, tempmap2 = lcpmap2, overwrite=True) else: # Just in case mapcalc = grass.mapcalc_start("$outmap = if(isnull($tempmap1),0,1)", outmap = rastout, tempmap1 = lcpmap1, overwrite=True) else: # Rename the cumulative lcp map from previous iteration so that mapcalc can use it (x=x+y logic doesn't work with mapcalc) grass.run_command('g.rename', rast = rastout + ',' + lcptemp, overwrite=True) # rastout = Previous LCP + Current LCP if p2: mapcalc = grass.mapcalc_start("$outmap = $inmap + if(isnull($tempmap1),0,1) + if(isnull($tempmap2),0,1)", inmap = lcptemp, outmap = rastout, tempmap1 = lcpmap1, tempmap2 = lcpmap2) else: mapcalc = grass.mapcalc_start("$outmap = $inmap + if(isnull($tempmap1),0,1)", inmap = lcptemp, outmap = rastout, tempmap1 = lcpmap1) # If vector output is needed, do all necessary things like merging the vectors and getting values for attribute table (if specified) if vectout: if costatt == "e": # Only if cost attributes are needed if len(drainlist1) > 0: # Process 1 # Add attribute table to the vector path layer grass.run_command('v.db.addtable', map = vectdrain1) # Get path Euclidean distances and add them to the new column in attribute table. Also add the current point cat to the attribute "from_point" grass.run_command('v.db.addcolumn', map = vectdrain1, columns = "length double precision, from_point int, to_point int, cost double precision") grass.run_command('v.to.db', map = vectdrain1, type = "line", option = "length", columns = "length") grass.run_command('v.db.update', map = vectdrain1, column = "from_point", value = str(cat1)) # Same as previous section but for process 2 if p2 and (len(drainlist2) > 0): grass.run_command('v.db.addtable', map = vectdrain2) grass.run_command('v.db.addcolumn', map = vectdrain2, columns = "length double precision, from_point int, to_point int, cost double precision") grass.run_command('v.to.db', map = vectdrain2, type = "line", option = "length", columns = "length") grass.run_command('v.db.update', map = vectdrain2, column = "from_point", value = str(cat2)) # A loop to update the path attribute values to the attribute table if len(drainlist1) > 0: drainseq = 1 # This is just a helper counter because for newly created vector layer the cats start from 1 and just go successively, so no need to introduce any unnecessary catlist for drainpoint in drainlist1: # Update to_point column with values from drainlist grass.run_command('v.db.update', map = vectdrain1, column = "to_point", value = str(drainpoint), where = "cat = " + str(drainseq)) # Update the cost column using costdict created earlier grass.run_command('v.db.update', map = vectdrain1, column = "cost", value = costdict1[drainpoint], where = "cat = " + str(drainseq)) drainseq += 1 # The same for process 2 if p2 and (len(drainlist2) > 0): drainseq = 1 # Reset the counter for drainpoint in drainlist2: grass.run_command('v.db.update', map = vectdrain2, column = "to_point", value = str(drainpoint), where = "cat = " + str(drainseq)) grass.run_command('v.db.update', map = vectdrain2, column = "cost", value = costdict2[drainpoint], where = "cat = " + str(drainseq)) drainseq += 1 # Patch vector layers # For both processes, first make sure that drainlists for current iteration are not empty. If they are not (i.e. the drainlist for current iteration > 0), then drain vectors will be used in v.patch, otherwise empty strings will be used in patching. This is to make sure that vectors from previous iterations are not used. if len(drainlist1) > 0: vect1 = vectdrain1 else: vect1 = "" if len(drainlist2) > 0: vect2 = vectdrain2 else: vect2 = "" # If BOTH drain processes resulted in vectors, create a comma character to be used in v.patch (input parameter must be a string type and layers should be separated by comma) if (len(drainlist1) > 0) and (len(drainlist2) > 0): comma = "," else: comma = "" # Finally do the patching if cat1 == points_cats[0]: # If it's the very first iteration if p2: # If iteration has 2 points grass.run_command('v.patch', overwrite = True, flags=costatt, input = vect1 + comma + vect2, output = vectout) else: # Technically this should never be called (because not having 2 points per iteration can happen only for the very last iteration), but I'll leave it here just in case or for future reference grass.run_command('g.rename', overwrite = True, vect = vect1 + "," + vectout) else: if grass.find_file(vectout, element='vector')['name']: # Check whether vectout exists or not (this can happen when the first iteration did not produce any vectors, i.e. search radius was too small). If it does exist, add "a" (append) flag to v.patch, otherwise omit it. append = costatt + "a" else: append = costatt # Choose between two patching scenarios: 1 or 2 process versions. if p2: grass.run_command('v.patch', overwrite = True, flags=append, input = vect1 + comma + vect2, output = vectout) else: grass.run_command('v.patch', overwrite = True, flags=append, input = vect1, output = vectout) # Make 0 values of raster into NULLs if rastout: mapcalc.wait() nullproc = grass.run_command('r.null', map = rastout, setnull = "0") grass.message("All done!")
def main(): map = options['map'] nlines = options['lines'] rast = options['raster'] omit = flags['n'] flip = flags['f'] smooth = flags['s'] #for -n flag of d.legend if not grass.find_file(map)['file']: grass.fatal(_("Raster map <%s> not found") % map) # for rast= if rast and not grass.find_file(rast)['file']: grass.fatal(_("Raster map <%s> not found") % rast) s = grass.read_command('d.info', flags = 'f') if not s: sys.exit(1) f = tuple([float(x) for x in s.split()[1:5]]) grass.run_command('d.erase') os.environ['GRASS_PNG_READ'] = 'TRUE' #draw title # set vertical divide at 65 instead of 80 if real labels in cats/ file?? make_frame(f, 90, 100, 70, 100) # use map name without mapset suffix mapname = map.split('@')[0] grass.run_command('d.text', color='black', size=5, at='5,97', align='cl', text=mapname) #draw legend # set legend vertical position and size based on number of categories cats = grass.read_command('r.describe', map=map, flags = '1n') ncats = len(cats.strip().split('\n')) # Only need to adjust legend size if number of categories is between 1 and 10 if ncats < 2: ncats = 2 if ncats > 10: ncats = 10 VSpacing = (100 - (ncats * 10) + 10) if not nlines: nlines = None if rast: lmap = rast else: lmap = map kv = grass.raster_info(map = lmap) if kv['datatype'] is 'CELL': leg_at = None else: leg_at = '%f,95,5,10' %VSpacing # checking for histogram causes more problems than it solves # histfiledir = grass.find_file(lmap, 'cell_misc')['file'] # has_hist = os.path.isfile(os.path.join(histfiledir, 'histogram')) lflags = '' if flip: lflags += 'f' if omit: lflags += 'n' if smooth: lflags += 's' # if has_hist or omit: # lflags += 'n' make_frame(f, 0, 90, 70, 100) grass.run_command('d.legend', flags = lflags, rast = lmap, lines = nlines, at = leg_at) #draw map make_frame(f, 0, 100, 0, 70) grass.run_command('d.rast', map = map)
def main(): map = options["map"] nlines = options["lines"] rast = options["raster"] omit = flags["n"] flip = flags["f"] smooth = flags["s"] # for -n flag of d.legend if not grass.find_file(map)["file"]: grass.fatal(_("Raster map <%s> not found") % map) # for rast= if rast and not grass.find_file(rast)["file"]: grass.fatal(_("Raster map <%s> not found") % rast) s = grass.read_command("d.info", flags="f") if not s: sys.exit(1) # fixes trunk r64459 s = s.split(":")[1] f = tuple([float(x) for x in s.split()]) grass.run_command("d.erase") os.environ["GRASS_RENDER_FILE_READ"] = "TRUE" # draw title # set vertical divide at 65 instead of 80 if real labels in cats/ file?? make_frame(f, 90, 100, 70, 100) # use map name without mapset suffix mapname = map.split("@")[0] grass.run_command("d.text", color="black", size=5, at="5,97", align="cl", text=mapname) # draw legend # set legend vertical position and size based on number of categories cats = grass.read_command("r.describe", map=map, flags="1n") ncats = len(cats.strip().split("\n")) # Only need to adjust legend size if number of categories is between 1 and 10 if ncats < 2: ncats = 2 if ncats > 10: ncats = 10 VSpacing = 100 - (ncats * 10) + 10 if not nlines: nlines = None if rast: lmap = rast else: lmap = map kv = grass.raster_info(map=lmap) if kv["datatype"] is "CELL": leg_at = None else: leg_at = "%f,95,5,10" % VSpacing # checking for histogram causes more problems than it solves # histfiledir = grass.find_file(lmap, 'cell_misc')['file'] # has_hist = os.path.isfile(os.path.join(histfiledir, 'histogram')) lflags = "" if flip: lflags += "f" if omit: lflags += "n" if smooth: lflags += "s" # if has_hist or omit: # lflags += 'n' make_frame(f, 0, 90, 70, 100) grass.run_command("d.legend", flags=lflags, raster=lmap, lines=nlines, at=leg_at) # draw map make_frame(f, 0, 100, 0, 70) grass.run_command("d.rast", map=map)
def multiscalesmooth(input, smooth, sd, alpha=0.05): chisqa = (2.807 - 0.6422 * math.log10(alpha) - 3.410 * math.pow(alpha, 0.3411)) chisqb = (-5.871 - 3.675 * math.log10(alpha) + 4.690 * math.pow(alpha, 0.3377)) gs.message("Preparing initial grids", flag='i') # create copy of initial grid of values using current region gs.mapcalc('z0 = ${input}', input=input, quiet=True) tmp_rast.add('z0') # set number of aggregation levels and neighborhood size NUM_LEVELS = 4 NUM_CELLS = 3 # expand region to accommodate integer number of cells at coarsest # level, by adding roungly equal number of cells on either side # (with one extra on top/right if an odd number of cells is needed) max_size = NUM_CELLS**NUM_LEVELS region = gs.region() extra = region['cols'] % max_size if (0 < extra): addx = (max_size-extra)/2.0 else: addx = 0.0 extra = region['rows'] % max_size if (0 < extra): addy = (max_size-extra)/2.0 else: addy = 0.0 gs.run_command('g.region', flags='a', w = region['w'] - math.floor(addx) * region['ewres'], e = region['e'] + math.ceil(addx) * region['ewres'], s = region['s'] - math.floor(addy) * region['nsres'], n = region['n'] + math.ceil(addy) * region['nsres']) gs.debug('\n'.join(gs.parse_command('g.region', 'up').keys())) # create initial grid of variances; sd can be a raster or a constant gs.mapcalc('v0 = if(isnull(z0), null(), ${sd}^2)', sd=sd, quiet=True) tmp_rast.add('v0') # set initial "group variance" to individual msmt variance (noise) gs.run_command('g.copy', rast='v0,v.g') tmp_rast.add('v.g') # weights for aggregation, based on total variance gs.mapcalc('w = if(isnull(v0), 0, 1/v0)', quiet=True) tmp_rast.add('w') # squared weights gs.mapcalc('wsq = w^2', quiet=True) tmp_rast.add('wsq') # effective number of measurements gs.mapcalc('n = if(isnull(z0), 0, 1)', quiet=True) tmp_rast.add('n') # aggregate to broader scales for j in range(NUM_LEVELS): i = j + 1 gs.message('Aggregating from %d to %d' % (j, i), flag='i') gs.debug(_('Region dimensions: %d x %d' % (gs.region()['rows'], gs.region()['cols']))) # rename previous (finer scale) weights grid gs.run_command('g.rename', rast='w,w.finer', overwrite=True, quiet=True) tmp_rast.add('w.finer') # calc neighborhood weights, num cells, effective num cells coarsen_region() gs.run_command('r.resamp.stats', method='sum', input='w.finer', output='w', quiet=True) gs.run_command('r.resamp.stats', method='sum', input='wsq', output='wsq', overwrite=True, quiet=True) gs.run_command('r.resamp.stats', method='sum', input='n', output='n', overwrite=True, quiet=True) # calc variance-weighted neighborhood mean refine_region() gs.mapcalc('tmp = w.finer * z%d / w' % j, quiet=True, overwrite=True) tmp_rast.add('tmp') coarsen_region() gs.run_command('r.resamp.stats', method='sum', input='tmp', output='z%d' % i, quiet=True) tmp_rast.add('z%d' % i) # calc between-cell variance, taken over neighborhood refine_region() gs.mapcalc('tmp = w.finer * (z%d - z%d)^2 / w' % (j, i), quiet=True, overwrite=True) tmp_rast.add('tmp') coarsen_region() gs.run_command('r.resamp.stats', method='sum', input='tmp', output='v.bg', overwrite=True, quiet=True) tmp_rast.add('v.bg') # calc wtd avg of within-cell variance, taken over neighborhood if (i==1): gs.mapcalc('v.wg = 0', quiet=True, overwrite=True) tmp_rast.add('v.wg') else: refine_region() gs.mapcalc('tmp = w.finer * v.g / w', quiet=True, overwrite=True) tmp_rast.add('tmp') coarsen_region() gs.run_command('r.resamp.stats', method='sum', input='tmp', output='v.wg', overwrite=True, quiet=True) # calc total group variance # ~= total variance of cell vals in the underlying neighborhood gs.mapcalc('v.g = v.bg + v.wg', quiet=True, overwrite=True) tmp_rast.add('v.g') # calc chisq critical values (where df = n.eff - 1) gs.mapcalc('chisq = 1 + ${chisqa}/sqrt(${df}) + ${chisqb}/${df}', chisqa=chisqa, chisqb=chisqb, df='(w^2/wsq - 1)', quiet=True) tmp_rast.add('chisq') # set coarsened cell variances: if group variance is small # relative to noise variance (mean of finer scale variances), # use variance of neighborhood mean instead of group variance gs.mapcalc('v%d = if(v.g/chisq < ${mv}, ${vm}, v.g)' % i, vm = '(1.0/w)', mv = '(n/w)', quiet=True) tmp_rast.add('v%d' % i) # get arbitrarily large value to fill null variance cells bigvar = gs.raster_info('v0')['max'] * 10 # prep for refinement phase gs.run_command('g.rename', rast='z%d,%s' % (NUM_LEVELS, smooth), quiet=True) tmp_rast.remove('z%d' % NUM_LEVELS) gs.run_command('g.rename', rast='v%d,v.smooth' % NUM_LEVELS, quiet=True) tmp_rast.add('v.smooth') tmp_rast.remove('v%d' % NUM_LEVELS) # refine, smooth, and combine each layer in turn for j in reversed(range(NUM_LEVELS)): i = j + 1 gs.message('Refining from %d to %d' % (i, j), flag='i') # create smoothed higher resolution versions of z and v # using weight matrix equivalent to ArcGIS circle with radius 2 refine_region() gs.run_command('r.neighbors', flags='ac', input=smooth, output='zs', method='average', size=5, overwrite=True, quiet=True) tmp_rast.add('zs') gs.run_command('r.neighbors', flags='ac', input='v.smooth', output='vs', method='average', size=5, overwrite=True, quiet=True) tmp_rast.add('vs') # combine two levels using least variance, using no-null # versions of finer z and v z_c = 'if(isnull(z%d), 0, z%d)' % (j, j) v_c = 'if(isnull(v%d), %f, v%d)' % (j, bigvar, j) gs.mapcalc('${smooth} = (${z_c}/${v_c} + zs/vs) / (1/${v_c} + 1/vs)', smooth=smooth, z_c=z_c, v_c=v_c, quiet=True, overwrite=True) gs.mapcalc('v.smooth = 1 / (1/${v_c} + 1/vs)', v_c = v_c, quiet=True, overwrite=True) cleanup() return None
def __init__(self,**optionsandflags): '''Process all arguments and prepare processing''' # add all options and flags as attributes (only nonempty ones) self.options = {} for o in optionsandflags: if optionsandflags[o]!='': self.options[o] = optionsandflags[o] self.__dict__.update(self.options) # dictionary of maps where the value will be averaged over all hydrotopes self.floatmaps = {} # default columns self.strcolumns = [self.subbasins,self.landuse, self.soil] # managment and wetland for r in ['management','wetland']: self.__dict__[r] = self._maskOrBlank(r) self.strcolumns += [self.__dict__[r]] # check contours and create raster if needed if 'contours' in self.options: try: self.contours = map(int,self.contours.split(',')) if len(self.contours)==1: self.contours = self.contours[0] except: grass.fatal(('''Contours should be either an interval [integer] or a list of breaks separated by commas.''')) # create contourrast self.mkContours() else: self.contourrast = self._maskOrBlank('contourrast') # add to columns self.strcolumns += [self.contourrast] self.floatmaps[self.contourrast] = self.elevation # glaciers self.glaciers = self._maskOrBlank('glaciers') self.strcolumns += [self.glaciers] # other raster to include? if 'more' in self.options: self.more = self.more.split(',') self.strcolumns += self.more # check if all input maps are int/CELL maps gm('Check if all input are integer raster...') for m in self.strcolumns: if grass.raster_info(m)['datatype']!='CELL': grass.fatal('%s is not an integer/CELL raster, convert using int() in r.mapcalc' %m) # check that all input maps have no NULLs in catchment over subbasins area g_run('r.mask',raster=self.subbasins,overwrite=True) gm('Checking for NULLs in input maps...') pow2 = 2**np.arange(len(self.strcolumns)) ifnull = ' + '.join(['isnull(%s)*%s' %(m,i) for m,i in zip(self.strcolumns,pow2)]) grass.mapcalc('null__areas=%s' %ifnull, overwrite=True) g_run('r.null',map='null__areas',setnull=0,quiet=True) null = grass.parse_command('r.stats',input='null__areas',flags='aN',separator='=') if len(null)>0: gm("In any of the input maps are NULL/no data values over the subbasins area.") gm(" See the null__area raster with this legend including their combinations.") for m,i in zip(self.strcolumns,pow2): gm("%s = %s" %(i,m)) gm('null__area area [km2]') for m in sorted(null.keys()): gm("%s %s" %(m,float(null[m])*10**-6)) gm("How should they appear in the .str file?") gm("Set them with r.null") grass.fatal('Exiting!') g_run('r.mask', flags='r', quiet=True) return
def InitRasterPairs(self, rasterList, plottype): """Initialize or update raster dictionary with raster pairs for bivariate scatterplots """ if len(rasterList) == 0: return rdict = {} # initialize a dictionary for rpair in rasterList: idx = rasterList.index(rpair) try: ret0 = grass.raster_info(rpair[0]) ret1 = grass.raster_info(rpair[1]) except: continue # if r.info cannot parse map, skip it self.raster[rpair] = UserSettings.Get(group = plottype, key = 'rasters') # some default settings rdict[rpair] = {} # initialize sub-dictionaries for each raster in the list rdict[rpair][0] = {} rdict[rpair][1] = {} rdict[rpair][0]['units'] = '' rdict[rpair][1]['units'] = '' if ret0['units'] not in ('(none)', '"none"', '', None): rdict[rpair][0]['units'] = ret0['units'] if ret1['units'] not in ('(none)', '"none"', '', None): rdict[rpair][1]['units'] = ret1['units'] rdict[rpair]['plegend'] = rpair[0].split('@')[0] + ' vs ' + rpair[1].split('@')[0] rdict[rpair]['datalist'] = [] # list of cell value,frequency pairs for plotting histogram rdict[rpair][0]['datatype'] = ret0['datatype'] rdict[rpair][1]['datatype'] = ret1['datatype'] # #initialize with saved values # if self.properties['raster']['ptype'] != None and \ self.properties['raster']['ptype'] != '': rdict[rpair]['ptype'] = self.properties['raster']['ptype'] else: rdict[rpair]['ptype'] = 'dot' if self.properties['raster']['psize'] != None: rdict[rpair]['psize'] = self.properties['raster']['psize'] else: rdict[rpair]['psize'] = 1 if self.properties['raster']['pfill'] != None and \ self.properties['raster']['pfill'] != '': rdict[rpair]['pfill'] = self.properties['raster']['pfill'] else: rdict[rpair]['pfill'] = 'solid' if idx <= len(self.colorList): rdict[rpair]['pcolor'] = self.colorDict[self.colorList[idx]] else: r = randint(0, 255) b = randint(0, 255) g = randint(0, 255) rdict[rpair]['pcolor'] = ((r,g,b,255)) return rdict
def main(): pan = options['pan'] msxlst = options['msx'].split(',') outputsuffix = options['suffix'] custom_ratio = options['ratio'] center = options['center'] center2 = options['center2'] modulation = options['modulation'] modulation2 = options['modulation2'] if options['trim']: trimming_factor = float(options['trim']) else: trimming_factor = False histogram_match = flags['l'] second_pass = flags['2'] color_match = flags['c'] # # Check & warn user about "ns == ew" resolution of current region ====== # region = grass.region() # nsr = region['nsres'] # ewr = region['ewres'] # # if nsr != ewr: # msg = ('>>> Region's North:South ({ns}) and East:West ({ew}) ' # 'resolutions do not match!') # msg = msg.format(ns=nsr, ew=ewr) # grass.message(msg, flag='w') mapset = grass.gisenv()['MAPSET'] # Current Mapset? region = grass.region() # and region settings # List images and their properties # pygrass.raster.abstract.Info can not cope with # Info(name@mapset, mapset) # -> fully qualified names and input images from other mapsets are # not supported # -> use r.info via raster_info imglst = [pan] imglst.extend(msxlst) # List of input imagery images = {} for img in imglst: # Retrieving Image Info # images[img] = Info(img, mapset) # images[img].read() try: images[img] = grass.raster_info(img) except: grass.fatal(_("msx input not found")) panres = images[pan]['nsres'] # Panchromatic resolution grass.use_temp_region() # to safely modify the region if flags['a']: run('g.region', align=pan) # Respect extent, change resolution else: run('g.region', res=panres) # Respect extent, change resolution grass.message( "|! Region's resolution matched to Pan's ({p})".format(p=panres)) # Loop Algorithm over Multi-Spectral images for msx in msxlst: grass.message("\nProcessing image: {m}".format(m=msx)) # Tracking command history -- Why don't do this all r.* modules? cmd_history = [] # # 1. Compute Ratio # grass.message("\n|1 Determining ratio of low to high resolution") # Custom Ratio? Skip standard computation method. if custom_ratio: ratio = float(custom_ratio) grass.warning('Using custom ratio, overriding standard method!') # Multi-Spectral resolution(s), multiple else: # Image resolutions grass.message(" > Retrieving image resolutions") msxres = images[msx]['nsres'] # check if panres == msxres: msg = ("The Panchromatic's image resolution ({pr}) " "equals to the Multi-Spectral's one ({mr}). " "Something is probably not right! " "Please check your input images.") msg = msg.format(pr=panres, mr=msxres) grass.fatal(_(msg)) # compute ratio ratio = msxres / panres msg_ratio = (' >> Resolution ratio ' 'low ({m:.{dec}f}) to high ({p:.{dec}f}): {r:.1f}') msg_ratio = msg_ratio.format(m=msxres, p=panres, r=ratio, dec=3) grass.message(msg_ratio) # 2nd Pass requested, yet Ratio < 5.5 if second_pass and ratio < 5.5: grass.message( " >>> Resolution ratio < 5.5, skipping 2nd pass.\n" " >>> If you insist, force it via the <ratio> option!", flag='i') second_pass = bool(0) # # 2. High Pass Filtering # grass.message('\n|2 High Pass Filtering the Panchromatic Image') tmpfile = grass.tempfile() # Temporary file - replace with os.getpid? tmp = 'tmp.' + grass.basename(tmpfile) # use its basename tmp_pan_hpf = '{tmp}_pan_hpf'.format(tmp=tmp) # HPF image tmp_msx_blnr = '{tmp}_msx_blnr'.format(tmp=tmp) # Upsampled MSx tmp_msx_hpf = '{tmp}_msx_hpf'.format(tmp=tmp) # Fused image tmp_msx_mapcalc = tmp_msx_hpf + '_mapcalc' tmp_hpf_matrix = grass.tempfile() # ASCII filter # Construct and apply Filter hpf = get_high_pass_filter(ratio, center) hpf_ascii(center, hpf, tmp_hpf_matrix, second_pass) run('r.mfilter', input=pan, filter=tmp_hpf_matrix, output=tmp_pan_hpf, title='High Pass Filtered Panchromatic image', overwrite=True) # 2nd pass if second_pass and ratio > 5.5: # Temporary files # 2nd Pass HPF image tmp_pan_hpf_2 = '{tmp}_pan_hpf_2'.format(tmp=tmp) # 2nd Pass ASCII filter tmp_hpf_matrix_2 = grass.tempfile() # Construct and apply 2nd Filter hpf_2 = get_high_pass_filter(ratio, center2) hpf_ascii(center2, hpf_2, tmp_hpf_matrix_2, second_pass) run('r.mfilter', input=pan, filter=tmp_hpf_matrix_2, output=tmp_pan_hpf_2, title='2-High-Pass Filtered Panchromatic Image', overwrite=True) # # 3. Upsampling low resolution image # grass.message("\n|3 Upsampling (bilinearly) low resolution image") run('r.resamp.interp', method='bilinear', input=msx, output=tmp_msx_blnr, overwrite=True) # # 4. Weighting the High Pass Filtered image(s) # grass.message("\n|4 Weighting the High-Pass-Filtered image (HPFi)") # Compute (1st Pass) Weighting msg_w = " > Weighting = StdDev(MSx) / StdDev(HPFi) * " \ "Modulating Factor" grass.message(msg_w) # StdDev of Multi-Spectral Image(s) msx_avg = avg(msx) msx_sd = stddev(msx) grass.message(" >> StdDev of <{m}>: {sd:.3f}".format(m=msx, sd=msx_sd)) # StdDev of HPF Image hpf_sd = stddev(tmp_pan_hpf) grass.message(" >> StdDev of HPFi: {sd:.3f}".format(sd=hpf_sd)) # Modulating factor modulator = get_modulator_factor(modulation, ratio) grass.message(" >> Modulating Factor: {m:.2f}".format(m=modulator)) # weighting HPFi weighting = hpf_weight(msx_sd, hpf_sd, modulator, 1) # # 5. Adding weighted HPF image to upsampled Multi-Spectral band # grass.message("\n|5 Adding weighted HPFi to upsampled image") fusion = '{hpf} = {msx} + {pan} * {wgt}' fusion = fusion.format(hpf=tmp_msx_hpf, msx=tmp_msx_blnr, pan=tmp_pan_hpf, wgt=weighting) grass.mapcalc(fusion) # command history hst = 'Weigthing applied: {msd:.3f} / {hsd:.3f} * {mod:.3f}' cmd_history.append(hst.format(msd=msx_sd, hsd=hpf_sd, mod=modulator)) if second_pass and ratio > 5.5: # # 4+ 2nd Pass Weighting the High Pass Filtered image # grass.message("\n|4+ 2nd Pass Weighting the HPFi") # StdDev of HPF Image #2 hpf_2_sd = stddev(tmp_pan_hpf_2) grass.message( " >> StdDev of 2nd HPFi: {h:.3f}".format(h=hpf_2_sd)) # Modulating factor #2 modulator_2 = get_modulator_factor2(modulation2) msg = ' >> 2nd Pass Modulating Factor: {m:.2f}' grass.message(msg.format(m=modulator_2)) # 2nd Pass weighting weighting_2 = hpf_weight(msx_sd, hpf_2_sd, modulator_2, 2) # # 5+ Adding weighted HPF image to upsampled Multi-Spectral band # grass.message("\n|5+ Adding small-kernel-based weighted " "2nd HPFi back to fused image") add_back = '{final} = {msx_hpf} + {pan_hpf} * {wgt}' # r.mapcalc: do not use input as output add_back = add_back.format(final=tmp_msx_mapcalc, msx_hpf=tmp_msx_hpf, pan_hpf=tmp_pan_hpf_2, wgt=weighting_2) grass.mapcalc(add_back) run('g.remove', flags="f", type="raster", name=tmp_msx_hpf) run("g.rename", raster=(tmp_msx_mapcalc, tmp_msx_hpf)) # 2nd Pass history entry hst = "2nd Pass Weighting: {m:.3f} / {h:.3f} * {mod:.3f}" cmd_history.append( hst.format(m=msx_sd, h=hpf_2_sd, mod=modulator_2)) # # 6. Stretching linearly the HPF-Sharpened image(s) to match the Mean # and Standard Deviation of the input Multi-Sectral image(s) # if histogram_match: # adapt output StdDev and Mean to the input(ted) ones # technically, this is not histogram matching but # normalizing to the input's mean + stddev grass.message("\n|+ Matching histogram of Pansharpened image " "to %s" % (msx)) # Collect stats for linear histogram matching msx_hpf_avg = avg(tmp_msx_hpf) msx_hpf_sd = stddev(tmp_msx_hpf) msx_info = images[msx] outfn = 'round' if msx_info['datatype'] == 'FCELL': outfn = 'float' elif msx_info['datatype'] == 'DCELL': outfn = 'double' # expression for mapcalc lhm = "{out} = {outfn}(double({hpf} - {hpfavg}) / {hpfsd} * " \ "{msxsd} + {msxavg})" # r.mapcalc: do not use input as output lhm = lhm.format(out=tmp_msx_mapcalc, outfn=outfn, hpf=tmp_msx_hpf, hpfavg=msx_hpf_avg, hpfsd=msx_hpf_sd, msxsd=msx_sd, msxavg=msx_avg) # compute grass.mapcalc(lhm, quiet=True, overwrite=True) run('g.remove', flags="f", type="raster", name=tmp_msx_hpf) run("g.rename", raster=(tmp_msx_mapcalc, tmp_msx_hpf)) # snap outliers to input range snapout = "{out} = {outfn}(if({hpf} < {oldmin}, {oldmin}, " \ "if({hpf} > {oldmax}, {oldmax}, {hpf})))" snapout = snapout.format(out=tmp_msx_mapcalc, outfn=outfn, hpf=tmp_msx_hpf, oldmin=msx_info['min'], oldmax=msx_info['max']) grass.mapcalc(snapout, quiet=True, overwrite=True) run('g.remove', flags="f", type="raster", name=tmp_msx_hpf) run("g.rename", raster=(tmp_msx_mapcalc, tmp_msx_hpf)) # update history string cmd_history.append("Linear Histogram Matching: %s" % lhm) else: # scale result to input using quantiles grass.message("\n|+ Quantile scaling of Pansharpened image " "to %s" % (msx)) msx_info = images[msx] outfn = 'round' if msx_info['datatype'] == 'FCELL': outfn = 'float' elif msx_info['datatype'] == 'DCELL': outfn = 'double' # quantile scaling percentiles = "10,50,90" allq = grass.read_command('r.quantile', input=msx, percentiles=percentiles, quiet=True) allq = allq.splitlines() msx_plo = float(allq[0].split(':')[2]) msx_med = float(allq[1].split(':')[2]) msx_phi = float(allq[2].split(':')[2]) allq = grass.read_command('r.quantile', input=tmp_msx_hpf, percentiles=percentiles, quiet=True) allq = allq.splitlines() hpf_plo = float(allq[0].split(':')[2]) hpf_med = float(allq[1].split(':')[2]) hpf_phi = float(allq[2].split(':')[2]) # scale factors sfplo = (msx_med - msx_plo) / (hpf_med - hpf_plo) sfphi = (msx_phi - msx_med) / (hpf_phi - hpf_med) scale = "{out} = {outfn}(double({hpf} - {hpf_med}) * " \ "if({hpf} < {hpf_med}, {sfplo}, " \ "{sfphi}) + {msx_med})" scale = scale.format(out=tmp_msx_mapcalc, outfn=outfn, hpf=tmp_msx_hpf, hpf_med=hpf_med, sfplo=sfplo, sfphi=sfphi, msx_med=msx_med) grass.mapcalc(scale, quiet=True) run('g.remove', flags="f", type="raster", name=tmp_msx_hpf) run("g.rename", raster=(tmp_msx_mapcalc, tmp_msx_hpf)) # snap outliers to input range snapout = "{out} = {outfn}(if({hpf} < {oldmin}, {oldmin}, " \ "if({hpf} > {oldmax}, {oldmax}, {hpf})))" snapout = snapout.format(out=tmp_msx_mapcalc, outfn=outfn, hpf=tmp_msx_hpf, oldmin=msx_info['min'], oldmax=msx_info['max']) grass.mapcalc(snapout, quiet=True, overwrite=True) run('g.remove', flags="f", type="raster", name=tmp_msx_hpf) run("g.rename", raster=(tmp_msx_mapcalc, tmp_msx_hpf)) # update history string cmd_history.append("Linear Scaling: %s" % scale) if color_match: grass.message("\n|* Matching output to input color table") run('r.colors', map=tmp_msx_hpf, raster=msx) # # Optional. Trim to remove black border effect (rectangular only) # if trimming_factor: tf = trimming_factor # communicate msg = '\n|* Trimming output image border pixels by ' msg += '{factor} times the low resolution\n'.format(factor=tf) nsew = ' > Input extent: n: {n}, s: {s}, e: {e}, w: {w}' nsew = nsew.format(n=region['n'], s=region['s'], e=region['e'], w=region['w']) msg += nsew grass.message(msg) # re-set borders region.n -= tf * images[msx]['nsres'] region.s += tf * images[msx]['nsres'] region.e -= tf * images[msx]['ewres'] region.w += tf * images[msx]['ewres'] # communicate and act msg = ' > Output extent: n: {n}, s: {s}, e: {e}, w: {w}' msg = msg.format(n=region['n'], s=region['s'], e=region['e'], w=region['w']) grass.message(msg) # modify only the extent run('g.region', n=region['n'], s=region['s'], e=region['e'], w=region['w']) # r.mapcalc: do not use input as output trim = "{out} = {input}".format(out=tmp_msx_mapcalc, input=tmp_msx_hpf) grass.mapcalc(trim) run('g.remove', flags="f", type="raster", name=tmp_msx_hpf) run("g.rename", raster=(tmp_msx_mapcalc, tmp_msx_hpf)) # # End of Algorithm # history entry run("r.support", map=tmp_msx_hpf, history="\n".join(cmd_history)) # add suffix to basename & rename end product msx_name = "{base}{suffix}" msx_name = msx_name.format(base=msx.split('@')[0], suffix=outputsuffix) run("g.rename", raster=(tmp_msx_hpf, msx_name)) # remove temporary files cleanup() # visualising-related information grass.del_temp_region() # restoring previous region settings grass.message("\n|! Original Region restored") grass.message( "\n>>> Hint, rebalancing colors (via i.colors.enhance) " "may improve appearance of RGB composites!", flag='i')
def main(): global TMPLOC, SRCGISRC, GISDBASE, TMP_REG_NAME GDALdatasource = options['input'] output = options['output'] method = options['resample'] memory = options['memory'] bands = options['band'] tgtres = options['resolution'] title = options["title"] if options['resolution_value']: if tgtres != 'value': grass.fatal(_("To set custom resolution value, select 'value' in resolution option")) tgtres_value = float(options['resolution_value']) if tgtres_value <= 0: grass.fatal(_("Resolution value can't be smaller than 0")) elif tgtres == 'value': grass.fatal(_("Please provide the resolution for the imported dataset or change to 'estimated' resolution")) grassenv = grass.gisenv() tgtloc = grassenv['LOCATION_NAME'] tgtmapset = grassenv['MAPSET'] GISDBASE = grassenv['GISDBASE'] tgtgisrc = os.environ['GISRC'] SRCGISRC = grass.tempfile() TMPLOC = 'temp_import_location_' + str(os.getpid()) f = open(SRCGISRC, 'w') f.write('MAPSET: PERMANENT\n') f.write('GISDBASE: %s\n' % GISDBASE) f.write('LOCATION_NAME: %s\n' % TMPLOC) f.write('GUI: text\n') f.close() tgtsrs = grass.read_command('g.proj', flags='j', quiet=True) # create temp location from input without import grass.verbose(_("Creating temporary location for <%s>...") % GDALdatasource) parameters = dict(input=GDALdatasource, output=output, memory=memory, flags='c', title=title, location=TMPLOC, quiet=True) if bands: parameters['band'] = bands try: grass.run_command('r.in.gdal', **parameters) except CalledModuleError: grass.fatal(_("Unable to read GDAL dataset <%s>") % GDALdatasource) # switch to temp location os.environ['GISRC'] = str(SRCGISRC) # switch to target location os.environ['GISRC'] = str(tgtgisrc) # try r.in.gdal directly first additional_flags = 'l' if flags['l'] else '' if flags['o']: additional_flags += 'o' if flags['o'] or grass.run_command('r.in.gdal', input=GDALdatasource, flags='j', errors='status', quiet=True) == 0: parameters = dict(input=GDALdatasource, output=output, memory=memory, flags='k' + additional_flags) if bands: parameters['band'] = bands try: grass.run_command('r.in.gdal', **parameters) grass.verbose(_("Input <%s> successfully imported without reprojection") % GDALdatasource) return 0 except CalledModuleError as e: grass.fatal(_("Unable to import GDAL dataset <%s>") % GDALdatasource) # make sure target is not xy if grass.parse_command('g.proj', flags='g')['name'] == 'xy_location_unprojected': grass.fatal(_("Coordinate reference system not available for current location <%s>") % tgtloc) # switch to temp location os.environ['GISRC'] = str(SRCGISRC) # make sure input is not xy if grass.parse_command('g.proj', flags='g')['name'] == 'xy_location_unprojected': grass.fatal(_("Coordinate reference system not available for input <%s>") % GDALdatasource) # import into temp location grass.verbose(_("Importing <%s> to temporary location...") % GDALdatasource) parameters = dict(input=GDALdatasource, output=output, memory=memory, flags='k' + additional_flags) if bands: parameters['band'] = bands try: grass.run_command('r.in.gdal', **parameters) except CalledModuleError: grass.fatal(_("Unable to import GDAL dataset <%s>") % GDALdatasource) outfiles = grass.list_grouped('raster')['PERMANENT'] # is output a group? group = False path = os.path.join(GISDBASE, TMPLOC, 'group', output) if os.path.exists(path): group = True path = os.path.join(GISDBASE, TMPLOC, 'group', output, 'POINTS') if os.path.exists(path): grass.fatal(_("Input contains GCPs, rectification is required")) # switch to target location os.environ['GISRC'] = str(tgtgisrc) region = grass.region() rflags = None if flags['n']: rflags = 'n' for outfile in outfiles: n = region['n'] s = region['s'] e = region['e'] w = region['w'] grass.use_temp_region() if options['extent'] == 'input': # r.proj -g try: tgtextents = grass.read_command('r.proj', location=TMPLOC, mapset='PERMANENT', input=outfile, flags='g', memory=memory, quiet=True) except CalledModuleError: grass.fatal(_("Unable to get reprojected map extent")) try: srcregion = grass.parse_key_val(tgtextents, val_type=float, vsep=' ') n = srcregion['n'] s = srcregion['s'] e = srcregion['e'] w = srcregion['w'] except ValueError: # import into latlong, expect 53:39:06.894826N srcregion = grass.parse_key_val(tgtextents, vsep=' ') n = grass.float_or_dms(srcregion['n'][:-1]) * \ (-1 if srcregion['n'][-1] == 'S' else 1) s = grass.float_or_dms(srcregion['s'][:-1]) * \ (-1 if srcregion['s'][-1] == 'S' else 1) e = grass.float_or_dms(srcregion['e'][:-1]) * \ (-1 if srcregion['e'][-1] == 'W' else 1) w = grass.float_or_dms(srcregion['w'][:-1]) * \ (-1 if srcregion['w'][-1] == 'W' else 1) grass.run_command('g.region', n=n, s=s, e=e, w=w) # v.in.region in tgt vreg = TMP_REG_NAME = 'vreg_tmp_' + str(os.getpid()) grass.run_command('v.in.region', output=vreg, quiet=True) grass.del_temp_region() # reproject to src # switch to temp location os.environ['GISRC'] = str(SRCGISRC) try: grass.run_command('v.proj', input=vreg, output=vreg, location=tgtloc, mapset=tgtmapset, quiet=True) except CalledModuleError: grass.fatal(_("Unable to reproject to source location")) # set region from region vector grass.run_command('g.region', raster=outfile) grass.run_command('g.region', vector=vreg) # align to first band grass.run_command('g.region', align=outfile) # get number of cells cells = grass.region()['cells'] estres = math.sqrt((n - s) * (e - w) / cells) # remove from source location for multi bands import grass.run_command('g.remove', type='vector', name=vreg, flags='f', quiet=True) os.environ['GISRC'] = str(tgtgisrc) grass.run_command('g.remove', type='vector', name=vreg, flags='f', quiet=True) grass.message(_("Estimated target resolution for input band <{out}>: {res}").format(out=outfile, res=estres)) if flags['e']: continue if options['extent'] == 'input': grass.use_temp_region() grass.run_command('g.region', n=n, s=s, e=e, w=w) res = None if tgtres == 'estimated': res = estres elif tgtres == 'value': res = tgtres_value grass.message(_("Using given resolution for input band <{out}>: {res}").format(out=outfile, res=res)) # align to requested resolution grass.run_command('g.region', res=res, flags='a') else: curr_reg = grass.region() grass.message(_("Using current region resolution for input band " "<{out}>: nsres={ns}, ewres={ew}").format(out=outfile, ns=curr_reg['nsres'], ew=curr_reg['ewres'])) # r.proj grass.message(_("Reprojecting <%s>...") % outfile) try: grass.run_command('r.proj', location=TMPLOC, mapset='PERMANENT', input=outfile, method=method, resolution=res, memory=memory, flags=rflags, quiet=True) except CalledModuleError: grass.fatal(_("Unable to to reproject raster <%s>") % outfile) if grass.raster_info(outfile)['min'] is None: grass.fatal(_("The reprojected raster <%s> is empty") % outfile) if options['extent'] == 'input': grass.del_temp_region() if flags['e']: return 0 if group: grass.run_command('i.group', group=output, input=','.join(outfiles)) # TODO: write metadata with r.support return 0
def run_analyses(settings, analysesFile, update, giface, eventHandler, scanFilter, **kwargs): """Runs all functions in specified Python file which start with 'run_'. The Python file is reloaded every time""" scan_params = settings['tangible']['scan'] scan_name = settings['tangible']['output']['scan'] if scanFilter['filter']: try: info = gscript.raster_info(scan_name + 'tmp') except CalledModuleError: print 'error in r.info' return if scanFilter['debug']: try: print info['max'] - info['min'] except TypeError: # unsupported operand type(s) for -: 'NoneType' and 'NoneType' return threshold = scanFilter['threshold'] if info['max'] - info['min'] > threshold: scanFilter['counter'] += 1 return try: gscript.run_command('g.copy', raster=[scan_name + 'tmp', scan_name], overwrite=True, quiet=True) except CalledModuleError: print 'error copying scanned data from temporary name' return # workaround weird georeferencing # filters cases when extent and elev values are in inconsistent state # probably it reads it before the header is written try: info = gscript.raster_info(scan_name) except CalledModuleError: print 'error in r.info' return try: if (abs(info['north'] - info['south']) / (info['max'] - info['min'])) < 1: return except ZeroDivisionError: return env = get_environment(rast=scan_name) if not analysesFile or not os.path.exists(analysesFile): return # run analyses try: myanalyses = imp.load_source('myanalyses', analysesFile) except StandardError as e: print e return functions = [func for func in dir(myanalyses) \ if (func.startswith('run_') and func != 'run_command') or func.startswith('drawing_')] for func in functions: exec('del myanalyses.' + func) try: myanalyses = imp.load_source('myanalyses', analysesFile) except StandardError as e: print e return # color output color = None if settings['tangible']['output']['color']: color = settings['tangible']['output']['color_name'] # blender path blender_path = None if settings['tangible']['output']['blender']: blender_path = settings['tangible']['output']['blender_path'] # drawing needs different parameters # functions postprocessing drawing results start with 'drawing' # functions postprocessing scanning results start with 'run' if settings['tangible']['drawing']['active']: functions = [func for func in dir(myanalyses) if func.startswith('drawing_')] for func in functions: try: exec('myanalyses.' + func + "(real_elev=scan_params['elevation']," " scanned_elev=scan_name," " blender_path=blender_path," " zexag=scan_params['zexag']," " draw_vector=settings['tangible']['drawing']['name']," " draw_vector_append=settings['tangible']['drawing']['append']," " draw_vector_append_name=settings['tangible']['drawing']['appendName']," " giface=giface, update=update," " eventHandler=eventHandler, env=env, **kwargs)") except (CalledModuleError, StandardError, ScriptError) as e: print traceback.print_exc() else: functions = [func for func in dir(myanalyses) if func.startswith('run_') and func != 'run_command'] for func in functions: try: exec('myanalyses.' + func + "(real_elev=scan_params['elevation']," " scanned_elev=scan_name," " scanned_color=color," " blender_path=blender_path," " zexag=scan_params['zexag']," " giface=giface, update=update," " eventHandler=eventHandler, env=env, **kwargs)") except (CalledModuleError, StandardError, ScriptError) as e: print traceback.print_exc()
def main(): # temporary region gscript.use_temp_region() # set graphics driver driver = "cairo" # set rendering directory render = os.path.normpath("C:/Users/Brendan/Documents/grassdata/rendering/fusion") # set maps highres_dem = "uav_dsm@fusion" lowres_dem = "lidar_dem@fusion" # set parameters overwrite = True tension = 20 smooth = 1 npmin = 80 dmin = 0.3 # assign variables highres_sample = "highres_sample" lowres_sample = "lowres_sample" cover = "cover" fused_points="fused_points" fusion = "fusion" dx = "dx" dy = "dy" # set parameters for resampling info = gscript.raster_info(highres_dem) highres_npoints = int(info.cols) * int(info.rows) / 10 info = gscript.raster_info(lowres_dem) lowres_npoints = int(info.cols) * int(info.rows) / 10 # randomly sample high resolution dem gscript.run_command('g.region', raster=highres_dem) gscript.run_command('r.random', input=highres_dem, npoints=highres_npoints, vector=highres_sample, flags='d', overwrite=overwrite) # set cover map gscript.run_command('g.region', raster=lowres_dem) gscript.run_command('r.mapcalc', expression="{cover} = if(isnull({highres_dem}),{lowres_dem},null())".format(cover=cover, lowres_dem=lowres_dem, highres_dem=highres_dem), overwrite=overwrite) # randomly sample low resolution dem gscript.run_command('g.region', raster=lowres_dem) gscript.run_command('r.random', input=lowres_dem, npoints=lowres_npoints, cover=cover, vector=lowres_sample, flags='d', overwrite=overwrite) # patch gscript.run_command('v.patch', input=(highres_sample,lowres_sample), output=fused_points ,flags='b', overwrite=overwrite) # interpolation with partial derivatives gscript.run_command('v.surf.rst', input=fused_points, elevation=fusion, slope=dx, aspect=dy, tension=tension, smooth=smooth, npmin=npmin, dmin=dmin, flags='d', overwrite=overwrite) gscript.run_command('r.colors', map=fusion, color="elevation") # render elevation gscript.run_command('g.region', raster=lowres_dem) info = gscript.parse_command('r.info', map=fusion, flags='g') relief = "relief" gscript.run_command('d.mon', start=driver, width=info.cols, height=info.rows, output=os.path.join(render,fusion+".png"), overwrite=overwrite) gscript.run_command('r.relief', input=fusion, output=relief, zscale=1, overwrite=overwrite) gscript.run_command('r.colors', map=fusion, color="elevation") gscript.run_command('d.shade', shade=relief, color=fusion, brighten=25) gscript.run_command('d.legend', raster=fusion, at=(5,50,5,7)) gscript.run_command('d.mon', stop=driver) # remove temporary maps gscript.run_command('g.remove', type='vector', name=['highres_sample', 'lowres_sample', 'fused_points'], flags='f') gscript.run_command('g.remove', type='raster', name='cover', flags='f')