def mapsets(self, pattern=None, permissions=True): """Return a list of the available mapsets. :param pattern: the pattern to filter the result :type pattern: str :param permissions: check the permission of mapset :type permissions: bool :return: a list of mapset's names :rtype: list of strings :: >>> location = Location() >>> sorted(location.mapsets()) # doctest: +ELLIPSIS [...] """ mapsets = [mapset for mapset in self] if permissions: mapsets = [ mapset for mapset in mapsets if libgis.G_mapset_permissions(encode(mapset)) ] if pattern: return fnmatch.filter(mapsets, pattern) return mapsets
def wait(self): """Wait for the module to finish. Call this method if the run() call was performed with self.false_ = False. :return: A reference to this object """ if self._finished is False: if self.stdin: self.stdin = encode(self.stdin) stdout, stderr = self._popen.communicate(input=self.stdin) self.outputs["stdout"].value = decode(stdout) if stdout else "" self.outputs["stderr"].value = decode(stderr) if stderr else "" self.time = time.time() - self.start_time self.returncode = self._popen.returncode self._finished = True if self._popen.poll(): raise CalledModuleError( returncode=self._popen.returncode, code=self.get_bash(), module=self.name, errors=stderr, ) self._popen = None return self
def _set_date(self, datetimeobj): if datetimeobj: date_str = datetimeobj.strftime(self.date_fmt) date_str = encode(date_str) return libraster.Rast_set_history(self.c_hist, libraster.HIST_MAPID, ctypes.c_char_p(date_str))
def _write(self, mapsets): """Write to SEARCH_PATH file the changes in the search path :param mapsets: a list of mapset's names :type mapsets: list """ with open(self.spath, "wb+") as f: ms = [decode(m) for m in self.location.mapsets()] f.write(b"\n".join([encode(m) for m in mapsets if m in ms]))
def locations(self): """Return a list of locations that are available in the gisdbase: :: >>> gisdbase = Gisdbase() >>> gisdbase.locations() # doctest: +ELLIPSIS [...] .. """ return sorted([loc for loc in listdir(self.name) if libgis.G_is_location(encode(join(self.name, loc)))])
def run(self): while True: line = self.inf.readline() if not line: break line = line.replace(self.ifs, " ") line = encode(line) self.outf.write(line) self.outf.flush() self.outf.close()
def main(): table = options['table'] force = flags['f'] if not options['driver'] or not options['database']: # check if DB parameters are set, and if not set them. grass.run_command('db.connect', flags='c', quiet=True) kv = grass.db_connection() if options['database']: database = options['database'] else: database = kv['database'] if options['driver']: driver = options['driver'] else: driver = kv['driver'] # schema needed for PG? if force: grass.message(_("Forcing ...")) # check if table exists if not grass.db_table_exist(table): grass.warning( _("Table <%s> not found in database <%s>") % (table, database)) sys.exit(0) # check if table is used somewhere (connected to vector map) used = grass.db.db_table_in_vector(table) if used: grass.warning( _("Deleting table <%s> which is attached to following map(s):") % table) for vect in used: grass.warning("%s" % vect) if not force: grass.message(_("The table <%s> would be deleted.") % table) grass.message("") grass.message( _("You must use the force flag to actually remove it. Exiting.")) sys.exit(0) p = grass.feed_command('db.execute', input='-', database=database, driver=driver) p.stdin.write(encode("DROP TABLE " + table)) p.stdin.close() p.wait() if p.returncode != 0: grass.fatal(_("Cannot continue (problem deleting table)."))
def text_file_md5(filename, exclude_lines=None, exclude_re=None, prepend_lines=None, append_lines=None): """Get a MD5 (check) sum of a text file. Works in the same way as `file_md5()` function but ignores newlines characters and excludes lines from the file as well as prepend or append them if requested. :param exclude_lines: list of strings to be excluded (newline characters should not be part of the strings) :param exclude_re: regular expression string; lines matching this regular expression will not be considered :param prepend_lines: list of lines to be prepended to the file before computing the sum :param append_lines: list of lines to be appended to the file before computing the sum """ hasher = hashlib.md5() if exclude_re: regexp = re.compile(exclude_re) if prepend_lines: for line in prepend_lines: hasher.update(line if sys.version_info[0] == 2 else encode(line)) with open(filename, "r") as f: for line in f: # replace platform newlines by standard newline if os.linesep != "\n": line = line.rstrip(os.linesep) + "\n" if exclude_lines and line in exclude_lines: continue if exclude_re and regexp.match(line): continue hasher.update(line if sys.version_info[0] == 2 else encode(line)) if append_lines: for line in append_lines: hasher.update(line if sys.version_info[0] == 2 else encode(line)) return hasher.hexdigest()
def SnapToNode(e, n, tresh, vectMap): """Find nearest node to click coordinates (within given threshold)""" if not haveCtypes: return None vectMap, mapSet = ParseMapStr(vectMap) openedMap = pointer(vectlib.Map_info()) ret = vectlib.Vect_open_old(openedMap, c_char_p(encode(vectMap)), c_char_p(encode(mapSet))) if ret == 1: vectlib.Vect_close(openedMap) if ret != 2: return None nodeNum = vectlib.Vect_find_node(openedMap, c_double(e), c_double(n), c_double(0), c_double(tresh), vectlib.WITHOUT_Z) if nodeNum > 0: e = c_double(0) n = c_double(0) vectlib.Vect_get_node_coor(openedMap, nodeNum, byref(e), byref(n), None) # z e = e.value n = n.value else: vectlib.Vect_close(openedMap) return False return e, n
def main(): map = options['map'] layer = options['layer'] columns = options['columns'] columns = [col.strip() for col in columns.split(',')] # does map exist in CURRENT mapset? mapset = grass.gisenv()['MAPSET'] exists = bool( grass.find_file(map, element='vector', mapset=mapset)['file']) if not exists: grass.fatal(_("Vector map <%s> not found in current mapset") % map) try: f = grass.vector_db(map)[int(layer)] except KeyError: grass.fatal( _("There is no table connected to this map. Run v.db.connect or v.db.addtable first." )) table = f['table'] database = f['database'] driver = f['driver'] column_existing = grass.vector_columns(map, int(layer)).keys() for col in columns: if not col: grass.fatal( _("There is an empty column. Did you leave a trailing comma?")) col_name = col.split(' ')[0].strip() if col_name in column_existing: grass.error( _("Column <%s> is already in the table. Skipping.") % col_name) continue grass.verbose(_("Adding column <%s> to the table") % col_name) p = grass.feed_command('db.execute', input='-', database=database, driver=driver) res = "ALTER TABLE {} ADD COLUMN {}".format(table, col) p.stdin.write(encode(res)) grass.debug(res) p.stdin.close() if p.wait() != 0: grass.fatal(_("Unable to add column <%s>.") % col) # write cmd history: grass.vector_history(map)
def test_write_labels_bytes(self): """This tests if Python module works""" write_command( "r.category", map=self.raster, rules="-", stdin="1:kůň\n2:kráva\n3:ovečka\n4:býk", separator=":", encoding=None, ) res = read_command( "r.category", map=self.raster, separator=":", encoding=None ).strip() self.assertEquals(res, encode("1:kůň\n2:kráva\n3:ovečka\n4:býk")) self.assertIsInstance(res, bytes)
def is_valid(value, path, type): """Private function to check the correctness of a value. :param value: Name of the directory :type value: str :param path: Path where the directory is located :type path: path :param type: it is a string defining the type that will e checked, valid types are: GISBASE, GISDBASE, LOCATION_NAME, MAPSET :type type: str :return: True if valid else False :rtype: str """ return bool(CHECK_IS[type](encode(join(path, value))))
def test_bytes_garbage_in_out(self): """If the input is bytes we should not touch it for encoding""" self.assertEqual( b"P\xc5\x99\xc3\xad\xc5\xa1ern\xc3\xbd k\xc5\xaf\xc5\x88", utils.encode("Příšerný kůň"), )
def test_unicode(self): self.assertEqual(b"text", utils.encode("text"))
def test_bytes(self): self.assertEqual(b"text", utils.encode(b"text"))
def GetNearestNodeCat(e, n, layer, tresh, vectMap): if not haveCtypes: return -2 vectMapName, mapSet = ParseMapStr(vectMap) openedMap = pointer(vectlib.Map_info()) ret = vectlib.Vect_open_old(openedMap, c_char_p(encode(vectMapName)), c_char_p(encode(mapSet))) if ret == 1: vectlib.Vect_close(openedMap) if ret != 2: return -1 nodeNum = vectlib.Vect_find_node(openedMap, c_double(e), c_double(n), c_double(0), c_double(tresh), vectlib.WITHOUT_Z) if nodeNum > 0: e = c_double(0) n = c_double(0) vectlib.Vect_get_node_coor(openedMap, nodeNum, byref(e), byref(n), None) # z e = e.value n = n.value else: vectlib.Vect_close(openedMap) return -1 box = vectlib.bound_box() List = POINTER(vectlib.boxlist) List = vectlib.Vect_new_boxlist(c_int(0)) box.E = box.W = e box.N = box.S = n box.T = box.B = 0 vectlib.Vect_select_lines_by_box( openedMap, byref(box), vectlib.GV_POINT, List) found = 0 dcost = 0 Cats = POINTER(vectlib.line_cats) Cats = vectlib.Vect_new_cats_struct() cat = c_int(0) for j in range(List.contents.n_values): line = List.contents.id[j] type = vectlib.Vect_read_line(openedMap, None, Cats, line) if type != vectlib.GV_POINT: continue if vectlib.Vect_cat_get(Cats, c_int(layer), byref(cat)): found = 1 break if found: return cat.value return -1
def HashCmd(cmd, region): """Returns a hash from command given as a list and a region as a dict.""" name = "_".join(cmd) if region: name += str(sorted(region.items())) return hashlib.sha1(encode(name)).hexdigest()
def test_bytes_grabage_in_out(self): """If the input is bytes we should not touch it for encoding""" self.assertEqual(b'Příšerný kůň', utils.encode(b'Příšerný kůň'))
def test_none(self): """If the input is a boolean return bytes""" if sys.version_info.major >= 3: self.assertRaises(TypeError, utils.encode, None) else: self.assertEqual("None", utils.encode(None))
def test_unicode(self): self.assertEqual(b'text', utils.encode(u'text'))
def main(): global temp_dist, temp_src input = options['input'] output = options['output'] distances = options['distances'] units = options['units'] zero = flags['z'] tmp = str(os.getpid()) temp_dist = "r.buffer.tmp.%s.dist" % tmp temp_src = "r.buffer.tmp.%s.src" % tmp # check if input file exists if not grass.find_file(input)['file']: grass.fatal(_("Raster map <%s> not found") % input) scale = scales[units] distances = distances.split(',') distances1 = [scale * float(d) for d in distances] distances2 = [d * d for d in distances1] s = grass.read_command("g.proj", flags='j') kv = grass.parse_key_val(s) if kv['+proj'] == 'longlat': metric = 'geodesic' else: metric = 'squared' grass.run_command('r.grow.distance', input=input, metric=metric, distance=temp_dist, flags='m') if zero: exp = "$temp_src = if($input == 0,null(),1)" else: exp = "$temp_src = if(isnull($input),null(),1)" grass.message(_("Extracting buffers (1/2)...")) grass.mapcalc(exp, temp_src=temp_src, input=input) exp = "$output = if(!isnull($input),$input,%s)" if metric == 'squared': for n, dist2 in enumerate(distances2): exp %= "if($dist <= %f,%d,%%s)" % (dist2, n + 2) else: for n, dist2 in enumerate(distances1): exp %= "if($dist <= %f,%d,%%s)" % (dist2, n + 2) exp %= "null()" grass.message(_("Extracting buffers (2/2)...")) grass.mapcalc(exp, output=output, input=temp_src, dist=temp_dist) p = grass.feed_command('r.category', map=output, separator=':', rules='-') msg = "1:distances calculated from these locations\n" p.stdin.write(encode(msg)) d0 = "0" for n, d in enumerate(distances): msg = "%d:%s-%s %s\n" % (n + 2, d0, d, units) p.stdin.write(encode(msg)) d0 = d p.stdin.close() p.wait() grass.run_command('r.colors', map=output, color='rainbow') # write cmd history: grass.raster_history(output)
def HashCmds(cmds, region): """Returns a hash from list of commands and regions as dicts.""" name = ";".join([item for sublist in cmds for item in sublist]) if region: name += str(sorted(region.items())) return hashlib.sha1(encode(name)).hexdigest()
def call_module(module, stdin=None, merge_stderr=False, capture_stdout=True, capture_stderr=True, **kwargs): r"""Run module with parameters given in `kwargs` and return its output. >>> print (call_module('g.region', flags='pg')) # doctest: +ELLIPSIS projection=... zone=... n=... s=... w=... >>> call_module('m.proj', flags='i', input='-', stdin="50.0 41.5") '8642890.65|6965155.61|0.00\n' >>> call_module('g.region', aabbbccc='notexist') # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... CalledModuleError: Module run g.region ... ended with error If `stdin` is not set and `kwargs` contains ``input`` with value set to ``-`` (dash), the function raises an error. Note that ``input`` nor ``output`` parameters are used by this function itself, these are usually module parameters which this function just passes to it. However, when ``input`` is in parameters the function checks if its values is correct considering value of ``stdin`` parameter. :param str module: module name :param stdin: string to be used as module standard input (stdin) or `None` :param merge_stderr: if the standard error output should be merged with stdout :param kwargs: module parameters :returns: module standard output (stdout) as string or None if apture_stdout is False :raises CalledModuleError: if module return code is non-zero :raises ValueError: if the parameters are not correct .. note:: The data read is buffered in memory, so do not use this method if the data size is large or unlimited. """ # TODO: remove this: do_doctest_gettext_workaround() # implementation inspired by subprocess.check_output() function if stdin: if 'input' in kwargs and kwargs['input'] != '-': raise ValueError( _("input='-' must be used when stdin is specified")) if stdin == subprocess.PIPE: raise ValueError(_("stdin must be string or buffer, not PIPE")) kwargs['stdin'] = subprocess.PIPE # to be able to send data to stdin elif 'input' in kwargs and kwargs['input'] == '-': raise ValueError(_("stdin must be used when input='-'")) if merge_stderr and not (capture_stdout and capture_stderr): raise ValueError( _("You cannot merge stdout and stderr and not capture them")) if 'stdout' in kwargs: raise TypeError( _("stdout argument not allowed, it could be overridden")) if 'stderr' in kwargs: raise TypeError( _("stderr argument not allowed, it could be overridden")) if capture_stdout: kwargs['stdout'] = subprocess.PIPE if capture_stderr: if merge_stderr: kwargs['stderr'] = subprocess.STDOUT else: kwargs['stderr'] = subprocess.PIPE process = start_command(module, **kwargs) # input=None means no stdin (our default) # for no stdout, output is None which is out interface # for stderr=STDOUT or no stderr, errors is None # which is fine for CalledModuleError output, errors = process.communicate( input=encode(decode(stdin)) if stdin else None) returncode = process.poll() if returncode: raise CalledModuleError(returncode, module, kwargs, errors) return decode(output) if output else None
def RunCommand(prog, flags="", overwrite=False, quiet=False, verbose=False, parent=None, read=False, parse=None, stdin=None, getErrorMsg=False, **kwargs): """Run GRASS command :param prog: program to run :param flags: flags given as a string :param overwrite, quiet, verbose: flags :param parent: parent window for error messages :param read: fetch stdout :param parse: fn to parse stdout (e.g. grass.parse_key_val) or None :param stdin: stdin or None :param getErrorMsg: get error messages on failure :param kwargs: program parameters :return: returncode (read == False and getErrorMsg == False) :return: returncode, messages (read == False and getErrorMsg == True) :return: stdout (read == True and getErrorMsg == False) :return: returncode, stdout, messages (read == True and getErrorMsg == True) :return: stdout, stderr """ cmdString = ' '.join( grass.make_command(prog, flags, overwrite, quiet, verbose, **kwargs)) Debug.msg(1, "gcmd.RunCommand(): %s" % cmdString) kwargs['stderr'] = subprocess.PIPE if read: kwargs['stdout'] = subprocess.PIPE if stdin: kwargs['stdin'] = subprocess.PIPE if parent: messageFormat = os.getenv('GRASS_MESSAGE_FORMAT', 'gui') os.environ['GRASS_MESSAGE_FORMAT'] = 'standard' start = time.time() ps = grass.start_command(prog, flags, overwrite, quiet, verbose, **kwargs) if stdin: ps.stdin.write(encode(stdin)) ps.stdin.close() ps.stdin = None stdout, stderr = list(map(DecodeString, ps.communicate())) if parent: # restore previous settings os.environ['GRASS_MESSAGE_FORMAT'] = messageFormat ret = ps.returncode Debug.msg( 1, "gcmd.RunCommand(): get return code %d (%.6f sec)" % (ret, (time.time() - start))) if ret != 0: if stderr: Debug.msg(2, "gcmd.RunCommand(): error %s" % stderr) else: Debug.msg(2, "gcmd.RunCommand(): nothing to print ???") if parent: GError(parent=parent, caption=_("Error in %s") % prog, message=stderr) if not read: if not getErrorMsg: return ret else: return ret, _formatMsg(stderr) if stdout: Debug.msg(3, "gcmd.RunCommand(): return stdout\n'%s'" % stdout) else: Debug.msg(3, "gcmd.RunCommand(): return stdout = None") if parse: stdout = parse(stdout) if not getErrorMsg: return stdout if read and getErrorMsg: return ret, stdout, _formatMsg(stderr) return stdout, _formatMsg(stderr)
def test_bytes(self): self.assertEqual(b'text', utils.encode(b'text'))
def test_int(self): """If the input is an integer return bytes""" if sys.version_info.major >= 3: self.assertRaises(TypeError, utils.encode, 1234567890) else: self.assertEqual("1234567890", utils.encode(1234567890))
def test_none(self): """If the input is a boolean return bytes""" self.assertEqual(b'None', utils.encode(None))
def test_float(self): """If the input is a float return bytes""" if sys.version_info.major >= 3: self.assertRaises(TypeError, utils.encode, 12345.6789) else: self.assertEqual("12345.6789", utils.encode(12345.6789))
def test_float(self): """If the input is a float return bytes""" self.assertEqual(b'12345.6789', utils.encode(12345.6789))
def main(): global temp_dist, temp_src input = options["input"] output = options["output"] distances = options["distances"] units = options["units"] zero = flags["z"] tmp = str(os.getpid()) temp_dist = "r.buffer.tmp.%s.dist" % tmp temp_src = "r.buffer.tmp.%s.src" % tmp # check if input file exists if not grass.find_file(input)["file"]: grass.fatal(_("Raster map <%s> not found") % input) scale = scales[units] distances = distances.split(",") distances1 = [scale * float(d) for d in distances] distances2 = [d * d for d in distances1] s = grass.read_command("g.proj", flags="j") kv = grass.parse_key_val(s) if kv["+proj"] == "longlat": metric = "geodesic" else: metric = "squared" grass.run_command("r.grow.distance", input=input, metric=metric, distance=temp_dist, flags="m") if zero: exp = "$temp_src = if($input == 0,null(),1)" else: exp = "$temp_src = if(isnull($input),null(),1)" grass.message(_("Extracting buffers (1/2)...")) grass.mapcalc(exp, temp_src=temp_src, input=input) exp = "$output = if(!isnull($input),$input,%s)" if metric == "squared": for n, dist2 in enumerate(distances2): exp %= "if($dist <= %f,%d,%%s)" % (dist2, n + 2) else: for n, dist2 in enumerate(distances1): exp %= "if($dist <= %f,%d,%%s)" % (dist2, n + 2) exp %= "null()" grass.message(_("Extracting buffers (2/2)...")) grass.mapcalc(exp, output=output, input=temp_src, dist=temp_dist) p = grass.feed_command("r.category", map=output, separator=":", rules="-") msg = "1:distances calculated from these locations\n" p.stdin.write(encode(msg)) d0 = "0" for n, d in enumerate(distances): msg = "%d:%s-%s %s\n" % (n + 2, d0, d, units) p.stdin.write(encode(msg)) d0 = d p.stdin.close() p.wait() grass.run_command("r.colors", map=output, color="rainbow") # write cmd history: grass.raster_history(output)
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') s = decode(s) 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 = decode(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(encode(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)