v.db.addtable.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #!/usr/bin/env python
  2. #
  3. ############################################################################
  4. #
  5. # MODULE: v.db.addtable
  6. # AUTHOR(S): Markus Neteler
  7. # Converted to Python by Glynn Clements
  8. # Key column added by Martin Landa <landa.martin gmail.com>
  9. # PURPOSE: interface to db.execute to creates and add a new table to given vector map
  10. # COPYRIGHT: (C) 2005, 2007, 2008, 2011 by Markus Neteler & the GRASS Development Team
  11. #
  12. # This program is free software under the GNU General Public
  13. # License (>=v2). Read the file COPYING that comes with GRASS
  14. # for details.
  15. #
  16. #############################################################################
  17. #%module
  18. #% description: Creates and connects a new attribute table to a given layer of an existing vector map.
  19. #% keywords: vector
  20. #% keywords: attribute table
  21. #% keywords: database
  22. #%end
  23. #%option G_OPT_V_MAP
  24. #%end
  25. #%option
  26. #% key: table
  27. #% type: string
  28. #% description: Name of new attribute table (default: vector map name)
  29. #% required: no
  30. #% guisection: Definition
  31. #%end
  32. #%option
  33. #% key: layer
  34. #% type: integer
  35. #% description: Layer number where to add new attribute table
  36. #% answer: 1
  37. #% required: no
  38. #% guisection: Definition
  39. #%end
  40. #%option G_OPT_DB_KEYCOLUMN
  41. #% guisection: Definition
  42. #%end
  43. #%option
  44. #% key: columns
  45. #% type: string
  46. #% label: Name and type of the new column(s)
  47. #% description: Types depend on database backend, but all support VARCHAR(), INT, DOUBLE PRECISION and DATE. Example: "label varchar(250), type integer"
  48. #% required: no
  49. #% multiple: yes
  50. #% key_desc: name type
  51. #% guisection: Definition
  52. #%end
  53. import sys
  54. import os
  55. import grass.script as grass
  56. def main():
  57. vector = options['map']
  58. table = options['table']
  59. layer = options['layer']
  60. columns = options['columns']
  61. key = options['key']
  62. # does map exist in CURRENT mapset?
  63. mapset = grass.gisenv()['MAPSET']
  64. if not grass.find_file(vector, element = 'vector', mapset = mapset)['file']:
  65. grass.fatal(_("Vector map <%s> not found in current mapset") % vector)
  66. map_name = vector.split('@')[0]
  67. if not table:
  68. if layer == '1':
  69. grass.verbose(_("Using vector map name as table name: <%s>") % map_name)
  70. table = map_name
  71. else:
  72. # to avoid tables with identical names on higher layers
  73. table = "%s_%s" % (map_name, layer)
  74. grass.verbose(_("Using vector map name extended by layer number as table name: <%s>") % table)
  75. else:
  76. grass.verbose(_("Using user specified table name: %s") % table)
  77. # check if DB parameters are set, and if not set them.
  78. grass.run_command('db.connect', flags = 'c')
  79. grass.verbose(_("Creating new DB connection based on default mapset settings..."))
  80. kv = grass.db_connection()
  81. database = kv['database']
  82. driver = kv['driver']
  83. # maybe there is already a table linked to the selected layer?
  84. nuldev = file(os.devnull, 'w')
  85. try:
  86. grass.vector_db(map_name, stderr = nuldev)[int(layer)]
  87. grass.fatal(_("There is already a table linked to layer <%s>") % layer)
  88. except KeyError:
  89. pass
  90. # maybe there is already a table with that name?
  91. tables = grass.read_command('db.tables', flags = 'p', database = database, driver = driver,
  92. stderr = nuldev)
  93. if not table in tables.splitlines():
  94. if columns:
  95. column_def = map(lambda x: x.strip().lower(), columns.strip().split(','))
  96. else:
  97. column_def = []
  98. # if not existing, create it:
  99. column_def_key = "%s integer" % key
  100. if column_def_key not in column_def:
  101. column_def.insert(0, column_def_key)
  102. column_def = ','.join(column_def)
  103. grass.verbose(_("Creating table with columns (%s)...") % column_def)
  104. sql = "CREATE TABLE %s (%s)" % (table, column_def)
  105. if grass.run_command('db.execute', database = database, driver = driver, sql = sql) != 0:
  106. grass.fatal(_("Unable to create table <%s>") % table)
  107. # connect the map to the DB:
  108. grass.run_command('v.db.connect', quiet = True,
  109. map = map_name, database = database, driver = driver,
  110. layer = layer, table = table, key = key)
  111. # finally we have to add cats into the attribute DB to make modules such as v.what.rast happy:
  112. # (creates new row for each vector line):
  113. grass.run_command('v.to.db', map = map_name, layer = layer,
  114. option = 'cat', column = key, qlayer = layer)
  115. grass.verbose(_("Current attribute table links:"))
  116. if grass.verbosity() > 2:
  117. grass.run_command('v.db.connect', flags = 'p', map = map_name)
  118. # write cmd history:
  119. grass.vector_history(map_name)
  120. return 0
  121. if __name__ == "__main__":
  122. options, flags = grass.parser()
  123. sys.exit(main())