[GRASS-SVN] r48403 - grass/trunk/gui/wxpython/gui_modules
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Sep 22 01:19:24 EDT 2011
Author: cmbarton
Date: 2011-09-21 22:19:24 -0700 (Wed, 21 Sep 2011)
New Revision: 48403
Added:
grass/trunk/gui/wxpython/gui_modules/histogram2.py
Modified:
grass/trunk/gui/wxpython/gui_modules/mapdisp.py
grass/trunk/gui/wxpython/gui_modules/preferences.py
grass/trunk/gui/wxpython/gui_modules/toolbars.py
Log:
wxGUI: new histogramming tool based on PyPlot. Histograms single maps and imagery groups, with control over line colors and styles, axes and other plot features.
Added: grass/trunk/gui/wxpython/gui_modules/histogram2.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/histogram2.py (rev 0)
+++ grass/trunk/gui/wxpython/gui_modules/histogram2.py 2011-09-22 05:19:24 UTC (rev 48403)
@@ -0,0 +1,1388 @@
+"""!
+ at package histogram2.py
+
+Raster histogramming using PyPlot (wx.lib.plot.py); replacement for d.hist
+
+Classes:
+ - HistFrame
+ - SetRasterDialog
+ - TextDialog
+ - OptDialog
+
+(C) 2011 by the GRASS Development Team
+
+This program is free software under the GNU General Public License
+(>=v2). Read the file COPYING that comes with GRASS for details.
+
+ at author Michael Barton, Arizona State University
+"""
+
+import os
+import sys
+import math
+import random
+
+import wx
+import wx.lib.colourselect as csel
+
+import os
+import sys
+
+import wx
+
+import render
+import menuform
+import disp_print
+import utils
+import gdialogs
+import globalvar
+import gselect
+import gcmd
+import toolbars
+from preferences import DefaultFontDialog
+from debug import Debug as Debug
+from icon import Icons as Icons
+from gcmd import GError
+from preferences import globalSettings as UserSettings
+
+from grass.script import core as grass
+from grass.script import raster as raster
+
+try:
+ import numpy
+ import wx.lib.plot as plot
+except ImportError:
+ msg= _("This module requires the NumPy module, which could not be "
+ "imported. It probably is not installed (it's not part of the "
+ "standard Python distribution). See the Numeric Python site "
+ "(http://numpy.scipy.org) for information on downloading source or "
+ "binaries.")
+ print >> sys.stderr, "profile.py: " + msg
+
+class HistFrame(wx.Frame):
+ """!Mainframe for displaying profile of raster map. Uses wx.lib.plot.
+ """
+ def __init__(self, parent=None, id=wx.ID_ANY, title=_("GRASS Histogramming Tool"),
+ rasterList=[],
+ pos=wx.DefaultPosition, size=wx.DefaultSize,
+ style=wx.DEFAULT_FRAME_STYLE):
+
+ self.parent = parent # MapFrame
+ self.mapwin = self.parent.MapWindow
+ self.Map = render.Map() # instance of render.Map to be associated with display
+ self.rasterList = rasterList #list of rasters to histogram; could come from layer manager
+
+ self.pstyledict = { 'solid' : wx.SOLID,
+ 'dot' : wx.DOT,
+ 'long-dash' : wx.LONG_DASH,
+ 'short-dash' : wx.SHORT_DASH,
+ 'dot-dash' : wx.DOT_DASH }
+
+ self.ptfilldict = { 'transparent' : wx.TRANSPARENT,
+ 'solid' : wx.SOLID }
+
+ wx.Frame.__init__(self, parent, id, title, pos, size, style)
+
+ #
+ # Icon
+ #
+ self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
+
+ #
+ # Add toolbar
+ #
+ self.toolbar = toolbars.Histogram2Toolbar(parent=self)
+ self.SetToolBar(self.toolbar)
+
+ #
+ # Set the size & cursor
+ #
+ self.SetClientSize(size)
+
+ #
+ # Add statusbar
+ #
+ self.statusbar = self.CreateStatusBar(number=2, style=0)
+ self.statusbar.SetStatusWidths([-2, -1])
+
+ #
+ # Define canvas
+ #
+ self.client = plot.PlotCanvas(self) # plot canvas settings
+
+ # Create mouse event for showing cursor coords in status bar
+ self.client.canvas.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
+
+ # Show closest point when enabled
+ self.client.canvas.Bind(wx.EVT_MOTION, self.OnMotion)
+
+ #
+ # Init variables
+ #
+ self.group = ''
+
+ self.raster = {}
+
+ if len(self.rasterList) > 0: # set 1 raster name from layer manager if a map is selected
+ self.raster[self.rasterList[0]] = UserSettings.Get(group='histogram', key='raster') # some default settings
+ self.raster[self.rasterList[0]]['units'] = ''
+ self.raster[self.rasterList[0]]['plegend'] = ''
+ self.raster[self.rasterList[0]]['datalist'] = [] # list of cell value,frequency pairs for plotting histogram
+ self.raster[self.rasterList[0]]['pline'] = None
+ colstr = str(self.raster[self.rasterList[0]]['pcolor']) # changing color string to tuple
+ self.raster[self.rasterList[0]]['pcolor'] = tuple(int(colval) for colval in colstr.strip('()').split(','))
+
+ self.plotlist = [] # list of things to plot
+ self.histogram = None # plot draw object
+ self.ptitle = _('Histogram of') # title of window
+ self.xlabel = _("Raster cell values") # default X-axis label
+ self.ylabel = _("Cell counts") # default Y-axis label
+ self.maptype = 'raster' # default type of histogram to plot
+
+ self.properties = {} # plot properties
+
+ self.properties['font'] = {}
+ self.properties['font']['prop'] = UserSettings.Get(group='histogram', key='font')
+ self.properties['font']['wxfont'] = wx.Font(11, wx.FONTFAMILY_SWISS,
+ wx.FONTSTYLE_NORMAL,
+ wx.FONTWEIGHT_NORMAL)
+
+ self.properties['grid'] = UserSettings.Get(group='histogram', key='grid')
+ colstr = str(self.properties['grid']['color']) # changing color string to tuple
+ self.properties['grid']['color'] = tuple(int(colval) for colval in colstr.strip('()').split(','))
+
+ self.properties['x-axis'] = {}
+ self.properties['x-axis']['prop'] = UserSettings.Get(group='histogram', key='x-axis')
+ self.properties['x-axis']['axis'] = None
+
+ self.properties['y-axis'] = {}
+ self.properties['y-axis']['prop'] = UserSettings.Get(group='histogram', key='y-axis')
+ self.properties['y-axis']['axis'] = None
+
+ self.properties['legend'] = UserSettings.Get(group='histogram', key='legend')
+
+ self.histtype = 'count'
+ self.bins = 255
+
+ self.zoom = False # zooming disabled
+ self.drag = False # draging disabled
+ self.client.SetShowScrollbars(True) # vertical and horizontal scrollbars
+
+ # x and y axis set to normal (non-log)
+ self.client.setLogScale((False, False))
+ if self.properties['x-axis']['prop']['type']:
+ self.client.SetXSpec(self.properties['x-axis']['prop']['type'])
+ else:
+ self.client.SetXSpec('auto')
+
+ if self.properties['y-axis']['prop']['type']:
+ self.client.SetYSpec(self.properties['y-axis']['prop']['type'])
+ else:
+ self.client.SetYSpec('auto')
+
+ #
+ # Bind various events
+ #
+ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+
+ self.CentreOnScreen()
+
+ self._createColorDict()
+
+ def _createColorDict(self):
+ """!Create color dictionary to return wx.Color tuples
+ for assigning colors to images in imagery groups"""
+
+ self.colorDict = {}
+ for clr in grass.named_colors.iterkeys():
+ if clr == 'white' or clr == 'black': continue
+ r = grass.named_colors[clr][0] * 255
+ g = grass.named_colors[clr][1] * 255
+ b = grass.named_colors[clr][2] * 255
+ self.colorDict[clr] = (r,g,b,255)
+
+ def OnSelectRaster(self, event):
+ """!Select raster map(s) to profile
+ """
+ dlg = SetRasterDialog(parent=self)
+
+ if dlg.ShowModal() == wx.ID_OK:
+ self.rasterList = dlg.rasterList
+ self.group = dlg.group
+ self.bins = dlg.bins
+ self.histtype = dlg.histtype
+ self.maptype = dlg.maptype
+
+ # plot profile
+ if len(self.rasterList) > 0:
+ self.OnCreateHist(event=None)
+
+ dlg.Destroy()
+
+ def OnCreateHist(self, event):
+ """!Main routine for creating a histogram. Uses r.stats to
+ create a list of cell value and count/percent/area pairs. This is passed to
+ plot to create a line graph of the histogram.
+ """
+
+ self.SetCursor(self.parent.cursors["default"])
+ self.SetGraphStyle()
+ self.SetRaster()
+ self.DrawPlot()
+
+ def SetGraphStyle(self):
+ """!Set plot and text options
+ """
+ self.client.SetFont(self.properties['font']['wxfont'])
+ self.client.SetFontSizeTitle(self.properties['font']['prop']['titleSize'])
+ self.client.SetFontSizeAxis(self.properties['font']['prop']['axisSize'])
+
+ self.client.SetEnableZoom(self.zoom)
+ self.client.SetEnableDrag(self.drag)
+
+ #
+ # axis settings
+ #
+ if self.properties['x-axis']['prop']['type'] == 'custom':
+ self.client.SetXSpec('min')
+ else:
+ self.client.SetXSpec(self.properties['x-axis']['prop']['type'])
+
+ if self.properties['y-axis']['prop']['type'] == 'custom':
+ self.client.SetYSpec('min')
+ else:
+ self.client.SetYSpec(self.properties['y-axis']['prop']['type'])
+
+ if self.properties['x-axis']['prop']['type'] == 'custom' and \
+ self.properties['x-axis']['prop']['min'] < self.properties['x-axis']['prop']['max']:
+ self.properties['x-axis']['axis'] = (self.properties['x-axis']['prop']['min'],
+ self.properties['x-axis']['prop']['max'])
+ else:
+ self.properties['x-axis']['axis'] = None
+
+ if self.properties['y-axis']['prop']['type'] == 'custom' and \
+ self.properties['y-axis']['prop']['min'] < self.properties['y-axis']['prop']['max']:
+ self.properties['y-axis']['axis'] = (self.properties['y-axis']['prop']['min'],
+ self.properties['y-axis']['prop']['max'])
+ else:
+ self.properties['y-axis']['axis'] = None
+
+ self.client.SetEnableGrid(self.properties['grid']['enabled'])
+
+ self.client.SetGridColour(wx.Color(self.properties['grid']['color'][0],
+ self.properties['grid']['color'][1],
+ self.properties['grid']['color'][2],
+ 255))
+
+ self.client.SetFontSizeLegend(self.properties['font']['prop']['legendSize'])
+ self.client.SetEnableLegend(self.properties['legend']['enabled'])
+
+ if self.properties['x-axis']['prop']['log'] == True:
+ self.properties['x-axis']['axis'] = None
+ self.client.SetXSpec('min')
+ if self.properties['y-axis']['prop']['log'] == True:
+ self.properties['y-axis']['axis'] = None
+ self.client.SetYSpec('min')
+
+ self.client.setLogScale((self.properties['x-axis']['prop']['log'],
+ self.properties['y-axis']['prop']['log']))
+
+ def SetRaster(self):
+ """!Build data list for ploting each raster."""
+
+ #
+ # populate raster dictionary
+ #
+ if len(self.rasterList) == 0: return # nothing selected
+
+ colorList = []
+ for clr in ["blue", "green", "red", "yellow", "magenta", "cyan", \
+ "aqua", "grey", "orange", "brown", "purple", "violet", \
+ "indigo"]:
+ colorList.append(self.colorDict[clr])
+
+ if len(self.rasterList) > len(colorList):
+ # just in case the imagery group has many maps
+ diff = len(self.rasterList) - len(colorList)
+ for x in range(0, diff):
+ r = randint(0, 255)
+ b = randint(0, 255)
+ g = randint(0, 255)
+ colorList.append((r,g,b,255))
+
+ rastcolor = zip(self.rasterList, colorList)
+
+ for r,c in rastcolor:
+ if r in self.raster: continue # only reset values if rasters have changed
+ self.raster[r] = {}
+ try:
+ ret = raster.raster_info(r)
+ except:
+ continue
+ self.raster[r]['datatype'] = 'CELL'
+ self.raster[r]['datatype'] = ret['datatype']
+ self.raster[r]['units'] = ret['units']
+ self.raster[r]['plegend'] = r # raster name to use in legend
+ self.raster[r]['datalist'] = [] # list of cell value,frequency pairs for plotting histogram
+ self.raster[r]['pline'] = None
+ if 'pcolor' not in self.raster[r]:
+ self.raster[r]['pcolor'] = c
+ if 'pwidth' not in self.raster[r]:
+ self.raster[r]['pwidth'] = 1
+ if 'pstyle' not in self.raster[r]:
+ self.raster[r]['pstyle'] = 'solid'
+
+ self.ptitle = _('Histogram of') # reset window title
+
+ #
+ # create datalist for each raster map
+ #
+ for r in self.rasterList:
+ self.raster[r]['datalist'] = self.CreateDatalist(r)
+
+ #
+ # update title
+ #
+ if self.maptype == 'group':
+ self.ptitle = _('Histogram of %s') % self.group.split('@')[0]
+ else:
+ self.ptitle = _('Histogram of %s') % self.rasterList[0].split('@')[0]
+
+
+ #
+ # set xlabel based on first raster map in list to be histogrammed
+ #
+ units = self.raster[self.rasterList[0]]['units']
+ if units != '' and units != '(none)' and units != None:
+ self.xlabel = _('Raster cell values %s') % units
+ else:
+ self.xlabel = _('Raster cell values')
+
+ #
+ # set ylabel from self.histtype
+ #
+ if self.histtype == 'count': self.ylabel = _('Cell counts')
+ if self.histtype == 'percent': self.ylabel = _('Percent of total cells')
+ if self.histtype == 'area': self.ylabel = _('Area')
+
+ def CreateDatalist(self, raster):
+ """!Build a list of cell value, frequency pairs for histogram
+ frequency can be in cell counts, percents, or area
+ """
+ datalist = []
+
+ if self.histtype == 'count': freqflag = 'cn'
+ if self.histtype == 'percent': freqflag = 'pn'
+ if self.histtype == 'area': freqflag = 'an'
+
+ try:
+ ret = gcmd.RunCommand("r.stats",
+ input=raster,
+ flags=freqflag,
+ nsteps=self.bins,
+ fs=',',
+ quiet=True,
+ read = True)
+
+ if not ret:
+ return dataset
+
+ for line in ret.splitlines():
+ cellval, histval = line.strip().split(',')
+ histval = histval.strip()
+ if self.raster[raster]['datatype'] != 'CELL':
+ cellval = cellval.split('-')[0]
+ if self.histtype == 'percent':
+ histval = histval.rstrip('%')
+
+ datalist.append((cellval,histval))
+
+ return datalist
+ except gcmd.GException, e:
+ gcmd.GError(parent = self,
+ message = e.value)
+ return None
+
+ #### Maybe add a barplot routine to make an 'area' graph. Could make it slow down a lot
+ def DrawPlot(self):
+ """!Draw line and point plot from transect datalist and
+ transect segment endpoint coordinates.
+ """
+ # graph the cell value, frequency pairs for the histogram
+ self.plotlist = []
+
+ for r in self.rasterList:
+ if len(self.raster[r]['datalist']) > 0:
+ col = wx.Color(self.raster[r]['pcolor'][0],
+ self.raster[r]['pcolor'][1],
+ self.raster[r]['pcolor'][2],
+ 255)
+ self.raster[r]['pline'] = plot.PolyLine(self.raster[r]['datalist'],
+ colour=col,
+ width=self.raster[r]['pwidth'],
+ style=self.pstyledict[self.raster[r]['pstyle']],
+ legend=self.raster[r]['plegend'])
+
+ self.plotlist.append(self.raster[r]['pline'])
+
+ self.histogram = plot.PlotGraphics(self.plotlist,
+ self.ptitle,
+ self.xlabel,
+ self.ylabel)
+
+ if self.properties['x-axis']['prop']['type'] == 'custom':
+ self.client.SetXSpec('min')
+ else:
+ self.client.SetXSpec(self.properties['x-axis']['prop']['type'])
+
+ if self.properties['y-axis']['prop']['type'] == 'custom':
+ self.client.SetYSpec('min')
+ else:
+ self.client.SetYSpec(self.properties['y-axis']['prop']['type'])
+
+ self.client.Draw(self.histogram, self.properties['x-axis']['axis'],
+ self.properties['y-axis']['axis'])
+
+ def OnZoom(self, event):
+ """!Enable zooming and disable dragging
+ """
+ self.zoom = True
+ self.drag = False
+ self.client.SetEnableZoom(self.zoom)
+ self.client.SetEnableDrag(self.drag)
+
+ def OnDrag(self, event):
+ """!Enable dragging and disable zooming
+ """
+ self.zoom = False
+ self.drag = True
+ self.client.SetEnableDrag(self.drag)
+ self.client.SetEnableZoom(self.zoom)
+
+ def OnRedraw(self, event):
+ """!Redraw the hisogram window. Unzoom to original size
+ """
+ self.client.Reset()
+ self.client.Redraw()
+
+ def Update(self):
+ """!Update histogram after changing options
+ """
+ self.SetGraphStyle()
+ self.DrawPlot()
+
+ def OnErase(self, event):
+ """!Erase the histogram window
+ """
+ self.client.Clear()
+ self.mapwin.ClearLines(self.mapwin.pdc)
+ self.mapwin.ClearLines(self.mapwin.pdcTmp)
+ self.mapwin.polycoords = []
+ self.mapwin.Refresh()
+
+ def SaveToFile(self, event):
+ """!Save histogram to graphics file
+ """
+ self.client.SaveFile()
+
+ def OnMouseLeftDown(self,event):
+ s= "Left Mouse Down at Point: (%.4f, %.4f)" % self.client._getXY(event)
+ self.SetStatusText(s)
+ event.Skip() #allows plotCanvas OnMouseLeftDown to be called
+
+ def OnMotion(self, event):
+ # indicate when mouse is outside the plot area
+ if self.client.OnLeave(event): print 'out of area'
+ #show closest point (when enbled)
+ if self.client.GetEnablePointLabel() == True:
+ #make up dict with info for the pointLabel
+ #I've decided to mark the closest point on the closest curve
+ dlst= self.client.GetClosetPoint( self.client._getXY(event), pointScaled= True)
+ if dlst != []: #returns [] if none
+ curveNum, legend, pIndex, pointXY, scaledXY, distance = dlst
+ #make up dictionary to pass to my user function (see DrawPointLabel)
+ mDataDict= {"curveNum":curveNum, "legend":legend, "pIndex":pIndex,\
+ "pointXY":pointXY, "scaledXY":scaledXY}
+ #pass dict to update the pointLabel
+ self.client.UpdatePointLabel(mDataDict)
+ event.Skip() #go to next handler
+
+ def HistOptionsMenu(self, event):
+ """!Popup menu for histogram and text options
+ """
+ point = wx.GetMousePosition()
+ popt = wx.Menu()
+ # Add items to the menu
+ settext = wx.MenuItem(popt, -1, 'Histogram text settings')
+ popt.AppendItem(settext)
+ self.Bind(wx.EVT_MENU, self.PText, settext)
+
+ setgrid = wx.MenuItem(popt, -1, 'Histogram plot settings')
+ popt.AppendItem(setgrid)
+ self.Bind(wx.EVT_MENU, self.POptions, setgrid)
+
+ # Popup the menu. If an item is selected then its handler
+ # will be called before PopupMenu returns.
+ self.PopupMenu(popt)
+ popt.Destroy()
+
+ def NotFunctional(self):
+ """!Creates a 'not functional' message dialog
+ """
+ dlg = wx.MessageDialog(parent = self,
+ message = _('This feature is not yet functional'),
+ caption = _('Under Construction'),
+ style = wx.OK | wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+ def OnPText(self, dlg):
+ """!Custom text settings for histogram plot.
+ """
+ self.ptitle = dlg.ptitle
+ self.xlabel = dlg.xlabel
+ self.ylabel = dlg.ylabel
+ dlg.UpdateSettings()
+
+ self.client.SetFont(self.properties['font']['wxfont'])
+ self.client.SetFontSizeTitle(self.properties['font']['prop']['titleSize'])
+ self.client.SetFontSizeAxis(self.properties['font']['prop']['axisSize'])
+
+ if self.histogram:
+ self.histogram.setTitle(dlg.ptitle)
+ self.histogram.setXLabel(dlg.xlabel)
+ self.histogram.setYLabel(dlg.ylabel)
+
+ self.OnRedraw(event=None)
+
+ def PText(self, event):
+ """!Set custom text values for profile title and axis labels.
+ """
+ dlg = TextDialog(parent=self, id=wx.ID_ANY, title=_('Histogram text settings'))
+
+ if dlg.ShowModal() == wx.ID_OK:
+ self.OnPText(dlg)
+
+ dlg.Destroy()
+
+ def POptions(self, event):
+ """!Set various profile options, including: line width, color,
+ style; marker size, color, fill, and style; grid and legend
+ options. Calls OptDialog class.
+ """
+ dlg = OptDialog(parent=self, id=wx.ID_ANY, title=_('Histogram settings'))
+ btnval = dlg.ShowModal()
+
+ if btnval == wx.ID_SAVE:
+ dlg.UpdateSettings()
+ self.SetGraphStyle()
+ dlg.Destroy()
+ elif btnval == wx.ID_CANCEL:
+ dlg.Destroy()
+
+ def PrintMenu(self, event):
+ """!Print options and output menu
+ """
+ point = wx.GetMousePosition()
+ printmenu = wx.Menu()
+ # Add items to the menu
+ setup = wx.MenuItem(printmenu, -1,'Page setup')
+ printmenu.AppendItem(setup)
+ self.Bind(wx.EVT_MENU, self.OnPageSetup, setup)
+
+ preview = wx.MenuItem(printmenu, -1,'Print preview')
+ printmenu.AppendItem(preview)
+ self.Bind(wx.EVT_MENU, self.OnPrintPreview, preview)
+
+ doprint = wx.MenuItem(printmenu, -1,'Print display')
+ printmenu.AppendItem(doprint)
+ self.Bind(wx.EVT_MENU, self.OnDoPrint, doprint)
+
+ # Popup the menu. If an item is selected then its handler
+ # will be called before PopupMenu returns.
+ self.PopupMenu(printmenu)
+ printmenu.Destroy()
+
+ def OnPageSetup(self, event):
+ self.client.PageSetup()
+
+ def OnPrintPreview(self, event):
+ self.client.PrintPreview()
+
+ def OnDoPrint(self, event):
+ self.client.Printout()
+
+ def OnQuit(self, event):
+ self.Close(True)
+
+ def OnCloseWindow(self, event):
+ """
+ Close profile window and clean up
+ """
+ self.mapwin.ClearLines()
+ self.mapwin.mouse['begin'] = self.mapwin.mouse['end'] = (0.0, 0.0)
+ self.mapwin.mouse['use'] = 'pointer'
+ self.mapwin.mouse['box'] = 'point'
+ self.mapwin.polycoords = []
+ self.mapwin.SetCursor(self.Parent.cursors["default"])
+
+ self.mapwin.UpdateMap(render=False, renderVector=False)
+
+ self.Destroy()
+
+class SetRasterDialog(wx.Dialog):
+ def __init__(self, parent, id=wx.ID_ANY,
+ title=_("Select raster map or imagery group to histogram"),
+ pos=wx.DefaultPosition, size=wx.DefaultSize,
+ style=wx.DEFAULT_DIALOG_STYLE):
+ """!Dialog to select raster maps to histogram.
+ """
+
+ wx.Dialog.__init__(self, parent, id, title, pos, size, style)
+
+ self.parent = parent
+ self.rasterList = self.parent.rasterList
+ self.group = self.parent.group
+ self.bins = self.parent.bins
+ self.histtype = self.parent.histtype
+ self.maptype = self.parent.maptype
+
+ self._do_layout()
+
+ def _do_layout(self):
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ box = wx.GridBagSizer (hgap=3, vgap=3)
+
+ #
+ # select single raster or image group to histogram radio buttons
+ #
+ self.rasterRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " %s " % _("Histogram single raster"), style = wx.RB_GROUP)
+ self.groupRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " %s " % _("Histogram imagery group"))
+ if self.maptype == 'raster':
+ self.rasterRadio.SetValue(True)
+ elif self.maptype == 'group':
+ self.groupRadio.SetValue(True)
+ box.Add(item=self.rasterRadio, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 0))
+ box.Add(item=self.groupRadio, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 1))
+
+ #
+ # Select a raster to histogram
+ #
+ label = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("Select raster map:"))
+ box.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(1, 0))
+ self.rselection = gselect.Select(self, id=wx.ID_ANY,
+ size=globalvar.DIALOG_GSELECT_SIZE,
+ type='cell')
+ if self.groupRadio.GetValue() == True:
+ self.rselection.Disable()
+ else:
+ if len(self.rasterList) > 0: self.rselection.SetValue(self.rasterList[0])
+ box.Add(item=self.rselection, pos=(1, 1))
+
+ #
+ # Select an image group to histogram
+ #
+ label = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("Select image group:"))
+ box.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(2, 0))
+ self.gselection = gselect.Select(self, id=wx.ID_ANY,
+ size=globalvar.DIALOG_GSELECT_SIZE,
+ type='group')
+ if self.rasterRadio.GetValue() == True:
+ self.gselection.Disable()
+ else:
+ if self.group != None: self.gselection.SetValue(self.group)
+ box.Add(item=self.gselection, pos=(2, 1))
+
+ #
+ # Nsteps for FP maps and histogram type selection
+ #
+
+ label = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("Number of bins (for FP maps)"))
+ box.Add(item=label,
+ flag=wx.ALIGN_CENTER_VERTICAL, pos=(3, 0))
+ bins = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="", pos=(30, 50),
+ size=(100,-1), style=wx.SP_ARROW_KEYS)
+ bins.SetRange(1,1000)
+ bins.SetValue(self.bins)
+ box.Add(item=bins,
+ flag=wx.ALIGN_CENTER_VERTICAL, pos=(3, 1))
+
+ label = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("Histogram type"))
+ box.Add(item=label,
+ flag=wx.ALIGN_CENTER_VERTICAL, pos=(4, 0))
+ types = ['count', 'percent', 'area']
+ histtype = wx.ComboBox(parent=self, id=wx.ID_ANY, size=(250, -1),
+ choices=types, style=wx.CB_DROPDOWN)
+ histtype.SetStringSelection(self.histtype)
+ box.Add(item=histtype,
+ flag=wx.ALIGN_CENTER_VERTICAL, pos=(4, 1))
+
+ sizer.Add(item=box, proportion=0,
+ flag=wx.ALL, border=10)
+
+ line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20, -1), style=wx.LI_HORIZONTAL)
+ sizer.Add(item=line, proportion=0,
+ flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border=5)
+
+ btnsizer = wx.StdDialogButtonSizer()
+
+ btn = wx.Button(self, wx.ID_OK)
+ btn.SetDefault()
+ btnsizer.AddButton(btn)
+
+ btn = wx.Button(self, wx.ID_CANCEL)
+ btnsizer.AddButton(btn)
+ btnsizer.Realize()
+
+ sizer.Add(item=btnsizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
+
+ #
+ # bindings
+ #
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnHistMap, self.rasterRadio)
+ self.Bind(wx.EVT_RADIOBUTTON, self.OnHistMap, self.groupRadio)
+ self.rselection.Bind(wx.EVT_TEXT, self.OnRasterSelection)
+ self.gselection.Bind(wx.EVT_TEXT, self.OnGroupSelection)
+ bins.Bind(wx.EVT_TEXT, self.OnSetBins)
+ bins.Bind(wx.EVT_SPINCTRL, self.OnSetBins)
+ histtype.Bind(wx.EVT_TEXT, self.OnSetHisttypes)
+
+ self.SetSizer(sizer)
+ sizer.Fit(self)
+
+ def OnHistMap(self, event):
+ """!Hander for radio buttons to choose between histogramming a
+ single raster and an imagery group
+ """
+ if self.rasterRadio.GetValue() == True:
+ self.maptype = 'raster'
+ self.rselection.Enable()
+ self.gselection.Disable()
+ self.gselection.SetValue('')
+ elif self.groupRadio.GetValue() == True:
+ self.maptype = 'group'
+ self.gselection.Enable()
+ self.rselection.Disable()
+ self.rselection.SetValue('')
+ else:
+ pass
+
+ def OnRasterSelection(self, event):
+ """!Handler for selecting a single raster map
+ """
+ self.rasterList = []
+ self.rasterList.append(event.GetString())
+
+ def OnGroupSelection(self, event):
+ """!Handler for selecting imagery group
+ """
+ self.rasterList = []
+ self.group = event.GetString()
+ self.rasterList = grass.read_command('i.group',
+ group='%s' % self.group,
+ quiet=True,
+ flags='g').strip().split('\n')
+
+ def OnSetBins(self, event):
+ """!Bins for histogramming FP maps (=nsteps in r.stats)
+ """
+ if event.GetValue() != None:
+ self.bins = event.GetValue()
+ elif event.GetString() != None and int(event.GetString()) > 0:
+ self.bins = int(event.GetString())
+
+ def OnSetHisttypes(self, event):
+ self.histtype = event.GetString()
+ print 'histtype = ' + self.histtype
+
+class TextDialog(wx.Dialog):
+ def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize,
+ style=wx.DEFAULT_DIALOG_STYLE):
+ """!Dialog to set histogram text options: font, title
+ and font size, axis labels and font size
+ """
+ wx.Dialog.__init__(self, parent, id, title, pos, size, style)
+ #
+ # initialize variables
+ #
+ # combo box entry lists
+ self.ffamilydict = { 'default' : wx.FONTFAMILY_DEFAULT,
+ 'decorative' : wx.FONTFAMILY_DECORATIVE,
+ 'roman' : wx.FONTFAMILY_ROMAN,
+ 'script' : wx.FONTFAMILY_SCRIPT,
+ 'swiss' : wx.FONTFAMILY_SWISS,
+ 'modern' : wx.FONTFAMILY_MODERN,
+ 'teletype' : wx.FONTFAMILY_TELETYPE }
+
+ self.fstyledict = { 'normal' : wx.FONTSTYLE_NORMAL,
+ 'slant' : wx.FONTSTYLE_SLANT,
+ 'italic' : wx.FONTSTYLE_ITALIC }
+
+ self.fwtdict = { 'normal' : wx.FONTWEIGHT_NORMAL,
+ 'light' : wx.FONTWEIGHT_LIGHT,
+ 'bold' : wx.FONTWEIGHT_BOLD }
+
+ self.parent = parent
+
+ self.ptitle = self.parent.ptitle
+ self.xlabel = self.parent.xlabel
+ self.ylabel = self.parent.ylabel
+
+ self.properties = self.parent.properties # read-only
+
+ # font size
+ self.fontfamily = self.properties['font']['wxfont'].GetFamily()
+ self.fontstyle = self.properties['font']['wxfont'].GetStyle()
+ self.fontweight = self.properties['font']['wxfont'].GetWeight()
+
+ self._do_layout()
+
+
+#### This stays with relevant changes to dictionary/list names
+ def _do_layout(self):
+ """!Do layout"""
+ # dialog layout
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ box = wx.StaticBox(parent=self, id=wx.ID_ANY,
+ label=" %s " % _("Text settings"))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
+
+ #
+ # profile title
+ #
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Profile title:"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 0))
+ self.ptitleentry = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(250,-1))
+ # self.ptitleentry.SetFont(self.font)
+ self.ptitleentry.SetValue(self.ptitle)
+ gridSizer.Add(item=self.ptitleentry, pos=(0, 1))
+
+ #
+ # title font
+ #
+ tlabel = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Title font size (pts):"))
+ gridSizer.Add(item=tlabel, flag=wx.ALIGN_CENTER_VERTICAL, pos=(1, 0))
+ self.ptitlesize = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="", pos=(30, 50),
+ size=(50,-1), style=wx.SP_ARROW_KEYS)
+ self.ptitlesize.SetRange(5,100)
+ self.ptitlesize.SetValue(int(self.properties['font']['prop']['titleSize']))
+ gridSizer.Add(item=self.ptitlesize, pos=(1, 1))
+
+ #
+ # x-axis label
+ #
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("X-axis label:"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(2, 0))
+ self.xlabelentry = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(250,-1))
+ # self.xlabelentry.SetFont(self.font)
+ self.xlabelentry.SetValue(self.xlabel)
+ gridSizer.Add(item=self.xlabelentry, pos=(2, 1))
+
+ #
+ # y-axis label
+ #
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Y-axis label:"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(3, 0))
+ self.ylabelentry = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(250,-1))
+ # self.ylabelentry.SetFont(self.font)
+ self.ylabelentry.SetValue(self.ylabel)
+ gridSizer.Add(item=self.ylabelentry, pos=(3, 1))
+
+ #
+ # font size
+ #
+ llabel = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Label font size (pts):"))
+ gridSizer.Add(item=llabel, flag=wx.ALIGN_CENTER_VERTICAL, pos=(4, 0))
+ self.axislabelsize = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="", pos=(30, 50),
+ size=(50, -1), style=wx.SP_ARROW_KEYS)
+ self.axislabelsize.SetRange(5, 100)
+ self.axislabelsize.SetValue(int(self.properties['font']['prop']['axisSize']))
+ gridSizer.Add(item=self.axislabelsize, pos=(4,1))
+
+ boxSizer.Add(item=gridSizer)
+ sizer.Add(item=boxSizer, flag=wx.ALL | wx.EXPAND, border=3)
+
+ #
+ # font settings
+ #
+ box = wx.StaticBox(parent=self, id=wx.ID_ANY,
+ label=" %s " % _("Font settings"))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
+ gridSizer.AddGrowableCol(1)
+
+ #
+ # font family
+ #
+ label1 = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Font family:"))
+ gridSizer.Add(item=label1, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 0))
+ self.ffamilycb = wx.ComboBox(parent=self, id=wx.ID_ANY, size=(250, -1),
+ choices=self.ffamilydict.keys(), style=wx.CB_DROPDOWN)
+ self.ffamilycb.SetStringSelection('swiss')
+ for item in self.ffamilydict.items():
+ if self.fontfamily == item[1]:
+ self.ffamilycb.SetStringSelection(item[0])
+ break
+ gridSizer.Add(item=self.ffamilycb, pos=(0, 1), flag=wx.ALIGN_RIGHT)
+
+ #
+ # font style
+ #
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Style:"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(1, 0))
+ self.fstylecb = wx.ComboBox(parent=self, id=wx.ID_ANY, size=(250, -1),
+ choices=self.fstyledict.keys(), style=wx.CB_DROPDOWN)
+ self.fstylecb.SetStringSelection('normal')
+ for item in self.fstyledict.items():
+ if self.fontstyle == item[1]:
+ self.fstylecb.SetStringSelection(item[0])
+ break
+ gridSizer.Add(item=self.fstylecb, pos=(1, 1), flag=wx.ALIGN_RIGHT)
+
+ #
+ # font weight
+ #
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Weight:"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(2, 0))
+ self.fwtcb = wx.ComboBox(parent=self, size=(250, -1),
+ choices=self.fwtdict.keys(), style=wx.CB_DROPDOWN)
+ self.fwtcb.SetStringSelection('normal')
+ for item in self.fwtdict.items():
+ if self.fontweight == item[1]:
+ self.fwtcb.SetStringSelection(item[0])
+ break
+
+ gridSizer.Add(item=self.fwtcb, pos=(2, 1), flag=wx.ALIGN_RIGHT)
+
+ boxSizer.Add(item=gridSizer, flag=wx.EXPAND)
+ sizer.Add(item=boxSizer, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
+
+ line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20, -1), style=wx.LI_HORIZONTAL)
+ sizer.Add(item=line, proportion=0,
+ flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border=3)
+
+ #
+ # buttons
+ #
+ btnSave = wx.Button(self, wx.ID_SAVE)
+ btnApply = wx.Button(self, wx.ID_APPLY)
+ btnOk = wx.Button(self, wx.ID_OK)
+ btnCancel = wx.Button(self, wx.ID_CANCEL)
+ btnOk.SetDefault()
+
+ # bindings
+ btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
+ btnApply.SetToolTipString(_("Apply changes for the current session"))
+ btnOk.Bind(wx.EVT_BUTTON, self.OnOk)
+ btnOk.SetToolTipString(_("Apply changes for the current session and close dialog"))
+ btnOk.SetDefault()
+ btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
+ btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
+ btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
+ btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
+
+ # sizers
+ btnStdSizer = wx.StdDialogButtonSizer()
+ btnStdSizer.AddButton(btnOk)
+ btnStdSizer.AddButton(btnApply)
+ btnStdSizer.AddButton(btnCancel)
+ btnStdSizer.Realize()
+
+ btnSizer = wx.BoxSizer(wx.HORIZONTAL)
+ btnSizer.Add(item=btnSave, proportion=0, flag=wx.ALIGN_LEFT | wx.ALL, border=5)
+ btnSizer.Add(item=btnStdSizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
+ sizer.Add(item=btnSizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
+
+ #
+ # bindings
+ #
+ self.ptitleentry.Bind(wx.EVT_TEXT, self.OnTitle)
+ self.xlabelentry.Bind(wx.EVT_TEXT, self.OnXLabel)
+ self.ylabelentry.Bind(wx.EVT_TEXT, self.OnYLabel)
+
+ self.SetSizer(sizer)
+ sizer.Fit(self)
+
+ def OnTitle(self, event):
+ self.ptitle = event.GetString()
+
+ def OnXLabel(self, event):
+ self.xlabel = event.GetString()
+
+ def OnYLabel(self, event):
+ self.ylabel = event.GetString()
+
+ def UpdateSettings(self):
+ self.properties['font']['prop']['titleSize'] = self.ptitlesize.GetValue()
+ self.properties['font']['prop']['axisSize'] = self.axislabelsize.GetValue()
+
+ family = self.ffamilydict[self.ffamilycb.GetStringSelection()]
+ self.properties['font']['wxfont'].SetFamily(family)
+ style = self.fstyledict[self.fstylecb.GetStringSelection()]
+ self.properties['font']['wxfont'].SetStyle(style)
+ weight = self.fwtdict[self.fwtcb.GetStringSelection()]
+ self.properties['font']['wxfont'].SetWeight(weight)
+
+ def OnSave(self, event):
+ """!Button 'Save' pressed"""
+ self.UpdateSettings()
+ fileSettings = {}
+ UserSettings.ReadSettingsFile(settings=fileSettings)
+ fileSettings['histogram'] = UserSettings.Get(group='histogram')
+ file = UserSettings.SaveToFile(fileSettings)
+ self.parent.parent.GetLayerManager().goutput.WriteLog(_('Histogram settings saved to file \'%s\'.') % file)
+ self.EndModal(wx.ID_OK)
+
+ def OnApply(self, event):
+ """!Button 'Apply' pressed"""
+ self.UpdateSettings()
+ self.parent.OnPText(self)
+
+ def OnOk(self, event):
+ """!Button 'OK' pressed"""
+ self.UpdateSettings()
+ self.EndModal(wx.ID_OK)
+
+ def OnCancel(self, event):
+ """!Button 'Cancel' pressed"""
+ self.EndModal(wx.ID_CANCEL)
+
+class OptDialog(wx.Dialog):
+ def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize,
+ style=wx.DEFAULT_DIALOG_STYLE):
+
+ """!Dialog to set various profile options, including: line
+ width, color, style; marker size, color, fill, and style; grid
+ and legend options.
+ """
+ wx.Dialog.__init__(self, parent, id, title, pos, size, style)
+ # init variables
+ self.pstyledict = parent.pstyledict
+ self.ptfilldict = parent.ptfilldict
+
+ self.axislist = ['min',
+ 'auto',
+ 'custom']
+
+ # widgets ids
+ self.wxId = {}
+
+ self.parent = parent
+
+ # read-only
+ self.raster = self.parent.raster
+ self.rasterList = self.parent.rasterList
+ self.properties = self.parent.properties
+ self.map = ''
+
+ if len(self.rasterList) == 0:
+ wx.MessageBox(parent = self,
+ message = _("No map or image group selected to histogram."),
+ caption = _("Warning"), style = wx.OK | wx.ICON_ERROR)
+
+ self._do_layout()
+
+ def _do_layout(self):
+ """!Do layout"""
+ # dialog layout
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ #
+ # histogram line settings
+ #
+ box = wx.StaticBox(parent=self, id=wx.ID_ANY,
+ label=" %s " % _("Histogram settings"))
+ boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+
+ self.wxId['pcolor'] = 0
+ self.wxId['pwidth'] = 0
+ self.wxId['pstyle'] = 0
+ self.wxId['plegend'] = 0
+
+ if len(self.rasterList) > 0:
+ box = wx.StaticBox(parent=self, id=wx.ID_ANY,
+ label=_("Map/image histogrammed"))
+ boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+
+ gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
+
+ row = 0
+ self.mapchoice = wx.Choice(parent = self, id = wx.ID_ANY, size = (300, -1),
+ choices = self.rasterList)
+ if self.map == None or self.map == '':
+ self.map = self.rasterList[self.mapchoice.GetCurrentSelection()]
+ else:
+ self.mapchoice.SetStringSelection(self.map)
+ gridSizer.Add(item=self.mapchoice, flag=wx.ALIGN_CENTER_VERTICAL,
+ pos=(row, 0), span=(1, 2))
+
+ row +=1
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Line color"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
+ pcolor = csel.ColourSelect(parent=self, id=wx.ID_ANY, colour=self.raster[self.map]['pcolor'])
+ self.wxId['pcolor'] = pcolor.GetId()
+ gridSizer.Add(item=pcolor, pos=(row, 1))
+
+ row += 1
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Line width"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
+ pwidth = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="",
+ size=(50,-1), style=wx.SP_ARROW_KEYS)
+ pwidth.SetRange(1, 10)
+ pwidth.SetValue(self.raster[self.map]['pwidth'])
+ self.wxId['pwidth'] = pwidth.GetId()
+ gridSizer.Add(item=pwidth, pos=(row, 1))
+
+ row +=1
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Line style"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
+ pstyle = wx.Choice(parent=self, id=wx.ID_ANY,
+ size=(120, -1), choices=self.pstyledict.keys(), style=wx.CB_DROPDOWN)
+ pstyle.SetStringSelection(self.raster[self.map]['pstyle'])
+ self.wxId['pstyle'] = pstyle.GetId()
+ gridSizer.Add(item=pstyle, pos=(row, 1))
+
+ row += 1
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Legend"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
+ plegend = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(200,-1))
+ plegend.SetValue(self.raster[self.map]['plegend'])
+ gridSizer.Add(item=plegend, pos=(row, 1))
+ self.wxId['plegend'] = plegend.GetId()
+ boxSizer.Add(item=gridSizer)
+
+ flag = wx.ALL
+ boxMainSizer.Add(item=boxSizer, flag=flag, border=3)
+
+ sizer.Add(item=boxMainSizer, flag=wx.ALL | wx.EXPAND, border=3)
+
+ middleSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ #
+ # axis options
+ #
+ box = wx.StaticBox(parent=self, id=wx.ID_ANY,
+ label=" %s " % _("Axis settings"))
+ boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+
+ self.wxId['x-axis'] = {}
+ self.wxId['y-axis'] = {}
+
+ idx = 0
+ for axis, atype in [(_("X-Axis"), 'x-axis'),
+ (_("Y-Axis"), 'y-axis')]:
+ box = wx.StaticBox(parent=self, id=wx.ID_ANY,
+ label=" %s " % axis)
+ boxSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
+
+ prop = self.properties[atype]['prop']
+
+ row = 0
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Style"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
+ type = wx.Choice(parent=self, id=wx.ID_ANY,
+ size=(100, -1), choices=self.axislist, style=wx.CB_DROPDOWN)
+ type.SetStringSelection(prop['type'])
+ self.wxId[atype]['type'] = type.GetId()
+ gridSizer.Add(item=type, pos=(row, 1))
+
+ row += 1
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Custom min"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
+ min = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(70, -1))
+ min.SetValue(str(prop['min']))
+ self.wxId[atype]['min'] = min.GetId()
+ gridSizer.Add(item=min, pos=(row, 1))
+
+ row += 1
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Custom max"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
+ max = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(70, -1))
+ max.SetValue(str(prop['max']))
+ self.wxId[atype]['max'] = max.GetId()
+ gridSizer.Add(item=max, pos=(row, 1))
+
+ row += 1
+ log = wx.CheckBox(parent=self, id=wx.ID_ANY, label=_("Log scale"))
+ log.SetValue(prop['log'])
+ self.wxId[atype]['log'] = log.GetId()
+ gridSizer.Add(item=log, pos=(row, 0), span=(1, 2))
+
+ if idx == 0:
+ flag = wx.ALL | wx.EXPAND
+ else:
+ flag = wx.TOP | wx.BOTTOM | wx.RIGHT | wx.EXPAND
+
+ boxSizer.Add(item=gridSizer, flag=wx.ALL, border=3)
+ boxMainSizer.Add(item=boxSizer, flag=flag, border=3)
+
+ idx += 1
+
+ middleSizer.Add(item=boxMainSizer, flag=wx.ALL | wx.EXPAND, border=3)
+
+ #
+ # grid & legend options
+ #
+ self.wxId['grid'] = {}
+ self.wxId['legend'] = {}
+ self.wxId['font'] = {}
+ box = wx.StaticBox(parent=self, id=wx.ID_ANY,
+ label=" %s " % _("Grid and Legend settings"))
+ boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
+ gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
+
+ row = 0
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Grid color"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
+ gridcolor = csel.ColourSelect(parent=self, id=wx.ID_ANY, colour=self.properties['grid']['color'])
+ self.wxId['grid']['color'] = gridcolor.GetId()
+ gridSizer.Add(item=gridcolor, pos=(row, 1))
+
+ row +=1
+ gridshow = wx.CheckBox(parent=self, id=wx.ID_ANY, label=_("Show grid"))
+ gridshow.SetValue(self.properties['grid']['enabled'])
+ self.wxId['grid']['enabled'] = gridshow.GetId()
+ gridSizer.Add(item=gridshow, pos=(row, 0), span=(1, 2))
+
+ row +=1
+ label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Legend font size"))
+ gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
+ legendfontsize = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="",
+ size=(50, -1), style=wx.SP_ARROW_KEYS)
+ legendfontsize.SetRange(5,100)
+ legendfontsize.SetValue(int(self.properties['font']['prop']['legendSize']))
+ self.wxId['font']['legendSize'] = legendfontsize.GetId()
+ gridSizer.Add(item=legendfontsize, pos=(row, 1))
+
+ row += 1
+ legendshow = wx.CheckBox(parent=self, id=wx.ID_ANY, label=_("Show legend"))
+ legendshow.SetValue(self.properties['legend']['enabled'])
+ self.wxId['legend']['enabled'] = legendshow.GetId()
+ gridSizer.Add(item=legendshow, pos=(row, 0), span=(1, 2))
+
+ boxMainSizer.Add(item=gridSizer, flag=flag, border=3)
+
+ middleSizer.Add(item=boxMainSizer, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
+
+ sizer.Add(item=middleSizer, flag=wx.ALL, border=0)
+
+ #
+ # line & buttons
+ #
+ line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20, -1), style=wx.LI_HORIZONTAL)
+ sizer.Add(item=line, proportion=0,
+ flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border=3)
+
+ #
+ # buttons
+ #
+ btnSave = wx.Button(self, wx.ID_SAVE)
+ btnApply = wx.Button(self, wx.ID_APPLY)
+ btnCancel = wx.Button(self, wx.ID_CANCEL)
+ btnSave.SetDefault()
+
+ # tooltips for buttons
+ btnApply.SetToolTipString(_("Apply changes for the current session"))
+ btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
+ btnSave.SetDefault()
+ btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
+
+ # sizers
+ btnStdSizer = wx.StdDialogButtonSizer()
+ btnStdSizer.AddButton(btnCancel)
+ btnStdSizer.AddButton(btnSave)
+ btnStdSizer.AddButton(btnApply)
+ btnStdSizer.Realize()
+
+ sizer.Add(item=btnStdSizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
+
+ #
+ # bindings for buttons and map plot settings controls
+ #
+ self.mapchoice.Bind(wx.EVT_CHOICE, self.OnSetMap)
+ pcolor.Bind(csel.EVT_COLOURSELECT, self.OnSetOpt)
+ pwidth.Bind(wx.EVT_SPINCTRL, self.OnSetOpt)
+ pstyle.Bind(wx.EVT_CHOICE, self.OnSetOpt)
+ plegend.Bind(wx.EVT_TEXT, self.OnSetOpt)
+ btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
+ btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
+ btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
+
+ self.SetSizer(sizer)
+ sizer.Fit(self)
+
+ def OnSetMap(self, event):
+ """!Handler for changing map selection"""
+ self.map = event.GetString()
+
+ # update plot settings controls for selected map
+ self.FindWindowById(self.wxId['pcolor']).SetColour(self.raster[self.map]['pcolor'])
+ self.FindWindowById(self.wxId['pwidth']).SetValue(self.raster[self.map]['pwidth'])
+ self.FindWindowById(self.wxId['pstyle']).SetStringSelection(self.raster[self.map]['pstyle'])
+ self.FindWindowById(self.wxId['plegend']).SetValue(self.raster[self.map]['plegend'])
+ self.Refresh()
+
+ def OnSetOpt(self, event):
+ """!Handler for changing any other option"""
+ self.map = self.rasterList[self.mapchoice.GetCurrentSelection()]
+ self.UpdateSettings()
+ self.parent.SetGraphStyle()
+ if self.parent.histogram:
+ self.parent.DrawPlot()
+
+ def UpdateSettings(self):
+ """!Apply settings to each map and to entire plot"""
+
+ # update plot settings for selected map
+ self.raster[self.map]['pcolor'] = self.FindWindowById(self.wxId['pcolor']).GetColour()
+ self.raster[self.map]['pwidth'] = int(self.FindWindowById(self.wxId['pwidth']).GetValue())
+ self.raster[self.map]['pstyle'] = self.FindWindowById(self.wxId['pstyle']).GetStringSelection()
+ self.raster[self.map]['plegend'] = self.FindWindowById(self.wxId['plegend']).GetValue()
+
+ # update settings for entire plot
+ for axis in ('x-axis', 'y-axis'):
+ self.properties[axis]['prop']['type'] = self.FindWindowById(self.wxId[axis]['type']).GetStringSelection()
+ self.properties[axis]['prop']['min'] = float(self.FindWindowById(self.wxId[axis]['min']).GetValue())
+ self.properties[axis]['prop']['max'] = float(self.FindWindowById(self.wxId[axis]['max']).GetValue())
+ self.properties[axis]['prop']['log'] = self.FindWindowById(self.wxId[axis]['log']).IsChecked()
+
+ self.properties['grid']['color'] = self.FindWindowById(self.wxId['grid']['color']).GetColour()
+ self.properties['grid']['enabled'] = self.FindWindowById(self.wxId['grid']['enabled']).IsChecked()
+
+ self.properties['font']['prop']['legendSize'] = self.FindWindowById(self.wxId['font']['legendSize']).GetValue()
+ self.properties['legend']['enabled'] = self.FindWindowById(self.wxId['legend']['enabled']).IsChecked()
+
+ def OnSave(self, event):
+ """!Button 'Save' pressed"""
+ self.UpdateSettings()
+ fileSettings = {}
+ UserSettings.ReadSettingsFile(settings=fileSettings)
+
+ fileSettings['histogram'] = UserSettings.Get(group='histogram')
+ file = UserSettings.SaveToFile(fileSettings)
+ self.parent.parent.GetLayerManager().goutput.WriteLog(_('Histogram settings saved to file \'%s\'.') % file)
+ self.parent.SetGraphStyle()
+ if self.parent.histogram:
+ self.parent.DrawPlot()
+ self.Close()
+
+ def OnApply(self, event):
+ """!Button 'Apply' pressed. Does not close dialog"""
+ self.UpdateSettings()
+ self.parent.SetGraphStyle()
+ if self.parent.histogram:
+ self.parent.DrawPlot()
+
+ def OnCancel(self, event):
+ """!Button 'Cancel' pressed"""
+ self.Close()
+
Property changes on: grass/trunk/gui/wxpython/gui_modules/histogram2.py
___________________________________________________________________
Added: svn:executable
+ *
Modified: grass/trunk/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/mapdisp.py 2011-09-21 21:45:31 UTC (rev 48402)
+++ grass/trunk/gui/wxpython/gui_modules/mapdisp.py 2011-09-22 05:19:24 UTC (rev 48403)
@@ -46,6 +46,7 @@
import dbm
import dbm_dialogs
import histogram
+import histogram2
import profile
import globalvar
import utils
@@ -1540,6 +1541,11 @@
toolsmenu.AppendItem(profile)
self.Bind(wx.EVT_MENU, self.Profile, profile)
+ histogram2 = wx.MenuItem(toolsmenu, wx.ID_ANY, _("Create histogram with PyPlot"))
+ histogram2.SetBitmap(icons["histogram"].GetBitmap(self.iconsize))
+ toolsmenu.AppendItem(histogram2)
+ self.Bind(wx.EVT_MENU, self.Histogram2, histogram2)
+
histogram = wx.MenuItem(toolsmenu, wx.ID_ANY, icons["histogram"].GetLabel())
histogram.SetBitmap(icons["histogram"].GetBitmap(self.iconsize))
toolsmenu.AppendItem(histogram)
@@ -1710,7 +1716,17 @@
self.histogram.Refresh()
self.histogram.Update()
+ def Histogram2(self, event):
+ """!Init histogram display canvas and tools
+ """
+ self.histogram2 = histogram2.HistFrame(self,
+ id = wx.ID_ANY, size = globalvar.HIST_WINDOW_SIZE,
+ style = wx.DEFAULT_FRAME_STYLE)
+ #show new display
+ self.histogram2.Show()
+ self.histogram2.Refresh()
+
def OnDecoration(self, event):
"""!Decorations overlay menu
"""
Modified: grass/trunk/gui/wxpython/gui_modules/preferences.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/preferences.py 2011-09-21 21:45:31 UTC (rev 48402)
+++ grass/trunk/gui/wxpython/gui_modules/preferences.py 2011-09-22 05:19:24 UTC (rev 48403)
@@ -445,6 +445,38 @@
'enabled' : True
},
},
+ 'histogram': {
+ 'raster' : {
+ 'pcolor' : (0, 0, 0, 255), # line color
+ 'pwidth' : 1, # line width
+ 'pstyle' : 'solid', # line pen style
+ 'datatype' : 'cell', # raster type
+ },
+ 'font' : {
+ 'titleSize' : 12,
+ 'axisSize' : 11,
+ 'legendSize' : 10,
+ },
+ 'grid' : {
+ 'color' : (200, 200, 200, 255),
+ 'enabled' : True,
+ },
+ 'x-axis' : {
+ 'type' : 'auto', # axis format
+ 'min' : 0, # axis min for custom axis range
+ 'max' : 0, # axis max for custom axis range
+ 'log' : False,
+ },
+ 'y-axis' : {
+ 'type' : 'auto', # axis format
+ 'min' : 0, # axis min for custom axis range
+ 'max' : 0, # axis max for custom axis range
+ 'log' : False,
+ },
+ 'legend' : {
+ 'enabled' : True
+ },
+ },
'gcpman' : {
'rms' : {
'highestonly' : True,
Modified: grass/trunk/gui/wxpython/gui_modules/toolbars.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/toolbars.py 2011-09-21 21:45:31 UTC (rev 48402)
+++ grass/trunk/gui/wxpython/gui_modules/toolbars.py 2011-09-22 05:19:24 UTC (rev 48403)
@@ -1416,6 +1416,45 @@
self.parent.OnQuit))
)
+class Histogram2Toolbar(AbstractToolbar):
+ """!Toolbar for histogramming raster map
+ """
+ def __init__(self, parent):
+ AbstractToolbar.__init__(self, parent)
+
+ self.InitToolbar(self._toolbarData())
+
+ # realize the toolbar
+ self.Realize()
+
+ def _toolbarData(self):
+ """!Toolbar data"""
+ icons = Icons['profile']
+ return self._getToolbarData((('addraster', Icons['layerManager']["addRast"],
+ self.parent.OnSelectRaster),
+ (None, ),
+ ('draw', icons["draw"],
+ self.parent.OnCreateHist),
+ ('erase', Icons['displayWindow']["erase"],
+ self.parent.OnErase),
+ ('drag', Icons['displayWindow']['pan'],
+ self.parent.OnDrag),
+ ('zoom', Icons['displayWindow']['zoomIn'],
+ self.parent.OnZoom),
+ ('unzoom', Icons['displayWindow']['zoomBack'],
+ self.parent.OnRedraw),
+ (None, ),
+ ('image', Icons['displayWindow']["saveFile"],
+ self.parent.SaveToFile),
+ ('print', Icons['displayWindow']["print"],
+ self.parent.PrintMenu),
+ (None, ),
+ ('settings', icons["options"],
+ self.parent.HistOptionsMenu),
+ ('quit', icons["quit"],
+ self.parent.OnQuit),
+ ))
+
class LMWorkspaceToolbar(AbstractToolbar):
"""!Layer Manager `workspace` toolbar
"""
More information about the grass-commit
mailing list