GRASS Programmer's Manual  6.4.2(2012)
profile.py
Go to the documentation of this file.
00001 """!
00002 @package profile
00003 
00004 Profile analysis of GRASS raster maps and images.
00005 
00006 Uses PyPlot (wx.lib.plot.py)
00007 
00008 Classes:
00009  - ProfileFrame
00010  - SetRasterDialog
00011  - TextDialog
00012  - OptDialog
00013 
00014 (C) 2007-2008 by the GRASS Development Team
00015 
00016 This program is free software under the GNU General Public License
00017 (>=v2). Read the file COPYING that comes with GRASS for details.
00018 
00019 @author Michael Barton
00020 @author Various updates by Martin Landa <landa.martin gmail.com>
00021 """
00022 
00023 import os
00024 import sys
00025 import math
00026 
00027 import wx
00028 import wx.lib.colourselect as  csel
00029 
00030 try:
00031     import numpy
00032     import wx.lib.plot as plot
00033 except ImportError:
00034     msg= _("This module requires the NumPy module, which could not be "
00035            "imported. It probably is not installed (it's not part of the "
00036            "standard Python distribution). See the Numeric Python site "
00037            "(http://numpy.scipy.org) for information on downloading source or "
00038            "binaries.")
00039     print >> sys.stderr, "profile.py: " + msg
00040 
00041 import globalvar
00042 import render
00043 import menuform
00044 import disp_print
00045 import gselect
00046 import gcmd
00047 import toolbars
00048 from debug import Debug as Debug
00049 from icon import Icons as Icons
00050 from preferences import globalSettings as UserSettings
00051 from grass.script import core as grass
00052 
00053 class ProfileFrame(wx.Frame):
00054     """!Mainframe for displaying profile of raster map. Uses wx.lib.plot.
00055     """
00056     def __init__(self, parent=None, id=wx.ID_ANY, title=_("GRASS Profile Analysis Tool"),
00057                  rasterList=[],
00058                  pos=wx.DefaultPosition, size=wx.DefaultSize,
00059                  style=wx.DEFAULT_FRAME_STYLE):
00060 
00061         self.parent = parent # MapFrame
00062         self.mapwin = self.parent.MapWindow
00063         self.Map = render.Map()  # instance of render.Map to be associated with display
00064 
00065         self.pstyledict = { 'solid' : wx.SOLID,
00066                             'dot' : wx.DOT,
00067                             'long-dash' : wx.LONG_DASH,
00068                             'short-dash' : wx.SHORT_DASH,
00069                             'dot-dash' : wx.DOT_DASH }
00070 
00071         self.ptfilldict = { 'transparent' : wx.TRANSPARENT,
00072                             'solid' : wx.SOLID }
00073 
00074         wx.Frame.__init__(self, parent, id, title, pos, size, style)
00075 
00076         #
00077         # Icon
00078         #
00079         self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
00080         
00081         #
00082         # Add toolbar
00083         #
00084         self.toolbar = toolbars.ProfileToolbar(parent=self)
00085         self.SetToolBar(self.toolbar)
00086         
00087         #
00088         # Set the size & cursor
00089         #
00090         self.SetClientSize(size)
00091 
00092         #
00093         # Add statusbar
00094         #
00095         self.statusbar = self.CreateStatusBar(number=2, style=0)
00096         self.statusbar.SetStatusWidths([-2, -1])
00097 
00098         #
00099         # Define canvas
00100         #
00101         # plot canvas settings
00102         self.client = plot.PlotCanvas(self)
00103         #define the function for drawing pointLabels
00104         self.client.SetPointLabelFunc(self.DrawPointLabel)
00105         # Create mouse event for showing cursor coords in status bar
00106         self.client.canvas.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
00107         # Show closest point when enabled
00108         self.client.canvas.Bind(wx.EVT_MOTION, self.OnMotion)
00109 
00110         #
00111         # Init variables
00112         #
00113         # 0    -> default raster map to profile
00114         # 1, 2 -> optional raster map to profile
00115         # units -> map data units (used for y axis legend)
00116         self.raster = {}
00117         for idx in (0, 1, 2):
00118             self.raster[idx] = {}
00119             self.raster[idx]['name'] = ''
00120             self.raster[idx]['units'] = ''
00121             self.raster[idx]['plegend'] = ''
00122             # list of distance,value pairs for plotting profile
00123             self.raster[idx]['datalist'] = []
00124             # first (default) profile line
00125             self.raster[idx]['pline'] = None
00126             self.raster[idx]['prop'] = UserSettings.Get(group='profile', key='raster' + str(idx))
00127             # changing color string to tuple
00128             colstr = str(self.raster[idx]['prop']['pcolor'])
00129             self.raster[idx]['prop']['pcolor'] = tuple(int(colval) for colval in colstr.strip('()').split(','))
00130 
00131         # set raster map name (if given)
00132         for idx in range(len(rasterList)):
00133             self.raster[idx]['name'] = rasterList[idx]
00134 
00135         # string of coordinates for r.profile
00136         self.coordstr = '' 
00137         # segment endpoint list
00138         self.seglist = []
00139         # list of things to plot
00140         self.plotlist = []
00141         # segment endpoints data 
00142         self.ppoints = '' 
00143         # plot draw object
00144         self.profile = None 
00145         # total transect length
00146         self.transect_length = 0.0
00147 
00148         # title of window
00149         self.ptitle = _('Profile of')
00150 
00151         # determine units (axis labels)
00152         if self.parent.Map.projinfo['units'] != '':
00153             self.xlabel = _('Distance (%s)') % self.parent.Map.projinfo['units']
00154         else:
00155             self.xlabel = _("Distance along transect")
00156         self.ylabel = _("Cell values")
00157 
00158         self.properties = {}
00159         self.properties['font'] = {}
00160         self.properties['font']['prop'] = UserSettings.Get(group='profile', key='font')
00161         self.properties['font']['wxfont'] = wx.Font(11, wx.FONTFAMILY_SWISS,
00162                                                     wx.FONTSTYLE_NORMAL,
00163                                                     wx.FONTWEIGHT_NORMAL)
00164         
00165         self.properties['marker'] = UserSettings.Get(group='profile', key='marker')
00166         # changing color string to tuple
00167         colstr = str(self.properties['marker']['color'])
00168         self.properties['marker']['color'] = tuple(int(colval) for colval in colstr.strip('()').split(','))
00169 
00170         self.properties['grid'] = UserSettings.Get(group='profile', key='grid')
00171         # changing color string to tuple
00172         colstr = str(self.properties['grid']['color'])
00173         self.properties['grid']['color'] = tuple(int(colval) for colval in colstr.strip('()').split(','))
00174                 
00175         self.properties['x-axis'] = {}
00176         
00177         self.properties['x-axis']['prop'] = UserSettings.Get(group='profile', key='x-axis')
00178         self.properties['x-axis']['axis'] = None
00179 
00180         self.properties['y-axis'] = {}
00181         self.properties['y-axis']['prop'] = UserSettings.Get(group='profile', key='y-axis')
00182         self.properties['y-axis']['axis'] = None
00183         
00184         self.properties['legend'] = UserSettings.Get(group='profile', key='legend')
00185         
00186         # zooming disabled
00187         self.zoom = False
00188         # draging disabled
00189         self.drag = False 
00190 
00191         # vertical and horizontal scrollbars
00192         self.client.SetShowScrollbars(True)
00193 
00194         # x and y axis set to normal (non-log)
00195         self.client.setLogScale((False, False))
00196         if self.properties['x-axis']['prop']['type']:
00197             self.client.SetXSpec(self.properties['x-axis']['prop']['type'])
00198         else:
00199             self.client.SetXSpec('auto')
00200         
00201         if self.properties['y-axis']['prop']['type']:
00202             self.client.SetYSpec(self.properties['y-axis']['prop']['type'])
00203         else:
00204             self.client.SetYSpec('auto')
00205 
00206         #
00207         # Bind various events
00208         #
00209         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
00210         
00211         self.CentreOnScreen()
00212 
00213     def OnDrawTransect(self, event):
00214         """!Draws transect to profile in map display
00215         """
00216         self.mapwin.polycoords = []
00217         self.seglist = []
00218         self.mapwin.ClearLines(self.mapwin.pdc)
00219         self.ppoints = ''
00220 
00221         self.parent.SetFocus()
00222         self.parent.Raise()
00223         
00224         self.mapwin.mouse['use'] = 'profile'
00225         self.mapwin.mouse['box'] = 'line'
00226         self.mapwin.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH)
00227         self.mapwin.polypen = wx.Pen(colour='dark green', width=2, style=wx.SHORT_DASH)
00228         self.mapwin.SetCursor(self.Parent.cursors["cross"])
00229 
00230     def OnSelectRaster(self, event):
00231         """!Select raster map(s) to profile
00232         """
00233         dlg = SetRasterDialog(parent=self)
00234 
00235         if dlg.ShowModal() == wx.ID_OK:
00236             for r in self.raster.keys():
00237                 self.raster[r]['name'] = dlg.raster[r]['name']
00238 
00239             # plot profile
00240             if self.raster[0]['name'] and len(self.mapwin.polycoords) > 0:
00241                 self.OnCreateProfile(event=None)
00242 
00243         dlg.Destroy()
00244 
00245     def SetRaster(self):
00246         """!Create coordinate string for profiling. Create segment list for
00247         transect segment markers.
00248         """
00249         #
00250         # create list of coordinate points for r.profile
00251         #
00252                 
00253         dist = 0
00254         cumdist = 0
00255         self.coordstr = ''
00256         lasteast = lastnorth = None
00257         
00258         if len(self.mapwin.polycoords) > 0:
00259             for point in self.mapwin.polycoords:
00260                 # build string of coordinate points for r.profile
00261                 if self.coordstr == '':
00262                     self.coordstr = '%d,%d' % (point[0], point[1])
00263                 else:
00264                     self.coordstr = '%s,%d,%d' % (self.coordstr, point[0], point[1])
00265 
00266         if self.raster[0]['name'] == '':
00267             return
00268 
00269         # title of window
00270         self.ptitle = _('Profile of')
00271 
00272         #
00273         # create list of coordinates for transect segment markers
00274         #
00275 
00276         if len(self.mapwin.polycoords) > 0:
00277             for point in self.mapwin.polycoords:
00278                 # get value of raster cell at coordinate point
00279                 ret = gcmd.RunCommand('r.what',
00280                                       parent = self,
00281                                       read = True,
00282                                       input = self.raster[0]['name'],
00283                                       east_north = '%d,%d' % (point[0],point[1]))
00284                 
00285                 val = ret.splitlines()[0].split('|')[3]
00286                 
00287                 # calculate distance between coordinate points
00288                 if lasteast and lastnorth:
00289                     dist = math.sqrt(math.pow((lasteast-point[0]),2) + math.pow((lastnorth-point[1]),2))
00290                 cumdist += dist
00291                 
00292                 #store total transect length
00293                 self.transect_length = cumdist
00294 
00295                 # build a list of distance,value pairs for each segment of transect
00296                 self.seglist.append((cumdist,val))
00297                 lasteast = point[0]
00298                 lastnorth = point[1]
00299 
00300             # delete first and last segment point
00301             try:
00302                 self.seglist.pop(0)
00303                 self.seglist.pop()
00304             except:
00305                 pass
00306 
00307         #
00308         # create datalist for each raster map
00309         #
00310         
00311         for r in self.raster.itervalues():
00312             if r['name'] == '':
00313                 continue
00314             r['datalist'] = self.CreateDatalist(r['name'], self.coordstr)
00315             r['plegend'] = _('Profile of %s') % r['name']
00316 
00317             ret = gcmd.RunCommand('r.info',
00318                                   parent = self,
00319                                   read = True,
00320                                   quiet = True,
00321                                   flags = 'u',
00322                                   map = r['name'])
00323 
00324             if ret:
00325                 r['units'] = ret.splitlines()[0].split('=')[1]
00326 
00327             # update title
00328             self.ptitle += ' %s and' % r['name']
00329 
00330         self.ptitle = self.ptitle.rstrip('and')
00331         
00332         #
00333         # set ylabel to match units if they exist
00334         #
00335         self.ylabel = ''
00336         i = 0
00337         
00338         for r in self.raster.itervalues():
00339             if r['name'] == '':
00340                 continue
00341             if r['units'] != '':
00342                 self.ylabel = '%s (%d),' % (r['units'], i)
00343             i += 1
00344         if self.ylabel == '':
00345             self.ylabel = _('Raster values')
00346         else:
00347             self.ylabel = self.ylabel.rstrip(',')
00348 
00349     def SetGraphStyle(self):
00350         """!Set plot and text options
00351         """
00352         self.client.SetFont(self.properties['font']['wxfont'])
00353         self.client.SetFontSizeTitle(self.properties['font']['prop']['titleSize'])
00354         self.client.SetFontSizeAxis(self.properties['font']['prop']['axisSize'])
00355 
00356         self.client.SetEnableZoom(self.zoom)
00357         self.client.SetEnableDrag(self.drag)
00358         
00359         #
00360         # axis settings
00361         #
00362         if self.properties['x-axis']['prop']['type'] == 'custom':
00363             self.client.SetXSpec('min')
00364         else:
00365             self.client.SetXSpec(self.properties['x-axis']['prop']['type'])
00366 
00367         if self.properties['y-axis']['prop']['type'] == 'custom':
00368             self.client.SetYSpec('min')
00369         else:
00370             self.client.SetYSpec(self.properties['y-axis']['prop']['type'])
00371 
00372         if self.properties['x-axis']['prop']['type'] == 'custom' and \
00373                self.properties['x-axis']['prop']['min'] < self.properties['x-axis']['prop']['max']:
00374             self.properties['x-axis']['axis'] = (self.properties['x-axis']['prop']['min'],
00375                                                  self.properties['x-axis']['prop']['max'])
00376         else:
00377             self.properties['x-axis']['axis'] = None
00378 
00379         if self.properties['y-axis']['prop']['type'] == 'custom' and \
00380                 self.properties['y-axis']['prop']['min'] < self.properties['y-axis']['prop']['max']:
00381             self.properties['y-axis']['axis'] = (self.properties['y-axis']['prop']['min'],
00382                                                  self.properties['y-axis']['prop']['max'])
00383         else:
00384             self.properties['y-axis']['axis'] = None
00385 
00386         self.client.SetEnableGrid(self.properties['grid']['enabled'])
00387         
00388         self.client.SetGridColour(wx.Color(self.properties['grid']['color'][0],
00389                                            self.properties['grid']['color'][1],
00390                                            self.properties['grid']['color'][2],
00391                                            255))
00392 
00393         self.client.SetFontSizeLegend(self.properties['font']['prop']['legendSize'])
00394         self.client.SetEnableLegend(self.properties['legend']['enabled'])
00395 
00396         if self.properties['x-axis']['prop']['log'] == True:
00397             self.properties['x-axis']['axis'] = None
00398             self.client.SetXSpec('min')
00399         if self.properties['y-axis']['prop']['log'] == True:
00400             self.properties['y-axis']['axis'] = None
00401             self.client.SetYSpec('min')
00402             
00403         self.client.setLogScale((self.properties['x-axis']['prop']['log'],
00404                                  self.properties['y-axis']['prop']['log']))
00405 
00406         # self.client.SetPointLabelFunc(self.DrawPointLabel())
00407 
00408     def CreateDatalist(self, raster, coords):
00409         """!Build a list of distance, value pairs for points along transect
00410         """
00411         datalist = []
00412         
00413         # keep total number of transect points to 500 or less to avoid 
00414         # freezing with large, high resolution maps
00415         region = grass.region()
00416         curr_res = min(float(region['nsres']),float(region['ewres']))
00417         transect_rec = 0
00418         if self.transect_length / curr_res > 500:
00419             transect_res = self.transect_length / 500
00420         else: transect_res = curr_res
00421         
00422         try:
00423             ret = gcmd.RunCommand("r.profile",
00424                              input=raster,
00425                              profile=coords,
00426                              res=transect_res,
00427                              null="nan",
00428                              quiet=True,
00429                              read = True)
00430             
00431             if not ret:
00432                 return dataset
00433             
00434             for line in ret.splitlines():
00435                 dist, elev = line.split(' ')
00436                 if elev != 'nan':
00437                     datalist.append((dist,elev))
00438 
00439             return datalist
00440         except gcmd.GException, e:
00441             gcmd.GError(parent = self,
00442                         message = e.value)
00443             return None
00444 
00445     def OnCreateProfile(self, event):
00446         """!Main routine for creating a profile. Uses r.profile to
00447         create a list of distance,cell value pairs. This is passed to
00448         plot to create a line graph of the profile. If the profile
00449         transect is in multiple segments, these are drawn as
00450         points. Profile transect is drawn, using methods in mapdisp.py
00451         """
00452     
00453         if len(self.mapwin.polycoords) == 0 or self.raster[0]['name'] == '':
00454             dlg = wx.MessageDialog(parent=self,
00455                                    message=_('You must draw a transect to profile in the map display window.'),
00456                                    caption=_('Nothing to profile'),
00457                                    style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
00458             dlg.ShowModal()
00459             dlg.Destroy()
00460             return
00461 
00462         self.mapwin.SetCursor(self.parent.cursors["default"])
00463         self.SetCursor(self.parent.cursors["default"])
00464         self.SetGraphStyle()
00465 
00466         self.SetRaster()
00467             
00468         self.DrawPlot()
00469 
00470         # reset transect
00471         self.mapwin.mouse['begin'] = self.mapwin.mouse['end'] = (0.0,0.0)
00472         self.mapwin.mouse['use'] = 'pointer'
00473         self.mapwin.mouse['box'] = 'point'
00474 
00475     def DrawPlot(self):
00476         """!Draw line and point plot from transect datalist and
00477         transect segment endpoint coordinates.
00478         """
00479         # graph the distance, value pairs for the transect
00480         self.plotlist = []
00481         if len(self.seglist) > 0 :
00482             self.ppoints = plot.PolyMarker(self.seglist,
00483                                            legend=' ' + self.properties['marker']['legend'],
00484                                            colour=wx.Color(self.properties['marker']['color'][0],
00485                                                            self.properties['marker']['color'][1],
00486                                                            self.properties['marker']['color'][2],
00487                                                            255),
00488                                            size=self.properties['marker']['size'],
00489                                            fillstyle=self.ptfilldict[self.properties['marker']['fill']],
00490                                            marker=self.properties['marker']['type'])
00491             self.plotlist.append(self.ppoints)
00492 
00493         for r in self.raster.itervalues():
00494             if len(r['datalist']) > 0:
00495                 col = wx.Color(r['prop']['pcolor'][0],
00496                                r['prop']['pcolor'][1],
00497                                r['prop']['pcolor'][2],
00498                                255)
00499                 r['pline'] = plot.PolyLine(r['datalist'],
00500                                            colour=col,
00501                                            width=r['prop']['pwidth'],
00502                                            style=self.pstyledict[r['prop']['pstyle']],
00503                                            legend=r['plegend'])
00504 
00505                 self.plotlist.append(r['pline'])
00506 
00507         self.profile = plot.PlotGraphics(self.plotlist,
00508                                          self.ptitle,
00509                                          self.xlabel,
00510                                          self.ylabel)
00511 
00512         if self.properties['x-axis']['prop']['type'] == 'custom':
00513             self.client.SetXSpec('min')
00514         else:
00515             self.client.SetXSpec(self.properties['x-axis']['prop']['type'])
00516 
00517         if self.properties['y-axis']['prop']['type'] == 'custom':
00518             self.client.SetYSpec('min')
00519         else:
00520             self.client.SetYSpec(self.properties['y-axis']['prop']['type'])
00521 
00522         self.client.Draw(self.profile, self.properties['x-axis']['axis'],
00523                          self.properties['y-axis']['axis'])
00524 
00525     def OnZoom(self, event):
00526         """!Enable zooming and disable dragging
00527         """
00528         self.zoom = True
00529         self.drag = False
00530         self.client.SetEnableZoom(self.zoom)
00531         self.client.SetEnableDrag(self.drag)
00532 
00533     def OnDrag(self, event):
00534         """!Enable dragging and disable zooming
00535         """
00536         self.zoom = False
00537         self.drag = True
00538         self.client.SetEnableDrag(self.drag)
00539         self.client.SetEnableZoom(self.zoom)
00540 
00541     def OnRedraw(self, event):
00542         """!Redraw the profile window. Unzoom to original size
00543         """
00544         self.client.Reset()
00545         self.client.Redraw()
00546 
00547     def Update(self):
00548         """!Update profile after changing options
00549         """
00550         self.SetGraphStyle()
00551         self.DrawPlot()
00552 
00553     def OnErase(self, event):
00554         """!Erase the profile window
00555         """
00556         self.client.Clear()
00557         self.mapwin.ClearLines(self.mapwin.pdc)
00558         self.mapwin.ClearLines(self.mapwin.pdcTmp)
00559         self.mapwin.polycoords = []
00560         self.mapwin.Refresh()
00561         #        try:
00562         #            self.mapwin.pdc.ClearId(self.mapwin.lineid)
00563         #            self.mapwin.pdc.ClearId(self.mapwin.plineid)
00564         #            self.mapwin.Refresh()
00565         #        except:
00566         #            pass
00567 
00568     def SaveToFile(self, event):
00569         """!Save profile to graphics file
00570         """
00571         self.client.SaveFile()
00572 
00573     def SaveProfileToFile(self, event):
00574         """!Save r.profile data to a csv file
00575         """    
00576         wildcard = _("Comma separated value (*.csv)|*.csv")
00577         
00578         dlg = wx.FileDialog(
00579             self, message=_("Path and prefix (for raster name) to save profile values..."),
00580             defaultDir=os.getcwd(), 
00581             defaultFile="",  wildcard=wildcard, style=wx.SAVE
00582             )
00583         if dlg.ShowModal() == wx.ID_OK:
00584             path = dlg.GetPath()
00585             
00586             for r in self.raster.itervalues():
00587                 if r['name'] == '':
00588                     continue
00589 
00590                 print 'path = '+str(path)
00591                 pfile = path+'_'+str(r['name'])+'.csv'
00592                 print 'pfile1 = '+str(pfile)
00593                 try:
00594                     file = open(pfile, "w")
00595                 except IOError:
00596                     wx.MessageBox(parent=self,
00597                                   message=_("Unable to open file <%s> for writing.") % pfile,
00598                                   caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
00599                     return False
00600                 for datapair in r['datalist']:
00601                     file.write('%d,%d\n' % (float(datapair[0]),float(datapair[1])))
00602                                         
00603                 file.close()
00604 
00605         dlg.Destroy()
00606     
00607     def DrawPointLabel(self, dc, mDataDict):
00608         """!This is the fuction that defines how the pointLabels are
00609             plotted dc - DC that will be passed mDataDict - Dictionary
00610             of data that you want to use for the pointLabel
00611 
00612             As an example I have decided I want a box at the curve
00613             point with some text information about the curve plotted
00614             below.  Any wxDC method can be used.
00615         """
00616         dc.SetPen(wx.Pen(wx.BLACK))
00617         dc.SetBrush(wx.Brush( wx.BLACK, wx.SOLID ) )
00618 
00619         sx, sy = mDataDict["scaledXY"] #scaled x,y of closest point
00620         dc.DrawRectangle( sx-5,sy-5, 10, 10)  #10by10 square centered on point
00621         px,py = mDataDict["pointXY"]
00622         cNum = mDataDict["curveNum"]
00623         pntIn = mDataDict["pIndex"]
00624         legend = mDataDict["legend"]
00625         #make a string to display
00626         s = "Crv# %i, '%s', Pt. (%.2f,%.2f), PtInd %i" %(cNum, legend, px, py, pntIn)
00627         dc.DrawText(s, sx , sy+1)
00628 
00629     def OnMouseLeftDown(self,event):
00630         s= "Left Mouse Down at Point: (%.4f, %.4f)" % self.client._getXY(event)
00631         self.SetStatusText(s)
00632         event.Skip()            #allows plotCanvas OnMouseLeftDown to be called
00633 
00634     def OnMotion(self, event):
00635         # indicate when mouse is outside the plot area
00636         if self.client.OnLeave(event): print 'out of area'
00637         #show closest point (when enbled)
00638         if self.client.GetEnablePointLabel() == True:
00639             #make up dict with info for the pointLabel
00640             #I've decided to mark the closest point on the closest curve
00641             dlst= self.client.GetClosetPoint( self.client._getXY(event), pointScaled= True)
00642             if dlst != []:      #returns [] if none
00643                 curveNum, legend, pIndex, pointXY, scaledXY, distance = dlst
00644                 #make up dictionary to pass to my user function (see DrawPointLabel)
00645                 mDataDict= {"curveNum":curveNum, "legend":legend, "pIndex":pIndex,\
00646                     "pointXY":pointXY, "scaledXY":scaledXY}
00647                 #pass dict to update the pointLabel
00648                 self.client.UpdatePointLabel(mDataDict)
00649         event.Skip()           #go to next handler
00650 
00651     def ProfileOptionsMenu(self, event):
00652         """!Popup menu for profile and text options
00653         """
00654         point = wx.GetMousePosition()
00655         popt = wx.Menu()
00656         # Add items to the menu
00657         settext = wx.MenuItem(popt, -1, 'Profile text settings')
00658         popt.AppendItem(settext)
00659         self.Bind(wx.EVT_MENU, self.PText, settext)
00660 
00661         setgrid = wx.MenuItem(popt, -1, 'Profile plot settings')
00662         popt.AppendItem(setgrid)
00663         self.Bind(wx.EVT_MENU, self.POptions, setgrid)
00664 
00665         # Popup the menu.  If an item is selected then its handler
00666         # will be called before PopupMenu returns.
00667         self.PopupMenu(popt)
00668         popt.Destroy()
00669 
00670     def NotFunctional(self):
00671         """!Creates a 'not functional' message dialog
00672         """
00673         dlg = wx.MessageDialog(parent = self,
00674                                message = _('This feature is not yet functional'),
00675                                caption = _('Under Construction'),
00676                                style = wx.OK | wx.ICON_INFORMATION)
00677         dlg.ShowModal()
00678         dlg.Destroy()
00679 
00680     def OnPText(self, dlg):
00681         """!Use user's provided profile text settings.
00682         """
00683         self.ptitle = dlg.ptitle
00684         self.xlabel = dlg.xlabel
00685         self.ylabel = dlg.ylabel
00686         dlg.UpdateSettings()
00687 
00688         self.client.SetFont(self.properties['font']['wxfont'])
00689         self.client.SetFontSizeTitle(self.properties['font']['prop']['titleSize'])
00690         self.client.SetFontSizeAxis(self.properties['font']['prop']['axisSize'])
00691 
00692         if self.profile:
00693             self.profile.setTitle(dlg.ptitle)
00694             self.profile.setXLabel(dlg.xlabel)
00695             self.profile.setYLabel(dlg.ylabel)
00696         
00697         self.OnRedraw(event=None)
00698     
00699     def PText(self, event):
00700         """!Set custom text values for profile title and axis labels.
00701         """
00702         dlg = TextDialog(parent=self, id=wx.ID_ANY, title=_('Profile text settings'))
00703 
00704         if dlg.ShowModal() == wx.ID_OK:
00705             self.OnPText(dlg)
00706 
00707         dlg.Destroy()
00708 
00709     def POptions(self, event):
00710         """!Set various profile options, including: line width, color,
00711         style; marker size, color, fill, and style; grid and legend
00712         options.  Calls OptDialog class.
00713         """
00714         dlg = OptDialog(parent=self, id=wx.ID_ANY, title=_('Profile settings'))
00715         btnval = dlg.ShowModal()
00716 
00717         if btnval == wx.ID_SAVE:
00718             dlg.UpdateSettings()            
00719             self.SetGraphStyle()            
00720             dlg.Destroy()            
00721         elif btnval == wx.ID_CANCEL:
00722             dlg.Destroy()
00723 
00724     def PrintMenu(self, event):
00725         """!Print options and output menu
00726         """
00727         point = wx.GetMousePosition()
00728         printmenu = wx.Menu()
00729         # Add items to the menu
00730         setup = wx.MenuItem(printmenu, -1,'Page setup')
00731         printmenu.AppendItem(setup)
00732         self.Bind(wx.EVT_MENU, self.OnPageSetup, setup)
00733 
00734         preview = wx.MenuItem(printmenu, -1,'Print preview')
00735         printmenu.AppendItem(preview)
00736         self.Bind(wx.EVT_MENU, self.OnPrintPreview, preview)
00737 
00738         doprint = wx.MenuItem(printmenu, -1,'Print display')
00739         printmenu.AppendItem(doprint)
00740         self.Bind(wx.EVT_MENU, self.OnDoPrint, doprint)
00741 
00742         # Popup the menu.  If an item is selected then its handler
00743         # will be called before PopupMenu returns.
00744         self.PopupMenu(printmenu)
00745         printmenu.Destroy()
00746 
00747     def OnPageSetup(self, event):
00748         self.client.PageSetup()
00749 
00750     def OnPrintPreview(self, event):
00751         self.client.PrintPreview()
00752 
00753     def OnDoPrint(self, event):
00754         self.client.Printout()
00755 
00756     def OnQuit(self, event):
00757         self.Close(True)
00758 
00759     def OnCloseWindow(self, event):
00760         """
00761         Close profile window and clean up
00762         """
00763         self.mapwin.ClearLines()
00764         self.mapwin.mouse['begin'] = self.mapwin.mouse['end'] = (0.0, 0.0)
00765         self.mapwin.mouse['use'] = 'pointer'
00766         self.mapwin.mouse['box'] = 'point'
00767         self.mapwin.polycoords = []
00768         self.mapwin.SetCursor(self.Parent.cursors["default"])
00769 
00770         self.mapwin.UpdateMap(render=False, renderVector=False)
00771 
00772         self.Destroy()
00773 
00774 class SetRasterDialog(wx.Dialog):
00775     def __init__(self, parent, id=wx.ID_ANY, title=_("Select raster map to profile"),
00776                  pos=wx.DefaultPosition, size=wx.DefaultSize,
00777                  style=wx.DEFAULT_DIALOG_STYLE):
00778         """!Dialog to select raster maps to profile.
00779         """
00780 
00781         wx.Dialog.__init__(self, parent, id, title, pos, size, style)
00782 
00783         self.parent = parent
00784         self.coordstr = self.parent.coordstr
00785 
00786         #         if self.coordstr == '':
00787         #             dlg = wx.MessageDialog(parent=self,
00788         #                                    message=_('You must draw a transect to profile in the map display window.'),
00789         #                                    caption=_('Nothing to profile'),
00790         #                                    style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
00791         #             dlg.ShowModal()
00792         #             dlg.Destroy()
00793         #             self.Close(True)
00794         #             return
00795 
00796         self.raster = { 0 : { 'name' : self.parent.raster[0]['name'],
00797                               'id' : None },
00798                         1 : { 'name' : self.parent.raster[1]['name'],
00799                               'id' : None },
00800                         2 : { 'name' : self.parent.raster[2]['name'],
00801                               'id' : None }
00802                         }
00803 
00804         sizer = wx.BoxSizer(wx.VERTICAL)
00805 
00806         box = wx.GridBagSizer (hgap=3, vgap=3)
00807         
00808         i = 0
00809         for txt in [_("Select raster map 1 (required):"),
00810                     _("Select raster map 2 (optional):"),
00811                     _("Select raster map 3 (optional):")]:
00812             label = wx.StaticText(parent=self, id=wx.ID_ANY, label=txt)
00813             box.Add(item=label,
00814                     flag=wx.ALIGN_CENTER_VERTICAL, pos=(i, 0))
00815             
00816             selection = gselect.Select(self, id=wx.ID_ANY,
00817                                        size=globalvar.DIALOG_GSELECT_SIZE,
00818                                        type='cell')
00819             selection.SetValue(str(self.raster[i]['name']))
00820             self.raster[i]['id'] = selection.GetChildren()[0].GetId()
00821             selection.Bind(wx.EVT_TEXT, self.OnSelection)
00822             
00823             box.Add(item=selection, pos=(i, 1))
00824             
00825             i += 1 
00826             
00827         sizer.Add(item=box, proportion=0,
00828                   flag=wx.ALL, border=10)
00829 
00830         line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20, -1), style=wx.LI_HORIZONTAL)
00831         sizer.Add(item=line, proportion=0,
00832                   flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border=5)
00833 
00834         btnsizer = wx.StdDialogButtonSizer()
00835 
00836         btn = wx.Button(self, wx.ID_OK)
00837         btn.SetDefault()
00838         btnsizer.AddButton(btn)
00839 
00840         btn = wx.Button(self, wx.ID_CANCEL)
00841         btnsizer.AddButton(btn)
00842         btnsizer.Realize()
00843 
00844         sizer.Add(item=btnsizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
00845 
00846         self.SetSizer(sizer)
00847         sizer.Fit(self)
00848 
00849     def OnSelection(self, event):
00850         id = event.GetId()
00851         for r in self.raster.itervalues():
00852             if r['id'] == id:
00853                 r['name'] = event.GetString()
00854                 break
00855 
00856 class TextDialog(wx.Dialog):
00857     def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize,
00858                  style=wx.DEFAULT_DIALOG_STYLE):
00859         """!Dialog to set profile text options: font, title
00860         and font size, axis labels and font size
00861         """
00862         wx.Dialog.__init__(self, parent, id, title, pos, size, style)
00863         #
00864         # initialize variables
00865         #
00866         # combo box entry lists
00867         self.ffamilydict = { 'default' : wx.FONTFAMILY_DEFAULT,
00868                              'decorative' : wx.FONTFAMILY_DECORATIVE,
00869                              'roman' : wx.FONTFAMILY_ROMAN,
00870                              'script' : wx.FONTFAMILY_SCRIPT,
00871                              'swiss' : wx.FONTFAMILY_SWISS,
00872                              'modern' : wx.FONTFAMILY_MODERN,
00873                              'teletype' : wx.FONTFAMILY_TELETYPE }
00874 
00875         self.fstyledict = { 'normal' : wx.FONTSTYLE_NORMAL,
00876                             'slant' : wx.FONTSTYLE_SLANT,
00877                             'italic' : wx.FONTSTYLE_ITALIC }
00878 
00879         self.fwtdict = { 'normal' : wx.FONTWEIGHT_NORMAL,
00880                          'light' : wx.FONTWEIGHT_LIGHT,
00881                          'bold' : wx.FONTWEIGHT_BOLD }
00882 
00883         self.parent = parent
00884 
00885         self.ptitle = self.parent.ptitle
00886         self.xlabel = self.parent.xlabel
00887         self.ylabel = self.parent.ylabel
00888 
00889         self.properties = self.parent.properties # read-only
00890         
00891         # font size
00892         self.fontfamily = self.properties['font']['wxfont'].GetFamily()
00893         self.fontstyle = self.properties['font']['wxfont'].GetStyle()
00894         self.fontweight = self.properties['font']['wxfont'].GetWeight()
00895 
00896         self._do_layout()
00897         
00898     def _do_layout(self):
00899         """!Do layout"""
00900         # dialog layout
00901         sizer = wx.BoxSizer(wx.VERTICAL)
00902 
00903         box = wx.StaticBox(parent=self, id=wx.ID_ANY,
00904                            label=" %s " % _("Text settings"))
00905         boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
00906         gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
00907 
00908         #
00909         # profile title
00910         #
00911         label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Profile title:"))
00912         gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 0))
00913         self.ptitleentry = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(250,-1))
00914         # self.ptitleentry.SetFont(self.font)
00915         self.ptitleentry.SetValue(self.ptitle)
00916         gridSizer.Add(item=self.ptitleentry, pos=(0, 1))
00917 
00918         #
00919         # title font
00920         #
00921         tlabel = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Title font size (pts):"))
00922         gridSizer.Add(item=tlabel, flag=wx.ALIGN_CENTER_VERTICAL, pos=(1, 0))
00923         self.ptitlesize = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="", pos=(30, 50),
00924                                       size=(50,-1), style=wx.SP_ARROW_KEYS)
00925         self.ptitlesize.SetRange(5,100)
00926         self.ptitlesize.SetValue(int(self.properties['font']['prop']['titleSize']))
00927         gridSizer.Add(item=self.ptitlesize, pos=(1, 1))
00928 
00929         #
00930         # x-axis label
00931         #
00932         label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("X-axis label:"))
00933         gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(2, 0))
00934         self.xlabelentry = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(250,-1))
00935         # self.xlabelentry.SetFont(self.font)
00936         self.xlabelentry.SetValue(self.xlabel)
00937         gridSizer.Add(item=self.xlabelentry, pos=(2, 1))
00938 
00939         #
00940         # y-axis label
00941         #
00942         label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Y-axis label:"))
00943         gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(3, 0))
00944         self.ylabelentry = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(250,-1))
00945         # self.ylabelentry.SetFont(self.font)
00946         self.ylabelentry.SetValue(self.ylabel)
00947         gridSizer.Add(item=self.ylabelentry, pos=(3, 1))
00948 
00949         #
00950         # font size
00951         #
00952         llabel = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Label font size (pts):"))
00953         gridSizer.Add(item=llabel, flag=wx.ALIGN_CENTER_VERTICAL, pos=(4, 0))
00954         self.axislabelsize = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="", pos=(30, 50),
00955                                          size=(50, -1), style=wx.SP_ARROW_KEYS)
00956         self.axislabelsize.SetRange(5, 100) 
00957         self.axislabelsize.SetValue(int(self.properties['font']['prop']['axisSize']))
00958         gridSizer.Add(item=self.axislabelsize, pos=(4,1))
00959 
00960         boxSizer.Add(item=gridSizer)
00961         sizer.Add(item=boxSizer, flag=wx.ALL | wx.EXPAND, border=3)
00962 
00963         #
00964         # font settings
00965         #
00966         box = wx.StaticBox(parent=self, id=wx.ID_ANY,
00967                            label=" %s " % _("Font settings"))
00968         boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
00969         gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
00970         gridSizer.AddGrowableCol(1)
00971 
00972         #
00973         # font family
00974         #
00975         label1 = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Font family:"))
00976         gridSizer.Add(item=label1, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 0))
00977         self.ffamilycb = wx.ComboBox(parent=self, id=wx.ID_ANY, size=(250, -1),
00978                                 choices=self.ffamilydict.keys(), style=wx.CB_DROPDOWN)
00979         self.ffamilycb.SetStringSelection('swiss')
00980         for item in self.ffamilydict.items():
00981             if self.fontfamily == item[1]:
00982                 self.ffamilycb.SetStringSelection(item[0])
00983                 break
00984         gridSizer.Add(item=self.ffamilycb, pos=(0, 1), flag=wx.ALIGN_RIGHT)
00985 
00986         #
00987         # font style
00988         #
00989         label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Style:"))
00990         gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(1, 0))
00991         self.fstylecb = wx.ComboBox(parent=self, id=wx.ID_ANY, size=(250, -1),
00992                                     choices=self.fstyledict.keys(), style=wx.CB_DROPDOWN)
00993         self.fstylecb.SetStringSelection('normal')
00994         for item in self.fstyledict.items():
00995             if self.fontstyle == item[1]:
00996                 self.fstylecb.SetStringSelection(item[0])
00997                 break
00998         gridSizer.Add(item=self.fstylecb, pos=(1, 1), flag=wx.ALIGN_RIGHT)
00999 
01000         #
01001         # font weight
01002         #
01003         label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Weight:"))
01004         gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(2, 0))
01005         self.fwtcb = wx.ComboBox(parent=self, size=(250, -1),
01006                                  choices=self.fwtdict.keys(), style=wx.CB_DROPDOWN)
01007         self.fwtcb.SetStringSelection('normal')
01008         for item in self.fwtdict.items():
01009             if self.fontweight == item[1]:
01010                 self.fwtcb.SetStringSelection(item[0])
01011                 break
01012 
01013         gridSizer.Add(item=self.fwtcb, pos=(2, 1), flag=wx.ALIGN_RIGHT)
01014                       
01015         boxSizer.Add(item=gridSizer, flag=wx.EXPAND)
01016         sizer.Add(item=boxSizer, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
01017 
01018         line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20, -1), style=wx.LI_HORIZONTAL)
01019         sizer.Add(item=line, proportion=0,
01020                   flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border=3)
01021 
01022         #
01023         # buttons
01024         #
01025         btnSave = wx.Button(self, wx.ID_SAVE)
01026         btnApply = wx.Button(self, wx.ID_APPLY)
01027         btnOk = wx.Button(self, wx.ID_OK)
01028         btnCancel = wx.Button(self, wx.ID_CANCEL)
01029         btnOk.SetDefault()
01030 
01031         # bindigs
01032         btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
01033         btnApply.SetToolTipString(_("Apply changes for the current session"))
01034         btnOk.Bind(wx.EVT_BUTTON, self.OnOk)
01035         btnOk.SetToolTipString(_("Apply changes for the current session and close dialog"))
01036         btnOk.SetDefault()
01037         btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
01038         btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
01039         btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
01040         btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
01041 
01042         # sizers
01043         btnStdSizer = wx.StdDialogButtonSizer()
01044         btnStdSizer.AddButton(btnOk)
01045         btnStdSizer.AddButton(btnApply)
01046         btnStdSizer.AddButton(btnCancel)
01047         btnStdSizer.Realize()
01048         
01049         btnSizer = wx.BoxSizer(wx.HORIZONTAL)
01050         btnSizer.Add(item=btnSave, proportion=0, flag=wx.ALIGN_LEFT | wx.ALL, border=5)
01051         btnSizer.Add(item=btnStdSizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
01052         sizer.Add(item=btnSizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
01053 
01054         #
01055         # bindings
01056         #
01057         self.ptitleentry.Bind(wx.EVT_TEXT, self.OnTitle)
01058         self.xlabelentry.Bind(wx.EVT_TEXT, self.OnXLabel)
01059         self.ylabelentry.Bind(wx.EVT_TEXT, self.OnYLabel)
01060 
01061         self.SetSizer(sizer)
01062         sizer.Fit(self)
01063 
01064     def OnTitle(self, event):
01065         self.ptitle = event.GetString()
01066 
01067     def OnXLabel(self, event):
01068         self.xlabel = event.GetString()
01069 
01070     def OnYLabel(self, event):
01071         self.ylabel = event.GetString()
01072 
01073     def UpdateSettings(self):
01074         self.properties['font']['prop']['titleSize'] = self.ptitlesize.GetValue()
01075         self.properties['font']['prop']['axisSize'] = self.axislabelsize.GetValue()
01076 
01077         family = self.ffamilydict[self.ffamilycb.GetStringSelection()]
01078         self.properties['font']['wxfont'].SetFamily(family)
01079         style = self.fstyledict[self.fstylecb.GetStringSelection()]
01080         self.properties['font']['wxfont'].SetStyle(style)
01081         weight = self.fwtdict[self.fwtcb.GetStringSelection()]
01082         self.properties['font']['wxfont'].SetWeight(weight)
01083 
01084     def OnSave(self, event):
01085         """!Button 'Save' pressed"""
01086         self.UpdateSettings()
01087         fileSettings = {}
01088         UserSettings.ReadSettingsFile(settings=fileSettings)
01089         fileSettings['profile'] = UserSettings.Get(group='profile')
01090         file = UserSettings.SaveToFile(fileSettings)
01091         self.parent.parent.GetLayerManager().goutput.WriteLog(_('Profile settings saved to file \'%s\'.') % file)
01092         self.EndModal(wx.ID_OK)
01093 
01094     def OnApply(self, event):
01095         """!Button 'Apply' pressed"""
01096         self.UpdateSettings()
01097         self.parent.OnPText(self)
01098         
01099     def OnOk(self, event):
01100         """!Button 'OK' pressed"""
01101         self.UpdateSettings()
01102         self.EndModal(wx.ID_OK)
01103 
01104     def OnCancel(self, event):
01105         """!Button 'Cancel' pressed"""
01106         self.EndModal(wx.ID_CANCEL)
01107         
01108 class OptDialog(wx.Dialog):
01109     def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize,
01110                  style=wx.DEFAULT_DIALOG_STYLE): 
01111         """!Dialog to set various profile options, including: line
01112         width, color, style; marker size, color, fill, and style; grid
01113         and legend options.
01114         """
01115         wx.Dialog.__init__(self, parent, id, title, pos, size, style)
01116         # init variables
01117         self.pstyledict = parent.pstyledict
01118         self.ptfilldict = parent.ptfilldict
01119 
01120         self.pttypelist = ['circle',
01121                            'dot',
01122                            'square',
01123                            'triangle',
01124                            'triangle_down',
01125                            'cross',
01126                            'plus']
01127         
01128         self.axislist = ['min',
01129                          'auto',
01130                          'custom']
01131 
01132         # widgets ids
01133         self.wxId = {}
01134         
01135         self.parent = parent
01136 
01137         # read-only
01138         self.raster = self.parent.raster
01139         self.properties = self.parent.properties
01140         
01141         self._do_layout()
01142 
01143     def _do_layout(self):
01144         """!Do layout"""
01145         # dialog layout
01146         sizer = wx.BoxSizer(wx.VERTICAL)
01147 
01148         #
01149         # profile line settings
01150         #
01151         box = wx.StaticBox(parent=self, id=wx.ID_ANY,
01152                            label=" %s " % _("Profile line settings"))
01153         boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
01154 
01155         idx = 1
01156         self.wxId['pcolor'] = []
01157         self.wxId['pwidth'] = []
01158         self.wxId['pstyle'] = []
01159         self.wxId['plegend'] = []
01160         for r in self.raster.itervalues():
01161             box = wx.StaticBox(parent=self, id=wx.ID_ANY,
01162                                label=" %s %d " % (_("Profile"), idx))
01163             boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
01164             
01165             gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
01166             row = 0            
01167             label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Line color"))
01168             gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
01169             pcolor = csel.ColourSelect(parent=self, id=wx.ID_ANY, colour=r['prop']['pcolor'])
01170             self.wxId['pcolor'].append(pcolor.GetId())
01171             gridSizer.Add(item=pcolor, pos=(row, 1))
01172 
01173             row += 1
01174             label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Line width"))
01175             gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
01176             pwidth = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="",
01177                                  size=(50,-1), style=wx.SP_ARROW_KEYS)
01178             pwidth.SetRange(1, 10)
01179             pwidth.SetValue(r['prop']['pwidth'])
01180             self.wxId['pwidth'].append(pwidth.GetId())
01181             gridSizer.Add(item=pwidth, pos=(row, 1))
01182 
01183             row +=1
01184             label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Line style"))
01185             gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
01186             pstyle = wx.ComboBox(parent=self, id=wx.ID_ANY, 
01187                                  size=(120, -1), choices=self.pstyledict.keys(), style=wx.CB_DROPDOWN)
01188             pstyle.SetStringSelection(r['prop']['pstyle'])
01189             self.wxId['pstyle'].append(pstyle.GetId())
01190             gridSizer.Add(item=pstyle, pos=(row, 1))
01191 
01192             row += 1
01193             label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Legend"))
01194             gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
01195             plegend = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(200,-1))
01196             plegend.SetValue(r['plegend'])
01197             gridSizer.Add(item=plegend, pos=(row, 1))
01198             self.wxId['plegend'].append(plegend.GetId())
01199             boxSizer.Add(item=gridSizer)
01200 
01201             if idx == 0:
01202                 flag = wx.ALL
01203             else:
01204                 flag = wx.TOP | wx.BOTTOM | wx.RIGHT
01205             boxMainSizer.Add(item=boxSizer, flag=flag, border=3)
01206 
01207             idx += 1
01208             
01209         sizer.Add(item=boxMainSizer, flag=wx.ALL | wx.EXPAND, border=3)
01210 
01211         middleSizer = wx.BoxSizer(wx.HORIZONTAL)
01212         
01213         #
01214         # segment marker settings
01215         #
01216         box = wx.StaticBox(parent=self, id=wx.ID_ANY,
01217                            label=" %s " % _("Transect segment marker settings"))
01218         boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
01219 
01220         self.wxId['marker'] = {}
01221         gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
01222         label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Color"))
01223         gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 0))
01224         ptcolor = csel.ColourSelect(parent=self, id=wx.ID_ANY, colour=self.properties['marker']['color'])
01225         self.wxId['marker']['color'] = ptcolor.GetId()
01226         gridSizer.Add(item=ptcolor, pos=(0, 1))
01227 
01228         label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Size"))
01229         gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(1, 0))
01230         ptsize = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="",
01231                              size=(50, -1), style=wx.SP_ARROW_KEYS)
01232         ptsize.SetRange(1, 10)
01233         ptsize.SetValue(self.properties['marker']['size'])
01234         self.wxId['marker']['size'] = ptsize.GetId()
01235         gridSizer.Add(item=ptsize, pos=(1, 1))
01236         
01237         label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Style"))
01238         gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(2, 0))
01239         ptfill = wx.ComboBox(parent=self, id=wx.ID_ANY,
01240                              size=(120, -1), choices=self.ptfilldict.keys(), style=wx.CB_DROPDOWN)
01241         ptfill.SetStringSelection(self.properties['marker']['fill'])
01242         self.wxId['marker']['fill'] = ptfill.GetId()
01243         gridSizer.Add(item=ptfill, pos=(2, 1))
01244         
01245         label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Legend"))
01246         gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(3, 0))
01247         ptlegend = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(200,-1))
01248         ptlegend.SetValue(self.properties['marker']['legend'])
01249         self.wxId['marker']['legend'] = ptlegend.GetId()
01250         gridSizer.Add(item=ptlegend, pos=(3, 1))
01251                 
01252         label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Type"))
01253         gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(4, 0))
01254         pttype = wx.ComboBox(parent=self, 
01255                              size=(200, -1), choices=self.pttypelist, style=wx.CB_DROPDOWN)
01256         pttype.SetStringSelection(self.properties['marker']['type'])
01257         self.wxId['marker']['type'] = pttype.GetId()
01258         gridSizer.Add(item=pttype, pos=(4, 1))
01259 
01260         boxMainSizer.Add(item=gridSizer, flag=wx.ALL, border=3)
01261         middleSizer.Add(item=boxMainSizer, flag=wx.ALL | wx.EXPAND, border=3)
01262 
01263         #
01264         # axis options
01265         #
01266         box = wx.StaticBox(parent=self, id=wx.ID_ANY,
01267                            label=" %s " % _("Axis settings"))
01268         boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
01269 
01270         self.wxId['x-axis'] = {}
01271         self.wxId['y-axis'] = {}
01272         idx = 0
01273         for axis, atype in [(_("X-Axis"), 'x-axis'),
01274                      (_("Y-Axis"), 'y-axis')]:
01275             box = wx.StaticBox(parent=self, id=wx.ID_ANY,
01276                                label=" %s " % axis)
01277             boxSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
01278             gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
01279 
01280             prop = self.properties[atype]['prop']
01281             
01282             row = 0
01283             label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Style"))
01284             gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
01285             type = wx.ComboBox(parent=self, id=wx.ID_ANY,
01286                                size=(100, -1), choices=self.axislist, style=wx.CB_DROPDOWN)
01287             type.SetStringSelection(prop['type']) 
01288             self.wxId[atype]['type'] = type.GetId()
01289             gridSizer.Add(item=type, pos=(row, 1))
01290             
01291             row += 1
01292             label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Custom min"))
01293             gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
01294             min = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(70, -1))
01295             min.SetValue(str(prop['min']))
01296             self.wxId[atype]['min'] = min.GetId()
01297             gridSizer.Add(item=min, pos=(row, 1))
01298 
01299             row += 1
01300             label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Custom max"))
01301             gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
01302             max = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(70, -1))
01303             max.SetValue(str(prop['max']))
01304             self.wxId[atype]['max'] = max.GetId()
01305             gridSizer.Add(item=max, pos=(row, 1))
01306             
01307             row += 1
01308             log = wx.CheckBox(parent=self, id=wx.ID_ANY, label=_("Log scale"))
01309             log.SetValue(prop['log'])
01310             self.wxId[atype]['log'] = log.GetId()
01311             gridSizer.Add(item=log, pos=(row, 0), span=(1, 2))
01312 
01313             if idx == 0:
01314                 flag = wx.ALL | wx.EXPAND
01315             else:
01316                 flag = wx.TOP | wx.BOTTOM | wx.RIGHT | wx.EXPAND
01317 
01318             boxSizer.Add(item=gridSizer, flag=wx.ALL, border=3)
01319             boxMainSizer.Add(item=boxSizer, flag=flag, border=3)
01320 
01321             idx += 1
01322             
01323         middleSizer.Add(item=boxMainSizer, flag=wx.ALL | wx.EXPAND, border=3)
01324 
01325         #
01326         # grid & legend options
01327         #
01328         self.wxId['grid'] = {}
01329         self.wxId['legend'] = {}
01330         self.wxId['font'] = {}
01331         box = wx.StaticBox(parent=self, id=wx.ID_ANY,
01332                            label=" %s " % _("Grid and Legend settings"))
01333         boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
01334         gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
01335 
01336         row = 0
01337         label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Grid color"))
01338         gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
01339         gridcolor = csel.ColourSelect(parent=self, id=wx.ID_ANY, colour=self.properties['grid']['color'])
01340         self.wxId['grid']['color'] = gridcolor.GetId()
01341         gridSizer.Add(item=gridcolor, pos=(row, 1))
01342 
01343         row +=1
01344         gridshow = wx.CheckBox(parent=self, id=wx.ID_ANY, label=_("Show grid"))
01345         gridshow.SetValue(self.properties['grid']['enabled'])
01346         self.wxId['grid']['enabled'] = gridshow.GetId()
01347         gridSizer.Add(item=gridshow, pos=(row, 0), span=(1, 2))
01348 
01349         row +=1
01350         label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Legend font size"))
01351         gridSizer.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(row, 0))
01352         legendfontsize = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="", 
01353                                      size=(50, -1), style=wx.SP_ARROW_KEYS)
01354         legendfontsize.SetRange(5,100)
01355         legendfontsize.SetValue(int(self.properties['font']['prop']['legendSize']))
01356         self.wxId['font']['legendSize'] = legendfontsize.GetId()
01357         gridSizer.Add(item=legendfontsize, pos=(row, 1))
01358 
01359         row += 1
01360         legendshow = wx.CheckBox(parent=self, id=wx.ID_ANY, label=_("Show legend"))
01361         legendshow.SetValue(self.properties['legend']['enabled'])
01362         self.wxId['legend']['enabled'] = legendshow.GetId()
01363         gridSizer.Add(item=legendshow, pos=(row, 0), span=(1, 2))
01364 
01365         boxMainSizer.Add(item=gridSizer, flag=flag, border=3)
01366 
01367         middleSizer.Add(item=boxMainSizer, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
01368 
01369         sizer.Add(item=middleSizer, flag=wx.ALL, border=0)
01370         
01371         #
01372         # line & buttons
01373         #
01374         line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20, -1), style=wx.LI_HORIZONTAL)
01375         sizer.Add(item=line, proportion=0,
01376                   flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border=3)
01377 
01378         #
01379         # buttons
01380         #
01381         btnSave = wx.Button(self, wx.ID_SAVE)
01382         btnApply = wx.Button(self, wx.ID_APPLY)
01383         btnCancel = wx.Button(self, wx.ID_CANCEL)
01384         btnSave.SetDefault()
01385 
01386         # bindigs
01387         btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
01388         btnApply.SetToolTipString(_("Apply changes for the current session"))
01389         btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
01390         btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
01391         btnSave.SetDefault()
01392         btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
01393         btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
01394 
01395         # sizers
01396         btnStdSizer = wx.StdDialogButtonSizer()
01397         btnStdSizer.AddButton(btnCancel)
01398         btnStdSizer.AddButton(btnSave)
01399         btnStdSizer.AddButton(btnApply)
01400         btnStdSizer.Realize()
01401         
01402         sizer.Add(item=btnStdSizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
01403 
01404         self.SetSizer(sizer)
01405         sizer.Fit(self)
01406 
01407     def UpdateSettings(self):
01408         idx = 0
01409         for r in self.raster.itervalues():
01410             r['prop']['pcolor'] = self.FindWindowById(self.wxId['pcolor'][idx]).GetColour()
01411             r['prop']['pwidth'] = int(self.FindWindowById(self.wxId['pwidth'][idx]).GetValue())
01412             r['prop']['pstyle'] = self.FindWindowById(self.wxId['pstyle'][idx]).GetStringSelection()
01413             r['plegend'] = self.FindWindowById(self.wxId['plegend'][idx]).GetValue()
01414             idx +=1
01415 
01416         self.properties['marker']['color'] = self.FindWindowById(self.wxId['marker']['color']).GetColour()
01417         self.properties['marker']['fill'] = self.FindWindowById(self.wxId['marker']['fill']).GetStringSelection()
01418         self.properties['marker']['size'] = self.FindWindowById(self.wxId['marker']['size']).GetValue()
01419         self.properties['marker']['type'] = self.FindWindowById(self.wxId['marker']['type']).GetValue()
01420         self.properties['marker']['legend'] = self.FindWindowById(self.wxId['marker']['legend']).GetValue()
01421 
01422         for axis in ('x-axis', 'y-axis'):
01423             self.properties[axis]['prop']['type'] = self.FindWindowById(self.wxId[axis]['type']).GetValue()
01424             self.properties[axis]['prop']['min'] = float(self.FindWindowById(self.wxId[axis]['min']).GetValue())
01425             self.properties[axis]['prop']['max'] = float(self.FindWindowById(self.wxId[axis]['max']).GetValue())
01426             self.properties[axis]['prop']['log'] = self.FindWindowById(self.wxId[axis]['log']).IsChecked()
01427 
01428         self.properties['grid']['color'] = self.FindWindowById(self.wxId['grid']['color']).GetColour()
01429         self.properties['grid']['enabled'] = self.FindWindowById(self.wxId['grid']['enabled']).IsChecked()
01430 
01431         self.properties['font']['prop']['legendSize'] = self.FindWindowById(self.wxId['font']['legendSize']).GetValue()
01432         self.properties['legend']['enabled'] = self.FindWindowById(self.wxId['legend']['enabled']).IsChecked()
01433 
01434     def OnSave(self, event):
01435         """!Button 'Save' pressed"""
01436         self.UpdateSettings()
01437         fileSettings = {}
01438         UserSettings.ReadSettingsFile(settings=fileSettings)
01439         fileSettings['profile'] = UserSettings.Get(group='profile')
01440         file = UserSettings.SaveToFile(fileSettings)
01441         self.parent.parent.GetLayerManager().goutput.WriteLog(_('Profile settings saved to file \'%s\'.') % file)
01442         self.parent.SetGraphStyle()
01443         if self.parent.profile:
01444             self.parent.DrawPlot()
01445         self.Close()
01446 
01447     def OnApply(self, event):
01448         """!Button 'Apply' pressed. Does not close dialog"""
01449         self.UpdateSettings()
01450         self.parent.SetGraphStyle()
01451         if self.parent.profile:
01452             self.parent.DrawPlot()
01453         
01454     def OnCancel(self, event):
01455         """!Button 'Cancel' pressed"""
01456         self.Close()
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines