GRASS Programmer's Manual
6.4.2(2012)
|
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()