[GRASS-SVN] r47763 - in grass/branches/develbranch_6/gui/wxpython:
. gui_modules
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Aug 18 17:34:34 EDT 2011
Author: annakrat
Date: 2011-08-18 14:34:34 -0700 (Thu, 18 Aug 2011)
New Revision: 47763
Modified:
grass/branches/develbranch_6/gui/wxpython/gui_modules/colorrules.py
grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py
grass/branches/develbranch_6/gui/wxpython/wxgui.py
Log:
wxGUI: sync colorrules.py with trunk (rev from 47714 to r47762)
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/colorrules.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/colorrules.py 2011-08-18 21:28:20 UTC (rev 47762)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/colorrules.py 2011-08-18 21:34:34 UTC (rev 47763)
@@ -30,6 +30,7 @@
import wx
import wx.lib.colourselect as csel
import wx.lib.scrolledpanel as scrolled
+import wx.lib.filebrowsebutton as filebrowse
import grass.script as grass
@@ -46,17 +47,17 @@
class RulesPanel:
- def __init__(self, parent, mapType, columnType, properties, panelWidth = 180):
+ def __init__(self, parent, mapType, attributeType, properties, panelWidth = 180):
"""!Create rules panel
@param mapType raster/vector
- @param columnType color/size for choosing widget type
- @param properties properties of classes derived from ColorTabel
+ @param attributeType color/size for choosing widget type
+ @param properties properties of classes derived from ColorTable
@param panelWidth width of scroll panel"""
self.ruleslines = {}
self.mapType = mapType
- self.columnType = columnType
+ self.attributeType = attributeType
self.properties = properties
self.parent = parent
@@ -72,15 +73,11 @@
self.mainPanel.SetSizer(self.mainSizer)
self.mainPanel.SetAutoLayout(True)
- if self.mapType == 'vector' and self.columnType == 'color':
- self.label = wx.StaticText(parent, id = wx.ID_ANY, label = _("Set color for attribute values:"))
- elif self.mapType == 'vector' and self.columnType == 'size':
- if self.parent.vectorType == 'points':
- label = label = _("Set size for attribute values:")
- else:
- label = label = _("Set width for attribute values:")
- self.label = wx.StaticText(parent, id = wx.ID_ANY, label = label)
-
+ # (un)check all
+ self.checkAll = wx.CheckBox(parent, id = wx.ID_ANY, label = _("Check all"))
+ self.checkAll.SetValue(True)
+ # clear button
+ self.clearAll = wx.Button(parent, id = wx.ID_ANY, label = _("Clear all"))
# determines how many rules should be added
self.numRules = wx.SpinCtrl(parent, id = wx.ID_ANY,
min = 1, max = 1e6)
@@ -88,12 +85,28 @@
self.btnAdd = wx.Button(parent, id = wx.ID_ADD)
self.btnAdd.Bind(wx.EVT_BUTTON, self.OnAddRules)
+ self.checkAll.Bind(wx.EVT_CHECKBOX, self.OnCheckAll)
+ self.clearAll.Bind(wx.EVT_BUTTON, self.OnClearAll)
+
def Clear(self):
"""!Clear and widgets and delete information"""
self.ruleslines.clear()
self.mainPanel.DestroyChildren()
+ def OnCheckAll(self, event):
+ """!(Un)check all rules"""
+ check = event.GetInt()
+ for child in self.mainPanel.GetChildren():
+ if child.GetName() == 'enable':
+ child.SetValue(check)
+ else:
+ child.Enable(check)
+
+ def OnClearAll(self, event):
+ """!Delete all widgets in panel"""
+ self.Clear()
+
def OnAddRules(self, event):
"""!Add rules button pressed"""
nrules = self.numRules.GetValue()
@@ -111,32 +124,39 @@
# enable
enable = wx.CheckBox(parent = self.mainPanel, id = num)
enable.SetValue(True)
+ enable.SetName('enable')
enable.Bind(wx.EVT_CHECKBOX, self.OnRuleEnable)
# value
txt_ctrl = wx.TextCtrl(parent = self.mainPanel, id = 1000 + num,
size = (80, -1),
style = wx.TE_NOHIDESEL)
if self.mapType == 'vector':
- txt_ctrl.SetToolTipString(_("Enter vector attribute values (e.g. 5) "
- "or ranges (e.g. 5 to 10)"))
+ txt_ctrl.SetToolTipString(_("Enter vector attribute values"))
txt_ctrl.Bind(wx.EVT_TEXT, self.OnRuleValue)
- if self.columnType == 'color':
+ txt_ctrl.SetName('source')
+ if self.attributeType == 'color':
# color
columnCtrl = csel.ColourSelect(self.mainPanel, id = 2000 + num,
size = globalvar.DIALOG_COLOR_SIZE)
columnCtrl.Bind(csel.EVT_COLOURSELECT, self.OnRuleColor)
+ columnCtrl.SetName('target')
if not start:
self.ruleslines[enable.GetId()] = { 'value' : '',
'color': "0:0:0" }
- if self.columnType == 'size':
- # size
+ else:
+ # size or width
+ init = 2
+ if self.attributeType == 'size':
+ init = 100
columnCtrl = wx.SpinCtrl(self.mainPanel, id = 2000 + num,
- size = (50, -1), min = 1, max = 1e3,
- initial = 5)
+ size = (50, -1), min = 1, max = 1e4,
+ initial = init)
columnCtrl.Bind(wx.EVT_SPINCTRL, self.OnRuleSize)
+ columnCtrl.Bind(wx.EVT_TEXT, self.OnRuleSize)
+ columnCtrl.SetName('target')
if not start:
self.ruleslines[enable.GetId()] = { 'value' : '',
- 'size': 5 }
+ self.attributeType: init }
self.mainSizer.Add(item = enable, proportion = 0,
flag = wx.ALIGN_CENTER_VERTICAL)
@@ -156,13 +176,19 @@
if event.IsChecked():
self.mainPanel.FindWindowById(id + 1000).Enable()
self.mainPanel.FindWindowById(id + 2000).Enable()
- if self.mapType == 'vector':
- value = self.SQLConvert(self.mainPanel.FindWindowById(id + 1000).GetValue(), self.columnType)
+ if self.mapType == 'vector' and not self.parent.GetParent().colorTable:
+ vals = []
+ vals.append(self.mainPanel.FindWindowById(id + 1000).GetValue())
+ try:
+ vals.append(self.mainPanel.FindWindowById(id + 1 + 1000).GetValue())
+ except AttributeError:
+ vals.append(None)
+ value = self.SQLConvert(vals)
else:
value = self.mainPanel.FindWindowById(id + 1000).GetValue()
color = self.mainPanel.FindWindowById(id + 2000).GetValue()
- if self.columnType == 'color':
+ if self.attributeType == 'color':
# color
color_str = str(color[0]) + ':' \
+ str(color[1]) + ':' \
@@ -171,9 +197,9 @@
'color' : color_str }
else:
- # size
+ # size or width
self.ruleslines[id] = {'value' : value,
- 'size' : float(color) }
+ self.attributeType : float(color) }
else:
self.mainPanel.FindWindowById(id + 1000).Disable()
@@ -197,97 +223,88 @@
num = event.GetId()
size = event.GetInt()
- self.ruleslines[num - 2000]['size'] = size
+ self.ruleslines[num - 2000][self.attributeType] = size
def OnRuleValue(self, event):
"""!Rule value changed"""
num = event.GetId()
- vals = event.GetString().strip()
+ val = event.GetString().strip()
- if vals == '':
+ if val == '':
return
-
- if self.mapType == 'vector':
- self.SetVectorRule(num, vals)
+ try:
+ table = self.parent.colorTable
+ except AttributeError:
+ # due to scrollpanel in vector dialog
+ table = self.parent.GetParent().colorTable
+ if table:
+ self.SetRasterRule(num, val)
else:
- self.SetRasterRule(num, vals)
+ self.SetVectorRule(num, val)
- def SetRasterRule(self, num, vals):
+ def SetRasterRule(self, num, val):
"""!Set raster rule"""
- self.ruleslines[num-1000]['value'] = vals
+ self.ruleslines[num - 1000]['value'] = val
- def SetVectorRule(self, num, vals):
+ def SetVectorRule(self, num, val):
"""!Set vector rule"""
- tc = self.mainPanel.FindWindowById(num)
- if self.columnType == 'color':
- source, target = 'source_rgb', 'rgb'
- else:
- source, target = 'source_size', 'size'
- if self.properties[source] == '' or self.properties[target] == '':
- tc.SetValue('')
- gcmd.GMessage(parent = self,
- message = _("Please select attribute column "
- "and RGB color column first"))
- else:
- try:
- self.ruleslines[num-1000]['value'] = self.SQLConvert(vals, self.columnType)
- except ValueError:
- tc.SetValue('')
- self.ruleslines[num-1000]['value'] = ''
-
- return
+ vals = []
+ vals.append(val)
+ try:
+ vals.append(self.mainPanel.FindWindowById(num + 1).GetValue())
+ except AttributeError:
+ vals.append(None)
+ self.ruleslines[num - 1000]['value'] = self.SQLConvert(vals)
def Enable(self, enable = True):
"""!Enable/Disable all widgets"""
for child in self.mainPanel.GetChildren():
child.Enable(enable)
+ sql = True
+ self.LoadRulesline(sql)# todo
self.btnAdd.Enable(enable)
self.numRules.Enable(enable)
+ self.checkAll.Enable(enable)
+ self.clearAll.Enable(enable)
def LoadRules(self):
- """!Fill rule widgets from ruleslines"""
message = ""
for item in range(len(self.ruleslines)):
self.mainPanel.FindWindowById(item + 1000).SetValue(self.ruleslines[item]['value'])
r, g, b = (0, 0, 0) # default
- if self.ruleslines[item][self.columnType] == '':
- if self.columnType == 'color':
- self.ruleslines[item][self.columnType] = '%d:%d:%d' % (r, g, b)
- elif self.columnType == 'size':
- self.ruleslines[item][self.columnType] = 100
+ if not self.ruleslines[item][self.attributeType]:
+ if self.attributeType == 'color':
+ self.ruleslines[item][self.attributeType] = '%d:%d:%d' % (r, g, b)
+ elif self.attributeType == 'size':
+ self.ruleslines[item][self.attributeType] = 100
+ elif self.attributeType == 'width':
+ self.ruleslines[item][self.attributeType] = 2
- if self.columnType == 'color':
+ if self.attributeType == 'color':
try:
- r, g, b = map(int, self.ruleslines[item][self.columnType].split(':'))
+ r, g, b = map(int, self.ruleslines[item][self.attributeType].split(':'))
except ValueError, e:
message = _("Bad color format. Use color format '0:0:0'")
self.mainPanel.FindWindowById(item + 2000).SetValue((r, g, b))
else:
- value = float(self.ruleslines[item][self.columnType])
+ value = float(self.ruleslines[item][self.attributeType])
self.mainPanel.FindWindowById(item + 2000).SetValue(value)
if message:
gcmd.GMessage(parent = self.parent, message = message)
return False
- return True
-
- def SQLConvert(self, vals, type = 'color'):
+ return True
+
+ def SQLConvert(self, vals):
"""!Prepare value for SQL query"""
- if type == 'color':
- source = 'source_rgb'
- elif type == 'size':
- source = 'source_size'
- valslist = []
- valslist = vals.split('to')
- if len(valslist) == 1:
- sqlrule = '%s=%s' % (self.properties[source], valslist[0])
- elif len(valslist) > 1:
- sqlrule = '%s>=%s AND %s<=%s' % (self.properties[source], valslist[0],
- self.properties[source], valslist[1])
+ if vals[0].isdigit():
+ sqlrule = '%s>=%s' % (self.properties['sourceColumn'], vals[0])
+ if vals[1]:
+ sqlrule += ' AND %s<%s' % (self.properties['sourceColumn'], vals[1])
else:
- return None
+ sqlrule = '%s=%s' % (self.properties['sourceColumn'], vals[0])
return sqlrule
@@ -302,7 +319,6 @@
@param nviz True if ColorTable is called from nviz thematic mapping
"""
self.parent = parent # GMFrame
-
wx.Frame.__init__(self, parent, id, title, style = style, **kwargs)
self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
@@ -313,8 +329,7 @@
# input map to change
self.inmap = ''
# reference to layer with preview
- self.layer = None
-
+ self.layer = None
# layout
self._doLayout()
@@ -334,10 +349,10 @@
# if not the right type, than select another
try:
sel = self.parent.curr_page.maptree.layer_selected
- if sel and self.parent.curr_page.maptree.GetPyData(sel)[0]['type'] == self.type:
+ if sel and self.parent.curr_page.maptree.GetPyData(sel)[0]['type'] == self.mapType:
layer = sel
else:
- layer = self.parent.curr_page.maptree.FindItemByData(key = 'type', value = self.type)
+ layer = self.parent.curr_page.maptree.FindItemByData(key = 'type', value = self.mapType)
except:
layer = None
if layer:
@@ -346,7 +361,69 @@
type = mapLayer.GetType()
self.selectionInput.SetValue(name)
self.inmap = name
-
+
+ def _createMapSelection(self, parent):
+ """!Create map selection part of dialog"""
+ # top controls
+ if self.mapType == 'raster':
+ maplabel = _('Select raster map:')
+ else:
+ maplabel = _('Select vector map:')
+ inputBox = wx.StaticBox(parent, id = wx.ID_ANY,
+ label = " %s " % maplabel)
+ inputSizer = wx.StaticBoxSizer(inputBox, wx.VERTICAL)
+
+ self.selectionInput = gselect.Select(parent, id = wx.ID_ANY,
+ size = globalvar.DIALOG_GSELECT_SIZE,
+ type = self.mapType)
+ # layout
+ inputSizer.Add(item = self.selectionInput,
+ flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND, border = 5)
+ return inputSizer
+
+ def _createFileSelection(self, parent):
+ """!Create file (open/save rules) selection part of dialog"""
+ inputBox = wx.StaticBox(parent, id = wx.ID_ANY,
+ label = " %s " % _("Import or export color table:"))
+ inputSizer = wx.StaticBoxSizer(inputBox, wx.VERTICAL)
+
+ self.loadRules = filebrowse.FileBrowseButton(parent = parent, id = wx.ID_ANY, fileMask = '*',
+ size = globalvar.DIALOG_GSELECT_SIZE,
+ labelText = _('Load color table from file:'),
+ dialogTitle = _('Choose file to load color table'),
+ buttonText = _('Load'),
+ toolTip = _("Type filename or click to choose "
+ "file and load color table"),
+ startDirectory = os.getcwd(), fileMode = wx.OPEN,
+ changeCallback = self.OnLoadRulesFile)
+ self.saveRules = filebrowse.FileBrowseButton(parent = parent, id = wx.ID_ANY, fileMask = '*',
+ size = globalvar.DIALOG_GSELECT_SIZE,
+ labelText = _('Save color table to file:'),
+ dialogTitle = _('Choose file to save color table'),
+ toolTip = _("Type filename or click to choose "
+ "file and save color table"),
+ buttonText = _('Save'),
+ startDirectory = os.getcwd(), fileMode = wx.SAVE,
+ changeCallback = self.OnSaveRulesFile)
+
+ default = wx.Button(parent = parent, id = wx.ID_ANY, label = _("Reload default table"))
+ # layout
+ sizer = wx.BoxSizer(wx.HORIZONTAL)
+ sizer.Add(item = self.loadRules, flag = wx.RIGHT, border = 10)
+ sizer.Add(item = default, flag = wx.ALIGN_CENTER_VERTICAL)
+ inputSizer.Add(item = sizer, flag = wx.TOP|wx.LEFT, border = 5)
+ sizer = wx.BoxSizer(wx.HORIZONTAL)
+ sizer.Add(item = self.saveRules, flag = wx.ALIGN_CENTER_VERTICAL)
+ inputSizer.Add(item = sizer, flag = wx.ALL, border = 5)
+
+ default.Bind(wx.EVT_BUTTON, self.OnLoadDefaultTable)
+
+ if self.mapType == 'vector':
+ # parent is collapsible pane
+ parent.SetSizer(inputSizer)
+
+ return inputSizer
+
def _createPreview(self, parent):
"""!Create preview"""
# initialize preview display
@@ -368,6 +445,7 @@
# layout
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
+ btnSizer.Add(wx.Size(-1, -1), proportion = 1)
btnSizer.Add(self.btnHelp,
flag = wx.LEFT | wx.RIGHT, border = 5)
btnSizer.Add(self.btnCancel,
@@ -385,37 +463,30 @@
row = 0
# label with range
- self.cr_label = wx.StaticText(parent, id = wx.ID_ANY, label = '')
+ self.cr_label = wx.StaticText(parent, id = wx.ID_ANY)
bodySizer.Add(item = self.cr_label, pos = (row, 0), span = (1, 3),
flag = wx.ALL, border = 5)
row += 1
# color table
- self.colorRulesPanel = RulesPanel(parent = parent, mapType = self.type,
- columnType = 'color', properties = self.properties)
- if self.type == 'vector':
- bodySizer.Add(item = self.colorRulesPanel.label, pos = (row, 0), span = (1, 2),
- flag = wx.ALL, border = 5)
- row += 1
+ self.rulesPanel = RulesPanel(parent = parent, mapType = self.mapType,
+ attributeType = self.attributeType, properties = self.properties)
- bodySizer.Add(item = self.colorRulesPanel.mainPanel, pos = (row, 0), span = (1, 2),
+ bodySizer.Add(item = self.rulesPanel.mainPanel, pos = (row, 0), span = (1, 2),
flag = wx.ALL, border = 5)
# add two rules as default
- self.colorRulesPanel.AddRules(2)
+ self.rulesPanel.AddRules(2)
# preview window
self._createPreview(parent = parent)
bodySizer.Add(item = self.preview, pos = (row, 2),
- flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 10)
- bodySizer.AddGrowableRow(row)
- bodySizer.AddGrowableCol(2)
+ flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 5)
row += 1
+ # add ckeck all and clear all
+ bodySizer.Add(item = self.rulesPanel.checkAll, flag = wx.ALIGN_CENTER_VERTICAL,
+ pos = (row, 0))
+ bodySizer.Add(item = self.rulesPanel.clearAll, pos = (row, 1))
- # add rules button and spin to sizer
- bodySizer.Add(item = self.colorRulesPanel.numRules, pos = (row, 0),
- flag = wx.ALIGN_CENTER_VERTICAL)
- bodySizer.Add(item = self.colorRulesPanel.btnAdd, pos = (row, 1))
-
# preview button
self.btnPreview = wx.Button(parent, id = wx.ID_ANY,
label = _("Preview"))
@@ -424,6 +495,14 @@
self.btnPreview.Enable(False)
self.btnPreview.SetToolTipString(_("Show preview of map "
"(current Map Display extent is used)."))
+ row +=1
+ # add rules button and spin to sizer
+ bodySizer.Add(item = self.rulesPanel.numRules, pos = (row, 0),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+ bodySizer.Add(item = self.rulesPanel.btnAdd, pos = (row, 1))
+
+
+
return bodySizer
@@ -437,10 +516,8 @@
def OnCloseWindow(self, event):
"""!Window closed
- Also remove associated rendered images
"""
- self.Map.Clean()
- self.Destroy()
+ self.OnCancel(event)
def OnApply(self, event):
"""!Apply selected color table
@@ -448,22 +525,178 @@
@return True on success otherwise False
"""
ret = self.CreateColorTable()
+ if not self.colorTable:
+ self.UseAttrColumn()
if ret:
display = self.parent.GetLayerTree().GetMapDisplay()
if display and display.IsAutoRendered():
display.GetWindow().UpdateMap(render = True)
-
+
return ret
def OnOK(self, event):
"""!Apply selected color table and close the dialog"""
if self.OnApply(event):
- self.Destroy()
+ self.OnCancel(event)
def OnCancel(self, event):
- """!Do not apply any changes and close the dialog"""
+ """!Do not apply any changes, remove associated
+ rendered images and close the dialog"""
+ self.Map.Clean()
self.Destroy()
+ def OnSaveRulesFile(self, event):
+ """!Save color table to file"""
+ path = event.GetString()
+ if not os.path.exists(path):
+ return
+
+ rulestxt = ''
+ for rule in self.rulesPanel.ruleslines.itervalues():
+ if not rule['value']:
+ continue
+ rulestxt += rule['value'] + ' ' + rule['color'] + '\n'
+ if not rulestxt:
+ gcmd.GMessage(message = _("Nothing to save."),
+ parent = self)
+ return
+
+ fd = open(path, 'w')
+ fd.write(rulestxt)
+ fd.close()
+
+ def OnLoadRulesFile(self, event):
+ """!Load color table from file"""
+ path = event.GetString()
+ if not os.path.exists(path):
+ return
+
+ self.rulesPanel.Clear()
+
+ file = open(path, 'r')
+ ctable = file.read()
+ self.ReadColorTable(ctable = ctable)
+
+ def ReadColorTable(self, ctable):
+ """!Read color table
+
+ @param table color table in format coming from r.colors.out"""
+
+ rulesNumber = len(ctable.splitlines())
+ self.rulesPanel.AddRules(rulesNumber)
+
+ minim = maxim = count = 0
+ for line in ctable.splitlines():
+ try:
+ value, color = map(lambda x: x.strip(), line.split(' '))
+ except ValueError:
+ gcmd.GMessage(parent = self, message = _("Invalid color table format"))
+ self.rulesPanel.Clear()
+ return
+
+ self.rulesPanel.ruleslines[count]['value'] = value
+ self.rulesPanel.ruleslines[count]['color'] = color
+ self.rulesPanel.mainPanel.FindWindowById(count + 1000).SetValue(value)
+ rgb = list()
+ for c in color.split(':'):
+ rgb.append(int(c))
+ self.rulesPanel.mainPanel.FindWindowById(count + 2000).SetColour(rgb)
+ # range
+ try:
+ if float(value) < minim:
+ minim = float(value)
+ if float(value) > maxim:
+ maxim = float(value)
+ except ValueError: # nv, default
+ pass
+ count += 1
+
+ if self.mapType == 'vector':
+ # raster min, max is known from r.info
+ self.properties['min'], self.properties['max'] = minim, maxim
+ self.SetRangeLabel()
+
+ self.OnPreview(tmp = True)
+
+ def OnLoadDefaultTable(self, event):
+ """!Load internal color table"""
+ self.LoadTable()
+
+ def LoadTable(self, mapType = 'raster'):
+ """!Load current color table (using `r(v).colors.out`)
+
+ @param mapType map type (raster or vector)"""
+
+ self.rulesPanel.Clear()
+ if mapType == 'raster':
+ cmd = ['r.colors.out',
+ 'read=True',
+ 'map=%s' % self.inmap,
+ 'rules=-']
+ else:
+ cmd = ['v.colors.out',
+ 'read=True',
+ 'map=%s' % self.inmap,
+ 'rules=-']
+
+ if self.properties['sourceColumn'] and self.properties['sourceColumn'] != 'cat':
+ cmd.append('column=%s' % self.properties['sourceColumn'])
+
+ cmd = utils.CmdToTuple(cmd)
+
+ if self.inmap:
+ ctable = gcmd.RunCommand(cmd[0], **cmd[1])
+ else:
+ self.OnPreview()
+ return
+
+ self.ReadColorTable(ctable = ctable)
+
+ def CreateColorTable(self, tmp = False):
+ """!Creates color table
+
+ @return True on success
+ @return False on failure
+ """
+ rulestxt = ''
+
+ for rule in self.rulesPanel.ruleslines.itervalues():
+ if not rule['value']: # skip empty rules
+ continue
+
+ if rule['value'] not in ('nv', 'default') and \
+ rule['value'][-1] != '%' and \
+ not self._IsNumber(rule['value']):
+ gcmd.GError(_("Invalid rule value '%s'. Unable to apply color table.") % rule['value'],
+ parent = self)
+ return False
+
+ rulestxt += rule['value'] + ' ' + rule['color'] + '\n'
+
+ if not rulestxt:
+ gcmd.GMessage(parent = self, message = _("No color rules given."))
+ return False
+
+ gtemp = utils.GetTempfile()
+ output = open(gtemp, "w")
+ try:
+ output.write(rulestxt)
+ finally:
+ output.close()
+
+ cmd = ['%s.colors' % self.mapType[0],#r.colors/v.colors
+ 'map=%s' % self.inmap,
+ 'rules=%s' % gtemp]
+ if self.mapType == 'vector' and self.properties['sourceColumn']\
+ and self.properties['sourceColumn'] != 'cat':
+ cmd.append('column=%s' % self.properties['sourceColumn'])
+ cmd = utils.CmdToTuple(cmd)
+ ret = gcmd.RunCommand(cmd[0], **cmd[1])
+ if ret != 0:
+ return False
+
+ return True
+
def DoPreview(self, ltype, cmdlist):
"""!Update preview (based on computational region)"""
@@ -475,7 +708,7 @@
self.layer.SetCmd(cmdlist)
# apply new color table and display preview
- self.CreateColorTable(force = True)
+ self.CreateColorTable(tmp = True)
self.preview.UpdatePreview()
def RunHelp(self, cmd):
@@ -498,8 +731,9 @@
def __init__(self, parent, **kwargs):
"""!Dialog for interactively entering color rules for raster maps"""
- self.type = 'raster'
-
+ self.mapType = 'raster'
+ self.attributeType = 'color'
+ self.colorTable = True
# raster properties
self.properties = {
# min cat in raster map
@@ -510,10 +744,6 @@
ColorTable.__init__(self, parent,
title = _('Create new color table for raster map'), **kwargs)
-
-
- # additional bindings for raster color management
- self.Bind(wx.EVT_BUTTON, self.OnSaveTable, self.btnSave)
self._initLayer()
@@ -521,39 +751,6 @@
self.CentreOnScreen()
self.Show()
- def _createMapSelection(self, parent):
- """!Create map selection part of dialog"""
- # top controls
- maplabel = _('Select raster map:')
- inputBox = wx.StaticBox(parent, id = wx.ID_ANY,
- label = " %s " % maplabel)
- inputSizer = wx.StaticBoxSizer(inputBox, wx.VERTICAL)
-
- self.selectionInput = gselect.Select(parent, id = wx.ID_ANY,
- size = globalvar.DIALOG_GSELECT_SIZE,
- type = 'cell')
- self.ovrwrtcheck = wx.CheckBox(parent, id = wx.ID_ANY,
- label = _('replace existing color table'))
- self.ovrwrtcheck.SetValue(UserSettings.Get(group = 'cmd', key = 'overwrite', subkey = 'enabled'))
-
- self.btnSave = wx.Button(parent, id = wx.ID_SAVE)
- self.btnSave.SetToolTipString(_('Save color table to file'))
-
- # layout
- inputSizer.Add(item = self.selectionInput,
- flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND, border = 5)
- replaceSizer = wx.BoxSizer(wx.HORIZONTAL)
- replaceSizer.Add(item = self.ovrwrtcheck, proportion = 1,
- flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL, border = 1)
-
- replaceSizer.Add(item = self.btnSave, proportion = 0,
- flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
-
- inputSizer.Add(item = replaceSizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 0)
-
- return inputSizer
-
def _doLayout(self):
"""!Do main layout"""
sizer = wx.BoxSizer(wx.VERTICAL)
@@ -564,6 +761,12 @@
sizer.Add(item = mapSelection, proportion = 0,
flag = wx.ALL | wx.EXPAND, border = 5)
#
+ # manage extern tables
+ #
+ fileSelection = self._createFileSelection(parent = self)
+ sizer.Add(item = fileSelection, proportion = 0,
+ flag = wx.ALL | wx.EXPAND, border = 5)
+ #
# body & preview
#
bodySizer = self._createBody(parent = self)
@@ -589,7 +792,9 @@
"""!Raster map selected"""
if event:
self.inmap = event.GetString()
-
+
+ self.loadRules.SetValue('')
+ self.saveRules.SetValue('')
if self.inmap:
if not grass.find_file(name = self.inmap, element = 'cell')['file']:
self.inmap = None
@@ -598,7 +803,7 @@
self.btnPreview.Enable(False)
self.btnOK.Enable(False)
self.btnApply.Enable(False)
- self.OnLoadTable(event)
+ self.LoadTable()
return
info = grass.raster_info(map = self.inmap)
@@ -606,7 +811,7 @@
if info:
self.properties['min'] = info['min']
self.properties['max'] = info['max']
- self.OnLoadTable(event)
+ self.LoadTable()
else:
self.inmap = ''
self.properties['min'] = self.properties['max'] = None
@@ -629,41 +834,9 @@
self.btnPreview.Enable()
self.btnOK.Enable()
self.btnApply.Enable()
-
- def OnLoadTable(self, event):
- """!Load current color table (using `r.colors.out`)"""
-
- self.colorRulesPanel.Clear()
-
- if self.inmap:
- ctable = gcmd.RunCommand('r.colors.out',
- parent = self,
- read = True,
- map = self.inmap,
- rules = '-')
- else:
- self.OnPreview(event)
- return
-
- rulesNumber = len(ctable.splitlines())
- self.colorRulesPanel.AddRules(rulesNumber)
-
- count = 0
- for line in ctable.splitlines():
- value, color = map(lambda x: x.strip(), line.split(' '))
- self.colorRulesPanel.ruleslines[count]['value'] = value
- self.colorRulesPanel.ruleslines[count]['color'] = color
- self.colorRulesPanel.mainPanel.FindWindowById(count + 1000).SetValue(value)
- rgb = list()
- for c in color.split(':'):
- rgb.append(int(c))
- self.colorRulesPanel.mainPanel.FindWindowById(count + 2000).SetColour(rgb)
- count += 1
-
- self.OnPreview(tmp = False)
- def OnPreview(self, event = None, tmp = True):
+ def OnPreview(self, tmp = True):
"""!Update preview (based on computational region)"""
if not self.inmap:
self.preview.EraseMap()
@@ -703,147 +876,66 @@
parent = self,
flags = 'r',
map = self.inmap)
-
- def OnSaveTable(self, event):
- """!Save color table to file"""
- rulestxt = ''
- for rule in self.ruleslines.itervalues():
- if not rule['value']:
- continue
- rulestxt += rule['value'] + ' ' + rule['color'] + '\n'
- if not rulestxt:
- gcmd.GMessage(message = _("Nothing to save."),
- parent = self)
- return
- dlg = wx.FileDialog(parent = self,
- message = _("Save color table to file"),
- defaultDir = os.getcwd(), style = wx.SAVE | wx.OVERWRITE_PROMPT)
- if dlg.ShowModal() == wx.ID_OK:
- path = dlg.GetPath()
- fd = open(path, 'w')
- fd.write(rulestxt)
- fd.close()
- dlg.Destroy()
-
def OnHelp(self, event):
"""!Show GRASS manual page"""
cmd = 'r.colors'
ColorTable.RunHelp(self, cmd = cmd)
- def CreateColorTable(self, force = False):
- """!Creates color table
- @return True on success
- @return False on failure
- """
- rulestxt = ''
-
- for rule in self.colorRulesPanel.ruleslines.itervalues():
- if not rule['value']: # skip empty rules
- continue
-
- if rule['value'] not in ('nv', 'default') and \
- rule['value'][-1] != '%' and \
- not self._IsNumber(rule['value']):
- gcmd.GError(_("Invalid rule value '%s'. Unable to apply color table.") % rule['value'],
- parent = self)
- return False
-
- rulestxt += rule['value'] + ' ' + rule['color'] + '\n'
-
- if not rulestxt:
- gcmd.GMessage(parent = self, message = _("No color rules given."))
- return False
-
- gtemp = utils.GetTempfile()
- output = open(gtemp, "w")
- try:
- output.write(rulestxt)
- finally:
- output.close()
-
- if not force and not self.ovrwrtcheck.IsChecked():
- flags = 'w'
- else:
- flags = ''
-
- ret = gcmd.RunCommand('r.colors',
- flags = flags,
- map = self.inmap,
- rules = gtemp)
- if ret != 0:
- gcmd.GMessage(_("Color table already exists. "
- "Check out 'replace existing color table' to "
- "overwrite it."),
- parent = self)
- return False
-
- return True
class VectorColorTable(ColorTable):
- def __init__(self, parent, **kwargs):
+ def __init__(self, parent, attributeType, **kwargs):
"""!Dialog for interactively entering color rules for vector maps"""
-
- self.type = 'vector'
+ # dialog attributes
+ self.mapType = 'vector'
+ self.attributeType = attributeType # color, size, width
+ # in version 7 v.colors used, otherwise color column only
+ self.version7 = int(grass.version()['version'].split('.')[0]) >= 7
+ self.colorTable = False
# vector properties
self.properties = {
- # list of database layers for vector (minimum of 1)
- 'layers' : [],
- # list of database columns for vector
- 'columns' : [],
# vector layer for attribute table to use for setting color
'layer' : 1,
# vector attribute table used for setting color
'table' : '',
# vector attribute column for assigning colors
- 'source_rgb' : '',
+ 'sourceColumn' : '',
+ # vector attribute column to use for loading colors
+ 'loadColumn' : '',
# vector attribute column to use for storing colors
- 'rgb' : '',
- # vector attribute column for assigning size
- 'source_size' : '',
- # vector attribute column to use for storing size
- 'size' : '',
- }
-
+ 'storeColumn' : '',
+ # vector attribute column for temporary storing colors
+ 'tmpColumn' : 'tmp_0',
+ # min value of attribute column/vector color table
+ 'min': None,
+ # max value of attribute column/vector color table
+ 'max': None
+ }
+ self.columnsProp = {'color': {'name': 'GRASSRGB', 'type1': 'varchar(11)', 'type2': ['character']},
+ 'size' : {'name': 'GRASSSIZE', 'type1': 'integer', 'type2': ['integer']},
+ 'width': {'name': 'GRASSWIDTH', 'type1': 'integer', 'type2': ['integer']}}
ColorTable.__init__(self, parent = parent,
- title = _('Create new color table for vector map'), **kwargs)
+ title = _('Create new color rules for vector map'), **kwargs)
# additional bindings for vector color management
- self.Bind(wx.EVT_COMBOBOX, self.OnLayerSelection, self.cb_vlayer)
- self.Bind(wx.EVT_COMBOBOX, self.OnColumnSelection, self.cb_color_att)
- self.Bind(wx.EVT_COMBOBOX, self.OnRGBColSelection, self.cb_rgb_col)
- self.Bind(wx.EVT_BUTTON, self.OnAddColumn, self.btn_add_RGB)
+ self.Bind(wx.EVT_COMBOBOX, self.OnLayerSelection, self.layerSelect)
+ self.Bind(wx.EVT_COMBOBOX, self.OnSourceColumnSelection, self.sourceColumn)
+ self.Bind(wx.EVT_COMBOBOX, self.OnFromColSelection, self.fromColumn)
+ self.Bind(wx.EVT_COMBOBOX, self.OnToColSelection, self.toColumn)
+ self.Bind(wx.EVT_BUTTON, self.OnAddColumn, self.addColumn)
self._initLayer()
- self.cr_label.SetLabel(_("Enter vector attribute values (e.g. 5) "
- "or ranges (e.g. 5 to 10)"))
+ if self.colorTable:
+ self.cr_label.SetLabel(_("Enter vector attribute values or percents:"))
+ else:
+ self.cr_label.SetLabel(_("Enter vector attribute values:"))
self.SetMinSize(self.GetSize())
self.CentreOnScreen()
+
+ self.SetSize((-1, 735))
self.Show()
-
- def _createMapSelection(self, parent):
- """!Create map selection part of dialog"""
- # top controls
- maplabel = _('Select vector map:')
- inputBox = wx.StaticBox(parent, id = wx.ID_ANY,
- label = " %s " % maplabel)
- inputSizer = wx.StaticBoxSizer(inputBox, wx.VERTICAL)
-
- self.selectionInput = gselect.Select(parent, id = wx.ID_ANY,
- size = globalvar.DIALOG_GSELECT_SIZE,
- type = 'vector')
-
- # layout
- inputSizer.Add(item = self.selectionInput,
- flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND, border = 5)
- replaceSizer = wx.BoxSizer(wx.HORIZONTAL)
-
- inputSizer.Add(item = replaceSizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 0)
- return inputSizer
-
def _createVectorAttrb(self, parent):
"""!Create part of dialog with layer/column selection"""
inputBox = wx.StaticBox(parent = parent, id = wx.ID_ANY,
@@ -852,114 +944,137 @@
label = _('Layer:'))
cb_vc_label = wx.StaticText(parent, id = wx.ID_ANY,
label = _('Attribute column:'))
- cb_vrgb_label = wx.StaticText(parent, id = wx.ID_ANY,
- label = _('RGB color column:'))
+
+ if self.attributeType == 'color':
+ labels = [_("Load color from column:"), _("Save color to column:")]
+ elif self.attributeType == 'size':
+ labels = [_("Load size from column:"), _("Save size to column:")]
+ elif self.attributeType == 'width':
+ labels = [_("Load width from column:"), _("Save width to column:")]
+
+ if self.version7 and self.attributeType == 'color':
+ self.useColumn = wx.CheckBox(parent, id = wx.ID_ANY,
+ label = _("Use color column instead of color table:"))
+ self.useColumn.Bind(wx.EVT_CHECKBOX, self.OnCheckColumn)
+
+ fromColumnLabel = wx.StaticText(parent, id = wx.ID_ANY,
+ label = labels[0])
+ toColumnLabel = wx.StaticText(parent, id = wx.ID_ANY,
+ label = labels[1])
+
self.rgb_range_label = wx.StaticText(parent, id = wx.ID_ANY)
- self.cb_vlayer = gselect.LayerSelect(parent)
- self.cb_color_att = gselect.ColumnSelect(parent)
- self.cb_rgb_col = gselect.ColumnSelect(parent)
- self.btn_add_RGB = wx.Button(parent, id = wx.ID_ANY,
+ self.layerSelect = gselect.LayerSelect(parent)
+ self.sourceColumn = gselect.ColumnSelect(parent)
+ self.fromColumn = gselect.ColumnSelect(parent)
+ self.toColumn = gselect.ColumnSelect(parent)
+ self.addColumn = wx.Button(parent, id = wx.ID_ANY,
label = _('Add column'))
- self.btn_add_RGB.SetToolTipString(_("Add GRASSRGB column to current attribute table."))
+ self.addColumn.SetToolTipString(_("Add GRASSRGB column to current attribute table."))
# layout
inputSizer = wx.StaticBoxSizer(inputBox, wx.VERTICAL)
vSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
- vSizer.Add(cb_vl_label, pos = (0, 0),
+ row = 0
+ vSizer.Add(cb_vl_label, pos = (row, 0),
flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(self.cb_vlayer, pos = (0, 1),
+ vSizer.Add(self.layerSelect, pos = (row, 1),
flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(cb_vc_label, pos = (1, 0),
+ row += 1
+ vSizer.Add(cb_vc_label, pos = (row, 0),
flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(self.cb_color_att, pos = (1, 1),
+ vSizer.Add(self.sourceColumn, pos = (row, 1),
flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(self.rgb_range_label, pos = (1, 2),
+ vSizer.Add(self.rgb_range_label, pos = (row, 2),
flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(cb_vrgb_label, pos = (2, 0),
+ row += 1
+ if self.version7 and self.attributeType == 'color':
+ vSizer.Add(self.useColumn, pos = (row, 0), span = (1, 2),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+ row += 1
+
+ vSizer.Add(fromColumnLabel, pos = (row, 0),
flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(self.cb_rgb_col, pos = (2, 1),
+ vSizer.Add(self.fromColumn, pos = (row, 1),
flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(self.btn_add_RGB, pos = (2, 2),
+ row += 1
+ vSizer.Add(toColumnLabel, pos = (row, 0),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+ vSizer.Add(self.toColumn, pos = (row, 1),
flag = wx.ALIGN_CENTER_VERTICAL)
+ vSizer.Add(self.addColumn, pos = (row, 2),
+ flag = wx.ALIGN_CENTER_VERTICAL)
inputSizer.Add(item = vSizer,
flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND, border = 5)
-
+ self.colorColumnSizer = vSizer
return inputSizer
def _doLayout(self):
"""!Do main layout"""
+ scrollPanel = scrolled.ScrolledPanel(self, id = wx.ID_ANY, size = (650, 500),
+ style = wx.TAB_TRAVERSAL)
+ scrollPanel.SetupScrolling()
sizer = wx.BoxSizer(wx.VERTICAL)
#
# map selection
#
- mapSelection = self._createMapSelection(parent = self)
+ mapSelection = self._createMapSelection(parent = scrollPanel)
sizer.Add(item = mapSelection, proportion = 0,
flag = wx.ALL | wx.EXPAND, border = 5)
#
+ # manage extern tables
+ #
+ if self.version7 and self.attributeType == 'color':
+ self.cp = wx.CollapsiblePane(scrollPanel, label = _("Import or export color table"),
+ winid = wx.ID_ANY,
+ style = wx.CP_DEFAULT_STYLE|wx.CP_NO_TLW_RESIZE)
+ self.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self.OnPaneChanged, self.cp)
+
+ self._createFileSelection(parent = self.cp.GetPane())
+ sizer.Add(item = self.cp, proportion = 0,
+ flag = wx.ALL | wx.EXPAND, border = 5)
+ #
# set vector attributes
#
- vectorAttrb = self._createVectorAttrb(parent = self)
+ vectorAttrb = self._createVectorAttrb(parent = scrollPanel)
sizer.Add(item = vectorAttrb, proportion = 0,
flag = wx.ALL | wx.EXPAND, border = 5)
#
# body & preview
#
- bodySizer = self._createBody(parent = self)
- sizer.Add(item = bodySizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 5)
+ bodySizer = self._createBody(parent = scrollPanel)
+ sizer.Add(item = bodySizer, proportion = 0,
+ flag = wx.ALL, border = 5)
+
+
+ scrollPanel.SetSizer(sizer)
+ scrollPanel.Fit()
+
#
# buttons
#
btnSizer = self._createButtons()
- sizer.Add(item = wx.StaticLine(parent = self, id = wx.ID_ANY,
+ mainsizer = wx.BoxSizer(wx.VERTICAL)
+ mainsizer.Add(scrollPanel, proportion = 1, flag = wx.EXPAND | wx.ALL, border = 5)
+ mainsizer.Add(item = wx.StaticLine(parent = self, id = wx.ID_ANY,
style = wx.LI_HORIZONTAL), proportion = 0,
flag = wx.EXPAND | wx.ALL, border = 5)
+ mainsizer.Add(item = btnSizer, proportion = 0,
+ flag = wx.ALL | wx.ALIGN_RIGHT | wx.EXPAND, border = 5)
- sizer.Add(item = btnSizer, proportion = 0,
- flag = wx.ALL | wx.ALIGN_RIGHT, border = 5)
-
- self.SetSizer(sizer)
- sizer.Layout()
- sizer.Fit(self)
+ self.SetSizer(mainsizer)
+ mainsizer.Layout()
+ mainsizer.Fit(self)
+
+ def OnPaneChanged(self, event = None):
+ # redo the layout
self.Layout()
-
- def SetInfoString(self):
- """!Show information about vector map column type/range"""
- driver, db = self.dbInfo.GetDbSettings(int(self.properties['layer']))
- nrows = grass.db_describe(table = self.properties['table'], driver = driver, database = db)['nrows']
- self.properties['min'] = self.properties['max'] = ''
- type = self.dbInfo.GetTableDesc(self.properties['table'])\
- [self.properties['source_rgb']]['type']
- ctype = self.dbInfo.GetTableDesc(self.properties['table'])\
- [self.properties['source_rgb']]['ctype']
- if ctype == int or ctype == float:
- if nrows < 500: # not too large
- ret = gcmd.RunCommand('v.db.select',
- quiet = True,
- read = True,
- flags = 'c',
- map = self.inmap,
- layer = self.properties['layer'],
- columns = self.properties['source_rgb']).strip('\n')
- records = ret.split('\n')
- try:
- self.properties['min'] = min(map(float, records))
- self.properties['max'] = max(map(float, records))
- except ValueError:
- self.properties['min'] = self.properties['max'] = ''
-
- if self.properties['min'] or self.properties['max']:
- if ctype == int:
- self.cr_label.SetLabel(_("Enter vector attribute values or ranges (type: %s, range: %d - %d)")
- % (type, self.properties['min'], self.properties['max']))
- elif ctype == float:
- self.cr_label.SetLabel(_("Enter vector attribute values or ranges (type: %s, range: %.1f - %.1f )")
- % (type, self.properties['min'], self.properties['max']))
+ # and also change the labels
+ if self.cp.IsExpanded():
+ self.cp.SetLabel('')
else:
- self.cr_label.SetLabel(_("Enter vector attribute values or ranges (type: %s)") % type)
-
-
+ self.cp.SetLabel(_("Import or export color table"))
+
def CheckMapset(self):
"""!Check if current vector is in current mapset"""
if grass.find_file(name = self.inmap,
@@ -978,15 +1093,59 @@
if dlg.ShowModal() == wx.ID_YES:
dlg.Destroy()
menuform.GUI(parent = self).ParseCommand(['v.db.addtable', 'map=' + self.inmap],
- completed = (self.CreateTable, self.inmap, ''))
+ completed = (self.CreateAttrTable, self.inmap, ''))
else:
dlg.Destroy()
+
+ def OnCheckColumn(self, event):
+ """!Use color column instead of color table"""
+ if self.useColumn.GetValue():
+ self.properties['loadColumn'] = self.fromColumn.GetStringSelection()
+ self.properties['storeColumn'] = self.toColumn.GetStringSelection()
+ self.fromColumn.Enable(True)
+ self.toColumn.Enable(True)
+ self.colorTable = False
+ if self.properties['loadColumn']:
+ self.LoadTable()
+ else:
+ self.rulesPanel.Clear()
+ else:
+ self.properties['loadColumn'] = ''
+ self.properties['storeColumn'] = ''
+ self.fromColumn.Enable(False)
+ self.toColumn.Enable(False)
+ self.colorTable = True
+
+ self.LoadTable()
+
+
+ def EnableVectorAttributes(self, enable):
+ """!Enable/disable part of dialog connected with db"""
+ for child in self.colorColumnSizer.GetChildren():
+ child.GetWindow().Enable(enable)
+
+ def DisableClearAll(self):
+ """!Enable, disable the whole dialog"""
+ self.rulesPanel.Clear()
+ self.EnableVectorAttributes(False)
+ self.btnPreview.Enable(False)
+ self.btnOK.Enable(False)
+ self.btnApply.Enable(False)
+ self.preview.EraseMap()
+
def OnSelectionInput(self, event):
"""!Vector map selected"""
if event:
+ if self.inmap:
+ # switch to another map -> delete temporary column
+ self.DeleteTemporaryColumn()
self.inmap = event.GetString()
-
+
+ if self.version7 and self.attributeType == 'color':
+ self.loadRules.SetValue('')
+ self.saveRules.SetValue('')
+
if self.inmap:
if not grass.find_file(name = self.inmap, element = 'vector')['file']:
self.inmap = None
@@ -994,99 +1153,163 @@
self.UpdateDialog()
def UpdateDialog(self):
- """!Update dialog after map selection"""
+ """!Update dialog after map selection"""
if not self.inmap:
- self.colorRulesPanel.ruleslines.Clear()
- self.btnPreview.Enable(False)
- self.btnOK.Enable(False)
- self.btnApply.Enable(False)
- self.preview.EraseMap()
+ self.DisableClearAll()
return
-
+
+ if self.inmap and not self.CheckMapset():
+ # currently v.colors need the map to be in current mapset
+ if self.version7 and self.attributeType == 'color':
+ message = _("Selected map <%s> is not in current mapset <%s>. "
+ "Color rules cannot be edited.") % \
+ (self.inmap, grass.gisenv()['MAPSET'])
+ else:
+ message = _("Selected map <%s> is not in current mapset <%s>. "
+ "Attribute table cannot be edited.") % \
+ (self.inmap, grass.gisenv()['MAPSET'])
+ wx.CallAfter(gcmd.GMessage, parent = self, message = message)
+ self.DisableClearAll()
+ return
+
# check for db connection
self.dbInfo = gselect.VectorDBInfo(self.inmap)
- if not len(self.dbInfo.layers):
- wx.CallAfter(self.NoConnection, self.inmap)
- for combo in (self.cb_vlayer, self.cb_color_att, self.cb_rgb_col):
+ enable = True
+ if not len(self.dbInfo.layers): # no connection
+ if not (self.version7 and self.attributeType == 'color'): # otherwise it doesn't matter
+ wx.CallAfter(self.NoConnection, self.inmap)
+ enable = False
+ for combo in (self.layerSelect, self.sourceColumn, self.fromColumn, self.toColumn):
combo.SetValue("")
- combo.Disable()
combo.Clear()
- enable = False
- else:
+ for prop in ('sourceColumn', 'loadColumn', 'storeColumn'):
+ self.properties[prop] = ''
+ self.EnableVectorAttributes(False)
+
+ else: # db connection exist
# initialize layer selection combobox
- for combo in (self.cb_vlayer, self.cb_color_att, self.cb_rgb_col):
- combo.Enable()
- self.cb_vlayer.InsertLayers(self.inmap)
+ self.EnableVectorAttributes(True)
+ self.layerSelect.InsertLayers(self.inmap)
# initialize attribute table for layer=1
- self.properties['layer'] = self.cb_vlayer.GetString(0)
- self.cb_vlayer.SetStringSelection(self.properties['layer'])
+ self.properties['layer'] = self.layerSelect.GetString(0)
+ self.layerSelect.SetStringSelection(self.properties['layer'])
layer = int(self.properties['layer'])
self.properties['table'] = self.dbInfo.layers[layer]['table']
+ if self.attributeType == 'color':
+ self.AddTemporaryColumn(type = 'varchar(11)')
+ else:
+ self.AddTemporaryColumn(type = 'integer')
+
# initialize column selection comboboxes
+
self.OnLayerSelection(event = None)
+ if self.version7 and self.attributeType == 'color':
+ self.useColumn.SetValue(False)
+ self.OnCheckColumn(event = None)
+
+ self.LoadTable()
- if self.CheckMapset():
- enable = True
- self.btn_add_RGB.Enable(True)
- else:
- enable = False
- wx.CallAfter(gcmd.GMessage, parent = self,
- message = _("Selected map <%s> is not in current mapset <%s>. "
- "Attribute table cannot be edited. "
- "Color rules will not be saved.") %
- (self.inmap, grass.gisenv()['MAPSET']))
-
- self.btn_add_RGB.Enable(False)
-
self.btnPreview.Enable(enable)
self.btnOK.Enable(enable)
self.btnApply.Enable(enable)
+
+ def AddTemporaryColumn(self, type):
+ """!Add temporary column to not overwrite the original values,
+ need to be deleted when closing dialog and unloading map
+
+ @param type type of column (e.g. vachar(11))"""
+ # because more than one dialog with the same map can be opened we must test column name and
+ # create another one
+ while self.properties['tmpColumn'] in self.dbInfo.GetTableDesc(self.properties['table']).keys():
+ name, idx = self.properties['tmpColumn'].split('_')
+ idx = int(idx)
+ idx += 1
+ self.properties['tmpColumn'] = name + '_' + str(idx)
+ if self.version7:
+ modul = 'v.db.addcolumn'
+ else:
+ modul = 'v.db.addcol'
+ ret = gcmd.RunCommand(modul,
+ parent = self,
+ map = self.inmap,
+ layer = self.properties['layer'],
+ column = '%s %s' % (self.properties['tmpColumn'], type))
+
+ def DeleteTemporaryColumn(self):
+ """!Delete temporary column"""
+ if self.inmap:
+ if self.version7:
+ modul = 'v.db.dropcolumn'
+ else:
+ modul = 'v.db.dropcol'
+ ret = gcmd.RunCommand(modul,
+ map = self.inmap,
+ layer = self.properties['layer'],
+ column = self.properties['tmpColumn'])
+
def OnLayerSelection(self, event):
# reset choices in column selection comboboxes if layer changes
- vlayer = int(self.cb_vlayer.GetStringSelection())
- self.cb_color_att.InsertColumns(vector = self.inmap, layer = vlayer, dbInfo = self.dbInfo)
- self.cb_color_att.SetSelection(0)
- self.properties['source_rgb'] = self.cb_color_att.GetString(0)
- self.cb_rgb_col.InsertColumns(vector = self.inmap, layer = vlayer, type = ["character"], dbInfo = self.dbInfo)
-# self.cb_rgb_col.Delete(self.cb_rgb_col.FindString(self.properties['source_rgb']))
- found = self.cb_rgb_col.FindString('GRASSRGB')
+ vlayer = int(self.layerSelect.GetStringSelection())
+ self.sourceColumn.InsertColumns(vector = self.inmap, layer = vlayer,
+ type = ['integer', 'double precision'], dbInfo = self.dbInfo,
+ excludeCols = ['tmpColumn'])
+ self.sourceColumn.SetStringSelection('cat')
+ self.properties['sourceColumn'] = self.sourceColumn.GetString(0)
+
+ if self.attributeType == 'color':
+ type = ['character']
+ else:
+ type = ['integer']
+ self.fromColumn.InsertColumns(vector = self.inmap, layer = vlayer, type = type,
+ dbInfo = self.dbInfo, excludeCols = ['tmpColumn'])
+ self.toColumn.InsertColumns(vector = self.inmap, layer = vlayer, type = type,
+ dbInfo = self.dbInfo, excludeCols = ['tmpColumn'])
+
+ found = self.fromColumn.FindString(self.columnsProp[self.attributeType]['name'])
if found != wx.NOT_FOUND:
- self.cb_rgb_col.SetSelection(found)
- self.properties['rgb'] = self.cb_rgb_col.GetString(found)
+ self.fromColumn.SetSelection(found)
+ self.toColumn.SetSelection(found)
+ self.properties['loadColumn'] = self.fromColumn.GetString(found)
+ self.properties['storeColumn'] = self.toColumn.GetString(found)
else:
- self.properties['rgb'] = ''
-## self.SetInfoString()
+ self.properties['loadColumn'] = ''
+ self.properties['storeColumn'] = ''
- self.LoadTable(attColumn = self.properties['source_rgb'],
- rgbColumn = self.properties['rgb'], rulesPanel = self.colorRulesPanel)
+ if event:
+ self.LoadTable()
self.Update()
- def OnColumnSelection(self, event):
- self.properties['source_rgb'] = event.GetString()
+ def OnSourceColumnSelection(self, event):
+ self.properties['sourceColumn'] = event.GetString()
- self.LoadTable(attColumn = self.properties['source_rgb'],
- rgbColumn = self.properties['rgb'], rulesPanel = self.colorRulesPanel)
+ self.LoadTable()
def OnAddColumn(self, event):
- """!Add GRASSRGB column if it doesn't exist"""
- if 'GRASSRGB' not in self.cb_rgb_col.GetItems():
- ret = gcmd.RunCommand('v.db.addcolumn',
- map = self.inmap,
+ """!Add GRASS(RGB,SIZE,WIDTH) column if it doesn't exist"""
+ if self.columnsProp[self.attributeType]['name'] not in self.fromColumn.GetItems():
+ if self.version7:
+ modul = 'v.db.addcolumn'
+ else:
+ modul = 'v.db.addcol'
+ ret = gcmd.RunCommand(modul,
+ map = self.inmap,
layer = self.properties['layer'],
- columns = 'GRASSRGB varchar(20)')
- self.cb_rgb_col.InsertColumns(self.inmap, self.properties['layer'], type = ["character"])
- self.cb_rgb_col.SetStringSelection('GRASSRGB')
- self.properties['rgb'] = self.cb_rgb_col.GetStringSelection()
+ columns = '%s %s' % (self.columnsProp[self.attributeType]['name'],
+ self.columnsProp[self.attributeType]['type1']))
+ self.toColumn.InsertColumns(self.inmap, self.properties['layer'],
+ type = self.columnsProp[self.attributeType]['type2'])
+ self.toColumn.SetStringSelection(self.columnsProp[self.attributeType]['name'])
+ self.properties['storeColumn'] = self.toColumn.GetStringSelection()
- self.LoadTable(attColumn = self.properties['source_rgb'], rgbColumn = self.properties['rgb'],
- rulesPanel = self.colorRulesPanel, type = 'color')
+ self.LoadTable()
else:
gcmd.GMessage(parent = self,
- message = _("GRASSRGB column already exists."))
+ message = _("%s column already exists.") % \
+ self.columnsProp[self.attributeType]['name'])
- def CreateTable(self, dcmd, layer, params, propwin):
+ def CreateAttrTable(self, dcmd, layer, params, propwin):
"""!Create attribute table"""
if dcmd:
cmd = utils.CmdToTuple(dcmd)
@@ -1095,115 +1318,197 @@
self.OnSelectionInput(None)
return True
- for combo in (self.cb_vlayer, self.cb_color_att, self.cb_rgb_col):
+ for combo in (self.layerSelect, self.sourceColumn, self.fromColumn, self.toColumn):
combo.SetValue("")
combo.Disable()
return False
- def LoadTable(self, attColumn, rgbColumn, rulesPanel, type = 'color'):
+ def LoadTable(self):
+ """!Load table"""
+ if self.colorTable:
+ ColorTable.LoadTable(self, mapType = 'vector')
+ else:
+ self.LoadRulesFromColumn()
+
+ def LoadRulesFromColumn(self):
"""!Load current column (GRASSRGB, size column)"""
- rulesPanel.Clear()
- if not attColumn or not rgbColumn:
+ self.rulesPanel.Clear()
+ if not self.properties['sourceColumn']:
self.preview.EraseMap()
return
busy = wx.BusyInfo(message = _("Please wait, loading data from attribute table..."),
parent = self)
wx.Yield()
+
+ columns = self.properties['sourceColumn']
+ if self.properties['loadColumn']:
+ columns += ',' + self.properties['loadColumn']
+
if self.inmap:
- outFile = tempfile.NamedTemporaryFile(mode='w+b')
+ outFile = tempfile.NamedTemporaryFile(mode = 'w+b')
sep = '|'
ret = gcmd.RunCommand('v.db.select',
- quiet = True,
- flags = 'c',
- map = self.inmap,
- layer = self.properties['layer'],
- columns = attColumn + ',' + rgbColumn,
- fs = sep,
- stdout = outFile)
-
+ quiet = True,
+ flags = 'c',
+ map = self.inmap,
+ layer = self.properties['layer'],
+ columns = columns,
+ fs = sep,
+ stdout = outFile)
else:
- self.OnPreview(event)
+ self.preview.EraseMap()
busy.Destroy()
return
- if type == 'color':
- ctype = self.dbInfo.GetTableDesc(self.properties['table'])\
- [self.properties['source_rgb']]['ctype']
- elif type == 'size':
- ctype = self.dbInfo.GetTableDesc(self.properties['table'])\
- [self.properties['source_size']]['ctype']
+
outFile.seek(0)
i = 0
minim = maxim = 0.0
+ limit = 1000
while True:
# os.linesep doesn't work here (MSYS)
record = outFile.readline().replace('\n', '')
-
if not record:
break
- rulesPanel.ruleslines[i] = {}
+ self.rulesPanel.ruleslines[i] = {}
- value = record.split(sep)[0]
- if ctype not in (int, float):
- value = "'" + value + "'"
+ if not self.properties['loadColumn']:
+ col1 = record
+ col2 = None
else:
- if float(value) < minim:
- minim = float(value)
- if float(value) > maxim:
- maxim = float(value)
- rulesPanel.ruleslines[i]['value'] = value
- rulesPanel.ruleslines[i][type] = record.split(sep)[1]
+ col1, col2 = record.split(sep)
+
+ if float(col1) < minim:
+ minim = float(col1)
+ if float(col1) > maxim:
+ maxim = float(col1)
+
+ self.rulesPanel.ruleslines[i]['value'] = col1
+ self.rulesPanel.ruleslines[i][self.attributeType] = col2
+
i += 1
+
+ if i > limit:
+ dlg = wx.MessageDialog (parent = self, message = _(
+ "Number of loaded records reached %d, "
+ "displaying all the records will be time-consuming "
+ "and may lead to computer freezing, "
+ "do you still want to continue?") % i,
+ caption = _("Too many records"),
+ style = wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
+ if dlg.ShowModal() == wx.ID_YES:
+ dlg.Destroy()
+ else:
+ busy.Destroy()
+ dlg.Destroy()
+ return
+
- rulesPanel.AddRules(i, start = True)
- ret = rulesPanel.LoadRules()
- self.SetRangeLabel(type, ctype, minim, maxim)
+ self.rulesPanel.AddRules(i, start = True)
+ ret = self.rulesPanel.LoadRules()
+ self.properties['min'], self.properties['max'] = minim, maxim
+ self.SetRangeLabel()
+
if ret:
- self.OnPreview()
+ self.OnPreview()
else:
- rulesPanel.Clear()
+ self.rulesPanel.Clear()
busy.Destroy()
- def SetRangeLabel(self, type, ctype, minim, maxim):
+ def SetRangeLabel(self):
"""!Set labels with info about attribute column range"""
- if type == 'color':
- if minim or maxim:
- if ctype == int:
- self.rgb_range_label.SetLabel(_("range: %.1f to %.1f") % (minim, maxim))
- elif ctype == float:
- self.rgb_range_label.SetLabel(_("range: %d to %d") % (minim, maxim))
+
+ if self.properties['sourceColumn']:
+ ctype = self.dbInfo.GetTableDesc(self.properties['table'])[self.properties['sourceColumn']]['ctype']
+ else:
+ ctype = int
+
+ range = ''
+ if self.properties['min'] or self.properties['max']:
+ if ctype == float:
+ range = _("(range: %.1f to %.1f)") % (self.properties['min'], self.properties['max'])
+ elif ctype == int:
+ range = _("(range: %d to %d)") % (self.properties['min'], self.properties['max'])
+ if range:
+ if self.colorTable:
+ self.cr_label.SetLabel(_("Enter vector attribute values or percents %s:") % range)
else:
- self.rgb_range_label.SetLabel('')
- elif type == 'size':
- if minim or maxim:
- if ctype == int:
- self.size_range_label.SetLabel(_("range: %.1f to %.1f") % (minim, maxim))
- elif ctype == float:
- self.size_range_label.SetLabel(_("range: %d to %d") % (minim, maxim))
+ self.cr_label.SetLabel(_("Enter vector attribute values %s:") % range)
+ else:
+ if self.colorTable:
+ self.cr_label.SetLabel(_("Enter vector attribute values or percents:"))
else:
- self.size_range_label.SetLabel('')
+ self.cr_label.SetLabel(_("Enter vector attribute values:"))
-
- def OnRGBColSelection(self, event):
- self.properties['rgb'] = event.GetString()
+ def OnFromColSelection(self, event):
+ """!Selection in combobox (for loading values) changed"""
+ self.properties['loadColumn'] = event.GetString()
- self.LoadTable(attColumn = self.properties['source_rgb'],
- rgbColumn = self.properties['rgb'], rulesPanel = self.colorRulesPanel)
+ self.LoadTable()
+
+ def OnToColSelection(self, event):
+ """!Selection in combobox (for storing values) changed"""
+ self.properties['storeColumn'] = event.GetString()
+
+ def OnPreview(self, event = None, tmp = True):
+ """!Update preview (based on computational region)"""
+ if self.colorTable:
+ self.OnTablePreview(tmp)
+ else:
+ self.OnColumnPreview()
+
+ def OnTablePreview(self, tmp):
+ """!Update preview (based on computational region)"""
+ if not self.inmap:
+ self.preview.EraseMap()
+ return
+
+ ltype = 'vector'
+ cmdlist = ['d.vect',
+ 'map=%s' % self.inmap]
+
+ # find existing color table and copy to temp file
+ old_colrtable = None
+ path = grass.find_file(name = self.inmap, element = 'vector')['file']
+
+ if os.path.exists(os.path.join(path, 'colr')):
+ old_colrtable = os.path.join(path, 'colr')
+ colrtemp = utils.GetTempfile()
+ shutil.copyfile(old_colrtable, colrtemp)
- def OnPreview(self, event = None):
+ ColorTable.DoPreview(self, ltype, cmdlist)
+
+ # restore previous color table
+ if tmp:
+ if old_colrtable:
+ shutil.copyfile(colrtemp, old_colrtable)
+ os.remove(colrtemp)
+ else:
+ gcmd.RunCommand('v.colors',
+ parent = self,
+ flags = 'r',
+ map = self.inmap)
+ def OnColumnPreview(self):
"""!Update preview (based on computational region)"""
- if not self.inmap or not self.properties["rgb"]:
+ if not self.inmap or not self.properties['tmpColumn']:
self.preview.EraseMap()
return
cmdlist = ['d.vect',
'-a',
'map=%s' % self.inmap,
- 'rgb_column=%s' % self.properties["rgb"],
'type=point,line,boundary,area']
+
+ if self.attributeType == 'color':
+ cmdlist.append('rgb_column=%s' % self.properties['tmpColumn'])
+ elif self.attributeType == 'size':
+ cmdlist.append('size_column=%s' % self.properties['tmpColumn'])
+ elif self.attributeType == 'width':
+ cmdlist.append('width_column=%s' % self.properties['tmpColumn'])
+
ltype = 'vector'
ColorTable.DoPreview(self, ltype, cmdlist)
@@ -1213,7 +1518,38 @@
cmd = 'v.colors'
ColorTable.RunHelp(self, cmd = cmd)
- def CreateColorTable(self, force = False):
+ def UseAttrColumn(self, useAttrColumn = True):
+ """!Use attribute column to render map"""
+ # TODO switch back to table, not only selected map
+ layer = self.parent.curr_page.maptree.layer_selected
+ if layer and self.parent.curr_page.maptree.GetPyData(layer)[0]['maplayer'].GetName() == self.inmap:
+## cmd = self.parent.curr_page.maptree.GetPyData(layer)[0]['maplayer'].GetCmd()
+## if useAttrColumn:
+## cmd[1].update({'flags': 'a', })
+ cmdlist = ['d.vect',
+ '-a',
+ 'map=%s' % self.inmap,
+ 'type=point,line,boundary,area']
+
+ if self.attributeType == 'color':
+ cmdlist.append('rgb_column=%s' % self.properties['storeColumn'])
+ elif self.attributeType == 'size':
+ cmdlist.append('size_column=%s' % self.properties['storeColumn'])
+ elif self.attributeType == 'width':
+ cmdlist.append('width_column=%s' % self.properties['storeColumn'])
+
+ self.parent.curr_page.maptree.GetPyData(layer)[0]['maplayer'].SetCmd(cmdlist)
+
+ def CreateColorTable(self, tmp = False):
+ """!Create color rules (color table or color column)"""
+ if self.colorTable:
+ ret = ColorTable.CreateColorTable(self)
+ else:
+ ret = self.UpdateColorColumn(tmp)
+
+ return ret
+
+ def UpdateColorColumn(self, tmp):
"""!Creates color table
@return True on success
@@ -1221,13 +1557,19 @@
"""
rulestxt = ''
- for rule in self.colorRulesPanel.ruleslines.itervalues():
+ for rule in self.rulesPanel.ruleslines.itervalues():
if not rule['value']: # skip empty rules
continue
-
+ if tmp:
+ rgb_col = self.properties['tmpColumn']
+ else:
+ rgb_col = self.properties['storeColumn']
+ if not self.properties['storeColumn']:
+ gcmd.GMessage(self.parent, message = _("Please select column to save values to."))
+
rulestxt += "UPDATE %s SET %s='%s' WHERE %s ;\n" % (self.properties['table'],
- self.properties['rgb'],
- rule['color'],
+ rgb_col,
+ rule[self.attributeType],
rule['value'])
if not rulestxt:
return False
@@ -1244,15 +1586,11 @@
input = gtemp)
return True
-
-## def ColorFromString(self, rgb):
-## """!Convert color string '255:255:255' to tuple"""
-## try:
-## r, g, b = rgb.split(':')
-## return (r, g, b)
-##
-## except ValueError:
-## return False
+ def OnCancel(self, event):
+ """!Do not apply any changes and close the dialog"""
+ self.DeleteTemporaryColumn()
+ self.Map.Clean()
+ self.Destroy()
class ThematicVectorTable(VectorColorTable):
def __init__(self, parent, vectorType, **kwargs):
@@ -1261,69 +1599,9 @@
self.vectorType = vectorType
VectorColorTable.__init__(self, parent = parent, **kwargs)
- # additional bingings
- self.Bind(wx.EVT_COMBOBOX, self.OnSizeSourceSelection, self.cb_size_att)
- self.Bind(wx.EVT_COMBOBOX, self.OnSizeSelection, self.cb_size_col)
- self.Bind(wx.EVT_BUTTON, self.OnAddSizeColumn, self.btn_add_size)
- self.Bind(wx.EVT_CHECKBOX, self.OnColorChecked, self.rgb_check)
- self.Bind(wx.EVT_CHECKBOX, self.OnSizeChecked, self.size_check)
self.SetTitle(_("Thematic mapping for vector map in 3D view"))
-
- def UpdateDialog(self):
- """!Update dialog according to selected map"""
- VectorColorTable.UpdateDialog(self)
-
- if not len(self.dbInfo.layers):
- for combo in (self.cb_size_att, self.cb_size_col):
- combo.SetValue("")
- combo.Disable()
- combo.Clear()
- enable = False
- else:
- # initialize layer selection combobox
- for combo in (self.cb_vlayer, self.cb_size_att, self.cb_size_col):
- combo.Enable()
-
- if self.CheckMapset():
- self.btn_add_size.Enable(True)
- else:
- self.btn_add_RGB.Enable(False)
-
- def OnLayerSelection(self, event):
- VectorColorTable.OnLayerSelection(self, event)
- # reset choices in column selection comboboxes if layer changes
- vlayer = int(self.cb_vlayer.GetStringSelection())
- self.cb_size_att.InsertColumns(vector = self.inmap, layer = vlayer, dbInfo = self.dbInfo)
- self.cb_size_att.SetSelection(0)
- self.properties['source_size'] = self.cb_size_att.GetString(0)
- self.cb_size_col.InsertColumns(vector = self.inmap, layer = vlayer,
- type = ["integer", "double precision"], dbInfo = self.dbInfo)
- for item in self.cb_size_col.GetItems():
- if item.lower().find('size') >= 0:
- self.cb_size_col.SetStringSelection(item)
- self.properties['size'] = item
- else:
- self.properties['size'] = ''
-## self.SetInfoString()
- self.LoadTable(attColumn = self.properties['source_size'], rgbColumn = self.properties['size'],
- rulesPanel = self.sizeRulesPanel, type = 'size')
- self.Update()
-
- def OnSizeSelection(self, event):
- self.properties['size'] = event.GetString()
-
- self.LoadTable(attColumn = self.properties['source_size'], rgbColumn = self.properties['size'],
- rulesPanel = self.sizeRulesPanel, type = 'size')
-
- def OnSizeSourceSelection(self, event):
- self.properties['source_size'] = event.GetString()
-
-## self.SetInfoString()
-
- self.LoadTable(attColumn = self.properties['source_size'], rgbColumn = self.properties['size'],
- rulesPanel = self.sizeRulesPanel, type = 'size')
def _initLayer(self):
"""!Set initial layer when opening dialog"""
@@ -1331,275 +1609,33 @@
self.selectionInput.SetValue(self.inmap)
self.selectionInput.Disable()
- def _doLayout(self):
- """!Do main layout"""
- sizer = wx.BoxSizer(wx.VERTICAL)
- #
- # map selection
- #
- mapSelection = self._createMapSelection(parent = self)
- sizer.Add(item = mapSelection, proportion = 0,
- flag = wx.ALL | wx.EXPAND, border = 5)
- #
- # set vector attributes
- #
- vectorAttrb = self._createVectorAttrb(parent = self)
- sizer.Add(item = vectorAttrb, proportion = 0,
- flag = wx.ALL | wx.EXPAND, border = 5)
- #
- # body & preview
- #
- bodySizer = self._createBody(parent = self)
- sizer.Add(item = bodySizer, proportion = 1,
- flag = wx.ALL | wx.EXPAND, border = 5)
- #
- # buttons
- #
- btnSizer = self._createButtons()
-
- sizer.Add(item = wx.StaticLine(parent = self, id = wx.ID_ANY,
- style = wx.LI_HORIZONTAL), proportion = 0,
- flag = wx.EXPAND | wx.ALL, border = 5)
-
- sizer.Add(item = btnSizer, proportion = 0,
- flag = wx.ALL | wx.ALIGN_RIGHT, border = 5)
-
- self.SetSizer(sizer)
- sizer.Layout()
- sizer.Fit(self)
- self.Layout()
-
- def _createBody(self, parent):
- """!Create dialog body consisting of rules and preview"""
- bodySizer = wx.GridBagSizer(hgap = 5, vgap = 5)
- row = 0
-
- # label with instructions - don't want it now
- self.cr_label = wx.StaticText(parent, id = wx.ID_ANY)
- self.cr_label.Hide()
-
- # color table
- self.colorRulesPanel = RulesPanel(parent = parent, mapType = self.type,
- columnType = 'color', properties = self.properties,
- panelWidth = 200)
- # size table
- self.sizeRulesPanel = RulesPanel(parent = parent, mapType = self.type,
- columnType = 'size', properties = self.properties,
- panelWidth = 200)
-
- bodySizer.Add(item = self.colorRulesPanel.label, pos = (row, 0), span = (1, 2))
- bodySizer.Add(item = self.sizeRulesPanel.label, pos = (row, 2), span = (1, 2))
- row += 1
-
- bodySizer.Add(item = self.colorRulesPanel.mainPanel, pos = (row, 0), span = (1, 2))
- # add two rules as default
- self.colorRulesPanel.AddRules(2)
- bodySizer.Add(item = self.sizeRulesPanel.mainPanel, pos = (row, 2), span = (1, 2))
- # add two rules as default
- self.sizeRulesPanel.AddRules(2)
-
- # preview window
- self._createPreview(parent = parent)
- bodySizer.Add(item = self.preview, pos = (row, 4),
- flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 10)
- bodySizer.AddGrowableRow(row)
- bodySizer.AddGrowableCol(4)
- row += 1
-
- # add rules button and spin to sizer
- bodySizer.Add(item = self.colorRulesPanel.numRules, pos = (row, 0),
- flag = wx.ALIGN_CENTER_VERTICAL)
- bodySizer.Add(item = self.colorRulesPanel.btnAdd, pos = (row, 1))
- bodySizer.Add(item = self.sizeRulesPanel.numRules, pos = (row, 2),
- flag = wx.ALIGN_CENTER_VERTICAL)
- bodySizer.Add(item = self.sizeRulesPanel.btnAdd, pos = (row, 3),
- flag = wx.ALIGN_LEFT)
-
- # preview button
- self.btnPreview = wx.Button(parent, id = wx.ID_ANY,
- label = _("Preview"))
- bodySizer.Add(item = self.btnPreview, pos = (row, 4),
- flag = wx.ALIGN_RIGHT)
- self.btnPreview.Enable(False)
- self.btnPreview.SetToolTipString(_("Show preview of map "
- "(current Map Display extent is used)."))
-
- return bodySizer
-
- def _createVectorAttrb(self, parent):
- """!Create part of dialog with layer/column selection"""
- inputBox = wx.StaticBox(parent = parent, id = wx.ID_ANY,
- label = " %s " % _("Select vector columns"))
- layer_label = wx.StaticText(parent, id = wx.ID_ANY, label = _('Layer:'))
- self.rgb_check = wx.CheckBox(parent, id = wx.ID_ANY, label = _('Use color for thematic mapping:'))
- if self.vectorType == 'points':
- label = _('Use symbol size for thematic mapping:')
- else:
- label = _('Use line width for thematic mapping:')
- self.size_check = wx.CheckBox(parent, id = wx.ID_ANY, label = label)
-
- self.rgb_check.SetValue(True)
- self.size_check.SetValue(True)
-
- color_att_label = wx.StaticText(parent, id = wx.ID_ANY,
- label = _('Attribute column:'))
- size_att_label = wx.StaticText(parent, id = wx.ID_ANY,
- label = _('Attribute column:'))
- rgb_col_label = wx.StaticText(parent, id = wx.ID_ANY,
- label = _('RGB color column:'))
- if self.vectorType == 'points':
- label = _('Symbol size column:')
- else:
- label = _('Line with column:')
- size_col_label = wx.StaticText(parent, id = wx.ID_ANY, label = label)
-
- self.rgb_range_label = wx.StaticText(parent, id = wx.ID_ANY)
- self.size_range_label = wx.StaticText(parent, id = wx.ID_ANY)
- cb_size = (150, -1)
- self.cb_vlayer = gselect.LayerSelect(parent, size = cb_size)
- self.cb_color_att = gselect.ColumnSelect(parent, size = cb_size)
- self.cb_size_att = gselect.ColumnSelect(parent, size = cb_size)
- self.cb_rgb_col = gselect.ColumnSelect(parent, size = cb_size)
- self.cb_size_col = gselect.ColumnSelect(parent, size = cb_size)
- self.btn_add_RGB = wx.Button(parent, id = wx.ID_ANY,
- label = _('Add column'))
- self.btn_add_size = wx.Button(parent, id = wx.ID_ANY,
- label = _('Add column'))
- self.btn_add_RGB.SetToolTipString(_("Add GRASSRGB column to current attribute table."))
-
- if self.vectorType == 'points':
- label = _("Add size column to current attribute table.")
- else:
- label = _("Add width column to current attribute table.")
- self.btn_add_size.SetToolTipString(label)
-
- # layout
- inputSizer = wx.StaticBoxSizer(inputBox, wx.VERTICAL)
- vSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
- vSizer.AddGrowableCol(2)
-
- vSizer.Add(layer_label, pos = (0, 0),
- flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(self.cb_vlayer, pos = (0, 1),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- vSizer.Add(self.rgb_check, pos = (1, 0), span = (1, 3),
- flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(self.size_check, pos = (1, 3), span = (1, 3),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- vSizer.Add(color_att_label, pos = (2, 0),
- flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(size_att_label, pos = (2, 3),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- vSizer.Add(rgb_col_label, pos = (4, 0),
- flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(size_col_label, pos = (4, 3),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- vSizer.Add(self.cb_color_att, pos = (2, 1),
- flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(self.cb_size_att, pos = (2, 4),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- vSizer.Add(self.rgb_range_label, pos = (3, 1),
- flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(self.size_range_label, pos = (3, 4),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- vSizer.Add(self.cb_rgb_col, pos = (4, 1),
- flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(self.cb_size_col, pos = (4, 4),
- flag = wx.ALIGN_CENTER_VERTICAL)
-
- vSizer.Add(self.btn_add_RGB, pos = (4, 2),
- flag = wx.ALIGN_CENTER_VERTICAL)
- vSizer.Add(self.btn_add_size, pos = (4, 5),
- flag = wx.ALIGN_CENTER_VERTICAL)
- inputSizer.Add(item = vSizer,
- flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND, border = 5)
-
- return inputSizer
-
- def OnAddSizeColumn(self, event):
- """!Add size column if it doesn't exist"""
- if self.vectorType == 'points':
- name = 'GRASSSIZE'
- else:
- name = 'GRASSWIDTH'
-
- ret = gcmd.RunCommand('v.db.addcolumn',
- map = self.inmap,
- layer = self.properties['layer'],
- columns = '%s integer' % name)
- self.cb_size_col.InsertColumns(self.inmap, self.properties['layer'], type = ["integer"])
- self.cb_size_col.SetStringSelection(name)
- self.properties['size'] = name
-
- self.LoadTable(attColumn = self.properties['source_size'], rgbColumn = self.properties['size'],
- rulesPanel = self.sizeRulesPanel, type = 'size')
-
- def OnColorChecked(self, event):
- """!Use color for thematic mapping"""
- if self.rgb_check.IsChecked():
- self.colorRulesPanel.Enable(True)
- else:
- self.colorRulesPanel.Enable(False)
-
- def OnSizeChecked(self, event):
- """!Use size for thematic mapping"""
- if self.size_check.IsChecked():
- self.sizeRulesPanel.Enable(True)
- else:
- self.sizeRulesPanel.Enable(False)
-
- def OnPreview(self, event = None):
- """!Update preview (based on computational region)"""
- if not self.inmap:
- self.preview.EraseMap()
- return
-
- cmdlist = ['d.vect',
- '-a',
- 'map=%s' % self.inmap,
- 'type=point,line,boundary,area']
-
- if self.size_check.IsChecked() and self.properties["size"]:
- if self.vectorType == 'points':
- cmdlist.append('size_column=%s' % self.properties["size"])
- else:
- cmdlist.append('width_column=%s' % self.properties["size"])
-
- if self.rgb_check.IsChecked() and self.properties["rgb"]:
- cmdlist.append('rgb_column=%s' % self.properties["rgb"])
- ltype = 'vector'
- ColorTable.DoPreview(self, ltype, cmdlist)
-
def OnApply(self, event):
"""!Apply selected color table
@return True on success otherwise False
"""
- ret = VectorColorTable.CreateColorTable(self)
+
+ ret = self.CreateColorTable()
if not ret:
- gcmd.GMessage(parent = self, message = _("No color rules given."))
- ret = self.CreateSizeTable()
- if not ret:
- gcmd.GMessage(parent = self, message = _("No size rules given."))
+ gcmd.GMessage(parent = self, message = _("No rules given."))
data = self.parent.GetLayerData(nvizType = 'vector')
data['vector']['points']['thematic']['layer'] = int(self.properties['layer'])
- if self.size_check.IsChecked() and self.properties['size']:
- data['vector'][self.vectorType]['thematic']['sizecolumn'] = self.properties['size']
- else:
- data['vector'][self.vectorType]['thematic']['sizecolumn'] = None
+ value = None
+ if self.properties['storeColumn']:
+ value = self.properties['storeColumn']
- if self.rgb_check.IsChecked() and self.properties['rgb']:
- data['vector'][self.vectorType]['thematic']['rgbcolumn'] = self.properties['rgb']
+ if not self.colorTable:
+ if self.attributeType == 'color':
+ data['vector'][self.vectorType]['thematic']['rgbcolumn'] = value
+ else:
+ data['vector'][self.vectorType]['thematic']['sizecolumn'] = value
else:
- data['vector'][self.vectorType]['thematic']['rgbcolumn'] = None
+ if self.attributeType == 'color':
+ data['vector'][self.vectorType]['thematic']['rgbcolumn'] = None
+ else:
+ data['vector'][self.vectorType]['thematic']['sizecolumn'] = None
data['vector'][self.vectorType]['thematic']['update'] = None
@@ -1608,39 +1644,7 @@
self.parent.mapWindow.Refresh(False)
return ret
-
- def CreateSizeTable(self, force = False):
- """!Creates size table
-
- @return True on success
- @return False on failure
- """
- VectorColorTable.CreateColorTable(self)
- rulestxt = ''
-
- for rule in self.sizeRulesPanel.ruleslines.itervalues():
- if not rule['value']: # skip empty rules
- continue
-
- rulestxt += "UPDATE %s SET %s='%s' WHERE %s ;\n" % (self.properties['table'],
- self.properties['size'],
- rule['size'],
- rule['value'])
- if not rulestxt:
- return False
-
- gtemp = utils.GetTempfile()
- output = open(gtemp, "w")
- try:
- output.write(rulestxt)
- finally:
- output.close()
-
- gcmd.RunCommand('db.execute',
- parent = self,
- input = gtemp)
- return True
-
+
class BufferedWindow(wx.Window):
"""!A Buffered window class"""
def __init__(self, parent, id,
Property changes on: grass/branches/develbranch_6/gui/wxpython/gui_modules/colorrules.py
___________________________________________________________________
Added: svn:mergeinfo
+ /grass/trunk/gui/wxpython/gui_modules/colorrules.py:47121,47227,47283,47740-47742,47760-47762
Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py 2011-08-18 21:28:20 UTC (rev 47762)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py 2011-08-18 21:34:34 UTC (rev 47763)
@@ -786,12 +786,13 @@
if vector:
self.InsertColumns(vector, layer)
- def InsertColumns(self, vector, layer, excludeKey = False, type = None, dbInfo = None):
+ def InsertColumns(self, vector, layer, excludeKey = False, excludeCols = None, type = None, dbInfo = None):
"""!Insert columns for a vector attribute table into the columns combobox
@param vector vector name
@param layer vector layer number
@param excludeKey exclude key column from the list?
+ @param excludeCols list of columns to be removed from the list
@param type only columns of given type (given as list)
"""
if not dbInfo:
@@ -806,13 +807,20 @@
columns[val['index']] = key
if excludeKey: # exclude key column
columns.remove(keyColumn)
+ if excludeCols: # exclude key column
+ for key in columnchoices.iterkeys():
+ if key in excludeCols:
+ columns.remove(key)
if type: # only selected column types
for key, value in columnchoices.iteritems():
if value['type'] not in type:
- columns.remove(key)
+ try:
+ columns.remove(key)
+ except ValueError:
+ pass
except (KeyError, ValueError):
columns = list()
-
+
self.SetItems(columns)
self.SetValue(self.defaultValue)
Property changes on: grass/branches/develbranch_6/gui/wxpython/gui_modules/gselect.py
___________________________________________________________________
Added: svn:mergeinfo
+ /grass/trunk/gui/wxpython/gui_modules/gselect.py:47121,47227,47283,47714
Modified: grass/branches/develbranch_6/gui/wxpython/wxgui.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/wxgui.py 2011-08-18 21:28:20 UTC (rev 47762)
+++ grass/branches/develbranch_6/gui/wxpython/wxgui.py 2011-08-18 21:34:34 UTC (rev 47763)
@@ -1012,7 +1012,7 @@
if cmd[0] == 'r.colors':
ctable = colorrules.RasterColorTable(self)
else:
- ctable = colorrules.VectorColorTable(self)
+ ctable = colorrules.VectorColorTable(self, attributeType = 'color')
ctable.CentreOnScreen()
ctable.Show()
Property changes on: grass/branches/develbranch_6/gui/wxpython/wxgui.py
___________________________________________________________________
Added: svn:mergeinfo
+ /grass/trunk/gui/wxpython/wxgui.py:47121,47227,47283,47714
More information about the grass-commit
mailing list