vector.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. """
  2. @package grass.script.vector
  3. @brief GRASS Python scripting module
  4. Vector related functions to be used in Python scripts.
  5. Usage:
  6. @code
  7. from grass.script import core, vector as grass
  8. grass.parser()
  9. grass.vector_db(map)
  10. ...
  11. @endcode
  12. (C) 2008-2009 by the GRASS Development Team
  13. This program is free software under the GNU General Public
  14. License (>=v2). Read the file COPYING that comes with GRASS
  15. for details.
  16. @author Glynn Clements
  17. @author Martin Landa <landa.martin gmail.com>
  18. """
  19. import os
  20. from core import *
  21. # run "v.db.connect -g ..." and parse output
  22. def vector_db(map, **args):
  23. """Return the database connection details for a vector map
  24. (interface to `v.db.connect -g'). Example:
  25. \code
  26. >>> grass.vector_db('lakes')
  27. {1: {'layer': '1', 'name': '',
  28. 'database': '/home/martin/grassdata/nc_spm_08/PERMANENT/dbf/',
  29. 'driver': 'dbf', 'key': 'cat', 'table': 'lakes'}}
  30. \endcode
  31. @param map vector map
  32. @param args
  33. @return dictionary { layer : { 'layer', 'table, 'database', 'driver', 'key' }
  34. """
  35. s = read_command('v.db.connect', flags = 'g', map = map, fs = ';', **args)
  36. result = {}
  37. for l in s.splitlines():
  38. f = l.split(';')
  39. if len(f) != 5:
  40. continue
  41. if '/' in f[0]:
  42. f1 = f[0].split('/')
  43. layer = f1[0]
  44. name = f1[1]
  45. else:
  46. layer = f[0]
  47. name = ''
  48. result[int(layer)] = {
  49. 'layer' : layer,
  50. 'name' : name,
  51. 'table' : f[1],
  52. 'key' : f[2],
  53. 'database' : f[3],
  54. 'driver' : f[4] }
  55. return result
  56. def vector_layer_db(map, layer):
  57. """Return the database connection details for a vector map layer.
  58. If db connection for given layer is not defined, fatal() is called.
  59. @param map map name
  60. @param layer layer number
  61. @return parsed output
  62. """
  63. try:
  64. f = vector_db(map)[int(layer)]
  65. except KeyError:
  66. grass.fatal("Database connection not defined for layer %s" % layer)
  67. return f
  68. # run "v.info -c ..." and parse output
  69. def vector_columns(map, layer = None, **args):
  70. """Return a dictionary of the columns for the database table connected to
  71. a vector map (interface to `v.info -c').
  72. @param map map name
  73. @param layer layer number (None for all layers)
  74. @param args
  75. @return parsed output
  76. """
  77. s = read_command('v.info', flags = 'c', map = map, layer = layer, quiet = True, **args)
  78. result = {}
  79. for line in s.splitlines():
  80. f = line.split('|')
  81. if len(f) == 2:
  82. result[f[1]] = f[0]
  83. return result
  84. # add vector history
  85. def vector_history(map):
  86. """Set the command history for a vector map to the command used to
  87. invoke the script (interface to `v.support').
  88. @param map mapname
  89. @return v.support output
  90. """
  91. run_command('v.support', map = map, cmdhist = os.environ['CMDLINE'])
  92. # run "v.info -t" and parse output
  93. def vector_info_topo(map):
  94. """Return information about a vector map (interface to `v.info
  95. -t'). Example:
  96. \code
  97. >>> grass.vector_info_topo('lakes')
  98. {'kernels': 0, 'lines': 0, 'centroids': 15279,
  99. 'boundaries': 27764, 'points': 0, 'faces': 0,
  100. 'primitives': 43043, 'islands': 7470, 'nodes': 35234, 'map3d': 0, 'areas': 15279}
  101. \endcode
  102. @param map map name
  103. @return parsed output
  104. """
  105. s = read_command('v.info', flags = 't', map = map)
  106. return parse_key_val(s, val_type = int)
  107. # interface for v.db.select
  108. def vector_db_select(map, layer = 1, **kwargs):
  109. """Get attribute data of selected vector map layer.
  110. Function returns list of columns and dictionary of values ordered by
  111. key column value. Example:
  112. \code
  113. >>> print grass.vector_select('lakes')['values'][3]
  114. ['3', '19512.86146', '708.44683', '4', '55652', 'LAKE/POND', '39000', '']
  115. \endcode
  116. @param map map name
  117. @param layer layer number
  118. @param kwargs v.db.select options
  119. @return dictionary ('columns' and 'values')
  120. """
  121. try:
  122. key = vector_db(map = map)[layer]['key']
  123. except KeyError:
  124. error('Missing layer %d in vector map <%s>' % (layer, map))
  125. return { 'columns' : [], 'values' : {} }
  126. if kwargs.has_key('columns'):
  127. if key not in kwargs['columns'].split(','):
  128. # add key column if missing
  129. debug("Adding key column to the output")
  130. kwargs['columns'] += ',' + key
  131. ret = read_command('v.db.select',
  132. map = map,
  133. layer = layer,
  134. fs = '|', **kwargs)
  135. if not ret:
  136. error('vector_select() failed')
  137. return { 'columns' : [], 'values' : {} }
  138. columns = []
  139. values = {}
  140. for line in ret.splitlines():
  141. if not columns:
  142. columns = line.split('|')
  143. key_index = columns.index(key)
  144. continue
  145. value = line.split('|')
  146. key_value = int(value[key_index])
  147. values[key_value] = line.split('|')
  148. return { 'columns' : columns,
  149. 'values' : values }