浏览代码

Added temporal raster and 3D raster algebra classes and tests

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@58971 15284696-431f-4ddb-bdfa-cd5b030d7da7
Soeren Gebbert 11 年之前
父节点
当前提交
047fa04d74

文件差异内容过多而无法显示
+ 1 - 1
lib/python/temporal/Makefile


+ 4 - 0
lib/python/temporal/__init__.py

@@ -28,3 +28,7 @@ from c_libraries_interface import *
 from temporal_algebra import *
 from temporal_algebra import *
 from temporal_vector_algebra import *
 from temporal_vector_algebra import *
 from temporal_vector_operator import *
 from temporal_vector_operator import *
+from temporal_raster_operator import *
+from temporal_raster_base_algebra import *
+from temporal_raster_algebra import *
+from temporal_raster3d_algebra import *

+ 4 - 6
lib/python/temporal/open_stds.py

@@ -30,7 +30,7 @@ def open_old_space_time_dataset(name, type, dbif=None):
     """!This function opens an existing space time dataset and return the
     """!This function opens an existing space time dataset and return the
        created and intialized object of the specified type.
        created and intialized object of the specified type.
 
 
-       This function will raise a ScriptError in case the type is wrong,
+       This function will call exit() or raise a grass.pygrass.messages.FatalError in case the type is wrong,
        or the space time dataset was not found.
        or the space time dataset was not found.
 
 
        @param name The name of the space time dataset, if the name does not
        @param name The name of the space time dataset, if the name does not
@@ -112,7 +112,7 @@ def check_new_space_time_dataset(name, type, dbif=None, overwrite=False):
     elif type == "stvds" or type == "vect" or type == "vector":
     elif type == "stvds" or type == "vect" or type == "vector":
         sp = dataset_factory("stvds", id)
         sp = dataset_factory("stvds", id)
     else:
     else:
-        core.error(_("Unkown type: %s") % (type))
+        msgr.error(_("Unkown type: %s") % (type))
         return None
         return None
 
 
     dbif, connected = init_dbif(dbif)
     dbif, connected = init_dbif(dbif)
@@ -142,12 +142,10 @@ def open_new_space_time_dataset(name, type, temporaltype, title, descr, semantic
        @param semantic Semantical information
        @param semantic Semantical information
        @param dbif The temporal database interface to be used
        @param dbif The temporal database interface to be used
        @param overwrite Flag to allow overwriting
        @param overwrite Flag to allow overwriting
-       @param dry Do not create the space time dataset in the temporal database,
-                  make a dry run with including all checks
 
 
        @return The new created space time dataset
        @return The new created space time dataset
 
 
-       This function will raise a ScriptError in case of an error.
+       This function will raise a FatalError in case of an error.
     """
     """
     dbif, connected = init_dbif(dbif)
     dbif, connected = init_dbif(dbif)
     msgr = get_tgis_message_interface()
     msgr = get_tgis_message_interface()
@@ -177,7 +175,7 @@ def open_new_space_time_dataset(name, type, temporaltype, title, descr, semantic
 
 
 ############################################################################
 ############################################################################
 
 
-def check_new_map_dataset(name, layer=None, type="raster", 
+def check_new_map_dataset(name, layer=None, type="raster",
                           overwrite=False, dbif=None):
                           overwrite=False, dbif=None):
     """!Check if a new map dataset of a specific type can be created in
     """!Check if a new map dataset of a specific type can be created in
         the temporal database
         the temporal database

+ 147 - 44
lib/python/temporal/temporal_algebra.py

@@ -390,10 +390,7 @@ try:
 except:
 except:
     pass
     pass
 
 
-import re
-import sys
 import os
 import os
-import grass.pygrass.modules as pygrass
 import grass.script as grass
 import grass.script as grass
 from space_time_datasets import *
 from space_time_datasets import *
 from factory import *
 from factory import *
@@ -608,6 +605,7 @@ class TemporalAlgebraLexer(object):
              print tok
              print tok
 
 
 ###############################################################################
 ###############################################################################
+
 class GlobalTemporalVar(object):
 class GlobalTemporalVar(object):
     """ This class handles global temporal variable conditional expressions,
     """ This class handles global temporal variable conditional expressions,
         like start_doy() == 3.
         like start_doy() == 3.
@@ -650,11 +648,23 @@ class GlobalTemporalVar(object):
 
 
         return(valuelist)
         return(valuelist)
 
 
+    def __str__(self):
+        return str(self.tfunc) + str(self.compop) + str(self.value)
+
 ###############################################################################
 ###############################################################################
 
 
 class TemporalAlgebraParser(object):
 class TemporalAlgebraParser(object):
     """The temporal algebra class"""
     """The temporal algebra class"""
 
 
+    # Get the tokens from the lexer class
+    tokens = TemporalAlgebraLexer.tokens
+
+    # 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'), #2
+        )
+
     def __init__(self, pid=None, run = True, debug = False, spatial = False, null = False):
     def __init__(self, pid=None, run = True, debug = False, spatial = False, null = False):
         self.run = run
         self.run = run
         self.debug = debug
         self.debug = debug
@@ -674,11 +684,12 @@ class TemporalAlgebraParser(object):
         if self.dbif.connected:
         if self.dbif.connected:
             self.dbif.close()
             self.dbif.close()
 
 
-    def parse(self, expression, stdstype = 'strds', basename = None):
+    def parse(self, expression, stdstype = 'strds', basename = None, overwrite=False):
         self.lexer = TemporalAlgebraLexer()
         self.lexer = TemporalAlgebraLexer()
         self.lexer.build()
         self.lexer.build()
         self.parser = yacc.yacc(module=self, debug=self.debug)
         self.parser = yacc.yacc(module=self, debug=self.debug)
 
 
+        self.overwrite = overwrite
         self.count = 0
         self.count = 0
         self.stdstype = stdstype
         self.stdstype = stdstype
         self.basename = basename
         self.basename = basename
@@ -701,14 +712,87 @@ class TemporalAlgebraParser(object):
         self.names[name] = name
         self.names[name] = name
         return name
         return name
 
 
-    # Get the tokens from the lexer class
-    tokens = TemporalAlgebraLexer.tokens
+    def generate_new_map(self, base_map, bool_op = 'and', copy = True):
+        """!Generate a new map using the spatio-temporal extent of the base map
 
 
-    # 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'), #2
-        )
+           @param base_map This map is used to create the new map
+        """
+        # Generate an intermediate name for the result map list.
+        name = self.generate_map_name()
+        # Check for mapset in given stds input.
+        mapname = name + "@" + self.mapset
+        # Create new map based on the related map list.
+        map_new = base_map.get_new_instance(mapname)
+        # Set initial map extend of new vector map.
+        self.overlay_map_extent(map_new, base_map, bool_op = bool_op, copy = copy)
+
+        return map_new
+
+    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
+                  extent operation (intersection, union, disjoint union)
+           @param copy Specifies if the temporal extent of mapB should be
+                  copied to mapA
+           @return 0 if there is no overlay
+        """
+        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
+
+            # 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)
 
 
     ######################### Temporal functions ##############################
     ######################### Temporal functions ##############################
 
 
@@ -1671,6 +1755,7 @@ class TemporalAlgebraParser(object):
             return(inverselist)
             return(inverselist)
         else:
         else:
             return(resultlist)
             return(resultlist)
+
     ###########################################################################
     ###########################################################################
 
 
     def p_statement_assign(self, t):
     def p_statement_assign(self, t):
@@ -1682,8 +1767,8 @@ class TemporalAlgebraParser(object):
         if self.run:
         if self.run:
             resultstds = open_new_space_time_dataset(t[1], self.stdstype, \
             resultstds = open_new_space_time_dataset(t[1], self.stdstype, \
                                                         self.temporaltype, "", "", \
                                                         self.temporaltype, "", "", \
-                                                        'mean', None, \
-                                                        overwrite = grass.overwrite())
+                                                        'mean', dbif=self.dbif, \
+                                                        overwrite = self.overwrite)
             if isinstance(t[3], list):
             if isinstance(t[3], list):
                 num = len(t[3])
                 num = len(t[3])
                 count = 0
                 count = 0
@@ -1702,9 +1787,11 @@ class TemporalAlgebraParser(object):
                         dbif.close()
                         dbif.close()
             t[0] = t[3]
             t[0] = t[3]
 
 
+        else:
+            t[0] = t[3]
+
         if self.debug:
         if self.debug:
             print t[1], "=", t[3]
             print t[1], "=", t[3]
-            t[0] = t[3]
 
 
     def p_stds_1(self, t):
     def p_stds_1(self, t):
         # Definition of a space time dataset
         # Definition of a space time dataset
@@ -1780,11 +1867,12 @@ class TemporalAlgebraParser(object):
                     map_i.map_value = gvar
                     map_i.map_value = gvar
 
 
             t[0] = maplist
             t[0] = maplist
+        else:
+            t[0] = "td(" + str(t[3]) + ")"
 
 
         if self.debug:
         if self.debug:
-            print "td(" + t[3] + ")"
+            print "td(" + str(t[3]) + ")"
 
 
-            t[0] = "td(" + t[3] + ")"
 
 
     def p_t_time_var(self, t):
     def p_t_time_var(self, t):
         # Temporal variables that return a double or integer value
         # Temporal variables that return a double or integer value
@@ -1862,13 +1950,14 @@ class TemporalAlgebraParser(object):
                 gvar.compop = t[4]
                 gvar.compop = t[4]
                 gvar.value  = t[5]
                 gvar.value  = t[5]
                 t[0] = gvar
                 t[0] = gvar
+        else:
+            t[0] = True
 
 
         if self.debug:
         if self.debug:
             if len(t) == 6:
             if len(t) == 6:
                 print t[1], t[4], t[5]
                 print t[1], t[4], t[5]
             if len(t) == 4:
             if len(t) == 4:
                 print t[1], t[2], t[3]
                 print t[1], t[2], t[3]
-            t[0] = True
 
 
     def p_t_var_expr_time1(self, t):
     def p_t_var_expr_time1(self, t):
         # Examples:
         # Examples:
@@ -1889,10 +1978,11 @@ class TemporalAlgebraParser(object):
             gvar.compop = t[4]
             gvar.compop = t[4]
             gvar.value  = t[5]
             gvar.value  = t[5]
             t[0] = gvar
             t[0] = gvar
+        else:
+            t[0] = True
 
 
         if self.debug:
         if self.debug:
             print t[1], t[4], t[5]
             print t[1], t[4], t[5]
-            t[0] = True
 
 
     def p_t_var_expr_time2(self, t):
     def p_t_var_expr_time2(self, t):
         """
         """
@@ -1911,11 +2001,12 @@ class TemporalAlgebraParser(object):
             gvar.compop = reverseop[t[2]]
             gvar.compop = reverseop[t[2]]
             gvar.value  = t[1]
             gvar.value  = t[1]
             t[0] = gvar
             t[0] = gvar
+        else:
+            t[0] = True
 
 
         if self.debug:
         if self.debug:
             print(t[4])
             print(t[4])
             print t[1], t[4], t[5]
             print t[1], t[4], t[5]
-            t[0] = True
 
 
     def p_t_var_expr_comp(self, t):
     def p_t_var_expr_comp(self, t):
         """
         """
@@ -1934,10 +2025,11 @@ class TemporalAlgebraParser(object):
             resultlist.append(tvarexprB)
             resultlist.append(tvarexprB)
 
 
             t[0] = resultlist
             t[0] = resultlist
+        else:
+            t[0] = True
 
 
         if self.debug:
         if self.debug:
             print t[1], t[2] + t[3], t[4]
             print t[1], t[2] + t[3], t[4]
-            t[0] = True
 
 
     def p_t_var_expr_comp_op(self, t):
     def p_t_var_expr_comp_op(self, t):
         """
         """
@@ -1958,10 +2050,11 @@ class TemporalAlgebraParser(object):
             resultlist.append(tvarexprB)
             resultlist.append(tvarexprB)
 
 
             t[0] = resultlist
             t[0] = resultlist
+        else:
+            t[0] = True
 
 
         if self.debug:
         if self.debug:
             print t[1], t[2], t[3]
             print t[1], t[2], t[3]
-            t[0] = True
 
 
     def p_expr_t_select(self, t):
     def p_expr_t_select(self, t):
         # Temporal equal selection
         # Temporal equal selection
@@ -1984,10 +2077,11 @@ class TemporalAlgebraParser(object):
             selectlist = self.perform_temporal_selection(maplistA, maplistB)
             selectlist = self.perform_temporal_selection(maplistA, maplistB)
             # Return map list.
             # Return map list.
             t[0] = selectlist
             t[0] = selectlist
+        else:
+            t[0] = t[1] + "*"
 
 
         if self.debug:
         if self.debug:
             print t[1] + "* = ", t[1], t[2], t[3]
             print t[1] + "* = ", t[1], t[2], t[3]
-            t[0] = t[1] + "*"
 
 
     def p_expr_t_not_select(self, t):
     def p_expr_t_not_select(self, t):
         # Temporal equal selection
         # Temporal equal selection
@@ -2009,10 +2103,11 @@ class TemporalAlgebraParser(object):
                                                          inverse = True)
                                                          inverse = True)
             # Return map list.
             # Return map list.
             t[0] = selectlist
             t[0] = selectlist
+        else:
+            t[0] = t[1] + "*"
 
 
         if self.debug:
         if self.debug:
             print t[1] + "* = ", t[1], t[2], t[3]
             print t[1] + "* = ", t[1], t[2], t[3]
-            t[0] = t[1] + "*"
 
 
 
 
     def p_expr_t_select_operator(self, t):
     def p_expr_t_select_operator(self, t):
@@ -2050,10 +2145,11 @@ class TemporalAlgebraParser(object):
 
 
             # Return map list.
             # Return map list.
             t[0] = selectlist
             t[0] = selectlist
+        else:
+            t[0] = t[1] + "*"
 
 
         if self.debug:
         if self.debug:
             print t[1] + "* = ", t[1], t[2], t[3]
             print t[1] + "* = ", t[1], t[2], t[3]
-            t[0] = t[1] + "*"
 
 
 
 
     def p_expr_condition_if(self, t):
     def p_expr_condition_if(self, t):
@@ -2074,10 +2170,11 @@ class TemporalAlgebraParser(object):
             resultlist   = self.check_stds(thenresult, clear = True)
             resultlist   = self.check_stds(thenresult, clear = True)
             # Return resulting map list.
             # Return resulting map list.
             t[0] = resultlist
             t[0] = resultlist
+        else:
+            t[0] = t[5] + "*"
 
 
         if self.debug:
         if self.debug:
-            print t[5] + "* = ", "if condition", t[3], ' then ', t[5]
-            t[0] = t[5] + "*"
+            print str(t[5]) + "* = ", "if condition", str(t[3]), ' then ', str(t[5])
 
 
     def p_expr_condition_if_relation(self, t):
     def p_expr_condition_if_relation(self, t):
         # Examples
         # Examples
@@ -2098,10 +2195,11 @@ class TemporalAlgebraParser(object):
             resultlist   = self.check_stds(thenresult, clear = True)
             resultlist   = self.check_stds(thenresult, clear = True)
             # Return resulting map list.
             # Return resulting map list.
             t[0] = resultlist
             t[0] = resultlist
+        else:
+            t[0] = t[7] + "*"
 
 
         if self.debug:
         if self.debug:
-            print t[5] + "* = ", "if condition", t[3], ' then ', t[5]
-            t[0] = t[5] + "*"
+            print "result* = ", "if ", str(t[3]),  "condition", str(t[5]), " then ", str(t[7])
 
 
     def p_expr_condition_elif(self, t):
     def p_expr_condition_elif(self, t):
         # Examples
         # Examples
@@ -2130,10 +2228,11 @@ class TemporalAlgebraParser(object):
             resultlist   = self.check_stds(resultlist, clear = True)
             resultlist   = self.check_stds(resultlist, clear = True)
             # Return resulting map list.
             # Return resulting map list.
             t[0] = resultlist
             t[0] = resultlist
+        else:
+            t[0] = t[5] + "*"
 
 
         if self.debug:
         if self.debug:
-            print t[5] + "* = ", "if condition", t[3], " then ", t[5], ' else ', t[7]
-            t[0] = t[5] + "*"
+            print str(t[5]) + "* = ", "if condition", str(t[3]), " then ", str(t[5]), ' else ', str(t[7])
 
 
     def p_expr_condition_elif_relation(self, t):
     def p_expr_condition_elif_relation(self, t):
         # Examples
         # Examples
@@ -2165,15 +2264,18 @@ class TemporalAlgebraParser(object):
             resultlist   = self.check_stds(resultlist, clear = True)
             resultlist   = self.check_stds(resultlist, clear = True)
             # Return resulting map list.
             # Return resulting map list.
             t[0] = resultlist
             t[0] = resultlist
-
-        if self.debug:
+        else:
             if t[5]:
             if t[5]:
-                print t[7], "* = ", "if condition", t[5], " then ", t[7], ' else ', t[9]
                 t[0] = str(t[7])
                 t[0] = str(t[7])
             else:
             else:
-                print t[9], "* = ", "if condition", t[5], " then ", t[7], ' else ', t[9]
                 t[0] = str(t[9])
                 t[0] = str(t[9])
 
 
+        if self.debug:
+            if t[5]:
+                print str(t[7]), "* = ", "if condition", str(t[5]), " then ", str(t[7]), ' else ', str(t[9])
+            else:
+                print str(t[9]), "* = ", "if condition", str(t[5]), " then ", str(t[7]), ' else ', str(t[9])
+
     def p_expr_t_buff(self, t):
     def p_expr_t_buff(self, t):
         # Examples
         # Examples
         # buff_t(A : B, "10 minutes")  # Select the part of A that is temporally
         # buff_t(A : B, "10 minutes")  # Select the part of A that is temporally
@@ -2196,13 +2298,14 @@ class TemporalAlgebraParser(object):
                 # Perform buffering.
                 # Perform buffering.
                 map.temporal_buffer(increment)
                 map.temporal_buffer(increment)
             t[0] = bufflist
             t[0] = bufflist
+        else:
+            t[0] = t[3] + "*"
 
 
         if self.debug:
         if self.debug:
             if len(t) == 10:
             if len(t) == 10:
-                print t[3] + "* = buff_t(", t[3], "," , '"', t[6], t[7], '"', ")"
+                print str(t[3]) + "* = buff_t(", str(t[3]), "," , '"', str(t[6]), str(t[7]), '"', ")"
             elif len(t) == 7:
             elif len(t) == 7:
-                print t[3] + "* = buff_t(", t[3], ",", t[5], ")"
-            t[0] = t[3] + "*"
+                print str(t[3]) + "* = buff_t(", str(t[3]), ",", str(t[5]), ")"
 
 
     def p_expr_t_snap(self, t):
     def p_expr_t_snap(self, t):
         # Examples
         # Examples
@@ -2217,10 +2320,11 @@ class TemporalAlgebraParser(object):
             # Perform snapping.
             # Perform snapping.
             snaplist = AbstractSpaceTimeDataset.snap_map_list(maplist)
             snaplist = AbstractSpaceTimeDataset.snap_map_list(maplist)
             t[0] = snaplist
             t[0] = snaplist
+        else:
+            t[0] = t[3] + "*"
 
 
         if self.debug:
         if self.debug:
-            print t[3] + "* = tsnap(", t[3], ")"
-            t[0] = t[3] + "*"
+            print str(t[3]) + "* = tsnap(", str(t[3]), ")"
 
 
     def p_expr_t_shift(self, t):
     def p_expr_t_shift(self, t):
         # Examples
         # Examples
@@ -2243,13 +2347,14 @@ class TemporalAlgebraParser(object):
             # Perform shifting.
             # Perform shifting.
             shiftlist = AbstractSpaceTimeDataset.shift_map_list(maplist, increment)
             shiftlist = AbstractSpaceTimeDataset.shift_map_list(maplist, increment)
             t[0] = shiftlist
             t[0] = shiftlist
+        else:
+            t[0] = t[3] + "*"
 
 
         if self.debug:
         if self.debug:
             if len(t) == 10:
             if len(t) == 10:
-                print t[3] + "* = tshift(", t[3], "," , '"', t[6], t[7], '"', ")"
+                print str(t[3]) + "* = tshift(", str(t[3]), "," , '"', str(t[6]), str(t[7]), '"', ")"
             elif len(t) == 7:
             elif len(t) == 7:
-                print t[3] + "* = tshift(", t[3], ",", t[5], ")"
-            t[0] = t[3] + "*"
+                print str(t[3]) + "* = tshift(", str(t[3]), ",", str(t[5]), ")"
 
 
     # Handle errors.
     # Handle errors.
     def p_error(self, t):
     def p_error(self, t):
@@ -2261,5 +2366,3 @@ class TemporalAlgebraParser(object):
 if __name__ == "__main__":
 if __name__ == "__main__":
     import doctest
     import doctest
     doctest.testmod()
     doctest.testmod()
-
-

+ 110 - 0
lib/python/temporal/temporal_raster3d_algebra.py

@@ -0,0 +1,110 @@
+"""!@package grass.temporal
+
+Temporal raster algebra
+
+(C) 2013 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.
+
+@author Thomas Leppelt and Soeren Gebbert
+
+"""
+
+from temporal_raster_base_algebra import *
+
+###############################################################################
+
+class TemporalRaster3DAlgebraParser(TemporalRasterBaseAlgebraParser):
+    """The temporal raster algebra class"""
+
+    def __init__(self, pid=None, run=False, debug=True, spatial = False):
+        TemporalRasterBaseAlgebraParser.__init__(self, pid, run, debug, spatial)
+
+        self.m_mapcalc = pygrass.Module('r3.mapcalc')
+
+    def parse(self, expression, basename = None, overwrite=False):
+        self.lexer = TemporalRasterAlgebraLexer()
+        self.lexer.build()
+        self.parser = yacc.yacc(module=self, debug=self.debug)
+
+        self.overwrite = overwrite
+        self.count = 0
+        self.stdstype = "str3ds"
+        self.basename = basename
+        self.expression = expression
+        self.parser.parse(expression)
+
+    ######################### Temporal functions ##############################
+
+    def p_statement_assign(self, t):
+        # The expression should always return a list of maps.
+        """
+        statement : stds EQUALS expr
+        """
+        TemporalRasterBaseAlgebraParser.p_statement_assign(self, t)
+
+    def p_ts_neighbor_operation(self, t):
+        # Examples:
+        # A[1,0,-1]
+        # B[-2]
+        # C[1,-2,1,3]
+        """
+        expr : stds L_SPAREN number COMMA number COMMA number R_SPAREN
+             | stds L_SPAREN number R_SPAREN
+             | stds L_SPAREN number COMMA number COMMA number COMMA number R_SPAREN
+        """
+        # Check input stds.
+        maplist = self.check_stds(t[1])
+        t_neighbor = 0
+        row_neighbor = None
+        col_neighbor = None
+        depth_neighbor = None
+        if len(t) == 5:
+            t_neighbor = t[3]
+        elif len(t) == 9:
+            row_neighbor = t[3]
+            col_neighbor = t[5]
+            depth_neighbor = t[7]
+        elif len(t) == 11:
+            t_neighbor = t[9]
+            row_neighbor = t[3]
+            col_neighbor = t[5]
+            depth_neighbor = t[7]
+        if self.run:
+            resultlist = []
+            max_index = len(maplist)
+            for map_i in maplist:
+                # Get map index and temporal extent.
+                map_index = maplist.index(map_i)
+                new_index = map_index + t_neighbor
+                if new_index < max_index and new_index >= 0:
+                    map_i_t_extent = map_i.get_temporal_extent()
+                    # Get neighboring map and set temporal extent.
+                    map_n = maplist[new_index]
+                    # Generate an intermediate map for the result map list.
+                    map_new = self.generate_new_map(map_n, bool_op = 'and', copy = True)
+                    map_new.set_temporal_extent(map_i_t_extent)
+                    # Create r.mapcalc expression string for the operation.
+                    if "cmd_list" in dir(map_new) and len(t) == 5:
+                        cmdstring = "%s" %(map_new.cmd_list)
+                    elif "cmd_list" not in dir(map_new) and len(t) == 5:
+                        cmdstring = "%s" %(map_n.get_id())
+                    elif "cmd_list" in dir(map_new) and len(t) in (9,11):
+                        cmdstring = "%s[%s,%s,%s]" %(map_new.cmd_list, row_neighbor, col_neighbor, depth_neighbor)
+                    elif "cmd_list" not in dir(map_new) and len(t) in (9,11):
+                        cmdstring = "%s[%s,%s,%s]" %(map_n.get_id(), row_neighbor, col_neighbor, depth_neighbor)
+                    # Set new command list for map.
+                    map_new.cmd_list = cmdstring
+                    # Append map with updated command list to result list.
+                    resultlist.append(map_new)
+
+            t[0] = resultlist
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
+
+

+ 149 - 0
lib/python/temporal/temporal_raster_algebra.py

@@ -0,0 +1,149 @@
+"""!@package grass.temporal
+
+Temporal raster algebra
+
+(C) 2013 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.
+
+@author Thomas Leppelt and Soeren Gebbert
+
+@code
+
+    >>> p = TemporalRasterAlgebraLexer()
+    >>> p.build()
+    >>> p.debug = True
+    >>> expression =  'R = A[0,1,0] / B[0,0,1] * 20 + C[0,1,1] - 2.45'
+    >>> p.test(expression)
+    R = A[0,1,0] / B[0,0,1] * 20 + C[0,1,1] - 2.45
+    LexToken(NAME,'R',1,0)
+    LexToken(EQUALS,'=',1,2)
+    LexToken(NAME,'A',1,4)
+    LexToken(L_SPAREN,'[',1,5)
+    LexToken(INT,0,1,6)
+    LexToken(COMMA,',',1,7)
+    LexToken(INT,1,1,8)
+    LexToken(COMMA,',',1,9)
+    LexToken(INT,0,1,10)
+    LexToken(R_SPAREN,']',1,11)
+    LexToken(DIV,'/',1,13)
+    LexToken(NAME,'B',1,15)
+    LexToken(L_SPAREN,'[',1,16)
+    LexToken(INT,0,1,17)
+    LexToken(COMMA,',',1,18)
+    LexToken(INT,0,1,19)
+    LexToken(COMMA,',',1,20)
+    LexToken(INT,1,1,21)
+    LexToken(R_SPAREN,']',1,22)
+    LexToken(MULT,'*',1,24)
+    LexToken(INT,20,1,26)
+    LexToken(ADD,'+',1,29)
+    LexToken(NAME,'C',1,31)
+    LexToken(L_SPAREN,'[',1,32)
+    LexToken(INT,0,1,33)
+    LexToken(COMMA,',',1,34)
+    LexToken(INT,1,1,35)
+    LexToken(COMMA,',',1,36)
+    LexToken(INT,1,1,37)
+    LexToken(R_SPAREN,']',1,38)
+    LexToken(SUB,'-',1,40)
+    LexToken(FLOAT,2.45,1,42)
+
+@endcode
+"""
+
+from temporal_raster_base_algebra import *
+
+###############################################################################
+
+class TemporalRasterAlgebraParser(TemporalRasterBaseAlgebraParser):
+    """The temporal raster algebra class"""
+
+    def __init__(self, pid=None, run=False, debug=True, spatial = False):
+        TemporalRasterBaseAlgebraParser.__init__(self, pid, run, debug, spatial)
+
+        self.m_mapcalc = pygrass.Module('r.mapcalc')
+
+    def parse(self, expression, basename = None, overwrite=False):
+        self.lexer = TemporalRasterAlgebraLexer()
+        self.lexer.build()
+        self.parser = yacc.yacc(module=self, debug=self.debug)
+
+        self.overwrite = overwrite
+        self.count = 0
+        self.stdstype = "strds"
+        self.basename = basename
+        self.expression = expression
+        self.parser.parse(expression)
+
+    ######################### Temporal functions ##############################
+
+    def p_statement_assign(self, t):
+        # The expression should always return a list of maps.
+        """
+        statement : stds EQUALS expr
+        """
+        TemporalRasterBaseAlgebraParser.p_statement_assign(self, t)
+
+    def p_ts_neighbour_operation(self, t):
+        # Examples:
+        # A[1,0]
+        # B[-2]
+        # C[-2,1,3]
+        """
+        expr : stds L_SPAREN number COMMA number R_SPAREN
+             | stds L_SPAREN number R_SPAREN
+             | stds L_SPAREN number COMMA number COMMA number R_SPAREN
+        """
+        # Check input stds.
+        maplist = self.check_stds(t[1])
+        row_neigbour = None
+        col_neigbour = None
+        if len(t) == 5:
+            t_neighbour = t[3]
+        elif len(t) == 7:
+            t_neighbour = 0
+            row_neigbour = t[3]
+            col_neigbour = t[5]
+        elif len(t) == 9:
+            t_neighbour = t[7]
+            row_neigbour = t[3]
+            col_neigbour = t[5]
+        if self.run:
+            resultlist = []
+            max_index = len(maplist)
+            for map_i in maplist:
+                # Get map index and temporal extent.
+                map_index = maplist.index(map_i)
+                new_index = map_index + t_neighbour
+                if new_index < max_index and new_index >= 0:
+                    map_i_t_extent = map_i.get_temporal_extent()
+                    # Get neighbouring map and set temporal extent.
+                    map_n = maplist[new_index]
+                    # Generate an intermediate map for the result map list.
+                    map_new = self.generate_new_map(map_n, bool_op = 'and', copy = True)
+                    map_new.set_temporal_extent(map_i_t_extent)
+                    # Create r.mapcalc expression string for the operation.
+                    if "cmd_list" in dir(map_new) and len(t) == 5:
+                        cmdstring = "%s" %(map_new.cmd_list)
+                    elif "cmd_list" not in dir(map_new) and len(t) == 5:
+                        cmdstring = "%s" %(map_n.get_id())
+                    elif "cmd_list" in dir(map_new) and len(t) in (7, 9):
+                        cmdstring = "%s[%s,%s]" %(map_new.cmd_list, row_neigbour, col_neigbour)
+                    elif "cmd_list" not in dir(map_new) and len(t) in (7, 9):
+                        cmdstring = "%s[%s,%s]" %(map_n.get_id(), row_neigbour, col_neigbour)
+                    # Set new command list for map.
+                    map_new.cmd_list = cmdstring
+                    # Append map with updated command list to result list.
+                    resultlist.append(map_new)
+
+            t[0] = resultlist
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
+
+

文件差异内容过多而无法显示
+ 2590 - 0
lib/python/temporal/temporal_raster_base_algebra.py


+ 390 - 0
lib/python/temporal/temporal_raster_operator.py

@@ -0,0 +1,390 @@
+"""!@package grass.temporal
+
+Temporal operator evaluation with PLY
+
+(C) 2013 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.
+
+@author Thomas Leppelt and Soeren Gebbert
+
+@code
+    >>> p = TemporalRasterOperatorParser()
+    >>> 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)
+    >>> 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 =  "{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 =  "{||}"
+    >>> 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 | contains,&&}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during', 'contains'], '=', '&&')
+    >>> expression =  "{equal | during | contains,/}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during', 'contains'], '=', '/')
+    >>> expression =  "{equal | during | contains,|*}"
+    >>> p.parse(expression)
+    >>> print(p.relations, p.temporal, p.function)
+    (['equal', 'during', 'contains'], '|', '*')
+
+@endcode
+"""
+
+try:
+    import ply.lex as lex
+    import ply.yacc as yacc
+except:
+    pass
+
+class TemporalRasterOperatorLexer(object):
+    """!Lexical analyzer for the GRASS GIS temporal operator"""
+
+    # 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',
+        'MOD',
+        'DIV',
+        'MULT',
+        'ADD',
+        'SUB',
+        '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_MOD                = r'[\%]'
+    t_DIV                = r'[\/]'
+    t_MULT               = r'[\*]'
+    t_ADD                = r'[\+]'
+    t_SUB                = 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 TemporalRasterOperatorLexer.relations.keys():
+            t.type = TemporalRasterOperatorLexer.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 TemporalRasterOperatorParser(object):
+    """The temporal algebra class"""
+
+    def __init__(self):
+        self.lexer = TemporalRasterOperatorLexer()
+        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 = TemporalRasterOperatorLexer.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 arithmetic CRPAREN
+        """
+        # Set three operator components.
+        self.relations = ['equal']
+        self.temporal  = "="
+        self.function  = t[2]
+
+        t[0] = t[2]
+
+    def p_comparison(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN temporal AND CRPAREN
+                 | CLPAREN temporal OR CRPAREN
+        """
+        # Set three operator components.
+        self.relations = ['equal']
+        self.temporal  = "="
+        if t[2] == t[3]:
+            self.function  = t[2] + t[3]
+        else:
+            raise SyntaxError("syntax error on line %d near '%s'" %
+                                (t.lineno, t.value))
+
+        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 arithmetic CRPAREN
+        """
+        # Set three operator components.
+        self.relations = ['equal']
+        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 arithmetic CRPAREN
+                 | CLPAREN relationlist COMMA arithmetic 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_comparison_relation(self, t):
+        # The expression should always return a list of maps.
+        """
+        operator : CLPAREN relation COMMA temporal AND CRPAREN
+                 | CLPAREN relation COMMA temporal OR CRPAREN
+                 | CLPAREN relationlist COMMA temporal AND CRPAREN
+                 | CLPAREN relationlist COMMA temporal OR CRPAREN
+        """
+        # Set three operator components.
+        if isinstance(t[2], list):
+            self.relations = t[2]
+        else:
+            self.relations = [t[2]]
+        self.temporal  = "="
+        if t[4] == t[5]:
+            self.function  = t[4] + t[5]
+        else:
+            raise SyntaxError("syntax error on line %d near '%s'" %
+                                (t.lineno, t.value))
+
+        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 arithmetic CRPAREN
+                 | CLPAREN relationlist COMMA temporal arithmetic CRPAREN
+        """
+        # Set three operator components.
+        if isinstance(t[2], list):
+            self.relations = t[2]
+        else:
+            self.relations = [t[2]]
+        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
+                 | ADD
+        """
+        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_arithmetic_operator(self, t):
+        # The list of relations.
+        """
+        arithmetic : MOD
+                   | DIV
+                   | MULT
+                   | ADD
+                   | SUB
+        """
+        t[0] = t[1]
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
+

+ 26 - 104
lib/python/temporal/temporal_vector_algebra.py

@@ -419,17 +419,7 @@ for details.
 @endcode
 @endcode
 """
 """
 
 
-try:
-    import ply.yacc as yacc
-except:
-    pass
-
 import grass.pygrass.modules as pygrass
 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_vector_operator import *
 from temporal_algebra import *
 from temporal_algebra import *
 
 
@@ -482,6 +472,8 @@ class TemporalVectorAlgebraLexer(TemporalAlgebraLexer):
             t.type = 'NAME'
             t.type = 'NAME'
         return t
         return t
 
 
+##############################################################################
+
 class TemporalVectorAlgebraParser(TemporalAlgebraParser):
 class TemporalVectorAlgebraParser(TemporalAlgebraParser):
     """The temporal algebra class"""
     """The temporal algebra class"""
 
 
@@ -504,13 +496,14 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
         self.m_mremove = pygrass.Module('g.mremove', quiet=True, run_=False)
         self.m_mremove = pygrass.Module('g.mremove', quiet=True, run_=False)
         self.m_buffer = pygrass.Module('v.buffer', quiet=True, run_=False)
         self.m_buffer = pygrass.Module('v.buffer', quiet=True, run_=False)
 
 
-    def parse(self, expression, stdstype = 'strds', basename = None):
+    def parse(self, expression, basename = None, overwrite = False):
         self.lexer = TemporalVectorAlgebraLexer()
         self.lexer = TemporalVectorAlgebraLexer()
         self.lexer.build()
         self.lexer.build()
         self.parser = yacc.yacc(module=self, debug=self.debug)
         self.parser = yacc.yacc(module=self, debug=self.debug)
 
 
+        self.overwrite = overwrite
         self.count = 0
         self.count = 0
-        self.stdstype = stdstype
+        self.stdstype = "stvds"
         self.basename = basename
         self.basename = basename
         self.expression = expression
         self.expression = expression
         self.parser.parse(expression)
         self.parser.parse(expression)
@@ -613,59 +606,15 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
            @param copy Specifies if the temporal extent of mapB should be
            @param copy Specifies if the temporal extent of mapB should be
                   copied to mapA
                   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
+        returncode = TemporalAlgebraParser.overlay_map_extent(self, mapA, mapB,
+                                                              bool_op, temp_op,
+                                                              copy)
+        if not copy and returncode == 1:
             # Conditional append of command list.
             # Conditional append of command list.
             if "cmd_list" in dir(mapA) and "cmd_list" in dir(mapB):
             if "cmd_list" in dir(mapA) and "cmd_list" in dir(mapB):
                 mapA.cmd_list = mapA.cmd_list + mapB.cmd_list
                 mapA.cmd_list = mapA.cmd_list + mapB.cmd_list
             elif "cmd_list" not in dir(mapA) and "cmd_list" in dir(mapB):
             elif "cmd_list" not in dir(mapA) and "cmd_list" in dir(mapB):
                 mapA.cmd_list = mapB.cmd_list
                 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)
         return(returncode)
 
 
@@ -688,7 +637,7 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
                     # Check if resultmap names exist in GRASS database.
                     # Check if resultmap names exist in GRASS database.
                     vectorname = self.basename + "_" + str(i)
                     vectorname = self.basename + "_" + str(i)
                     vectormap = VectorDataset(vectorname + "@" + get_current_mapset())
                     vectormap = VectorDataset(vectorname + "@" + get_current_mapset())
-                    if vectormap.map_exists() and grass.overwrite() == False:
+                    if vectormap.map_exists() and self.overwrite == False:
                         self.msgr.fatal(_("Error vector maps with basename %s exist. "
                         self.msgr.fatal(_("Error vector maps with basename %s exist. "
                                       "Use --o flag to overwrite existing file") \
                                       "Use --o flag to overwrite existing file") \
                                       %(vectorname))
                                       %(vectorname))
@@ -741,10 +690,10 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
                             newident = self.basename + "_" + str(count)
                             newident = self.basename + "_" + str(count)
                             m = copy.deepcopy(self.m_rename)
                             m = copy.deepcopy(self.m_rename)
                             m.inputs["vect"].value = (map_i.get_name(),newident)
                             m.inputs["vect"].value = (map_i.get_name(),newident)
-                            m.flags["overwrite"].value = grass.overwrite()
+                            m.flags["overwrite"].value = self.overwrite
                             m.run()
                             m.run()
                             #m(vect = (map_i.get_name(),newident), \
                             #m(vect = (map_i.get_name(),newident), \
-                            #    overwrite = grass.overwrite)
+                            #    overwrite = self.overwrite)
                             map_i.set_id(newident + "@" + mapset)
                             map_i.set_id(newident + "@" + mapset)
                             count += 1
                             count += 1
                             register_list.append(map_i)
                             register_list.append(map_i)
@@ -758,16 +707,16 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
                     resultstds = open_new_space_time_dataset(t[1], self.stdstype, \
                     resultstds = open_new_space_time_dataset(t[1], self.stdstype, \
                                                                 'absolute', t[1], t[1], \
                                                                 'absolute', t[1], t[1], \
                                                                 "temporal vector algebra", dbif=dbif,
                                                                 "temporal vector algebra", dbif=dbif,
-                                                                overwrite = grass.overwrite())
+                                                                overwrite = self.overwrite)
                     for map_i in register_list:
                     for map_i in register_list:
                         # Check if modules should be executed from command list.
                         # Check if modules should be executed from command list.
                         if "cmd_list" in dir(map_i):
                         if "cmd_list" in dir(map_i):
                             # Get meta data from grass database.
                             # Get meta data from grass database.
                             map_i.load()
                             map_i.load()
-                            if map_i.is_in_db(dbif=dbif) and grass.overwrite():
+                            if map_i.is_in_db(dbif=dbif) and self.overwrite:
                                 # Update map in temporal database.
                                 # Update map in temporal database.
                                 map_i.update_all(dbif=dbif)
                                 map_i.update_all(dbif=dbif)
-                            elif map_i.is_in_db(dbif=dbif) and grass.overwrite() == False:
+                            elif map_i.is_in_db(dbif=dbif) and self.overwrite == False:
                                 # Raise error if map exists and no overwrite flag is given.
                                 # Raise error if map exists and no overwrite flag is given.
                                 self.msgr.fatal(_("Error vector map %s exist in temporal database. "
                                 self.msgr.fatal(_("Error vector map %s exist in temporal database. "
                                                   "Use overwrite flag.  : \n%s") \
                                                   "Use overwrite flag.  : \n%s") \
@@ -789,14 +738,6 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
                 self.remove_intermediate_vector_maps()
                 self.remove_intermediate_vector_maps()
             t[0] = register_list
             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):
     def p_overlay_operation(self, t):
         """
         """
         expr : stds AND stds
         expr : stds AND stds
@@ -826,7 +767,7 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
 
 
         if self.run:
         if self.run:
             t[0] = self.create_overlay_operations(maplistA, maplistB, ("EQUAL",), "=", t[2])
             t[0] = self.create_overlay_operations(maplistA, maplistB, ("EQUAL",), "=", t[2])
-        if self.debug:
+        else:
             t[0] = t[1]
             t[0] = t[1]
 
 
     def p_overlay_operation_relation(self, t):
     def p_overlay_operation_relation(self, t):
@@ -843,7 +784,7 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
 
 
         if self.run:
         if self.run:
             t[0] = self.create_overlay_operations(maplistA, maplistB, relations, temporal, function)
             t[0] = self.create_overlay_operations(maplistA, maplistB, relations, temporal, function)
-        if self.debug:
+        else:
             t[0] = t[1]
             t[0] = t[1]
 
 
     def create_overlay_operations(self, maplistA, maplistB, relations, temporal, function):
     def create_overlay_operations(self, maplistA, maplistB, relations, temporal, function):
@@ -875,15 +816,8 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
             resultlist = []
             resultlist = []
             for map_i in topolist:
             for map_i in topolist:
                 # Generate an intermediate name for the result map list.
                 # 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)
+                map_new = self.generate_new_map(base_map=map_i, bool_op=opname,
+                                                copy=True)
                 # Set first input for overlay module.
                 # Set first input for overlay module.
                 mapainput = map_i.get_id()
                 mapainput = map_i.get_id()
                 # Loop over temporal related maps and create overlay modules.
                 # Loop over temporal related maps and create overlay modules.
@@ -915,14 +849,14 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
                                 m.inputs["ainput"].value = str(mapainput)
                                 m.inputs["ainput"].value = str(mapainput)
                                 m.inputs["binput"].value = str(mapbinput)
                                 m.inputs["binput"].value = str(mapbinput)
                                 m.outputs["output"].value = name
                                 m.outputs["output"].value = name
-                                m.flags["overwrite"].value = grass.overwrite()
+                                m.flags["overwrite"].value = self.overwrite
                             else:
                             else:
                                 patchinput = str(mapainput) + ',' + str(mapbinput)
                                 patchinput = str(mapainput) + ',' + str(mapbinput)
                                 m = copy.deepcopy(self.m_patch)
                                 m = copy.deepcopy(self.m_patch)
                                 m.run_ = False
                                 m.run_ = False
                                 m.inputs["input"].value = patchinput
                                 m.inputs["input"].value = patchinput
                                 m.outputs["output"].value = name
                                 m.outputs["output"].value = name
-                                m.flags["overwrite"].value = grass.overwrite()
+                                m.flags["overwrite"].value = self.overwrite
                             # Conditional append of module command.
                             # Conditional append of module command.
                             if "cmd_list" in dir(map_new):
                             if "cmd_list" in dir(map_new):
                                 map_new.cmd_list.append(m)
                                 map_new.cmd_list.append(m)
@@ -952,16 +886,9 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
             resultlist = []
             resultlist = []
 
 
             for map_i in bufflist:
             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)
+                # Generate an intermediate name for the result map list.
+                map_new = self.generate_new_map(base_map=map_i, bool_op=None,
+                                                copy=True)
                 # Change spatial extent based on buffer size.
                 # Change spatial extent based on buffer size.
                 map_new.spatial_buffer(float(t[5]))
                 map_new.spatial_buffer(float(t[5]))
                 # Check buff type.
                 # Check buff type.
@@ -976,8 +903,8 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
                 m.inputs["type"].value = buff_type
                 m.inputs["type"].value = buff_type
                 m.inputs["input"].value = str(map_i.get_id())
                 m.inputs["input"].value = str(map_i.get_id())
                 m.inputs["distance"].value = float(t[5])
                 m.inputs["distance"].value = float(t[5])
-                m.outputs["output"].value = name
-                m.flags["overwrite"].value = grass.overwrite()
+                m.outputs["output"].value = map_new.get_name()
+                m.flags["overwrite"].value = self.overwrite
 
 
                 # Conditional append of module command.
                 # Conditional append of module command.
                 if "cmd_list" in dir(map_new):
                 if "cmd_list" in dir(map_new):
@@ -988,9 +915,6 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
 
 
             t[0] = resultlist
             t[0] = resultlist
 
 
-        if self.debug:
-            pass
-
     def p_buff_function(self, t):
     def p_buff_function(self, t):
         """buff_function    : BUFF_POINT
         """buff_function    : BUFF_POINT
                             | BUFF_LINE
                             | BUFF_LINE
@@ -1008,5 +932,3 @@ class TemporalVectorAlgebraParser(TemporalAlgebraParser):
 if __name__ == "__main__":
 if __name__ == "__main__":
     import doctest
     import doctest
     doctest.testmod()
     doctest.testmod()
-
-

+ 84 - 0
lib/python/temporal/unittests_temporal_raster3d_algebra.py

@@ -0,0 +1,84 @@
+"""!Unit test to register raster maps with absolute and relative
+   time using tgis.register_maps_in_space_time_dataset()
+
+(C) 2013 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.
+
+@author Soeren Gebbert
+"""
+
+import grass.script
+import grass.temporal as tgis
+import unittest
+import datetime
+import os
+
+class TestRegisterFunctions(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        """!Initiate the temporal GIS and set the region
+        """
+        tgis.init(True) # Raise on error instead of exit(1)
+        grass.script.use_temp_region()
+        ret = grass.script.run_command("g.region", n=80.0, s=0.0, e=120.0,
+                                       w=0.0, t=100.0, b=0.0, res=10.0)
+
+        ret += grass.script.run_command("r3.mapcalc", overwrite=True, quiet=True, expression="a1 = 1")
+        ret += grass.script.run_command("r3.mapcalc", overwrite=True, quiet=True, expression="a2 = 2")
+        ret += grass.script.run_command("r3.mapcalc", overwrite=True, quiet=True, expression="a3 = 3")
+        ret += grass.script.run_command("r3.mapcalc", overwrite=True, quiet=True, expression="a4 = 4")
+
+
+        tgis.open_new_space_time_dataset(name="A", type="str3ds", temporaltype="absolute",
+                                         title="A", descr="A", semantic="field", overwrite=True)
+
+        tgis.register_maps_in_space_time_dataset(type="rast3d", name="A", maps="a1,a2,a3,a4",
+                                                 start="2001-01-01", increment="1 day", interval=True)
+
+    def test_temporal_neighbors_1(self):
+        """Simple temporal neighborhood computation test"""
+        tra = tgis.TemporalRaster3DAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = A[-1] + A[1]',
+                  basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="str3ds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 4)  # 1 + 3
+        self.assertEqual(D.metadata.get_max_max(), 6) # 2 + 4
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def test_temporal_neighbors_2(self):
+        """Simple temporal neighborhood computation test"""
+        tra = tgis.TemporalRaster3DAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = A[0,0,0,-1] + A[0,0,0,1]',
+                  basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="str3ds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 4)  # 1 + 3
+        self.assertEqual(D.metadata.get_max_max(), 6) # 2 + 4
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def tearDown(self):
+        ret = grass.script.run_command("t.remove", type="str3ds", flags="rf", input="D", quiet=True)
+
+    @classmethod
+    def tearDownClass(cls):
+        """!Remove the temporary region
+        """
+        ret = grass.script.run_command("t.remove", type="str3ds", flags="rf", input="A", quiet=True)
+        grass.script.del_temp_region()
+
+if __name__ == '__main__':
+    unittest.main()
+
+

+ 282 - 0
lib/python/temporal/unittests_temporal_raster_algebra.py

@@ -0,0 +1,282 @@
+"""!Unit test to register raster maps with absolute and relative
+   time using tgis.register_maps_in_space_time_dataset()
+
+(C) 2013 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.
+
+@author Soeren Gebbert
+"""
+
+import grass.script
+import grass.temporal as tgis
+import unittest
+import datetime
+import os
+
+class TestRegisterFunctions(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        """!Initiate the temporal GIS and set the region
+        """
+        tgis.init(True) # Raise on error instead of exit(1)
+        grass.script.use_temp_region()
+        ret = grass.script.run_command("g.region", n=80.0, s=0.0, e=120.0,
+                                       w=0.0, t=1.0, b=0.0, res=10.0)
+
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="a1 = 1")
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="a2 = 2")
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="a3 = 3")
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="a4 = 4")
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="b1 = 5")
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="b2 = 6")
+        ret += grass.script.run_command("r.mapcalc", overwrite=True, quiet=True, expression="c1 = 7")
+
+
+        tgis.open_new_space_time_dataset(name="A", type="strds", temporaltype="absolute",
+                                         title="A", descr="A", semantic="field", overwrite=True)
+        tgis.open_new_space_time_dataset(name="B", type="strds", temporaltype="absolute",
+                                         title="B", descr="B", semantic="field", overwrite=True)
+        tgis.open_new_space_time_dataset(name="C", type="strds", temporaltype="absolute",
+                                         title="B", descr="C", semantic="field", overwrite=True)
+
+        tgis.register_maps_in_space_time_dataset(type="rast", name="A", maps="a1,a2,a3,a4",
+                                                 start="2001-01-01", increment="1 day", interval=True)
+        tgis.register_maps_in_space_time_dataset(type="rast", name="B", maps="b1,b2",
+                                                 start="2001-01-01", increment="2 day", interval=True)
+
+        tgis.register_maps_in_space_time_dataset(type="rast", name="C", maps="c1",
+                                                 start="2001-01-02", increment="2 day", interval=True)
+
+    def test_simple_arith_if_1(self):
+        """Simple arithmetic test with if condition"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = if({equal}, start_date() >= "2001-01-02", A + A)', basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 3)
+        self.assertEqual(D.metadata.get_min_min(), 4)
+        self.assertEqual(D.metadata.get_max_max(), 8)
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_simple_arith_if_2(self):
+        """Simple arithmetic test with if condition"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = if({equal}, A#A == 1, A - A)', basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 0)
+        self.assertEqual(D.metadata.get_max_max(), 0)
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_complex_arith_if_1(self):
+        """Complex arithmetic test with if condition"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = if(start_date() < "2001-01-03" && A#A == 1, A{starts,=+}C, A{finishes,=+}C)', \
+                  basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 9)  # 2 + 7 a2 + c1
+        self.assertEqual(D.metadata.get_max_max(), 10) # 3 + 7 a3 + c1
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def test_simple_arith_1(self):
+        """Simple arithmetic test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {equal,*} A {equal,+} A", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 2)  # 1*1 + 1
+        self.assertEqual(D.metadata.get_max_max(), 20) # 4*4 + 4
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_simple_arith_2(self):
+        """Simple arithmetic test that creates an empty strds"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {during,*} A {during,+} A", basename="d", overwrite=True)
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 0)
+
+    def test_simple_arith_3(self):
+        """Simple arithmetic test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A / A + A*A/A", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 2) # 1/1 + 1*1/1
+        self.assertEqual(D.metadata.get_max_max(), 5) # 4/4 + 4*4/4
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_temporal_intersection_1(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {equal,&+} B", basename="d", overwrite=True)
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 0)
+
+    def test_temporal_intersection_2(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {during,&+} B", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 6) # 1 + 5
+        self.assertEqual(D.metadata.get_max_max(), 10) # 4 + 6
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_temporal_intersection_3(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {starts,&+} B", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 6) # 1 + 5
+        self.assertEqual(D.metadata.get_max_max(), 9) # 3 + 6
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def test_temporal_intersection_4(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {finishes,&+} B", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 7)  # 2 + 5
+        self.assertEqual(D.metadata.get_max_max(), 10) # 4 + 6
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_temporal_intersection_5(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = A {starts|finishes,&+} B", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 6)  # 1 + 5
+        self.assertEqual(D.metadata.get_max_max(), 10) # 4 + 6
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_temporal_intersection_6(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = B {overlaps,|+} C", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 1)
+        self.assertEqual(D.metadata.get_min_min(), 12) # 5 + 7
+        self.assertEqual(D.metadata.get_max_max(), 12) # 5 + 7
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def test_temporal_intersection_7(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression="D = B {overlapped,|+} C", basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 1)
+        self.assertEqual(D.metadata.get_min_min(), 13) # 6 + 7
+        self.assertEqual(D.metadata.get_max_max(), 13) # 6 + 7
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_temporal_intersection_8(self):
+        """Simple temporal intersection test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = A {during,=+} buff_t(C, "1 day") ',
+                  basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 8)  # 1 + 7  a1 + c1
+        self.assertEqual(D.metadata.get_max_max(), 11) # 4 + 7  a4 + c1
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual(end, datetime.datetime(2001, 1, 5))
+
+    def test_temporal_neighbors_1(self):
+        """Simple temporal neighborhood computation test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = A[-1] + A[1]',
+                  basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 4)  # 1 + 3
+        self.assertEqual(D.metadata.get_max_max(), 6) # 2 + 4
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def test_temporal_neighbors_2(self):
+        """Simple temporal neighborhood computation test"""
+        tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
+        tra.parse(expression='D = A[0,0,-1] + A[0,0,1]',
+                  basename="d", overwrite=True)
+
+        D = tgis.open_old_space_time_dataset("D", type="strds")
+        D.select()
+        self.assertEqual(D.metadata.get_number_of_maps(), 2)
+        self.assertEqual(D.metadata.get_min_min(), 4)  # 1 + 3
+        self.assertEqual(D.metadata.get_max_max(), 6) # 2 + 4
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 2))
+        self.assertEqual(end, datetime.datetime(2001, 1, 4))
+
+    def tearDown(self):
+        ret = grass.script.run_command("t.remove", flags="rf", input="D", quiet=True)
+
+    @classmethod
+    def tearDownClass(cls):
+        """!Remove the temporary region
+        """
+        ret = grass.script.run_command("t.remove", flags="rf", input="A,B,C", quiet=True)
+        grass.script.del_temp_region()
+
+if __name__ == '__main__':
+    unittest.main()
+
+