[GRASS-SVN] r44122 - grass/trunk/gui/wxpython/gui_modules
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Oct 31 06:03:08 EDT 2010
Author: martinl
Date: 2010-10-31 03:03:08 -0700 (Sun, 31 Oct 2010)
New Revision: 44122
Modified:
grass/trunk/gui/wxpython/gui_modules/colorrules.py
Log:
wxGUI/colorrules: load/save raster color tables (based on patch by Anna Kratochvilova)
minor clean up
Modified: grass/trunk/gui/wxpython/gui_modules/colorrules.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/colorrules.py 2010-10-31 09:00:13 UTC (rev 44121)
+++ grass/trunk/gui/wxpython/gui_modules/colorrules.py 2010-10-31 10:03:08 UTC (rev 44122)
@@ -2,7 +2,7 @@
@package colorrules.py
@brief Dialog for interactive management of raster color tables and
-vector rgb_column
+vector rgb_column attributes.
Classes:
- ColorTable
@@ -14,6 +14,7 @@
@author Michael Barton (Arizona State University)
@author Martin Landa <landa.martin gmail.com> (various updates)
+ at author Anna Kratochvilova (load/save raster color tables)
"""
import os
@@ -36,16 +37,16 @@
from preferences import globalSettings as UserSettings
class ColorTable(wx.Frame):
- def __init__(self, parent, cmd, id=wx.ID_ANY, title = _("Set color table"),
+ def __init__(self, parent, raster, id=wx.ID_ANY, title = _("Set color table"),
style=wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER,
**kwargs):
"""!Dialog for interactively entering rules for map management
commands
- @param cmd command (given as list)
+ @param raster True to raster otherwise vector
"""
self.parent = parent # GMFrame
- self.cmd = cmd
+ self.raster = raster
wx.Frame.__init__(self, parent, id, title, style = style, **kwargs)
@@ -53,31 +54,32 @@
# input map to change
self.inmap = ''
-
- # raster properties
- self.rast = {
- # min cat in raster map
- 'min' : None,
- # max cat in raster map
- 'max' : None,
- }
-
- # vector properties
- self.vect = {
- # list of database layers for vector (minimum of 1)
- 'layers' : ['1'],
- # 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
- 'column' : '',
- # vector attribute column to use for storing colors
- 'rgb' : '',
- }
+ if self.raster:
+ # raster properties
+ self.properties = {
+ # min cat in raster map
+ 'min' : None,
+ # max cat in raster map
+ 'max' : None,
+ }
+ else:
+ # vector properties
+ self.properties = {
+ # list of database layers for vector (minimum of 1)
+ 'layers' : ['1'],
+ # 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
+ 'column' : '',
+ # vector attribute column to use for storing colors
+ 'rgb' : '',
+ }
+
# rules for creating colortable
self.ruleslines = {}
@@ -87,33 +89,38 @@
# reference to layer with preview
self.layer = None
- if self.cmd == 'r.colors':
+ if self.raster:
self.SetTitle(_('Create new color table for raster map'))
- self.elem = 'cell'
- crlabel = _('Enter raster cat values or percents')
- elif self.cmd == 'vcolors':
+ crlabel = _('Enter raster category values or percents')
+ else:
self.SetTitle(_('Create new color table for vector map'))
- self.elem = 'vector'
crlabel = _('Enter vector attribute values or ranges (n or n1 to n2)')
# top controls
- if self.cmd == 'r.colors':
+ if self.raster:
maplabel = _('Select raster map:')
- elif self.cmd == 'vcolors':
+ else:
maplabel = _('Select vector map:')
inputBox = wx.StaticBox(parent=self, id=wx.ID_ANY,
label=" %s " % maplabel)
self.inputSizer = wx.StaticBoxSizer(inputBox, wx.VERTICAL)
+ if self.raster:
+ elem = 'cell'
+ else:
+ elem = 'vector'
self.selectionInput = gselect.Select(parent=self, id=wx.ID_ANY,
size=globalvar.DIALOG_GSELECT_SIZE,
- type=self.elem)
+ type=elem)
self.ovrwrtcheck = wx.CheckBox(parent=self, id=wx.ID_ANY,
label=_('replace existing color table'))
self.ovrwrtcheck.SetValue(UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'))
- self.helpbtn = wx.Button(parent=self, id=wx.ID_HELP)
-
- if self.elem == 'vector':
+
+ if self.raster:
+ self.btnSave = wx.Button(parent=self, id=wx.ID_SAVE)
+ self.btnSave.SetToolTipString(_('Save color table to file'))
+
+ if not self.raster:
self.cb_vl_label = wx.StaticText(parent=self, id=wx.ID_ANY,
label=_('Layer:'))
self.cb_vc_label = wx.StaticText(parent=self, id=wx.ID_ANY,
@@ -146,11 +153,13 @@
self.btnOK.SetDefault()
self.btnOK.Enable(False)
self.btnApply.Enable(False)
-
+
self.btnPreview = wx.Button(parent=self, id=wx.ID_ANY,
label=_("Preview"))
self.btnPreview.Enable(False)
self.btnAdd = wx.Button(parent=self, id=wx.ID_ADD)
+ self.helpbtn = wx.Button(parent=self, id=wx.ID_HELP)
+
# bindings
self.Bind(wx.EVT_BUTTON, self.OnHelp, self.helpbtn)
@@ -161,9 +170,11 @@
self.Bind(wx.EVT_BUTTON, self.OnPreview, self.btnPreview)
self.Bind(wx.EVT_BUTTON, self.OnAddRules, self.btnAdd)
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
-
- # additional bindings for vector color management
- if self.cmd == 'vcolors':
+
+ # additional bindings for raster/vector color management
+ if self.raster:
+ self.Bind(wx.EVT_BUTTON, self.OnSaveTable, self.btnSave)
+ else:
self.Bind(wx.EVT_COMBOBOX, self.OnLayerSelection, self.cb_vlayer)
self.Bind(wx.EVT_COMBOBOX, self.OnColumnSelection, self.cb_vcol)
self.Bind(wx.EVT_COMBOBOX, self.OnRGBColSelection, self.cb_vrgb)
@@ -177,11 +188,9 @@
mapLayer = self.parent.curr_page.maptree.GetPyData(layer)[0]['maplayer']
name = mapLayer.GetName()
type = mapLayer.GetType()
- if (type == 'raster' and self.elem == 'cell') or \
- (type == 'vector' and self.elem == 'vector'):
- self.selectionInput.SetValue(name)
- self.inmap = name
- self.OnSelectionInput(None)
+ self.selectionInput.SetValue(name)
+ self.inmap = name
+ self.OnSelectionInput(None)
# layout
self.__doLayout()
@@ -200,12 +209,13 @@
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.EXPAND, border=1)
- replaceSizer.Add(item=self.helpbtn, proportion=0,
- flag=wx.ALIGN_RIGHT | wx.ALL, border=1)
-
+ flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=1)
+ if self.raster:
+ replaceSizer.Add(item=self.btnSave, proportion=0,
+ flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
+
self.inputSizer.Add(item=replaceSizer, proportion=1,
- flag=wx.ALL | wx.EXPAND, border=1)
+ flag=wx.ALL | wx.EXPAND, border=0)
#
# body & preview
@@ -214,8 +224,8 @@
row = 0
bodySizer.Add(item=self.cr_label, pos=(row, 0), span=(1, 3),
flag=wx.ALL, border=5)
-
- if self.cmd == 'vcolors':
+
+ if not self.raster:
vSizer = wx.GridBagSizer(hgap=5, vgap=5)
vSizer.Add(self.cb_vl_label, pos=(0, 0),
flag=wx.ALIGN_CENTER_VERTICAL)
@@ -249,6 +259,8 @@
flag=wx.ALIGN_RIGHT)
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
+ btnSizer.Add(self.helpbtn,
+ flag=wx.LEFT | wx.RIGHT, border=5)
btnSizer.Add(self.btnCancel,
flag=wx.LEFT | wx.RIGHT, border=5)
btnSizer.Add(self.btnApply,
@@ -340,47 +352,50 @@
self.Destroy()
def OnSelectionInput(self, event):
+ """!Raster/vector map selected"""
if event:
self.inmap = event.GetString()
- if self.inmap == '':
+ if not self.inmap:
self.btnPreview.Enable(False)
self.btnOK.Enable(False)
self.btnApply.Enable(False)
return
- if self.elem == 'cell':
+ if self.raster:
info = gcmd.RunCommand('r.info',
parent = self,
read = True,
flags = 'r',
map = self.inmap)
-
+
if info:
for line in info.splitlines():
if 'min' in line:
- self.rast['min'] = float(line.split('=')[1])
+ self.properties['min'] = float(line.split('=')[1])
elif 'max' in line:
- self.rast['max'] = float(line.split('=')[1])
+ self.properties['max'] = float(line.split('=')[1])
+ self.OnLoadTable(event)
else:
self.inmap = ''
- self.rast['min'] = self.rast['max'] = None
+ self.properties['min'] = self.properties['max'] = None
self.btnPreview.Enable(False)
self.btnOK.Enable(False)
self.btnApply.Enable(False)
self.preview.EraseMap()
- self.cr_label.SetLabel(_('Enter raster cat values or percents'))
+ self.cr_label.SetLabel(_('Enter raster category values or percents'))
return
- self.cr_label.SetLabel(_('Enter raster cat values or percents (range = %(min)d-%(max)d)') %
- { 'min' : self.rast['min'],
- 'max' : self.rast['max'] })
- elif self.elem == 'vector':
+ self.cr_label.SetLabel(_('Enter raster category values or percents (range = %(min)d-%(max)d)') %
+ { 'min' : self.properties['min'],
+ 'max' : self.properties['max'] })
+
+ else:
# initialize layer selection combobox
self.cb_vlayer.InsertLayers(self.inmap)
# initialize attribute table for layer=1
- layer = int(self.vect['layer'])
- self.vect['table'] = gselect.VectorDBInfo(self.inmap).layers[layer]['table']
+ layer = int(self.properties['layer'])
+ self.properties['table'] = gselect.VectorDBInfo(self.inmap).layers[layer]['table']
# initialize column selection comboboxes
self.cb_vcol.InsertColumns(vector=self.inmap, layer=layer)
self.cb_vrgb.InsertColumns(vector=self.inmap, layer=layer)
@@ -399,10 +414,10 @@
self.Update()
def OnColumnSelection(self, event):
- self.vect['column'] = event.GetString()
+ self.properties['column'] = event.GetString()
def OnRGBColSelection(self, event):
- self.vect['rgb'] = event.GetString()
+ self.properties['rgb'] = event.GetString()
def OnRuleEnable(self, event):
"""!Rule enabled/disabled"""
@@ -431,8 +446,7 @@
tc = self.FindWindowById(num)
- if self.elem == 'cell':
-
+ if self.raster:
try:
if vals != '-' and \
vals[-1] != '%':
@@ -444,8 +458,8 @@
self.ruleslines[num-1000]['value'] = vals
- elif self.elem == 'vector':
- if self.vect['column'] == '' or self.vect['rgb'] == '':
+ else:
+ if self.properties['column'] == '' or self.properties['rgb'] == '':
tc.SetValue('')
wx.MessageBox(parent=self,
message=_("Please select attribute column "
@@ -475,32 +489,94 @@
valslist = []
valslist = vals.split('to')
if len(valslist) == 1:
- sqlrule = '%s=%s' % (self.vect['column'], valslist[0])
+ sqlrule = '%s=%s' % (self.properties['column'], valslist[0])
elif len(valslist) > 1:
- sqlrule = '%s>=%s AND %s<=%s' % (self.vect['column'], valslist[0],
- self.vect['column'], valslist[1])
+ sqlrule = '%s>=%s AND %s<=%s' % (self.properties['column'], valslist[0],
+ self.properties['column'], valslist[1])
else:
return None
return sqlrule
+ def OnLoadTable(self, event):
+ """!Load current color table (using `r.colors -p`)"""
+ ctable = gcmd.RunCommand('r.colors',
+ parent = self,
+ read = True,
+ flags = 'p',
+ map = self.inmap)
+ self.ruleslines.clear()
+ self.cr_panel.DestroyChildren()
+ rulesNumber = len(ctable.splitlines())
+ self.AddRules(rulesNumber)
+
+ count = 0
+ for line in ctable.splitlines()[1:]:
+ item = line.split()
+ for part in range(0, 2):
+ itemSplit = item[part].split(':', 1)
+ self.ruleslines[count]['value'] = itemSplit[0]
+ if ':' not in itemSplit[1]:
+ itemSplit[1] += (':' + itemSplit[1]) * 2
+ self.ruleslines[count]['color'] = itemSplit[1]
+ self.FindWindowById(count + 1000).SetValue(itemSplit[0])
+ rgb = list()
+ for color in itemSplit[1].split(':'):
+ rgb.append(int(color))
+ self.FindWindowById(count + 2000).SetColour(rgb)
+ count += 1
+ if count < rulesNumber - 1:
+ break
+
+ self.OnPreview(tmp = False)
+
+ 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 OnApply(self, event):
- self.CreateColorTable()
+ """!Apply selected color table
+
+ @return True on success otherwise False
+ """
+ ret = self.CreateColorTable()
display = self.parent.GetLayerTree().GetMapDisplay()
- if display:
+ if display and display.IsAutoRendered():
display.GetWindow().UpdateMap(render = True)
+ return ret
+
def OnOK(self, event):
- self.OnApply(event)
- self.Destroy()
+ """!Apply selected color table and close the dialog"""
+ if self.OnApply(event):
+ self.Destroy()
def OnCancel(self, event):
+ """!Do not apply any changes and close the dialog"""
self.Destroy()
- def OnPreview(self, event):
- """!Update preview"""
+ def OnPreview(self, event = None, tmp = True):
+ """!Update preview (based on computational region)"""
# raster
- if self.elem == 'cell':
+ if self.raster:
cmdlist = ['d.rast',
'map=%s' % self.inmap]
ltype = 'raster'
@@ -516,15 +592,13 @@
colrtemp = utils.GetTempfile()
shutil.copyfile(old_colrtable, colrtemp)
# vector
- elif self.elem == 'vector':
+ else:
cmdlist = ['d.vect',
'-a',
'map=%s' % self.inmap,
- 'rgb_column=%s' % self.vect["rgb"],
+ 'rgb_column=%s' % self.properties["rgb"],
'type=point,line,boundary,area']
ltype = 'vector'
- else:
- return
if not self.layer:
self.layer = self.Map.AddLayer(type=ltype, name='preview', command=cmdlist,
@@ -534,11 +608,11 @@
self.layer.SetCmd(cmdlist)
# apply new color table and display preview
- self.CreateColorTable(force=True)
+ self.CreateColorTable(force = True)
self.preview.UpdatePreview()
# restore previous color table
- if self.elem == 'cell':
+ if self.raster and tmp:
if old_colrtable:
shutil.copyfile(colrtemp, old_colrtable)
os.remove(colrtemp)
@@ -550,28 +624,36 @@
def OnHelp(self, event):
"""!Show GRASS manual page"""
+ if self.raster:
+ cmd = 'r.colors'
+ else:
+ cmd = 'vcolors'
gcmd.RunCommand('g.manual',
quiet = True,
parent = self,
- entry = self.cmd)
+ entry = cmd)
- def CreateColorTable(self, force=False):
- """!Creates color table"""
+ def CreateColorTable(self, force = False):
+ """!Creates color table
+
+ @return True on success
+ @return False on failure
+ """
rulestxt = ''
for rule in self.ruleslines.itervalues():
if not rule['value']: # skip empty rules
continue
- if self.elem == 'cell':
+ if self.raster:
rulestxt += rule['value'] + ' ' + rule['color'] + '\n'
- elif self.elem == 'vector':
- rulestxt += "UPDATE %s SET %s='%s' WHERE %s ;\n" % (self.vect['table'],
- self.vect['rgb'],
+ else:
+ rulestxt += "UPDATE %s SET %s='%s' WHERE %s ;\n" % (self.properties['table'],
+ self.properties['rgb'],
rule['color'],
rule['value'])
- if rulestxt == '':
- return
+ if not rulestxt:
+ return False
gtemp = utils.GetTempfile()
output = open(gtemp, "w")
@@ -580,24 +662,31 @@
finally:
output.close()
- if self.elem == 'cell':
+ if self.raster:
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
- gcmd.RunCommand('r.colors',
- parent = self,
- flags = flags,
- map = self.inmap,
- rules = gtemp)
-
- elif self.elem == 'vector':
+ else:
gcmd.RunCommand('db.execute',
parent = self,
input = gtemp)
+ return True
+
class BufferedWindow(wx.Window):
"""!A Buffered window class"""
def __init__(self, parent, id,
More information about the grass-commit
mailing list