vinfo.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. """
  2. @package dbmgr.vinfo
  3. @brief Support classes for Database Manager
  4. List of classes:
  5. - vinfo::VectorDBInfo
  6. (C) 2007-2011 by the GRASS Development Team
  7. This program is free software under the GNU General Public License
  8. (>=v2). Read the file COPYING that comes with GRASS for details.
  9. @author Martin Landa <landa.martin gmail.com>
  10. """
  11. import os
  12. import types
  13. import wx
  14. from gui_core.gselect import VectorDBInfo as VectorDBInfoBase
  15. from core.gcmd import RunCommand
  16. from core.settings import UserSettings
  17. import grass.script as grass
  18. def unicodeValue(value):
  19. """!Encode value"""
  20. if type(value) == types.UnicodeType:
  21. return value
  22. enc = UserSettings.Get(group = 'atm', key = 'encoding', subkey = 'value')
  23. if enc:
  24. try:
  25. value = unicode(value, enc)
  26. except LookupError, e:
  27. value = e
  28. elif 'GRASS_DB_ENCODING' in os.environ:
  29. try:
  30. value = unicode(value, os.environ['GRASS_DB_ENCODING'])
  31. except LookupError, e:
  32. value = e
  33. else:
  34. try:
  35. value = unicode(value, 'ascii')
  36. except UnicodeDecodeError:
  37. value = _("Unable to decode value. Set encoding in GUI preferences ('Attributes').")
  38. return value
  39. def createDbInfoDesc(panel, mapDBInfo, layer):
  40. """!Create database connection information content"""
  41. infoFlexSizer = wx.FlexGridSizer (cols = 2, hgap = 1, vgap = 1)
  42. infoFlexSizer.AddGrowableCol(1)
  43. infoFlexSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  44. label = "Driver:"))
  45. infoFlexSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  46. label = mapDBInfo.layers[layer]['driver']))
  47. infoFlexSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  48. label = "Database:"))
  49. infoFlexSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  50. label = mapDBInfo.layers[layer]['database']))
  51. infoFlexSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  52. label = "Table:"))
  53. infoFlexSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  54. label = mapDBInfo.layers[layer]['table']))
  55. infoFlexSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  56. label = "Key:"))
  57. infoFlexSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
  58. label = mapDBInfo.layers[layer]['key']))
  59. return infoFlexSizer
  60. class VectorDBInfo(VectorDBInfoBase):
  61. """!Class providing information about attribute tables
  62. linked to the vector map"""
  63. def __init__(self, map):
  64. VectorDBInfoBase.__init__(self, map)
  65. def GetColumns(self, table):
  66. """!Return list of columns names (based on their index)"""
  67. try:
  68. names = [''] * len(self.tables[table].keys())
  69. except KeyError:
  70. return []
  71. for name, desc in self.tables[table].iteritems():
  72. names[desc['index']] = name
  73. return names
  74. def SelectByPoint(self, queryCoords, qdist):
  75. """!Get attributes by coordinates (all available layers)
  76. Return line id or None if no line is found"""
  77. line = None
  78. nselected = 0
  79. data = grass.vector_what(map = self.map,
  80. coord = (float(queryCoords[0]), float(queryCoords[1])),
  81. distance = float(qdist))
  82. if len(data) < 1 or all(('Table' not in record) for record in data):
  83. return None
  84. # process attributes
  85. ret = dict()
  86. for key in ['Category', 'Layer', 'Table', 'Id']:
  87. ret[key] = list()
  88. for record in data:
  89. if not 'Table' in record:
  90. continue
  91. table = record['Table']
  92. for key, value in record['Attributes'].iteritems():
  93. if len(value) < 1:
  94. value = None
  95. else:
  96. if self.tables[table][key]['ctype'] != types.StringType:
  97. value = self.tables[table][key]['ctype'] (value)
  98. else:
  99. value = unicodeValue(value)
  100. self.tables[table][key]['values'].append(value)
  101. for key, value in record.iteritems():
  102. if key == 'Attributes':
  103. continue
  104. if key in ret:
  105. ret[key].append(value)
  106. if 'Id' not in record.keys():
  107. ret['Id'].append(None)
  108. return ret
  109. def SelectFromTable(self, layer, cols = '*', where = None):
  110. """!Select records from the table
  111. Return number of selected records, -1 on error
  112. """
  113. if layer <= 0:
  114. return -1
  115. nselected = 0
  116. table = self.layers[layer]["table"] # get table desc
  117. # select values (only one record)
  118. if where is None or where is '':
  119. sql = "SELECT %s FROM %s" % (cols, table)
  120. else:
  121. sql = "SELECT %s FROM %s WHERE %s" % (cols, table, where)
  122. ret = RunCommand('db.select',
  123. parent = self,
  124. read = True,
  125. quiet = True,
  126. flags = 'v',
  127. sql= sql,
  128. database = self.layers[layer]["database"],
  129. driver = self.layers[layer]["driver"])
  130. # self.tables[table][key][1] = str(cat)
  131. if ret:
  132. for line in ret.splitlines():
  133. name, value = line.split('|')
  134. # casting ...
  135. if value:
  136. if self.tables[table][name]['ctype'] != type(''):
  137. value = self.tables[table][name]['ctype'] (value)
  138. else:
  139. value = unicodeValue(value)
  140. else:
  141. value = None
  142. self.tables[table][name]['values'].append(value)
  143. nselected = 1
  144. return nselected