[GRASS-SVN] r71369 - in grass/trunk/lib/python/temporal: . testsuite

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Aug 10 04:36:46 PDT 2017


Author: huhabla
Date: 2017-08-10 04:36:46 -0700 (Thu, 10 Aug 2017)
New Revision: 71369

Added:
   grass/trunk/lib/python/temporal/testsuite/unittests_temporal_raster_algebra_spatial_topology.py
Modified:
   grass/trunk/lib/python/temporal/core.py
   grass/trunk/lib/python/temporal/register.py
   grass/trunk/lib/python/temporal/space_time_datasets.py
   grass/trunk/lib/python/temporal/temporal_algebra.py
   grass/trunk/lib/python/temporal/temporal_granularity.py
   grass/trunk/lib/python/temporal/temporal_operator.py
   grass/trunk/lib/python/temporal/temporal_raster_algebra.py
   grass/trunk/lib/python/temporal/temporal_raster_base_algebra.py
   grass/trunk/lib/python/temporal/temporal_vector_algebra.py
   grass/trunk/lib/python/temporal/testsuite/unittests_temporal_conditionals.py
   grass/trunk/lib/python/temporal/testsuite/unittests_temporal_raster3d_algebra.py
   grass/trunk/lib/python/temporal/testsuite/unittests_temporal_raster_conditionals.py
Log:
temporal framework: Added spatial topological operators to the temporal algebra


Modified: grass/trunk/lib/python/temporal/core.py
===================================================================
--- grass/trunk/lib/python/temporal/core.py	2017-08-10 09:33:59 UTC (rev 71368)
+++ grass/trunk/lib/python/temporal/core.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -456,7 +456,7 @@
     for mapset in mapsets:
         driver = c_library_interface.get_driver_name(mapset)
         database = c_library_interface.get_database_name(mapset)
-        
+
         message_interface.debug(1, "get_available_temporal_mapsets: "\
                                    "\n  mapset %s\n  driver %s\n  database %s"%(mapset,
                                    driver, database))
@@ -1063,14 +1063,14 @@
         if dbstring is None:
             global tgis_database_string
             self.dbstring = tgis_database_string
-        
+
         self.dbstring = dbstring
 
         self.msgr = get_tgis_message_interface()
         self.msgr.debug(1, "DBConnection constructor:"\
                            "\n  backend: %s"\
                            "\n  dbstring: %s"%(backend, self.dbstring))
-                           #"\n  traceback:%s"%(backend, self.dbstring, 
+                           #"\n  traceback:%s"%(backend, self.dbstring,
                            #str("  \n".join(traceback.format_stack()))))
 
     def __del__(self):

Modified: grass/trunk/lib/python/temporal/register.py
===================================================================
--- grass/trunk/lib/python/temporal/register.py	2017-08-10 09:33:59 UTC (rev 71368)
+++ grass/trunk/lib/python/temporal/register.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -483,7 +483,7 @@
         # In case of a empty map continue, do not register empty maps
 
         if delete_empty:
-            if type in ["raster", "raster_3d"]:
+            if type in ["raster", "raster_3d", "rast", "rast3d"]:
                 if map_layer.metadata.get_min() is None and \
                    map_layer.metadata.get_max() is None:
                     empty_maps.append(map_layer)

Modified: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py	2017-08-10 09:33:59 UTC (rev 71368)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -42,6 +42,7 @@
         .. code-block:: python
 
             >>> import grass.script as grass
+            >>> import grass.temporal as tgis
             >>> init()
             >>> grass.use_temp_region()
             >>> grass.run_command("g.region", n=80.0, s=0.0, e=120.0, w=0.0,
@@ -53,7 +54,7 @@
             >>> grass.run_command("r.timestamp", map="strds_map_test_case",
             ...                   date="15 jan 1999", quiet=True)
             0
-            >>> mapset = get_current_mapset()
+            >>> mapset = tgis.get_current_mapset()
             >>> name = "strds_map_test_case"
             >>> identifier = "%s@%s" % (name, mapset)
             >>> rmap = RasterDataset(identifier)
@@ -1022,24 +1023,23 @@
 
             >>> import grass.temporal as tgis
             >>> tgis.init()
-            >>> strds = tgis.SpaceTimeRasterDataset("old at PERMANENT")
+            >>> mapset = tgis.get_current_mapset()
+            >>> strds = tgis.SpaceTimeRasterDataset("old@%s"%mapset)
             >>> strds.is_in_db()
             False
             >>> strds.is_stds()
             True
             >>> strds.get_type()
             'strds'
-            >>> newstrds = strds.get_new_instance("newstrds at PERMANENT")
+            >>> newstrds = strds.get_new_instance("newstrds@%s"%mapset)
             >>> isinstance(newstrds, SpaceTimeRasterDataset)
             True
-            >>> newmap = strds.get_new_map_instance("newmap at PERMANENT")
+            >>> newmap = strds.get_new_map_instance("newmap@%s"%mapset)
             >>> isinstance(newmap, RasterDataset)
             True
-            >>> strds.reset("new at PERMANENT")
+            >>> strds.reset("new@%s"%mapset)
             >>> strds.is_in_db()
             False
-            >>> strds.get_id()
-            'new at PERMANENT'
             >>> strds.reset(None)
             >>> strds.is_in_db()
             False
@@ -1131,24 +1131,23 @@
 
             >>> import grass.temporal as tgis
             >>> tgis.init()
-            >>> str3ds = tgis.SpaceTimeRaster3DDataset("old at PERMANENT")
+            >>> mapset = tgis.get_current_mapset()
+            >>> str3ds = tgis.SpaceTimeRaster3DDataset("old@%s"%mapset)
             >>> str3ds.is_in_db()
             False
             >>> str3ds.is_stds()
             True
             >>> str3ds.get_type()
             'str3ds'
-            >>> newstrds = str3ds.get_new_instance("newstrds at PERMANENT")
+            >>> newstrds = str3ds.get_new_instance("newstrds@%s"%mapset)
             >>> isinstance(newstrds, SpaceTimeRaster3DDataset)
             True
-            >>> newmap = str3ds.get_new_map_instance("newmap at PERMANENT")
+            >>> newmap = str3ds.get_new_map_instance("newmap@%s"%mapset)
             >>> isinstance(newmap, Raster3DDataset)
             True
-            >>> str3ds.reset("new at PERMANENT")
+            >>> str3ds.reset("new@%s"%mapset)
             >>> str3ds.is_in_db()
             False
-            >>> str3ds.get_id()
-            'new at PERMANENT'
             >>> str3ds.reset(None)
             >>> str3ds.is_in_db()
             False
@@ -1259,24 +1258,23 @@
 
             >>> import grass.temporal as tgis
             >>> tgis.init()
-            >>> stvds = tgis.SpaceTimeVectorDataset("old at PERMANENT")
+            >>> mapset = tgis.get_current_mapset()
+            >>> stvds = tgis.SpaceTimeVectorDataset("old@%s"%mapset)
             >>> stvds.is_in_db()
             False
             >>> stvds.is_stds()
             True
             >>> stvds.get_type()
             'stvds'
-            >>> newstvds = stvds.get_new_instance("newstvds at PERMANENT")
+            >>> newstvds = stvds.get_new_instance("newstvds@%s"%mapset)
             >>> isinstance(newstvds, SpaceTimeVectorDataset)
             True
-            >>> newmap = stvds.get_new_map_instance("newmap at PERMANENT")
+            >>> newmap = stvds.get_new_map_instance("newmap@%s"%mapset)
             >>> isinstance(newmap, VectorDataset)
             True
-            >>> stvds.reset("new at PERMANENT")
+            >>> stvds.reset("new@%s"%mapset)
             >>> stvds.is_in_db()
             False
-            >>> stvds.get_id()
-            'new at PERMANENT'
             >>> stvds.reset(None)
             >>> stvds.is_in_db()
             False

Modified: grass/trunk/lib/python/temporal/temporal_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_algebra.py	2017-08-10 09:33:59 UTC (rev 71368)
+++ grass/trunk/lib/python/temporal/temporal_algebra.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -778,6 +778,11 @@
         self.nprocs = nprocs
         self.use_granularity = False
 
+        # Topology lists
+        self.temporal_topology_list = ["EQUAL", "FOLLOWS", "PRECEDES", "OVERLAPS", "OVERLAPPED", \
+                                       "DURING", "STARTS", "FINISHES", "CONTAINS", "STARTED", "FINISHED"]
+        self.spatial_topology_list = ["EQUIVALENT", "COVER", "OVERLAP", "IN", "CONTAIN", "MEET"]
+
     def __del__(self):
         if self.dbif.connected:
             self.dbif.close()
@@ -1039,6 +1044,7 @@
             :return: Map list with specified temporal extent.
         """
         resultdict = {}
+        temporal_topo_list, spatial_topo_list = self._check_topology(topolist=topolist)
 
         for map_i in maplist:
             # Loop over temporal related maps and create overlay modules.
@@ -1050,30 +1056,32 @@
             for topo in topolist:
                 if topo in tbrelations.keys():
                     for map_j in (tbrelations[topo]):
-                        if temporal == 'r':
-                            # Generate an intermediate map for the result map list.
-                            map_new = self.generate_new_map(base_map=map_i, bool_op='and',
-                                                            copy=True,  rename=True)
-                        # Create overlaid map extent.
-                        returncode = self.overlay_map_extent(map_new, map_j, 'and',
-                                                             temp_op=temporal)
-                        # Stop the loop if no temporal or spatial relationship exist.
-                        if returncode == 0:
-                            break
-                        # Append map to result map list.
-                        elif returncode == 1:
-                            # print(map_new.get_id() + " " + str(map_new.get_temporal_extent_as_tuple()))
-                            # print(map_new.condition_value)
-                            # print(map_new.cmd_list)
-                            # resultlist.append(map_new)
-                            resultdict[map_new.get_id()] = map_new
+                        if self._check_spatial_topology_relation(spatial_topo_list, map_i, map_j) is True:
+                            if temporal == 'r':
+                                # Generate an intermediate map for the result map list.
+                                map_new = self.generate_new_map(base_map=map_i, bool_op='and',
+                                                                copy=True,  rename=True)
+                            # Create overlaid map extent.
+                            returncode = self.overlay_map_extent(map_new, map_j, 'and',
+                                                                 temp_op=temporal)
+                            print(map_new.get_id(), map_j.get_id())
+                            # Stop the loop if no temporal or spatial relationship exist.
+                            if returncode == 0:
+                                break
+                            # Append map to result map list.
+                            elif returncode == 1:
+                                # print(map_new.get_id() + " " + str(map_new.get_temporal_extent_as_tuple()))
+                                # print(map_new.condition_value)
+                                # print(map_new.cmd_list)
+                                # resultlist.append(map_new)
+                                resultdict[map_new.get_id()] = map_new
 
-                        # Create r.mapcalc expression string for the operation.
-                        #cmdstring = self.build_command_string(s_expr_a = map_new,
-                        #                                                                s_expr_b = map_j,
-                        #                                                                operator = function)
-                        # Conditional append of module command.
-                        #map_new.cmd_list = cmdstring
+                            # Create r.mapcalc expression string for the operation.
+                            #cmdstring = self.build_command_string(s_expr_a = map_new,
+                            #                                                                s_expr_b = map_j,
+                            #                                                                operator = function)
+                            # Conditional append of module command.
+                            #map_new.cmd_list = cmdstring
                     if returncode == 0:
                         break
             # Append map to result map list.
@@ -1221,33 +1229,110 @@
 
         return(maplist)
 
-    def get_temporal_topo_list(self,
-                               maplistA,
-                               maplistB=None,
-                               topolist=["EQUAL"],
-                               assign_val=False,
-                               count_map=False,
-                               compare_bool=False,
-                               compop=None,
-                               aggregate=None):
-        """Build temporal topology for two space time data sets, copy map objects
+    def _check_spatial_topology_entries(self, spatial_topo_list, spatial_relations):
+        """Check the spatial topology entries in the spatial relation list
+
+        Return True if no spatial relation list is provided or if one spatial relation
+        was found
+
+        :param spatial_topo_list: The spatial relations that were defined in the expression
+        :param spatial_relations: The spatial relations of a single map object
+
+        :return: True if a spatial  topological relation was found, False if not
+        """
+
+        # Check spatial topology
+        spatial_topo_check = False
+        if len(spatial_topo_list) == 0:
+            spatial_topo_check = True
+        else:
+            for spatial_topology in spatial_topo_list:
+                if spatial_topology in spatial_relations.keys():
+                    spatial_topo_check = True
+
+        if self.debug is True:
+            print("Spatial topology list", spatial_topo_list, spatial_topo_check)
+
+        return spatial_topo_check
+
+    def _check_spatial_topology_relation(self, spatial_topo_list, map_a, map_b):
+        """Check if map_b has one of the spatial topological relations to map_a that is defined
+        in spatial_topo_list
+
+        :param spatial_topo_list:
+        :param map_a:
+        :param map_b:
+        :return:
+        """
+
+        # Check spatial topology
+        spatial_topo_check = False
+        if len(spatial_topo_list) == 0:
+            spatial_topo_check = True
+        else:
+            map_a_sr = map_a.get_spatial_relations()
+
+            for spatial_topology in spatial_topo_list:
+                if spatial_topology in map_a_sr.keys():
+                    if map_b in map_a_sr[spatial_topology]:
+                        spatial_topo_check = True
+
+        if self.debug is True:
+            print("Spatial topology list", spatial_topo_list, spatial_topo_check)
+
+        return spatial_topo_check
+
+    def _check_topology(self, topolist):
+        """Check the topology definitions of the expression
+
+        :param topolist: List of strings of temporal and spatial relations.
+
+        :return: A tuple of spatial and temporal topology lists (temporal_topo_list, spatial_topo_list)
+
+        :raises: This method will raise a syntax error in case the topology name is unknown
+        """
+        temporal_topo_list = []
+        spatial_topo_list= []
+        # Check if given temporal relation are valid.
+        for topo in topolist:
+            if topo.upper() not in self.temporal_topology_list and topo.upper() not in self.spatial_topology_list:
+                raise SyntaxError("Unpermitted topological relation name '" + topo + "'")
+
+            if topo.upper() in self.spatial_topology_list:
+                spatial_topo_list.append(topo.upper())
+
+            if topo.upper() in self.temporal_topology_list:
+                temporal_topo_list.append(topo.upper())
+
+        return temporal_topo_list, spatial_topo_list
+
+    def build_spatio_temporal_topology_list(self,
+                                            maplistA,
+                                            maplistB=None,
+                                            topolist=["EQUAL"],
+                                            assign_val=False,
+                                            count_map=False,
+                                            compare_bool=False,
+                                            compop=None,
+                                            aggregate=None):
+        """Build spatio-temporal topology for two space time data sets, copy map objects
           for given relation into map list.
 
           :param maplistA: List of maps.
           :param maplistB: List of maps.
-          :param topolist: List of strings of temporal relations.
+          :param topolist: List of strings of spatio-temporal relations.
           :param assign_val: Boolean for assigning a boolean map value based on
-                            the map_values from the compared map list by
-                            topological relationships.
+                             the map_values from the compared map list by
+                             topological relationships.
           :param count_map: Boolean if the number of topological related maps
-                           should be returned.
+                            should be returned.
           :param compare_bool: Boolean for comparing boolean map values based on
-                            related map list and compariosn operator.
+                               related map list and comparison operator.
           :param compop: Comparison operator, && or ||.
           :param aggregate: Aggregation operator for relation map list, & or |.
 
           :return: List of maps from maplistA that fulfil the topological relationships
-                  to maplistB specified in topolist.
+                   to maplistB specified in topolist.
 
           .. code-block:: python
 
@@ -1269,7 +1354,7 @@
               ...     check = mapB.set_relative_time(i, i + 1, "months")
               ...     mapsA.append(mapA)
               ...     mapsB.append(mapB)
-              >>> resultlist = l.get_temporal_topo_list(mapsA, mapsB, ['EQUAL'])
+              >>> resultlist = l.build_spatio_temporal_topology_list(mapsA, mapsB, ['EQUAL'])
               >>> for map in resultlist:
               ...     if map.get_equal():
               ...         relations = map.get_equal()
@@ -1285,7 +1370,7 @@
               Map a7 has equal relation to map b7
               Map a8 has equal relation to map b8
               Map a9 has equal relation to map b9
-              >>> resultlist = l.get_temporal_topo_list(mapsA, mapsB, ['DURING'])
+              >>> resultlist = l.build_spatio_temporal_topology_list(mapsA, mapsB, ['DURING'])
               >>> print(resultlist)
               []
               >>> # Create two list of maps with equal time stamps
@@ -1302,7 +1387,7 @@
               ...     check = mapB.set_relative_time(i, i + 2, "months")
               ...     mapsA.append(mapA)
               ...     mapsB.append(mapB)
-              >>> resultlist = l.get_temporal_topo_list(mapsA, mapsB, ['starts','during'])
+              >>> resultlist = l.build_spatio_temporal_topology_list(mapsA, mapsB, ['starts','during'])
               >>> for map in resultlist:
               ...     if map.get_starts():
               ...         relations = map.get_starts()
@@ -1366,7 +1451,7 @@
               ...             datetime(2000,1,i + 7))
               ...     mapsA.append(mapA)
               ...     mapsB.append(mapB)
-              >>> resultlist = l.get_temporal_topo_list(mapsA, mapsB)
+              >>> resultlist = l.build_spatio_temporal_topology_list(mapsA, mapsB)
               >>> for map in resultlist:
               ...     print(map.get_id())
               a5 at B
@@ -1374,88 +1459,85 @@
               a7 at B
               a8 at B
               a9 at B
-              >>> resultlist = l.get_temporal_topo_list(mapsA, mapsB, ['during'])
+              >>> resultlist = l.build_spatio_temporal_topology_list(mapsA, mapsB, ['during'])
               >>> for map in resultlist:
               ...     print(map.get_id())
 
         """
-        topologylist = ["EQUAL", "FOLLOWS", "PRECEDES", "OVERLAPS", "OVERLAPPED", \
-                        "DURING", "STARTS", "FINISHES", "CONTAINS", "STARTED", \
-                        "FINISHED"]
-        complementdict = {"EQUAL": "EQUAL", "FOLLOWS" : "PRECEDES",
-                          "PRECEDES" : "FOLLOWS", "OVERLAPS" : "OVERLAPPED",
-                          "OVERLAPPED" : "OVERLAPS", "DURING" : "CONTAINS",
-                          "CONTAINS" : "DURING", "STARTS" : "STARTED",
-                          "STARTED" : "STARTS", "FINISHES" : "FINISHED",
-                          "FINISHED" : "FINISHES"}
+        # Check the topology definitions and return the list of temporal and spatial
+        # topological relations that must be fulfilled
+        temporal_topo_list, spatial_topo_list = self._check_topology(topolist=topolist)
+
         resultdict = {}
-        # Check if given temporal relation are valid.
-        for topo in topolist:
-          if topo.upper() not in topologylist:
-              raise SyntaxError("Unpermitted temporal relation name '" + topo + "'")
 
-        # Create temporal topology for maplistA to maplistB.
+        # Create spatio-temporal topology for maplistA to maplistB.
         tb = SpatioTemporalTopologyBuilder()
-        # Dictionary with different spatial variables used for topology builder.
-        spatialdict = {'strds' : '2D', 'stvds' : '2D', 'str3ds' : '3D'}
-        # Build spatial temporal topology
-        if self.spatial:
-            tb.build(maplistA, maplistB, spatial = spatialdict[self.stdstype])
+        if len(spatial_topo_list) > 0:
+            # Dictionary with different spatial variables used for topology builder.
+            spatialdict = {'strds' : '2D', 'stvds' : '2D', 'str3ds' : '3D'}
+            tb.build(maplistA, maplistB, spatial=spatialdict[self.stdstype])
         else:
             tb.build(maplistA, maplistB)
         # Iterate through maps in maplistA and search for relationships given
         # in topolist.
         for map_i in maplistA:
-            tbrelations = map_i.get_temporal_relations()
             if assign_val:
-                self.assign_bool_value(map_i,  tbrelations,  topolist)
+                self.assign_bool_value(map_i, temporal_topo_list, spatial_topo_list)
             elif compare_bool:
-                self.compare_bool_value(map_i,  tbrelations, compop, aggregate, topolist)
-            for topo in topolist:
-                if topo.upper() in tbrelations.keys():
-                    if count_map:
-                        relationmaplist = tbrelations[topo.upper()]
-                        gvar = GlobalTemporalVar()
-                        gvar.td = len(relationmaplist)
-                        if "map_value" in dir(map_i):
-                            map_i.map_value.append(gvar)
-                        else:
-                            map_i.map_value = gvar
-                    # Use unique identifier, since map names may be equal
-                    resultdict[map_i.uid] = map_i
+                self.compare_bool_value(map_i, compop, aggregate, temporal_topo_list, spatial_topo_list)
+
+            temporal_relations = map_i.get_temporal_relations()
+            spatial_relations = map_i.get_spatial_relations()
+
+            for temporal_topology in temporal_topo_list:
+                if temporal_topology.upper() in temporal_relations.keys():
+                    if self._check_spatial_topology_entries(spatial_topo_list, spatial_relations) is True:
+                        if count_map:
+                            relationmaplist = temporal_relations[temporal_topology.upper()]
+                            gvar = GlobalTemporalVar()
+                            gvar.td = len(relationmaplist)
+                            if "map_value" in dir(map_i):
+                                map_i.map_value.append(gvar)
+                            else:
+                                map_i.map_value = gvar
+                        # Use unique identifier, since map names may be equal
+                        resultdict[map_i.uid] = map_i
         resultlist = resultdict.values()
 
         # Sort list of maps chronological.
-        resultlist = sorted(resultlist, key = AbstractDatasetComparisonKeyStartTime)
+        resultlist = sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime)
 
         return(resultlist)
 
     def assign_bool_value(self,
                           map_i,
-                          tbrelations,
-                          topolist=["EQUAL"]):
+                          temporal_topo_list=["EQUAL"],
+                          spatial_topo_list=[]):
         """ Function to assign boolean map value based on the map_values from the
         compared map list by topological relationships.
 
           :param map_i: Map object with temporal extent.
-          :param tbrelations: List of temporal relation to map_i.
-          :param topolist: List of strings for given temporal relations.
+          :param temporal_topo_list: List of strings for given temporal relations.
+          :param spatial_topo_list: List of strings for given spatial relations.
 
           :return: Map object with conditional value that has been assigned by
                         relation maps that fulfil the topological relationships to
-                        maplistB specified in topolist.
+                        maplistB specified in temporal_topo_list.
         """
+
+        temporal_relations = map_i.get_temporal_relations()
         condition_value_list = []
-        for topo in topolist:
-            if topo.upper() in tbrelations.keys():
-                #relationmaplist = tbrelations[complementdict[topo.upper()]]
-                relationmaplist = tbrelations[topo.upper()]
+        for topo in temporal_topo_list:
+            if topo.upper() in temporal_relations.keys():
+                relationmaplist = temporal_relations[topo.upper()]
                 for relationmap in relationmaplist:
-                    for boolean in relationmap.condition_value:
-                        if isinstance(boolean, bool):
-                            condition_value_list.append(boolean)
-                    if self.debug:
-                        print(str(relationmap.get_temporal_extent_as_tuple()) + str(boolean))
+                    if self._check_spatial_topology_relation(spatial_topo_list, map_i, relationmap) is True:
+                        for boolean in relationmap.condition_value:
+                            if isinstance(boolean, bool):
+                                condition_value_list.append(boolean)
+                        if self.debug:
+                            print("assign_bool_value", str(relationmap.get_temporal_extent_as_tuple())
+                                  + str(boolean))
         if all(condition_value_list):
             resultbool = True
         else:
@@ -1466,39 +1548,46 @@
 
     def compare_bool_value(self,
                            map_i,
-                           tbrelations,
                            compop,
                            aggregate,
-                           topolist=["EQUAL"]):
+                           temporal_topo_list=["EQUAL"],
+                           spatial_topo_list=[]):
         """ Function to evaluate two map lists with boolean values by boolean
             comparison operator.
 
           :param map_i: Map object with temporal extent.
-          :param tbrelations: List of temporal relation to map_i.
-          :param topolist: List of strings for given temporal relations.
           :param compop: Comparison operator, && or ||.
           :param aggregate: Aggregation operator for relation map list, & or |.
+          :param temporal_topo_list: List of strings for given temporal relations.
+          :param spatial_topo_list: List of strings for given spatial relations.
 
           :return: Map object with conditional value that has been evaluated by
                         comparison operators.
         """
+
+        temporal_relations = map_i.get_temporal_relations()
+
         # Build conditional list with elements from related maps and given relation operator.
         leftbool = map_i.condition_value[0]
         condition_value_list = [leftbool]
         count = 0
-        for topo in topolist:
-            if topo.upper() in tbrelations.keys():
-                relationmaplist = tbrelations[topo.upper()]
-                if count == 0:
-                    condition_value_list.append(compop[0])
-                    condition_value_list.append('(')
+        for topo in temporal_topo_list:
+            if topo.upper() in temporal_relations.keys():
+                relationmaplist = temporal_relations[topo.upper()]
                 for relationmap in relationmaplist:
-                    for boolean in relationmap.condition_value:
-                        if isinstance(boolean, bool):
-                            if count > 0:
-                                condition_value_list.append(aggregate)
-                            condition_value_list.append(boolean)
-                            count = count + 1
+                    if self._check_spatial_topology_relation(spatial_topo_list, map_i, relationmap) is True:
+                        if count == 0:
+                            condition_value_list.append(compop[0])
+                            condition_value_list.append('(')
+                        for boolean in relationmap.condition_value:
+                            if isinstance(boolean, bool):
+                                if count > 0:
+                                    condition_value_list.append(aggregate)
+                                condition_value_list.append(boolean)
+                                count = count + 1
+
+                        if self.debug:
+                            print("compare_bool_value", map_i.get_id(), relationmap.get_id())
         if count > 0:
             condition_value_list.append(')')
         # Convert conditional list to concatenated string and evaluate booleans.
@@ -1605,13 +1694,13 @@
 
         """
         if not inverse:
-            topolist = self.get_temporal_topo_list(maplistA, maplistB, topolist,
-                                                    assign_val = assign_val)
+            topolist = self.build_spatio_temporal_topology_list(maplistA, maplistB, topolist,
+                                                                assign_val = assign_val)
             resultlist = topolist
 
         else:
-            topolist = self.get_temporal_topo_list(maplistA, maplistB, topolist,
-                                                    assign_val = assign_val)
+            topolist = self.build_spatio_temporal_topology_list(maplistA, maplistB, topolist,
+                                                                assign_val = assign_val)
             resultlist = []
             for map_i in maplistA:
                 if map_i not in topolist:
@@ -1927,7 +2016,7 @@
         """ This function evaluates temporal variable expressions of a conditional
              expression in two steps.
              At first it combines stepwise the single conditions by their relations with LALR.
-             In this prossess sub condition map lists will be created which will include
+             In this process sub condition map lists will be created which will include
              information of the underlying single conditions. Important: The temporal
              relations between conditions are evaluated by implicit aggregation.
              In the second step the aggregated condition map list will be compared with the
@@ -1974,7 +2063,7 @@
                 operator = tvarexpr[iter +1]
                 relexpr = tvarexpr[iter +2]
                 if all([issubclass(type(ele), list) for ele in [expr,  relexpr]]):
-                    resultlist = self.get_temporal_topo_list(expr,  relexpr)
+                    resultlist = self.build_spatio_temporal_topology_list(expr, relexpr)
             # Loop through the list, search for map lists or global variables.
             for expr in tvarexpr:
                 if isinstance(expr, list):
@@ -2381,9 +2470,9 @@
         if self.run:
             maplistA   = self.check_stds(t[1])
             maplistB   = self.check_stds(t[3])
-            resultlist = self.get_temporal_topo_list(maplistA,
-                                                     maplistB,
-                                                     count_map=True)
+            resultlist = self.build_spatio_temporal_topology_list(maplistA,
+                                                                  maplistB,
+                                                                  count_map=True)
             t[0] = resultlist
 
     def p_t_hash2(self,t):
@@ -2398,10 +2487,10 @@
             maplistA   = self.check_stds(t[1])
             maplistB   = self.check_stds(t[3])
             topolist   = self.eval_toperator(t[2], optype='hash')[0]
-            resultlist = self.get_temporal_topo_list(maplistA,
-                                                     maplistB,
-                                                     topolist,
-                                                     count_map=True)
+            resultlist = self.build_spatio_temporal_topology_list(maplistA,
+                                                                  maplistB,
+                                                                  topolist,
+                                                                  count_map=True)
             t[0] = resultlist
 
     def p_t_hash_paren(self, t):
@@ -2588,9 +2677,9 @@
             function = t[2] + t[3]
             aggregate = t[2]
             # Build conditional values based on topological relationships.
-            complist = self.get_temporal_topo_list(tvarexprA, tvarexprB, topolist=relations,
-                                                   compare_bool=True, compop=function[0],
-                                                   aggregate=aggregate)
+            complist = self.build_spatio_temporal_topology_list(tvarexprA, tvarexprB, topolist=relations,
+                                                                compare_bool=True, compop=function[0],
+                                                                aggregate=aggregate)
             # Set temporal extent based on topological relationships.
             resultlist = self.set_temporal_extent_list(complist, topolist = relations,
                                                        temporal=temporal)
@@ -2610,8 +2699,8 @@
             # Evaluate temporal comparison operator.
             relations, temporal, function, aggregate = self.eval_toperator(t[2],  optype='boolean')
             # Build conditional values based on topological relationships.
-            complist = self.get_temporal_topo_list(tvarexprA, tvarexprB, topolist=relations,
-                               compare_bool=True, compop=function[0], aggregate=aggregate)
+            complist = self.build_spatio_temporal_topology_list(tvarexprA, tvarexprB, topolist=relations,
+                                                                compare_bool=True, compop=function[0], aggregate=aggregate)
             # Set temporal extent based on topological relationships.
             resultlist = self.set_temporal_extent_list(complist, topolist=relations,
                                                        temporal=temporal)

Modified: grass/trunk/lib/python/temporal/temporal_granularity.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_granularity.py	2017-08-10 09:33:59 UTC (rev 71368)
+++ grass/trunk/lib/python/temporal/temporal_granularity.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -1021,25 +1021,25 @@
 
 def gran_singular_unit(gran):
     """Return the absolute granularity unit in its singular term
-    
+
     :param gran: input granularity
     :return: granularity unit
-    
+
     .. code-block:: python
 
         >>> import grass.temporal as tgis
         >>> tgis.init()
         >>> tgis.gran_singular_unit('1 month')
-        month
-        
+        'month'
+
         >>> tgis.gran_singular_unit('2 months')
-        month
-        
+        'month'
+
         >>> tgis.gran_singular_unit('6 seconds')
-        second
-        
+        'second'
+
         >>> tgis.gran_singular_unit('1 year')
-        year
+        'year'
     """
     if check_granularity_string(gran, 'absolute'):
         output, unit = gran.split(" ")
@@ -1057,31 +1057,31 @@
     else:
         print(_("Invalid absolute granularity"))
         return False
-        
 
+
 #######################################################################
 
 def gran_plural_unit(gran):
     """Return the absolute granularity unit in its singular term
-    
+
     :param gran: input granularity
     :return: granularity unit
-    
+
     .. code-block:: python
 
         >>> import grass.temporal as tgis
         >>> tgis.init()
         >>> tgis.gran_singular_unit('1 month')
-        months
-        
+        'month'
+
         >>> tgis.gran_singular_unit('2 months')
-        months
-        
+        'month'
+
         >>> tgis.gran_singular_unit('6 seconds')
-        seconds
-        
+        'second'
+
         >>> tgis.gran_singular_unit('1 year')
-        years
+        'year'
     """
     if check_granularity_string(gran, 'absolute'):
         output, unit = gran.split(" ")
@@ -1106,7 +1106,7 @@
        granularity based on the Gregorian calendar hierarchy that 1 year
        equals 12 months or 365.2425 days or 24 * 365.2425 hours or 86400 *
        365.2425 seconds.
-       
+
        :param from_gran: input granularity, this should be bigger than to_gran
        :param to_gran: output granularity
        :return: The output granularity
@@ -1117,25 +1117,25 @@
            >>> tgis.init()
            >>> tgis.gran_to_gran('1 month', '1 day')
            '30.436875 days'
-            
+
            >>> tgis.gran_to_gran('1 month', '1 day', True)
            30.436875
-            
+
            >>> tgis.gran_to_gran('10 year', '1 hour')
            '87658.2 hours'
-            
+
            >>> tgis.gran_to_gran('10 year', '1 minute')
            '5259492.0 minutes'
-            
+
            >>> tgis.gran_to_gran('6 months', '1 day')
            '182.62125 days'
-            
+
            >>> tgis.gran_to_gran('1 months', '1 second')
            '2629746.0 seconds'
-            
+
            >>> tgis.gran_to_gran('1 month', '1 second', True)
            2629746.0
-           
+
            >>> tgis.gran_to_gran('30 month', '1 month', True)
            30
     """
@@ -1171,8 +1171,8 @@
     else:
         print(_("Invalid absolute granularity"))
         return False
-        
 
+
 ###############################################################################
 # http://akiscode.com/articles/gcd_of_a_list.shtml
 # Copyright (c) 2010 Stephen Akiki

Modified: grass/trunk/lib/python/temporal/temporal_operator.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_operator.py	2017-08-10 09:33:59 UTC (rev 71368)
+++ grass/trunk/lib/python/temporal/temporal_operator.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -12,6 +12,12 @@
 .. code-block:: python
 
     >>> p = TemporalOperatorParser()
+    >>> expression =  "{equal|equivalent|cover|in|meet|contain|overlap}"
+    >>> p.parse(expression, optype = 'relation')
+    >>> print((p.relations, p.temporal, p.function))
+    (['equal', 'equivalent', 'cover', 'in', 'meet', 'contain', 'overlap'], None, None)
+
+    >>> p = TemporalOperatorParser()
     >>> expression =  "{equal| during}"
     >>> p.parse(expression, optype = 'relation')
     >>> print((p.relations, p.temporal, p.function))
@@ -146,6 +152,7 @@
 
     # Functions that defines topological relations.
     relations = {
+        # temporal relations
         'equal'      : "EQUAL",
         'follows'    : "FOLLOWS",
         'precedes'   : "PRECEDES",
@@ -157,7 +164,14 @@
         'contains'   : "CONTAINS",
         'started'    : "STARTED",
         'finished'   : "FINISHED",
-        'over'       : "OVER"
+        'over'       : "OVER",
+        # spatial relations
+        'equivalent' : "EQUIVALENT",
+        'cover'      : "COVER",
+        'overlap'    : "OVERLAP",
+        'in'         : "IN",
+        'contain'    : "CONTAIN",
+        'meet'       : "MEET"
         }
 
     # This is the list of token names.
@@ -451,7 +465,7 @@
         else:
             if len(t) == 4:
                 # Set three operator components.
-                self.relations = ['equal']
+                self.relations = ['equal', 'equivalent']
                 self.temporal  = "l"
                 self.function  = t[2]
             elif len(t) == 6:
@@ -579,7 +593,7 @@
             t[0] = t[2]
 
     def p_relation(self, t):
-        # The list of relations.
+        # The list of relations. Temporal and spatial relations are supported
         """
         relation : EQUAL
                  | FOLLOWS
@@ -592,6 +606,12 @@
                  | CONTAINS
                  | STARTED
                  | FINISHED
+                 | EQUIVALENT
+                 | COVER
+                 | OVERLAP
+                 | IN
+                 | CONTAIN
+                 | MEET
         """
         t[0] = t[1]
 
@@ -657,6 +677,7 @@
                 | NOT
         """
         t[0] = t[1]
+
 ###############################################################################
 
 if __name__ == "__main__":

Modified: grass/trunk/lib/python/temporal/temporal_raster_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_raster_algebra.py	2017-08-10 09:33:59 UTC (rev 71368)
+++ grass/trunk/lib/python/temporal/temporal_raster_algebra.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -78,7 +78,10 @@
                                                  spatial=spatial, register_null=register_null,
                                                  dry_run=dry_run, nprocs=nprocs)
 
-        self.m_mapcalc = pymod.Module('r.mapcalc')
+        if spatial is True:
+            self.m_mapcalc = pymod.Module('r.mapcalc', region="union", run_=False)
+        else:
+            self.m_mapcalc = pymod.Module('r.mapcalc')
         self.m_mremove = pymod.Module('g.remove')
 
     def parse(self, expression, basename = None, overwrite=False):

Modified: grass/trunk/lib/python/temporal/temporal_raster_base_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_raster_base_algebra.py	2017-08-10 09:33:59 UTC (rev 71368)
+++ grass/trunk/lib/python/temporal/temporal_raster_base_algebra.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -175,10 +175,10 @@
             return "null()"
 
     ######################### Temporal functions ##############################
-    def get_temporal_topo_list(self, maplistA, maplistB=None, topolist=["EQUAL"],
-                               assign_val=False, count_map=False, compare_bool=False,
-                               compare_cmd=False,  compop=None, aggregate=None,
-                               new=False,  convert=False,  operator_cmd=False):
+    def build_spatio_temporal_topology_list(self, maplistA, maplistB=None, topolist=["EQUAL"],
+                                            assign_val=False, count_map=False, compare_bool=False,
+                                            compare_cmd=False, compop=None, aggregate=None,
+                                            new=False, convert=False, operator_cmd=False):
         """Build temporal topology for two space time data sets, copy map objects
         for given relation into map list.
 
@@ -204,65 +204,94 @@
 
         :return: List of maps from maplistA that fulfil the topological relationships
               to maplistB specified in topolist.
+
+        >>> # Create two list of maps with equal time stamps
+        >>> from datetime import datetime
+        >>> import grass.temporal as tgis
+        >>> tgis.init(True)
+        >>> l = tgis.TemporalAlgebraParser()
+        >>> mapsA = []
+        >>> mapsB = []
+        >>> for i in range(10):
+        ...     idA = "a%i at B"%(i)
+        ...     mapA = tgis.RasterDataset(idA)
+        ...     mapA.uid = idA
+        ...     mapA.map_value = True
+        ...     idB = "b%i at B"%(i)
+        ...     mapB = tgis.RasterDataset(idB)
+        ...     mapB.uid = idB
+        ...     mapB.map_value = False
+        ...     check = mapA.set_absolute_time(datetime(2000,1,i+1),
+        ...             datetime(2000,1,i + 2))
+        ...     check = mapB.set_absolute_time(datetime(2000,1,i+6),
+        ...             datetime(2000,1,i + 7))
+        ...     mapsA.append(mapA)
+        ...     mapsB.append(mapB)
+        >>> resultlist = l.build_spatio_temporal_topology_list(mapsA, mapsB)
+        >>> for map in resultlist:
+        ...     print(map.get_id())
+        a5 at B
+        a6 at B
+        a7 at B
+        a8 at B
+        a9 at B
+
         """
-        topologylist = ["EQUAL", "FOLLOWS", "PRECEDES", "OVERLAPS", "OVERLAPPED",
-                        "DURING", "STARTS", "FINISHES", "CONTAINS", "STARTED",
-                        "FINISHED"]
-        complementdict = {"EQUAL": "EQUAL", "FOLLOWS" : "PRECEDES",
-                          "PRECEDES" : "FOLLOWS", "OVERLAPS" : "OVERLAPPED",
-                          "OVERLAPPED" : "OVERLAPS", "DURING" : "CONTAINS",
-                          "CONTAINS" : "DURING", "STARTS" : "STARTED",
-                          "STARTED" : "STARTS", "FINISHES" : "FINISHED",
-                          "FINISHED" : "FINISHES"}
+        print(topolist, assign_val, count_map, compare_bool, compare_cmd,
+              compop, aggregate, new, convert, operator_cmd)
+
+        # Check the topology definitions and return the list of temporal and spatial
+        # topological relations that must be fulfilled
+        temporal_topo_list, spatial_topo_list = self._check_topology(topolist=topolist)
+
         resultdict = {}
-        # Check if given temporal relation are valid.
-        for topo in topolist:
-          if topo.upper() not in topologylist:
-              raise SyntaxError("Unpermitted temporal relation name '" + topo + "'")
-
         # Create temporal topology for maplistA to maplistB.
         tb = SpatioTemporalTopologyBuilder()
-        # Dictionary with different spatial variables used for topology builder.
-        spatialdict = {'strds' : '2D', 'stvds' : '2D', 'str3ds' : '3D'}
-        # Build spatial temporal topology
-        if self.spatial:
+        # Build spatio-temporal topology
+        if len(spatial_topo_list) > 0:
+            # Dictionary with different spatial variables used for topology builder.
+            spatialdict = {'strds' : '2D', 'stvds' : '2D', 'str3ds' : '3D'}
             tb.build(maplistA, maplistB, spatial=spatialdict[self.stdstype])
         else:
             tb.build(maplistA, maplistB)
         # Iterate through maps in maplistA and search for relationships given
         # in topolist.
         for map_i in maplistA:
-            tbrelations = map_i.get_temporal_relations()
-            # Check for boolean parameters for further calculations.
             if assign_val:
-                self.assign_bool_value(map_i,  tbrelations,  topolist)
+                self.assign_bool_value(map_i, temporal_topo_list, spatial_topo_list)
             elif compare_bool:
-                self.compare_bool_value(map_i,  tbrelations, compop, aggregate, topolist)
+                self.compare_bool_value(map_i, compop, aggregate, temporal_topo_list, spatial_topo_list)
             elif compare_cmd:
-                self.compare_cmd_value(map_i,  tbrelations, compop, aggregate, topolist, convert)
+                self.compare_cmd_value(map_i, compop, aggregate, temporal_topo_list, spatial_topo_list, convert)
             elif operator_cmd:
-                self.operator_cmd_value(map_i,  tbrelations, compop, topolist)
+                self.operator_cmd_value(map_i,  compop, temporal_topo_list, spatial_topo_list)
 
-            for topo in topolist:
-                if topo.upper() in tbrelations.keys():
-                    if count_map:
-                        relationmaplist = tbrelations[topo.upper()]
-                        gvar = GlobalTemporalVar()
-                        gvar.td = len(relationmaplist)
-                        if "map_value" in dir(map_i):
-                            map_i.map_value.append(gvar)
-                        else:
-                            map_i.map_value = gvar
-                    # Use unique identifier, since map names may be equal
-                    resultdict[map_i.uid] = map_i
+            temporal_relations = map_i.get_temporal_relations()
+            spatial_relations = map_i.get_spatial_relations()
+
+            for temporal_topology in temporal_topo_list:
+                if temporal_topology.upper() in temporal_relations.keys():
+                    if self._check_spatial_topology_entries(spatial_topo_list, spatial_relations) is True:
+                        if count_map:
+                            relationmaplist = temporal_relations[temporal_topology.upper()]
+                            gvar = GlobalTemporalVar()
+                            gvar.td = len(relationmaplist)
+                            if "map_value" in dir(map_i):
+                                map_i.map_value.append(gvar)
+                            else:
+                                map_i.map_value = gvar
+                        # Use unique identifier, since map names may be equal
+                        resultdict[map_i.uid] = map_i
+                        # map_i.print_info()
+
         resultlist = resultdict.values()
 
         # Sort list of maps chronological.
-        resultlist = sorted(resultlist, key = AbstractDatasetComparisonKeyStartTime)
+        resultlist = sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime)
 
         return(resultlist)
 
-    def build_command_string(self, map_i,  relmap, operator = None, cmd_type = None):
+    def build_command_string(self, map_i, relmap, operator = None, cmd_type = None):
         """This function build the r.mapcalc command string for conditionals,
         spatial variable combinations and boolean comparisons.
 
@@ -312,26 +341,33 @@
             cmdstring = "(%s %s %s)" %(leftsub, operator, rightsub)
         return(cmdstring)
 
-    def compare_cmd_value(self,  map_i, tbrelations, compop, aggregate,
-                          topolist = ["EQUAL"],  convert = False):
+    def compare_cmd_value(self, map_i, compop, aggregate,
+                          temporal_topo_list = ["EQUAL"],
+                          spatial_topo_list = [], convert = False):
         """ Function to evaluate two map lists with boolean values by boolean
         comparison operator.
 
+        R = A && B
+
+        R = if(A < 1 && B > 1, A, B)
+
+        R = if(A < 1 {&&,equal|equivalent} B > 1, A, B)
+
         Extended temporal algebra version with command
         list builder for temporal raster algebra.
 
         :param map_i: Map object with temporal extent.
-        :param tbrelations: List of temporal relation to map_i.
-        :param topolist: List of strings for given temporal relations.
+        :param temporal_relations: List of temporal relation to map_i.
+        :param temporal_topo_list: List of strings for given temporal relations.
         :param compop: Comparison operator, && or ||.
         :param aggregate: Aggregation operator for relation map list, & or |.
         :param convert: Boolean if conditional values should be converted to
-                    r.mapcalc command strings.
+                        r.mapcalc command strings.
 
         :return: Map object with conditional value that has been evaluated by
                     comparison operators.
         """
-        # Build comandlist list with elements from related maps and given relation operator.
+        # Build command list list with elements from related maps and given relation operator.
         if convert and "condition_value" in dir(map_i):
             if map_i.condition_value != []:
                 cmdstring = str(int(map_i.condition_value[0]))
@@ -341,57 +377,76 @@
             cmd_value_list = [leftcmd]
         count = 0
 
-        for topo in topolist:
-            if topo.upper() in tbrelations.keys():
-                relationmaplist = tbrelations[topo.upper()]
+        temporal_relations = map_i.get_temporal_relations()
+
+        for topo in temporal_topo_list:
+            if topo.upper() in temporal_relations.keys():
+                relationmaplist = temporal_relations[topo.upper()]
                 if count == 0 and "cmd_list" in dir(map_i):
                     cmd_value_list.append(compop)
                     cmd_value_list.append('(')
                 for relationmap in relationmaplist:
-                    if convert and "condition_value" in dir(relationmap):
-                        if relationmap.condition_value != []:
-                            cmdstring = str(int(relationmap.condition_value[0]))
-                            relationmap.cmd_list = cmdstring
-                    if "cmd_list" in dir(relationmap):
-                        if count > 0:
-                            cmd_value_list.append(aggregate + aggregate)
-                        cmd_value_list.append(relationmap.cmd_list)
-                        count = count + 1
+                    if self._check_spatial_topology_relation(spatial_topo_list, map_i, relationmap) is True:
+                        if convert and "condition_value" in dir(relationmap):
+                            if relationmap.condition_value != []:
+                                cmdstring = str(int(relationmap.condition_value[0]))
+                                relationmap.cmd_list = cmdstring
+                        if "cmd_list" in dir(relationmap):
+                            if count > 0:
+                                cmd_value_list.append(aggregate + aggregate)
+                            cmd_value_list.append(relationmap.cmd_list)
+                            count = count + 1
+                        if self.debug:
+                            print("compare_cmd_value", map_i.get_id(),
+                                  relationmap.get_id(), relationmap.cmd_list)
         if count > 0:
             cmd_value_list.append(')')
             cmd_value_str = ''.join(map(str, cmd_value_list))
             # Add command list to result map.
             map_i.cmd_list = cmd_value_str
 
+            print(cmd_value_str)
+
             return(cmd_value_str)
 
-    def operator_cmd_value(self,  map_i, tbrelations, operator, topolist = ["EQUAL"]):
+    def operator_cmd_value(self,  map_i, operator,
+                          temporal_topo_list = ["EQUAL"],
+                          spatial_topo_list = []):
         """ Function to evaluate two map lists by given arithmetic operator.
 
         :param map_i: Map object with temporal extent.
-        :param tbrelations: List of temporal relation to map_i.
-        :param topolist: List of strings for given temporal relations.
         :param operator: Arithmetic operator, +-*/%.
+        :param temporal_topo_list: List of strings for given temporal relations.
+        :param spatial_topo_list: List of strings for given spatial relations.
 
-        :return: Map object with command list with  operators that has been
-                    evaluated by implicit aggregration.
+        :return: Map object with command list with operators that has been
+                    evaluated by implicit aggregation.
         """
+
+        temporal_relations = map_i.get_temporal_relations()
+        spatial_relations = map_i.get_spatial_relations()
+
         # Build comandlist list with elements from related maps and given relation operator.
         leftcmd = map_i
         cmdstring = ""
-        for topo in topolist:
-            if topo.upper() in tbrelations.keys():
-                relationmaplist = tbrelations[topo.upper()]
+        for topo in temporal_topo_list:
+            if topo.upper() in temporal_relations.keys():
+                relationmaplist = temporal_relations[topo.upper()]
                 for relationmap in relationmaplist:
-                    # Create r.mapcalc expression string for the operation.
-                    cmdstring = self.build_command_string(leftcmd,
-                                                          relationmap,
-                                                          operator=operator,
-                                                          cmd_type="operator")
-                    leftcmd = cmdstring
+                    if self._check_spatial_topology_relation(spatial_topo_list, map_i, relationmap) is True:
+                        # Create r.mapcalc expression string for the operation.
+                        cmdstring = self.build_command_string(leftcmd,
+                                                              relationmap,
+                                                              operator=operator,
+                                                              cmd_type="operator")
+                        leftcmd = cmdstring
+
+                        if self.debug:
+                            print("operator_cmd_value", map_i.get_id(), operator, relationmap.get_id())
         # Add command list to result map.
         map_i.cmd_list = cmdstring
 
+        print("map command string", cmdstring)
         return(cmdstring)
 
     def set_temporal_extent_list(self, maplist, topolist=["EQUAL"], temporal='l' ,
@@ -400,11 +455,11 @@
         other map list and given temporal operator.
 
         :param maplist: List of map objects for which relations has been build
-                                    correctely.
+                        correctly.
         :param topolist: List of strings of temporal relations.
         :param temporal: The temporal operator specifying the temporal
-                                        extent operation (intersection, union, disjoint
-                                        union, right reference, left reference).
+                         extent operation (intersection, union, disjoint
+                         union, right reference, left reference).
         :param cmd_bool: Boolean if command string should be merged for related maps.
         :param cmd_type: map object with defined temporal relation to map_i:
                         condition, conclusion or operator.
@@ -413,6 +468,7 @@
         :return: Map list with specified temporal extent and optional command string.
         """
         resultdict = {}
+        temporal_topo_list, spatial_topo_list = self._check_topology(topolist=topolist)
 
         for map_i in maplist:
             # Loop over temporal related maps and create overlay modules.
@@ -427,34 +483,35 @@
             for topo in topolist:
                 if topo in tbrelations.keys():
                     for map_j in (tbrelations[topo]):
-                        if temporal == 'r':
-                            # Generate an intermediate map for the result map list.
-                            map_new = self.generate_new_map(base_map=map_i,
-                                                            bool_op='and',
-                                                            copy=True,
-                                                            rename=True)
-                        # Create overlaid map extent.
-                        returncode = self.overlay_map_extent(map_new, map_j,
-                                                             'and',
-                                                             temp_op = temporal)
+                        if self._check_spatial_topology_relation(spatial_topo_list, map_i, map_j) is True:
+                            if temporal == 'r':
+                                # Generate an intermediate map for the result map list.
+                                map_new = self.generate_new_map(base_map=map_i,
+                                                                bool_op='and',
+                                                                copy=True,
+                                                                rename=True)
+                            # Create overlaid map extent.
+                            returncode = self.overlay_map_extent(map_new, map_j,
+                                                                 'and',
+                                                                 temp_op=temporal)
 
-                        # Stop the loop if no temporal or spatial relationship exist.
-                        if returncode == 0:
-                            break
-                        # Append map to result map list.
-                        elif returncode == 1:
-                            # print(map_new.cmd_list)
-                            # resultlist.append(map_new)
-                            if cmd_bool:
-                                # Create r.mapcalc expression string for the operation.
-                                cmdstring = self.build_command_string(map_i,
-                                                                      map_j,
-                                                                      operator=operator,
-                                                                      cmd_type=cmd_type)
-                                # Conditional append of module command.
-                                map_new.cmd_list = cmdstring
-                            # Write map object to result dictionary.
-                            resultdict[map_new.uid] = map_new
+                            # Stop the loop if no temporal or spatial relationship exist.
+                            if returncode == 0:
+                                break
+                            # Append map to result map list.
+                            elif returncode == 1:
+                                # print(map_new.cmd_list)
+                                # resultlist.append(map_new)
+                                if cmd_bool:
+                                    # Create r.mapcalc expression string for the operation.
+                                    cmdstring = self.build_command_string(map_i,
+                                                                          map_j,
+                                                                          operator=operator,
+                                                                          cmd_type=cmd_type)
+                                    # Conditional append of module command.
+                                    map_new.cmd_list = cmdstring
+                                # Write map object to result dictionary.
+                                resultdict[map_new.uid] = map_new
                     if returncode == 0:
                         break
             # Append map to result map list.
@@ -477,12 +534,12 @@
         :param thenlist: Map list with temporal extents and command list or numeric string.
         :param elselist: Map list with temporal extents and command list or numeric string.
         :param condition_topolist: List of strings for given temporal relations between
-                        conditions and conclusions.
+                                   conditions and conclusions.
         :param conclusion_topolist: List of strings for given temporal relations between
-                        conditions (then and else).
+                                    conditions (then and else).
         :param temporal: The temporal operator specifying the temporal
-                                        extent operation (intersection, union, disjoint
-                                        union, right reference, left reference).
+                         extent operation (intersection, union, disjoint
+                         union, right reference, left reference).
         :param null: Boolean if null map support should be activated.
 
         :return: map list with resulting command string for given condition type.
@@ -492,8 +549,8 @@
         # Check if alternative conclusion map list is given.
         if all([isinstance(thenlist, list), isinstance(elselist, list)]):
             # Build conclusion command map list.
-            conclusiontopolist = self.get_temporal_topo_list(thenlist, elselist,
-                                                             conclusion_topolist)
+            conclusiontopolist = self.build_spatio_temporal_topology_list(thenlist, elselist,
+                                                                          conclusion_topolist)
             conclusionlist = self.set_temporal_extent_list(conclusiontopolist,
                                                            topolist=conclusion_topolist,
                                                            temporal=temporal ,
@@ -549,9 +606,10 @@
             return(resultlist)
         elif isinstance(conclusionlist,  list):
             # Build result command map list between conditions and conclusions.
-            conditiontopolist = self.get_temporal_topo_list(iflist,
-                                                            conclusionlist,
-                                                            topolist=condition_topolist)
+            print("build_condition_cmd_list", condition_topolist)
+            conditiontopolist = self.build_spatio_temporal_topology_list(iflist,
+                                                                         conclusionlist,
+                                                                         topolist=condition_topolist)
             resultlist = self.set_temporal_extent_list(conditiontopolist,
                                                        topolist=condition_topolist,
                                                        temporal='r',
@@ -603,7 +661,8 @@
                         m_expression = newident + "=" + map_i.cmd_list
                         m.inputs["expression"].value = str(m_expression)
                         m.flags["overwrite"].value = self.overwrite
-                        #print(m.get_bash())
+                        if self.debug:
+                            print(m.get_bash())
                         self.process_chain_dict["processes"].append(m.get_dict())
 
                         if self.dry_run is False:
@@ -620,7 +679,8 @@
                         m_expression = newident + "=" + map_i.get_map_id()
                         m.inputs["expression"].value = str(m_expression)
                         m.flags["overwrite"].value = self.overwrite
-                        #print(m.get_bash())
+                        if self.debug:
+                            print(m.get_bash())
                         self.process_chain_dict["processes"].append(m.get_dict())
 
                         if self.dry_run is False:
@@ -761,7 +821,7 @@
         maplistA = self.check_stds(t[1])
         maplistB = self.check_stds(t[3])
 
-        topolist = self.get_temporal_topo_list(maplistA, maplistB)
+        topolist = self.build_spatio_temporal_topology_list(maplistA, maplistB)
 
         if self.run:
             resultlist = []
@@ -930,7 +990,7 @@
         # Check input stds.
         maplistA = self.check_stds(t[1])
         maplistB = self.check_stds(t[3])
-        topolist = self.get_temporal_topo_list(maplistA, maplistB)
+        topolist = self.build_spatio_temporal_topology_list(maplistA, maplistB)
 
         if self.run:
             resultlist = []
@@ -1081,11 +1141,11 @@
             maplistB = self.check_stds(t[3])
             relations, temporal, function, aggregate = self.eval_toperator(t[2], optype='raster')
             # Build conditional values based on topological relationships.
-            complist = self.get_temporal_topo_list(maplistA,
-                                                   maplistB,
-                                                   topolist=relations,
-                                                   operator_cmd=True,
-                                                   compop=function)
+            complist = self.build_spatio_temporal_topology_list(maplistA,
+                                                                maplistB,
+                                                                topolist=relations,
+                                                                operator_cmd=True,
+                                                                compop=function)
             # Set temporal extent based on topological relationships.
             resultlist = self.set_temporal_extent_list(complist,
                                                        topolist=relations,
@@ -1116,11 +1176,11 @@
             maplistB = self.check_stds(t[3])
             relations, temporal, function, aggregate = self.eval_toperator(t[2], optype='raster')
             # Build conditional values based on topological relationships.
-            complist = self.get_temporal_topo_list(maplistA,
-                                                   maplistB,
-                                                   topolist=relations,
-                                                   operator_cmd=True,
-                                                   compop=function)
+            complist = self.build_spatio_temporal_topology_list(maplistA,
+                                                                maplistB,
+                                                                topolist=relations,
+                                                                operator_cmd=True,
+                                                                compop=function)
             # Set temporal extent based on topological relationships.
             resultlist = self.set_temporal_extent_list(complist,
                                                        topolist=relations,
@@ -1347,12 +1407,12 @@
             function = t[2] + t[3]
             aggregate = t[2]
             # Build conditional values based on topological relationships.
-            complist = self.get_temporal_topo_list(s_var_exprA,
-                                                   s_var_exprB,
-                                                   topolist=relations,
-                                                   compare_cmd=True,
-                                                   compop=function,
-                                                   aggregate=aggregate)
+            complist = self.build_spatio_temporal_topology_list(s_var_exprA,
+                                                                s_var_exprB,
+                                                                topolist=relations,
+                                                                compare_cmd=True,
+                                                                compop=function,
+                                                                aggregate=aggregate)
             # Set temporal extent based on topological relationships.
             resultlist = self.set_temporal_extent_list(complist,
                                                        topolist=relations,
@@ -1377,12 +1437,12 @@
             # Evaluate temporal comparison operator.
             relations, temporal, function, aggregate = self.eval_toperator(t[2], optype='boolean')
             # Build conditional values based on topological relationships.
-            complist = self.get_temporal_topo_list(s_var_exprA,
-                                                   s_var_exprB,
-                                                   topolist=relations,
-                                                   compare_cmd=True,
-                                                   compop=function,
-                                                   aggregate=aggregate)
+            complist = self.build_spatio_temporal_topology_list(s_var_exprA,
+                                                                s_var_exprB,
+                                                                topolist=relations,
+                                                                compare_cmd=True,
+                                                                compop=function,
+                                                                aggregate=aggregate)
             # Set temporal extent based on topological relationships.
             resultlist = self.set_temporal_extent_list(complist,
                                                        topolist=relations,
@@ -1720,13 +1780,13 @@
             function = t[2] + t[3]
             aggregate = t[2]
             # Build conditional values based on topological relationships.
-            complist = self.get_temporal_topo_list(s_var_exprA,
-                                                   s_var_exprB,
-                                                   topolist=relations,
-                                                   compare_cmd=True,
-                                                   compop=function,
-                                                   aggregate=aggregate,
-                                                   convert=True)
+            complist = self.build_spatio_temporal_topology_list(s_var_exprA,
+                                                                s_var_exprB,
+                                                                topolist=relations,
+                                                                compare_cmd=True,
+                                                                compop=function,
+                                                                aggregate=aggregate,
+                                                                convert=True)
             # Set temporal extent based on topological relationships.
             resultlist = self.set_temporal_extent_list(complist,
                                                        topolist=relations,

Modified: grass/trunk/lib/python/temporal/temporal_vector_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_vector_algebra.py	2017-08-10 09:33:59 UTC (rev 71368)
+++ grass/trunk/lib/python/temporal/temporal_vector_algebra.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -162,10 +162,10 @@
 
     ######################### Temporal functions ##############################
 
-    def get_temporal_topo_list(self, maplistA, maplistB = None, topolist = ["EQUAL"],
-                               assign_val = False, count_map = False, compare_bool = False,
-                               compare_cmd = False,  compop = None, aggregate = None,
-                               new = False,  convert = False,  overlay_cmd = False):
+    def build_spatio_temporal_topology_list(self, maplistA, maplistB = None, topolist = ["EQUAL"],
+                                            assign_val = False, count_map = False, compare_bool = False,
+                                            compare_cmd = False, compop = None, aggregate = None,
+                                            new = False, convert = False, overlay_cmd = False):
         """Build temporal topology for two space time data sets, copy map objects
           for given relation into map list.
 
@@ -540,8 +540,8 @@
             temporal = 'l'
             function = t[2]
             # Build command list for related maps.
-            complist = self.get_temporal_topo_list(maplistA, maplistB, topolist = relations,
-                                                                    compop = function, overlay_cmd = True)
+            complist = self.build_spatio_temporal_topology_list(maplistA, maplistB, topolist = relations,
+                                                                compop = function, overlay_cmd = True)
             # Set temporal extent based on topological relationships.
             resultlist = self.set_temporal_extent_list(complist, topolist = relations,
                                 temporal = temporal)
@@ -563,8 +563,8 @@
             maplistB = self.check_stds(t[3])
             relations, temporal, function,  aggregate = self.eval_toperator(t[2],  optype = 'overlay')
             # Build command list for related maps.
-            complist = self.get_temporal_topo_list(maplistA, maplistB, topolist = relations,
-                                                                    compop = function, overlay_cmd = True)
+            complist = self.build_spatio_temporal_topology_list(maplistA, maplistB, topolist = relations,
+                                                                compop = function, overlay_cmd = True)
             # Set temporal extent based on topological relationships.
             resultlist = self.set_temporal_extent_list(complist, topolist = relations,
                                 temporal = temporal)

Modified: grass/trunk/lib/python/temporal/testsuite/unittests_temporal_conditionals.py
===================================================================
--- grass/trunk/lib/python/temporal/testsuite/unittests_temporal_conditionals.py	2017-08-10 09:33:59 UTC (rev 71368)
+++ grass/trunk/lib/python/temporal/testsuite/unittests_temporal_conditionals.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -38,7 +38,7 @@
         cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="e1 = 11")
         cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="e2 = 12")
         cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="e3 = 13")
-        
+
         cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="singletmap = 99")
 
         tgis.open_new_stds(name="A", type="strds", temporaltype="absolute",
@@ -51,7 +51,7 @@
                                          title="D", descr="D", semantic="field", overwrite=True)
         tgis.open_new_stds(name="E", type="strds", temporaltype="absolute",
                                          title="E", descr="E", semantic="field", overwrite=True)
-                                         
+
         tgis.register_maps_in_space_time_dataset(type="raster", name="A", maps="a1,a2,a3,a4",
                                                  start="2001-01-01", increment="1 day", interval=True)
         tgis.register_maps_in_space_time_dataset(type="raster", name="B", maps="b1,b2",
@@ -62,7 +62,7 @@
                                                  start="2001-01-03", increment="1 day", interval=True)
         tgis.register_maps_in_space_time_dataset(type="raster", name="E", maps="e1,e2,e3",
                                                  start="2000-12-31", increment="2 day", interval=True)
-        tgis.register_maps_in_space_time_dataset(type="raster", name=None,  maps="singletmap", 
+        tgis.register_maps_in_space_time_dataset(type="raster", name=None,  maps="singletmap",
                                                 start="2001-01-03", end="2001-01-04")
 
     def tearDown(self):
@@ -83,8 +83,8 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 2)
-        self.assertEqual(D.metadata.get_min_min(), 3) 
-        self.assertEqual(D.metadata.get_max_max(), 4) 
+        self.assertEqual(D.metadata.get_min_min(), 3)
+        self.assertEqual(D.metadata.get_max_max(), 4)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 3))
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
@@ -99,14 +99,14 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 4)
-        self.assertEqual(D.metadata.get_min_min(), 1) 
-        self.assertEqual(D.metadata.get_max_max(), 4) 
+        self.assertEqual(D.metadata.get_min_min(), 1)
+        self.assertEqual(D.metadata.get_max_max(), 4)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1))
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
         self.assertEqual( D.check_temporal_topology(),  True)
         self.assertEqual(D.get_granularity(),  u'1 day')
-    
+
     def test_temporal_condition_3(self):
         """Testing the temporal select operator with equal relations. """
         ta = tgis.TemporalAlgebraParser(run=True, debug=True)
@@ -115,14 +115,14 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 4)
-        self.assertEqual(D.metadata.get_min_min(), 1) 
-        self.assertEqual(D.metadata.get_max_max(), 4) 
+        self.assertEqual(D.metadata.get_min_min(), 1)
+        self.assertEqual(D.metadata.get_max_max(), 4)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1))
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
         self.assertEqual( D.check_temporal_topology(),  True)
         self.assertEqual(D.get_granularity(),  u'1 day')
-    
+
     def test_temporal_condition_4(self):
         """Testing the temporal select operator with equal relations. """
         ta = tgis.TemporalAlgebraParser(run=True, debug=True)
@@ -131,8 +131,8 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 2)
-        self.assertEqual(D.metadata.get_min_min(), 3) 
-        self.assertEqual(D.metadata.get_max_max(), 4) 
+        self.assertEqual(D.metadata.get_min_min(), 3)
+        self.assertEqual(D.metadata.get_max_max(), 4)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 3))
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
@@ -147,14 +147,14 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 2)
-        self.assertEqual(D.metadata.get_min_min(), 1) 
-        self.assertEqual(D.metadata.get_max_max(), 2) 
+        self.assertEqual(D.metadata.get_min_min(), 1)
+        self.assertEqual(D.metadata.get_max_max(), 2)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1))
         self.assertEqual(end, datetime.datetime(2001, 1, 3))
         self.assertEqual( D.check_temporal_topology(),  True)
         self.assertEqual(D.get_granularity(),  u'1 day')
-    
+
     def test_temporal_condition_6(self):
         """Testing the temporal select operator with equal relations. """
         ta = tgis.TemporalAlgebraParser(run=True, debug=True)
@@ -164,8 +164,8 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 2)
-        self.assertEqual(D.metadata.get_min_min(), 2) 
-        self.assertEqual(D.metadata.get_max_max(), 3) 
+        self.assertEqual(D.metadata.get_min_min(), 2)
+        self.assertEqual(D.metadata.get_max_max(), 3)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 2))
         self.assertEqual(end, datetime.datetime(2001, 1, 4))
@@ -181,8 +181,8 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 2)
-        self.assertEqual(D.metadata.get_min_min(), 5) 
-        self.assertEqual(D.metadata.get_max_max(), 6) 
+        self.assertEqual(D.metadata.get_min_min(), 5)
+        self.assertEqual(D.metadata.get_max_max(), 6)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1))
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
@@ -198,8 +198,8 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 2)
-        self.assertEqual(D.metadata.get_min_min(), 5) 
-        self.assertEqual(D.metadata.get_max_max(), 6) 
+        self.assertEqual(D.metadata.get_min_min(), 5)
+        self.assertEqual(D.metadata.get_max_max(), 6)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1))
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
@@ -215,8 +215,8 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 1)
-        self.assertEqual(D.metadata.get_min_min(), 5) 
-        self.assertEqual(D.metadata.get_max_max(), 5) 
+        self.assertEqual(D.metadata.get_min_min(), 5)
+        self.assertEqual(D.metadata.get_max_max(), 5)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1))
         self.assertEqual(end, datetime.datetime(2001, 1, 3))
@@ -232,14 +232,14 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 3)
-        self.assertEqual(D.metadata.get_min_min(), 11) 
-        self.assertEqual(D.metadata.get_max_max(), 13) 
+        self.assertEqual(D.metadata.get_min_min(), 11)
+        self.assertEqual(D.metadata.get_max_max(), 13)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2000, 12, 31))
         self.assertEqual(end, datetime.datetime(2001, 1, 6))
         self.assertEqual( D.check_temporal_topology(),  True)
         self.assertEqual(D.get_granularity(),  u'2 days')
- 
+
     def test_temporal_condition_11(self):
         """Testing the temporal select operator with equal relations. """
         ta = tgis.TemporalAlgebraParser(run=True, debug=True)
@@ -249,8 +249,8 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 1)
-        self.assertEqual(D.metadata.get_min_min(), 11) 
-        self.assertEqual(D.metadata.get_max_max(), 11) 
+        self.assertEqual(D.metadata.get_min_min(), 11)
+        self.assertEqual(D.metadata.get_max_max(), 11)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2000, 12, 31))
         self.assertEqual(end, datetime.datetime(2001, 1, 2))
@@ -266,14 +266,14 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 1)
-        self.assertEqual(D.metadata.get_min_min(), 11) 
-        self.assertEqual(D.metadata.get_max_max(), 11) 
+        self.assertEqual(D.metadata.get_min_min(), 11)
+        self.assertEqual(D.metadata.get_max_max(), 11)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2000, 12, 31))
         self.assertEqual(end, datetime.datetime(2001, 1, 2))
         self.assertEqual( D.check_temporal_topology(),  True)
         self.assertEqual(D.get_granularity(),  u'2 days')
-    
+
     def test_temporal_conditional_13(self):
         """Testing the hash operator function in conditional statement. """
         ta = tgis.TemporalAlgebraParser(run=True, debug=True)
@@ -284,14 +284,14 @@
         D.select()
         maplist = D.get_registered_maps_as_objects()
         self.assertEqual(D.metadata.get_number_of_maps(), 4)
-        self.assertEqual(D.metadata.get_min_min(), 1) 
-        self.assertEqual(D.metadata.get_max_max(), 4) 
+        self.assertEqual(D.metadata.get_min_min(), 1)
+        self.assertEqual(D.metadata.get_max_max(), 4)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1))
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
         self.assertEqual( D.check_temporal_topology(),  True)
         self.assertEqual(D.get_granularity(),  u'1 day')
- 
+
     def test_temporal_condition_else_1(self):
         """Testing the temporal select operator with equal relations. """
         ta = tgis.TemporalAlgebraParser(run=True, debug=True)
@@ -301,14 +301,14 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 4)
-        self.assertEqual(D.metadata.get_min_min(), 1) 
-        self.assertEqual(D.metadata.get_max_max(), 9) 
+        self.assertEqual(D.metadata.get_min_min(), 1)
+        self.assertEqual(D.metadata.get_max_max(), 9)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 1))
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
         self.assertEqual( D.check_temporal_topology(),  True)
         self.assertEqual(D.get_granularity(),  u'1 day')
-    
+
     def test_temporal_condition_else_2(self):
         """Testing the temporal select operator with equal relations. """
         ta = tgis.TemporalAlgebraParser(run=True, debug=True)
@@ -318,8 +318,8 @@
         D = tgis.open_old_stds("R", type="strds")
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 2)
-        self.assertEqual(D.metadata.get_min_min(), 4) 
-        self.assertEqual(D.metadata.get_max_max(), 8) 
+        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, 3))
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
@@ -336,7 +336,7 @@
         D.select()
         self.assertEqual(D.metadata.get_number_of_maps(), 2)
         self.assertEqual(D.metadata.get_min_min(), 8)
-        self.assertEqual(D.metadata.get_max_max(), 9) 
+        self.assertEqual(D.metadata.get_max_max(), 9)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2001, 1, 3))
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
@@ -354,8 +354,8 @@
         for map in D.get_registered_maps_as_objects():
             print(map.get_map_id())
         self.assertEqual(D.metadata.get_number_of_maps(), 3)
-        self.assertEqual(D.metadata.get_min_min(), 5) 
-        self.assertEqual(D.metadata.get_max_max(), 11) 
+        self.assertEqual(D.metadata.get_min_min(), 5)
+        self.assertEqual(D.metadata.get_max_max(), 11)
         start, end = D.get_absolute_time()
         self.assertEqual(start, datetime.datetime(2000, 12, 31))
         self.assertEqual(end, datetime.datetime(2001, 1, 5))

Modified: grass/trunk/lib/python/temporal/testsuite/unittests_temporal_raster3d_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/testsuite/unittests_temporal_raster3d_algebra.py	2017-08-10 09:33:59 UTC (rev 71368)
+++ grass/trunk/lib/python/temporal/testsuite/unittests_temporal_raster3d_algebra.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -32,7 +32,7 @@
         cls.runModule("r3.mapcalc", overwrite=True, quiet=True, expression="a4 = 4")
 
         tgis.open_new_stds(name="A", type="str3ds", temporaltype="absolute",
-                                         title="A", descr="A", semantic="field", overwrite=True)
+                           title="A", descr="A", semantic="field", overwrite=True)
 
         tgis.register_maps_in_space_time_dataset(type="raster_3d", name="A", maps="a1,a2,a3,a4",
                                                  start="2001-01-01", increment="1 day", interval=True)
@@ -44,11 +44,14 @@
     def tearDownClass(cls):
         """Remove the temporary region
         """
-        cls.runModule("t.remove", type="str3ds", flags="rf", inputs="A", quiet=True)
+        #cls.runModule("t.remove", type="str3ds", flags="rf", inputs="A", quiet=True)
         cls.del_temp_region()
 
     def test_temporal_neighbors_1(self):
         """Simple temporal neighborhood computation test"""
+        A = tgis.open_old_stds("A", type="str3ds")
+        A.print_info()
+
         tra = tgis.TemporalRaster3DAlgebraParser(run = True, debug = True)
         tra.parse(expression='D = A[-1] + A[1]',
                   basename="d", overwrite=True)
@@ -65,6 +68,9 @@
 
     def test_temporal_neighbors_2(self):
         """Simple temporal neighborhood computation test"""
+        A = tgis.open_old_stds("A", type="str3ds")
+        A.print_info()
+
         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)

Added: grass/trunk/lib/python/temporal/testsuite/unittests_temporal_raster_algebra_spatial_topology.py
===================================================================
--- grass/trunk/lib/python/temporal/testsuite/unittests_temporal_raster_algebra_spatial_topology.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/testsuite/unittests_temporal_raster_algebra_spatial_topology.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -0,0 +1,133 @@
+"""
+(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.
+
+:authors: Soeren Gebbert and Thomas Leppelt
+"""
+
+import datetime
+import grass.temporal as tgis
+from grass.gunittest.case import TestCase
+from grass.gunittest.main import test
+
+
+class TestTemporalRasterAlgebraImplicitAggregation(TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        """Initiate the temporal GIS and set the region
+        """
+        tgis.init(True) # Raise on error instead of exit(1)
+        cls.use_temp_region()
+        cls.runModule("g.region", n=30.0, s=0.0, e=30.0, w=0.0, t=1.0, b=0.0, res=10.0)
+        cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="a1 = 1")
+        cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="b1 = 1")
+
+        cls.runModule("g.region", n=50.0, s=20.0, e=50.0, w=20.0, t=1.0, b=0.0, res=10.0)
+        cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="a2 = 2")
+        cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="b2 = 2")
+
+        cls.runModule("g.region", n=40.0, s=25.0, e=40.0, w=25.0, t=1.0, b=0.0, res=10.0)
+        cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="a3 = 3")
+        cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="b3 = 3")
+
+        cls.runModule("g.region", n=60.0, s=40.0, e=60.0, w=40.0, t=1.0, b=0.0, res=10.0)
+        cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="a4 = 4")
+        cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="b4 = 4")
+
+        cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="singletmap = 100")
+        cls.runModule("r.mapcalc", overwrite=True, quiet=True, expression="singlemap = 1000")
+
+        tgis.open_new_stds(name="A", type="strds", temporaltype="absolute",
+                           title="A", descr="A", semantic="field", overwrite=True)
+
+        tgis.open_new_stds(name="B", type="strds", temporaltype="absolute",
+                           title="B", descr="B", semantic="field", overwrite=True)
+
+        tgis.register_maps_in_space_time_dataset(type="raster", name="A", maps="a1,a2,a3,a4",
+                                                 start="2001-01-01", interval=False)
+
+        tgis.register_maps_in_space_time_dataset(type="raster", name="B", maps="b1,b2,b3,b4",
+                                                 start="2001-01-01", interval=False)
+
+        tgis.register_maps_in_space_time_dataset(type="raster", name=None,  maps="singletmap",
+                                                 start="2001-01-01")
+
+    def tearDown(self):
+        self.runModule("t.remove", flags="rf", inputs="R", quiet=True)
+
+    @classmethod
+    def tearDownClass(cls):
+        """Remove the temporary region
+        """
+        cls.runModule("t.remove", flags="rf", inputs="A,B", quiet=True)
+        cls.runModule("t.unregister", maps="singletmap", quiet=True)
+        cls.del_temp_region()
+
+    def test_equal_equivalent_sum(self):
+        """Spatial topology distinction with equal timestamps
+
+        STRDS A and B have identical time stamps, hence the differentiation
+        is based on the spatial topological relations
+
+        R = A {+,equal|equivalent,l} B
+
+        spatial equal extents pairs: a1,b1  a2,b2  a3,b3  a4,b4
+
+        r1 = a1 + b1  # 2
+        r1 = a2 + b2  # 4
+        r1 = a3 + b3  # 6
+        r1 = a4 + b4  # 8
+
+        """
+        ta = tgis.TemporalRasterAlgebraParser(run=True, debug=True, spatial=True)
+        ta.parse(expression="R = A {+,equal|equivalent,l} B",   basename="r", overwrite=True)
+
+        D = tgis.open_old_stds("R", type="strds")
+        D.select()
+
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 2)
+        self.assertEqual(D.metadata.get_max_max(), 8)
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual( D.check_temporal_topology(),  False)
+        self.assertEqual(D.get_granularity(),  None)
+
+
+    def test_equal_equivalent_compare(self):
+        """Test implicit aggregation
+
+        STRDS A and B have identical time stamps, hence the differentiation
+        is based on the spatial topological relations
+
+        R = if({equal|equivalent}, A > 0 {&&,equal|equivalent} B < 10, A {+,equal|equivalent,l} B
+
+        spatial equal extents pairs: a1,b1  a2,b2  a3,b3  a4,b4
+
+        r1 = a1 + b1  # 2
+        r1 = a2 + b2  # 4
+        r1 = a3 + b3  # 6
+        r1 = a4 + b4  # 8
+
+        """
+        ta = tgis.TemporalRasterAlgebraParser(run=True, debug=True, spatial=True)
+        ta.parse(expression="R = if({equal|equivalent}, A > 0 {&&,equal|equivalent} B < 10, A {+,equal|equivalent,l} B)",
+                 basename="r", overwrite=True)
+
+        D = tgis.open_old_stds("R", type="strds")
+        D.select()
+
+        self.assertEqual(D.metadata.get_number_of_maps(), 4)
+        self.assertEqual(D.metadata.get_min_min(), 2)
+        self.assertEqual(D.metadata.get_max_max(), 8)
+        start, end = D.get_absolute_time()
+        self.assertEqual(start, datetime.datetime(2001, 1, 1))
+        self.assertEqual( D.check_temporal_topology(),  False)
+        self.assertEqual(D.get_granularity(),  None)
+
+
+if __name__ == '__main__':
+    test()

Modified: grass/trunk/lib/python/temporal/testsuite/unittests_temporal_raster_conditionals.py
===================================================================
--- grass/trunk/lib/python/temporal/testsuite/unittests_temporal_raster_conditionals.py	2017-08-10 09:33:59 UTC (rev 71368)
+++ grass/trunk/lib/python/temporal/testsuite/unittests_temporal_raster_conditionals.py	2017-08-10 11:36:46 UTC (rev 71369)
@@ -44,7 +44,7 @@
                                          title="C", descr="C", semantic="field", overwrite=True)
         tgis.open_new_stds(name="D", type="strds", temporaltype="absolute",
                                          title="D", descr="D", semantic="field", overwrite=True)
- 
+
         tgis.register_maps_in_space_time_dataset(type="raster", name="A", maps="a1,a2,a3,a4",
                                                  start="2001-01-01", increment="1 day", interval=True)
         tgis.register_maps_in_space_time_dataset(type="raster", name="B", maps="b1,b2",
@@ -53,7 +53,7 @@
                                                  start="2001-01-02", increment="2 day", interval=True)
         tgis.register_maps_in_space_time_dataset(type="raster", name="D", maps="d1,d2,d3,d4",
                                                  start="2001-01-03", increment="1 day", interval=True)
-        
+
     def tearDown(self):
         self.runModule("t.remove", flags="rf", inputs="R", quiet=True)
 
@@ -65,8 +65,8 @@
         cls.del_temp_region()
 
     def test_temporal_conditional_time_dimension_bug(self):
-        """Testing the conditional time dimension bug, that uses the time 
-            dimension of the conditional statement instead the time dimension 
+        """Testing the conditional time dimension bug, that uses the time
+            dimension of the conditional statement instead the time dimension
             of the then/else statement."""
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
         tra.parse(expression='R = if({contains}, B == 5,  A - 1,  A + 1)', basename="r", overwrite=True)
@@ -83,8 +83,8 @@
         self.assertEqual(R.get_granularity(),  u'1 day')
 
     def test_temporal_conditional_1(self):
-        """Testing the conditional time dimension bug, that uses the time 
-            dimension of the conditional statement instead the time dimension 
+        """Testing the conditional time dimension bug, that uses the time
+            dimension of the conditional statement instead the time dimension
             of the then/else statement."""
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
         tra.parse(expression='R = if(td(A) == 1,  D * 2, D)', basename="r", overwrite=True)
@@ -101,8 +101,8 @@
         self.assertEqual(R.get_granularity(),  u'1 day')
 
     def test_temporal_conditional_relation_1(self):
-        """Testing the conditional time dimension bug, that uses the time 
-            dimension of the conditional statement instead the time dimension 
+        """Testing the conditional time dimension bug, that uses the time
+            dimension of the conditional statement instead the time dimension
             of the then/else statement."""
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
         tra.parse(expression='R = if({during},exist(A),  B - 1,  B + 1)', basename="r", overwrite=True)
@@ -119,7 +119,7 @@
         self.assertEqual(R.get_granularity(),  u'2 days')
 
     def test_spatial_conditional_1(self):
-        """Testing the spatial conditionals combined by AND/OR operators. 
+        """Testing the spatial conditionals combined by AND/OR operators.
             Evaluation  """
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
         tra.parse(expression='R = if(A > 1 && A < 4 && isntnull(A), A)', basename="r", overwrite=True)
@@ -136,7 +136,7 @@
         self.assertEqual(R.get_granularity(),  u'1 day')
 
     def test_spatial_conditional_2(self):
-        """Testing the spatial conditionals combined by AND/OR operators. 
+        """Testing the spatial conditionals combined by AND/OR operators.
             Evaluation  """
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
         tra.parse(expression='R = if(A > 1 && A < 4 && isntnull(A), A, null())', basename="r", overwrite=True)
@@ -153,7 +153,7 @@
         self.assertEqual(R.get_granularity(),  u'1 day')
 
     def test_spatial_conditional_3(self):
-        """Testing the spatial conditionals combined by AND/OR operators. 
+        """Testing the spatial conditionals combined by AND/OR operators.
             Evaluation  """
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
         tra.parse(expression='R = if(A > 1, A, D)', basename="r", overwrite=True)
@@ -170,7 +170,7 @@
         self.assertEqual(R.get_granularity(),  u'1 day')
 
     def test_spatial_conditional_4(self):
-        """Testing the spatial conditionals combined by AND/OR operators. 
+        """Testing the spatial conditionals combined by AND/OR operators.
             Evaluation  """
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
         tra.parse(expression='R = if(A > 0, A)', basename="r", overwrite=True)
@@ -187,7 +187,7 @@
         self.assertEqual(R.get_granularity(),  u'1 day')
 
     def test_spatial_conditional_5(self):
-        """Testing the spatial conditionals combined by AND/OR operators. 
+        """Testing the spatial conditionals combined by AND/OR operators.
             Evaluation  """
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
         tra.parse(expression='R = if(B > 5 {&&,contains,l} A < 5, B)', basename="r", overwrite=True)
@@ -202,9 +202,9 @@
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
         self.assertEqual( R.check_temporal_topology(),  True)
         self.assertEqual(R.get_granularity(),  u'2 days')
-    
+
     def test_spatial_conditional_relation_1(self):
-        """Testing the spatial conditionals combined by AND/OR operators. 
+        """Testing the spatial conditionals combined by AND/OR operators.
             Evaluation  """
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
         tra.parse(expression='R = if({contains},B > 5, D)', basename="r", overwrite=True)
@@ -251,9 +251,9 @@
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
         self.assertEqual( R.check_temporal_topology(),  True)
         self.assertEqual(R.get_granularity(),  u'1 day')
-    
+
     def test_spatial_conditional_numeric_relation_2(self):
-        """Testing the spatial conditionals combined by AND/OR operators. 
+        """Testing the spatial conditionals combined by AND/OR operators.
             Evaluation  """
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
         tra.parse(expression='R = if({contains},B > 5, A + 2 / 4.0)', basename="r", overwrite=True)
@@ -268,7 +268,7 @@
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
         self.assertEqual( R.check_temporal_topology(),  True)
         self.assertEqual(R.get_granularity(),  u'1 day')
-    
+
     def test_spatial_conditional_numeric_1(self):
         """Testing the spatial conditionals with numeric conclusions"""
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
@@ -412,9 +412,9 @@
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
         self.assertEqual( R.check_temporal_topology(),  True)
         self.assertEqual(R.get_granularity(),  u'1 day')
-    
+
     def test_spatiotemporal_conditional_numeric_relation_2(self):
-        """Testing the spatial conditionals combined by AND/OR operators. 
+        """Testing the spatial conditionals combined by AND/OR operators.
             Evaluation  """
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)
         tra.parse(expression='R = if({contains},td(B) == 2 && start_date(B) == "2001-01-03" && B > 5 , A + 2 / 4.0)', basename="r", overwrite=True)
@@ -429,7 +429,7 @@
         self.assertEqual(end, datetime.datetime(2001, 1, 5))
         self.assertEqual( R.check_temporal_topology(),  True)
         self.assertEqual(R.get_granularity(),  u'1 day')
- 
+
     def test_spatiotemporal_conditional_numeric_1(self):
         """Testing the spatial conditionals with numeric conclusions"""
         tra = tgis.TemporalRasterAlgebraParser(run = True, debug = True)



More information about the grass-commit mailing list