dbm_base.py 6.6 KB

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