vector.py 5.0 KB

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