[GRASS-SVN] r58807 - in grass/trunk: lib/python/temporal temporal temporal/t.vect.mapcalc temporal/t.vect.mapcalc/test_suite

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Jan 30 09:00:32 PST 2014


Author: huhabla
Date: 2014-01-30 09:00:32 -0800 (Thu, 30 Jan 2014)
New Revision: 58807

Added:
   grass/trunk/lib/python/temporal/temporal_vector_algebra.py
   grass/trunk/lib/python/temporal/temporal_vector_operator.py
   grass/trunk/temporal/t.vect.mapcalc/
   grass/trunk/temporal/t.vect.mapcalc/Makefile
   grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.html
   grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.py
   grass/trunk/temporal/t.vect.mapcalc/test_suite/
   grass/trunk/temporal/t.vect.mapcalc/test_suite/test.t.vect.mapcalc.sh
Modified:
   grass/trunk/lib/python/temporal/Makefile
   grass/trunk/lib/python/temporal/__init__.py
   grass/trunk/lib/python/temporal/register.py
   grass/trunk/lib/python/temporal/temporal_algebra.py
Log:
Added modified temporal vector algebra code from GSoC 2013 student Thomas Leppelt.


Modified: grass/trunk/lib/python/temporal/Makefile
===================================================================
--- grass/trunk/lib/python/temporal/Makefile	2014-01-29 19:29:26 UTC (rev 58806)
+++ grass/trunk/lib/python/temporal/Makefile	2014-01-30 17:00:32 UTC (rev 58807)
@@ -8,7 +8,7 @@
 GDIR = $(PYDIR)/grass
 DSTDIR = $(GDIR)/temporal
 
-MODULES = base core abstract_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets open_stds factory gui_support list_stds register sampling metadata spatial_extent temporal_extent datetime_math temporal_granularity spatio_temporal_relationships unit_tests aggregation stds_export stds_import extract mapcalc univar_statistics temporal_topology_dataset_connector spatial_topology_dataset_connector c_libraries_interface temporal_algebra
+MODULES = base core abstract_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets open_stds factory gui_support list_stds register sampling metadata spatial_extent temporal_extent datetime_math temporal_granularity spatio_temporal_relationships unit_tests aggregation stds_export stds_import extract mapcalc univar_statistics temporal_topology_dataset_connector spatial_topology_dataset_connector c_libraries_interface temporal_algebra temporal_vector_algebra temporal_vector_operator
 
 PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
 PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)

Modified: grass/trunk/lib/python/temporal/__init__.py
===================================================================
--- grass/trunk/lib/python/temporal/__init__.py	2014-01-29 19:29:26 UTC (rev 58806)
+++ grass/trunk/lib/python/temporal/__init__.py	2014-01-30 17:00:32 UTC (rev 58807)
@@ -26,3 +26,5 @@
 from univar_statistics import *
 from c_libraries_interface import *
 from temporal_algebra import *
+from temporal_vector_algebra import *
+from temporal_vector_operator import *

Modified: grass/trunk/lib/python/temporal/register.py
===================================================================
--- grass/trunk/lib/python/temporal/register.py	2014-01-29 19:29:26 UTC (rev 58806)
+++ grass/trunk/lib/python/temporal/register.py	2014-01-30 17:00:32 UTC (rev 58807)
@@ -172,6 +172,12 @@
 
         # Get a new instance of the map type
         map = dataset_factory(type, maplist[count]["id"])
+        
+        if map.map_exists() is not True:
+            msgr.fatal(_("Unable to update %(t)s map <%(id)s>. "
+                            "The map does not exists.") %
+                            {'t': map.get_type(),
+                            'id': map.get_map_id()})
 
         # Use the time data from file
         if "start" in maplist[count]:

Modified: grass/trunk/lib/python/temporal/temporal_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_algebra.py	2014-01-29 19:29:26 UTC (rev 58806)
+++ grass/trunk/lib/python/temporal/temporal_algebra.py	2014-01-30 17:00:32 UTC (rev 58807)
@@ -2,12 +2,12 @@
 
 Temporal algebra parser class
 
-(C) 2013 by the GRASS Development Team
+(C) 2014 by the GRASS Development Team
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 
- at author Thomas Leppelt and Soeren Gebbert
+ at authors Thomas Leppelt and Soeren Gebbert
 
 @code
 
@@ -659,13 +659,9 @@
         self.run = run
         self.debug = debug
         self.pid = pid
-        self.lexer = TemporalAlgebraLexer()
-        self.lexer.build()
         # Intermediate vector map names
         self.names = {}
         # Count map names
-        self.count = 0
-        self.parser = yacc.yacc(module=self, debug=False)
         self.spatial = spatial
         self.null = null
         self.mapset = get_current_mapset()
@@ -679,6 +675,10 @@
             self.dbif.close()
 
     def parse(self, expression, stdstype = 'strds', basename = None):
+        self.lexer = TemporalAlgebraLexer()
+        self.lexer.build()
+        self.parser = yacc.yacc(module=self, debug=self.debug)
+
         self.count = 0
         self.stdstype = stdstype
         self.basename = basename
@@ -1685,19 +1685,21 @@
                                                         'mean', None, \
                                                         overwrite = grass.overwrite())
             if isinstance(t[3], list):
-                dbif, connect = init_dbif(None)
                 num = len(t[3])
                 count = 0
-                for map in t[3]:
-                    map.select()
-                    #map.update()
-                    resultstds.register_map(map, dbif)
-                    count += 1
-                    if count % 10 == 0:
-                        self.msgr.percent(count, num, 1)
+                if num > 0:
+                    dbif, connected = init_dbif(None)
+                    for map in t[3]:
+                        map.select(dbif=dbif)
+                        #map.update()
+                        resultstds.register_map(map, dbif=dbif)
+                        count += 1
+                        if count % 10 == 0:
+                            self.msgr.percent(count, num, 1)
 
-                resultstds.update_from_registered_maps(dbif)
-                dbif.close()
+                    resultstds.update_from_registered_maps(dbif=dbif)
+                    if connected:
+                        dbif.close()
             t[0] = t[3]
 
         if self.debug:
@@ -2249,7 +2251,6 @@
                 print t[3] + "* = tshift(", t[3], ",", t[5], ")"
             t[0] = t[3] + "*"
 
-
     # Handle errors.
     def p_error(self, t):
         raise SyntaxError("syntax error on line %d near '%s' expression '%s'" %

Added: grass/trunk/lib/python/temporal/temporal_vector_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_vector_algebra.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_vector_algebra.py	2014-01-30 17:00:32 UTC (rev 58807)
@@ -0,0 +1,1013 @@
+"""!@package grass.temporal
+
+Temporal vector algebra
+
+(C) 2014 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at authors Thomas Leppelt and Soeren Gebbert
+
+ at code
+
+    >>> import grass.temporal as tgis
+    >>> tgis.init(True)
+    >>> p = tgis.TemporalVectorAlgebraLexer()
+    >>> p.build()
+    >>> p.debug = True
+    >>> expression =  "C = A : B"
+    >>> p.test(expression)
+    C = A : B
+    LexToken(NAME,'C',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'A',1,4)
+    LexToken(T_SELECT,':',1,6)
+    LexToken(NAME,'B',1,8)
+    >>> expression =  "C = test1 !: test2"
+    >>> p.test(expression)
+    C = test1 !: test2
+    LexToken(NAME,'C',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'test1',1,4)
+    LexToken(T_NOT_SELECT,'!:',1,10)
+    LexToken(NAME,'test2',1,13)
+    >>> expression =  "C = test1 {equal,:} test2"
+    >>> p.test(expression)
+    C = test1 {equal,:} test2
+    LexToken(NAME,'C',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'test1',1,4)
+    LexToken(T_SELECT_OPERATOR,'{equal,:}',1,10)
+    LexToken(NAME,'test2',1,20)
+    >>> expression =  "C = test1 {equal,!:} test2"
+    >>> p.test(expression)
+    C = test1 {equal,!:} test2
+    LexToken(NAME,'C',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'test1',1,4)
+    LexToken(T_SELECT_OPERATOR,'{equal,!:}',1,10)
+    LexToken(NAME,'test2',1,21)
+    >>> expression =  "C = test1 # test2"
+    >>> p.test(expression)
+    C = test1 # test2
+    LexToken(NAME,'C',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'test1',1,4)
+    LexToken(HASH,'#',1,10)
+    LexToken(NAME,'test2',1,12)
+    >>> expression =  "C = test1 {#} test2"
+    >>> p.test(expression)
+    C = test1 {#} test2
+    LexToken(NAME,'C',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'test1',1,4)
+    LexToken(T_HASH_OPERATOR,'{#}',1,10)
+    LexToken(NAME,'test2',1,14)
+    >>> expression =  "C = test1 {equal,#} test2"
+    >>> p.test(expression)
+    C = test1 {equal,#} test2
+    LexToken(NAME,'C',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'test1',1,4)
+    LexToken(T_HASH_OPERATOR,'{equal,#}',1,10)
+    LexToken(NAME,'test2',1,20)
+    >>> expression =  "C = test1 {equal|during,#} test2"
+    >>> p.test(expression)
+    C = test1 {equal|during,#} test2
+    LexToken(NAME,'C',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'test1',1,4)
+    LexToken(T_HASH_OPERATOR,'{equal|during,#}',1,10)
+    LexToken(NAME,'test2',1,27)
+    >>> expression =  "E = test1 : test2 !: test1"
+    >>> p.test(expression)
+    E = test1 : test2 !: test1
+    LexToken(NAME,'E',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'test1',1,4)
+    LexToken(T_SELECT,':',1,10)
+    LexToken(NAME,'test2',1,12)
+    LexToken(T_NOT_SELECT,'!:',1,18)
+    LexToken(NAME,'test1',1,21)
+    >>> expression =  'D = buff_t(test1,"10 months")'
+    >>> p.test(expression)
+    D = buff_t(test1,"10 months")
+    LexToken(NAME,'D',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(BUFF_T,'buff_t',1,4)
+    LexToken(LPAREN,'(',1,10)
+    LexToken(NAME,'test1',1,11)
+    LexToken(COMMA,',',1,16)
+    LexToken(QUOTE,'"',1,17)
+    LexToken(INT,10,1,18)
+    LexToken(NAME,'months',1,21)
+    LexToken(QUOTE,'"',1,27)
+    LexToken(RPAREN,')',1,28)
+    >>> expression =  'H = tsnap(test1)'
+    >>> p.test(expression)
+    H = tsnap(test1)
+    LexToken(NAME,'H',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(TSNAP,'tsnap',1,4)
+    LexToken(LPAREN,'(',1,9)
+    LexToken(NAME,'test1',1,10)
+    LexToken(RPAREN,')',1,15)
+    >>> expression =  'H = tsnap(test2 {during,:} buff_t(test1, "1 days"))'
+    >>> p.test(expression)
+    H = tsnap(test2 {during,:} buff_t(test1, "1 days"))
+    LexToken(NAME,'H',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(TSNAP,'tsnap',1,4)
+    LexToken(LPAREN,'(',1,9)
+    LexToken(NAME,'test2',1,10)
+    LexToken(T_SELECT_OPERATOR,'{during,:}',1,16)
+    LexToken(BUFF_T,'buff_t',1,27)
+    LexToken(LPAREN,'(',1,33)
+    LexToken(NAME,'test1',1,34)
+    LexToken(COMMA,',',1,39)
+    LexToken(QUOTE,'"',1,41)
+    LexToken(INT,1,1,42)
+    LexToken(NAME,'days',1,44)
+    LexToken(QUOTE,'"',1,48)
+    LexToken(RPAREN,')',1,49)
+    LexToken(RPAREN,')',1,50)
+    >>> expression =  'H = tshift(test2 {during,:} buff_t(test1, "1 days"), "1 months")'
+    >>> p.test(expression)
+    H = tshift(test2 {during,:} buff_t(test1, "1 days"), "1 months")
+    LexToken(NAME,'H',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(TSHIFT,'tshift',1,4)
+    LexToken(LPAREN,'(',1,10)
+    LexToken(NAME,'test2',1,11)
+    LexToken(T_SELECT_OPERATOR,'{during,:}',1,17)
+    LexToken(BUFF_T,'buff_t',1,28)
+    LexToken(LPAREN,'(',1,34)
+    LexToken(NAME,'test1',1,35)
+    LexToken(COMMA,',',1,40)
+    LexToken(QUOTE,'"',1,42)
+    LexToken(INT,1,1,43)
+    LexToken(NAME,'days',1,45)
+    LexToken(QUOTE,'"',1,49)
+    LexToken(RPAREN,')',1,50)
+    LexToken(COMMA,',',1,51)
+    LexToken(QUOTE,'"',1,53)
+    LexToken(INT,1,1,54)
+    LexToken(NAME,'months',1,56)
+    LexToken(QUOTE,'"',1,62)
+    LexToken(RPAREN,')',1,63)
+    >>> expression =  'H = tshift(A , 10)'
+    >>> p.test(expression)
+    H = tshift(A , 10)
+    LexToken(NAME,'H',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(TSHIFT,'tshift',1,4)
+    LexToken(LPAREN,'(',1,10)
+    LexToken(NAME,'A',1,11)
+    LexToken(COMMA,',',1,13)
+    LexToken(INT,10,1,15)
+    LexToken(RPAREN,')',1,17)
+    >>> expression =  'H = if(td(A) > 10, A)'
+    >>> p.test(expression)
+    H = if(td(A) > 10, A)
+    LexToken(NAME,'H',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(IF,'if',1,4)
+    LexToken(LPAREN,'(',1,6)
+    LexToken(TD,'td',1,7)
+    LexToken(LPAREN,'(',1,9)
+    LexToken(NAME,'A',1,10)
+    LexToken(RPAREN,')',1,11)
+    LexToken(GREATER,'>',1,13)
+    LexToken(INT,10,1,15)
+    LexToken(COMMA,',',1,17)
+    LexToken(NAME,'A',1,19)
+    LexToken(RPAREN,')',1,20)
+    >>> expression =  'H = if(td(A) > 10, A, B)'
+    >>> p.test(expression)
+    H = if(td(A) > 10, A, B)
+    LexToken(NAME,'H',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(IF,'if',1,4)
+    LexToken(LPAREN,'(',1,6)
+    LexToken(TD,'td',1,7)
+    LexToken(LPAREN,'(',1,9)
+    LexToken(NAME,'A',1,10)
+    LexToken(RPAREN,')',1,11)
+    LexToken(GREATER,'>',1,13)
+    LexToken(INT,10,1,15)
+    LexToken(COMMA,',',1,17)
+    LexToken(NAME,'A',1,19)
+    LexToken(COMMA,',',1,20)
+    LexToken(NAME,'B',1,22)
+    LexToken(RPAREN,')',1,23)
+    >>> expression =  'I = if(equals,td(A) > 10 {equals,||} td(B) < 10, A)'
+    >>> p.test(expression)
+    I = if(equals,td(A) > 10 {equals,||} td(B) < 10, A)
+    LexToken(NAME,'I',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(IF,'if',1,4)
+    LexToken(LPAREN,'(',1,6)
+    LexToken(NAME,'equals',1,7)
+    LexToken(COMMA,',',1,13)
+    LexToken(TD,'td',1,14)
+    LexToken(LPAREN,'(',1,16)
+    LexToken(NAME,'A',1,17)
+    LexToken(RPAREN,')',1,18)
+    LexToken(GREATER,'>',1,20)
+    LexToken(INT,10,1,22)
+    LexToken(T_OVERLAY_OPERATOR,'{equals,||}',1,25)
+    LexToken(TD,'td',1,37)
+    LexToken(LPAREN,'(',1,39)
+    LexToken(NAME,'B',1,40)
+    LexToken(RPAREN,')',1,41)
+    LexToken(LOWER,'<',1,43)
+    LexToken(INT,10,1,45)
+    LexToken(COMMA,',',1,47)
+    LexToken(NAME,'A',1,49)
+    LexToken(RPAREN,')',1,50)
+    >>> expression =  'I = if(equals,td(A) > 10 || start_day() < 10, A)'
+    >>> p.test(expression)
+    I = if(equals,td(A) > 10 || start_day() < 10, A)
+    LexToken(NAME,'I',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(IF,'if',1,4)
+    LexToken(LPAREN,'(',1,6)
+    LexToken(NAME,'equals',1,7)
+    LexToken(COMMA,',',1,13)
+    LexToken(TD,'td',1,14)
+    LexToken(LPAREN,'(',1,16)
+    LexToken(NAME,'A',1,17)
+    LexToken(RPAREN,')',1,18)
+    LexToken(GREATER,'>',1,20)
+    LexToken(INT,10,1,22)
+    LexToken(OR,'|',1,25)
+    LexToken(OR,'|',1,26)
+    LexToken(START_DAY,'start_day',1,28)
+    LexToken(LPAREN,'(',1,37)
+    LexToken(RPAREN,')',1,38)
+    LexToken(LOWER,'<',1,40)
+    LexToken(INT,10,1,42)
+    LexToken(COMMA,',',1,44)
+    LexToken(NAME,'A',1,46)
+    LexToken(RPAREN,')',1,47)
+    >>> expression =  'E = if({equals},td(A) >= 4 {contain,&&} td(B) == 2, C : D)'
+    >>> p.test(expression)
+    E = if({equals},td(A) >= 4 {contain,&&} td(B) == 2, C : D)
+    LexToken(NAME,'E',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(IF,'if',1,4)
+    LexToken(LPAREN,'(',1,6)
+    LexToken(T_REL_OPERATOR,'{equals}',1,7)
+    LexToken(COMMA,',',1,15)
+    LexToken(TD,'td',1,16)
+    LexToken(LPAREN,'(',1,18)
+    LexToken(NAME,'A',1,19)
+    LexToken(RPAREN,')',1,20)
+    LexToken(GREATER_EQUALS,'>=',1,22)
+    LexToken(INT,4,1,25)
+    LexToken(T_OVERLAY_OPERATOR,'{contain,&&}',1,27)
+    LexToken(TD,'td',1,40)
+    LexToken(LPAREN,'(',1,42)
+    LexToken(NAME,'B',1,43)
+    LexToken(RPAREN,')',1,44)
+    LexToken(CEQUALS,'==',1,46)
+    LexToken(INT,2,1,49)
+    LexToken(COMMA,',',1,50)
+    LexToken(NAME,'C',1,52)
+    LexToken(T_SELECT,':',1,54)
+    LexToken(NAME,'D',1,56)
+    LexToken(RPAREN,')',1,57)
+    >>> expression =  'F = if({equals},A {equal,#}, B, C : D)'
+    >>> p.test(expression)
+    F = if({equals},A {equal,#}, B, C : D)
+    LexToken(NAME,'F',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(IF,'if',1,4)
+    LexToken(LPAREN,'(',1,6)
+    LexToken(T_REL_OPERATOR,'{equals}',1,7)
+    LexToken(COMMA,',',1,15)
+    LexToken(NAME,'A',1,16)
+    LexToken(T_HASH_OPERATOR,'{equal,#}',1,18)
+    LexToken(COMMA,',',1,27)
+    LexToken(NAME,'B',1,29)
+    LexToken(COMMA,',',1,30)
+    LexToken(NAME,'C',1,32)
+    LexToken(T_SELECT,':',1,34)
+    LexToken(NAME,'D',1,36)
+    LexToken(RPAREN,')',1,37)
+    >>> expression =  'E = A : B ^ C : D'
+    >>> p.test(expression)
+    E = A : B ^ C : D
+    LexToken(NAME,'E',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'A',1,4)
+    LexToken(T_SELECT,':',1,6)
+    LexToken(NAME,'B',1,8)
+    LexToken(XOR,'^',1,10)
+    LexToken(NAME,'C',1,12)
+    LexToken(T_SELECT,':',1,14)
+    LexToken(NAME,'D',1,16)
+    >>> expression =  'E = A : B {|^} C : D'
+    >>> p.test(expression)
+    E = A : B {|^} C : D
+    LexToken(NAME,'E',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'A',1,4)
+    LexToken(T_SELECT,':',1,6)
+    LexToken(NAME,'B',1,8)
+    LexToken(T_OVERLAY_OPERATOR,'{|^}',1,10)
+    LexToken(NAME,'C',1,15)
+    LexToken(T_SELECT,':',1,17)
+    LexToken(NAME,'D',1,19)
+    >>> expression =  'E = buff_a(A, 10)'
+    >>> p.test(expression)
+    E = buff_a(A, 10)
+    LexToken(NAME,'E',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(BUFF_AREA,'buff_a',1,4)
+    LexToken(LPAREN,'(',1,10)
+    LexToken(NAME,'A',1,11)
+    LexToken(COMMA,',',1,12)
+    LexToken(INT,10,1,14)
+    LexToken(RPAREN,')',1,16)
+    >>> p = tgis.TemporalVectorAlgebraParser()
+    >>> p.run = False
+    >>> p.debug = True
+    >>> expression =  "D = A : (B !: C)"
+    >>> p.parse(expression)
+    B* =  B !: C
+    A* =  A : B*
+    D = A*
+    >>> expression =  "D = A {!:} B {during,:} C"
+    >>> print(expression)
+    D = A {!:} B {during,:} C
+    >>> p.parse(expression)
+    A* =  A {!:} B
+    A** =  A* {during,:} C
+    D = A**
+    >>> expression =  "D = A {:} B {during,!:} C"
+    >>> print(expression)
+    D = A {:} B {during,!:} C
+    >>> p.parse(expression)
+    A* =  A {:} B
+    A** =  A* {during,!:} C
+    D = A**
+    >>> expression =  "D = A {:} (B {during,!:} (C : E))"
+    >>> print(expression)
+    D = A {:} (B {during,!:} (C : E))
+    >>> p.parse(expression)
+    C* =  C : E
+    B* =  B {during,!:} C*
+    A* =  A {:} B*
+    D = A*
+    >>> p.run = False
+    >>> p.debug = False
+    >>> expression =  "C = test1 : test2"
+    >>> print(expression)
+    C = test1 : test2
+    >>> p.parse(expression, 'stvds')
+    >>> expression =  'D = buff_t(test1,"10 months")'
+    >>> print(expression)
+    D = buff_t(test1,"10 months")
+    >>> p.parse(expression, 'stvds')
+    >>> expression =  'E = test2 {during,:} buff_t(test1,"1 days")'
+    >>> print(expression)
+    E = test2 {during,:} buff_t(test1,"1 days")
+    >>> p.parse(expression, 'stvds')
+    >>> expression =  'F = test2 {equal,:} buff_t(test1,"1 days")'
+    >>> print(expression)
+    F = test2 {equal,:} buff_t(test1,"1 days")
+    >>> p.parse(expression, 'stvds')
+    >>> p.debug = True
+    >>> expression =  'H = tsnap(test2 {during,:} buff_t(test1, "1 days"))'
+    >>> p.parse(expression, 'stvds')
+    test1* = buff_t( test1 , " 1 days " )
+    test2* =  test2 {during,:} test1*
+    test2** = tsnap( test2* )
+    H = test2**
+    >>> expression =  'H = tshift(test2 {during,:} test1, "1 days")'
+    >>> p.parse(expression, 'stvds')
+    test2* =  test2 {during,:} test1
+    test2** = tshift( test2* , " 1 days " )
+    H = test2**
+    >>> expression =  'H = tshift(H, 3)'
+    >>> p.parse(expression, 'stvds')
+    H* = tshift( H , 3 )
+    H = H*
+    >>> expression =  'C = if(td(A) == 2, A)'
+    >>> p.parse(expression, 'stvds')
+    td(A)
+    td(A) == 2
+    A* =  if condition True  then  A
+    C = A*
+    >>> expression =  'C = if(td(A) == 5 || start_date() >= "2010-01-01", A, B)'
+    >>> p.parse(expression, 'stvds')
+    td(A)
+    td(A) == 5
+    start_date >= "2010-01-01"
+    True || True
+    A* =  if condition True  then  A  else  B
+    C = A*
+    >>> expression =  'C = if(td(A) == 5, A, B)'
+    >>> p.parse(expression, 'stvds')
+    td(A)
+    td(A) == 5
+    A* =  if condition True  then  A  else  B
+    C = A*
+
+ at endcode
+"""
+
+try:
+    import ply.yacc as yacc
+except:
+    pass
+
+import grass.pygrass.modules as pygrass
+import grass.script as grass
+from space_time_datasets import *
+from factory import *
+from open_stds import *
+import copy
+from temporal_vector_operator import *
+from temporal_algebra import *
+
+m_overlay = pygrass.Module('v.overlay', quiet=True, run_=False)
+m_rename = pygrass.Module('g.rename', quiet=True, run_=False)
+m_patch = pygrass.Module('v.patch', quiet=True, run_=False)
+m_mremove = pygrass.Module('g.mremove', quiet=True, run_=False)
+m_buffer = pygrass.Module('v.buffer', quiet=True, run_=False)
+
+##############################################################################
+
+class TemporalVectorAlgebraLexer(TemporalAlgebraLexer):
+    """!Lexical analyzer for the GRASS GIS temporal vector algebra"""
+
+    def __init__(self):
+        TemporalAlgebraLexer.__init__(self)
+
+    # Buffer functions from v.buffer
+    vector_buff_functions = {
+       'buff_p'  : 'BUFF_POINT',
+       'buff_l'   : 'BUFF_LINE',
+       'buff_a'   : 'BUFF_AREA',
+       }
+
+    # This is the list of token names.
+    vector_tokens = (
+        'DISOR',
+        'XOR',
+        'NOT',
+        'T_OVERLAY_OPERATOR',
+    )
+
+    # Build the token list
+    tokens = TemporalAlgebraLexer.tokens \
+                    + vector_tokens \
+                    + tuple(vector_buff_functions.values())
+
+    # Regular expression rules for simple tokens
+    t_DISOR              = r'\+'
+    t_XOR                = r'\^'
+    t_NOT                = r'\~'
+    t_T_OVERLAY_OPERATOR = r'\{([a-zA-Z\|]+[,])?([\|&+=]?[\|&+=\^\~])\}'
+
+    # Parse symbols
+    def temporal_symbol(self, t):
+        # Check for reserved words
+        if t.value in TemporalVectorAlgebraLexer.time_functions.keys():
+            t.type = TemporalVectorAlgebraLexer.time_functions.get(t.value)
+        elif t.value in TemporalVectorAlgebraLexer.datetime_functions.keys():
+            t.type = TemporalVectorAlgebraLexer.datetime_functions.get(t.value)
+        elif t.value in TemporalVectorAlgebraLexer.conditional_functions.keys():
+            t.type = TemporalVectorAlgebraLexer.conditional_functions.get(t.value)
+        elif t.value in TemporalVectorAlgebraLexer.vector_buff_functions.keys():
+            t.type = TemporalVectorAlgebraLexer.vector_buff_functions.get(t.value)
+        else:
+            t.type = 'NAME'
+        return t
+
+class TemporalVectorAlgebraParser(TemporalAlgebraParser):
+    """The temporal algebra class"""
+
+    # Get the tokens from the lexer class
+    tokens = TemporalVectorAlgebraLexer.tokens
+      
+    def remove_intermediate_vector_maps(self):
+        """! Removes the intermediate vector maps.
+        """
+        if self.names != {}:
+            namelist = self.names.values()
+            max = 100
+            chunklist = [namelist[i:i + max] for i in range(0, len(namelist), max)]
+            for chunk in chunklist:
+                stringlist = ",".join(chunk)
+                if self.debug:
+                    print "g.mremove vect=%s"%(stringlist)
+
+                if self.run:
+                    m = copy.deepcopy(m_mremove)
+                    m.inputs["vect"].value = stringlist
+                    m.flags["f"].value = True
+                    m.run()
+
+    # Setting equal precedence level for select and hash operations.
+    precedence = (
+        ('left', 'T_SELECT_OPERATOR', 'T_SELECT', 'T_NOT_SELECT'), # 1
+        ('left', 'AND', 'OR', 'T_COMP_OPERATOR', 'T_OVERLAY_OPERATOR', 'DISOR', \
+          'NOT', 'XOR'), #2
+        )
+
+    def __init__(self, pid=None, run=False, debug=True, spatial = False):
+        TemporalAlgebraParser.__init__(self, pid, run, debug, spatial)
+
+    def parse(self, expression, stdstype = 'strds', basename = None):
+        self.lexer = TemporalVectorAlgebraLexer()
+        self.lexer.build()
+        self.parser = yacc.yacc(module=self, debug=self.debug)
+
+        self.count = 0
+        self.stdstype = stdstype
+        self.basename = basename
+        self.expression = expression
+        self.parser.parse(expression)
+
+
+    ######################### Temporal functions ##############################
+
+    def eval_toperator(self, operator, comparison = False):
+        """!This function evaluates a string containing temporal operations.
+
+          @param operator String of temporal operations, e.g. {equal|during,=!:}.
+
+          @return List of temporal relations (equal, during), the given function
+           (!:) and the interval/instances (=).
+
+          @code
+          >>> import grass.temporal as tgis
+          >>> tgis.init(True)
+          >>> p = tgis.TemporalVectorAlgebraParser()
+          >>> operator = "{equal,:}"
+          >>> p.eval_toperator(operator)
+          (['EQUAL'], '=', ':')
+          >>> operator = "{equal|during,:}"
+          >>> p.eval_toperator(operator)
+          (['EQUAL', 'DURING'], '=', ':')
+          >>> operator = "{equal,!:}"
+          >>> p.eval_toperator(operator)
+          (['EQUAL'], '=', '!:')
+          >>> operator = "{equal|during,!:}"
+          >>> p.eval_toperator(operator)
+          (['EQUAL', 'DURING'], '=', '!:')
+          >>> operator = "{equal|during,=!:}"
+          >>> p.eval_toperator(operator)
+          (['EQUAL', 'DURING'], '=', '!:')
+          >>> operator = "{equal|during|starts,#}"
+          >>> p.eval_toperator(operator)
+          (['EQUAL', 'DURING', 'STARTS'], '=', '#')
+          >>> operator = "{!:}"
+          >>> p.eval_toperator(operator)
+          (['EQUAL'], '=', '!:')
+          >>> operator = "{=:}"
+          >>> p.eval_toperator(operator)
+          (['EQUAL'], '=', ':')
+          >>> operator = "{#}"
+          >>> p.eval_toperator(operator)
+          (['EQUAL'], '=', '#')
+          >>> operator = "{equal|during}"
+          >>> p.eval_toperator(operator)
+          (['EQUAL', 'DURING'], None, None)
+          >>> operator = "{equal}"
+          >>> p.eval_toperator(operator)
+          (['EQUAL'], None, None)
+          >>> operator = "{equal,||}"
+          >>> p.eval_toperator(operator, True)
+          (['EQUAL'], '=', '||')
+          >>> operator = "{equal|during,&&}"
+          >>> p.eval_toperator(operator, True)
+          (['EQUAL', 'DURING'], '=', '&&')
+          >>> operator = "{&}"
+          >>> p.eval_toperator(operator)
+          (['EQUAL'], '=', '&')
+
+          @endcode
+
+        """
+
+        p = TemporalVectorOperatorParser()
+        p.parse(operator, comparison)
+        p.relations = [rel.upper() for rel in p.relations]
+
+        return(p.relations, p.temporal, p.function)
+
+    def overlay_map_extent(self, mapA, mapB, bool_op = None, temp_op = '=',
+                            copy = False):
+        """!Compute the spatio-temporal extent of two topological related maps
+
+           @param mapA The first map
+           @param mapB The second maps
+           @param bool_op The boolean operator specifying the spatial extent
+                  operation (intersection, union, disjoint union)
+           @param temp_op The temporal operator specifying the temporal
+                  exntent operation (intersection, union, disjoint union)
+           @param copy Specifies if the temporal extent of mapB should be
+                  copied to mapA
+        """
+        returncode = 1
+        if copy:
+            map_extent_temporal = mapB.get_temporal_extent()
+            map_extent_spatial = mapB.get_spatial_extent()
+            # Set initial map extend of new vector map.
+            mapA.set_spatial_extent(map_extent_spatial)
+            mapA.set_temporal_extent(map_extent_temporal)
+            if "cmd_list" in dir(mapB):
+                mapA.cmd_list = mapB.cmd_list
+        else:
+            # Calculate spatial extent for different overlay operations.
+            if bool_op == 'and':
+                overlay_ext = mapA.spatial_intersection(mapB)
+                if overlay_ext != None:
+                    mapA.set_spatial_extent(overlay_ext)
+                else:
+                    returncode = 0
+            elif bool_op in ['or', 'xor']:
+                overlay_ext = mapA.spatial_union(mapB)
+                if overlay_ext != None:
+                    mapA.set_spatial_extent(overlay_ext)
+                else:
+                    returncode = 0
+            elif bool_op == 'disor':
+                overlay_ext = mapA.spatial_disjoint_union(mapB)
+                if overlay_ext != None:
+                    mapA.set_spatial_extent(overlay_ext)
+                else:
+                    returncode = 0
+            # Conditional append of command list.
+            if "cmd_list" in dir(mapA) and "cmd_list" in dir(mapB):
+                mapA.cmd_list = mapA.cmd_list + mapB.cmd_list
+            elif "cmd_list" not in dir(mapA) and "cmd_list" in dir(mapB):
+                mapA.cmd_list = mapB.cmd_list
+            # Calculate temporal extent for different temporal operators.
+            if temp_op == '&':
+                temp_ext = mapA.temporal_intersection(mapB)
+                if temp_ext != None:
+                    mapA.set_temporal_extent(temp_ext)
+                else:
+                    returncode = 0
+            elif temp_op == '|':
+                temp_ext = mapA.temporal_union(mapB)
+                if temp_ext != None:
+                    mapA.set_temporal_extent(temp_ext)
+                else:
+                    returncode = 0
+            elif temp_op == '+':
+                temp_ext = mapA.temporal_disjoint_union(mapB)
+                if temp_ext != None:
+                    mapA.set_temporal_extent(temp_ext)
+                else:
+                    returncode = 0
+
+        return(returncode)
+
+    ###########################################################################
+
+    def p_statement_assign(self, t):
+        # The expression should always return a list of maps.
+        """
+        statement : stds EQUALS expr
+
+        """
+        # Execute the command lists
+        if self.run:
+            if isinstance(t[3], list):
+                num = len(t[3])
+                count = 0
+                returncode = 0
+                register_list = []
+                for i in range(num):
+                    # Check if resultmap names exist in GRASS database.
+                    vectorname = self.basename + "_" + str(i)
+                    vectormap = VectorDataset(vectorname + "@" + get_current_mapset())
+                    if vectormap.map_exists() and grass.overwrite() == False:
+                        self.msgr.fatal(_("Error vector maps with basename %s exist. "
+                                      "Use --o flag to overwrite existing file") \
+                                      %(vectorname))
+                for map_i in t[3]:
+                    if "cmd_list" in dir(map_i):
+                        # Execute command list.
+                        for cmd in map_i.cmd_list:
+                            try:
+                                # We need to check if the input maps have areas in case of v.overlay
+                                # otherwise v.overlay will break
+                                if cmd.name == "v.overlay":
+                                    for name in (cmd.inputs["ainput"].value,
+                                                    cmd.inputs["binput"].value):
+                                        #self.msgr.message("Check if map <" + name + "> exists")
+                                        if name.find("@") < 0:
+                                            name = name + "@" + get_current_mapset()
+                                        tmp_map = map_i.get_new_instance(name)
+                                        if not tmp_map.map_exists():
+                                            raise Exception
+                                        #self.msgr.message("Check if map <" + name + "> has areas")
+                                        tmp_map.load()
+                                        if tmp_map.metadata.get_number_of_areas() == 0:
+                                            raise Exception
+                            except Exception:
+                                returncode = 1
+                                break
+
+                            # run the command
+                            # print the command that will be executed
+                            self.msgr.message("Run command:\n" + cmd.get_bash())
+                            cmd.run()
+                            if cmd.popen.returncode != 0:
+                                self.msgr.fatal(_("Error starting %s : \n%s") \
+                                                    %(cmd.get_bash(), \
+                                                    cmd.popen.stderr))
+                            mapname = cmd.outputs['output'].value
+                            if mapname.find("@") >= 0:
+                                map_test = map_i.get_new_instance(mapname)
+                            else:
+                                map_test = map_i.get_new_instance(mapname + "@" + self.mapset)
+                            if not map_test.map_exists():
+                                returncode = 1
+                                break
+                        if returncode == 0:
+                            # We remove the invalid vector name from the remove list.
+                            if self.names.has_key(map_i.get_name()):
+                                self.names.pop(map_i.get_name())
+                            mapset = map_i.get_mapset()
+                            # Change map name to given basename.
+                            newident = self.basename + "_" + str(count)
+                            m = copy.deepcopy(m_rename)
+                            m.inputs["vect"].value = (map_i.get_name(),newident)
+                            m.flags["overwrite"].value = grass.overwrite()
+                            m.run()
+                            #m(vect = (map_i.get_name(),newident), \
+                            #    overwrite = grass.overwrite)
+                            map_i.set_id(newident + "@" + mapset)
+                            count += 1
+                            register_list.append(map_i)
+                    else:
+                        register_list.append(map_i)
+                        
+                if len(register_list) > 0:
+                    # Open connection to temporal database.
+                    dbif, connected = init_dbif(dbif=self.dbif)
+                    # Create result space time dataset.
+                    resultstds = open_new_space_time_dataset(t[1], self.stdstype, \
+                                                                'absolute', t[1], t[1], \
+                                                                'mean', None, \
+                                                                overwrite = grass.overwrite())
+                    for map_i in register_list:
+                        # Check if modules should be executed from command list.
+                        if "cmd_list" in dir(map_i):
+                            # Get meta data from grass database.
+                            map_i.load()
+                            if map_i.is_in_db(dbif=dbif) and grass.overwrite():
+                                # Update map in temporal database.
+                                map_i.update_all(dbif=dbif)
+                            elif map_i.is_in_db(dbif=dbif) and grass.overwrite() == False:
+                                # Raise error if map exists and no overwrite flag is given.
+                                self.msgr.fatal(_("Error vector map %s exist in temporal database. "
+                                                  "Use overwrite flag.  : \n%s") \
+                                                  %(map_i.get_map_id(), cmd.popen.stderr))
+                            else:
+                                # Insert map into temporal database.
+                                map_i.insert(dbif=dbif)
+                        else:
+                            #Get metadata from temporal database.
+                            map_i.select(dbif=dbif)
+                        # Register map in result space time dataset.
+                        resultstds.register_map(map_i, dbif=dbif)
+                        #count += 1
+                        #if count % 10 == 0:
+                        #    grass.percent(count, num, 1)
+                    resultstds.update_from_registered_maps(dbif=dbif)
+                    if connected:
+                        dbif.close()
+                self.remove_intermediate_vector_maps()
+            t[0] = register_list
+
+        if self.debug:
+            if isinstance(t[3], list):
+                for map_i in t[3]:
+                    print(map_i.get_id())
+            else:
+                print(t[1] + " = " + str(t[3]))
+            t[0] = t[3]
+
+    def p_overlay_operation(self, t):
+        """
+        expr : stds AND stds
+             | expr AND stds
+             | stds AND expr
+             | expr AND expr
+             | stds OR stds
+             | expr OR stds
+             | stds OR expr
+             | expr OR expr
+             | stds XOR stds
+             | expr XOR stds
+             | stds XOR expr
+             | expr XOR expr
+             | stds NOT stds
+             | expr NOT stds
+             | stds NOT expr
+             | expr NOT expr
+             | stds DISOR stds
+             | expr DISOR stds
+             | stds DISOR expr
+             | expr DISOR expr
+        """
+        # Check input stds.
+        maplistA = self.check_stds(t[1])
+        maplistB = self.check_stds(t[3])
+
+        if self.run:
+            t[0] = self.create_overlay_operations(maplistA, maplistB, ("EQUAL",), "=", t[2])
+        if self.debug:
+            t[0] = t[1]
+
+    def p_overlay_operation_relation(self, t):
+        """
+        expr : stds T_OVERLAY_OPERATOR stds
+             | expr T_OVERLAY_OPERATOR stds
+             | stds T_OVERLAY_OPERATOR expr
+             | expr T_OVERLAY_OPERATOR expr
+        """
+        # Check input stds.
+        maplistA = self.check_stds(t[1])
+        maplistB = self.check_stds(t[3])
+        relations, temporal, function= self.eval_toperator(t[2])
+
+        if self.run:
+            t[0] = self.create_overlay_operations(maplistA, maplistB, relations, temporal, function)
+        if self.debug:
+            t[0] = t[1]
+
+    def create_overlay_operations(self, maplistA, maplistB, relations, temporal, function):
+        """!Create the spatial overlay operation commad list
+        
+           @param maplistA A list of map objects
+           @param maplistB A list of map objects
+           @param relations The temporal relationships that must be fullfilled as list of strings
+                            ("EQUAL", "DURING", ...)
+           @param temporal The temporal operator as string "=" or "&", ...
+           @param function The spatial overlay operations as string "&", "|", ...
+           @return Return the list of maps with overlay commands
+        """
+        topolist = self.get_temporal_topo_list(maplistA, maplistB, topolist = relations)
+        
+        # Select operation name.
+        if function == "&":
+            opname = "and"
+        elif function == "|":
+            opname = "or"
+        elif function == "^":
+            opname = "xor"
+        elif function == "~":
+            opname = "not"
+        elif function == "+":
+            opname = "disor"
+
+        if self.run:
+            resultlist = []
+            for map_i in topolist:
+                # Generate an intermediate name for the result map list.
+                name = self.generate_map_name()
+                # Get mapset input.
+                mapset = get_current_mapset()
+                # Check for mapset in given stds input.
+                mapname = name + "@" + mapset
+                # Create new map based on the related map list.
+                map_new = map_i.get_new_instance(mapname)
+                # Set initial map extend of new vector map.
+                self.overlay_map_extent(map_new, map_i, bool_op = opname, copy = True)
+                # Set first input for overlay module.
+                mapainput = map_i.get_id()
+                # Loop over temporal related maps and create overlay modules.
+                tbrelations = map_i.get_temporal_relations()
+                count = 0
+                for topo in relations:
+                    if topo in tbrelations.keys():
+                        for map_j in (tbrelations[topo]):
+                            # Create overlayed map extent.
+                            returncode = self.overlay_map_extent(map_new, map_j, opname, \
+                                                                    temp_op = temporal)
+                            # Stop the loop if no temporal or spatial relationship exist.
+                            if returncode == 0:
+                                break
+                            if count == 0:
+                                # Set map name.
+                                name = map_new.get_id()
+                            else:
+                                # Generate an intermediate name
+                                name = self.generate_map_name()
+                                map_new.set_id(name + "@" + mapset)
+                            # Set second input for overlay module.
+                            mapbinput = map_j.get_id()
+                            # Create module command in PyGRASS for v.overlay and v.patch.
+                            if opname != "disor":
+                                m = copy.deepcopy(m_overlay)
+                                m.run_ = False
+                                m.inputs["operator"].value = opname
+                                m.inputs["ainput"].value = str(mapainput)
+                                m.inputs["binput"].value = str(mapbinput)
+                                m.outputs["output"].value = name
+                                m.flags["overwrite"].value = grass.overwrite()
+                            else:
+                                patchinput = str(mapainput) + ',' + str(mapbinput)
+                                m = copy.deepcopy(m_patch)
+                                m.run_ = False
+                                m.inputs["input"].value = patchinput
+                                m.outputs["output"].value = name
+                                m.flags["overwrite"].value = grass.overwrite()
+                            # Conditional append of module command.
+                            if "cmd_list" in dir(map_new):
+                                map_new.cmd_list.append(m)
+                            else:
+                                map_new.cmd_list = [m]
+                            # Set new map name to temporary map name.
+                            mapainput = name
+                            count += 1
+                        if returncode == 0:
+                            break
+                # Append map to result map list.
+                if returncode == 1:
+                    resultlist.append(map_new)
+
+            return resultlist
+
+    def p_buffer_operation(self,t):
+        """
+        expr : buff_function LPAREN stds COMMA number RPAREN
+             | buff_function LPAREN expr COMMA number RPAREN
+        """
+
+        if self.run:
+            # Check input stds.
+            bufflist = self.check_stds(t[3])
+            # Create empty result list.
+            resultlist = []
+
+            for map_i in bufflist:
+                # Generate an intermediate name
+                name = self.generate_map_name()
+                # Get mapset input.
+                mapset = get_current_mapset()
+                # Check for mapset in given stds input.
+                mapname = name + "@" + mapset
+                # Create new map based on the related map list.
+                map_new = map_i.get_new_instance(mapname)
+                # Set initial map extend of new vector map.
+                self.overlay_map_extent(map_new, map_i, copy = True)
+                # Change spatial extent based on buffer size.
+                map_new.spatial_buffer(float(t[5]))
+                # Check buff type.
+                if t[1] == "buff_p":
+                    buff_type = "point"
+                elif t[1] == "buff_l":
+                    buff_type = "line"
+                elif t[1] == "buff_a":
+                    buff_type = "area"
+                m = copy.deepcopy(m_buffer)
+                m.run_ = False
+                m.inputs["type"].value = buff_type
+                m.inputs["input"].value = str(map_i.get_id())
+                m.inputs["distance"].value = float(t[5])
+                m.outputs["output"].value = name
+                m.flags["overwrite"].value = grass.overwrite()
+
+                # Conditional append of module command.
+                if "cmd_list" in dir(map_new):
+                    map_new.cmd_list.append(m)
+                else:
+                    map_new.cmd_list = [m]
+                resultlist.append(map_new)
+
+            t[0] = resultlist
+
+        if self.debug:
+            pass
+
+    def p_buff_function(self, t):
+        """buff_function    : BUFF_POINT
+                            | BUFF_LINE
+                            | BUFF_AREA
+                            """
+        t[0] = t[1]
+
+    # Handle errors.
+    def p_error(self, t):
+        raise SyntaxError("syntax error on line %d near '%s' expression '%s'" %
+            (t.lineno, t.value, self.expression))
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
+
+

Added: grass/trunk/lib/python/temporal/temporal_vector_operator.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_vector_operator.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_vector_operator.py	2014-01-30 17:00:32 UTC (rev 58807)
@@ -0,0 +1,349 @@
+"""!@package grass.temporal
+
+Temporal vector operator evaluation with PLY
+
+(C) 2014 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at authors Thomas Leppelt and Soeren Gebbert
+
+ at code
+    >>> import grass.temporal as tgis
+    >>> tgis.init(True)
+    >>> p = tgis.TemporalVectorOperatorParser()
+    >>> expression =  "{equal| during,&&}"
+    >>> p.parse(expression, True)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during'], '=', '&&')
+    >>> expression =  "{equal| during | follows,&&}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during', 'follows'], '&', '&')
+    >>> expression =  "{equal| during | follows,+!:}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during', 'follows'], '+', '!:')
+    >>> expression =  "{equal| during,!:}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during'], '=', '!:')
+    >>> expression =  "{!:}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal'], '=', '!:')
+    >>> expression =  "{&&}"
+    >>> p.parse(expression, True)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal'], '=', '&&')
+    >>> expression =  "{&&}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal'], '&', '&')
+    >>> expression =  "{|#}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal'], '|', '#')
+    >>> expression =  "{equal,||}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal'], '|', '|')
+    >>> expression =  "{equal|during,=!:}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during'], '=', '!:')
+    >>> expression =  "{equal|during|starts}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during', 'starts'], None, None)
+    >>> expression =  "{over| equal,||}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    ([['overlaps', 'overlapped'], 'equal'], '|', '|')
+    
+ at endcode
+"""
+try:
+    import ply.lex as lex
+    import ply.yacc as yacc
+except:
+    pass
+
+class TemporalVectorOperatorLexer(object):
+    """!Lexical analyzer for the GRASS GIS temporal vector operators"""
+    
+    # Functions that defines topological relations.
+    relations = {
+        'equal'      : "EQUAL",
+        'follows'    : "FOLLOWS",
+        'precedes'   : "PRECEDES",
+        'overlaps'   : "OVERLAPS",
+        'overlapped' : "OVERLAPPED",
+        'during'     : "DURING",
+        'starts'     : "STARTS",
+        'finishes'   : "FINISHES",
+        'contains'   : "CONTAINS",
+        'started'    : "STARTED",
+        'finished'   : "FINISHED",
+        'over'       : "OVER"
+        }
+        
+    # This is the list of token names.
+    tokens = (
+        'COMMA',
+        'LEFTREF',
+        'HASH',
+        'OR',
+        'AND',
+        'DISOR',
+        'XOR',
+        'NOT',
+        'T_SELECT',
+        'T_NOT_SELECT',
+        'CLPAREN',
+        'CRPAREN',
+    )
+    
+    # Build the token list
+    tokens = tokens + tuple(relations.values())
+
+    # Regular expression rules for simple tokens
+    t_T_SELECT           = r':'
+    t_T_NOT_SELECT       = r'!:'
+    t_COMMA              = r','
+    t_LEFTREF             = r'='
+    t_HASH               = r'\#'
+    t_OR                 = r'[\|]'
+    t_AND                = r'[&]'
+    t_DISOR              = r'\+'
+    t_XOR                = r'\^'
+    t_NOT                = r'\~'
+    t_CLPAREN             = r'\{'
+    t_CRPAREN             = r'\}'
+    
+    # These are the things that should be ignored.
+    t_ignore = ' \t'
+
+    # Track line numbers.
+    def t_newline(self, t):
+        r'\n+'
+        t.lineno += len(t.value)
+        
+    def t_NAME(self, t):
+        r'[a-zA-Z_][a-zA-Z_0-9]*'
+        self.temporal_symbol(t)
+        return t
+        
+    # Parse symbols
+    def temporal_symbol(self, t):
+        # Check for reserved words
+        if t.value in TemporalVectorOperatorLexer.relations.keys():
+            t.type = TemporalVectorOperatorLexer.relations.get(t.value)
+        #else:
+        #    t.type = 'NAME'
+        return(t)
+
+    # Handle errors.
+    def t_error(self, t):
+        raise SyntaxError("syntax error on line %d near '%s'" % 
+            (t.lineno, t.value))
+
+    # Build the lexer
+    def build(self,**kwargs):
+        self.lexer = lex.lex(module=self, **kwargs)
+        
+    # Just for testing
+    def test(self,data):
+        self.name_list = {}
+        print(data)
+        self.lexer.input(data)
+        while True:
+             tok = self.lexer.token()
+             if not tok: break
+             print tok
+             
+class TemporalVectorOperatorParser(object):
+    """!The parser for the GRASS GIS temporal vector operators"""
+    
+    def __init__(self):
+        self.lexer = TemporalVectorOperatorLexer()
+        self.lexer.build()
+        self.parser = yacc.yacc(module=self)
+
+    def parse(self, expression, comparison = False):
+        self.comparison = comparison
+        self.parser.parse(expression)
+        
+    # Error rule for syntax errors.
+    def p_error(self, t):
+        raise SyntaxError("invalid syntax")
+
+    # Get the tokens from the lexer class
+    tokens = TemporalVectorOperatorLexer.tokens
+
+    def p_relation_only(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN relation CRPAREN
+                 | CLPAREN relationlist CRPAREN
+        """
+        # Set three operator components.
+        if isinstance(t[2], list):
+            self.relations = t[2]
+        else:
+            self.relations = [t[2]]
+        self.temporal  = None 
+        self.function  = None
+        
+        t[0] = t[2]
+
+
+    def p_operator(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN select CRPAREN
+                 | CLPAREN HASH CRPAREN
+                 | CLPAREN overlay CRPAREN
+        """
+        # Set three operator components.
+        self.relations = ['equal']
+        self.temporal  = "=" 
+        self.function  = t[2]
+        
+        t[0] = t[2]
+        
+    def p_operator_temporal(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN temporal select CRPAREN
+                 | CLPAREN temporal HASH CRPAREN
+                 | CLPAREN temporal overlay CRPAREN
+        """
+        # Set three operator components.
+        self.relations = ['equal']
+        if self.comparison:
+            self.temporal = "="
+            self.function = t[2] + t[3]
+        else:
+            self.temporal = t[2]
+            self.function = t[3]
+        
+        t[0] = t[3]
+
+    def p_operator_relation(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN relation COMMA select CRPAREN
+                 | CLPAREN relationlist COMMA select CRPAREN
+                 | CLPAREN relation COMMA HASH CRPAREN
+                 | CLPAREN relationlist COMMA HASH CRPAREN
+                 | CLPAREN relation COMMA overlay CRPAREN
+                 | CLPAREN relationlist COMMA overlay CRPAREN
+        """
+        # Set three operator components.
+        if isinstance(t[2], list):
+            self.relations = t[2]
+        else:
+            self.relations = [t[2]]
+        self.temporal  = "=" 
+        self.function  = t[4]
+        
+        t[0] = t[4]
+
+    def p_operator_relation_temporal(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN relation COMMA temporal select CRPAREN
+                 | CLPAREN relationlist COMMA temporal select CRPAREN
+                 | CLPAREN relation COMMA temporal HASH CRPAREN
+                 | CLPAREN relationlist COMMA temporal HASH CRPAREN
+                 | CLPAREN relation COMMA temporal overlay CRPAREN
+                 | CLPAREN relationlist COMMA temporal overlay CRPAREN
+        """
+        # Set three operator components.
+        if isinstance(t[2], list):
+            self.relations = t[2]
+        else:
+            self.relations = [t[2]]
+        if self.comparison:
+            self.temporal = "="
+            self.function = t[4] + t[5]
+        else:
+            self.temporal = t[4]
+            self.function = t[5]
+        t[0] = t[5]
+        
+    def p_relation(self, t):
+        # The list of relations.
+        """
+        relation : EQUAL
+                 | FOLLOWS
+                 | PRECEDES
+                 | OVERLAPS
+                 | OVERLAPPED
+                 | DURING
+                 | STARTS
+                 | FINISHES
+                 | CONTAINS
+                 | STARTED
+                 | FINISHED
+        """
+        t[0] = t[1]
+        
+    def p_over(self, t):
+        # The list of relations.
+        """
+        relation : OVER
+        """
+        over_list = ["overlaps", "overlapped"]
+        t[0] = over_list
+
+    def p_relationlist(self, t):
+        # The list of relations.
+        """
+        relationlist : relation OR relation
+                     | relation OR relationlist
+        """
+        rel_list = []
+        rel_list.append(t[1])
+        if isinstance(t[3], list):
+            rel_list = rel_list + t[3]
+        else:
+            rel_list.append(t[3])
+        t[0] =  rel_list
+
+    def p_temporal_operator(self, t):
+        # The list of relations.
+        """
+        temporal : LEFTREF
+                 | OR
+                 | AND
+                 | DISOR
+        """
+        t[0] = t[1]
+
+    def p_select_operator(self, t):
+        # The list of relations.
+        """
+        select : T_SELECT
+               | T_NOT_SELECT
+        """
+        t[0] = t[1]
+
+    def p_overlay_operator(self, t):
+        # The list of relations.
+        """
+        overlay : OR
+                | AND
+                | DISOR
+                | XOR
+                | NOT
+        """
+        t[0] = t[1]
+###############################################################################             
+        
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
+    
\ No newline at end of file

Added: grass/trunk/temporal/t.vect.mapcalc/Makefile
===================================================================
--- grass/trunk/temporal/t.vect.mapcalc/Makefile	                        (rev 0)
+++ grass/trunk/temporal/t.vect.mapcalc/Makefile	2014-01-30 17:00:32 UTC (rev 58807)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../../
+
+PGM = t.vect.mapcalc
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script

Added: grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.html
===================================================================
--- grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.html	                        (rev 0)
+++ grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.html	2014-01-30 17:00:32 UTC (rev 58807)
@@ -0,0 +1,340 @@
+<h2>DESCRIPTION</h2> 
+
+t.vect.mapcalc performs temporal and spatial overlay and buffer functions on space time vector datasets (STVDS)
+by using the temporal vector algebra. New STVDS can be created, which are expressions of existing STVDS.
+
+<h3>PROGRAM USE</h3> 
+The module expects an <b>expression</b> as input parameter in the following form: <br>
+<br>
+<b> "result = expression" </b>
+<br>
+<br>
+
+The statement structure is similar to r.mapcalc, see <a href="r.mapcalc.html">r.mapcalc</a>.
+Where <b>result</b> represents the name of a space time vector dataset (STVDS)that will 
+contain the result of the calculation that is given as <b>expression</b> 
+on the right side of the equality sign. 
+These expression can be any valid or nested combination of temporal 
+operations and spatial overlay or buffer functions that are provided by the temporal algebra.  <br>
+The temporal vector algebra works with space time vector datasets only (STVDS).
+The algebra provides methods for map selection from STVDS based on their temporal relations. 
+It is also possible to temporally shift maps, to create temporal buffer and to snap time 
+instances to create a valid temporal topology. Furthermore expressions can be nested and 
+evaluated in conditional statements (if, else statements). Within if-statements the algebra 
+provides temporal variables like start time, end time, day of year, time differences or 
+number of maps per time interval to build up conditions. In addition the algebra provides 
+the spatial operations for vector overlay and buffering. All these operations can be assigned 
+to STVDS or to the resulting map lists of operations between STVDS. 
+<br>
+<br>
+As default, topological relationships between space time datasets will be 
+evaluated only temporal. Use the <b>s</b> flag to activate the 
+additionally evaluate the spatial topology based on the spatial extents of maps.
+<br>
+<br>
+The expression option must be passed as <b>quoted</b> 
+expression, for example: <br>
+<div class="code"><pre>t.vect.mapcalc expression="C = A & B" basename=result</pre></div> 
+Where <b>C</b> is the new space time vector dataset that will contain maps
+with the basename "result" that represent the intersection of maps from STVDS <b>A</b> and 
+equally temporal related maps from STVDS <b>B</b>.
+<br>
+<br>
+The map basename for the result STVDS must always be specified.
+
+<h2>Temporal vector algebra</h2>
+
+The temporal vector algebra provides a wide range of temporal and spatial operators and 
+functions that will be presented in the following section. <br>
+<br>
+
+<h3>Temporal relations</h3>
+
+Several temporal topology relations between space 
+time datasets are supported: <br>
+<div class="code"><pre>
+equals            A ------
+                  B ------
+
+during            A  ---- 
+                  B ------
+
+contains          A ------
+                  B  ---- 
+
+starts            A ----
+                  B ------
+
+started           A ------
+                  B ----
+
+finishs           A   ---- 
+                  B ------
+
+finished          A ------
+                  B   ----
+
+precedes          A ----
+                  B     ----
+
+follows           A     ----
+                  B ----
+
+overlapped        A   ------
+                  B ------
+
+overlaps          A ------
+                  B   ------
+
+over              booth overlaps and overlapped
+
+</pre></div>
+The relations must be read as: A is related to B, like - A equals B - A is 
+during B - A contains B <br>
+<br>
+Topological relations must be specified in {} parentheses. <br>
+
+<h3>Temporal Selection</h3>
+
+The temporal selection simply selects parts of a space time dataset without 
+processing raster or vector data.
+
+The algebra provides a selection operator <b>:</b> that selects parts 
+of a space time dataset that are temporally equal to parts of a second one 
+by default. The following expression
+<div class="code"><pre>
+C = A : B
+</pre></div>
+means: Select all parts of space time dataset A that are equal to B and store 
+it in space time dataset C. The parts are time stamped maps. <br>
+<br>
+In addition the inverse selection operator <b>!:</b> is defined as the complement of 
+the selection operator, hence the following expression
+<div class="code"><pre>
+C = A !: B
+</pre></div>
+means: select all parts of space time time dataset A that are not equal to B 
+and store it in space time dataset (STDS) C. <br>
+<br>
+To select parts of a STDS by different topological relations to other STDS, 
+the temporal topology selection operator can be used. The operator consists of 
+topological relations, that must be separated by the logical OR operator 
+<b>|</b> and the temporal selection operator. Both parts are separated by 
+comma and surrounded by curly braces: 
+{"topological relations", "temporal selection operator"}  <br>
+<br>
+Examples:
+<div class="code"><pre>
+C = A {equals,:} B
+C = A {equals,!:} B
+</pre></div>
+We can now define arbitrary topological relations using logical OR operator 
+to connect them:
+<div class="code"><pre>
+C = A {equals|during|overlaps,:} B
+</pre></div>
+Select all parts of A that are equal to B, during B or overlaps B. <br>
+<br>
+The selection operator is implicitly contained in the temporal topology 
+selection operator, so that the following statements are exactly the same:
+<div class="code"><pre>
+C = A : B
+C = A {:} B
+C = A {equal,:} B
+</pre></div>
+
+Same for the complementary selection:
+<div class="code"><pre>
+C = A !: B
+C = A {!:} B
+C = A {equal,!:} B
+</pre></div>
+
+<h3>Conditional statements</h3>
+
+Selection operations can be evaluated within conditional statements.
+<br>
+<div class="code"><pre>
+Note A and B can either be space time datasets or expressions.
+
+if statement                         decision option                        temporal relations
+  if(if, then, else)
+  if(conditions, A)                    A if conditions are True;              temporal topological relation between if and then is equal.
+  if(conditions, A, B)                 A if conditions are True, B otherwise; temporal topological relation between if, then and else is equal.
+  if(topologies, conditions, A)        A if conditions are True;              temporal topological relation between if and then is explicit specified by topologies.
+  if(topologies, conditions, A, B)     A if conditions are True, B otherwise; temporal topological relation between if, then and else is explicit specified by topologies.
+</pre></div>
+The conditions are comparison expressions that are used to evaluate 
+space time datasets. Specific values of temporal variables are 
+compared by logical operators and evaluated for each map of the STDS.
+<br>
+<br>
+The supported logical operators:
+<div class="code"><pre>
+Symbol  description
+
+  ==    equal
+  !=    not equal
+  >     greater than
+  >=    greater than or equal
+  <     less than
+  <=    less than or equal
+  &&    and
+  ||    or
+</pre></div>
+
+Temporal functions: <br>
+<div class="code"><pre>
+
+td(A)                   Returns a list of time intervals of STDS A
+
+start_time()            Start time as HH::MM:SS
+start_date()            Start date as yyyy-mm-DD
+start_datetime()        Start datetime as yyyy-mm-DD HH:MM:SS
+end_time()              End time as HH:MM:SS
+end_date()              End date as yyyy-mm-DD
+end_datetime()          End datetime as  yyyy-mm-DD HH:MM
+
+start_doy()             Day of year (doy) from the start time [1 - 366]
+start_dow()             Day of week (dow) from the start time [1 - 7], the start of the week is Monday == 1
+start_year()            The year of the start time [0 - 9999]
+start_month()           The month of the start time [1 - 12]
+start_week()            Week of year of the start time [1 - 54]
+start_day()             Day of month from the start time [1 - 31]
+start_hour()            The hour of the start time [0 - 23]
+start_minute()          The minute of the start time [0 - 59]
+start_second()          The second of the start time [0 - 59]
+end_doy()               Day of year (doy) from the end time [1 - 366]
+end_dow()               Day of week (dow) from the end time [1 - 7], the start of the week is Monday == 1
+end_year()              The year of the end time [0 - 9999]
+end_month()             The month of the end time [1 - 12]
+end_week()              Week of year of the end time [1 - 54]
+end_day()               Day of month from the start time [1 - 31]
+end_hour()              The hour of the end time [0 - 23]
+end_minute()            The minute of the end time [0 - 59]
+end_second()            The second of the end time [0 - 59]            
+</pre></div>
+
+Additionally the number of maps in intervals can be computed and 
+used in conditional statements. <br>
+The operator to count the number of maps 
+is the hash <b>#</b>. 
+<div class="code"><pre>
+A{contains,#}B
+</pre></div>
+This expression computes the number of maps from space 
+time dataset B which are during the time intervals of maps from 
+space time dataset A.<br>
+A list of integers (scalars) corresponding to the maps of A 
+that contain maps from B will be returned. <br>
+<br>
+
+Furthermore the temporal algebra allows temporal buffering, shifting 
+and snapping with the functions buff_t(), tshift() and tsnap()
+respectively.
+<div class="code"><pre>
+buff_t(A, size)         Buffer STDS A with granule ("1 month" or 5)
+tshift(A, size)         Shift STDS A with granule ("1 month" or 5)
+tsnap(A)                Snap time instances and intervals of STDS A
+</pre></div>
+
+<h3>Temporal Operators</h3>
+<p>
+The temporal algebra defines temporal operators that can be combined 
+later with spatial operators to perform spatio-temporal operations. 
+The temporal operators process the time instances and intervals of temporal related maps. 
+</p>
+<div class="code"><pre>
+AND             &       Intersection 
+OR              |       Union
+DISJOINT OR     +       Disjoint union
+LEFT REFERENCE  =       Use the time stamp of the left space time dataset
+</pre></div><p>
+For example we can compute the intersection, union or disjoint union from time stamps of maps 
+that temporally overlap, or we can just keep the time stamp of the left STDS.
+</p>
+
+<h3>Spatial vector operators</h3>
+
+The module supports the following boolean vector operations: <br>
+<div class="code"><pre>
+ Boolean Name   Operator Meaning         Precedence   Correspondent function 
+---------------------------------------------------------------------------------- 
+ AND            &        Intersection          1      (v.overlay operator=and) 
+ OR             |        Union                 1      (v.overlay operator=or)  
+ DISJOINT OR    +        Disjoint union        1      (v.patch)              
+ XOR            ^        Symmetric difference  1      (v.overlay operator=xor) 
+ NOT            ~        Complement            1      (v.overlay operator=not) 
+
+</pre></div>
+
+And vector functions:
+<div class="code"><pre>
+ buff_p(A, size)    	  Buffer the points of vector map layer A with size
+ buff_l(A, size)    	  Buffer the lines of vector map layer A with size
+ buff_a(A, size)    	  Buffer the areas of vector map layer A with size
+</pre></div>
+<br>
+
+<p>
+<h3>Combinations of temporal, vector and select operators</h3>
+
+We combine the temporal topology relations, the temporal operators and the spatial/select operators to create spatio-temporal operators:
+
+<pre class="code">
+{"list of temporal relations", "temporal operator" "spatial or select operator"} 
+</pre><p>
+The spatial and the select operators can be used stand-alone. In this case the temporal topology relation "equal" and the temporal operator "left reference =" is assumed and used as default. This allows the convenient use of the spatial and select 
+operators in case of space time vector datasets with equal time stamps.
+</p>
+<div class="code"> <pre>
+ ---------------------------------------
+|   |  & |  | |  ^ |  ~ |  + |  : |  !: |
+|---|----|----|----|----|----|----|-----|
+| & | && | &| | &^ | &~ | &+ | &: | &!: |
+| | | |& | || | |^ | |~ | |+ | |: | |!: |
+| + | +& | +| | +^ | +~ | ++ | +: | +!: |
+| = | =& | =| | =^ | =~ | =+ | =: | =!: |
+ ---------------------------------------
+</pre></div>
+
+<h3>Examples: </h3>
+
+Spatio-temporal intersect all maps from space time dataset A with all maps from space time dataset 
+B which have equal time stamps and are temporary before Jan. 1. 2005 and 
+store them in space time dataset D.
+<div class="code"><pre>
+D = if(start_date() < "2005-01-01", A & B)
+</pre></div>
+
+Buffer all vector points from space time vector dataset A and B with a distance of one and
+intersect the results with overlapping, containing, during and equal temporal relations
+to store the result in space time vector dataset D with intersected time stamps.
+<div class="code"><pre>
+D = buff_p(A, 1) {overlaps|overlapped|equal|during|contains,&&} buff_p(B, 1)
+</pre></div>
+
+Select all maps from space time dataset B which are during the temporal 
+buffered space time dataset A with a map interval of three days, else
+select maps from C and store them in space time dataset D.
+<div class="code"><pre>
+D = if(contain, td(buff_t(A, "1 days")) == 3, B, C)
+</pre></div>
+
+<h2>REFERENCES</h2>
+
+<tt><a href="http://www.dabeaz.com/ply/">PLY(Python-Lex-Yacc)</a></tt>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="t.select.html">t.select</a>
+</em>
+
+
+<h2>AUTHOR</h2>
+
+Thomas Leppelt, Soeren Gebbert, Thuenen Institut, Germany <br>
+
+<p><i>Last changed: $Date: 2013-07-24 17:35:20 +0100 (Thu, 24 Jul 2013) $</i>
+

Added: grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.py
===================================================================
--- grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.py	                        (rev 0)
+++ grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.py	2014-01-30 17:00:32 UTC (rev 58807)
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+############################################################################
+#
+# MODULE:       t.vect.mapcalc
+# AUTHOR(S):    Thomas Leppelt, Soeren Gebbert
+#
+# PURPOSE:      Provide temporal vector algebra to perform spatial an temporal operations
+#               for space time datasets by topological relationships to other space time
+#               datasets.
+# COPYRIGHT:    (C) 2014 by the GRASS Development Team
+#
+#               This program is free software under the GNU General Public
+#               License (version 2). Read the file COPYING that comes with GRASS
+#               for details.
+#
+#############################################################################
+
+#%module
+#% description: Apply temporal and spatial oeprations on space time vector datasets using temporal vector algebra.
+#% keywords: temporal
+#% keywords: mapalgebra
+#%end
+
+#%option
+#% key: expression
+#% type: string
+#% description: The mapcalc expression for temporal and spatial analysis of space time vector datasets.
+#% key_desc: expression
+#% required : yes
+#%end
+
+#%option
+#% key: basename
+#% type: string
+#% description: The basename of vector maps that are stored within the result space time vector dataset.
+#% key_desc: basename
+#% required : yes
+#%end
+
+#%flag
+#% key: s
+#% description: Activate spatial topology.
+#%end
+
+import grass.script as grass
+import grass.temporal as tgis
+import sys
+
+def main():
+    expression = options['expression']
+    basename = options['basename']
+    spatial = flags["s"]
+    stdstype = "stvds"
+
+    # Check for PLY istallation
+    try:
+        import ply.lex as lex
+        import ply.yacc as yacc
+    except:
+        grass.fatal(_("Please install PLY (Lex and Yacc Python implementation) to use the temporal algebra modules."))
+
+    tgis.init(True)
+    p = tgis.TemporalVectorAlgebraParser(run = True, debug=False, spatial = spatial)
+    p.parse(expression, stdstype, basename)
+
+if __name__ == "__main__":
+    options, flags = grass.parser()
+    sys.exit(main())
+

Added: grass/trunk/temporal/t.vect.mapcalc/test_suite/test.t.vect.mapcalc.sh
===================================================================
--- grass/trunk/temporal/t.vect.mapcalc/test_suite/test.t.vect.mapcalc.sh	                        (rev 0)
+++ grass/trunk/temporal/t.vect.mapcalc/test_suite/test.t.vect.mapcalc.sh	2014-01-30 17:00:32 UTC (rev 58807)
@@ -0,0 +1,77 @@
+#!/usr/bin/sh
+
+g.region s=0 n=80 w=0 e=120 b=0 t=50 res=10 -p
+
+export GRASS_OVERWRITE=1
+
+# Test for temporal algebra in LatLon location.
+rm /tmp/vinput1_point_test.txt
+rm /tmp/vinput2_point_test.txt
+rm /tmp/vinput3_point_test.txt
+rm /tmp/vinput4_point_test.txt
+rm /tmp/vinput1_area_test.txt
+rm /tmp/vinput2_area_test.txt
+rm /tmp/vinput3_area_test.txt
+rm /tmp/vinput4_area_test.txt
+
+# Create random area test maps.
+for i in {1..60}
+  do
+    if [[ "$i" -le 20 ]]; then
+      echo vtestpoint1_$i >> /tmp/vinput1_point_test.txt
+      echo vtestarea1_$i  >> /tmp/vinput1_area_test.txt
+      v.random --o -z output=vtestpoint1_$i n=3 seed=$i+1
+      v.voronoi --o input=vtestpoint1_$i output=vtestarea1_$i
+    elif [ "$i" -gt 20 ] && [ "$i" -le 40 ]; then
+      echo vtestpoint2_$i >> /tmp/vinput2_point_test.txt
+      echo vtestarea2_$i  >> /tmp/vinput2_area_test.txt
+      v.random --o -z output=vtestpoint2_$i n=3 seed=$i+1
+      v.voronoi --o input=vtestpoint2_$i output=vtestarea2_$i
+    else
+      echo vtestpoint3_$i >> /tmp/vinput3_point_test.txt
+      echo vtestpoint4_$i >> /tmp/vinput4_point_test.txt
+      echo vtestarea3_$i  >> /tmp/vinput3_area_test.txt
+      echo vtestarea4_$i  >> /tmp/vinput4_area_test.txt
+      v.random --o -z output=vtestpoint3_$i n=3 seed=$i+1
+      v.voronoi --o input=vtestpoint3_$i output=vtestarea3_$i
+      v.random --o -z output=vtestpoint4_$i n=3 seed=$i+1
+      v.voronoi --o input=vtestpoint4_$i output=vtestarea4_$i
+    fi
+  done
+
+# Create STVDS and register test maps.
+t.create output=A1 type=stvds title="Area test dataset" descr="Area test dataset"
+t.create output=A2 type=stvds title="Area test dataset" descr="Area test dataset"
+t.create output=A3 type=stvds title="Area test dataset" descr="Area test dataset"
+t.create output=A4 type=stvds title="Area test dataset" descr="Area test dataset"
+t.create output=P1 type=stvds title="Point test dataset" descr="Point test dataset"
+t.create output=P2 type=stvds title="Point test dataset" descr="Point test dataset"
+t.create output=P3 type=stvds title="Point test dataset" descr="Point test dataset"
+t.create output=P4 type=stvds title="Point test dataset" descr="Point test dataset"
+
+t.register -i type=vect input=A1 file=/tmp/vinput1_area_test.txt increment="1 days" start="2013-01-01"
+t.register -i type=vect input=A2 file=/tmp/vinput2_area_test.txt increment="1 days" start="2013-01-10"
+t.register -i type=vect input=A3 file=/tmp/vinput3_area_test.txt increment="3 days" start="2013-01-01"
+t.register -i type=vect input=A4 file=/tmp/vinput4_area_test.txt increment="3 days" start="2013-01-10"
+t.register -i type=vect input=P1 file=/tmp/vinput1_point_test.txt increment="1 days" start="2013-01-01"
+t.register -i type=vect input=P2 file=/tmp/vinput2_point_test.txt increment="1 days" start="2013-01-10"
+t.register -i type=vect input=P3 file=/tmp/vinput3_point_test.txt increment="3 days" start="2013-01-01"
+t.register -i type=vect input=P4 file=/tmp/vinput4_point_test.txt increment="3 days" start="2013-01-10"
+
+# Test different options.
+t.vect.mapcalc expression='B1 = A1 & A2' basename="bmap1"
+t.vect.list input=B1 column=name,start_time,end_time
+t.vect.mapcalc expression='B2 = A1 {equal|during,+&} A3' basename="bmap2"
+t.vect.list input=B2 column=name,start_time,end_time
+t.vect.mapcalc expression='B3 = buff_p(P1,10)' basename="bmap3"
+t.vect.list input=B3 column=name,start_time,end_time
+t.vect.mapcalc expression='B4 = buff_p(P2,30) {equal|during,|^} A4' basename="bmap4"
+t.vect.list input=B4 column=name,start_time,end_time
+t.vect.mapcalc expression='B5 = if(td(A1) == 1 || start_date() >= "2010-01-10", A2)' basename="bmap5"
+t.vect.list input=B5 column=name,start_time,end_time
+t.vect.mapcalc expression='B6 = buff_p(P2,30) {equal|during|started,&^} buff_p(P3,30)' basename="bmap6"
+t.vect.list input=B6 column=name,start_time,end_time
+t.vect.mapcalc expression='B7 = buff_p(P2,30) {starts,&^} buff_p(P3,30)' basename="bmap7"
+t.vect.list input=B8 column=name,start_time,end_time
+t.vect.mapcalc expression='B8 = buff_p(P2,30) {starts,|^} buff_p(P3,30)' basename="bmap8"
+t.vect.list input=B8 column=name,start_time,end_time



More information about the grass-commit mailing list