[GRASS-SVN] r42361 - grass/trunk/gui/wxpython/gui_modules
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri May 28 11:29:37 EDT 2010
Author: martinl
Date: 2010-05-28 11:29:36 -0400 (Fri, 28 May 2010)
New Revision: 42361
Modified:
grass/trunk/gui/wxpython/gui_modules/gdialogs.py
grass/trunk/gui/wxpython/gui_modules/mapdisp.py
grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py
grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py
grass/trunk/gui/wxpython/gui_modules/render.py
grass/trunk/gui/wxpython/gui_modules/wxnviz.py
Log:
wxGUI: image size dialog for exporting images
Modified: grass/trunk/gui/wxpython/gui_modules/gdialogs.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/gdialogs.py 2010-05-28 12:31:30 UTC (rev 42360)
+++ grass/trunk/gui/wxpython/gui_modules/gdialogs.py 2010-05-28 15:29:36 UTC (rev 42361)
@@ -17,6 +17,8 @@
- DxfImportDialog
- LayersList (used by MultiImport)
- SetOpacityDialog
+ - StaticWrapText
+ - ImageSizeDialog
(C) 2008-2010 by the GRASS Development Team
@@ -1487,3 +1489,72 @@
self.SetSize(self.wrappedSize)
del self.resizing
+class ImageSizeDialog(wx.Dialog):
+ """!Set size for saved graphic file"""
+ def __init__(self, parent, id = wx.ID_ANY, title=_("Set image size"),
+ style = wx.DEFAULT_DIALOG_STYLE, **kwargs):
+ self.parent = parent
+
+ wx.Dialog.__init__(self, parent, id = id, style=style, title=title, **kwargs)
+
+ self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
+
+ self.box = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
+ label = ' % s' % _("Image size"))
+
+ size = self.parent.GetWindow().GetClientSize()
+ self.width = wx.SpinCtrl(parent = self, id = wx.ID_ANY,
+ style = wx.SP_ARROW_KEYS)
+ self.width.SetRange(20, 1e6)
+ self.width.SetValue(size.width)
+ wx.CallAfter(self.width.SetFocus)
+ self.height = wx.SpinCtrl(parent = self, id = wx.ID_ANY,
+ style = wx.SP_ARROW_KEYS)
+ self.height.SetRange(20, 1e6)
+ self.height.SetValue(size.height)
+
+ self.btnOK = wx.Button(parent = self.panel, id = wx.ID_OK)
+ self.btnOK.SetDefault()
+ self.btnCancel = wx.Button(parent = self.panel, id = wx.ID_CANCEL)
+
+ self._layout()
+ self.SetSize(self.GetBestSize())
+
+ def _layout(self):
+ """!Do layout"""
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ # body
+ box = wx.StaticBoxSizer(self.box, wx.HORIZONTAL)
+ fbox = wx.FlexGridSizer(cols = 2, vgap = 5, hgap = 5)
+ fbox.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
+ label = _("Width:")),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+ fbox.Add(item = self.width)
+ fbox.Add(item = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
+ label = _("Height:")),
+ flag = wx.ALIGN_CENTER_VERTICAL)
+ fbox.Add(item = self.height)
+
+ box.Add(item = fbox, proportion = 1,
+ flag = wx.EXPAND | wx.ALL, border = 5)
+ sizer.Add(item = box, proportion = 1,
+ flag=wx.EXPAND | wx.ALL, border = 3)
+
+ # buttons
+ btnsizer = wx.StdDialogButtonSizer()
+ btnsizer.AddButton(self.btnOK)
+ btnsizer.AddButton(self.btnCancel)
+ btnsizer.Realize()
+
+ sizer.Add(item = btnsizer, proportion = 0,
+ flag = wx.EXPAND | wx.ALIGN_RIGHT | wx.ALL, border=5)
+
+ self.panel.SetSizer(sizer)
+ sizer.Fit(self.panel)
+ self.Layout()
+
+ def GetValues(self):
+ """!Get width/height values"""
+ return self.width.GetValue(), self.height.GetValue()
+
Modified: grass/trunk/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/mapdisp.py 2010-05-28 12:31:30 UTC (rev 42360)
+++ grass/trunk/gui/wxpython/gui_modules/mapdisp.py 2010-05-28 15:29:36 UTC (rev 42361)
@@ -1182,10 +1182,19 @@
else:
filetype, ltype = gdialogs.GetImageHandlers(self.MapWindow.img)
+ # get size
+ dlg = gdialogs.ImageSizeDialog(self)
+ dlg.CentreOnParent()
+ if dlg.ShowModal() != wx.ID_OK:
+ dlg.Destroy()
+ return
+ width, height = dlg.GetValues()
+ dlg.Destroy()
+
+ # get filename
dlg = wx.FileDialog(parent = self,
- message = _("Choose a file name to save the image (no need to add extension)"),
- defaultDir = "",
- defaultFile = "",
+ message = _("Choose a file name to save the image "
+ "(no need to add extension)"),
wildcard = filetype,
style=wx.SAVE | wx.FD_OVERWRITE_PROMPT)
@@ -1201,7 +1210,8 @@
if ext != extType:
path = base + '.' + extType
- self.MapWindow.SaveToFile(path, fileType)
+ self.MapWindow.SaveToFile(path, fileType,
+ width, height)
dlg.Destroy()
Modified: grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py 2010-05-28 12:31:30 UTC (rev 42360)
+++ grass/trunk/gui/wxpython/gui_modules/mapdisp_window.py 2010-05-28 15:29:36 UTC (rev 42361)
@@ -555,23 +555,21 @@
self.redrawAll = False
def OnSize(self, event):
- """!
- Scale map image so that it is
- the same size as the Window
+ """!Scale map image so that it is the same size as the Window
"""
Debug.msg(3, "BufferedWindow.OnSize():")
-
+
# set size of the input image
self.Map.ChangeMapSize(self.GetClientSize())
# align extent based on center point and display resolution
# this causes that image is not resized when display windows is resized
- # self.Map.AlignExtentFromDisplay()
-
+ ### self.Map.AlignExtentFromDisplay()
+
# Make new off screen bitmap: this bitmap will always have the
# current drawing in it, so it can be used to save the image to
# a file, or whatever.
self.buffer = wx.EmptyBitmap(max(1, self.Map.width), max(1, self.Map.height))
-
+
# get the image to be rendered
self.img = self.GetImage()
@@ -591,8 +589,7 @@
self.parent.StatusbarUpdate()
def OnIdle(self, event):
- """!
- Only re-render a composite map image from GRASS during
+ """!Only re-render a composite map image from GRASS during
idle time instead of multiple times during resizing.
"""
if self.resize:
@@ -600,17 +597,37 @@
event.Skip()
- def SaveToFile(self, FileName, FileType):
- """!
- This draws the psuedo DC to a buffer that
- can be saved to a file.
+ def SaveToFile(self, FileName, FileType, width, height):
+ """!This draws the pseudo DC to a buffer that can be saved to
+ a file.
+
+ @param FileName file name
+ @param FileType type of bitmap
+ @param width image width
+ @param height image height
"""
- dc = wx.BufferedPaintDC(self, self.buffer)
+ busy = wx.BusyInfo(message=_("Please wait, exporting image..."),
+ parent=self)
+ wx.Yield()
+
+ self.Map.ChangeMapSize((width, height))
+ ibuffer = wx.EmptyBitmap(max(1, width), max(1, height))
+ self.Map.Render(force=True, windres = True)
+ img = self.GetImage()
+ self.Draw(self.pdc, img, drawid = 99)
+ dc = wx.BufferedPaintDC(self, ibuffer)
+ dc.Clear()
+ self.PrepareDC(dc)
self.pdc.DrawToDC(dc)
if self.pdcVector:
self.pdcVector.DrawToDC(dc)
- self.buffer.SaveFile(FileName, FileType)
-
+ ibuffer.SaveFile(FileName, FileType)
+
+ busy.Destroy()
+
+ self.UpdateMap(render = True)
+ self.Refresh()
+
def GetOverlay(self):
"""!
Converts rendered overlay files to wx.Image
@@ -630,8 +647,7 @@
return imgs
def GetImage(self):
- """!
- Converts redered map files to wx.Image
+ """!Converts redered map files to wx.Image
Updates self.imagedict (id=99)
@@ -643,29 +659,29 @@
img = wx.Image(self.Map.mapfile, wx.BITMAP_TYPE_ANY)
else:
img = None
-
+
self.imagedict[img] = { 'id': imgId }
-
+
return img
def UpdateMap(self, render=True, renderVector=True):
"""!
Updates the canvas anytime there is a change to the
underlaying images or to the geometry of the canvas.
-
+
@param render re-render map composition
@param renderVector re-render vector map layer enabled for editing (used for digitizer)
"""
start = time.clock()
self.resize = False
-
+
# if len(self.Map.GetListOfLayers()) == 0:
# return False
if self.img is None:
render = True
-
+
#
# initialize process bar (only on 'render')
#
Modified: grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py 2010-05-28 12:31:30 UTC (rev 42360)
+++ grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py 2010-05-28 15:29:36 UTC (rev 42361)
@@ -1066,12 +1066,19 @@
return -1
- def SaveToFile(self, FileName, FileType):
+ def SaveToFile(self, FileName, FileType, width, height):
"""!This draws the DC to a buffer that can be saved to a file.
-
+
@todo fix BufferedPaintDC
+
+ @param FileName file name
+ @param FileType type of bitmap
+ @param width image width
+ @param height image height
"""
- self._display.SaveToFile(FileName)
+ self.SetCurrent()
+ self._display.SaveToFile(FileName, width, height)
+
# pbuffer = wx.EmptyBitmap(max(1, self.Map.width), max(1, self.Map.height))
# dc = wx.BufferedPaintDC(self, pbuffer)
# dc.Clear()
@@ -1079,7 +1086,7 @@
# self._display.Draw(False, -1)
# pbuffer.SaveFile(FileName, FileType)
# self.SwapBuffers()
-
+
def GetDisplay(self):
"""!Get display instance"""
return self._display
Modified: grass/trunk/gui/wxpython/gui_modules/render.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/render.py 2010-05-28 12:31:30 UTC (rev 42360)
+++ grass/trunk/gui/wxpython/gui_modules/render.py 2010-05-28 15:29:36 UTC (rev 42361)
@@ -9,7 +9,7 @@
- Overlay
- Map
-(C) 2006-2009 by the GRASS Development Team
+(C) 2006-2010 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
for details.
@@ -55,11 +55,10 @@
class Layer(object):
"""!Virtual class which stores information about layers (map layers and
overlays) of the map composition.
-
+
For map layer use MapLayer class.
For overlays use Overlay class.
"""
-
def __init__(self, type, cmd, name=None,
active=True, hidden=False, opacity=1.0):
"""
@@ -75,7 +74,7 @@
"""
self.type = type
self.name = name
-
+
if self.type == 'command':
self.cmd = []
for c in cmd:
@@ -93,7 +92,7 @@
"active=%d, opacity=%d, hidden=%d" % \
(self.type, self.GetCmd(string=True), self.name, self.active,
self.opacity, self.hidden))
-
+
# generated file for each layer
self.gtemp = tempfile.mkstemp()[1]
self.maskfile = self.gtemp + ".pgm"
@@ -101,14 +100,14 @@
self.mapfile = self.gtemp + ".png"
else:
self.mapfile = self.gtemp + ".ppm"
-
+
def __del__(self):
Debug.msg (3, "Layer.__del__(): layer=%s, cmd='%s'" %
(self.name, self.GetCmd(string=True)))
def Render(self):
"""!Render layer to image
-
+
@return rendered image filename
@return None on error
"""
@@ -200,9 +199,9 @@
def GetCmd(self, string=False):
"""
Get GRASS command as list of string.
-
+
@param string get command as string if True otherwise as list
-
+
@return command list/string
"""
if string:
@@ -224,9 +223,9 @@
def GetOpacity(self, float=False):
"""
Get layer opacity level
-
+
@param float get opacity level in <0,1> otherwise <0,100>
-
+
@return opacity level
"""
if float:
@@ -253,7 +252,7 @@
def IsActive(self):
"""!Check if layer is activated for rendering"""
return self.active
-
+
def SetType(self, type):
"""!Set layer type"""
if type not in ('raster', '3d-raster', 'vector',
@@ -300,10 +299,10 @@
self.force_render = True
class MapLayer(Layer):
- """!Represents map layer in the map canvas"""
def __init__(self, type, cmd, name=None,
- active=True, hidden=False, opacity=1.0):
- """
+ active=True, hidden=False, opacity=1.0):
+ """!Represents map layer in the map canvas
+
@param type layer type ('raster', 'vector', 'command', etc.)
@param cmd GRASS command to render layer,
given as list, e.g. ['d.rast', 'map=elevation at PERMANENT']
@@ -314,29 +313,26 @@
"""
Layer.__init__(self, type, cmd, name,
active, hidden, opacity)
-
- #self.mapfile = self.gtemp + ".ppm"
-
+
def GetMapset(self):
- """
- Get mapset of map layer
-
+ """!Get mapset of map layer
+
@return mapset name
@return '' on error (no name given)
"""
if not self.name:
return ''
-
+
try:
return self.name.split('@')[1]
except IndexError:
return self.name
-
+
class Overlay(Layer):
- """!Represents overlay displayed in map canvas"""
def __init__(self, id, type, cmd,
active=True, hidden=True, opacity=1.0):
- """
+ """!Represents overlay displayed in map canvas
+
@param id overlay id (for PseudoDC)
@param type overlay type ('barscale', 'legend', etc.)
@param cmd GRASS command to render overlay,
@@ -347,10 +343,9 @@
"""
Layer.__init__(self, 'overlay', cmd, type,
active, hidden, opacity)
-
+
self.id = id
- #self.mapfile = self.gtemp + ".png"
-
+
class Map(object):
"""!Map composition (stack of map layers and overlays)
"""
@@ -363,7 +358,7 @@
# list of layers
self.layers = list() # stack of available GRASS layer
-
+
self.overlays = list() # stack of available overlays
self.ovlookup = dict() # lookup dictionary for overlay items and overlays
@@ -385,7 +380,7 @@
# projection info
self.projinfo = self._projInfo()
-
+
def _runCommand(self, cmd, **kwargs):
"""!Run command in environment defined by self.gisrc if
defined"""
@@ -418,7 +413,7 @@
"""!Return region projection and map units information
"""
projinfo = dict()
-
+
ret = self._runCommand(gcmd.RunCommand, prog = 'g.proj',
read = True, flags = 'p')
@@ -435,7 +430,7 @@
break
return projinfo
-
+
def GetWindow(self):
"""!Read WIND file and set up self.wind dictionary"""
# FIXME: duplicated region WIND == g.region (at least some values)
@@ -459,81 +454,77 @@
return self.wind
def AdjustRegion(self):
+ """!Adjusts display resolution to match monitor size in
+ pixels. Maintains constant display resolution, not related to
+ computational region. Do NOT use the display resolution to set
+ computational resolution. Set computational resolution through
+ g.region.
"""
- Adjusts display resolution to match monitor size in pixels.
- Maintains constant display resolution, not related to computational
- region. Do NOT use the display resolution to set computational
- resolution. Set computational resolution through g.region.
- """
-
mapwidth = abs(self.region["e"] - self.region["w"])
mapheight = abs(self.region['n'] - self.region['s'])
-
+
self.region["nsres"] = mapheight / self.height
self.region["ewres"] = mapwidth / self.width
self.region['rows'] = round(mapheight / self.region["nsres"])
self.region['cols'] = round(mapwidth / self.region["ewres"])
self.region['cells'] = self.region['rows'] * self.region['cols']
-
+
Debug.msg (3, "Map.AdjustRegion(): %s" % self.region)
-
+
return self.region
def AlignResolution(self):
+ """!Sets display extents to even multiple of current
+ resolution defined in WIND file from SW corner. This must be
+ done manually as using the -a flag can produce incorrect
+ extents.
"""
- Sets display extents to even multiple of
- current resolution defined in WIND file from SW corner.
- This must be done manually as using the -a flag
- can produce incorrect extents.
- """
-
# new values to use for saving to region file
new = {}
n = s = e = w = 0.0
nwres = ewres = 0.0
-
+
# Get current values for region and display
nsres = self.GetRegion()['nsres']
ewres = self.GetRegion()['ewres']
-
+
n = float(self.region['n'])
s = float(self.region['s'])
e = float(self.region['e'])
w = float(self.region['w'])
-
+
# Calculate rows, columns, and extents
new['rows'] = math.fabs(round((n-s)/nsres))
new['cols'] = math.fabs(round((e-w)/ewres))
-
+
# Calculate new extents
new['s'] = nsres * round(s/nsres)
new['w'] = ewres * round(w/ewres)
new['n'] = new['s'] + (new['rows'] * nsres)
new['e'] = new['w'] + (new['cols'] * ewres)
-
+
return new
def AlignExtentFromDisplay(self):
"""!Align region extent based on display size from center point"""
-
# calculate new bounding box based on center of display
if self.region["ewres"] > self.region["nsres"]:
res = self.region["ewres"]
else:
res = self.region["nsres"]
-
+
Debug.msg(3, "Map.AlignExtentFromDisplay(): width=%d, height=%d, res=%f, center=%f,%f" % \
(self.width, self.height, res, self.region['center_easting'],
self.region['center_northing']))
ew = (self.width / 2) * res
ns = (self.height / 2) * res
-
+
self.region['n'] = self.region['center_northing'] + ns
self.region['s'] = self.region['center_northing'] - ns
self.region['e'] = self.region['center_easting'] + ew
self.region['w'] = self.region['center_easting'] - ew
-
+
# LL locations
if self.projinfo['proj'] == 'll':
if self.region['n'] > 90.0:
@@ -559,12 +550,12 @@
self.width = 640
self.height = 480
return False
-
+
def GetRegion(self, rast = [], zoom = False, vect = [], regionName = None,
n = None, s = None, e = None, w = None, default = False,
update = False):
"""!Get region settings (g.region -upgc)
-
+
Optionally extent, raster or vector map layer can be given.
@param rast list of raster maps
@@ -579,20 +570,20 @@
'n':'4928010', 's':'4913700', 'w':'589980',...}
"""
region = {}
-
+
tmpreg = os.getenv("GRASS_REGION")
if tmpreg:
del os.environ["GRASS_REGION"]
-
+
# use external gisrc if defined
gisrc_orig = os.getenv("GISRC")
if self.gisrc:
os.environ["GISRC"] = self.gisrc
-
+
# do not update & shell style output
cmd = {}
cmd['flags'] = 'ugpc'
-
+
if default:
cmd['flags'] += 'd'
@@ -607,13 +598,13 @@
cmd['e'] = e
if w:
cmd['w'] = w
-
+
if rast:
if zoom:
cmd['zoom'] = rast[0]
else:
cmd['rast'] = ','.join(rast)
-
+
if vect:
cmd['vect'] = ','.join(vect)
@@ -634,22 +625,22 @@
"fix the problem.")
e.Show()
return self.region
-
+
for reg in ret.splitlines():
key, val = reg.split("=", 1)
try:
region[key] = float(val)
except ValueError:
region[key] = val
-
+
# back to original gisrc
if self.gisrc:
os.environ["GISRC"] = gisrc_orig
-
+
# restore region
if tmpreg:
os.environ["GRASS_REGION"] = tmpreg
-
+
Debug.msg (3, "Map.GetRegion(): %s" % region)
if update:
@@ -662,17 +653,17 @@
return self.region
def SetRegion(self, windres=False):
- """
- Render string for GRASS_REGION env. variable, so that the images will be rendered
- from desired zoom level.
+ """!Render string for GRASS_REGION env. variable, so that the
+ images will be rendered from desired zoom level.
+
+ @param windres uses resolution from WIND file rather than
+ display (for modules that require set resolution like
+ d.rast.num)
- @param windres uses resolution from WIND file rather than display (for modules that require set
- resolution like d.rast.num)
-
@return String usable for GRASS_REGION variable or None
"""
grass_region = ""
-
+
if windres:
compRegion = self.GetRegion()
region = copy.copy(self.region)
@@ -720,41 +711,39 @@
continue
else:
grass_region += key + ": " + self.wind[key] + "; "
-
+
Debug.msg (3, "Map.SetRegion(): %s" % grass_region)
-
+
return grass_region
-
+
except:
return None
-
+
def GetListOfLayers(self, l_type=None, l_mapset=None, l_name=None,
l_active=None, l_hidden=None):
- """
- Returns list of layers of selected properties or list of all
- layers.
+ """!Returns list of layers of selected properties or list of
+ all layers.
@param l_type layer type, e.g. raster/vector/wms/overlay (value or tuple of values)
@param l_mapset all layers from given mapset (only for maplayers)
@param l_name all layers with given name
@param l_active only layers with 'active' attribute set to True or False
@param l_hidden only layers with 'hidden' attribute set to True or False
-
+
@return list of selected layers
"""
-
selected = []
-
+
if type(l_type) == type(''):
one_type = True
else:
one_type = False
-
+
if one_type and l_type == 'overlay':
list = self.overlays
else:
list = self.layers
-
+
# ["raster", "vector", "wms", ... ]
for layer in list:
# specified type only
@@ -763,39 +752,39 @@
continue
elif not one_type and layer.type not in l_type:
continue
-
+
# mapset
if (l_mapset != None and type != 'overlay') and \
layer.GetMapset() != l_mapset:
continue
-
+
# name
if l_name != None and layer.name != l_name:
continue
-
+
# hidden and active layers
if l_active != None and \
l_hidden != None:
if layer.active == l_active and \
layer.hidden == l_hidden:
selected.append(layer)
-
+
# active layers
elif l_active != None:
if layer.active == l_active:
selected.append(layer)
-
+
# hidden layers
elif l_hidden != None:
if layer.hidden == l_hidden:
selected.append(layer)
-
+
# all layers
else:
selected.append(layer)
-
+
Debug.msg (3, "Map.GetListOfLayers(): numberof=%d" % len(selected))
-
+
return selected
def _renderLayers(self, force, mapWindow, maps, masks, opacities):
@@ -828,11 +817,10 @@
Debug.msg (3, "Map.Render() type=%s, layer=%s " % (layer.type, layer.name))
ilayer += 1
-
+
def Render(self, force=False, mapWindow=None, windres=False):
- """
- Creates final image composite
-
+ """!Creates final image composite
+
This function can conditionaly use high-level tools, which
should be avaliable in wxPython library
@@ -845,12 +833,12 @@
maps = []
masks =[]
opacities = []
-
+
# use external gisrc if defined
gisrc_orig = os.getenv("GISRC")
if self.gisrc:
os.environ["GISRC"] = self.gisrc
-
+
tmp_region = os.getenv("GRASS_REGION")
os.environ["GRASS_REGION"] = self.SetRegion(windres)
os.environ["GRASS_WIDTH"] = str(self.width)
@@ -865,7 +853,7 @@
os.environ["GRASS_RENDER_IMMEDIATE"] = "png"
else:
os.environ["GRASS_RENDER_IMMEDIATE"] = "TRUE"
-
+
os.environ["GRASS_PNG_READ"] = "FALSE"
self._renderLayers(force, mapWindow, maps, masks, opacities)
@@ -885,7 +873,7 @@
maskstr += item.replace('\\', '/')
maskstr = maskstr.rstrip(',')
mapoutstr = self.mapfile.replace('\\', '/')
-
+
# compose command
bgcolor = ':'.join(map(str, UserSettings.Get(group='display', key='bgcolor',
subkey='color')))
@@ -918,21 +906,20 @@
if ret != 0:
print >> sys.stderr, _("ERROR: Rendering failed")
return None
-
+
# back to original gisrc
if self.gisrc:
os.environ["GISRC"] = gisrc_orig
-
- Debug.msg (2, "Map.Render() force=%s file=%s" % (force, self.mapfile))
-
+
+ Debug.msg (3, "Map.Render() force=%s file=%s" % (force, self.mapfile))
+
return self.mapfile
def AddLayer(self, type, command, name=None,
l_active=True, l_hidden=False, l_opacity=1.0, l_render=False,
pos=-1):
- """
- Adds generic map layer to list of layers
-
+ """!Adds generic map layer to list of layers
+
@param type layer type ('raster', 'vector', etc.)
@param command GRASS command given as list
@param name layer name
@@ -941,18 +928,17 @@
@param l_opacity opacity level range from 0(transparent) - 1(not transparent)
@param l_render render an image if True
@param pos position in layer list (-1 for append)
-
+
@return new layer on success
@return None on failure
-
"""
# l_opacity must be <0;1>
if l_opacity < 0: l_opacity = 0
elif l_opacity > 1: l_opacity = 1
-
+
layer = MapLayer(type=type, name=name, cmd=command,
active=l_active, hidden=l_hidden, opacity=l_opacity)
-
+
# add maplayer to the list of layers
if pos > -1:
self.layers.insert(pos, layer)
@@ -963,26 +949,24 @@
if l_render:
if not layer.Render():
raise gcmd.GStdError(_("Unable to render map layer <%s>.") % (name))
-
+
return layer
def DeleteLayer(self, layer, overlay=False):
- """
- Removes layer from list of layers
-
+ """!Removes layer from list of layers
+
@param layer layer instance in layer tree
@param overlay delete overlay (use self.DeleteOverlay() instead)
@return removed layer on success or None
"""
-
Debug.msg (3, "Map.DeleteLayer(): name=%s" % layer.name)
-
+
if overlay:
list = self.overlays
else:
list = self.layers
-
+
if layer in list:
if layer.mapfile:
base = os.path.split(layer.mapfile)[0]
@@ -994,29 +978,27 @@
for f in glob.glob(basefile):
os.remove(f)
list.remove(layer)
-
+
return layer
-
+
return None
def ReorderLayers(self, layerList):
- """
- Reorder list to match layer tree
-
+ """!Reorder list to match layer tree
+
@param layerList list of layers
"""
self.layers = layerList
-
+
layerNameList = ""
for layer in self.layers:
if layer.name:
layerNameList += layer.name + ','
Debug.msg (4, "Map.ReoderLayers(): layers=%s" % \
(layerNameList))
-
+
def ChangeLayer(self, layer, render=False, **kargs):
- """
- Change map layer properties
+ """!Change map layer properties
@param layer map layer instance
@param type layer type ('raster', 'vector', etc.)
@@ -1027,7 +1009,6 @@
@param opacity opacity level range from 0(transparent) - 1(not transparent)
@param render render an image if True
"""
-
Debug.msg (3, "Map.ChangeLayer(): layer=%s" % layer.name)
if kargs.has_key('type'):
@@ -1038,25 +1019,24 @@
if kargs.has_key('name'):
layer.SetName(kargs['name'])
-
+
if kargs.has_key('active'):
layer.SetActive(kargs['active'])
-
+
if kargs.has_key('hidden'):
layer.SetHidden(kargs['hidden'])
-
+
if kargs.has_key('opacity'):
layer.SetOpacity(kargs['opacity'])
-
+
if render and not layer.Render():
raise gcmd.GException(_("Unable to render map layer <%s>.") %
(name))
-
+
return layer
def ChangeOpacity(self, layer, l_opacity):
- """
- Changes opacity value of map layer
+ """!Changes opacity value of map layer
@param layer layer instance in layer tree
@param l_opacity opacity level <0;1>
@@ -1064,27 +1044,25 @@
# l_opacity must be <0;1>
if l_opacity < 0: l_opacity = 0
elif l_opacity > 1: l_opacity = 1
-
+
layer.opacity = l_opacity
Debug.msg (3, "Map.ChangeOpacity(): layer=%s, opacity=%f" % \
(layer.name, layer.opacity))
def ChangeLayerActive(self, layer, active):
- """
- Enable or disable map layer
-
+ """!Enable or disable map layer
+
@param layer layer instance in layer tree
@param active to be rendered (True)
"""
layer.active = active
-
+
Debug.msg (3, "Map.ChangeLayerActive(): name='%s' -> active=%d" % \
(layer.name, layer.active))
def ChangeLayerName (self, layer, name):
- """
- Change name of the layer
-
+ """!Change name of the layer
+
@param layer layer instance in layer tree
@param name layer name to set up
"""
@@ -1093,18 +1071,16 @@
layer.name = name
def RemoveLayer(self, name=None, id=None):
- """
- Removes layer from layer list
-
+ """!Removes layer from layer list
+
Layer is defined by name at mapset or id.
-
+
@param name layer name (must be unique)
@param id layer index in layer list
@return removed layer on success
@return None on failure
"""
-
# delete by name
if name:
retlayer = None
@@ -1118,13 +1094,12 @@
# del by id
elif id != None:
return self.layers.pop(id)
-
+
return None
def GetLayerIndex(self, layer, overlay=False):
- """
- Get index of layer in layer list.
-
+ """!Get index of layer in layer list.
+
@param layer layer instace in layer tree
@param overlay use list of overlays instead
@@ -1138,13 +1113,13 @@
if layer in list:
return list.index(layer)
-
+
return -1
def AddOverlay(self, id, type, command,
l_active=True, l_hidden=True, l_opacity=1.0, l_render=False):
- """
- Adds overlay (grid, barscale, legend, etc.) to list of overlays
+ """!Adds overlay (grid, barscale, legend, etc.) to list of
+ overlays
@param id overlay id (PseudoDC)
@param type overlay type (barscale, legend)
@@ -1152,37 +1127,35 @@
@param l_active overlay activated (True) or disabled (False)
@param l_hidden overlay is not shown in layer tree (if True)
@param l_render render an image (if True)
-
+
@return new layer on success
@retutn None on failure
"""
-
Debug.msg (2, "Map.AddOverlay(): cmd=%s, render=%d" % (command, l_render))
overlay = Overlay(id=id, type=type, cmd=command,
active=l_active, hidden=l_hidden, opacity=l_opacity)
-
+
# add maplayer to the list of layers
self.overlays.append(overlay)
-
+
if l_render and command != '' and not overlay.Render():
raise gcmd.GException(_("Unable render overlay <%s>.") %
(name))
-
+
return self.overlays[-1]
def ChangeOverlay(self, id, render=False, **kargs):
- """
- Change overlay properities
-
+ """!Change overlay properities
+
Add new overlay if overlay with 'id' doesn't exist.
-
+
@param id overlay id (PseudoDC)
@param type overlay type (barscale, legend)
@param command GRASS command to render overlay
@param l_active overlay activated (True) or disabled (False)
@param l_hidden overlay is not shown in layer tree (if True)
@param l_render render an image (if True)
-
+
@return new layer on success
"""
overlay = self.GetOverlay(id, list=False)
@@ -1197,10 +1170,10 @@
if kargs.has_key('active'):
overlay.SetActive(kargs['active'])
-
+
if kargs.has_key('hidden'):
overlay.SetHidden(kargs['hidden'])
-
+
if kargs.has_key('opacity'):
overlay.SetOpacity(kargs['opacity'])
@@ -1212,7 +1185,7 @@
def GetOverlay(self, id, list=False):
"""!Return overlay(s) with 'id'
-
+
@param id overlay id
@param list return list of overlays of True
otherwise suppose 'id' to be unique
@@ -1231,23 +1204,22 @@
return None
else:
return ovl[0]
-
+
return ovl
def DeleteOverlay(self, overlay):
"""!Delete overlay
-
+
@param id overlay id
-
+
@return removed overlay on success or None
"""
return self.DeleteLayer(overlay, overlay=True)
def Clean(self):
- """
- Clean layer stack - go trough all layers and remove them from layer list
- Removes also l_mapfile and l_maskfile
-
+ """!Clean layer stack - go trough all layers and remove them
+ from layer list Removes also l_mapfile and l_maskfile
+
@return 1 on faulure
@return None on success
"""
@@ -1265,7 +1237,7 @@
for f in glob.glob(removepath):
os.remove(f)
self.layers.remove(layer)
-
+
for overlay in self.overlays:
if overlay.mapfile:
dir = os.path.dirname(overlay.mapfile)
@@ -1284,31 +1256,30 @@
return self.layers.reverse()
if __name__ == "__main__":
- """
- Test of Display class.
+ """!Test of Display class.
Usage: display=Render()
"""
-
import gettext
gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode=True)
-
+
print "Initializing..."
- os.system("g.region -d")
-
+ grass.run_command("g.region", flags="d")
+
map = Map()
map.width = 640
map.height = 480
-
+
map.AddLayer(type="raster",
name="elevation.dem",
command = ["d.rast", "elevation.dem at PERMANENT", "catlist=1000-1500", "-i"],
l_opacity=.7)
-
+
map.AddLayer(type="vector",
name="streams",
command = ["d.vect", "streams at PERMANENT", "color=red", "width=3", "type=line"])
-
+
image = map.Render(force=True)
-
+
if image:
os.system("display %s" % image)
+
Modified: grass/trunk/gui/wxpython/gui_modules/wxnviz.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/wxnviz.py 2010-05-28 12:31:30 UTC (rev 42360)
+++ grass/trunk/gui/wxpython/gui_modules/wxnviz.py 2010-05-28 15:29:36 UTC (rev 42361)
@@ -44,6 +44,7 @@
self.data_obj = nv_data()
self.data = pointer(self.data_obj)
+ self.width = self.height = -1
Debug.msg(1, "Nviz::Nviz()")
@@ -64,7 +65,8 @@
@return 1 on success
@return 0 on failure (window resized by default to 20x20 px)
"""
-
+ self.width = width
+ self.height = height
Debug.msg(3, "Nviz::ResizeWindow(): width=%d height=%d",
width, height)
return Nviz_resize_window(width, height)
@@ -1093,14 +1095,23 @@
return -2 if ret < 0 else 1
- def SaveToFile(self, filename, itype = 'ppm'):
+ def SaveToFile(self, filename, width = 20, height = 20, itype = 'ppm'):
"""!Save current GL screen to ppm/tif file
@param filename file name
+ @param width image width
+ @param height image height
@param itype image type ('ppm' or 'tif')
"""
+ widthOrig = self.width
+ heightOrig = self.height
+
+ self.ResizeWindow(width, height)
+ GS_clear(self.data.bgcolor)
self.Draw(False, -1)
if itype == 'ppm':
GS_write_ppm(filename)
else:
GS_write_tif(filename)
+
+ self.ResizeWindow(widthOrig, heightOrig)
More information about the grass-commit
mailing list