[GRASS-SVN] r55829 - grass/trunk/gui/wxpython/animation
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Apr 16 03:28:07 PDT 2013
Author: annakrat
Date: 2013-04-16 03:28:07 -0700 (Tue, 16 Apr 2013)
New Revision: 55829
Modified:
grass/trunk/gui/wxpython/animation/controller.py
grass/trunk/gui/wxpython/animation/dialogs.py
grass/trunk/gui/wxpython/animation/frame.py
grass/trunk/gui/wxpython/animation/g.gui.animation.py
grass/trunk/gui/wxpython/animation/mapwindow.py
grass/trunk/gui/wxpython/animation/temporal_manager.py
Log:
wxGUI/animation: vector rendering (patch by Soeren Gebbert)
Modified: grass/trunk/gui/wxpython/animation/controller.py
===================================================================
--- grass/trunk/gui/wxpython/animation/controller.py 2013-04-16 08:31:10 UTC (rev 55828)
+++ grass/trunk/gui/wxpython/animation/controller.py 2013-04-16 10:28:07 UTC (rev 55829)
@@ -252,29 +252,33 @@
self.animationData.append(animData)
self._setAnimations()
- def SetAnimations(self, raster = None, strds = None):
+ def SetAnimations(self, inputs=None, dataType=None):
"""!Set animation data directly.
@param raster list of lists of raster maps or None
@param strds list of strds or None
+ @param inputs list of lists of raster maps or vector maps,
+ or a space time raster or vector dataset
+ @param dataType The type of the input data must be one of 'rast', 'vect', 'strds' or 'strds'
"""
try:
animationData = []
for i in range(len(self.animations)):
- if raster is not None and type(raster[i]) == list and raster[i]:
- anim = AnimationData()
- anim.SetDefaultValues(i, i)
- anim.inputMapType = 'rast'
- anim.inputData = ','.join(raster[i])
- animationData.append(anim)
+ if inputs is not None and inputs[i]:
+ if dataType == 'rast' or dataType == 'vect':
+ if type(inputs[i]) == list:
+ anim = AnimationData()
+ anim.SetDefaultValues(i, i)
+ anim.inputMapType = dataType
+ anim.inputData = ','.join(inputs[i])
+ animationData.append(anim)
+ elif dataType == 'strds' or dataType == 'stvds':
+ anim = AnimationData()
+ anim.SetDefaultValues(i, i)
+ anim.inputMapType = dataType
+ anim.inputData = inputs[i]
+ animationData.append(anim)
- elif strds is not None and strds[i]:
- anim = AnimationData()
- anim.SetDefaultValues(i, i)
- anim.inputMapType = 'strds'
- anim.inputData = strds[i]
- animationData.append(anim)
-
except (GException, ValueError, IOError) as e:
GError(parent = self.frame, message = str(e),
showTraceback = False, caption = _("Invalid input"))
@@ -301,6 +305,7 @@
self._updateSlider(timeLabels = timeLabels)
self._updateAnimations(activeIndices = indices, mapNamesDict = mapNamesDict)
+ wx.Yield()
self._updateBitmapData()
# if running:
# self.PauseAnimation(False)
@@ -371,7 +376,7 @@
def _load2DData(self, animationData):
prov = self.bitmapProviders[animationData.windowIndex]
- prov.SetData(datasource = animationData.mapData)
+ prov.SetData(datasource = animationData.mapData, dataType=animationData.inputMapType)
self.bitmapProviders[animationData.windowIndex].Load()
Modified: grass/trunk/gui/wxpython/animation/dialogs.py
===================================================================
--- grass/trunk/gui/wxpython/animation/dialogs.py 2013-04-16 08:31:10 UTC (rev 55828)
+++ grass/trunk/gui/wxpython/animation/dialogs.py 2013-04-16 10:28:07 UTC (rev 55829)
@@ -416,10 +416,8 @@
def _setMapTypes(self, view2d = True):
index = 0
- if view2d:
- inputTypes = self.animationData.inputMapTypes[::2]
- else:
- inputTypes = self.animationData.inputMapTypes
+
+ inputTypes = self.animationData.inputMapTypes
self.dataChoice.Clear()
for i, (itype, itypeName) in enumerate(inputTypes):
self.dataChoice.Append(itypeName, clientData = itype)
@@ -696,8 +694,11 @@
if self.inputMapType == 'strds':
sp = tgis.SpaceTimeRasterDataset(ident = timeseries)
elif self.inputMapType == 'stvds':
- sp = tgis.SpaceTimeRasterDataset(ident = timeseries)
- # else ?
+ sp = tgis.SpaceTimeVectorDataset(ident = timeseries)
+
+ if sp.is_in_db() == False:
+ raise GException(_("Space time dataset <%s> not found.") % timeseries)
+
sp.select()
rows = sp.get_registered_maps(columns = "id", where = None, order = "start_time", dbif = None)
timeseriesMaps = []
Modified: grass/trunk/gui/wxpython/animation/frame.py
===================================================================
--- grass/trunk/gui/wxpython/animation/frame.py 2013-04-16 08:31:10 UTC (rev 55828)
+++ grass/trunk/gui/wxpython/animation/frame.py 2013-04-16 10:28:07 UTC (rev 55829)
@@ -143,8 +143,14 @@
BestSize((self.toolbars['miscToolbar'].GetBestSize())))
self.controller.SetAnimationToolbar(self.toolbars['miscToolbar'])
- def SetAnimations(self, raster = None, strds = None):
- self.controller.SetAnimations(raster, strds)
+ def SetAnimations(self, inputs=None, dataType=None):
+ """!Set animation data
+
+ @param inputs list of lists of raster maps or vector maps,
+ or a space time raster or vector dataset
+ @param dataType The type of the input data must be one of 'rast', 'vect', 'strds' or 'strds'
+ """
+ self.controller.SetAnimations(inputs, dataType)
def OnAddAnimation(self, event):
self.controller.AddAnimation()
@@ -291,8 +297,6 @@
return self.mainSizer.IsShown(self.windows[index])
-
-
class AnimationSliderBase(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent = parent, id = wx.ID_ANY)
@@ -517,8 +521,8 @@
app = wx.PySimpleApp()
wx.InitAllImageHandlers()
- frame = AnimationFrame(parent = None)
- frame.SetAnimations(raster = None, strds = None)
+ frame = AnimationFrame(parent=None)
+ frame.SetAnimations(inputs=None, dataType=None)
frame.Show()
app.MainLoop()
Modified: grass/trunk/gui/wxpython/animation/g.gui.animation.py
===================================================================
--- grass/trunk/gui/wxpython/animation/g.gui.animation.py 2013-04-16 08:31:10 UTC (rev 55828)
+++ grass/trunk/gui/wxpython/animation/g.gui.animation.py 2013-04-16 10:28:07 UTC (rev 55829)
@@ -3,7 +3,7 @@
#
# MODULE: Animation
# AUTHOR(S): Anna Kratochvilova
-# PURPOSE: Tool for animating a series of GRASS raster maps
+# PURPOSE: Tool for animating a series of GRASS raster and vector maps
# or a space time raster dataset
# COPYRIGHT: (C) 2012 by Anna Kratochvilova, and the GRASS Development Team
#
@@ -20,7 +20,7 @@
############################################################################
#%module
-#% description: Tool for animating a series of raster maps or a space time raster dataset.
+#% description: Tool for animating a series of raster and vector maps or a space time raster ot vector dataset.
#% keywords: general
#% keywords: gui
#% keywords: display
@@ -31,14 +31,25 @@
#% required: no
#% guisection: Input
#%end
+#%option G_OPT_V_INPUTS
+#% key: vect
+#% label: Vector maps to animate
+#% required: no
+#% guisection: Input
+#%end
#%option G_OPT_STRDS_INPUT
#% key: strds
#% description: Space time raster dataset to animate
#% required: no
#% guisection: Input
#%end
+#%option G_OPT_STVDS_INPUT
+#% key: stvds
+#% description: Space time vector dataset to animate
+#% required: no
+#% guisection: Input
+#%end
-
import os
import sys
@@ -61,20 +72,38 @@
options, flags = grass.parser()
rast = options['rast']
+ vect = options['vect']
strds = options['strds']
+ stvds = options['stvds']
+
+ dataType=None
+ inputs=None
+ numInputs=0
+
+ if rast:
+ numInputs += 1
+ if vect:
+ numInputs += 1
+ if strds:
+ numInputs += 1
+ if stvds:
+ numInputs += 1
- if rast and strds:
- grass.fatal(_("Options 'rast' and 'strds' are mutually exclusive."))
+ if numInputs > 1:
+ grass.fatal(_("Options 'rast', 'vect', 'strds' and 'stvds' are mutually exclusive."))
if rast:
- rast = [rast.split(',')] + [None] * (MAX_COUNT - 1)
- else:
- rast = None
-
+ inputs = [rast.split(',')] + [None] * (MAX_COUNT - 1)
+ dataType='rast'
+ if vect:
+ inputs = [vect.split(',')] + [None] * (MAX_COUNT - 1)
+ dataType='vect'
if strds:
- strds = [strds] + [None] * (MAX_COUNT - 1)
- else:
- strds = None
+ inputs = [strds] + [None] * (MAX_COUNT - 1)
+ dataType='strds'
+ if stvds:
+ inputs = [stvds] + [None] * (MAX_COUNT - 1)
+ dataType='stvds'
app = wx.PySimpleApp()
if not CheckWxVersion([2, 9]):
@@ -83,10 +112,9 @@
frame = AnimationFrame(parent = None)
frame.CentreOnScreen()
frame.Show()
- frame.SetAnimations(raster = rast, strds = strds)
+ frame.SetAnimations(inputs = inputs, dataType = dataType)
app.MainLoop()
-
if __name__ == '__main__':
main()
Modified: grass/trunk/gui/wxpython/animation/mapwindow.py
===================================================================
--- grass/trunk/gui/wxpython/animation/mapwindow.py 2013-04-16 08:31:10 UTC (rev 55828)
+++ grass/trunk/gui/wxpython/animation/mapwindow.py 2013-04-16 10:28:07 UTC (rev 55829)
@@ -23,6 +23,7 @@
import grass.script as grass
from core.gcmd import RunCommand
from core.debug import Debug
+from core.settings import UserSettings
from grass.pydispatch.signal import Signal
@@ -170,9 +171,9 @@
suffix = '', nvizRegion = None):
"""!Sets data.
- @param datasource data to load (raster maps, m.nviz.image commands)
+ @param datasource data to load (raster maps, vector maps, m.nviz.image commands)
@param dataNames data labels (keys)
- @param dataType 'rast', 'nviz'
+ @param dataType 'rast', 'vect', 'nviz'
@param nvizRegion region which must be set for m.nviz.image
"""
self.datasource = datasource
@@ -223,17 +224,23 @@
dc.SelectObject(wx.NullBitmap)
return bitmap
- def Load(self, force = False):
+ def Load(self, force = False, nprocs=4):
"""!Loads data.
Shows progress dialog.
@param force if True reload all data, otherwise only missing data
+ @param imageWidth width of the image to render with d.rast or d.vect
+ @param imageHeight height of the image to render with d.rast or d.vect
+ @param nprocs number of procs to be used for rendering
"""
+ if nprocs <= 0:
+ nprocs = 1
+
count, maxLength = self._dryLoad(rasters = self.datasource,
names = self.dataNames, force = force)
progress = None
- if self.dataType == 'rast' and count > 5 or \
+ if self.dataType in ('rast', 'vect', 'strds', 'stvds') and count > 5 or \
self.dataType == 'nviz':
progress = wx.ProgressDialog(title = "Loading data",
message = " " * (maxLength + 20), # ?
@@ -245,9 +252,10 @@
else:
updateFunction = None
- if self.dataType == 'rast' or self.dataType == 'vect':
+ if self.dataType in ('rast', 'vect', 'strds', 'stvds'):
self._loadMaps(mapType=self.dataType, maps = self.datasource, names = self.dataNames,
- force = force, updateFunction = updateFunction)
+ force = force, updateFunction = updateFunction,
+ imageWidth=self.imageWidth, imageHeight=self.imageHeight, nprocs=nprocs)
elif self.dataType == 'nviz':
self._load3D(commands = self.datasource, region = self.nvizRegion, names = self.dataNames,
force = force, updateFunction = updateFunction)
@@ -280,7 +288,8 @@
return count, maxLength
- def _loadMaps(self, mapType, maps, names, force, updateFunction):
+ def _loadMaps(self, mapType, maps, names, force, updateFunction,
+ imageWidth, imageHeight, nprocs):
"""!Loads rasters/vectors (also from temporal dataset).
Uses d.rast/d.vect and multiprocessing for parallel rendering
@@ -290,6 +299,9 @@
@param names names used as keys for bitmaps
@param force load everything even though it is already there
@param updateFunction function called for updating progress dialog
+ @param imageWidth width of the image to render with d.rast or d.vect
+ @param imageHeight height of the image to render with d.rast or d.vect
+ @param nprocs number of procs to be used for rendering
"""
count = 0
@@ -304,7 +316,7 @@
# create no data bitmap
if None not in self.bitmapPool or force:
- self.bitmapPool[None] = self._createNoDataBitmap(self.imageWidth, self.imageHeight)
+ self.bitmapPool[None] = self._createNoDataBitmap(imageWidth, imageHeight)
for mapname, name in zip(maps, names):
count += 1
@@ -315,7 +327,7 @@
# Queue object for interprocess communication
q = Queue()
# The separate render process
- p = Process(target=mapRenderProcess, args=(mapType, mapname, self.imageWidth, self.imageHeight, q))
+ p = Process(target=mapRenderProcess, args=(mapType, mapname, imageWidth, imageHeight, q))
p.start()
queue_list.append(q)
@@ -325,7 +337,7 @@
proc_count += 1
# Wait for all running processes and read/store the created images
- if proc_count == self.nprocs or count == mapNum:
+ if proc_count == nprocs or count == mapNum:
for i in range(len(name_list)):
proc_list[i].join()
filename = queue_list[i].get()
@@ -333,7 +345,7 @@
# Unfortunately the png files must be read here,
# since the swig wx objects can not be serialized by the Queue object :(
if filename == None:
- self.bitmapPool[name_list[i]] = wx.EmptyBitmap(self.imageWidth, self.imageHeight)
+ self.bitmapPool[name_list[i]] = wx.EmptyBitmap(imageWidth, imageHeight)
else:
self.bitmapPool[name_list[i]] = wx.BitmapFromImage(wx.Image(filename))
os.remove(filename)
@@ -396,11 +408,11 @@
"""!Render raster or vector files as png image and write the
resulting png filename in the provided file queue
- @param mapType Must be "rast" or "vect"
- @param mapname raster or vector map name to be rendered
- @param width Width of the resulting image
- @param height Height of the resulting image
- @param fileQueue The inter process communication queue storing the file name of the image
+ @param mapType Must be "rast" or "vect"
+ @param mapname raster or vector map name to be rendered
+ @param width Width of the resulting image
+ @param height Height of the resulting image
+ @param fileQueue The inter process communication queue storing the file name of the image
"""
# temporary file, we use python here to avoid calling g.tempfile for each render process
@@ -410,17 +422,21 @@
# Set the environment variables for this process
os.environ['GRASS_WIDTH'] = str(width)
os.environ['GRASS_HEIGHT'] = str(height)
- os.environ['GRASS_RENDER_IMMEDIATE'] = "png"
+ driver = UserSettings.Get(group = 'display', key = 'driver', subkey = 'type')
+ os.environ['GRASS_RENDER_IMMEDIATE'] = driver
os.environ['GRASS_TRUECOLOR'] = "1"
os.environ['GRASS_TRANSPARENT'] = "1"
os.environ['GRASS_PNGFILE'] = str(filename)
-
- if mapType == "rast":
+
+ if mapType in ('rast', 'strds'):
Debug.msg(1, "Render raster image " + str(filename))
returncode, stdout, messages = read2_command('d.rast', map = mapname)
- else:
+ elif mapType in ('vect', 'stvds'):
Debug.msg(1, "Render vector image " + str(filename))
returncode, stdout, messages = read2_command('d.vect', map = mapname)
+ else:
+ returncode = 1
+ return
if returncode != 0:
fileQueue.put(None)
@@ -444,7 +460,7 @@
return key in self.bitmaps
def Clear(self, usedKeys):
- """!Removes all bitmaps which are currentlu not used.
+ """!Removes all bitmaps which are currently not used.
@param usedKeys keys which are currently used
"""
Modified: grass/trunk/gui/wxpython/animation/temporal_manager.py
===================================================================
--- grass/trunk/gui/wxpython/animation/temporal_manager.py 2013-04-16 08:31:10 UTC (rev 55828)
+++ grass/trunk/gui/wxpython/animation/temporal_manager.py 2013-04-16 10:28:07 UTC (rev 55829)
@@ -72,7 +72,6 @@
"""
self._gatherInformation(timeseries, etype, self.timeseriesList, self.timeseriesInfo)
-
def EvaluateInputData(self):
"""!Checks if all timeseries are compatible (raises GException).
@@ -311,6 +310,7 @@
sp.select()
# Get ordered map list
maps = sp.get_registered_maps_as_objects()
+
if not sp.check_temporal_topology(maps):
raise GException(_("Topology of Space time dataset %s is invalid." % id))
More information about the grass-commit
mailing list