vector.py 5.0 KB

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