query.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. """!
  2. @package gui_core.query
  3. @brief wxGUI query dialog
  4. Classes:
  5. - query::QueryDialog
  6. (C) 2013 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 Anna Kratochvilova <kratochanna gmail.com>
  10. """
  11. import os
  12. import sys
  13. import random
  14. import wx
  15. if __name__ == '__main__':
  16. sys.path.append(os.path.join(os.environ['GISBASE'], "etc", "gui", "wxpython"))
  17. from gui_core.treeview import TreeListView
  18. from core.treemodel import TreeModel, DictNode
  19. class QueryDialog(wx.Dialog):
  20. def __init__(self, parent, data = None):
  21. wx.Dialog.__init__(self, parent, id = wx.ID_ANY,
  22. title = _("Query results"),
  23. size = (420, 400),
  24. style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
  25. self.data = data
  26. self.panel = wx.Panel(self, id = wx.ID_ANY)
  27. self.mainSizer = wx.BoxSizer(wx.VERTICAL)
  28. self._colNames = [_("Feature"), _("Value")]
  29. self._model = QueryTreeBuilder(self.data, column=self._colNames[1])
  30. self.tree = TreeListView(model=self._model, parent=self.panel,
  31. columns=self._colNames,
  32. style=wx.TR_DEFAULT_STYLE |
  33. wx.TR_FULL_ROW_HIGHLIGHT | wx.TR_MULTIPLE)
  34. self.tree.SetColumnWidth(0, 220)
  35. self.tree.SetColumnWidth(1, 400)
  36. self.tree.ExpandAll(self._model.root)
  37. self.mainSizer.Add(item = self.tree, proportion = 1, flag = wx.EXPAND | wx.ALL, border = 5)
  38. close = wx.Button(self.panel, id = wx.ID_CLOSE)
  39. close.Bind(wx.EVT_BUTTON, lambda event: self.Close())
  40. copy = wx.Button(self.panel, id = wx.ID_ANY, label = _("Copy to clipboard"))
  41. copy.Bind(wx.EVT_BUTTON, self.Copy)
  42. self.Bind(wx.EVT_CLOSE, self.OnClose)
  43. hbox = wx.BoxSizer(wx.HORIZONTAL)
  44. hbox.AddStretchSpacer(1)
  45. hbox.Add(item = copy, proportion = 0, flag = wx.EXPAND | wx.RIGHT, border = 5)
  46. hbox.Add(item = close, proportion = 0, flag = wx.EXPAND | wx.ALL, border = 0)
  47. self.mainSizer.Add(item = hbox, proportion = 0, flag = wx.EXPAND | wx.ALL, border = 5)
  48. self.panel.SetSizer(self.mainSizer)
  49. self.mainSizer.Fit(self.panel)
  50. # for Windows
  51. self.SendSizeEvent()
  52. def SetData(self, data):
  53. state = self.tree.GetExpansionState()
  54. self.data = data
  55. self._model = QueryTreeBuilder(self.data, column=self._colNames[1])
  56. self.tree.SetModel(self._model)
  57. self.tree.SetExpansionState(state)
  58. def Copy(self, event):
  59. text = printResults(self._model, self._colNames[1])
  60. if wx.TheClipboard.Open():
  61. do = wx.TextDataObject()
  62. do.SetText(text)
  63. wx.TheClipboard.SetData(do)
  64. wx.TheClipboard.Close()
  65. def OnClose(self, event):
  66. self.Destroy()
  67. event.Skip()
  68. def QueryTreeBuilder(data, column):
  69. """!Builds tree model from query results.
  70. @param data query results as a dictionary
  71. @param column column name
  72. @returns tree model
  73. """
  74. def addNode(parent, data, model):
  75. for k, v in data.iteritems():
  76. if isinstance(v, dict):
  77. node = model.AppendNode(parent=parent, label=k)
  78. addNode(parent=node, data=v, model=model)
  79. else:
  80. node = model.AppendNode(parent=parent, label=k,
  81. data={column: str(v)})
  82. model = TreeModel(DictNode)
  83. for part in data:
  84. addNode(parent=model.root, data=part, model=model)
  85. return model
  86. def printResults(model, valueCol):
  87. """!Print all results to string.
  88. @param model results tree model
  89. @param valueCol column name with value to be printed
  90. """
  91. def printTree(node, textList, valueCol, indent=0):
  92. textList.append(indent*' ' + node.label + ': ' + node.data.get(valueCol, ''))
  93. for child in node.children:
  94. printTree(node=child, textList=textList, valueCol=valueCol, indent=indent + 2)
  95. textList=[]
  96. for child in model.root.children:
  97. printTree(node=child, textList=textList, valueCol=valueCol)
  98. return '\n'.join(textList)
  99. def PrepareQueryResults(coordinates, result):
  100. """!Prepare query results as a Query dialog input.
  101. Adds coordinates, improves vector results tree structure.
  102. """
  103. data = []
  104. data.append({_("east"): coordinates[0]})
  105. data.append({_("north"): coordinates[1]})
  106. for part in result:
  107. if 'Map' in part:
  108. itemText = part['Map']
  109. if 'Mapset' in part:
  110. itemText += '@' + part['Mapset']
  111. del part['Mapset']
  112. del part['Map']
  113. if part:
  114. data.append({itemText: part})
  115. else:
  116. data.append({itemText: _("Nothing found")})
  117. else:
  118. data.append(part)
  119. return data
  120. def test():
  121. app = wx.PySimpleApp()
  122. from grass.script import vector as gvect
  123. from grass.script import raster as grast
  124. testdata1 = grast.raster_what(map = ('elevation_shade@PERMANENT','landclass96'),
  125. coord = [(638509.051416,224742.348346)])
  126. testdata2 = gvect.vector_what(map=('firestations','bridges'),
  127. coord=(633177.897487,221352.921257), distance=10)
  128. testdata = testdata1 + testdata2
  129. data = PrepareQueryResults(coordinates = (638509.051416,224742.348346), result = testdata)
  130. frame = QueryDialog(parent = None, data = data)
  131. frame.ShowModal()
  132. frame.Destroy()
  133. app.MainLoop()
  134. if __name__ == "__main__":
  135. test()