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 get_db_info(self): """ check if there is defined driver or database :return: driver and database (default or defined) """ try: driver = self.code_dict['driver'] try: database = self.code_dict['database'] except: connect = script.db_connection() database = connect['database'] except: connect = script.db_connection() try: database = self.code_dict['database'] driver = connect['driver'] except: database = connect['database'] driver = connect['driver'] return driver, database
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') 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.fatal(_("Table <%s> not found in database <%s>") % (table, database)) # 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("DROP TABLE " + table) p.stdin.close() p.wait() if p.returncode != 0: grass.fatal(_("Cannot continue (problem deleting table)."))
def main(): table = options['table'] force = flags['f'] # check if DB parameters are set, and if not set them. grass.run_command('db.connect', flags = 'c') kv = grass.db_connection() database = kv['database'] driver = kv['driver'] # schema needed for PG? if force: grass.message(_("Forcing ...")) # check if table exists nuldev = file(os.devnull, 'w') if not grass.db_table_exist(table, stdout = nuldev, stderr = nuldev): grass.fatal(_("Table <%s> not found in current mapset") % table) # check if table is used somewhere (connected to vector map) used = [] vects = grass.list_strings('vect') for vect in vects: for f in grass.vector_db(vect, stderr = nuldev).itervalues(): if not f: continue if f['table'] == table: used.append(vect) break if used: grass.warning(_("Deleting table <%s> which is attached to following map(s):") % table) for vect in used: grass.message(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("DROP TABLE " + table) p.stdin.close() p.wait() if p.returncode != 0: grass.fatal(_("Cannot continue (problem deleting table)."))
def main(): # old connection old_database = options['old_database'] old_schema = options['old_schema'] # new connection default_connection = grass.db_connection() if options['new_driver']: new_driver = options['new_driver'] else: new_driver = default_connection['driver'] if options['new_database']: new_database = options['new_database'] else: new_database = default_connection['database'] if options['new_schema']: new_schema = options['new_schema'] else: new_schema = default_connection['schema'] if old_database == '': old_database = None old_database_subst = None if old_database is not None: old_database_subst = substitute_db(old_database) new_database_subst = substitute_db(new_database) if old_database_subst == new_database_subst and old_schema == new_schema: grass.fatal(_("Old and new database connection is identical. Nothing to do.")) mapset = grass.gisenv()['MAPSET'] vectors = grass.list_grouped('vect')[mapset] num_vectors = len(vectors) if flags['c']: # create new database if not existing create_db(new_driver, new_database) i = 0 for vect in vectors: vect = "%s@%s" % (vect, mapset) i += 1 grass.message(_("%s\nReconnecting vector map <%s> (%d of %d)...\n%s") % \ ('-' * 80, vect, i, num_vectors, '-' * 80)) for f in grass.vector_db(vect, stderr = nuldev).itervalues(): layer = f['layer'] schema_table = f['table'] key = f['key'] database = f['database'] driver = f['driver'] # split schema.table if '.' in schema_table: schema, table = schema_table.split('.', 1) else: schema = '' table = schema_table if new_schema: new_schema_table = "%s.%s" % (new_schema, table) else: new_schema_table = table grass.debug("DATABASE = '%s' SCHEMA = '%s' TABLE = '%s' ->\n" " NEW_DATABASE = '%s' NEW_SCHEMA_TABLE = '%s'" % \ (old_database, schema, table, new_database, new_schema_table)) do_reconnect = True if old_database_subst is not None: if database != old_database_subst: do_reconnect = False if database == new_database_subst: do_reconnect = False if schema != old_schema: do_reconnect = False if do_reconnect == True: grass.verbose(_("Reconnecting layer %d...") % layer) if flags['c']: # check if table exists in new database copy_tab(driver, database, schema_table, new_driver, new_database, new_schema_table) # drop original table if required if flags['d']: drop_tab(vect, layer, schema_table, driver, substitute_db(database)) # reconnect tables (don't use substituted new_database) # NOTE: v.db.connect creates an index on the key column try: grass.run_command('v.db.connect', flags = 'o', quiet = True, map = vect, layer = layer, driver = new_driver, database = new_database, table = new_schema_table, key = key) except CalledModuleError: grass.warning(_("Unable to connect table <%s> to vector <%s> on layer <%s>") % (table, vect, str(layer))) else: if database != new_database_subst: grass.warning(_("Layer <%d> will not be reconnected because " "database or schema do not match.") % layer) return 0
def main(): table = options['table'] column = options['column'] force = flags['f'] # check if DB parameters are set, and if not set them. grass.run_command('db.connect', flags='c') kv = grass.db_connection() database = kv['database'] driver = kv['driver'] # schema needed for PG? if force: grass.message(_("Forcing ...")) if column == "cat": grass.warning( _("Deleting <%s> column which may be needed to keep table connected to a vector map" ) % column) cols = [f[0] for f in grass.db_describe(table)['cols']] if column not in cols: grass.fatal(_("Column <%s> not found in table") % column) if not force: grass.message(_("Column <%s> would be deleted.") % column) grass.message("") grass.message( _("You must use the force flag (-f) to actually remove it. Exiting." )) return 0 if driver == "sqlite": #echo "Using special trick for SQLite" # http://www.sqlite.org/faq.html#q13 colnames = [] coltypes = [] for f in grass.db_describe(table)['cols']: if f[0] == column: continue colnames.append(f[0]) coltypes.append("%s %s" % (f[0], f[1])) colnames = ", ".join(colnames) coltypes = ", ".join(coltypes) cmds = [ "BEGIN TRANSACTION", "CREATE TEMPORARY TABLE ${table}_backup(${coldef})", "INSERT INTO ${table}_backup SELECT ${colnames} FROM ${table}", "DROP TABLE ${table}", "CREATE TABLE ${table}(${coldef})", "INSERT INTO ${table} SELECT ${colnames} FROM ${table}_backup", "DROP TABLE ${table}_backup", "COMMIT" ] tmpl = string.Template(';\n'.join(cmds)) sql = tmpl.substitute(table=table, coldef=coltypes, colnames=colnames) else: sql = "ALTER TABLE %s DROP COLUMN %s" % (table, column) if grass.write_command( 'db.execute', input='-', database=database, driver=driver, stdin=sql) != 0: grass.fatal(_("Cannot continue (problem deleting column)")) return 0
def main(): infile = options['input'] outfile = options['output'] # are we in LatLong location? s = grass.read_command("g.proj", flags='j') kv = grass.parse_key_val(s) if kv['+proj'] != 'longlat': grass.fatal(_("This module only operates in LatLong/WGS84 locations")) # input test if not os.access(infile, os.R_OK): grass.fatal(_("File <%s> not found") % infile) # DBF doesn't support lengthy text fields kv = grass.db_connection() dbfdriver = kv['driver'] == 'dbf' if dbfdriver: grass.warning( _("Since DBF driver is used, the content of the 'alternatenames' column might be cut with respect to the original Geonames.org column content")) with open(infile, encoding='utf-8') as f: num_places = sum(1 for each in f) grass.message(_("Converting %d place names...") % num_places) # pump data into GRASS: # http://download.geonames.org/export/dump/readme.txt # The main 'geoname' table has the following fields : # --------------------------------------------------- # geonameid : integer id of record in geonames database # name : name of geographical point (utf8) varchar(200) # asciiname : name of geographical point in plain ascii characters, varchar(200) # alternatenames : alternatenames, comma separated varchar(4000) # latitude : latitude in decimal degrees (wgs84) # longitude : longitude in decimal degrees (wgs84) # feature class : see http://www.geonames.org/export/codes.html, char(1) # feature code : see http://www.geonames.org/export/codes.html, varchar(10) # country code : ISO-3166 2-letter country code, 2 characters # cc2 : alternate country codes, comma separated, ISO-3166 2-letter country code, 60 characters # admin1 code : fipscode (subject to change to iso code), isocode for the us and ch, see file admin1Codes.txt for display names of this code; varchar(20) # admin2 code : code for the second administrative division, a county in the US, see file admin2Codes.txt; varchar(80) # admin3 code : code for third level administrative division, varchar(20) # admin4 code : code for fourth level administrative division, varchar(20) # population : integer # elevation : in meters, integer # gtopo30 : average elevation of 30'x30' (ca 900mx900m) area in meters, integer # timezone : the timezone id (see file http://download.geonames.org/export/dump/timeZones.txt) # modification date : date of last modification in yyyy-MM-dd format # geonameid|name|asciiname|alternatenames|latitude|longitude|featureclass|featurecode|countrycode|cc2|admin1code|admin2code|admin3code|admin4code|population|elevation|gtopo30|timezone|modificationdate # debug: # head -n 3 ${TMPFILE}.csv # use different column names limited to 10 chars for dbf if dbfdriver: columns = ['geonameid integer', 'name varchar(200)', 'asciiname varchar(200)', 'altname varchar(4000)', 'latitude double precision', 'longitude double precision', 'featrclass varchar(1)', 'featrcode varchar(10)', 'cntrycode varchar(2)', 'cc2 varchar(60)', 'admin1code varchar(20)', 'admin2code varchar(20)', 'admin3code varchar(20)', 'admin4code varchar(20)', 'population integer', 'elevation integer', 'gtopo30 integer', 'timezone varchar(50)', 'mod_date date'] else: columns = ['geonameid integer', 'name varchar(200)', 'asciiname varchar(200)', 'alternatename varchar(4000)', 'latitude double precision', 'longitude double precision', 'featureclass varchar(1)', 'featurecode varchar(10)', 'countrycode varchar(2)', 'cc2 varchar(60)', 'admin1code varchar(20)', 'admin2code varchar(20)', 'admin3code varchar(20)', 'admin4code varchar(20)', 'population integer', 'elevation integer', 'gtopo30 integer', 'timezone varchar(50)', 'modification date'] grass.run_command('v.in.ascii', cat=0, x=6, y=5, sep='tab', input=infile, output=outfile, columns=columns) # write cmd history: grass.vector_history(outfile)
vector = glob.glob1(homeServer, "vectortarpack") logging.debug("Found: %s raster pack, %s vector pack" % (raster, vector)) f.write("Found: %s raster pack, %s vector pack" % (raster, vector)) ## add some environment variables os.environ["GISBASE"] = gisbase sys.path.append(os.path.join(gisbase, "etc", "python")) import grass.script as grass import grass.script.setup as gsetup gsetup.init(gisbase, dbase, location, mapset) grass.run_command("db.connect", flags="p") kv = grass.db_connection() database = kv["database"] driver = kv["driver"] logging.debug("db.connect: driver: %s, database %s" % (driver, database)) # unpack raster and vector maps if len(raster) != 0: try: tar = tarfile.TarFile.open(name="rastertarpack", mode="r") tar.extractall() rasters = glob.glob1(homeServer, "*.rasterpack") except: logging.error("Error unpacking rastertarpack") f.write("Error unpacking rastertarpack") for i in rasters: logging.debug("Unpacking raster map <%s>" %
def main(): vector = options['map'] table = options['table'] layer = options['layer'] columns = options['columns'] key = options['key'] # does map exist in CURRENT mapset? mapset = grass.gisenv()['MAPSET'] if not grass.find_file(vector, element = 'vector', mapset = mapset)['file']: grass.fatal(_("Vector map <%s> not found in current mapset") % vector) map_name = vector.split('@')[0] if not table: if layer == '1': grass.verbose(_("Using vector map name as table name: <%s>") % map_name) table = map_name else: # to avoid tables with identical names on higher layers table = "%s_%s" % (map_name, layer) grass.verbose(_("Using vector map name extended by layer number as table name: <%s>") % table) else: grass.verbose(_("Using user specified table name: %s") % table) # check if DB parameters are set, and if not set them. grass.run_command('db.connect', flags = 'c') grass.verbose(_("Creating new DB connection based on default mapset settings...")) kv = grass.db_connection() database = kv['database'] driver = kv['driver'] schema = kv['schema'] # maybe there is already a table linked to the selected layer? nuldev = file(os.devnull, 'w') try: grass.vector_db(map_name, stderr = nuldev)[int(layer)] grass.fatal(_("There is already a table linked to layer <%s>") % layer) except KeyError: pass # maybe there is already a table with that name? tables = grass.read_command('db.tables', flags = 'p', database = database, driver = driver, stderr = nuldev) if not table in tables.splitlines(): if columns: column_def = map(lambda x: x.strip().lower(), columns.strip().split(',')) else: column_def = [] # if not existing, create it: column_def_key = "%s integer" % key if column_def_key not in column_def: column_def.insert(0, column_def_key) column_def = ','.join(column_def) grass.verbose(_("Creating table with columns (%s)...") % column_def) sql = "CREATE TABLE %s (%s)" % (table, column_def) try: grass.run_command('db.execute', database=database, driver=driver, sql=sql) except CalledModuleError: grass.fatal(_("Unable to create table <%s>") % table) # connect the map to the DB: if schema: table = '{schema}.{table}'.format(schema=schema, table=table) grass.run_command('v.db.connect', quiet = True, map = map_name, database = database, driver = driver, layer = layer, table = table, key = key) # finally we have to add cats into the attribute DB to make modules such as v.what.rast happy: # (creates new row for each vector line): grass.run_command('v.to.db', map = map_name, layer = layer, option = 'cat', column = key, qlayer = layer) grass.verbose(_("Current attribute table links:")) if grass.verbosity() > 2: grass.run_command('v.db.connect', flags = 'p', map = map_name) # write cmd history: grass.vector_history(map_name) return 0
def main(): table = options['table'] column = options['column'] force = flags['f'] # check if DB parameters are set, and if not set them. grass.run_command('db.connect', flags = 'c') kv = grass.db_connection() database = kv['database'] driver = kv['driver'] # schema needed for PG? if force: grass.message(_("Forcing ...")) if column == "cat": grass.warning(_("Deleting <%s> column which may be needed to keep table connected to a vector map") % column) cols = [f[0] for f in grass.db_describe(table)['cols']] if column not in cols: grass.fatal(_("Column <%s> not found in table") % column) if not force: grass.message(_("Column <%s> would be deleted.") % column) grass.message("") grass.message(_("You must use the force flag to actually remove it. Exiting.")) sys.exit(0) if driver == "sqlite": #echo "Using special trick for SQLite" # http://www.sqlite.org/faq.html#q13 colnames = [] coltypes = [] for f in grass.db_describe(table)['cols']: if f[0] == column: continue colnames.append(f[0]) coltypes.append("%s %s" % (f[0], f[1])) colnames = ", ".join(colnames) coltypes = ", ".join(coltypes) cmds = [ "BEGIN TRANSACTION", "CREATE TEMPORARY TABLE ${table}_backup(${coldef})", "INSERT INTO ${table}_backup SELECT ${colnames} FROM ${table}", "DROP TABLE ${table}", "CREATE TABLE ${table}(${coldef})", "INSERT INTO ${table} SELECT ${colnames} FROM ${table}_backup", "DROP TABLE ${table}_backup", "COMMIT" ] tmpl = string.Template(';\n'.join(cmds)) sql = tmpl.substitute(table = table, coldef = coltypes, colnames = colnames) else: sql = "ALTER TABLE %s DROP COLUMN %s" % (table, column) if grass.write_command('db.execute', input = '-', database = database, driver = driver, stdin = sql) != 0: grass.fatal(_("Cannot continue (problem deleting column)."))
def main(): # old connection old_database = options["old_database"] old_schema = options["old_schema"] # new connection default_connection = gscript.db_connection() if options["new_driver"]: new_driver = options["new_driver"] else: new_driver = default_connection["driver"] if options["new_database"]: new_database = options["new_database"] else: new_database = default_connection["database"] if options["new_schema"]: new_schema = options["new_schema"] else: new_schema = default_connection["schema"] if old_database == "": old_database = None old_database_subst = None if old_database is not None: old_database_subst = substitute_db(old_database) new_database_subst = substitute_db(new_database) if old_database_subst == new_database_subst and old_schema == new_schema: gscript.fatal( _("Old and new database connection is identical. " "Nothing to do.")) mapset = gscript.gisenv()["MAPSET"] vectors = gscript.list_grouped("vect")[mapset] num_vectors = len(vectors) if flags["c"]: # create new database if not existing create_db(new_driver, new_database) i = 0 for vect in vectors: vect = "%s@%s" % (vect, mapset) i += 1 gscript.message( _("%s\nReconnecting vector map <%s> " "(%d of %d)...\n%s") % ("-" * 80, vect, i, num_vectors, "-" * 80)) for f in gscript.vector_db(vect, stderr=nuldev).values(): layer = f["layer"] schema_table = f["table"] key = f["key"] database = f["database"] driver = f["driver"] # split schema.table if "." in schema_table: schema, table = schema_table.split(".", 1) else: schema = "" table = schema_table if new_schema: new_schema_table = "%s.%s" % (new_schema, table) else: new_schema_table = table gscript.debug( "DATABASE = '%s' SCHEMA = '%s' TABLE = '%s' ->\n" " NEW_DATABASE = '%s' NEW_SCHEMA_TABLE = '%s'" % (old_database, schema, table, new_database, new_schema_table)) do_reconnect = True if old_database_subst is not None: if database != old_database_subst: do_reconnect = False if database == new_database_subst: do_reconnect = False if schema != old_schema: do_reconnect = False if do_reconnect: gscript.verbose(_("Reconnecting layer %d...") % layer) if flags["c"]: # check if table exists in new database copy_tab( driver, database, schema_table, new_driver, new_database, new_schema_table, ) # drop original table if required if flags["d"]: drop_tab(vect, layer, schema_table, driver, substitute_db(database)) # reconnect tables (don't use substituted new_database) # NOTE: v.db.connect creates an index on the key column try: gscript.run_command( "v.db.connect", flags="o", quiet=True, map=vect, layer=layer, driver=new_driver, database=new_database, table=new_schema_table, key=key, ) except CalledModuleError: gscript.warning( _("Unable to connect table <%s> to vector " "<%s> on layer <%s>") % (table, vect, str(layer))) else: if database != new_database_subst: gscript.warning( _("Layer <%d> will not be reconnected " "because database or schema do not " "match.") % layer) return 0
def main(): vector = options['map'] table = options['table'] layer = options['layer'] columns = options['columns'] key = options['key'] # does map exist in CURRENT mapset? mapset = grass.gisenv()['MAPSET'] if not grass.find_file(vector, element='vector', mapset=mapset)['file']: grass.fatal(_("Vector map <%s> not found in current mapset") % vector) map_name = vector.split('@')[0] if not table: if layer == '1': grass.verbose(_("Using vector map name as table name: <%s>") % map_name) table = map_name else: # to avoid tables with identical names on higher layers table = "%s_%s" % (map_name, layer) grass.verbose( _("Using vector map name extended by layer number as table name: <%s>") % table) else: grass.verbose(_("Using user specified table name: %s") % table) # check if DB parameters are set, and if not set them. grass.run_command('db.connect', flags='c') grass.verbose(_("Creating new DB connection based on default mapset settings...")) kv = grass.db_connection() database = kv['database'] driver = kv['driver'] schema = kv['schema'] # maybe there is already a table linked to the selected layer? nuldev = file(os.devnull, 'w') try: grass.vector_db(map_name, stderr=nuldev)[int(layer)] grass.fatal(_("There is already a table linked to layer <%s>") % layer) except KeyError: pass # maybe there is already a table with that name? tables = grass.read_command('db.tables', flags='p', database=database, driver=driver, stderr=nuldev) if not table in tables.splitlines(): if columns: column_def = [x.strip().lower() for x in columns.strip().split(',')] else: column_def = [] # if not existing, create it: column_def_key = "%s integer" % key if column_def_key not in column_def: column_def.insert(0, column_def_key) column_def = ','.join(column_def) grass.verbose(_("Creating table with columns (%s)...") % column_def) sql = "CREATE TABLE %s (%s)" % (table, column_def) try: grass.run_command('db.execute', database=database, driver=driver, sql=sql) except CalledModuleError: grass.fatal(_("Unable to create table <%s>") % table) # connect the map to the DB: if schema: table = '{schema}.{table}'.format(schema=schema, table=table) grass.run_command('v.db.connect', quiet=True, map=map_name, database=database, driver=driver, layer=layer, table=table, key=key) # finally we have to add cats into the attribute DB to make modules such as v.what.rast happy: # (creates new row for each vector line): grass.run_command('v.to.db', map=map_name, layer=layer, option='cat', column=key, qlayer=layer) grass.verbose(_("Current attribute table links:")) if grass.verbosity() > 2: grass.run_command('v.db.connect', flags='p', map=map_name) # write cmd history: grass.vector_history(map_name) return 0
def main(): infile = options['input'] outfile = options['output'] #### setup temporary file tmpfile = grass.tempfile() #are we in LatLong location? s = grass.read_command("g.proj", flags='j') kv = grass.parse_key_val(s) if kv['+proj'] != 'longlat': grass.fatal(_("This module only operates in LatLong/WGS84 locations")) # input test if not os.access(infile, os.R_OK): grass.fatal(_("File <%s> not found") % infile) # DBF doesn't support lengthy text fields kv = grass.db_connection() dbfdriver = kv['driver'] == 'dbf' if dbfdriver: grass.warning(_("Since DBF driver is used, the content of the 'alternatenames' column might be cut with respect to the original Geonames.org column content")) #let's go #change TAB to vertical bar num_places = 0 inf = file(infile) outf = file(tmpfile, 'wb') for line in inf: fields = line.rstrip('\r\n').split('\t') line2 = '|'.join(fields) + '\n' outf.write(line2) num_places += 1 outf.close() inf.close() grass.message(_("Converted %d place names.") % num_places) # pump data into GRASS: # http://download.geonames.org/export/dump/readme.txt # The main 'geoname' table has the following fields : # --------------------------------------------------- # geonameid : integer id of record in geonames database # name : name of geographical point (utf8) varchar(200) # asciiname : name of geographical point in plain ascii characters, varchar(200) # alternatenames : alternatenames, comma separated varchar(4000) # latitude : latitude in decimal degrees (wgs84) # longitude : longitude in decimal degrees (wgs84) # feature class : see http://www.geonames.org/export/codes.html, char(1) # feature code : see http://www.geonames.org/export/codes.html, varchar(10) # country code : ISO-3166 2-letter country code, 2 characters # cc2 : alternate country codes, comma separated, ISO-3166 2-letter country code, 60 characters # admin1 code : fipscode (subject to change to iso code), isocode for the us and ch, see file admin1Codes.txt for display names of this code; varchar(20) # admin2 code : code for the second administrative division, a county in the US, see file admin2Codes.txt; varchar(80) # admin3 code : code for third level administrative division, varchar(20) # admin4 code : code for fourth level administrative division, varchar(20) # population : integer # elevation : in meters, integer # gtopo30 : average elevation of 30'x30' (ca 900mx900m) area in meters, integer # timezone : the timezone id (see file http://download.geonames.org/export/dump/timeZones.txt) # modification date : date of last modification in yyyy-MM-dd format # geonameid|name|asciiname|alternatenames|latitude|longitude|featureclass|featurecode|countrycode|cc2|admin1code|admin2code|admin3code|admin4code|population|elevation|gtopo30|timezone|modificationdate # TODO: elevation seems to contain spurious char stuff :( # debug: # head -n 3 ${TMPFILE}.csv # use different column names limited to 10 chars for dbf if dbfdriver: columns = ['geonameid integer', 'name varchar(200)', 'asciiname varchar(200)', 'altname varchar(4000)', 'latitude double precision', 'longitude double precision', 'featrclass varchar(1)', 'featrcode varchar(10)', 'cntrycode varchar(2)', 'cc2 varchar(60)', 'admin1code varchar(20)', 'admin2code varchar(20)', 'admin3code varchar(20)', 'admin4code varchar(20)', 'population integer', 'elevation varchar(5)', 'gtopo30 integer', 'timezone varchar(50)', 'mod_date date'] else: columns = ['geonameid integer', 'name varchar(200)', 'asciiname varchar(200)', 'alternatename varchar(4000)', 'latitude double precision', 'longitude double precision', 'featureclass varchar(1)', 'featurecode varchar(10)', 'countrycode varchar(2)', 'cc2 varchar(60)', 'admin1code varchar(20)', 'admin2code varchar(20)', 'admin3code varchar(20)', 'admin4code varchar(20)', 'population integer', 'elevation varchar(5)', 'gtopo30 integer', 'timezone varchar(50)', 'modification date'] grass.run_command('v.in.ascii', cat = 0, x = 6, y = 5, fs = '|', input = tmpfile, output = outfile, columns = columns) grass.try_remove(tmpfile) # write cmd history: grass.vector_history(outfile)
def main(): vector = options["map"] table = options["table"] layer = options["layer"] columns = options["columns"] key = options["key"] # does map exist in CURRENT mapset? mapset = grass.gisenv()["MAPSET"] if not grass.find_file(vector, element="vector", mapset=mapset)["file"]: grass.fatal(_("Vector map <%s> not found in current mapset") % vector) map_name = vector.split("@")[0] if not table: if layer == "1": grass.verbose( _("Using vector map name as table name: <%s>") % map_name) table = map_name else: # to avoid tables with identical names on higher layers table = "%s_%s" % (map_name, layer) grass.verbose( _("Using vector map name extended by layer number as table name: <%s>" ) % table) else: grass.verbose(_("Using user specified table name: %s") % table) # check if DB parameters are set, and if not set them. grass.run_command("db.connect", flags="c", quiet=True) grass.verbose( _("Creating new DB connection based on default mapset settings...")) kv = grass.db_connection() database = kv["database"] driver = kv["driver"] schema = kv["schema"] database2 = database.replace("$MAP/", map_name + "/") # maybe there is already a table linked to the selected layer? nuldev = open(os.devnull, "w") try: grass.vector_db(map_name, stderr=nuldev)[int(layer)] grass.fatal(_("There is already a table linked to layer <%s>") % layer) except KeyError: pass # maybe there is already a table with that name? tables = grass.read_command("db.tables", flags="p", database=database2, driver=driver, stderr=nuldev) tables = decode(tables) if table not in tables.splitlines(): colnames = [] column_def = [] if columns: column_def = [] for x in " ".join(columns.split()).split(","): colname = x.lower().split()[0] if colname in colnames: grass.fatal( _("Duplicate column name '%s' not allowed") % colname) colnames.append(colname) column_def.append(x) # if not existing, create it: if key not in colnames: column_def.insert(0, "%s integer" % key) column_def = ",".join(column_def) grass.verbose(_("Creating table with columns (%s)...") % column_def) sql = "CREATE TABLE %s (%s)" % (table, column_def) try: grass.run_command("db.execute", database=database2, driver=driver, sql=sql) except CalledModuleError: grass.fatal(_("Unable to create table <%s>") % table) # connect the map to the DB: if schema: table = "{schema}.{table}".format(schema=schema, table=table) grass.verbose(_("Connecting new table to vector map <%s>...") % map_name) grass.run_command( "v.db.connect", quiet=True, map=map_name, database=database, driver=driver, layer=layer, table=table, key=key, ) # finally we have to add cats into the attribute DB to make # modules such as v.what.rast happy: (creates new row for each # vector line): try: grass.run_command( "v.to.db", overwrite=True, map=map_name, layer=layer, option="cat", column=key, qlayer=layer, ) except CalledModuleError: # remove link grass.run_command("v.db.connect", quiet=True, flags="d", map=map_name, layer=layer) return 1 grass.verbose(_("Current attribute table links:")) if grass.verbosity() > 2: grass.run_command("v.db.connect", flags="p", map=map_name) # write cmd history: grass.vector_history(map_name) return 0