[GRASS-SVN] r33078 - grass/trunk/gui/wxpython/gui_modules

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Aug 26 00:57:38 EDT 2008


Author: cmbarton
Date: 2008-08-26 00:57:38 -0400 (Tue, 26 Aug 2008)
New Revision: 33078

Modified:
   grass/trunk/gui/wxpython/gui_modules/colorrules.py
   grass/trunk/gui/wxpython/gui_modules/gselect.py
Log:
New classes in gselect.py to create comboboxes for layer and column selection for vectors. Implemented in updated colorrules.py

Modified: grass/trunk/gui/wxpython/gui_modules/colorrules.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/colorrules.py	2008-08-26 04:51:33 UTC (rev 33077)
+++ grass/trunk/gui/wxpython/gui_modules/colorrules.py	2008-08-26 04:57:38 UTC (rev 33078)
@@ -102,21 +102,13 @@
         if self.cmd == 'vcolors':
             self.cb_vl_label = wx.StaticText(parent=self, id=wx.ID_ANY,
                                    label='Layer:')
-            self.cb_vlayer = wx.ComboBox(parent=self, id=wx.ID_ANY, size=(50, -1),
-                                 style=wx.CB_SIMPLE | wx.CB_READONLY,
-                                 choices=self.layerchoices)
-            self.cb_vlayer.SetSelection(0)
-            self.cb_vlayer.SetValue('1')
             self.cb_vc_label = wx.StaticText(parent=self, id=wx.ID_ANY,
                                    label='Attribute column:')
-            self.cb_vcol = wx.ComboBox(parent=self, id=wx.ID_ANY, size=(200, -1),
-                                 style=wx.CB_SIMPLE | wx.CB_READONLY,
-                                 choices=self.columnchoices)
             self.cb_vrgb_label = wx.StaticText(parent=self, id=wx.ID_ANY,
                                    label='RGB color column:')
-            self.cb_vrgb = wx.ComboBox(parent=self, id=wx.ID_ANY, size=(200, -1),
-                                 style=wx.CB_SIMPLE | wx.CB_READONLY,
-                                 choices=self.columnchoices)
+            self.cb_vlayer = gselect.LayerSelect(self, vector='')
+            self.cb_vcol = gselect.ColumnSelect(self, vector='', layer='')
+            self.cb_vrgb = gselect.ColumnSelect(self, vector='', layer='')
 
         # color table and preview window
         self.cr_label = wx.StaticText(parent=self, id=wx.ID_ANY,
@@ -289,29 +281,26 @@
             except:
                 pass
         elif self.cmd == 'vcolors':
-            self.mapDBInfo = dbm.VectorDBInfo(self.inmap)
-            self.layerchoices = self.mapDBInfo.layers.keys()
-            for n in range(len(self.layerchoices)):
-                self.cb_vlayer.Insert(str(self.layerchoices[n]), n)
+            self.cb_vlayer.InsertLayers(self.inmap)
+            #self.mapDBInfo = dbm.VectorDBInfo(self.inmap)
+            #self.layerchoices = self.mapDBInfo.layers.keys()
+            #for n in range(len(self.layerchoices)):
+            #    self.cb_vlayer.Insert(str(self.layerchoices[n]), n)
 
             # initialize column selection combox boxes for layer 1
+
             try:
-                self.vtable = self.mapDBInfo.layers[self.vlayer]['table']
-                for n in range(len(self.mapDBInfo.GetColumns(self.vtable))):
-                    self.cb_vcol.Insert(self.mapDBInfo.GetColumns(self.vtable)[n], n)
-                    self.cb_vrgb.Insert(self.mapDBInfo.GetColumns(self.vtable)[n], n)
+                self.cb_vcol.InsertColumns(vector=self.inmap, layer=self.vlayer)
+                self.cb_vrgb.InsertColumns(vector=self.inmap, layer=self.vlayer)
                 self.Update()
             except:
                 pass
                 
     def OnLayerSelection(self, event):
-        self.vlayer = int(event.GetString())
-        
         # reset choices in column selection comboboxes if layer changes
-        self.vtable = self.mapDBInfo.layers[self.vlayer]['table']
-        for n in range(len(self.mapDBInfo.GetColumns(self.vtable))):
-            self.cb_vcol.Insert(self.mapDBInfo.GetColumns(self.vtable)[n], n)
-            self.cb_vrgb.Insert(self.mapDBInfo.GetColumns(self.vtable)[n], n)
+        self.vlayer = int(event.GetString())
+        self.cb_vcol.InsertColumns(vector=self.inmap, layer=self.vlayer)
+        self.cb_vrgb.InsertColumns(vector=self.inmap, layer=self.vlayer)
         self.Update()
         
     def OnColumnSelection(self, event):

Modified: grass/trunk/gui/wxpython/gui_modules/gselect.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/gselect.py	2008-08-26 04:51:33 UTC (rev 33077)
+++ grass/trunk/gui/wxpython/gui_modules/gselect.py	2008-08-26 04:57:38 UTC (rev 33078)
@@ -292,3 +292,173 @@
         self.mapsets = mapsets
         self.exceptOf = exceptOf
         self.multiple = multiple
+        
+class VectorDBInfo:
+    """Class providing information about attribute tables
+    linked to a vector map"""
+    def __init__(self, map):
+        self.map = map
+        # {layer number : {table, database, driver})
+        self.layers = {}
+        # {table : {column name : type, length, values, ids}}
+        self.tables = {}
+
+        if not self.__CheckDBConnection(): # -> self.layers
+            return
+
+        self.__DescribeTables() # -> self.tables
+
+    def __CheckDBConnection(self):
+        """Check DB connection"""
+        layerCommand = gcmd.Command(cmd=["v.db.connect",
+                                         "-g", "--q",
+                                         "map=%s" % self.map],
+                                    rerr=None, stderr=None)
+        if layerCommand.returncode != 0:
+            return False
+
+        # list of available layers & (table, database, driver)
+        for line in layerCommand.ReadStdOutput():
+            lineList = line.split(' ')
+            layer = lineList[0]
+            if '/' in layer:
+                layer, layer_name = lineList[0].split('/')
+            else:
+                layer_name = None
+            # database can contain ' ' in it's path
+            if len(lineList) > 5:
+                database = ''.join(lineList[3:-1])
+            else:
+                database = lineList[3]
+            self.layers[int(layer)] = {
+                "name"     : layer_name,
+                "table"    : lineList[1],
+                "key"      : lineList[2],
+                "database" : database,
+                "driver"   : lineList[-1]
+                }
+            
+        if (len(self.layers.keys()) == 0):
+            return False
+
+        return True
+
+    def __DescribeTables(self):
+        """Describe linked tables"""
+        for layer in self.layers.keys():
+            # determine column names and types
+            table = self.layers[layer]["table"]
+            columnsCommand = gcmd.Command (cmd=["db.describe",
+                                                "-c", "--q",
+                                                "table=%s" % self.layers[layer]["table"],
+                                                "driver=%s" % self.layers[layer]["driver"],
+                                                "database=%s" % self.layers[layer]["database"]])
+
+
+            columns = {} # {name: {type, length, [values], [ids]}}
+
+            if columnsCommand.returncode == 0:
+                # skip nrows and ncols
+                i = 0
+                for line in columnsCommand.ReadStdOutput()[2:]:
+                    num, name, type, length = line.strip().split(':')
+                    # FIXME: support more datatypes
+                    if type.lower() == "integer":
+                        ctype = int
+                    elif type.lower() == "double precision":
+                        ctype = float
+                    else:
+                        ctype = str
+
+                    columns[name.strip()] = { 'index'  : i,
+                                              'type'   : type.lower(),
+                                              'ctype'  : ctype,
+                                              'length' : int(length),
+                                              'values' : [],
+                                              'ids'    : []}
+                    i += 1
+            else:
+                return False
+
+            # check for key column
+            # v.db.connect -g/p returns always key column name lowercase
+            if self.layers[layer]["key"] not in columns.keys():
+                for col in columns.keys():
+                    if col.lower() == self.layers[layer]["key"]:
+                        self.layers[layer]["key"] = col.upper()
+                        break
+            
+            self.tables[table] = columns
+            #print 'self tables =', self.tables[table]
+
+        return True
+    
+    def Reset(self):
+        """Reset"""
+        for layer in self.layers:
+            table = self.layers[layer]["table"] # get table desc
+            columns = self.tables[table]
+            for name in self.tables[table].keys():
+                self.tables[table][name]['values'] = []
+                self.tables[table][name]['ids']    = []
+
+class LayerSelect(wx.ComboBox):
+    """
+    Creates combo box for selecting data layers defined for vector.
+    The 'layer' terminology is likely to change for GRASS 7
+    """
+    def __init__(self, parent,
+                 id=wx.ID_ANY, value='1', pos=wx.DefaultPosition,
+                 size=wx.DefaultSize, choices=['1'], **kargs):
+
+        super(LayerSelect, self).__init__(parent, id, value, pos, size, choices)
+
+        self.vector = kargs['vector'] # vector map to check for attribute tables
+
+        if self.vector == '':
+            return
+        else:
+            self.InsertLayers(self.vector)
+        
+    def InsertLayers(self, vector):
+        """insert layers for a vector into the layer combobox"""
+        layerchoices = VectorDBInfo(vector).layers.keys()
+        self.Clear()
+        for n in range(len(layerchoices)):
+            self.Insert(str(layerchoices[n]), n)
+
+        self.SetSelection(0)
+        self.SetValue('1') # all vectors have a layer 1 by default
+
+class ColumnSelect(wx.ComboBox):
+    """
+    Creates combo box for selecting columns in the attribute table for a vector.
+    The 'layer' terminology is likely to change for GRASS 7
+    """
+    def __init__(self, parent,
+                 id=wx.ID_ANY, value='', pos=wx.DefaultPosition,
+                 size=wx.DefaultSize, choices=[''], **kargs):
+
+        super(ColumnSelect, self).__init__(parent, id, value, pos, size, choices)
+
+        self.vector = kargs['vector'] # vector map to check for attribute tables
+        self.layer = kargs['layer'] # data layer connected to attribute table
+
+        if self.vector == '' or self.layer == '':
+            return
+        else:
+            self.InsertColumns(self.vector, self.layer)
+                
+    def InsertColumns(self, vector, layer):
+        """Return list of columns names for a vector layer"""
+        if vector == '' or layer == '': return
+        
+        table = VectorDBInfo(vector).layers[layer]["table"]
+        columnchoices = VectorDBInfo(vector).tables[table].keys()
+        columnchoices.sort()
+        self.Clear()
+        for n in range(len(columnchoices)):
+            self.Insert(columnchoices[n], n)
+            
+        self.SetSelection(0)
+        self.SetValue(columnchoices[0]) #set the combobox to the first column 



More information about the grass-commit mailing list