def get_extensions(): addon_base = os.getenv('GRASS_ADDON_BASE') if not addon_base: grass.fatal(_("%s not defined") % "GRASS_ADDON_BASE") fXML = os.path.join(addon_base, 'modules.xml') if not os.path.exists(fXML): return [] # read XML file fo = open(fXML, 'r') try: tree = etree.fromstring(fo.read()) except StandardError as e: grass.error(_("Unable to parse metadata file: %s") % e) fo.close() return [] fo.close() libgis_rev = grass.version()['libgis_revision'] ret = list() for tnode in tree.findall('task'): gnode = tnode.find('libgis') if gnode is not None and \ gnode.get('revision', '') != libgis_rev: ret.append(tnode.get('name')) return ret
def create_register_file(self, filename): gs.message(_("Creating register file <{}>...").format(filename)) ip_timestamp = {} for mtd_file in self._filter("MTD_TL.xml"): ip = self._ip_from_path(mtd_file) ip_timestamp[ip] = self._parse_mtd_file(mtd_file)["timestamp"] if not ip_timestamp: gs.warning( _("Unable to determine timestamps. No metadata file found")) sep = "|" with open(filename, "w") as fd: for img_file in self.files: map_name = self._map_name(img_file) ip = self._ip_from_path(img_file) timestamp = ip_timestamp[ip] if timestamp: timestamp_str = timestamp.strftime("%Y-%m-%d %H:%M:%S.%f") else: timestamp_str = "" fd.write("{img}{sep}{ts}".format(img=map_name, sep=sep, ts=timestamp_str)) # Band references/semantic labels available from GRASS GIS 8.0.0 onwards if float(gs.version()["version"][0:3]) >= 7.9: semantic_label = self._extract_semantic_label(map_name) if semantic_label is None: continue fd.write("{sep}{semantic_label}".format( sep=sep, semantic_label=semantic_label)) fd.write("\n")
def get_cache_dir(name): """Get the default user cache directory The name parameter is used to distinguish cache data from different components, e.g., from different modules. The function creates the directory (including all its parent directories) if it does not exist. """ app_version = gs.version()["version"] if sys.platform.startswith("win"): # App name, directory, and the assumption that the directory # should be used are derived from the startup script. # Major version is part of the directory name. app_name = "GRASS{}".format(app_version.split(".", maxsplit=1)[0]) path = Path(os.getenv("APPDATA")) / app_name / "Cache" / name elif sys.platform.startswith("darwin"): app_name = "grass" path = Path( "~/Library/Caches").expanduser() / app_name / app_version / name else: app_name = "grass" # According to XDG Base Directory Specification 0.8: # If $XDG_CACHE_HOME is either not set or empty, a default equal # to $HOME/.cache should be used. env_var = os.getenv("XDG_CACHE_HOME") if env_var: path = Path(env_var) else: path = Path("~/.cache").expanduser() path = path / app_name / app_version / name path.mkdir(parents=True, exist_ok=True) return path
def write_register_file(filenames, register_output): gs.message(_("Creating register file <{}>...").format(register_output)) has_band_ref = float(gs.version()["version"][0:3]) >= 7.9 sep = "|" with open(register_output, "w") as fd: for img_file in filenames: map_name = _map_name(img_file) satellite = map_name.strip()[3] timestamp_str = map_name.split("_")[3] timestamp = datetime.strptime(timestamp_str, "%Y%m%d").strftime("%Y-%m-%d") fd.write("{img}{sep}{ts}".format(img=map_name, sep=sep, ts=timestamp)) if has_band_ref: try: band_ref = re.match(r".*_B([1-9]+).*", map_name).groups() band_ref = band_ref[0] if band_ref[0] else band_ref[1] except AttributeError: gs.warning( _("Unable to determine band reference for <{}>").format( map_name ) ) continue fd.write( "{sep}{br}".format(sep=sep, br="L{}_{}".format(satellite, band_ref)) ) fd.write(os.linesep)
def create_register_file(self, filename): ip_timestamp = {} for mtd_file in self._filter("MTD_TL.xml"): ip = self._ip_from_path(mtd_file) ip_timestamp[ip] = self._read_timestamp_from_mtd_file(mtd_file) if not ip_timestamp: gs.warning( _("Unable to determine timestamps. No metadata file found")) has_band_ref = gs.version()['version'] == '7.9.dev' sep = '|' with open(filename, 'w') as fd: for img_file in self.files: map_name = self._map_name(img_file) ip = self._ip_from_path(img_file) timestamp = ip_timestamp[ip] if timestamp: timestamp_str = timestamp.strftime("%Y-%m-%d %H:%M:%S.%f") else: timestamp_str = '' fd.write('{img}{sep}{ts}'.format(img=map_name, sep=sep, ts=timestamp_str)) if has_band_ref: fd.write('{sep}{br}'.format( sep=sep, br='S2_{}'.format(map_name[-2:].lstrip('0')))) fd.write(os.linesep)
def __init__(self): super(GrassGisProvider, self).__init__() msgr = Messenger() self._print_fn = msgr.message # type of computation (default) self.args.typecomp = CompType.full # options must be defined by set_options() self._options = None # logger self._add_logging_handler(handler=GrassGisLogHandler(), formatter=logging.Formatter("%(message)s")) # check version # TBD: change to pygrass API if list(map(int, gs.version()['version'].split('.')[:-1])) < [7, 7]: raise ProviderError("GRASS GIS version 7.8+ required") # force overwrite os.environ['GRASS_OVERWRITE'] = '1' # be quiet os.environ['GRASS_VERBOSE'] = '1' # define storage writter self.storage = GrassGisWritter()
def get_extensions(): addon_base = os.getenv("GRASS_ADDON_BASE") if not addon_base: gscript.fatal(_("%s not defined") % "GRASS_ADDON_BASE") fXML = os.path.join(addon_base, "modules.xml") if not os.path.exists(fXML): return [] # read XML file fo = open(fXML, "r") try: tree = etree.fromstring(fo.read()) except Exception as e: gscript.error(_("Unable to parse metadata file: %s") % e) fo.close() return [] fo.close() libgis_rev = gscript.version()["libgis_revision"] ret = list() for tnode in tree.findall("task"): gnode = tnode.find("libgis") if gnode is not None and gnode.get("revision", "") != libgis_rev: ret.append(tnode.get("name")) return ret
def OnHelp(self, event): # inspired by g.manual but simple not using GRASS_HTML_BROWSER # not using g.manual because it does not show entry = 'libpython/script_intro.html' major, minor, patch = gscript.version()['version'].split('.') url = 'http://grass.osgeo.org/grass%s%s/manuals/%s' % ( major, minor, entry) open_url(url)
def _grassDevTeam(start): try: end = grass.version()['date'] except KeyError: sys.stderr.write(_("Unable to get GRASS version\n")) from datetime import date end = date.today().year return '%(c)s %(start)s-%(end)s by the GRASS Development Team' % {'c': unichr(169), 'start': start, 'end': end}
def _grassDevTeam(start): try: end = grass.version()['date'] except KeyError: sys.stderr.write(_("Unable to get GRASS version\n")) from datetime import date end = date.today().year return '%(c)s %(start)s-%(end)s by the GRASS Development Team' % { 'c': _unichr(169), 'start': start, 'end': end}
def _grassDevTeam(start): try: end = grass.version()["date"] except KeyError: sys.stderr.write(_("Unable to get GRASS version\n")) from datetime import date end = date.today().year return "%(c)s %(start)s-%(end)s by the GRASS Development Team" % { "c": chr(169), "start": start, "end": end, }
def create_register_file(self, filename): gs.message(_("Creating register file <{}>...").format(filename)) ip_timestamp = {} for mtd_file in self._filter("MTD_TL.xml"): ip = self._ip_from_path(mtd_file) ip_timestamp[ip] = self._parse_mtd_file(mtd_file)['timestamp'] if not ip_timestamp: gs.warning(_("Unable to determine timestamps. No metadata file found")) has_band_ref = float(gs.version()['version'][0:3]) >= 7.9 sep = '|' with open(filename, 'w') as fd: for img_file in self.files: map_name = self._map_name(img_file) ip = self._ip_from_path(img_file) timestamp = ip_timestamp[ip] if timestamp: timestamp_str = timestamp.strftime("%Y-%m-%d %H:%M:%S.%f") else: timestamp_str = '' fd.write('{img}{sep}{ts}'.format( img=map_name, sep=sep, ts=timestamp_str )) if has_band_ref: try: band_ref = re.match( r'.*_B([0-18][0-9A]).*|.*_([S][C][L])_.*', map_name ).groups() band_ref = band_ref[0] if band_ref[0] else band_ref[1] band_ref = band_ref.lstrip('0') except AttributeError: gs.warning( _("Unable to determine band reference for <{}>").format( map_name)) continue fd.write('{sep}{br}'.format( sep=sep, br='S2_{}'.format(band_ref) )) fd.write(os.linesep)
def main(): """Do the main processing """ # Parse input options: patch_map = options['input'] patches = patch_map.split('@')[0] patches_mapset = patch_map.split('@')[1] if len( patch_map.split('@')) > 1 else None pop_proxy = options['pop_proxy'] layer = options['layer'] costs = options['costs'] cutoff = float(options['cutoff']) border_dist = int(options['border_dist']) conefor_dir = options['conefor_dir'] memory = int(options['memory']) # Parse output options: prefix = options['prefix'] edge_map = '{}_edges'.format(prefix) vertex_map = '{}_vertices'.format(prefix) shortest_paths = '{}_shortest_paths'.format(prefix) # Parse flags: p_flag = flags['p'] t_flag = flags['t'] r_flag = flags['r'] dist_flags = 'kn' if flags['k'] else 'n' lin_cat = 1 zero_dist = None folder = grass.tempdir() if not os.path.exists(folder): os.makedirs(folder) # Setup counter for progress message counter = 0 # Check if location is lat/lon (only in lat/lon geodesic distance # measuring is supported) if grass.locn_is_latlong(): grass.verbose("Location is lat/lon: Geodesic distance \ measure is used") # Check if prefix is legal GRASS name if not grass.legal_name(prefix): grass.fatal('{} is not a legal name for GRASS \ maps.'.format(prefix)) if prefix[0].isdigit(): grass.fatal('Tables names starting with a digit are not SQL \ compliant.'.format(prefix)) # Check if output maps not already exists or could be overwritten for output in [edge_map, vertex_map, shortest_paths]: if grass.db.db_table_exist(output) and not grass.overwrite(): grass.fatal('Vector map <{}> already exists'.format(output)) # Check if input has required attributes in_db_connection = grass.vector.vector_db(patch_map) if not int(layer) in in_db_connection.keys(): grass.fatal('No attribute table connected vector map {} at \ layer {}.'.format(patches, layer)) #Check if cat column exists pcols = grass.vector.vector_columns(patch_map, layer=layer) #Check if cat column exists if not 'cat' in pcols.keys(): grass.fatal('Cannot find the reqired column cat in vector map \ {}.'.format(patches)) #Check if pop_proxy column exists if not pop_proxy in pcols.keys(): grass.fatal('Cannot find column {} in vector map \ {}'.format(pop_proxy, patches)) #Check if pop_proxy column is numeric type if not pcols[pop_proxy]['type'] in ['INTEGER', 'REAL', 'DOUBLE PRECISION']: grass.fatal('Column {} is of type {}. Only numeric types \ (integer or double precision) \ allowed!'.format(pop_proxy, pcols[pop_proxy]['type'])) #Check if pop_proxy column does not contain values <= 0 pop_vals = np.fromstring(grass.read_command('v.db.select', flags='c', map=patches, columns=pop_proxy, nv=-9999).rstrip('\n'), dtype=float, sep='\n') if np.min(pop_vals) <= 0: grass.fatal('Column {} contains values <= 0 or NULL. Neither \ values <= 0 nor NULL allowed!}'.format(pop_proxy)) ############################################## # Use pygrass region instead of grass.parse_command !?! start_reg = grass.parse_command('g.region', flags='ugp') max_n = start_reg['n'] min_s = start_reg['s'] max_e = start_reg['e'] min_w = start_reg['w'] # cost_nsres = reg['nsres'] # cost_ewres = reg['ewres'] # Rasterize patches # http://www.gdal.org/gdal_tutorial.html # http://geoinformaticstutorial.blogspot.no/2012/11/convert- # shapefile-to-raster-with-gdal.html if t_flag: # Rasterize patches with "all-touched" mode using GDAL # Read region-settings (not needed canuse max_n, min_s, max_e, # min_w nsres, ewres... prast = os.path.join(folder, 'patches_rast.tif') # Check if GDAL-GRASS plugin is installed if ogr.GetDriverByName('GRASS'): #With GDAL-GRASS plugin #Locate file for patch vector map pfile = grass.parse_command('g.findfile', element='vector', file=patches, mapset=patches_mapset)['file'] pfile = os.path.join(pfile, 'head') else: # Without GDAL-GRASS-plugin grass.warning("Cannot find GDAL-GRASS plugin. Consider \ installing it in order to save time for \ all-touched rasterisation") pfile = os.path.join(folder, 'patches_vect.gpkg') # Export patch vector map to temp-file in a GDAL-readable # format (shp) grass.run_command('v.out.ogr', flags='m', quiet=True, input=patch_map, type='area', layer=layer, output=pfile, lco='GEOMETRY_NAME=geom') # Rasterize vector map with all-touched option os.system('gdal_rasterize -l {} -at -tr {} {} \ -te {} {} {} {} -ot Uint32 -a cat \ {} {} -q'.format(patches, start_reg['ewres'], start_reg['nsres'], start_reg['w'], start_reg['s'], start_reg['e'], start_reg['n'], pfile, prast)) if not ogr.GetDriverByName('GRASS'): # Remove vector temp-file os.remove(os.path.join(folder, 'patches_vect.gpkg')) # Import rasterized patches grass.run_command('r.external', flags='o', quiet=True, input=prast, output='{}_patches_pol'.format(TMP_PREFIX)) else: # Simple rasterisation (only area) # in G 7.6 also with support for 'centroid' if float(grass.version()['version'][:3]) >= 7.6: conv_types = ['area', 'centroid'] else: conv_types = ['area'] grass.run_command('v.to.rast', quiet=True, input=patches, use='cat', type=conv_types, output='{}_patches_pol'.format(TMP_PREFIX)) # Extract boundaries from patch raster map grass.run_command('r.mapcalc', expression='{p}_patches_boundary=if(\ {p}_patches_pol,\ if((\ (isnull({p}_patches_pol[-1,0])||| \ {p}_patches_pol[-1,0]!={p}_patches_pol)||| \ (isnull({p}_patches_pol[0,1])||| \ {p}_patches_pol[0,1]!={p}_patches_pol)||| \ (isnull({p}_patches_pol[1,0])||| \ {p}_patches_pol[1,0]!={p}_patches_pol)||| \ (isnull({p}_patches_pol[0,-1])||| \ {p}_patches_pol[0,-1]!={p}_patches_pol)), \ {p}_patches_pol,null()), null())'.format(p=TMP_PREFIX), quiet=True) rasterized_cats = grass.read_command( 'r.category', separator='newline', map='{p}_patches_boundary'.format(p=TMP_PREFIX)).replace( '\t', '').strip('\n') rasterized_cats = list( map(int, set([x for x in rasterized_cats.split('\n') if x != '']))) #Init output vector maps if they are requested by user network = VectorTopo(edge_map) network_columns = [(u'cat', 'INTEGER PRIMARY KEY'), (u'from_p', 'INTEGER'), (u'to_p', 'INTEGER'), (u'min_dist', 'DOUBLE PRECISION'), (u'dist', 'DOUBLE PRECISION'), (u'max_dist', 'DOUBLE PRECISION')] network.open('w', tab_name=edge_map, tab_cols=network_columns) vertex = VectorTopo(vertex_map) vertex_columns = [ (u'cat', 'INTEGER PRIMARY KEY'), (pop_proxy, 'DOUBLE PRECISION'), ] vertex.open('w', tab_name=vertex_map, tab_cols=vertex_columns) if p_flag: # Init cost paths file for start-patch grass.run_command('v.edit', quiet=True, map=shortest_paths, tool='create') grass.run_command('v.db.addtable', quiet=True, map=shortest_paths, columns="cat integer,\ from_p integer,\ to_p integer,\ dist_min double precision,\ dist double precision,\ dist_max double precision") start_region_bbox = Bbox(north=float(max_n), south=float(min_s), east=float(max_e), west=float(min_w)) vpatches = VectorTopo(patches, mapset=patches_mapset) vpatches.open('r', layer=int(layer)) ###Loop through patches vpatch_ids = np.array(vpatches.features_to_wkb_list( feature_type="centroid", bbox=start_region_bbox), dtype=[('vid', 'uint32'), ('cat', 'uint32'), ('geom', '|S10')]) cats = set(vpatch_ids['cat']) n_cats = len(cats) if n_cats < len(vpatch_ids['cat']): grass.verbose('At least one MultiPolygon found in patch map.\n \ Using average coordinates of the centroids for \ visual representation of the patch.') for cat in cats: if cat not in rasterized_cats: grass.warning('Patch {} has not been rasterized and will \ therefore not be treated as part of the \ network. Consider using t-flag or change \ resolution.'.format(cat)) continue grass.verbose("Calculating connectivity-distances for patch \ number {}".format(cat)) # Filter from_vpatch = vpatch_ids[vpatch_ids['cat'] == cat] # Get patch ID if from_vpatch['vid'].size == 1: from_centroid = Centroid(v_id=int(from_vpatch['vid']), c_mapinfo=vpatches.c_mapinfo) from_x = from_centroid.x from_y = from_centroid.y # Get centroid if not from_centroid: continue else: xcoords = [] ycoords = [] for f_p in from_vpatch['vid']: from_centroid = Centroid(v_id=int(f_p), c_mapinfo=vpatches.c_mapinfo) xcoords.append(from_centroid.x) ycoords.append(from_centroid.y) # Get centroid if not from_centroid: continue from_x = np.average(xcoords) from_y = np.average(ycoords) # Get BoundingBox from_bbox = grass.parse_command('v.db.select', map=patch_map, flags='r', where='cat={}'.format(cat)) attr_filter = vpatches.table.filters.select(pop_proxy) attr_filter = attr_filter.where("cat={}".format(cat)) proxy_val = vpatches.table.execute().fetchone() # Prepare start patch start_patch = '{}_patch_{}'.format(TMP_PREFIX, cat) reclass_rule = grass.encode('{} = 1\n* = NULL'.format(cat)) recl = grass.feed_command( 'r.reclass', quiet=True, input='{}_patches_boundary'.format(TMP_PREFIX), output=start_patch, rules='-') recl.stdin.write(reclass_rule) recl.stdin.close() recl.wait() # Check if patch was rasterised (patches smaller raster resolution and close to larger patches may not be rasterised) #start_check = grass.parse_command('r.info', flags='r', map=start_patch) #start_check = grass.parse_command('r.univar', flags='g', map=start_patch) #print(start_check) """if start_check['min'] != '1': grass.warning('Patch {} has not been rasterized and will \ therefore not be treated as part of the \ network. Consider using t-flag or change \ resolution.'.format(cat)) grass.run_command('g.remove', flags='f', vector=start_patch, raster=start_patch, quiet=True) grass.del_temp_region() continue""" # Prepare stop patches ############################################ reg = grass.parse_command('g.region', flags='ug', quiet=True, raster=start_patch, n=float(from_bbox['n']) + float(cutoff), s=float(from_bbox['s']) - float(cutoff), e=float(from_bbox['e']) + float(cutoff), w=float(from_bbox['w']) - float(cutoff), align='{}_patches_pol'.format(TMP_PREFIX)) north = reg['n'] if max_n > reg['n'] else max_n south = reg['s'] if min_s < reg['s'] else min_s east = reg['e'] if max_e < reg['e'] else max_e west = reg['w'] if min_w > reg['w'] else min_w # Set region to patch search radius grass.use_temp_region() grass.run_command('g.region', quiet=True, n=north, s=south, e=east, w=west, align='{}_patches_pol'.format(TMP_PREFIX)) # Create buffer around start-patch as a mask # for cost distance analysis grass.run_command('r.buffer', quiet=True, input=start_patch, output='MASK', distances=cutoff) grass.run_command('r.mapcalc', quiet=True, expression='{pf}_patch_{p}_neighbours_contur=\ if({pf}_patches_boundary=={p},\ null(),\ {pf}_patches_boundary)'.format( pf=TMP_PREFIX, p=cat)) grass.run_command('r.mask', flags='r', quiet=True) # Calculate cost distance cost_distance_map = '{}_patch_{}_cost_dist'.format(prefix, cat) grass.run_command('r.cost', flags=dist_flags, quiet=True, overwrite=True, input=costs, output=cost_distance_map, start_rast=start_patch, memory=memory) #grass.run_command('g.region', flags='up') # grass.raster.raster_history(cost_distance_map) cdhist = History(cost_distance_map) cdhist.clear() cdhist.creator = os.environ['USER'] cdhist.write() # History object cannot modify description grass.run_command('r.support', map=cost_distance_map, description='Generated by r.connectivity.distance', history=os.environ['CMDLINE']) # Export distance at boundaries maps = '{0}_patch_{1}_neighbours_contur,{2}_patch_{1}_cost_dist' maps = maps.format(TMP_PREFIX, cat, prefix), connections = grass.encode( grass.read_command('r.stats', flags='1ng', quiet=True, input=maps, separator=';').rstrip('\n')) if connections: con_array = np.genfromtxt(BytesIO(connections), delimiter=';', dtype=None, names=['x', 'y', 'cat', 'dist']) else: grass.warning('No connections for patch {}'.format(cat)) # Write centroid to vertex map vertex.write(Point(from_x, from_y), cat=int(cat), attrs=proxy_val) vertex.table.conn.commit() # Remove temporary map data grass.run_command('g.remove', quiet=True, flags='f', type=['raster', 'vector'], pattern="{}*{}*".format(TMP_PREFIX, cat)) grass.del_temp_region() continue #Find closest points on neigbour patches to_cats = set(np.atleast_1d(con_array['cat'])) to_coords = [] for to_cat in to_cats: connection = con_array[con_array['cat'] == to_cat] connection.sort(order=['dist']) pixel = border_dist if len( connection) > border_dist else len(connection) - 1 # closest_points_x = connection['x'][pixel] # closest_points_y = connection['y'][pixel] closest_points_to_cat = to_cat closest_points_min_dist = connection['dist'][0] closest_points_dist = connection['dist'][pixel] closest_points_max_dist = connection['dist'][-1] to_patch_ids = vpatch_ids[vpatch_ids['cat'] == int(to_cat)]['vid'] if len(to_patch_ids) == 1: to_centroid = Centroid(v_id=to_patch_ids, c_mapinfo=vpatches.c_mapinfo) to_x = to_centroid.x to_y = to_centroid.y elif len(to_patch_ids) >= 1: xcoords = [] ycoords = [] for t_p in to_patch_ids: to_centroid = Centroid(v_id=int(t_p), c_mapinfo=vpatches.c_mapinfo) xcoords.append(to_centroid.x) ycoords.append(to_centroid.y) # Get centroid if not to_centroid: continue to_x = np.average(xcoords) to_y = np.average(ycoords) to_coords.append('{},{},{},{},{},{}'.format( connection['x'][0], connection['y'][0], to_cat, closest_points_min_dist, closest_points_dist, closest_points_max_dist)) #Save edges to network dataset if closest_points_dist <= 0: zero_dist = 1 # Write data to network network.write(Line([(from_x, from_y), (to_x, to_y)]), cat=lin_cat, attrs=( cat, int(closest_points_to_cat), closest_points_min_dist, closest_points_dist, closest_points_max_dist, )) network.table.conn.commit() lin_cat = lin_cat + 1 # Save closest points and shortest paths through cost raster as # vector map (r.drain limited to 1024 points) if requested if p_flag: grass.verbose('Extracting shortest paths for patch number \ {}...'.format(cat)) points_n = len(to_cats) tiles = int(points_n / 1024.0) rest = points_n % 1024 if not rest == 0: tiles = tiles + 1 tile_n = 0 while tile_n < tiles: tile_n = tile_n + 1 #Import closest points for start-patch in 1000er blocks sp = grass.feed_command('v.in.ascii', flags='nr', overwrite=True, quiet=True, input='-', stderr=subprocess.PIPE, output="{}_{}_cp".format( TMP_PREFIX, cat), separator=",", columns="x double precision,\ y double precision,\ to_p integer,\ dist_min double precision,\ dist double precision,\ dist_max double precision") sp.stdin.write(grass.encode("\n".join(to_coords))) sp.stdin.close() sp.wait() # Extract shortest paths for start-patch in chunks of # 1024 points cost_paths = "{}_{}_cost_paths".format(TMP_PREFIX, cat) start_points = "{}_{}_cp".format(TMP_PREFIX, cat) grass.run_command('r.drain', overwrite=True, quiet=True, input=cost_distance_map, output=cost_paths, drain=cost_paths, start_points=start_points) grass.run_command('v.db.addtable', map=cost_paths, quiet=True, columns="cat integer,\ from_p integer,\ to_p integer,\ dist_min double precision,\ dist double precision,\ dist_max double precision") grass.run_command('v.db.update', map=cost_paths, column='from_p', value=cat, quiet=True) grass.run_command('v.distance', quiet=True, from_=cost_paths, to=start_points, upload='to_attr', column='to_p', to_column='to_p') grass.run_command('v.db.join', quiet=True, map=cost_paths, column='to_p', other_column='to_p', other_table=start_points, subset_columns='dist_min,dist,dist_max') #grass.run_command('v.info', flags='c', # map=cost_paths) grass.run_command('v.patch', flags='ae', overwrite=True, quiet=True, input=cost_paths, output=shortest_paths) # Remove temporary map data grass.run_command('g.remove', quiet=True, flags='f', type=['raster', 'vector'], pattern="{}*{}*".format(TMP_PREFIX, cat)) # Remove temporary map data for patch if r_flag: grass.run_command('g.remove', flags='f', type='raster', name=cost_distance_map, quiet=True) vertex.write(Point(from_x, from_y), cat=int(cat), attrs=proxy_val) vertex.table.conn.commit() # Print progress message grass.percent(i=int((float(counter) / n_cats) * 100), n=100, s=3) # Update counter for progress message counter = counter + 1 if zero_dist: grass.warning('Some patches are directly adjacent to others. \ Minimum distance set to 0.0000000001') # Close vector maps and build topology network.close() vertex.close() # Add vertex attributes # grass.run_command('v.db.addtable', map=vertex_map) # grass.run_command('v.db.join', map=vertex_map, column='cat', # other_table=in_db_connection[int(layer)]['table'], # other_column='cat', subset_columns=pop_proxy, # quiet=True) # Add history and meta data to produced maps grass.run_command('v.support', flags='h', map=edge_map, person=os.environ['USER'], cmdhist=os.environ['CMDLINE']) grass.run_command('v.support', flags='h', map=vertex_map, person=os.environ['USER'], cmdhist=os.environ['CMDLINE']) if p_flag: grass.run_command('v.support', flags='h', map=shortest_paths, person=os.environ['USER'], cmdhist=os.environ['CMDLINE']) # Output also Conefor files if requested if conefor_dir: query = """SELECT p_from, p_to, avg(dist) FROM (SELECT CASE WHEN from_p > to_p THEN to_p ELSE from_p END AS p_from, CASE WHEN from_p > to_p THEN from_p ELSE to_p END AS p_to, dist FROM {}) AS x GROUP BY p_from, p_to""".format(edge_map) with open(os.path.join(conefor_dir, 'undirected_connection_file'), 'w') as edges: edges.write( grass.read_command('db.select', sql=query, separator=' ')) with open(os.path.join(conefor_dir, 'directed_connection_file'), 'w') as edges: edges.write( grass.read_command('v.db.select', map=edge_map, separator=' ', flags='c')) with open(os.path.join(conefor_dir, 'node_file'), 'w') as nodes: nodes.write( grass.read_command('v.db.select', map=vertex_map, separator=' ', flags='c'))
def main(): global temp_ng, temp_ncin, temp_ncout # we discard stderrs when not debugging # ideally stderrs should be printed when an exception was raised # this would be done easily with StringIO # but it doesn't work with subprocess if not grass.debug_level(): nuldev = open(os.devnull, 'w') else: nuldev = sys.stderr # Initalise temporary verctor map names temp_ng = "v_lidar_mcc_tmp_ng_" + str(os.getpid()) temp_ncin = "v_lidar_mcc_tmp_ncin_" + str(os.getpid()) temp_ncout = "v_lidar_mcc_tmp_ncout_" + str(os.getpid()) input = options['input'] g_output = options['ground'] ng_output = options['nonground'] # does map exist? if not grass.find_file(input, element='vector')['file']: grass.fatal(_("Vector map <%s> not found") % input) # Count points in input map n_input = grass.vector_info(input)['points'] # does map contain points ? if not (n_input > 0): grass.fatal(_("Vector map <%s> does not contain points") % input) flag_n = flags['n'] ### Scale domain (l) # Evans & Hudak 2007 used scale domains 1 to 3 l = int(1) l_stop = int(options['nl']) if (l_stop < 1): grass.fatal("The minimum number of scale domains is 1.") ### Curvature tolerance threshold (t) # Evans & Hudak 2007 used a t-value of 0.3 t = float(options['t']) ###Increase of curvature tolerance threshold for each ti = t / 3.0 ### Convergence threshold (j) # Evans & Hudak 2007 used a convergence threshold of 0.3 j = float(options['j']) if (j <= 0): grass.fatal("The convergence threshold has to be > 0.") ### Tension parameter (f) # Evans & Hudak 2007 used a tension parameter 1.5 f = float(options['f']) if (f <= 0): grass.fatal("The tension parameter has to be > 0.") ### Spline steps parameter (s) # Evans & Hudak 2007 used the 12 nearest neighbors # (used spline steps $res * 5 before) s = int(options['s']) if (s <= 0): grass.fatal("The spline step parameter has to be > 0.") ###Read desired resolution from region #Evans & Hudak 2007 used a desired resolution (delta) of 1.5 gregion = grass.region() x_res_fin = gregion['ewres'] y_res_fin = gregion['nsres'] # Defineresolution steps in iteration n_res_steps = (l_stop + 1) / 2 # Pass ame of input map to v.outlier nc_points = input # controls first creation of the output map before patching ng_output_exists = False # append and do not build topology vpatch_flags = 'ab' # 7.x requires topology to see z coordinate # 7.1 v.patch has flags to use z even without topology # see #2433 on Trac and r66822 in Subversion build_before_patch = True unused, gver_minor, unused = grass.version()['version'].split('.') if int(gver_minor) >= 1: build_before_patch = False # do not expect topology and expect z vpatch_flags += 'nz' # Loop through scale domaines while (l <= l_stop): i = 1 convergence = 100 if (l < ((l_stop + 1) / 2)): xres = x_res_fin / (n_res_steps - (l - 1)) yres = y_res_fin / (n_res_steps - (l - 1)) elif (l == ((l_stop + 1) / 2)): xres = x_res_fin yres = y_res_fin else: xres = x_res_fin * ((l + 1) - n_res_steps) yres = y_res_fin * ((l + 1) - n_res_steps) grass.use_temp_region() grass.run_command("g.region", s=gregion['s'], w=gregion['w'], nsres=yres, ewres=xres, flags="a") xs_s = xres * s ys_s = yres * s grass.message("Processing scale domain " + str(l) + "...") # Repeat application of v.outlier until convergence level is reached while (convergence > j): grass.verbose("Number of input points in iteration " + str(i) + ": " + str(n_input)) # Run v.outlier if not flag_n: grass.run_command('v.outlier', input=nc_points, output=temp_ncout, outlier=temp_ng, ew_step=xs_s, ns_step=ys_s, lambda_=f, threshold=t, filter='positive', overwrite=True, quiet=True, stderr=nuldev) else: grass.run_command('v.outlier', input=nc_points, output=temp_ncout, outlier=temp_ng, ew_step=xs_s, ns_step=ys_s, lambda_=f, threshold=t, filter='negative', overwrite=True, quiet=True, stderr=nuldev) # Get information about results for calculating convergence level ng = grass.vector_info(temp_ng)['points'] nc = n_input - ng n_input = nc grass.run_command('g.remove', flags='f', type='vector', name=temp_ncin, quiet=True, stderr=nuldev) grass.run_command("g.rename", vector=temp_ncout + "," + temp_ncin, quiet=True, stderr=nuldev) nc_points = temp_ncin # Give information on process status grass.verbose("Unclassified points after iteration " + str(i) + ": " + str(nc)) grass.verbose("Points classified as non ground after iteration " + str(i) + ": " + str(ng)) # Set convergence level if (nc > 0): convergence = float(float(ng) / float(nc)) if build_before_patch: grass.run_command('v.build', map=temp_ng, stderr=nuldev) # Patch non-ground points to non-ground output map if ng_output_exists: grass.run_command('v.patch', input=temp_ng, output=ng_output, flags=vpatch_flags, overwrite=True, quiet=True, stderr=nuldev) else: grass.run_command('g.copy', vector=(temp_ng, ng_output), stderr=nuldev) ng_output_exists = True else: convergence = 0 # Give information on convergence level grass.verbose("Convergence level after run " + str(i) + " in scale domain " + str(l) + ": " + str(round(convergence, 3))) # Increase iterator i = i + 1 # Adjust curvature tolerance and reset scale domain t = t + ti l = l + 1 # Delete temporary region grass.del_temp_region() # Rename temporary map of points whichhave not been classified as non-ground to output vector map containing ground points grass.run_command("g.rename", vector=nc_points + "," + g_output, quiet=True, stderr=nuldev)
def _pageInfo(self): """Info page""" # get version and web site vInfo = grass.version() if not vInfo: sys.stderr.write(_("Unable to get GRASS version\n")) infoTxt = ScrolledPanel(self.aboutNotebook) infoTxt.SetBackgroundColour('WHITE') infoTxt.SetupScrolling() infoSizer = wx.BoxSizer(wx.VERTICAL) infoGridSizer = wx.GridBagSizer(vgap = 5, hgap = 5) logo = os.path.join(globalvar.ICONDIR, "grass-64x64.png") logoBitmap = wx.StaticBitmap(parent = infoTxt, id = wx.ID_ANY, bitmap = wx.Bitmap(name = logo, type = wx.BITMAP_TYPE_PNG)) infoSizer.Add(item = logoBitmap, proportion = 0, flag = wx.ALL | wx.ALIGN_CENTER, border = 20) infoLabel = 'GRASS GIS %s' % vInfo.get('version', _('unknown version')) if '64' in vInfo.get('build_platform', ''): infoLabel += ' (64bit)' info = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = infoLabel + os.linesep) info.SetFont(wx.Font(13, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, "")) info.SetForegroundColour(wx.Colour(35, 142, 35)) infoSizer.Add(item = info, proportion = 0, flag = wx.BOTTOM | wx.ALIGN_CENTER, border = 1) team = wx.StaticText(parent=infoTxt, label=_grassDevTeam(1999) + '\n') infoSizer.Add(item = team, proportion = 0, flag = wx.BOTTOM | wx.ALIGN_CENTER, border = 1) row = 0 infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = _('Official GRASS site:')), pos = (row, 0), flag = wx.ALIGN_RIGHT) infoGridSizer.Add(item = HyperLinkCtrl(parent = infoTxt, id = wx.ID_ANY, label = 'http://grass.osgeo.org'), pos = (row, 1), flag = wx.ALIGN_LEFT) row += 2 infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = '%s:' % _('Code Revision')), pos = (row, 0), flag = wx.ALIGN_RIGHT) infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = vInfo.get('revision', '?')), pos = (row, 1), flag = wx.ALIGN_LEFT) row += 1 infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = '%s:' % _('Build Date')), pos = (row, 0), flag = wx.ALIGN_RIGHT) infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = vInfo.get('build_date', '?')), pos = (row, 1), flag = wx.ALIGN_LEFT) ### show only basic info # row += 1 # infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, # label = '%s:' % _('GIS Library Revision')), # pos = (row, 0), # flag = wx.ALIGN_RIGHT) # infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, # label = vInfo['libgis_revision'] + ' (' + # vInfo['libgis_date'].split(' ')[0] + ')'), # pos = (row, 1), # flag = wx.ALIGN_LEFT) row += 2 infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = 'Python:'), pos = (row, 0), flag = wx.ALIGN_RIGHT) infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = platform.python_version()), pos = (row, 1), flag = wx.ALIGN_LEFT) row += 1 infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = 'wxPython:'), pos = (row, 0), flag = wx.ALIGN_RIGHT) infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = wx.__version__), pos = (row, 1), flag = wx.ALIGN_LEFT) infoGridSizer.AddGrowableCol(0) infoGridSizer.AddGrowableCol(1) infoSizer.Add(item = infoGridSizer, proportion = 1, flag = wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL) row += 2 infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = "%s:" % _('Language')), pos = (row, 0), flag = wx.ALIGN_RIGHT) self.langUsed = grass.gisenv().get('LANG', None) if not self.langUsed: import locale loc = locale.getdefaultlocale() if loc == (None, None): self.langUsed = _('unknown') else: self.langUsed = u'%s.%s' % (loc[0], loc[1]) infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = self.langUsed), pos = (row, 1), flag = wx.ALIGN_LEFT) infoTxt.SetSizer(infoSizer) infoSizer.Fit(infoTxt) return infoTxt
import sys import os import atexit try: import grass.script as grass except: try: from grass.script import core as grass except: if not os.environ.has_key("GISBASE"): print "You must be in GRASS GIS to run this program." sys.exit(1) grass_version = grass.version().get("version")[0:2] if grass_version != "7.": grass.fatal(_("Sorry, this script works in GRASS 7.* only")) else: from grass.lib.gis import * from grass.lib.vector import * from grass.lib.raster import * def cleanup(): nuldev = file(os.devnull, "w") if tmp: grass.run_command("g.remove", type="raster", name="%s" % tmp, quiet=True, stderr=nuldev) def main():
def __init__(self, parent, size=(650, 460), title=_('About GRASS GIS'), **kwargs): wx.Frame.__init__(self, parent=parent, id=wx.ID_ANY, title=title, size=size, **kwargs) panel = wx.Panel(parent=self, id=wx.ID_ANY) # icon self.SetIcon( wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO)) # get version and web site vInfo = grass.version() infoTxt = ScrolledPanel(parent=panel) infoTxt.SetupScrolling() infoSizer = wx.BoxSizer(wx.VERTICAL) infoGridSizer = wx.GridBagSizer(vgap=5, hgap=5) logo = os.path.join(globalvar.ETCDIR, "gui", "icons", "grass-64x64.png") logoBitmap = wx.StaticBitmap(parent=infoTxt, id=wx.ID_ANY, bitmap=wx.Bitmap(name=logo, type=wx.BITMAP_TYPE_PNG)) infoSizer.Add(item=logoBitmap, proportion=0, flag=wx.ALL | wx.ALIGN_CENTER, border=20) info = wx.StaticText(parent=infoTxt, id=wx.ID_ANY, label='GRASS GIS ' + vInfo['version'] + '\n\n') info.SetFont(wx.Font(13, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, "")) info.SetForegroundColour(wx.Colour(35, 142, 35)) infoSizer.Add(item=info, proportion=0, flag=wx.BOTTOM | wx.ALIGN_CENTER, border=1) row = 0 infoGridSizer.Add(item=wx.StaticText(parent=infoTxt, id=wx.ID_ANY, label=_('Official GRASS site:')), pos=(row, 0), flag=wx.ALIGN_RIGHT) infoGridSizer.Add(item=HyperLinkCtrl(parent=infoTxt, id=wx.ID_ANY, label='http://grass.osgeo.org'), pos=(row, 1), flag=wx.ALIGN_LEFT) row += 2 infoGridSizer.Add(item=wx.StaticText(parent=infoTxt, id=wx.ID_ANY, label='%s:' % _('SVN Revision')), pos=(row, 0), flag=wx.ALIGN_RIGHT) infoGridSizer.Add(item=wx.StaticText(parent=infoTxt, id=wx.ID_ANY, label=vInfo['revision']), pos=(row, 1), flag=wx.ALIGN_LEFT) row += 1 infoGridSizer.Add(item=wx.StaticText(parent=infoTxt, id=wx.ID_ANY, label='%s:' % _('GIS Library Revision')), pos=(row, 0), flag=wx.ALIGN_RIGHT) infoGridSizer.Add( item=wx.StaticText(parent=infoTxt, id=wx.ID_ANY, label=vInfo['libgis_revision'] + ' (' + vInfo['libgis_date'].split(' ')[0] + ')'), pos=(row, 1), flag=wx.ALIGN_LEFT) row += 2 infoGridSizer.Add(item=wx.StaticText(parent=infoTxt, id=wx.ID_ANY, label='Python:'), pos=(row, 0), flag=wx.ALIGN_RIGHT) infoGridSizer.Add(item=wx.StaticText(parent=infoTxt, id=wx.ID_ANY, label=platform.python_version()), pos=(row, 1), flag=wx.ALIGN_LEFT) row += 1 infoGridSizer.Add(item=wx.StaticText(parent=infoTxt, id=wx.ID_ANY, label='wxPython:'), pos=(row, 0), flag=wx.ALIGN_RIGHT) infoGridSizer.Add(item=wx.StaticText(parent=infoTxt, id=wx.ID_ANY, label=wx.__version__), pos=(row, 1), flag=wx.ALIGN_LEFT) infoGridSizer.AddGrowableCol(0) infoGridSizer.AddGrowableCol(1) infoSizer.Add(item=infoGridSizer, proportion=1, flag=wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL) row += 2 infoGridSizer.Add(item=wx.StaticText(parent=infoTxt, id=wx.ID_ANY, label="%s:" % _('Language')), pos=(row, 0), flag=wx.ALIGN_RIGHT) lang = grass.gisenv().get('LANG', None) if not lang: import locale loc = locale.getdefaultlocale() if loc == (None, None): lang = _('unknown') else: lang = u'%s.%s' % (loc[0], loc[1]) infoGridSizer.Add(item=wx.StaticText(parent=infoTxt, id=wx.ID_ANY, label=lang), pos=(row, 1), flag=wx.ALIGN_LEFT) # create a flat notebook for displaying information about GRASS aboutNotebook = GNotebook(panel, style=globalvar.FNPageStyle | FN.FNB_NO_X_BUTTON) aboutNotebook.SetTabAreaColour(globalvar.FNPageColor) for title, win in ((_("Info"), infoTxt), (_("Copyright"), self._pageCopyright()), (_("License"), self._pageLicense()), (_("Authors"), self._pageCredit()), (_("Contributors"), self._pageContributors()), (_("Extra contributors"), self._pageContributors(extra=True)), (_("Translators"), self._pageTranslators())): aboutNotebook.AddPage(page=win, text=title) wx.CallAfter(aboutNotebook.SetSelection, 0) # buttons btnClose = wx.Button(parent=panel, id=wx.ID_CLOSE) btnSizer = wx.BoxSizer(wx.HORIZONTAL) btnSizer.Add(item=btnClose, proportion=0, flag=wx.ALL | wx.ALIGN_RIGHT, border=5) # bindings btnClose.Bind(wx.EVT_BUTTON, self.OnCloseWindow) infoTxt.SetSizer(infoSizer) infoSizer.Fit(infoTxt) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(item=aboutNotebook, proportion=1, flag=wx.EXPAND | wx.ALL, border=1) sizer.Add(item=btnSizer, proportion=0, flag=wx.ALL | wx.ALIGN_RIGHT, border=1) panel.SetSizer(sizer) self.Layout() self.SetMinSize((400, 400))
def main(): """Process command line parameters and update the table""" options, flags = gs.parser() vector = options["map"] layer = options["layer"] where = options["where"] column = options["column"] expression = options["expression"] condition = options["condition"] functions_file = options["functions"] # Map needs to be in the current mapset mapset = gs.gisenv()["MAPSET"] if not gs.find_file(vector, element="vector", mapset=mapset)["file"]: gs.fatal( _("Vector map <{vector}> does not exist or is not in the current mapset" "(<{mapset}>) and therefore it cannot be modified").format( **locals())) # Map+layer needs to have a table connected try: # TODO: Support @OGR vector maps? Probably not supported by db.execute anyway. db_info = gs.vector_db(vector)[int(layer)] except KeyError: gs.fatal( _("There is no table connected to map <{vector}> (layer <{layer}>)." " Use v.db.connect or v.db.addtable to add it.").format( **locals())) table = db_info["table"] database = db_info["database"] driver = db_info["driver"] columns = gs.vector_columns(vector, layer) # Check that column exists try: column_info = columns[column] except KeyError: gs.fatal( _("Column <{column}> not found. Use v.db.addcolumn to create it."). format(column=column)) column_type = column_info["type"] # Check that optional function file exists if functions_file: if not os.access(functions_file, os.R_OK): gs.fatal(_("File <{file}> not found").format(file=functions_file)) # Define Python functions # Here we need the full-deal eval and exec functions and can't sue less # general alternatives such as ast.literal_eval. def expression_function(**kwargs): return eval(expression, globals(), kwargs) # pylint: disable=eval-used def condition_function(**kwargs): return eval(condition, globals(), kwargs) # pylint: disable=eval-used # TODO: Add error handling for failed imports. if options["packages"]: packages = options["packages"].split(",") for package in packages: # pylint: disable=exec-used exec(f"import {package}", globals(), globals()) if flags["s"]: exec(f"from {package} import *", globals(), globals()) # TODO: Add error handling for invalid syntax. if functions_file: with open(functions_file) as file: exec(file.read(), globals(), globals()) # pylint: disable=exec-used # Get table contents if not where: # The condition needs to be None, an empty string is passed through. where = None if gs.version()["version"] < "7.9": sep = "|" # Only one char sep for Python csv package. null = "NULL" csv_text = gs.read_command( "v.db.select", map=vector, layer=layer, separator=sep, null=null, where=where, ) table_contents = csv_loads(csv_text, delimeter=sep, null=null) else: # TODO: XXX is a workaround for a bug in v.db.select -j json_text = gs.read_command("v.db.select", map=vector, layer=layer, flags="j", null="XXX", where=where) table_contents = json.loads(json_text) cmd = python_to_transaction( table=table, table_contents=table_contents, column=column, column_type=column_type, expression=expression, expression_function=expression_function, condition=condition, condition_function=condition_function, ensure_lowercase=not flags["u"], ) # Messages if len(cmd) == 2: gs.message( "No rows to update. Try a different SQL where or Python condition." ) elif len(cmd) > 2: # First and last statement gs.verbose(f'Using SQL: "{cmd[1]}...{cmd[-2]}"') # The newline is needed for successful execution/reading of many statements. # TODO: Add error handling when there is a syntax error due to wrongly # generated SQL statement and/or sanitize the value in update more. gs.write_command("db.execute", input="-", database=database, driver=driver, stdin="\n".join(cmd)) gs.vector_history(vector)
exit( "This script requires the Python package \'MatPlotLib\'. Please install that and try again." ) try: import seaborn as sns except: exit( "This script requires the Python package \'Seaborn\'. Please install that and try again." ) try: import grass.script as grass except: exit( "You must have GRASS GIS installed, and be in a GRASS session to run this script" ) if int(grass.version()['version'].split('.')[0]) < 7: grass.fatal( "You must be in GRASS version 7.0.1 or higher to run this script!") import tempfile, math ################# SET UP THESE VALUES #################### ########################################################## RunLength = 500 #number of years the simulation ran for digits = 3 #number of digits that simulation year numbers are padded to prefix = "woodland_fires" coor = "701630.980259, 4326953.53628" #"727195.790391, 4285699.45461" # location(s) at which to take a virtual sediment core outprefix = "NV7" # A prefix for all output files. baseinterval = 0.001 # the depth intervals at which to collect proxies (default is 1mm) dispinterval = 100 # the number of depth intervals to amalgamate as the interval for the plot of proxies at the last year (default is 10cm) miny = -1.25 # optional minimum y value for the output stratigraphy plot proxyscale = 'linear' # Scale for the x axis of the output proxies plot. 'log' or 'linear'
import sys import os import atexit try: import grass.script as grass except: try: from grass.script import core as grass except: if "GISBASE" not in os.environ: print("You must be in GRASS GIS to run this program.") sys.exit(1) grass_version = grass.version().get("version")[0:2] if grass_version != "7.": grass.fatal(_("Sorry, this script works in GRASS 7.* only")) else: from grass.lib.gis import * from grass.lib.vector import * from grass.lib.raster import * def cleanup(): if tmp: grass.run_command("g.remove", type="raster", name="%s" % tmp, quiet=True, stderr=nuldev)
def main(): check_progs() inmap = options['input'] output = options['ldm'] width = options['width'] color = options['color'] graph = options['graph'] ldm_type = options['type'] mapset = grass.gisenv()['MAPSET'] global tmp, nuldev, grass_version nuldev = None grass_version = grass.version()['version'][0] if grass_version != '7': grass.fatal(_("Sorry, this script works in GRASS 7.* only")) # setup temporary files tmp = grass.tempfile() # check for LatLong location if grass.locn_is_latlong() == True: grass.fatal("Module works only in locations with cartesian coordinate system") # check if input file exists if not grass.find_file(inmap, element = 'vector')['file']: grass.fatal(_("<%s> does not exist.") % inmap) # check for lines iflines = grass.vector_info_topo(inmap)['lines'] if iflines == 0: grass.fatal(_("Map <%s> has no lines.") % inmap) # diplay options if flags['x']: env = grass.gisenv() mon = env.get('MONITOR', None) if not mon: if not graph: grass.fatal(_("Please choose \"graph\" output file with LDM graphics or not use flag \"x\"")) ####### DO IT ####### # copy input vector map and drop table grass.run_command('g.copy', vect = (inmap, 'v_ldm_vect'), quiet = True, stderr = nuldev) db = grass.vector_db('v_ldm_vect') if db != {}: grass.run_command('v.db.droptable', map_ = 'v_ldm_vect', flags = 'f', quiet = True, stderr = nuldev) # compute mean center of lines with v.mc.py module center_coords = grass.read_command('v.mc.py', input_ = inmap, type_ = 'line', quiet = True, stderr = nuldev).strip() mc_x = center_coords.split(' ')[0] mc_y = center_coords.split(' ')[1] center_coords = str(mc_x) + ',' + str(mc_y) ### inmap = 'v_ldm_vect' # count lines count = grass.vector_info_topo(inmap)['lines'] # add temp table with azimuths and lengths of lines in_cats = inmap + '_cats' grass.run_command('v.category', input_ = inmap, option = 'add', output = in_cats, quiet = True, stderr = nuldev) grass.run_command('v.db.addtable', map_ = in_cats, table = 'tmp_tab', columns = 'sum_azim double, len double', quiet = True, stderr = nuldev) grass.run_command('v.db.connect', map_ = in_cats, table = 'tmp_tab', flags = 'o', quiet = True, stderr = nuldev) grass.run_command('v.to.db', map_ = in_cats, opt = 'azimuth', columns = 'sum_azim', units = 'radians', quiet = True, stderr = nuldev) grass.run_command('v.to.db', map_ = in_cats, opt = 'length', columns = 'len', units = 'meters', quiet = True, stderr = nuldev) # find end azimuth p = grass.pipe_command('v.db.select', map_ = in_cats, columns = 'sum_azim', flags = 'c', quiet = True, stderr = nuldev) c = p.communicate()[0].strip().split('\n') sin = [] cos = [] for i in c: s1 = math.sin(float(i)) c1 = math.cos(float(i)) sin.append(s1) cos.append(c1) ca_sin = sum(map(float,sin)) ca_cos = sum(map(float,cos)) atan = math.atan2(ca_sin,ca_cos) end_azim = math.degrees(atan) # find compass angle if end_azim < 0: a2 = -(end_azim) if end_azim > 0: a2 = end_azim if (ca_sin > 0) and (ca_cos > 0): comp_angle = a2 if (ca_sin > 0) and (ca_cos < 0): comp_angle = a2 if (ca_sin < 0) and (ca_cos > 0): comp_angle = 360 - a2 if (ca_sin < 0) and (ca_cos < 0): comp_angle = 360 - a2 # find LDM if end_azim < 0: a2 = -(end_azim) if end_azim > 0: a2 = end_azim if (ca_sin > 0) and (ca_cos > 0): ldm = 90 - a2 if (ca_sin > 0) and (ca_cos < 0): ldm = 450 - a2 if (ca_sin < 0) and (ca_cos > 0): ldm = 90 + a2 if (ca_sin < 0) and (ca_cos < 0): ldm = 90 + a2 # find circular variance sin_pow = math.pow(ca_sin,2) cos_pow = math.pow(ca_cos,2) circ_var = 1-(math.sqrt(sin_pow+cos_pow))/count # find start/end points of "mean" line end_azim_dms = decimal2dms(end_azim) # if end_azim < 0: # end_azim_dms = '-' + (str(end_azim_dms)) start_azim = 180 - end_azim start_azim_dms = decimal2dms(start_azim) p = grass.pipe_command('v.db.select', map_ = in_cats, columns = 'len', flags = 'c', quiet = True, stderr = nuldev) c = p.communicate()[0].strip().split('\n') mean_length = sum(map(float,c))/len(c) half_length = float(mean_length)/2 tmp1 = tmp + '.inf' inf1 = file(tmp1, 'w') print >> inf1, 'N ' + str(end_azim_dms) + ' E ' + str(half_length) inf1.close() end_coords = grass.read_command('m.cogo', input_ = tmp1, output = '-', coord = center_coords, quiet = True).strip() tmp2 = tmp + '.inf2' inf2 = file(tmp2, 'w') print >> inf2, 'N ' + str(start_azim_dms) + ' W ' + str(half_length) inf2.close() start_coords = grass.read_command('m.cogo', input_ = tmp2, output = '-', coord = center_coords, quiet = True).strip() # make "arrowhead" symbol if flags['x'] or graph: tmp3 = tmp + '.arrowhead_1' outf3 = file(tmp3, 'w') if ldm_type == 'direct': t1 = """VERSION 1.0 BOX -0.5 -0.5 0.5 0.5 POLYGON RING FCOLOR NONE LINE 0 0 0.3 -1 END END POLYGON RING FCOLOR NONE LINE 0 0 -0.3 -1 END END END """ outf3.write(t1) outf3.close() gisdbase = grass.gisenv()['GISDBASE'] location = grass.gisenv()['LOCATION_NAME'] mapset = grass.gisenv()['MAPSET'] symbols_dir = os.path.join(gisdbase, location, mapset, 'symbol', 'arrows') symbol = os.path.join(symbols_dir, 'arrowhead_1') if not os.path.exists(symbols_dir): try: os.makedirs(symbols_dir) except OSError: pass if not os.path.isfile(symbol): shutil.copyfile(tmp3, symbol) # write LDM graph file and optionally display line of LDM with an arrow tmp4 = tmp + '.ldm' outf4 = file(tmp4, 'w') arrow_size = int(width) * 1.4 arrow_azim = 360 - float(end_azim) if ldm_type == 'direct': t2 = string.Template(""" move $start_coords width $width color $color draw $end_coords rotation $arrow_azim width $width symbol $symbol_s $arrow_size $end_coords $color """) s2 = t2.substitute(start_coords = start_coords, width = width, color = color, end_coords = end_coords, arrow_azim = arrow_azim, symbol_s = "arrows/arrowhead_1", arrow_size = arrow_size) else: t2 = string.Template(""" move $start_coords width $width color $color draw $end_coords """) s2 = t2.substitute(start_coords = start_coords, width = width, color = color, end_coords = end_coords) outf4.write(s2) outf4.close() if graph: shutil.copy(tmp4, graph) # save LDM line to vector if option "output" set if output: tmp5 = tmp + '.line' outf5 = file(tmp5, 'w') print >> outf5, str(start_coords) print >> outf5, str(end_coords) outf5.close() grass.run_command('v.in.lines', input_ = tmp5, output = output, separator = " ", overwrite = True, quiet = True) out_cats = output + '_cats' grass.run_command('v.category', input_ = output, option = 'add', output = out_cats, quiet = True, stderr = nuldev) grass.run_command('g.rename', vect = (out_cats,output), overwrite = True, quiet = True, stderr = nuldev) if circ_var: col = 'comp_angle double,dir_mean double,cir_var double,ave_x double,ave_y double,ave_len double' else: col = 'comp_angle double,dir_mean double,ave_x double,ave_y double,ave_len double' grass.run_command('v.db.addtable', map_ = output, columns = col, quiet = True, stderr = nuldev) tmp6 = tmp + '.sql' outf6 = file(tmp6, 'w') t3 = string.Template(""" UPDATE $output SET comp_angle = $comp_angle; UPDATE $output SET dir_mean = $ldm; UPDATE $output SET ave_x = $mc_x; UPDATE $output SET ave_y = $mc_y; UPDATE $output SET ave_len = $mean_length; """) s3 = t3.substitute(output = output, comp_angle = ("%0.3f" % comp_angle), ldm = ("%0.3f" % ldm), mc_x = ("%0.3f" % float(mc_x)), mc_y = ("%0.3f" % float(mc_y)), mean_length = ("%0.3f" % mean_length)) outf6.write(s3) if circ_var: print >> outf6, "UPDATE %s SET cir_var = %0.3f;" % (output, circ_var) outf6.close() grass.run_command('db.execute', input_ = tmp6, quiet = True, stderr = nuldev) # print LDM parameters to stdout (with <-g> flag in shell style): print_out = ['Compass Angle', 'Directional Mean', 'Average Center', 'Average Length'] if circ_var: print_out.append('Circular Variance') print_shell = ['compass_angle', 'directional_mean', 'average_center', 'average_length', 'circular_variance'] if circ_var: print_shell.append('circular_variance') print_vars = ["%0.3f" % comp_angle, "%0.3f" % ldm, "%0.3f" % float(mc_x) + ',' + "%0.3f" % float(mc_y), "%0.3f" % mean_length] if circ_var: print_vars.append("%0.3f" % circ_var) if flags['g']: for i,j in zip(print_shell, print_vars): print "%s=%s" % (i, j) else: for i,j in zip(print_out, print_vars): print "%s: %s" % (i, j) # diplay LDM graphics if flags['x']: if mon: if graph: grass.run_command('d.graph', input_ = graph, flags = 'm', quiet = True, stderr = nuldev) else: grass.run_command('d.graph', input_ = tmp4, flags = 'm', quiet = True, stderr = nuldev) elif graph: grass.message(_("\n Use this command in wxGUI \"Command console\" or with <d.mon> or with \"command layer\" to display LDM graphics: \n d.graph -m input=%s \n\n" ) % graph)
def calculate_lfp(input, output, idcol, id, coords, outlet, layer, outletidcol): prefix = "r_lfp_%d_" % os.getpid() if id: ids = id.split(",") for i in range(0, len(ids)): try: ids[i] = int(ids[i]) except: grass.fatal(_("Invalid ID '%s'") % ids[i]) else: ids = [] if coords: coords = coords.split(",") else: coords = [] # append outlet points to coordinates if outlet: p = grass.pipe_command("v.report", map=outlet, layer=layer, option="coor") for line in p.stdout: line = line.rstrip("\n") if line.startswith("cat|"): colnames = line.split("|") outletid_ind = -1 for i in range(0, len(colnames)): colname = colnames[i] if colname == outletidcol: outletid_ind = i elif colname == "x": x_ind = i elif colname == "y": y_ind = i if outletidcol and outletid_ind == -1: grass.fatal( _("Cannot find column <%s> in vector map <%s>") % (outletidcol, outlet)) continue cols = line.split("|") coords.extend([cols[x_ind], cols[y_ind]]) if outletid_ind >= 0: try: ids.extend([int(cols[outletid_ind])]) except: grass.fatal(_("Invalid ID '%s'") % ids[i]) p.wait() if p.returncode != 0: grass.fatal(_("Cannot read outlet points")) if len(ids) > 0: if len(ids) > len(coords) / 2: grass.fatal(_("Too many IDs")) elif len(ids) < len(coords) / 2: grass.fatal(_("Too few IDs")) assign_id = True else: assign_id = False # create the output vector map try: grass.run_command("v.edit", map=output, tool="create") except CalledModuleError: grass.fatal(_("Cannot create the output vector map")) if assign_id: try: grass.run_command("v.db.addtable", map=output, columns="%s integer" % idcol) except CalledModuleError: grass.fatal(_("Cannot add a table to the output vector map")) for i in range(0, len(coords) / 2): cat = i + 1 coor = "%s,%s" % (coords[2 * i], coords[2 * i + 1]) if assign_id: id = ids[i] grass.message(_("Processing outlet %d at %s...") % (id, coor)) else: grass.message(_("Processing outlet at %s...") % coor) # create the outlet vector map out = prefix + "out" p = grass.feed_command("v.in.ascii", overwrite=True, input="-", output=out, separator=",") p.stdin.write(coor) p.stdin.close() p.wait() if p.returncode != 0: grass.fatal(_("Cannot create the outlet vector map")) # convert the outlet vector map to raster try: grass.run_command("v.to.rast", overwrite=True, input=out, output=out, use="cat", type="point") except CalledModuleError: grass.fatal(_("Cannot convert the outlet vector to raster")) # calculate the downstream flow length flds = prefix + "flds" try: grass.run_command("r.stream.distance", overwrite=True, flags="om", stream_rast=out, direction=input, method="downstream", distance=flds) except CalledModuleError: grass.fatal(_("Cannot calculate the downstream flow length")) # find the longest flow length p = grass.pipe_command("r.info", flags="r", map=flds) max = "" for line in p.stdout: line = line.rstrip("\n") if line.startswith("max="): max = line.split("=")[1] break p.wait() if p.returncode != 0 or max == "": grass.fatal(_("Cannot find the longest flow length")) threshold = float(max) - 0.0005 # find the headwater cells heads = prefix + "heads" try: grass.run_command("r.mapcalc", overwrite=True, expression="%s=if(%s>=%f,1,null())" % (heads, flds, threshold)) except CalledModuleError: grass.fatal(_("Cannot find the headwater cells")) # create the headwater vector map try: grass.run_command("r.to.vect", overwrite=True, input=heads, output=heads, type="point") except CalledModuleError: grass.fatal(_("Cannot create the headwater vector map")) # calculate the longest flow path in vector format path = prefix + "path" try: grass.run_command("r.path", overwrite=True, input=input, vector_path=path, start_points=heads) except CalledModuleError: grass.fatal(_("Cannot create the longest flow path vector map")) # snap the outlet try: grass.run_command("r.to.vect", overwrite=True, input=out, output=out, type="point") except CalledModuleError: grass.fatal(_("Cannot snap the outlet")) # find the coordinates of the snapped outlet p = grass.pipe_command("v.to.db", flags="p", map=out, option="coor") coor = "" for line in p.stdout: line = line.rstrip("\n") if line == "cat|x|y|z": continue cols = line.split("|") coor = "%s,%s" % (cols[1], cols[2]) p.wait() if p.returncode != 0 or coor == "": grass.fatal(_("Cannot find the coordinates of the snapped outlet")) # split the longest flow path at the outlet try: grass.run_command("v.edit", map=path, tool="break", coords=coor) except CalledModuleError: grass.fatal(_("Cannot split the longest flow path at the outlet")) # select the final longest flow path lfp = prefix + "lfp" try: grass.run_command("v.select", overwrite=True, ainput=path, binput=heads, output=lfp) except CalledModuleError: grass.fatal(_("Cannot select the final longest flow path")) lfp2 = lfp + "2" try: grass.run_command("v.category", overwrite=True, input=lfp, output=lfp2, option="del", cat=-1) grass.run_command("v.category", overwrite=True, input=lfp2, output=lfp, option="add", cat=cat, step=0) except CalledModuleError: grass.fatal(_("Cannot add category %d") % cat) # copy the final longest flow path to the output map try: grass.run_command("v.edit", flags="r", map=output, tool="copy", bgmap=lfp, cats=0) except CalledModuleError: grass.fatal(_("Cannot copy the final longest flow path")) if assign_id: try: grass.run_command("v.to.db", map=output, option="cat", columns="cat") grass.run_command("v.db.update", map=output, column=idcol, value=id, where="cat=%d" % cat) except CalledModuleError: grass.fatal(_("Cannot assign ID %d") % id) # remove intermediate outputs grass.run_command("g.remove", flags="f", type="raster,vector", pattern="%s*" % prefix) # write history if supported version = grass.version() if version["revision"] != "exported": # the revision number is available version = int(version["revision"][1:]) else: # some binary distributions don't build from the SVN repository and # revision is not available; use the libgis revision as a fallback in # this case version = int(version["libgis_revision"]) if version >= 70740: # v.support -h added in r70740 grass.run_command("v.support", flags="h", map=output, cmdhist=os.environ["CMDLINE"])
def __init__(self, parent, size = (750, 400), title = _('About GRASS GIS'), **kwargs): wx.Frame.__init__(self, parent = parent, id = wx.ID_ANY, size = size, **kwargs) panel = wx.Panel(parent = self, id = wx.ID_ANY) # icon self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO)) # get version and web site vInfo = grass.version() infoTxt = wx.Panel(parent = panel, id = wx.ID_ANY) infoSizer = wx.BoxSizer(wx.VERTICAL) infoGridSizer = wx.GridBagSizer(vgap = 5, hgap = 5) infoGridSizer.AddGrowableCol(0) infoGridSizer.AddGrowableCol(1) logo = os.path.join(globalvar.ETCDIR, "gui", "icons", "grass.ico") logoBitmap = wx.StaticBitmap(parent = infoTxt, id = wx.ID_ANY, bitmap = wx.Bitmap(name = logo, type = wx.BITMAP_TYPE_ICO)) infoSizer.Add(item = logoBitmap, proportion = 0, flag = wx.ALL | wx.ALIGN_CENTER, border = 25) info = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = 'GRASS GIS ' + vInfo['version'] + '\n\n') info.SetFont(wx.Font(13, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, "")) infoSizer.Add(item = info, proportion = 0, flag = wx.BOTTOM | wx.ALIGN_CENTER, border = 15) row = 0 infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = _('Official GRASS site:')), pos = (row, 0), flag = wx.ALIGN_RIGHT) infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = 'http://grass.osgeo.org'), pos = (row, 1), flag = wx.ALIGN_LEFT) row += 2 infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = _('SVN Revision:')), pos = (row, 0), flag = wx.ALIGN_RIGHT) infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = vInfo['revision']), pos = (row, 1), flag = wx.ALIGN_LEFT) row += 1 infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = _('GIS Library Revision:')), pos = (row, 0), flag = wx.ALIGN_RIGHT) infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, label = vInfo['libgis_revision'] + ' (' + vInfo['libgis_date'].split(' ')[0] + ')'), pos = (row, 1), flag = wx.ALIGN_LEFT) infoSizer.Add(item = infoGridSizer, proportion = 1, flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL, border = 25) # create a flat notebook for displaying information about GRASS aboutNotebook = menuform.GNotebook(panel, style = globalvar.FNPageStyle | FN.FNB_NO_X_BUTTON) aboutNotebook.SetTabAreaColour(globalvar.FNPageColor) for title, win in ((_("Info"), infoTxt), (_("Copyright"), self._pageCopyright()), (_("License"), self._pageLicense()), (_("Authors"), self._pageCredit()), (_("Contributors"), self._pageContributors()), (_("Extra contributors"), self._pageContributors(extra = True)), (_("Translators"), self._pageTranslators())): aboutNotebook.AddPage(page = win, text = title) wx.CallAfter(aboutNotebook.SetSelection, 0) # buttons btnClose = wx.Button(parent = panel, id = wx.ID_CLOSE) btnSizer = wx.BoxSizer(wx.HORIZONTAL) btnSizer.Add(item = btnClose, proportion = 0, flag = wx.ALL | wx.ALIGN_RIGHT, border = 5) # bindings btnClose.Bind(wx.EVT_BUTTON, self.OnCloseWindow) infoTxt.SetSizer(infoSizer) infoSizer.Fit(infoTxt) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(item = aboutNotebook, proportion = 1, flag = wx.EXPAND | wx.ALL, border = 1) sizer.Add(item = btnSizer, proportion = 0, flag = wx.ALL | wx.ALIGN_RIGHT, border = 1) panel.SetSizer(sizer) self.Layout()
def _pageInfo(self): """Info page""" # get version and web site vInfo = grass.version() if not vInfo: sys.stderr.write(_("Unable to get GRASS version\n")) infoTxt = ScrolledPanel(self.aboutNotebook) infoTxt.SetBackgroundColour('WHITE') infoTxt.SetupScrolling() infoSizer = wx.BoxSizer(wx.VERTICAL) infoGridSizer = wx.GridBagSizer(vgap=5, hgap=5) logo = os.path.join(globalvar.ICONDIR, "grass-64x64.png") logoBitmap = wx.StaticBitmap( infoTxt, wx.ID_ANY, wx.Bitmap(name=logo, type=wx.BITMAP_TYPE_PNG)) infoSizer.Add(logoBitmap, proportion=0, flag=wx.ALL | wx.ALIGN_CENTER, border=20) infoLabel = 'GRASS GIS %s' % vInfo.get('version', _('unknown version')) if 'x86_64' in vInfo.get('build_platform', ''): infoLabel += ' (64bit)' info = StaticText(parent=infoTxt, id=wx.ID_ANY, label=infoLabel + os.linesep) info.SetFont(wx.Font(13, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, "")) info.SetForegroundColour(wx.Colour(35, 142, 35)) infoSizer.Add(info, proportion=0, flag=wx.BOTTOM | wx.ALIGN_CENTER, border=1) team = StaticText(parent=infoTxt, label=_grassDevTeam(1999) + '\n') infoSizer.Add(team, proportion=0, flag=wx.BOTTOM | wx.ALIGN_CENTER, border=1) row = 0 infoGridSizer.Add(StaticText(parent=infoTxt, id=wx.ID_ANY, label=_('Official GRASS site:')), pos=(row, 0), flag=wx.ALIGN_RIGHT) infoGridSizer.Add(HyperLinkCtrl(parent=infoTxt, id=wx.ID_ANY, label='https://grass.osgeo.org'), pos=(row, 1), flag=wx.ALIGN_LEFT) row += 2 infoGridSizer.Add(StaticText(parent=infoTxt, id=wx.ID_ANY, label='%s:' % _('Code Revision')), pos=(row, 0), flag=wx.ALIGN_RIGHT) infoGridSizer.Add(HyperLinkCtrl( parent=infoTxt, id=wx.ID_ANY, label=vInfo.get('revision', '?'), URL='https://github.com/OSGeo/grass.git'), pos=(row, 1), flag=wx.ALIGN_LEFT) row += 1 infoGridSizer.Add(StaticText(parent=infoTxt, id=wx.ID_ANY, label='%s:' % _('Build Date')), pos=(row, 0), flag=wx.ALIGN_RIGHT) infoGridSizer.Add(StaticText(parent=infoTxt, id=wx.ID_ANY, label=vInfo.get('build_date', '?')), pos=(row, 1), flag=wx.ALIGN_LEFT) # show only basic info # row += 1 # infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, # label = '%s:' % _('GIS Library Revision')), # pos = (row, 0), # flag = wx.ALIGN_RIGHT) # infoGridSizer.Add(item = wx.StaticText(parent = infoTxt, id = wx.ID_ANY, # label = vInfo['libgis_revision'] + ' (' + # vInfo['libgis_date'].split(' ')[0] + ')'), # pos = (row, 1), # flag = wx.ALIGN_LEFT) row += 2 infoGridSizer.Add(StaticText(parent=infoTxt, id=wx.ID_ANY, label='Python:'), pos=(row, 0), flag=wx.ALIGN_RIGHT) infoGridSizer.Add(StaticText(parent=infoTxt, id=wx.ID_ANY, label=platform.python_version()), pos=(row, 1), flag=wx.ALIGN_LEFT) row += 1 infoGridSizer.Add(StaticText(parent=infoTxt, id=wx.ID_ANY, label='wxPython:'), pos=(row, 0), flag=wx.ALIGN_RIGHT) infoGridSizer.Add(StaticText(parent=infoTxt, id=wx.ID_ANY, label=wx.__version__), pos=(row, 1), flag=wx.ALIGN_LEFT) infoGridSizer.AddGrowableCol(0) infoGridSizer.AddGrowableCol(1) infoSizer.Add(infoGridSizer, proportion=1, flag=wx.EXPAND) row += 2 infoGridSizer.Add(StaticText(parent=infoTxt, id=wx.ID_ANY, label="%s:" % _('Language')), pos=(row, 0), flag=wx.ALIGN_RIGHT) self.langUsed = grass.gisenv().get('LANG', None) if not self.langUsed: import locale loc = locale.getdefaultlocale() if loc == (None, None): self.langUsed = _('unknown') else: self.langUsed = u'%s.%s' % (loc[0], loc[1]) infoGridSizer.Add(StaticText(parent=infoTxt, id=wx.ID_ANY, label=self.langUsed), pos=(row, 1), flag=wx.ALIGN_LEFT) infoTxt.SetSizer(infoSizer) infoSizer.Fit(infoTxt) return infoTxt
def write_metadata(self): gs.message(_("Writing metadata to maps...")) ip_meta = {} for mtd_file in self._filter("MTD_TL.xml"): ip = self._ip_from_path(mtd_file) ip_meta[ip] = self._parse_mtd_file(mtd_file) if not ip_meta: gs.warning( _("Unable to determine timestamps. No metadata file found")) for img_file in self.files: map_name = self._map_name(img_file) ip = self._ip_from_path(img_file) meta = ip_meta[ip] if meta: bn = map_name.split("_")[2].lstrip("B").rstrip("A") if bn.isnumeric(): bn = int(bn) else: continue timestamp = meta["timestamp"] timestamp_str = timestamp.strftime("%d %b %Y %H:%M:%S.%f") descr_list = [] for dkey in meta.keys(): if dkey != "timestamp": if "TH_ANGLE_" in dkey: if dkey.endswith("TH_ANGLE_{}".format(bn)): descr_list.append("{}={}".format( dkey, meta[dkey])) else: descr_list.append("{}={}".format(dkey, meta[dkey])) descr = "\n".join(descr_list) bands = (gs.read_command( "g.list", type="raster", mapset=".", pattern="{}*".format(map_name), ).rstrip("\n").split("\n")) descr_dict = { dl.split("=")[0]: dl.split("=")[1] for dl in descr_list } env = gs.gisenv() json_standard_folder = os.path.join(env["GISDBASE"], env["LOCATION_NAME"], env["MAPSET"], "cell_misc") if flags["j"] and not os.path.isdir(json_standard_folder): os.makedirs(json_standard_folder) support_args = { "map": map_name, "source1": ip, "source2": img_file, "history": descr, } # Band references/semantic labels available from GRASS GIS 8.0.0 onwards if float(gs.version()["version"][0:3]) >= 7.9: support_args[ "semantic_label"] = self._extract_semantic_label( map_name) for band in bands: gs.run_command("r.support", **support_args) gs.run_command("r.timestamp", map=map_name, date=timestamp_str) if flags["j"]: metadatajson = os.path.join(json_standard_folder, map_name, "description.json") elif options["metadata"]: metadatajson = os.path.join(options["metadata"], map_name, "description.json") if flags["j"] or options["metadata"]: if not os.path.isdir(os.path.dirname(metadatajson)): os.makedirs(os.path.dirname(metadatajson)) with open(metadatajson, "w") as outfile: json.dump(descr_dict, outfile)
import sys import os import atexit try: import grass.script as grass except: try: from grass.script import core as grass except: if "GISBASE" not in os.environ: print("You must be in GRASS GIS to run this program.") sys.exit(1) grass_version = grass.version().get('version')[0:2] if grass_version != '7.': grass.fatal(_("Sorry, this script works in GRASS 7.* only")) else: from grass.lib.gis import * from grass.lib.vector import * from grass.lib.raster import * def cleanup(): if tmp: grass.run_command("g.remove", type="raster", name="%s" % tmp, quiet=True, stderr=nuldev)
fXML = os.path.join(addon_base, 'modules.xml') if not os.path.exists(fXML): return [] # read XML file fo = open(fXML, 'r') try: tree = etree.fromstring(fo.read()) except StandardError, e: grass.error(_("Unable to parse metadata file: %s") % e) fo.close() return [] fo.close() libgis_rev = grass.version()['libgis_revision'] ret = list() for tnode in tree.findall('task'): gnode = tnode.find('libgis') if gnode is not None and \ gnode.get('revision', '') != libgis_rev: ret.append(tnode.get('name')) return ret def main(): if flags['f']: extensions = grass.read_command('g.extension.py', quiet = True, flags = 'a').splitlines() else: extensions = get_extensions()
def main(): if platform.system() == 'Windows': try: import winreg except ImportError: import _winreg as winreg try: try: key = winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall', 0, winreg.KEY_READ | winreg.KEY_WOW64_64KEY) count = (winreg.QueryInfoKey(key)[0]) - 1 while (count >= 0): subkeyR = winreg.EnumKey(key, count) if subkeyR.startswith('R for'): count = -1 else: count = count - 1 winreg.CloseKey(key) key = winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, str('SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\' + subkeyR), 0, winreg.KEY_READ | winreg.KEY_WOW64_64KEY) value = winreg.QueryValueEx(key, 'InstallLocation')[0] winreg.CloseKey(key) except: key = winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall', 0, winreg.KEY_READ | winreg.KEY_WOW64_32KEY) count = (winreg.QueryInfoKey(key)[0]) - 1 while (count >= 0): subkeyR = winreg.EnumKey(key, count) if subkeyR.startswith('R for'): count = -1 else: count = count - 1 winreg.CloseKey(key) key = winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, str('SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\' + subkeyR), 0, winreg.KEY_READ | winreg.KEY_WOW64_64KEY) value = winreg.QueryValueEx(key, 'InstallLocation')[0] winreg.CloseKey(key) grass.message(_("R is installed!")) pathtor = os.path.join(value, 'bin\\Rscript') except: grass.fatal("Please install R!") else: try: subprocess.call(['which', 'R']) grass.message(_("R is installed!")) pathtor = 'Rscript' except: grass.fatal("Please install R!") elevation = str(options['elevation']).split('@')[0] incheck = grass.find_file(name=elevation, element='cell') if not incheck['file']: grass.fatal("Raster map <%s> not found" % elevation) grass.use_temp_region() grass.run_command('g.region', rast=elevation) user_res = int(options['user_res']) if user_res == 0: gregion = grass.region() res_int = int(round(gregion['nsres'])) grass.message(_("Resolution is kept at: %i m" % res_int)) else: res_int = user_res grass.run_command('g.region', res=res_int) coarse_elevation = elevation + '%' + str(user_res) grass.run_command('r.resample', input=elevation, output=coarse_elevation) elevation = coarse_elevation grass.message(_("Resolution changed to: %s m" % user_res)) minneighb = int(options['minneighb']) maxneighb = int(options['maxneighb']) outpdf = str(options['profile']) if outpdf.split('.')[-1] != 'pdf': grass.fatal("File type for output TG calculation profile is not pdf") outcsv = str(options['table']) if outcsv.split('.')[-1] != 'csv': grass.fatal("File type for output TG calculation table is not csv") tgmaps = flags['c'] grassversion = grass.version() grassversion = grassversion.version[:1] TGargs = [ elevation, str(res_int), str(minneighb), str(maxneighb), outpdf, outcsv, str(int(tgmaps)), str(grassversion) ] pyscfold = os.path.dirname(os.path.realpath(__file__)) pathtosc = os.path.join(pyscfold, 'TG_jozsa.R') myRSCRIPT = [pathtor, pathtosc] + TGargs if not os.path.isfile(pathtosc): grass.fatal("Put TG calculation R script to GRASS scripts folder...") if tgmaps: grass.message( _("Will create map of cell-based TG value, relative relief...")) grass.message( _("Starting R to calculate Topographic Grain... this may take some time..." )) devnull = open(os.devnull, 'w') error = subprocess.call(myRSCRIPT, stdout=devnull, stderr=devnull) if error > 0: grass.message(_("R error log below...")) errorlog = os.path.join(os.path.dirname(outpdf), 'errorlog.Rout') Rerror = open(errorlog, 'r') grass.message(_(Rerror.read())) Rerror.close() grass.fatal("TG calculation failed...") else: grass.message( _("R process finished...Continue working in GRASS GIS...")) elevation = str(options['elevation']).split('@')[0] grass.run_command('g.region', rast=elevation) ## Check if creating geomorphon map flag is activated geom = flags['g'] if not geom: grass.message(_("Not creating geomorphometric map...")) with open(outcsv, 'r') as csvfile: outcsv = csv.reader(csvfile, delimiter=',') for row in outcsv: last = row searchtg = int(last[1]) if user_res != 0: gregion = grass.region() res_int = int(round(gregion['nsres'])) multiply = int(user_res / res_int) searchtg = int(searchtg * multiply) grass.message(_("Estimated topographic grain value is %i" % searchtg)) else: ## Check if r.geomorphon is installed if not grass.find_program('r.geomorphon', '--help'): grass.fatal( "r.geomorphon is not installed, run separately after installation" ) else: ## Input for r.geomorphon #elevation = elevation reread above with open(outcsv, 'r') as csvfile: outcsv = csv.reader(csvfile, delimiter=',') for row in outcsv: last = row searchtg = int(last[1]) if user_res != 0: multiply = int(user_res / int_res) searchtg = int(searchtg * multiply) skiptg = int(options['skiptg']) flattg = float(options['flattg']) disttg = int(options['disttg']) geom_map = str(options['geom_map']) if geom_map[:11] == '<elevation>': geom_map = str(elevation + geom_map[11:-4] + str(searchtg)) ## Print out settings for geomorphon mapping grass.message(_("Generating geomorphons map with settings below:")) grass.message(_("Elevation map: %s" % elevation)) grass.message(_("Search distance: %i" % searchtg)) grass.message(_("Skip radius: %i" % skiptg)) grass.message(_("Flatness threshold: %.2f" % flattg)) grass.message(_("Flatness distance: %i" % disttg)) grass.message( _("Output map: %s" % geom_map + " *existing map will be overwritten")) try: grass.run_command('r.geomorphon', elevation=elevation, search=searchtg, skip=skiptg, flat=flattg, dist=disttg, forms=geom_map) except: grass.run_command('r.geomorphon', dem=elevation, search=searchtg, skip=skiptg, flat=flattg, dist=disttg, forms=geom_map) grass.del_temp_region()
import sys import os import atexit try: import grass.script as grass except: try: from grass.script import core as grass except: if not os.environ.has_key("GISBASE"): print "You must be in GRASS GIS to run this program." sys.exit(1) grass_version = grass.version().get('version')[0:3] if grass_version != '6.4': grass.fatal(_("Sorry, this script works in GRASS 6.4.* only")) else: from grass.lib.gis import * from grass.lib.vector import * def cleanup(): nuldev = file(os.devnull, 'w') if tmp: grass.run_command('g.remove', rast = '%s' % tmp, quiet = True, stderr = nuldev) def main():
pass else: sys.exit( """ In current version of program, must define: dem ---------> elevation data set name in current GRASS location resolution --> of CHILD grid n, s, w, e --> boundary conditions """ ) try: from grass import script as g print "---------------------------" print "GRASS GIS RUNNING. VERSION:" version = g.version() for row in version.items(): for item in row: print item, print "" print "ENVIRONMENT:" gisenv = g.gisenv() for row in gisenv.items(): for item in row: print item, print "" print "---------------------------" except: sys.exit("Must be run inside GRASS GIS; tested only with GRASS 7.0") # Create vector map around boundaries and classify them
def convert_lfp(input, output, coords): # calculate the diagonal resolution p = grass.pipe_command("r.info", flags="g", map=input) res = "" for line in p.stdout: line = line.rstrip("\n") if line.startswith("nsres="): res = line.split("=")[1] break p.wait() if p.returncode != 0 or res == "": grass.fatal(_("Cannot read the resolution of the input raster map")) res = float(res) diagres = math.ceil(math.sqrt(2) * res) # convert the input lfp raster to vector try: grass.run_command("r.to.vect", input=input, output=output, type="line") except CalledModuleError: grass.fatal(_("Cannot convert the input raster map to a vector map")) # r.to.vect sometimes produces continous line segments that are not # connected; merge them first try: grass.run_command("v.edit", map=output, tool="merge", where="") except CalledModuleError: grass.fatal(_("Cannot merge features in the output vector map")) # remove dangles try: grass.run_command("v.edit", map=output, tool="delete", query="dangle", threshold="0,0,-%f" % diagres) except CalledModuleError: grass.fatal(_("Cannot delete dangles from the output vector map")) try: grass.run_command("v.edit", map=output, tool="merge", where="") except CalledModuleError: grass.fatal(_("Cannot merge features in the output vector map")) # remove the shorter path from closed loops; these are not dangles try: grass.run_command("v.edit", map=output, tool="delete", query="length", threshold="0,0,-%f" % diagres) except CalledModuleError: grass.fatal(_("Cannot delete dangles from the output vector map")) try: grass.run_command("v.edit", map=output, tool="merge", where="") except CalledModuleError: grass.fatal(_("Cannot merge features in the output vector map")) # see how many lines are left p = grass.pipe_command("v.info", flags="t", map=output) lines = "" for line in p.stdout: line = line.rstrip("\n") if line.startswith("lines="): lines = line.split("=")[1] break p.wait() if p.returncode != 0 or lines == "": grass.fatal(_("Cannot read lines from the output vector map info")) lines = int(lines) if lines == 0: grass.fatal(_("Cannot create the longest flow path")) elif lines > 1: grass.fatal(_("Cannot simplify the longest flow path")) # leave only the minimum category p = grass.pipe_command("v.report", map=output, option="length") mincat = "" maxcat = "" for line in p.stdout: line = line.rstrip("\n") if line.startswith("cat|value|"): continue cat = line.split("|")[0] if mincat == "": mincat = cat maxcat = cat p.wait() if p.returncode != 0 or mincat == "" or maxcat == "": grass.fatal( _("Cannot read min/max categories from the output vector map")) mincat = int(mincat) maxcat = int(maxcat) try: grass.run_command("v.edit", map=output, tool="catdel", cats="%d-%d" % (mincat + 1, maxcat), where="") except CalledModuleError: grass.fatal(_("Cannot delete categories from the output vector map")) # if the outlet coordinates are given, flip the longest flow path so that # its end node is at the downstream end if coords != "": p = grass.pipe_command("v.to.db", flags="p", map=output, option="start") startx = "" starty = "" for line in p.stdout: line = line.rstrip("\n") if line == "cat|x|y|z": continue cols = line.split("|") startx = cols[1] starty = cols[2] p.wait() if p.returncode != 0 or startx == "" or starty == "": grass.fatal( _("Cannot read the start point of the longest flow path")) startx = float(startx) starty = float(starty) outxy = coords.split(",") outx = float(outxy[0]) outy = float(outxy[1]) if startx >= outx - res * 0.5 and startx <= outx + res * 0.5 and \ starty >= outy - res * 0.5 and starty <= outy + res * 0.5: try: grass.run_command("v.edit", map=output, tool="flip", where="") except CalledModuleError: grass.fatal(_("Cannot flip the longest flow path")) # write history if supported version = grass.version() if version["revision"] != "exported": # the revision number is available version = int(version["revision"][1:]) else: # some binary distributions don't build from the SVN repository and # revision is not available; use the libgis revision as a fallback in # this case version = int(version["libgis_revision"]) if version >= 70740: # v.support -h added in r70740 grass.run_command("v.support", flags="h", map=output, cmdhist=os.environ["CMDLINE"])