[GRASS-SVN] r55998 - grass/trunk/lib/python/temporal

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Apr 25 16:07:37 PDT 2013


Author: huhabla
Date: 2013-04-25 16:07:37 -0700 (Thu, 25 Apr 2013)
New Revision: 55998

Added:
   grass/trunk/lib/python/temporal/spatial_topology_dataset_connector.py
   grass/trunk/lib/python/temporal/spatio_temporal_relationships.py
   grass/trunk/lib/python/temporal/temporal_topology_dataset_connector.py
Removed:
   grass/trunk/lib/python/temporal/abstract_spatial_dataset.py
   grass/trunk/lib/python/temporal/abstract_temporal_dataset.py
   grass/trunk/lib/python/temporal/temporal_relationships.py
Modified:
   grass/trunk/lib/python/temporal/Makefile
   grass/trunk/lib/python/temporal/__init__.py
   grass/trunk/lib/python/temporal/abstract_dataset.py
   grass/trunk/lib/python/temporal/abstract_map_dataset.py
   grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
   grass/trunk/lib/python/temporal/space_time_datasets.py
   grass/trunk/lib/python/temporal/unit_tests.py
Log:
Better naming scheme. Added spatial topology class.


Modified: grass/trunk/lib/python/temporal/Makefile
===================================================================
--- grass/trunk/lib/python/temporal/Makefile	2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/Makefile	2013-04-25 23:07:37 UTC (rev 55998)
@@ -8,7 +8,7 @@
 GDIR = $(PYDIR)/grass
 DSTDIR = $(GDIR)/temporal
 
-MODULES = base core abstract_dataset abstract_temporal_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets create factory gui_support list register sampling metadata spatial_extent temporal_extent datetime_math temporal_granularity temporal_relationships unit_tests aggregation stds_export stds_import extract mapcalc univar_statistics
+MODULES = base core abstract_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets create factory gui_support list register sampling metadata spatial_extent temporal_extent datetime_math temporal_granularity spatio_temporal_relationships unit_tests aggregation stds_export stds_import extract mapcalc univar_statistics temporal_topology_dataset_connector spatial_topology_dataset_connector
 
 PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
 PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)

Modified: grass/trunk/lib/python/temporal/__init__.py
===================================================================
--- grass/trunk/lib/python/temporal/__init__.py	2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/__init__.py	2013-04-25 23:07:37 UTC (rev 55998)
@@ -3,14 +3,15 @@
 from temporal_extent import *
 from spatial_extent import *
 from metadata import *
+from temporal_topology_dataset_connector import *
+from spatial_topology_dataset_connector import *
 from abstract_dataset import *
-from abstract_temporal_dataset import *
 from abstract_map_dataset import *
 from abstract_space_time_dataset import *
 from space_time_datasets import *
 from datetime_math import *
 from temporal_granularity import *
-from temporal_relationships import *
+from spatio_temporal_relationships import *
 from create import *
 from factory import *
 from gui_support import *

Modified: grass/trunk/lib/python/temporal/abstract_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_dataset.py	2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/abstract_dataset.py	2013-04-25 23:07:37 UTC (rev 55998)
@@ -35,6 +35,8 @@
 from temporal_extent import *
 from spatial_extent import *
 from metadata import *
+from temporal_topology_dataset_connector import *
+from spatial_topology_dataset_connector import *
 
 
 class ImplementationError(Exception):
@@ -48,12 +50,96 @@
     
 ###############################################################################
 
-class AbstractDataset(object):
+class AbstractDataset(SpatialTopologyDatasetConnector, TemporalTopologyDatasetConnector):
     """!This is the base class for all datasets 
        (raster, vector, raster3d, strds, stvds, str3ds)"""
     def __init__(self):
-        pass
+        SpatialTopologyDatasetConnector.__init__(self)
+        TemporalTopologyDatasetConnector.__init__(self)
+        
+    def reset_topology(self):
+        """!Reset any information about temporal topology"""
+        self.reset_spatial_topology()
+        self.reset_temporal_topology()
+        
+    def get_number_of_relations(self):      
+        """! Return a dictionary in which the keys are the relation names and the value
+        are the number of relations.
+        
+        The following relations are available:
+        
+        Spatial relations
+        - equivalent
+        - overlap
+        - in
+        - contain
+        - meet
+        - cover
+        - covered
+        
+        Temporal relations
+        - equal
+        - follows
+        - precedes
+        - overlaps
+        - overlapped
+        - during (including starts, finishes)
+        - contains (including started, finished)
+        - starts
+        - started
+        - finishes
+        - finished
+       
+        To access topological information the spatial, temporal or booth topologies must be build first
+        using the SpatialTopologyBuilder, TemporalTopologyBuilder or SpatioTemporalTopologyBuilder.
+        
+        @return the dictionary with relations as keys and number as values or None in case the topology  wasn't build
+        """
+        if self.is_temporal_topology_build() and not self.is_spatial_topology_build():
+            return self.get_number_of_temporal_relations()
+        elif self.is_spatial_topology_build() and not self.is_temporal_topology_build():
+            self.get_number_of_spatial_relations()
+        else:
+            return  self.get_number_of_temporal_relations() + \
+                    self.get_number_of_spatial_relations()
+            
+        return None
 
+    def set_topology_build_true(self):
+        """!Use this method when the spatio-temporal topology was build"""
+        self.set_spatial_topology_build_true()
+        self.set_temporal_topology_build_true()
+        
+
+    def set_topology_build_false(self):
+        """!Use this method when the spatio-temporal topology was not build"""
+        self.set_spatial_topology_build_false()
+        self.set_temporal_topology_build_false()
+
+    def is_topology_build(self):
+        """!Check if the spatial and temporal topology was build
+        
+           @return A dictionary with "spatial" and "temporal" as keys that have boolen values
+        """
+        d = {}
+        d["spatial"] = self.is_spatial_topology_build()
+        d["temporal"] = self.is_temporal_topology_build()
+        
+        return d
+        
+
+    def print_topology_info(self):
+        if self.is_temporal_topology_build():
+            self.print_temporal_topology_info()
+        if self.is_spatial_topology_build():
+            self.print_spatial_topology_info()
+            
+    def print_topology_shell_info(self):
+        if self.is_temporal_topology_build():
+            self.print_temporal_topology_shell_info()
+        if self.is_spatial_topology_build():
+            self.print_spatial_topology_shell_info()
+            
     def reset(self, ident):
         """!Reset the internal structure and set the identifier
 

Modified: grass/trunk/lib/python/temporal/abstract_map_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_map_dataset.py	2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/abstract_map_dataset.py	2013-04-25 23:07:37 UTC (rev 55998)
@@ -17,10 +17,10 @@
 
 @author Soeren Gebbert
 """
-from abstract_temporal_dataset import *
+from abstract_dataset import *
 from datetime_math import *
 
-class AbstractMapDataset(AbstractTemporalDataset):
+class AbstractMapDataset(AbstractDataset):
     """!This is the base class for all maps (raster, vector, raster3d).
     
         The temporal extent, the spatial extent and the metadata of maps
@@ -37,7 +37,7 @@
         - Abstract methods that must be implemented in the map specific subclasses
     """
     def __init__(self):
-        AbstractTemporalDataset.__init__(self)
+        AbstractDataset.__init__(self)
 
     def get_new_stds_instance(self, ident):
         """!Return a new space time dataset instance that store maps with the type of this map object (rast, rast3d or vect)

Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2013-04-25 23:07:37 UTC (rev 55998)
@@ -15,7 +15,7 @@
 import sys
 from abstract_dataset import *
 from temporal_granularity import *
-from temporal_relationships import *
+from spatio_temporal_relationships import *
 
 ###############################################################################
 
@@ -973,7 +973,7 @@
         dbif, connected = init_dbif(dbif)
         obj_list = self.get_registered_maps_as_objects(where, order, dbif)
 
-        tb = TemporalTopologyBuilder()
+        tb = SpatioTemporalTopologyBuilder()
         tb.build(obj_list)
     
         if connected:

Deleted: grass/trunk/lib/python/temporal/abstract_spatial_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_spatial_dataset.py	2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/abstract_spatial_dataset.py	2013-04-25 23:07:37 UTC (rev 55998)
@@ -1,370 +0,0 @@
-# -*- coding: utf-8 -*-
-"""!@package grass.temporal
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related functions to be used in temporal GIS Python library package.
-
-Usage:
-
->>> import grass.temporal as tgis
->>> tmr = tgis.AbstractSpatialDataset()
-
-(C) 2008-2011 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Soeren Gebbert
-"""
-from abstract_dataset import *
-from datetime_math import *
-
-
-class AbstractTemporalDataset(AbstractDataset):
-    """!This class implements a spatial topology access structure for an abstract dataset
-
-       This object will be set up by spatial topology creation method provided by the 
-       SpatialTopologyBuilder.
-
-       The following spatial relations with access methods are supported:
-       - equivalent
-       - overlap
-       - in
-       - contain
-       - meet
-       - cover
-       - covered
-            
-        Usage:
-        
-        @code
-        
-        >>> import grass.temporal as tgis
-        >>> tgis.init()
-        >>> map = tgis.RasterDataset("a at P")
-        >>> tmr = tgis.AbstractTemporalDataset()
-        >>> tmr.append_equivalent(map)
-        >>> tmr.append_overlap(map)
-        >>> tmr.append_in(map)
-        >>> tmr.append_contain(map)
-        >>> tmr.append_meet(map)
-        >>> tmr.append_cover(map)
-        >>> tmr.append_covered(map)
-        >>> tmr.print_topology_info()
-         +-------------------- Spatial Topology --------------------------------------+
-         | Equivalent: ................ a at P
-         | Cover: ..................... a at P
-         | Covered: ................... a at P
-         | Overlap: ................... a at P
-         | In: ........................ a at P
-         | Contain: ................... a at P
-         | Meet: ...................... a at P
-        >>> tmr.print_topology_shell_info()
-        equivalent=a at P
-        overlap=a at P
-        in=a at P
-        contain=a at P
-        meet=a at P
-        cover=a at P
-        covered=a at P
-        
-        @endcode
-    """
-
-    def __init__(self):
-        AbstractDataset.__init__(self)
-        self.reset_topology()
-
-    def reset_topology(self):
-        """!Reset any information about temporal topology"""
-        self._topology = {}
-        self._has_topology = False
-        
-    def get_number_of_relations(self):      
-        """! Return a dictionary in which the keys are the relation names and the value
-        are the number of relations.
-        
-        The following relations are available:
-       - equivalent
-       - overlap
-       - in
-       - contain
-       - meet
-       - cover
-       - covered
-        
-        To access topological information the spatial topology must be build first
-        using the SpatialTopologyBuilder.
-        
-        @return the dictionary with relations as keys and number as values or None in case the topology wasn't build
-        """
-        if self._has_topology == False:
-            return None
-    
-        relations = {}
-        try:
-            relations["equivalent"] = len(self._topology["EQUIVALENT"]) 
-        except:
-            relations["equivalent"] = 0
-        try: 
-            relations["overlap"] = len(self._topology["OVERLAP"]) 
-        except: 
-            relations["overlap"] = 0
-        try: 
-            relations["in"] = len(self._topology["IN"])
-        except: 
-            relations["in"] = 0
-        try: 
-            relations["contain"] = len(self._topology["CONTAIN"])
-        except: 
-            relations["contain"] = 0
-        try: 
-            relations["meet"] = len(self._topology["MEET"])
-        except: 
-            relations["meet"] = 0
-        try: 
-            relations["cover"] = len(self._topology["COVER"])
-        except: 
-            relations["cover"] = 0
-        try: 
-            relations["covered"] = len(self._topology["COVERED"])
-        except: 
-            relations["covered"] = 0
-            
-        return relations
-
-    def set_topology_build_true(self):
-        """!Same as name"""
-        self._has_topology = True
-
-    def set_topology_build_false(self):
-        """!Same as name"""
-        self._has_topology = False
-
-    def is_topology_build(self):
-        """!Check if the temporal topology was build"""
-        return self._has_topology
-
-    def append_equivalent(self, map):
-        """!Append a map with equivalent spatial extent as this map
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "EQUIVALENT" not in self._topology:
-            self._topology["EQUIVALENT"] = []
-        self._topology["EQUIVALENT"].append(map)
-
-    def get_equivalent(self):
-        """!Return a list of map objects with equivalent spatial extent as this map
-
-           @return A list of map objects or None
-        """
-        if "EQUIVALENT" not in self._topology:
-            return None
-        return self._topology["EQUIVALENT"]
-
-    def append_overlap(self, map):
-        """!Append a map that this spatial overlap with this map
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "OVERLAP" not in self._topology:
-            self._topology["OVERLAP"] = []
-        self._topology["OVERLAP"].append(map)
-
-    def get_overlap(self):
-        """!Return a list of map objects that this map spatial overlap with
-
-           @return A list of map objects or None
-        """
-        if "OVERLAP" not in self._topology:
-            return None
-        return self._topology["OVERLAP"]
-
-    def append_in(self, map):
-        """!Append a map that this is spatial in this map
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "IN" not in self._topology:
-            self._topology["IN"] = []
-        self._topology["IN"].append(map)
-
-    def get_in(self):
-        """!Return a list of map objects that are spatial in this map
-
-           @return A list of map objects or None
-        """
-        if "IN" not in self._topology:
-            return None
-        return self._topology["IN"]
-
-    def append_contain(self, map):
-        """!Append a map that this map spatially contains
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "CONTAIN" not in self._topology:
-            self._topology["CONTAIN"] = []
-        self._topology["CONTAIN"].append(map)
-
-    def get_contain(self):
-        """!Return a list of map objects that this map contains
-
-           @return A list of map objects or None
-        """
-        if "CONTAIN" not in self._topology:
-            return None
-        return self._topology["CONTAIN"]
-
-    def append_meet(self, map):
-        """!Append a map that spatially meet with this map
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "MEET" not in self._topology:
-            self._topology["MEET"] = []
-        self._topology["MEET"].append(map)
-
-    def get_meet(self):
-        """!Return a list of map objects that spatially meet with this map
-
-           @return A list of map objects or None
-        """
-        if "MEET" not in self._topology:
-            return None
-        return self._topology["MEET"]
-
-    def append_cover(self, map):
-        """!Append a map that spatially cover this map
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "COVER" not in self._topology:
-            self._topology["COVER"] = []
-        self._topology["COVER"].append(map)
-
-    def get_cover(self):
-        """!Return a list of map objects that spatially cover this map
-
-           @return A list of map objects or None
-        """
-        if "COVER" not in self._topology:
-            return None
-        return self._topology["COVER"]
-
-    def append_covered(self, map):
-        """!Append a map that is spatially covered by this map
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "COVERED" not in self._topology:
-            self._topology["COVERED"] = []
-        self._topology["COVERED"].append(map)
-
-    def get_covered(self):
-        """!Return a list of map objects that are spatially covered by this map
-
-           @return A list of map objects or None
-        """
-        if "COVERED" not in self._topology:
-            return None
-        return self._topology["COVERED"]
-
-
-    def _generate_map_list_string(self, map_list, line_wrap=True):
-        count = 0
-        string = ""
-        for map_ in map_list:
-            if line_wrap and count > 0 and count % 3 == 0:
-                string += "\n | ............................ "
-                count = 0
-            if count == 0:
-                string += map_.get_id()
-            else:
-                string += ",%s" % map_.get_id()
-            count += 1
-
-        return string
-    
-    # Set the properties
-    equivalent = property(fget=get_equivalent, 
-                                       fset=append_equivalent)
-    cover = property(fget=get_cover, 
-                                     fset=append_cover)
-    covered = property(fget=get_covered, 
-                                       fset=append_covered)
-    overlap = property(fget=get_overlap, 
-                                     fset=append_overlap)
-    in = property(fget=get_in, 
-                                     fset=append_in)
-    contain = property(fget=get_contain, 
-                                     fset=append_contain)
-    meet = property(fget=get_meet, 
-                                     fset=append_meet)
-
-    def print_topology_info(self):
-        """!Print information about this class in human readable style"""
-        
-        print " +-------------------- Spatial Topology --------------------------------------+"
-        #          0123456789012345678901234567890
-        if self.equivalent is not None:
-            print " | Equivalent: ................ " + \
-                self._generate_map_list_string(self.equivalent)
-        if self.cover is not None:
-            print " | Cover: ..................... " + \
-                self._generate_map_list_string(self.cover)
-        if self.covered is not None:
-            print " | Covered: ................... " + \
-                self._generate_map_list_string(self.covered)
-        if self.overlap is not None:
-            print " | Overlap: ................... " + \
-                self._generate_map_list_string(self.overlap)
-        if self.in is not None:
-            print " | In: ........................ " + \
-                self._generate_map_list_string(self.in)
-        if self.contain is not None:
-            print " | Contain: ................... " + \
-                self._generate_map_list_string(self.contain)
-        if self.meet is not None:
-            print " | Meet: ...................... " + \
-                self._generate_map_list_string(self.meet)
-
-    def print_topology_shell_info(self):
-        """!Print information about this class in shell style"""
-        
-        if self.next() is not None:
-        if self.equivalent is not None:
-            print "equivalent=" + self._generate_map_list_string(self.equivalent, False)
-        if self.cover is not None:
-            print "cover=" + self._generate_map_list_string(
-                self.cover, False)
-        if self.covered is not None:
-            print "covered=" + \
-                self._generate_map_list_string(self.covered, False)
-        if self.overlap is not None:
-            print "overlap=" + \
-                self._generate_map_list_string(self.overlap)
-        if self.in is not None:
-            print "in=" + \
-                self._generate_map_list_string(self.in)
-        if self.contain is not None:
-            print "contain=" + \
-                self._generate_map_list_string(self.contain)
-        if self.meet is not None:
-            print "meet=" + \
-                self._generate_map_list_string(self.meet)
-
-###############################################################################
-
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()
\ No newline at end of file

Deleted: grass/trunk/lib/python/temporal/abstract_temporal_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_temporal_dataset.py	2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/abstract_temporal_dataset.py	2013-04-25 23:07:37 UTC (rev 55998)
@@ -1,589 +0,0 @@
-# -*- coding: utf-8 -*-
-"""!@package grass.temporal
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related functions to be used in temporal GIS Python library package.
-
-Usage:
-
->>> import grass.temporal as tgis
->>> tmr = tgis.AbstractTemporalDataset()
-
-(C) 2008-2011 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Soeren Gebbert
-"""
-from abstract_dataset import *
-from datetime_math import *
-
-
-class AbstractTemporalDataset(AbstractDataset):
-    """!This class implements a temporal topology access structure for an abstract dataset
-
-       This object will be set up by temporal topology creation method provided by the 
-       TemporallyTopologyBuilder.
-
-       If correctly initialize the calls next() and prev() 
-       let the user walk temporally forward and backward in time.
-
-       The following temporal relations with access methods are supported:
-       - equal
-       - follows
-       - precedes
-       - overlaps
-       - overlapped
-       - during (including starts, finishes)
-       - contains (including started, finished)
-       - starts
-       - started
-       - finishes
-       - finished
-
-
-       @code:
-       # We have build the temporal topology and we know the first map
-       start = first
-       while start:
-
-           # Print all maps this map temporally contains
-           dlist = start.get_contains()
-           for map in dlist:
-               map.print_info()
-
-           start = start.next()
-         @endcode  
-        
-        Usage:
-        
-        @code
-        
-        >>> import grass.temporal as tgis
-        >>> tgis.init()
-        >>> map = tgis.RasterDataset("a at P")
-        >>> tmr = tgis.AbstractTemporalDataset()
-        >>> tmr.set_next(map)
-        >>> tmr.set_prev(map)
-        >>> tmr.append_equal(map)
-        >>> tmr.append_follows(map)
-        >>> tmr.append_precedes(map)
-        >>> tmr.append_overlapped(map)
-        >>> tmr.append_overlaps(map)
-        >>> tmr.append_during(map)
-        >>> tmr.append_contains(map)
-        >>> tmr.append_starts(map)
-        >>> tmr.append_started(map)
-        >>> tmr.append_finishes(map)
-        >>> tmr.append_finished(map)
-        >>> tmr.print_topology_info()
-         +-------------------- Temporal Topology -------------------------------------+
-         | Next: ...................... a at P
-         | Previous: .................. a at P
-         | Equal:...................... a at P
-         | Follows: ................... a at P
-         | Precedes: .................. a at P
-         | Overlaps: .................. a at P
-         | Overlapped: ................ a at P
-         | During: .................... a at P
-         | Contains: .................. a at P
-         | Starts:.. .................. a at P
-         | Started:. .................. a at P
-         | Finishes:................... a at P
-         | Finished:................... a at P
-        >>> tmr.print_topology_shell_info()
-        next=a at P
-        prev=a at P
-        equal=a at P
-        follows=a at P
-        precedes=a at P
-        overlaps=a at P
-        overlapped=a at P
-        during=a at P
-        contains=a at P
-        starts=a at P
-        started=a at P
-        finishes=a at P
-        finished=a at P
-        
-        @endcode
-    """
-
-    def __init__(self):
-        AbstractDataset.__init__(self)
-        self.reset_topology()
-
-    def reset_topology(self):
-        """!Reset any information about temporal topology"""
-        self._topology = {}
-        self._has_topology = False
-        
-    def get_number_of_relations(self):      
-        """! Return a dictionary in which the keys are the relation names and the value
-        are the number of relations.
-        
-        The following relations are available:
-        - equal
-        - follows
-        - precedes
-        - overlaps
-        - overlapped
-        - during (including starts, finishes)
-        - contains (including started, finished)
-        - starts
-        - started
-        - finishes
-        - finished
-        
-        To access topological information the temporal topology must be build first
-        using the TemporalTopologyBuilder.
-        
-        @return the dictionary with relations as keys and number as values or None in case the topology wasn't build
-        """
-        if self._has_topology == False:
-            return None
-    
-        relations = {}
-        try:
-            relations["equal"] = len(self._topology["EQUAL"]) 
-        except:
-            relations["equal"] = 0
-        try: 
-            relations["follows"] = len(self._topology["FOLLOWS"]) 
-        except: 
-            relations["follows"] = 0
-        try: 
-            relations["precedes"] = len(self._topology["PRECEDES"])
-        except: 
-            relations["precedes"] = 0
-        try: 
-            relations["overlaps"] = len(self._topology["OVERLAPS"])
-        except: 
-            relations["overlaps"] = 0
-        try: 
-            relations["overlapped"] = len(self._topology["OVERLAPPED"])
-        except: 
-            relations["overlapped"] = 0
-        try: 
-            relations["during"] = len(self._topology["DURING"])
-        except: 
-            relations["during"] = 0
-        try: 
-            relations["contains"] = len(self._topology["CONTAINS"])
-        except: 
-            relations["contains"] = 0
-        try: 
-            relations["starts"] = len(self._topology["STARTS"])
-        except: 
-            relations["starts"] = 0
-        try:    
-            relations["started"] = len(self._topology["STARTED"])
-        except: 
-            relations["started"] = 0
-        try: 
-            relations["finishes"] = len(self._topology["FINISHES"])
-        except: 
-            relations["finishes"] = 0
-        try: 
-            relations["finished"] = len(self._topology["FINISHED"])
-        except: 
-            relations["finished"] = 0
-            
-        return relations
-
-    def set_topology_build_true(self):
-        """!Same as name"""
-        self._has_topology = True
-
-    def set_topology_build_false(self):
-        """!Same as name"""
-        self._has_topology = False
-
-    def is_topology_build(self):
-        """!Check if the temporal topology was build"""
-        return self._has_topology
-
-    def set_next(self, map):
-        """!Set the map that is temporally as closest located after this map.
-
-           Temporally located means that the start time of the "next" map is
-           temporally located AFTER the start time of this map, but temporally
-           near than other maps of the same dataset.
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        self._topology["NEXT"] = map
-
-    def set_prev(self, map):
-        """!Set the map that is temporally as closest located before this map.
-
-           Temporally located means that the start time of the "previous" map is
-           temporally located BEFORE the start time of this map, but temporally
-           near than other maps of the same dataset.
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        self._topology["PREV"] = map
-
-    def next(self):
-        """!Return the map with a start time temporally located after
-           the start time of this map, but temporal closer than other maps
-
-           @return A map object or None
-        """
-        if "NEXT" not in self._topology:
-            return None
-        return self._topology["NEXT"]
-
-    def prev(self):
-        """!Return the map with a start time temporally located before
-           the start time of this map, but temporal closer than other maps
-
-           @return A map object or None
-        """
-        if "PREV" not in self._topology:
-            return None
-        return self._topology["PREV"]
-
-    def append_equal(self, map):
-        """!Append a map with equivalent temporal extent as this map
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "EQUAL" not in self._topology:
-            self._topology["EQUAL"] = []
-        self._topology["EQUAL"].append(map)
-
-    def get_equal(self):
-        """!Return a list of map objects with equivalent temporal extent as this map
-
-           @return A list of map objects or None
-        """
-        if "EQUAL" not in self._topology:
-            return None
-        return self._topology["EQUAL"]
-
-    def append_starts(self, map):
-        """!Append a map that this map temporally starts with
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "STARTS" not in self._topology:
-            self._topology["STARTS"] = []
-        self._topology["STARTS"].append(map)
-
-    def get_starts(self):
-        """!Return a list of map objects that this map temporally starts with
-
-           @return A list of map objects or None
-        """
-        if "STARTS" not in self._topology:
-            return None
-        return self._topology["STARTS"]
-
-    def append_started(self, map):
-        """!Append a map that this map temporally started with
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "STARTED" not in self._topology:
-            self._topology["STARTED"] = []
-        self._topology["STARTED"].append(map)
-
-    def get_started(self):
-        """!Return a list of map objects that this map temporally started with
-
-           @return A list of map objects or None
-        """
-        if "STARTED" not in self._topology:
-            return None
-        return self._topology["STARTED"]
-
-    def append_finishes(self, map):
-        """!Append a map that this map temporally finishes with
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "FINISHES" not in self._topology:
-            self._topology["FINISHES"] = []
-        self._topology["FINISHES"].append(map)
-
-    def get_finishes(self):
-        """!Return a list of map objects that this map temporally finishes with
-
-           @return A list of map objects or None
-        """
-        if "FINISHES" not in self._topology:
-            return None
-        return self._topology["FINISHES"]
-
-    def append_finished(self, map):
-        """!Append a map that this map temporally finished with
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "FINISHED" not in self._topology:
-            self._topology["FINISHED"] = []
-        self._topology["FINISHED"].append(map)
-
-    def get_finished(self):
-        """!Return a list of map objects that this map temporally finished with
-
-           @return A list of map objects or None
-        """
-        if "FINISHED" not in self._topology:
-            return None
-        return self._topology["FINISHED"]
-
-    def append_overlaps(self, map):
-        """!Append a map that this map temporally overlaps
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "OVERLAPS" not in self._topology:
-            self._topology["OVERLAPS"] = []
-        self._topology["OVERLAPS"].append(map)
-
-    def get_overlaps(self):
-        """!Return a list of map objects that this map temporally overlaps
-
-           @return A list of map objects or None
-        """
-        if "OVERLAPS" not in self._topology:
-            return None
-        return self._topology["OVERLAPS"]
-
-    def append_overlapped(self, map):
-        """!Append a map that this map temporally overlapped
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "OVERLAPPED" not in self._topology:
-            self._topology["OVERLAPPED"] = []
-        self._topology["OVERLAPPED"].append(map)
-
-    def get_overlapped(self):
-        """!Return a list of map objects that this map temporally overlapped
-
-           @return A list of map objects or None
-        """
-        if "OVERLAPPED" not in self._topology:
-            return None
-        return self._topology["OVERLAPPED"]
-
-    def append_follows(self, map):
-        """!Append a map that this map temporally follows
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "FOLLOWS" not in self._topology:
-            self._topology["FOLLOWS"] = []
-        self._topology["FOLLOWS"].append(map)
-
-    def get_follows(self):
-        """!Return a list of map objects that this map temporally follows
-
-           @return A list of map objects or None
-        """
-        if "FOLLOWS" not in self._topology:
-            return None
-        return self._topology["FOLLOWS"]
-
-    def append_precedes(self, map):
-        """!Append a map that this map temporally precedes
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "PRECEDES" not in self._topology:
-            self._topology["PRECEDES"] = []
-        self._topology["PRECEDES"].append(map)
-
-    def get_precedes(self):
-        """!Return a list of map objects that this map temporally precedes
-
-           @return A list of map objects or None
-        """
-        if "PRECEDES" not in self._topology:
-            return None
-        return self._topology["PRECEDES"]
-
-    def append_during(self, map):
-        """!Append a map that this map is temporally located during
-           This includes temporal relationships starts and finishes
-
-           @param map This object should be of type 
-                        AbstractMapDataset or derived classes
-        """
-        if "DURING" not in self._topology:
-            self._topology["DURING"] = []
-        self._topology["DURING"].append(map)
-
-    def get_during(self):
-        """!Return a list of map objects that this map is temporally located during
-           This includes temporally relationships starts and finishes
-
-           @return A list of map objects or None
-        """
-        if "DURING" not in self._topology:
-            return None
-        return self._topology["DURING"]
-
-    def append_contains(self, map):
-        """!Append a map that this map temporally contains
-           This includes temporal relationships started and finished
-
-           @param map This object should be of type AbstractMapDataset 
-                        or derived classes
-        """
-        if "CONTAINS" not in self._topology:
-            self._topology["CONTAINS"] = []
-        self._topology["CONTAINS"].append(map)
-
-    def get_contains(self):
-        """!Return a list of map objects that this map temporally contains
-           This includes temporal relationships started and finished
-
-           @return A list of map objects or None
-        """
-        if "CONTAINS" not in self._topology:
-            return None
-        return self._topology["CONTAINS"]
-
-    def _generate_map_list_string(self, map_list, line_wrap=True):
-        count = 0
-        string = ""
-        for map_ in map_list:
-            if line_wrap and count > 0 and count % 3 == 0:
-                string += "\n | ............................ "
-                count = 0
-            if count == 0:
-                string += map_.get_id()
-            else:
-                string += ",%s" % map_.get_id()
-            count += 1
-
-        return string
-    
-    # Set the properties
-    equal = property(fget=get_equal, 
-                                       fset=append_equal)
-    follows = property(fget=get_follows, 
-                                    fset=append_follows)
-    precedes = property(fget=get_precedes, 
-                                     fset=append_precedes)
-    overlaps = property(fget=get_overlaps, 
-                                     fset=append_overlaps)
-    overlapped = property(fget=get_overlapped, 
-                                       fset=append_overlapped)
-    during = property(fget=get_during, 
-                                   fset=append_during)
-    contains = property(fget=get_contains, 
-                                     fset=append_contains)
-    starts = property(fget=get_starts, 
-                                     fset=append_starts)
-    started = property(fget=get_started, 
-                                     fset=append_started)
-    finishes = property(fget=get_finishes, 
-                                     fset=append_finishes)
-    finished = property(fget=get_finished, 
-                                     fset=append_finished)
-
-    def print_topology_info(self):
-        """!Print information about this class in human readable style"""
-        
-        print " +-------------------- Temporal Topology -------------------------------------+"
-        #          0123456789012345678901234567890
-        if self.next() is not None:
-            print " | Next: ...................... " + str(self.next().get_id())
-        if self.prev() is not None:
-            print " | Previous: .................. " + str(self.prev().get_id())
-        if self.equal is not None:
-            print " | Equal:...................... " + \
-                self._generate_map_list_string(self.equal)
-        if self.follows is not None:
-            print " | Follows: ................... " + \
-                self._generate_map_list_string(self.follows)
-        if self.precedes is not None:
-            print " | Precedes: .................. " + \
-                self._generate_map_list_string(self.precedes)
-        if self.overlaps is not None:
-            print " | Overlaps: .................. " + \
-                self._generate_map_list_string(self.overlaps)
-        if self.overlapped is not None:
-            print " | Overlapped: ................ " + \
-                self._generate_map_list_string(self.overlapped)
-        if self.during is not None:
-            print " | During: .................... " + \
-                self._generate_map_list_string(self.during)
-        if self.contains is not None:
-            print " | Contains: .................. " + \
-                self._generate_map_list_string(self.contains)
-        if self.starts is not None:
-            print " | Starts:.. .................. " + \
-                self._generate_map_list_string(self.starts)
-        if self.started is not None:
-            print " | Started:. .................. " + \
-                self._generate_map_list_string(self.started)
-        if self.finishes is not None:
-            print " | Finishes:................... " + \
-                self._generate_map_list_string(self.finishes)
-        if self.finished is not None:
-            print " | Finished:................... " + \
-                self._generate_map_list_string(self.finished)
-
-    def print_topology_shell_info(self):
-        """!Print information about this class in shell style"""
-        
-        if self.next() is not None:
-            print "next=" + self.next().get_id()
-        if self.prev() is not None:
-            print "prev=" + self.prev().get_id()
-        if self.equal is not None:
-            print "equal=" + self._generate_map_list_string(self.equal, False)
-        if self.follows is not None:
-            print "follows=" + self._generate_map_list_string(self.follows, False)
-        if self.precedes is not None:
-            print "precedes=" + self._generate_map_list_string(
-                self.precedes, False)
-        if self.overlaps is not None:
-            print "overlaps=" + self._generate_map_list_string(
-                self.overlaps, False)
-        if self.overlapped is not None:
-            print "overlapped=" + \
-                self._generate_map_list_string(self.overlapped, False)
-        if self.during is not None:
-            print "during=" + self._generate_map_list_string(self.during, False)
-        if self.contains is not None:
-            print "contains=" + self._generate_map_list_string(
-                self.contains, False)
-        if self.starts is not None:
-            print "starts=" + \
-                self._generate_map_list_string(self.starts)
-        if self.started is not None:
-            print "started=" + \
-                self._generate_map_list_string(self.started)
-        if self.finishes is not None:
-            print "finishes=" + \
-                self._generate_map_list_string(self.finishes)
-        if self.finished is not None:
-            print "finished=" + \
-                self._generate_map_list_string(self.finished)
-
-###############################################################################
-
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()
\ No newline at end of file

Modified: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py	2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py	2013-04-25 23:07:37 UTC (rev 55998)
@@ -28,6 +28,7 @@
 import grass.lib.raster3d as libraster3d
 import grass.script as grass
 
+from abstract_map_dataset import *
 from abstract_space_time_dataset import *
 
 ###############################################################################
@@ -57,6 +58,7 @@
         >>> rmap = RasterDataset(identifier)
         >>> rmap.set_absolute_time(start_time=datetime(2001,1,1), 
         ...                        end_time=datetime(2012,1,1))
+        True
         >>> rmap.map_exists()
         True
         >>> rmap.load()

Copied: grass/trunk/lib/python/temporal/spatial_topology_dataset_connector.py (from rev 55991, grass/trunk/lib/python/temporal/abstract_spatial_dataset.py)
===================================================================
--- grass/trunk/lib/python/temporal/spatial_topology_dataset_connector.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/spatial_topology_dataset_connector.py	2013-04-25 23:07:37 UTC (rev 55998)
@@ -0,0 +1,365 @@
+# -*- coding: utf-8 -*-
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in temporal GIS Python library package.
+
+Usage:
+
+>>> import grass.temporal as tgis
+>>> tmr = tgis.SpatialTopologyDatasetConnector()
+
+(C) 2008-2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+
+class SpatialTopologyDatasetConnector(object):
+    """!This class implements a spatial topology access structure to connect spatial related datasets
+
+       This object will be set up by spatial topology creation method provided by the 
+       SpatioTemporalTopologyBuilder.
+
+       The following spatial relations with access methods are supported:
+       - equivalent
+       - overlap
+       - in
+       - contain
+       - meet
+       - cover
+       - covered
+            
+        Usage:
+        
+        @code
+        
+        >>> import grass.temporal as tgis
+        >>> tgis.init()
+        >>> map = tgis.RasterDataset("a at P")
+        >>> tmr = tgis.SpatialTopologyDatasetConnector()
+        >>> tmr.append_equivalent(map)
+        >>> tmr.append_overlap(map)
+        >>> tmr.append_in(map)
+        >>> tmr.append_contain(map)
+        >>> tmr.append_meet(map)
+        >>> tmr.append_cover(map)
+        >>> tmr.append_covered(map)
+        >>> tmr.print_spatial_topology_info()
+         +-------------------- Spatial Topology --------------------------------------+
+         | Equivalent: ................ a at P
+         | Cover: ..................... a at P
+         | Covered: ................... a at P
+         | Overlap: ................... a at P
+         | In: ........................ a at P
+         | Contain: ................... a at P
+         | Meet: ...................... a at P
+        >>> tmr.print_spatial_topology_shell_info()
+        equivalent=a at P
+        cover=a at P
+        covered=a at P
+        overlap=a at P
+        in=a at P
+        contain=a at P
+        meet=a at P
+        
+        @endcode
+    """
+
+    def __init__(self):
+        self.reset_spatial_topology()
+
+    def reset_spatial_topology(self):
+        """!Reset any information about temporal topology"""
+        self._spatial_topology = {}
+        self._has_spatial_topology = False
+        
+    def get_number_of_spatial_relations(self):
+        """! Return a dictionary in which the keys are the relation names and the value
+        are the number of relations.
+        
+        The following relations are available:
+       - equivalent
+       - overlap
+       - in
+       - contain
+       - meet
+       - cover
+       - covered
+        
+        To access topological information the spatial topology must be build first
+        using the SpatialTopologyBuilder.
+        
+        @return the dictionary with relations as keys and number as values or None in case the topology wasn't build
+        """
+        if self._has_spatial_topology == False:
+            return None
+    
+        relations = {}
+        try:
+            relations["equivalent"] = len(self._spatial_topology["EQUIVALENT"]) 
+        except:
+            relations["equivalent"] = 0
+        try: 
+            relations["overlap"] = len(self._spatial_topology["OVERLAP"]) 
+        except: 
+            relations["overlap"] = 0
+        try: 
+            relations["in"] = len(self._spatial_topology["IN"])
+        except: 
+            relations["in"] = 0
+        try: 
+            relations["contain"] = len(self._spatial_topology["CONTAIN"])
+        except: 
+            relations["contain"] = 0
+        try: 
+            relations["meet"] = len(self._spatial_topology["MEET"])
+        except: 
+            relations["meet"] = 0
+        try: 
+            relations["cover"] = len(self._spatial_topology["COVER"])
+        except: 
+            relations["cover"] = 0
+        try: 
+            relations["covered"] = len(self._spatial_topology["COVERED"])
+        except: 
+            relations["covered"] = 0
+            
+        return relations
+
+    def set_spatial_topology_build_true(self):
+        """!Same as name"""
+        self._has_spatial_topology = True
+
+    def set_spatial_topology_build_false(self):
+        """!Same as name"""
+        self._has_spatial_topology = False
+
+    def is_spatial_topology_build(self):
+        """!Check if the temporal topology was build"""
+        return self._has_spatial_topology
+
+    def append_equivalent(self, map):
+        """!Append a map with equivalent spatial extent as this map
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "EQUIVALENT" not in self._spatial_topology:
+            self._spatial_topology["EQUIVALENT"] = []
+        self._spatial_topology["EQUIVALENT"].append(map)
+
+    def get_equivalent(self):
+        """!Return a list of map objects with equivalent spatial extent as this map
+
+           @return A list of map objects or None
+        """
+        if "EQUIVALENT" not in self._spatial_topology:
+            return None
+        return self._spatial_topology["EQUIVALENT"]
+
+    def append_overlap(self, map):
+        """!Append a map that this spatial overlap with this map
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "OVERLAP" not in self._spatial_topology:
+            self._spatial_topology["OVERLAP"] = []
+        self._spatial_topology["OVERLAP"].append(map)
+
+    def get_overlap(self):
+        """!Return a list of map objects that this map spatial overlap with
+
+           @return A list of map objects or None
+        """
+        if "OVERLAP" not in self._spatial_topology:
+            return None
+        return self._spatial_topology["OVERLAP"]
+
+    def append_in(self, map):
+        """!Append a map that this is spatial in this map
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "IN" not in self._spatial_topology:
+            self._spatial_topology["IN"] = []
+        self._spatial_topology["IN"].append(map)
+
+    def get_in(self):
+        """!Return a list of map objects that are spatial in this map
+
+           @return A list of map objects or None
+        """
+        if "IN" not in self._spatial_topology:
+            return None
+        return self._spatial_topology["IN"]
+
+    def append_contain(self, map):
+        """!Append a map that this map spatially contains
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "CONTAIN" not in self._spatial_topology:
+            self._spatial_topology["CONTAIN"] = []
+        self._spatial_topology["CONTAIN"].append(map)
+
+    def get_contain(self):
+        """!Return a list of map objects that this map contains
+
+           @return A list of map objects or None
+        """
+        if "CONTAIN" not in self._spatial_topology:
+            return None
+        return self._spatial_topology["CONTAIN"]
+
+    def append_meet(self, map):
+        """!Append a map that spatially meet with this map
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "MEET" not in self._spatial_topology:
+            self._spatial_topology["MEET"] = []
+        self._spatial_topology["MEET"].append(map)
+
+    def get_meet(self):
+        """!Return a list of map objects that spatially meet with this map
+
+           @return A list of map objects or None
+        """
+        if "MEET" not in self._spatial_topology:
+            return None
+        return self._spatial_topology["MEET"]
+
+    def append_cover(self, map):
+        """!Append a map that spatially cover this map
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "COVER" not in self._spatial_topology:
+            self._spatial_topology["COVER"] = []
+        self._spatial_topology["COVER"].append(map)
+
+    def get_cover(self):
+        """!Return a list of map objects that spatially cover this map
+
+           @return A list of map objects or None
+        """
+        if "COVER" not in self._spatial_topology:
+            return None
+        return self._spatial_topology["COVER"]
+
+    def append_covered(self, map):
+        """!Append a map that is spatially covered by this map
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "COVERED" not in self._spatial_topology:
+            self._spatial_topology["COVERED"] = []
+        self._spatial_topology["COVERED"].append(map)
+
+    def get_covered(self):
+        """!Return a list of map objects that are spatially covered by this map
+
+           @return A list of map objects or None
+        """
+        if "COVERED" not in self._spatial_topology:
+            return None
+        return self._spatial_topology["COVERED"]
+
+
+    def _generate_map_list_string(self, map_list, line_wrap=True):
+        count = 0
+        string = ""
+        for map_ in map_list:
+            if line_wrap and count > 0 and count % 3 == 0:
+                string += "\n | ............................ "
+                count = 0
+            if count == 0:
+                string += map_.get_id()
+            else:
+                string += ",%s" % map_.get_id()
+            count += 1
+
+        return string
+    
+    # Set the properties
+    equivalent = property(fget=get_equivalent, 
+                                       fset=append_equivalent)
+    cover = property(fget=get_cover, 
+                                     fset=append_cover)
+    covered = property(fget=get_covered, 
+                                       fset=append_covered)
+    overlap = property(fget=get_overlap, 
+                                     fset=append_overlap)
+    in_ = property(fget=get_in, 
+                                     fset=append_in)
+    contain = property(fget=get_contain, 
+                                     fset=append_contain)
+    meet = property(fget=get_meet, 
+                                     fset=append_meet)
+
+    def print_spatial_topology_info(self):
+        """!Print information about this class in human readable style"""
+        
+        print " +-------------------- Spatial Topology --------------------------------------+"
+        #          0123456789012345678901234567890
+        if self.equivalent is not None:
+            print " | Equivalent: ................ " + \
+                self._generate_map_list_string(self.equivalent)
+        if self.cover is not None:
+            print " | Cover: ..................... " + \
+                self._generate_map_list_string(self.cover)
+        if self.covered is not None:
+            print " | Covered: ................... " + \
+                self._generate_map_list_string(self.covered)
+        if self.overlap is not None:
+            print " | Overlap: ................... " + \
+                self._generate_map_list_string(self.overlap)
+        if self.in_ is not None:
+            print " | In: ........................ " + \
+                self._generate_map_list_string(self.in_)
+        if self.contain is not None:
+            print " | Contain: ................... " + \
+                self._generate_map_list_string(self.contain)
+        if self.meet is not None:
+            print " | Meet: ...................... " + \
+                self._generate_map_list_string(self.meet)
+
+    def print_spatial_topology_shell_info(self):
+        """!Print information about this class in shell style"""
+
+        if self.equivalent is not None:
+            print "equivalent=" + self._generate_map_list_string(self.equivalent, False)
+        if self.cover is not None:
+            print "cover=" + self._generate_map_list_string(
+                self.cover, False)
+        if self.covered is not None:
+            print "covered=" + \
+                self._generate_map_list_string(self.covered, False)
+        if self.overlap is not None:
+            print "overlap=" + \
+                self._generate_map_list_string(self.overlap)
+        if self.in_ is not None:
+            print "in=" + \
+                self._generate_map_list_string(self.in_)
+        if self.contain is not None:
+            print "contain=" + \
+                self._generate_map_list_string(self.contain)
+        if self.meet is not None:
+            print "meet=" + \
+                self._generate_map_list_string(self.meet)
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
\ No newline at end of file

Copied: grass/trunk/lib/python/temporal/spatio_temporal_relationships.py (from rev 55991, grass/trunk/lib/python/temporal/temporal_relationships.py)
===================================================================
--- grass/trunk/lib/python/temporal/spatio_temporal_relationships.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/spatio_temporal_relationships.py	2013-04-25 23:07:37 UTC (rev 55998)
@@ -0,0 +1,760 @@
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in temporal GIS Python library package.
+
+Usage:
+
+ at code
+import grass.temporal as tgis
+
+tgis.print_temporal_relations(maps)
+...
+ at endcode
+
+(C) 2008-2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+from abstract_dataset import *
+from datetime_math import *
+import grass.lib.vector as vector
+import grass.lib.gis as gis
+from ctypes import *
+
+###############################################################################
+
+class SpatioTemporalTopologyBuilder(object):
+    """!This class is designed to build the spatio-temporal topology 
+       of spatio-temporally related abstract dataset objects.
+       
+       The abstract dataset objects must be provided as a single list, or in two lists.
+
+        Example:
+        @code
+        # We have a space time raster dataset and build a map list
+        # from all registered maps ordered by start time
+        maps = strds.get_registered_maps_as_objects()
+
+        # Now lets build the temporal topology of the maps in the list
+        
+        tb = SpatioTemporalTopologyBuilder()
+        
+        tb.build(maps)
+
+        dbif, connected = init_dbif(None)
+            
+        for _map in tb:
+            _map.select(dbif)
+            _map.print_info()
+
+        # Using the next and previous methods, we can iterate over the
+        # topological related maps in this way
+
+        _first = tb.get_first()
+
+        while _first:
+            _first.print_topology_info()
+            _first = _first.next()
+
+        # Dictionary like accessed
+        _map = tb["name at mapset"]
+        @endcode
+
+    """
+    def __init__(self):
+        self._reset()
+        # 0001-01-01 00:00:00
+        self._timeref = datetime(1,1,1)
+
+    def _reset(self):
+        self._store = {}
+        self._first = None
+        self._iteratable = False
+
+    def _set_first(self, first):
+        self._first = first
+        self._insert(first)
+
+    def _detect_first(self):
+        if len(self) > 0:
+            prev_ = self._store.values()[0]
+            while prev_ is not None:
+                self._first = prev_
+                prev_ = prev_.prev()
+
+    def _insert(self, t):
+        self._store[t.get_id()] = t
+
+    def get_first(self):
+        """!Return the first map with the earliest start time
+
+           @return The map with the earliest start time
+        """
+        return self._first
+
+    def _build_internal_iteratable(self, maps):
+        """!Build an iteratable temporal topology structure for all maps in 
+           the list and store the maps internally
+
+           Basically the "next" and "prev" relations will be set in the 
+           temporal topology structure of each map
+           The maps will be added to the object, so they can be 
+           accessed using the iterator of this class
+
+           @param maps A sorted (by start_time)list of abstract_dataset 
+                        objects with initiated temporal extent
+        """
+        self._build_iteratable(maps)
+
+        for _map in maps:
+            self._insert(_map)
+
+        # Detect the first map
+        self._detect_first()
+
+    def _build_iteratable(self, maps):
+        """!Build an iteratable temporal topology structure for 
+           all maps in the list
+
+           Basically the "next" and "prev" relations will be set in 
+           the temporal topology structure of each map.
+
+           @param maps A sorted (by start_time)list of abstract_dataset 
+                        objects with initiated temporal extent
+        """
+#        for i in xrange(len(maps)):
+#            offset = i + 1
+#            for j in xrange(offset, len(maps)):
+#                # Get the temporal relationship
+#                relation = maps[j].temporal_relation(maps[i])
+#
+#                # Build the next reference
+#                if relation != "equal" and relation != "started":
+#                    maps[i].set_next(maps[j])
+#                    break
+
+        # First we need to order the map list chronologically 
+        sorted_maps = sorted(
+            maps, key=AbstractDatasetComparisonKeyStartTime)
+            
+        for i in xrange(len(sorted_maps) - 1):
+            sorted_maps[i].set_next(sorted_maps[i + 1])
+
+        for map_ in sorted_maps:
+            next_ = map_.next()
+            if next_:
+                next_.set_prev(map_)
+            map_.set_temporal_topology_build_true()
+        
+    def _map_to_rect(self, tree, map_, spatial=None):
+        """Use the temporal extent of a map to create and return a RTree rectange
+        
+        
+           @param spatial This indicates if the spatial topology is created as well:
+                          spatial can be None (no spatial topology), "2D" using west, east, 
+                          #south, north or "3D" using west, east, south, north, bottom, top
+        """
+        rect = vector.RTreeAllocRect(tree)
+        
+        start, end = map_.get_valid_time()
+        
+        if not end:
+            end = start
+        
+        if map_.is_time_absolute():
+            start = time_delta_to_relative_time(start - self._timeref)
+            end = time_delta_to_relative_time(end - self._timeref)
+        
+        if spatial is None:
+            vector.RTreeSetRect1D(rect, tree, float(start), float(end))
+        elif spatial == "2D":
+            north, south, east, west, top, bottom = map_.get_spatial_extent()
+            vector.RTreeSetRect3D(rect, tree, west, east, south, north, 
+                                  float(start), float(end))
+        elif spatial == "3D":
+            north, south, east, west, top, bottom = map_.get_spatial_extent()
+            vector.RTreeSetRect4D(rect, tree, west, east, south, north, 
+                                  bottom, top, float(start), float(end))
+        
+        return rect
+        
+    def _build_rtree(self, maps, spatial=None):
+        """Build and return the 1-4 dimensional R*-Tree
+        
+        
+           @param spatial This indicates if the spatial topology is created as well:
+                          spatial can be None (no spatial topology), "2D" using west, east, 
+                          south, north or "3D" using west, east, south, north, bottom, top
+        """
+        dim = 1
+        if spatial == "2D":
+            dim = 3
+        if spatial == "3D":
+            dim = 4
+        tree = vector.RTreeCreateTree(-1, 0, dim)
+
+        for i in xrange(len(maps)):
+            
+            rect = self._map_to_rect(tree, maps[i], spatial)
+            vector.RTreeInsertRect(rect, i + 1, tree)
+            
+        return tree
+
+    def build(self, mapsA, mapsB=None, spatial=None):
+        """!Build the spatio-temporal topology structure between 
+           one or two unordered lists of abstract dataset objects
+
+           This method builds the temporal or spatio-temporal topology from mapsA to 
+           mapsB and vice verse. The spatio-temporal topology structure of each map
+           will be reseted and rebuild for mapsA and mapsB.
+
+           After building the temporal or spatio-temporal topology the modified 
+           map objects of mapsA can be accessed
+           in the same way as a dictionary using there id. 
+           The implemented iterator assures
+           the chronological iteration over the mapsA.
+
+           @param mapsA A list of abstract_dataset 
+                         objects with initiated temporal extent
+           @param mapsB An optional list of abstract_dataset 
+                         objects with initiated temporal extent
+           @param spatial This indicates if the spatial topology is created as well:
+                          spatial can be None (no spatial topology), "2D" using west, east, 
+                          south, north or "3D" using west, east, south, north, bottom, top
+        """
+        
+        if spatial is not None:
+            dbif, connected = init_dbif(None)
+
+        identical = False
+        if mapsA == mapsB:
+            identical = True
+            
+        if mapsB == None:
+            mapsB = mapsA
+            idetnical = True
+
+        for map_ in mapsA:
+            map_.reset_topology()
+            # Spatial extent from the database
+            if spatial is not None:
+                map_.select(dbif)
+
+        if not identical:
+            for map_ in mapsB:
+                map_.reset_topology()
+                # Spatial extent from the database
+                if spatial is not None:
+                    map_.select(dbif)
+
+        tree = self. _build_rtree(mapsA, spatial)
+            
+        for j in xrange(len(mapsB)):            
+        
+            list_ = gis.ilist()
+            rect = self._map_to_rect(tree, mapsB[j], spatial)
+            num = vector.RTreeSearch2(tree, rect, byref(list_))
+            vector.RTreeFreeRect(rect)
+
+            for k in xrange(list_.n_values):
+                i = list_.value[k] - 1
+
+                # Get the temporal relationship
+                relation = mapsB[j].temporal_relation(mapsA[i])
+                
+                A = mapsA[i]
+                B = mapsB[j]
+                set_temoral_relationship(A, B, relation)
+                
+                if spatial is not None:
+                    relation = mapsB[j].spatial_relation(mapsA[i])
+                    set_spatial_relationship(A, B, relation)
+
+        self._build_internal_iteratable(mapsA)
+        if not identical and mapsB != None:
+            self._build_iteratable(mapsB)
+        
+        vector.RTreeDestroyTree(tree)
+        
+        if spatial is not None:
+            if connected:
+                dbif.close()
+
+    def __iter__(self):
+        start_ = self._first
+        while start_ is not None:
+            yield start_
+            start_ = start_.next()
+
+    def __getitem__(self, index):
+        return self._store[index.get_id()]
+
+    def __len__(self):
+        return len(self._store)
+
+    def __contains__(self, _map):
+        return _map in self._store.values()
+
+###############################################################################
+
+def set_temoral_relationship(A, B, relation):
+    if relation == "equal":
+        if B != A:
+            if not B.get_equal() or \
+            (B.get_equal() and \
+            A not in B.get_equal()):
+                B.append_equal(A)
+            if not A.get_equal() or \
+            (A.get_equal() and \
+            B not in A.get_equal()):
+                A.append_equal(B)
+    elif relation == "follows":
+        if not B.get_follows() or \
+            (B.get_follows() and \
+            A not in B.get_follows()):
+            B.append_follows(A)
+        if not A.get_precedes() or \
+            (A.get_precedes() and
+            B not in A.get_precedes()):
+            A.append_precedes(B)
+    elif relation == "precedes":
+        if not B.get_precedes() or \
+            (B.get_precedes() and \
+            A not in B.get_precedes()):
+            B.append_precedes(A)
+        if not A.get_follows() or \
+            (A.get_follows() and \
+            B not in A.get_follows()):
+            A.append_follows(B)
+    elif relation == "during" or relation == "starts" or \
+            relation == "finishes":
+        if not B.get_during() or \
+            (B.get_during() and \
+            A not in B.get_during()):
+            B.append_during(A)
+        if not A.get_contains() or \
+            (A.get_contains() and \
+            B not in A.get_contains()):
+            A.append_contains(B)
+        if relation == "starts":
+            if not B.get_starts() or \
+            (B.get_starts() and \
+            A not in B.get_starts()):
+                B.append_starts(A)
+            if not A.get_started() or \
+            (A.get_started() and \
+            B not in A.get_started()):
+                A.append_started(B)
+        if relation == "finishes":
+            if not B.get_finishes() or \
+            (B.get_finishes() and \
+            A not in B.get_finishes()):
+                B.append_finishes(A)
+            if not A.get_finished() or \
+            (A.get_finished() and \
+            B not in A.get_finished()):
+                A.append_finished(B)
+    elif relation == "contains" or relation == "started" or \
+            relation == "finished":
+        if not B.get_contains() or \
+            (B.get_contains() and \
+            A not in B.get_contains()):
+            B.append_contains(A)
+        if not A.get_during() or \
+            (A.get_during() and \
+            B not in A.get_during()):
+            A.append_during(B)
+        if relation == "started":
+            if not B.get_started() or \
+            (B.get_started() and \
+            A not in B.get_started()):
+                B.append_started(A)
+            if not A.get_starts() or \
+            (A.get_starts() and \
+            B not in A.get_starts()):
+                A.append_starts(B)
+        if relation == "finished":
+            if not B.get_finished() or \
+            (B.get_finished() and \
+            A not in B.get_finished()):
+                B.append_finished(A)
+            if not A.get_finishes() or \
+            (A.get_finishes() and \
+            B not in A.get_finishes()):
+                A.append_finishes(B)
+    elif relation == "overlaps":
+        if not B.get_overlaps() or \
+            (B.get_overlaps() and \
+            A not in B.get_overlaps()):
+            B.append_overlaps(A)
+        if not A.get_overlapped() or \
+            (A.get_overlapped() and \
+            B not in A.get_overlapped()):
+            A.append_overlapped(B)
+    elif relation == "overlapped":
+        if not B.get_overlapped() or \
+            (B.get_overlapped() and \
+            A not in B.get_overlapped()):
+            B.append_overlapped(A)
+        if not A.get_overlaps() or \
+            (A.get_overlaps() and \
+            B not in A.get_overlaps()):
+            A.append_overlaps(B)
+
+###############################################################################
+       
+def set_spatial_relationship(A, B, relation):
+    if relation == "equivalent":
+        if B != A:
+            if not B.get_equivalent() or \
+            (B.get_equivalent() and \
+            A not in B.get_equivalent()):
+                B.append_equivalent(A)
+            if not A.get_equivalent() or \
+            (A.get_equivalent() and \
+            B not in A.get_equivalent()):
+                A.append_equivalent(B)
+    elif relation == "overlap":
+        if not B.get_overlap() or \
+            (B.get_overlap() and \
+            A not in B.get_overlap()):
+            B.append_overlap(A)
+        if not A.get_overlap() or \
+            (A.get_overlap() and
+            B not in A.get_overlap()):
+            A.append_overlap(B)
+    elif relation == "meet":
+        if not B.get_meet() or \
+            (B.get_meet() and \
+            A not in B.get_meet()):
+            B.append_meet(A)
+        if not A.get_meet() or \
+            (A.get_meet() and
+            B not in A.get_meet()):
+            A.append_meet(B)
+    elif relation == "contain":
+        if not B.get_contain() or \
+            (B.get_contain() and \
+            A not in B.get_contain()):
+            B.append_contain(A)
+        if not A.get_in() or \
+            (A.get_in() and \
+            B not in A.get_in()):
+            A.append_in(B)
+    elif relation == "in":
+        if not B.get_in() or \
+            (B.get_in() and \
+            A not in B.get_in()):
+            B.append_in(A)
+        if not A.get_contain() or \
+            (A.get_contain() and \
+            B not in A.get_contain()):
+            A.append_contain(B)
+    elif relation == "cover":
+        if not B.get_cover() or \
+            (B.get_cover() and \
+            A not in B.get_cover()):
+            B.append_cover(A)
+        if not A.get_covered() or \
+            (A.get_covered() and \
+            B not in A.get_covered()):
+            A.append_covered(B)
+    elif relation == "covered":
+        if not B.get_covered() or \
+            (B.get_covered() and \
+            A not in B.get_covered()):
+            B.append_covered(A)
+        if not A.get_cover() or \
+            (A.get_cover() and \
+            B not in A.get_cover()):
+            A.append_cover(B)
+
+###############################################################################
+
+def print_temporal_topology_relationships(maps1, maps2=None, dbif=None):
+    """!Print the temporal relationships of the 
+       map lists maps1 and maps2 to stdout.
+
+        @param maps1 A list of abstract_dataset 
+                      objects with initiated temporal extent
+        @param maps2 An optional list of abstract_dataset 
+                      objects with initiated temporal extent
+        @param dbif The database interface to be used
+    """
+                    
+    tb = SpatioTemporalTopologyBuilder()
+
+    tb.build(maps1, maps2)
+
+    dbif, connected = init_dbif(dbif)
+        
+    for _map in tb:
+        _map.select(dbif)
+        _map.print_info()
+        
+    if connected:
+        dbif.close()
+        
+    return
+
+###############################################################################
+
+def count_temporal_topology_relationships(maps1, maps2=None, dbif=None):
+    """!Count the temporal relations of a single list of maps or between two lists of maps
+
+
+        @param maps1 A list of abstract_dataset 
+                      objects with initiated temporal extent
+        @param maps2 A list of abstract_dataset 
+                      objects with initiated temporal extent
+        @param dbif The database interface to be used
+        @return A dictionary with counted temporal relationships
+    """
+
+    
+    tb = SpatioTemporalTopologyBuilder()
+    tb.build(maps1, maps2)
+
+    dbif, connected = init_dbif(dbif)
+    
+    relations = None
+        
+    for _map in tb:
+        if relations != None:
+            r = _map.get_number_of_relations()
+            for k in r.keys():
+                relations[k] += r[k]
+        else:
+            relations = _map.get_number_of_relations()
+
+    if connected:
+        dbif.close()
+        
+    return relations
+
+###############################################################################
+
+def create_temporal_relation_sql_where_statement(
+                        start, end, use_start=True, use_during=False,
+                        use_overlap=False, use_contain=False, use_equal=False,
+                        use_follows=False, use_precedes=False):
+    """!Create a SQL WHERE statement for temporal relation selection of maps in space time datasets
+
+        @param start The start time
+        @param end The end time
+        @param use_start Select maps of which the start time is located in the selection granule
+                         @verbatim
+                         map    :        s
+                         granule:  s-----------------e
+
+                         map    :        s--------------------e
+                         granule:  s-----------------e
+
+                         map    :        s--------e
+                         granule:  s-----------------e
+                         @endverbatim
+
+        @param use_during Select maps which are temporal during the selection granule
+                         @verbatim
+                         map    :     s-----------e
+                         granule:  s-----------------e
+                         @endverbatim
+
+        @param use_overlap Select maps which temporal overlap the selection granule
+                         @verbatim
+                         map    :     s-----------e
+                         granule:        s-----------------e
+
+                         map    :     s-----------e
+                         granule:  s----------e
+                         @endverbatim
+
+        @param use_contain Select maps which temporally contain the selection granule
+                         @verbatim
+                         map    :  s-----------------e
+                         granule:     s-----------e
+                         @endverbatim
+
+        @param use_equal Select maps which temporally equal to the selection granule
+                         @verbatim
+                         map    :  s-----------e
+                         granule:  s-----------e
+                         @endverbatim
+
+        @param use_follows Select maps which temporally follow the selection granule
+                         @verbatim
+                         map    :              s-----------e
+                         granule:  s-----------e
+                         @endverbatim
+
+        @param use_precedes Select maps which temporally precedes the selection granule
+                         @verbatim
+                         map    :  s-----------e
+                         granule:              s-----------e
+                         @endverbatim
+
+        Usage:
+        
+        @code
+        
+        >>> # Relative time
+        >>> start = 1
+        >>> end = 2
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False)
+        >>> create_temporal_relation_sql_where_statement(start, end)
+        '((start_time >= 1 and start_time < 2) )'
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=True)
+        '((start_time >= 1 and start_time < 2) )'
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False, use_during=True)
+        '(((start_time > 1 and end_time < 2) OR (start_time >= 1 and end_time < 2) OR (start_time > 1 and end_time <= 2)))'
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False, use_overlap=True)
+        '(((start_time < 1 and end_time > 1 and end_time < 2) OR (start_time < 2 and start_time > 1 and end_time > 2)))'
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False, use_contain=True)
+        '(((start_time < 1 and end_time > 2) OR (start_time <= 1 and end_time > 2) OR (start_time < 1 and end_time >= 2)))'
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False, use_equal=True)
+        '((start_time = 1 and end_time = 2))'
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False, use_follows=True)
+        '((start_time = 2))'
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False, use_precedes=True)
+        '((end_time = 1))'
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=True, use_during=True, use_overlap=True, use_contain=True,
+        ... use_equal=True, use_follows=True, use_precedes=True)
+        '((start_time >= 1 and start_time < 2)  OR ((start_time > 1 and end_time < 2) OR (start_time >= 1 and end_time < 2) OR (start_time > 1 and end_time <= 2)) OR ((start_time < 1 and end_time > 1 and end_time < 2) OR (start_time < 2 and start_time > 1 and end_time > 2)) OR ((start_time < 1 and end_time > 2) OR (start_time <= 1 and end_time > 2) OR (start_time < 1 and end_time >= 2)) OR (start_time = 1 and end_time = 2) OR (start_time = 2) OR (end_time = 1))'
+
+        >>> # Absolute time
+        >>> start = datetime(2001, 1, 1, 12, 30)
+        >>> end = datetime(2001, 3, 31, 14, 30)
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False)
+        >>> create_temporal_relation_sql_where_statement(start, end)
+        "((start_time >= '2001-01-01 12:30:00' and start_time < '2001-03-31 14:30:00') )"
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=True)
+        "((start_time >= '2001-01-01 12:30:00' and start_time < '2001-03-31 14:30:00') )"
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False, use_during=True)
+        "(((start_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time >= '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time > '2001-01-01 12:30:00' and end_time <= '2001-03-31 14:30:00')))"
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False, use_overlap=True)
+        "(((start_time < '2001-01-01 12:30:00' and end_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time < '2001-03-31 14:30:00' and start_time > '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00')))"
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False, use_contain=True)
+        "(((start_time < '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time <= '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time < '2001-01-01 12:30:00' and end_time >= '2001-03-31 14:30:00')))"
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False, use_equal=True)
+        "((start_time = '2001-01-01 12:30:00' and end_time = '2001-03-31 14:30:00'))"
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False, use_follows=True)
+        "((start_time = '2001-03-31 14:30:00'))"
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=False, use_precedes=True)
+        "((end_time = '2001-01-01 12:30:00'))"
+        >>> create_temporal_relation_sql_where_statement(start, end, 
+        ... use_start=True, use_during=True, use_overlap=True, use_contain=True,
+        ... use_equal=True, use_follows=True, use_precedes=True)
+        "((start_time >= '2001-01-01 12:30:00' and start_time < '2001-03-31 14:30:00')  OR ((start_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time >= '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time > '2001-01-01 12:30:00' and end_time <= '2001-03-31 14:30:00')) OR ((start_time < '2001-01-01 12:30:00' and end_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time < '2001-03-31 14:30:00' and start_time > '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00')) OR ((start_time < '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time <= '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time < '2001-01-01 12:30:00' and end_time >= '2001-03-31 14:30:00')) OR (start_time = '2001-01-01 12:30:00' and end_time = '2001-03-31 14:30:00') OR (start_time = '2001-03-31 14:30:00') OR (end_time = '2001-01-01 12:30:00'))"
+        
+        @endcode
+        """
+
+    where = "("
+
+    if use_start:
+        if isinstance(start, datetime):
+            where += "(start_time >= '%s' and start_time < '%s') " % (start, end)
+        else:
+            where += "(start_time >= %i and start_time < %i) " % (start, end)
+
+    if use_during:
+        if use_start:
+            where += " OR "
+            
+        if isinstance(start, datetime):
+            where += "((start_time > '%s' and end_time < '%s') OR " % (start, end)
+            where += "(start_time >= '%s' and end_time < '%s') OR " % (start, end)
+            where += "(start_time > '%s' and end_time <= '%s'))" % (start, end)
+        else:
+            where += "((start_time > %i and end_time < %i) OR " % (start, end)
+            where += "(start_time >= %i and end_time < %i) OR " % (start, end)
+            where += "(start_time > %i and end_time <= %i))" % (start, end)
+
+    if use_overlap:
+        if use_start or use_during:
+            where += " OR "
+
+        if isinstance(start, datetime):
+            where += "((start_time < '%s' and end_time > '%s' and end_time < '%s') OR " % (start, start, end)
+            where += "(start_time < '%s' and start_time > '%s' and end_time > '%s'))" % (end, start, end)
+        else:
+            where += "((start_time < %i and end_time > %i and end_time < %i) OR " % (start, start, end)
+            where += "(start_time < %i and start_time > %i and end_time > %i))" % (end, start, end)
+
+    if use_contain:
+        if use_start or use_during or use_overlap:
+            where += " OR "
+
+        if isinstance(start, datetime):
+            where += "((start_time < '%s' and end_time > '%s') OR " % (start, end)
+            where += "(start_time <= '%s' and end_time > '%s') OR " % (start, end)
+            where += "(start_time < '%s' and end_time >= '%s'))" % (start, end)
+        else:
+            where += "((start_time < %i and end_time > %i) OR " % (start, end)
+            where += "(start_time <= %i and end_time > %i) OR " % (start, end)
+            where += "(start_time < %i and end_time >= %i))" % (start, end)
+
+    if use_equal:
+        if use_start or use_during or use_overlap or use_contain:
+            where += " OR "
+
+        if isinstance(start, datetime):
+            where += "(start_time = '%s' and end_time = '%s')" % (start, end)
+        else:
+            where += "(start_time = %i and end_time = %i)" % (start, end)
+
+    if use_follows:
+        if use_start or use_during or use_overlap or use_contain or use_equal:
+            where += " OR "
+
+        if isinstance(start, datetime):
+            where += "(start_time = '%s')" % (end)
+        else:
+            where += "(start_time = %i)" % (end)
+
+    if use_precedes:
+        if use_start or use_during or use_overlap or use_contain or use_equal \
+           or use_follows:
+            where += " OR "
+
+        if isinstance(start, datetime):
+            where += "(end_time = '%s')" % (start)
+        else:
+            where += "(end_time = %i)" % (start)
+
+    where += ")"
+
+    # Catch empty where statement
+    if where == "()":
+        where = None
+
+    return where
+    
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()

Deleted: grass/trunk/lib/python/temporal/temporal_relationships.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_relationships.py	2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/temporal_relationships.py	2013-04-25 23:07:37 UTC (rev 55998)
@@ -1,649 +0,0 @@
-"""!@package grass.temporal
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related functions to be used in temporal GIS Python library package.
-
-Usage:
-
- at code
-import grass.temporal as tgis
-
-tgis.print_temporal_relations(maps)
-...
- at endcode
-
-(C) 2008-2011 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Soeren Gebbert
-"""
-from abstract_map_dataset import *
-from datetime_math import *
-import grass.lib.vector as vector
-import grass.lib.gis as gis
-from ctypes import *
-
-###############################################################################
-
-class TemporalTopologyBuilder(object):
-    """!This class is designed to build the temporal topology 
-       of temporally related abstract dataset objects.
-       
-       The abstract dataset objects must be provided as a single list, or in two lists.
-
-        Example:
-        @code
-        # We have a space time raster dataset and build a map list
-        # from all registered maps ordered by start time
-        maps = strds.get_registered_maps_as_objects()
-
-        # Now lets build the temporal topology of the maps in the list
-        
-        tb = TemporalTopologyBuilder()
-        
-        tb.build(maps)
-
-        dbif, connected = init_dbif(None)
-            
-        for _map in tb:
-            _map.select(dbif)
-            _map.print_info()
-
-        # Using the next and previous methods, we can iterate over the
-        # topological related maps in this way
-
-        _first = tb.get_first()
-
-        while _first:
-            _first.print_topology_info()
-            _first = _first.next()
-
-        # Dictionary like accessed
-        _map = tb["name at mapset"]
-        @endcode
-
-    """
-    def __init__(self):
-        self._reset()
-        # 0001-01-01 00:00:00
-        self._timeref = datetime(1,1,1)
-
-    def _reset(self):
-        self._store = {}
-        self._first = None
-        self._iteratable = False
-
-    def _set_first(self, first):
-        self._first = first
-        self._insert(first)
-
-    def _detect_first(self):
-        if len(self) > 0:
-            prev_ = self._store.values()[0]
-            while prev_ is not None:
-                self._first = prev_
-                prev_ = prev_.prev()
-
-    def _insert(self, t):
-        self._store[t.get_id()] = t
-
-    def get_first(self):
-        """!Return the first map with the earliest start time
-
-           @return The map with the earliest start time
-        """
-        return self._first
-
-    def _build_internal_iteratable(self, maps):
-        """!Build an iteratable temporal topology structure for all maps in 
-           the list and store the maps internally
-
-           Basically the "next" and "prev" relations will be set in the 
-           temporal topology structure of each map
-           The maps will be added to the object, so they can be 
-           accessed using the iterator of this class
-
-           @param maps A sorted (by start_time)list of abstract_dataset 
-                        objects with initiated temporal extent
-        """
-        self._build_iteratable(maps)
-
-        for _map in maps:
-            self._insert(_map)
-
-        # Detect the first map
-        self._detect_first()
-
-    def _build_iteratable(self, maps):
-        """!Build an iteratable temporal topology structure for 
-           all maps in the list
-
-           Basically the "next" and "prev" relations will be set in 
-           the temporal topology structure of each map.
-
-           @param maps A sorted (by start_time)list of abstract_dataset 
-                        objects with initiated temporal extent
-        """
-#        for i in xrange(len(maps)):
-#            offset = i + 1
-#            for j in xrange(offset, len(maps)):
-#                # Get the temporal relationship
-#                relation = maps[j].temporal_relation(maps[i])
-#
-#                # Build the next reference
-#                if relation != "equal" and relation != "started":
-#                    maps[i].set_next(maps[j])
-#                    break
-
-        # First we need to order the map list chronologically 
-        sorted_maps = sorted(
-            maps, key=AbstractDatasetComparisonKeyStartTime)
-            
-        for i in xrange(len(sorted_maps) - 1):
-            sorted_maps[i].set_next(sorted_maps[i + 1])
-
-        for map_ in sorted_maps:
-            next_ = map_.next()
-            if next_:
-                next_.set_prev(map_)
-            map_.set_topology_build_true()
-        
-    def _map_to_rect(self, tree, map_):
-        """Use the temporal extent of a map to create and return a RTree rectange"""
-        rect = vector.RTreeAllocRect(tree)
-        
-        start, end = map_.get_valid_time()
-        
-        if not end:
-            end = start
-        
-        if map_.is_time_absolute():
-            start = time_delta_to_relative_time(start - self._timeref)
-            end = time_delta_to_relative_time(end - self._timeref)
-                
-        vector.RTreeSetRect1D(rect, tree, float(start), float(end))
-        
-        return rect
-        
-    def _build_1d_rtree(self, maps):
-        """Build and return the one dimensional R*-Tree"""
-
-        tree = vector.RTreeCreateTree(-1, 0, 1)
-
-        for i in xrange(len(maps)):
-            
-            rect = self._map_to_rect(tree, maps[i])
-            vector.RTreeInsertRect(rect, i + 1, tree)
-            
-        return tree
-
-    def build(self, mapsA, mapsB=None):
-        """!Build the temporal topology structure between 
-           one or two unordered lists of abstract dataset objects
-
-           This method builds the temporal topology from mapsA to 
-           mapsB and vice verse. The temporal topology structure of each map, 
-           defined in class temporal_map_relations,
-           will be reseted and rebuild for mapsA and mapsB.
-
-           After building the temporal topology the modified 
-           map objects of mapsA can be accessed
-           in the same way as a dictionary using there id. 
-           The implemented iterator assures
-           the chronological iteration over the mapsA.
-
-           @param mapsA A list of abstract_dataset 
-                         objects with initiated temporal extent
-           @param mapsB An optional list of abstract_dataset 
-                         objects with initiated temporal extent
-        """
-
-        identical = False
-        if mapsA == mapsB:
-            identical = True
-            
-        if mapsB == None:
-            mapsB = mapsA
-            idetnical = True
-
-        for map_ in mapsA:
-            map_.reset_topology()
-
-        if not identical:
-            for map_ in mapsB:
-                map_.reset_topology()
-
-        tree = self. _build_1d_rtree(mapsA)
-            
-        for j in xrange(len(mapsB)):            
-        
-            list_ = gis.ilist()
-            rect = self._map_to_rect(tree, mapsB[j])
-            num = vector.RTreeSearch2(tree, rect, byref(list_))
-            vector.RTreeFreeRect(rect)
-
-            for k in xrange(list_.n_values):
-                i = list_.value[k] - 1
-
-                # Get the temporal relationship
-                relation = mapsB[j].temporal_relation(mapsA[i])
-                
-                A = mapsA[i]
-                B = mapsB[j]
-                set_temoral_relationship(A, B, relation)
-
-        self._build_internal_iteratable(mapsA)
-        if not identical and mapsB != None:
-            self._build_iteratable(mapsB)
-        
-        vector.RTreeDestroyTree(tree)
-
-    def __iter__(self):
-        start_ = self._first
-        while start_ is not None:
-            yield start_
-            start_ = start_.next()
-
-    def __getitem__(self, index):
-        return self._store[index.get_id()]
-
-    def __len__(self):
-        return len(self._store)
-
-    def __contains__(self, _map):
-        return _map in self._store.values()
-
-###############################################################################
-
-
-def set_temoral_relationship(A, B, relation):
-    if relation == "equal":
-        if B != A:
-            if not B.get_equal() or \
-            (B.get_equal() and \
-            A not in B.get_equal()):
-                B.append_equal(A)
-            if not A.get_equal() or \
-            (A.get_equal() and \
-            B not in A.get_equal()):
-                A.append_equal(B)
-    elif relation == "follows":
-        if not B.get_follows() or \
-            (B.get_follows() and \
-            A not in B.get_follows()):
-            B.append_follows(A)
-        if not A.get_precedes() or \
-            (A.get_precedes() and
-            B not in A.get_precedes()):
-            A.append_precedes(B)
-    elif relation == "precedes":
-        if not B.get_precedes() or \
-            (B.get_precedes() and \
-            A not in B.get_precedes()):
-            B.append_precedes(A)
-        if not A.get_follows() or \
-            (A.get_follows() and \
-            B not in A.get_follows()):
-            A.append_follows(B)
-    elif relation == "during" or relation == "starts" or \
-            relation == "finishes":
-        if not B.get_during() or \
-            (B.get_during() and \
-            A not in B.get_during()):
-            B.append_during(A)
-        if not A.get_contains() or \
-            (A.get_contains() and \
-            B not in A.get_contains()):
-            A.append_contains(B)
-        if relation == "starts":
-            if not B.get_starts() or \
-            (B.get_starts() and \
-            A not in B.get_starts()):
-                B.append_starts(A)
-            if not A.get_started() or \
-            (A.get_started() and \
-            B not in A.get_started()):
-                A.append_started(B)
-        if relation == "finishes":
-            if not B.get_finishes() or \
-            (B.get_finishes() and \
-            A not in B.get_finishes()):
-                B.append_finishes(A)
-            if not A.get_finished() or \
-            (A.get_finished() and \
-            B not in A.get_finished()):
-                A.append_finished(B)
-    elif relation == "contains" or relation == "started" or \
-            relation == "finished":
-        if not B.get_contains() or \
-            (B.get_contains() and \
-            A not in B.get_contains()):
-            B.append_contains(A)
-        if not A.get_during() or \
-            (A.get_during() and \
-            B not in A.get_during()):
-            A.append_during(B)
-        if relation == "started":
-            if not B.get_started() or \
-            (B.get_started() and \
-            A not in B.get_started()):
-                B.append_started(A)
-            if not A.get_starts() or \
-            (A.get_starts() and \
-            B not in A.get_starts()):
-                A.append_starts(B)
-        if relation == "finished":
-            if not B.get_finished() or \
-            (B.get_finished() and \
-            A not in B.get_finished()):
-                B.append_finished(A)
-            if not A.get_finishes() or \
-            (A.get_finishes() and \
-            B not in A.get_finishes()):
-                A.append_finishes(B)
-    elif relation == "overlaps":
-        if not B.get_overlaps() or \
-            (B.get_overlaps() and \
-            A not in B.get_overlaps()):
-            B.append_overlaps(A)
-        if not A.get_overlapped() or \
-            (A.get_overlapped() and \
-            B not in A.get_overlapped()):
-            A.append_overlapped(B)
-    elif relation == "overlapped":
-        if not B.get_overlapped() or \
-            (B.get_overlapped() and \
-            A not in B.get_overlapped()):
-            B.append_overlapped(A)
-        if not A.get_overlaps() or \
-            (A.get_overlaps() and \
-            B not in A.get_overlaps()):
-            A.append_overlaps(B)
-
-###############################################################################
-
-def print_temporal_topology_relationships(maps1, maps2=None, dbif=None):
-    """!Print the temporal relationships of the 
-       map lists maps1 and maps2 to stdout.
-
-        @param maps1 A list of abstract_dataset 
-                      objects with initiated temporal extent
-        @param maps2 An optional list of abstract_dataset 
-                      objects with initiated temporal extent
-        @param dbif The database interface to be used
-    """
-                    
-    tb = TemporalTopologyBuilder()
-
-    tb.build(maps1, maps2)
-
-    dbif, connected = init_dbif(dbif)
-        
-    for _map in tb:
-        _map.select(dbif)
-        _map.print_info()
-        
-    if connected:
-        dbif.close()
-        
-    return
-
-###############################################################################
-
-def count_temporal_topology_relationships(maps1, maps2=None, dbif=None):
-    """!Count the temporal relations of a single list of maps or between two lists of maps
-
-
-        @param maps1 A list of abstract_dataset 
-                      objects with initiated temporal extent
-        @param maps2 A list of abstract_dataset 
-                      objects with initiated temporal extent
-        @param dbif The database interface to be used
-        @return A dictionary with counted temporal relationships
-    """
-
-    
-    tb = TemporalTopologyBuilder()
-    tb.build(maps1, maps2)
-
-    dbif, connected = init_dbif(dbif)
-    
-    relations = None
-        
-    for _map in tb:
-        if relations != None:
-            r = _map.get_number_of_relations()
-            for k in r.keys():
-                relations[k] += r[k]
-        else:
-            relations = _map.get_number_of_relations()
-
-    if connected:
-        dbif.close()
-        
-    return relations
-
-###############################################################################
-
-def create_temporal_relation_sql_where_statement(
-                        start, end, use_start=True, use_during=False,
-                        use_overlap=False, use_contain=False, use_equal=False,
-                        use_follows=False, use_precedes=False):
-    """!Create a SQL WHERE statement for temporal relation selection of maps in space time datasets
-
-        @param start The start time
-        @param end The end time
-        @param use_start Select maps of which the start time is located in the selection granule
-                         @verbatim
-                         map    :        s
-                         granule:  s-----------------e
-
-                         map    :        s--------------------e
-                         granule:  s-----------------e
-
-                         map    :        s--------e
-                         granule:  s-----------------e
-                         @endverbatim
-
-        @param use_during Select maps which are temporal during the selection granule
-                         @verbatim
-                         map    :     s-----------e
-                         granule:  s-----------------e
-                         @endverbatim
-
-        @param use_overlap Select maps which temporal overlap the selection granule
-                         @verbatim
-                         map    :     s-----------e
-                         granule:        s-----------------e
-
-                         map    :     s-----------e
-                         granule:  s----------e
-                         @endverbatim
-
-        @param use_contain Select maps which temporally contain the selection granule
-                         @verbatim
-                         map    :  s-----------------e
-                         granule:     s-----------e
-                         @endverbatim
-
-        @param use_equal Select maps which temporally equal to the selection granule
-                         @verbatim
-                         map    :  s-----------e
-                         granule:  s-----------e
-                         @endverbatim
-
-        @param use_follows Select maps which temporally follow the selection granule
-                         @verbatim
-                         map    :              s-----------e
-                         granule:  s-----------e
-                         @endverbatim
-
-        @param use_precedes Select maps which temporally precedes the selection granule
-                         @verbatim
-                         map    :  s-----------e
-                         granule:              s-----------e
-                         @endverbatim
-
-        Usage:
-        
-        @code
-        
-        >>> # Relative time
-        >>> start = 1
-        >>> end = 2
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False)
-        >>> create_temporal_relation_sql_where_statement(start, end)
-        '((start_time >= 1 and start_time < 2) )'
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=True)
-        '((start_time >= 1 and start_time < 2) )'
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False, use_during=True)
-        '(((start_time > 1 and end_time < 2) OR (start_time >= 1 and end_time < 2) OR (start_time > 1 and end_time <= 2)))'
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False, use_overlap=True)
-        '(((start_time < 1 and end_time > 1 and end_time < 2) OR (start_time < 2 and start_time > 1 and end_time > 2)))'
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False, use_contain=True)
-        '(((start_time < 1 and end_time > 2) OR (start_time <= 1 and end_time > 2) OR (start_time < 1 and end_time >= 2)))'
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False, use_equal=True)
-        '((start_time = 1 and end_time = 2))'
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False, use_follows=True)
-        '((start_time = 2))'
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False, use_precedes=True)
-        '((end_time = 1))'
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=True, use_during=True, use_overlap=True, use_contain=True,
-        ... use_equal=True, use_follows=True, use_precedes=True)
-        '((start_time >= 1 and start_time < 2)  OR ((start_time > 1 and end_time < 2) OR (start_time >= 1 and end_time < 2) OR (start_time > 1 and end_time <= 2)) OR ((start_time < 1 and end_time > 1 and end_time < 2) OR (start_time < 2 and start_time > 1 and end_time > 2)) OR ((start_time < 1 and end_time > 2) OR (start_time <= 1 and end_time > 2) OR (start_time < 1 and end_time >= 2)) OR (start_time = 1 and end_time = 2) OR (start_time = 2) OR (end_time = 1))'
-
-        >>> # Absolute time
-        >>> start = datetime(2001, 1, 1, 12, 30)
-        >>> end = datetime(2001, 3, 31, 14, 30)
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False)
-        >>> create_temporal_relation_sql_where_statement(start, end)
-        "((start_time >= '2001-01-01 12:30:00' and start_time < '2001-03-31 14:30:00') )"
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=True)
-        "((start_time >= '2001-01-01 12:30:00' and start_time < '2001-03-31 14:30:00') )"
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False, use_during=True)
-        "(((start_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time >= '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time > '2001-01-01 12:30:00' and end_time <= '2001-03-31 14:30:00')))"
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False, use_overlap=True)
-        "(((start_time < '2001-01-01 12:30:00' and end_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time < '2001-03-31 14:30:00' and start_time > '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00')))"
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False, use_contain=True)
-        "(((start_time < '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time <= '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time < '2001-01-01 12:30:00' and end_time >= '2001-03-31 14:30:00')))"
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False, use_equal=True)
-        "((start_time = '2001-01-01 12:30:00' and end_time = '2001-03-31 14:30:00'))"
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False, use_follows=True)
-        "((start_time = '2001-03-31 14:30:00'))"
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=False, use_precedes=True)
-        "((end_time = '2001-01-01 12:30:00'))"
-        >>> create_temporal_relation_sql_where_statement(start, end, 
-        ... use_start=True, use_during=True, use_overlap=True, use_contain=True,
-        ... use_equal=True, use_follows=True, use_precedes=True)
-        "((start_time >= '2001-01-01 12:30:00' and start_time < '2001-03-31 14:30:00')  OR ((start_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time >= '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time > '2001-01-01 12:30:00' and end_time <= '2001-03-31 14:30:00')) OR ((start_time < '2001-01-01 12:30:00' and end_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time < '2001-03-31 14:30:00' and start_time > '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00')) OR ((start_time < '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time <= '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time < '2001-01-01 12:30:00' and end_time >= '2001-03-31 14:30:00')) OR (start_time = '2001-01-01 12:30:00' and end_time = '2001-03-31 14:30:00') OR (start_time = '2001-03-31 14:30:00') OR (end_time = '2001-01-01 12:30:00'))"
-        
-        @endcode
-        """
-
-    where = "("
-
-    if use_start:
-        if isinstance(start, datetime):
-            where += "(start_time >= '%s' and start_time < '%s') " % (start, end)
-        else:
-            where += "(start_time >= %i and start_time < %i) " % (start, end)
-
-    if use_during:
-        if use_start:
-            where += " OR "
-            
-        if isinstance(start, datetime):
-            where += "((start_time > '%s' and end_time < '%s') OR " % (start, end)
-            where += "(start_time >= '%s' and end_time < '%s') OR " % (start, end)
-            where += "(start_time > '%s' and end_time <= '%s'))" % (start, end)
-        else:
-            where += "((start_time > %i and end_time < %i) OR " % (start, end)
-            where += "(start_time >= %i and end_time < %i) OR " % (start, end)
-            where += "(start_time > %i and end_time <= %i))" % (start, end)
-
-    if use_overlap:
-        if use_start or use_during:
-            where += " OR "
-
-        if isinstance(start, datetime):
-            where += "((start_time < '%s' and end_time > '%s' and end_time < '%s') OR " % (start, start, end)
-            where += "(start_time < '%s' and start_time > '%s' and end_time > '%s'))" % (end, start, end)
-        else:
-            where += "((start_time < %i and end_time > %i and end_time < %i) OR " % (start, start, end)
-            where += "(start_time < %i and start_time > %i and end_time > %i))" % (end, start, end)
-
-    if use_contain:
-        if use_start or use_during or use_overlap:
-            where += " OR "
-
-        if isinstance(start, datetime):
-            where += "((start_time < '%s' and end_time > '%s') OR " % (start, end)
-            where += "(start_time <= '%s' and end_time > '%s') OR " % (start, end)
-            where += "(start_time < '%s' and end_time >= '%s'))" % (start, end)
-        else:
-            where += "((start_time < %i and end_time > %i) OR " % (start, end)
-            where += "(start_time <= %i and end_time > %i) OR " % (start, end)
-            where += "(start_time < %i and end_time >= %i))" % (start, end)
-
-    if use_equal:
-        if use_start or use_during or use_overlap or use_contain:
-            where += " OR "
-
-        if isinstance(start, datetime):
-            where += "(start_time = '%s' and end_time = '%s')" % (start, end)
-        else:
-            where += "(start_time = %i and end_time = %i)" % (start, end)
-
-    if use_follows:
-        if use_start or use_during or use_overlap or use_contain or use_equal:
-            where += " OR "
-
-        if isinstance(start, datetime):
-            where += "(start_time = '%s')" % (end)
-        else:
-            where += "(start_time = %i)" % (end)
-
-    if use_precedes:
-        if use_start or use_during or use_overlap or use_contain or use_equal \
-           or use_follows:
-            where += " OR "
-
-        if isinstance(start, datetime):
-            where += "(end_time = '%s')" % (start)
-        else:
-            where += "(end_time = %i)" % (start)
-
-    where += ")"
-
-    # Catch empty where statement
-    if where == "()":
-        where = None
-
-    return where
-    
-
-###############################################################################
-
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()

Copied: grass/trunk/lib/python/temporal/temporal_topology_dataset_connector.py (from rev 55991, grass/trunk/lib/python/temporal/abstract_temporal_dataset.py)
===================================================================
--- grass/trunk/lib/python/temporal/temporal_topology_dataset_connector.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_topology_dataset_connector.py	2013-04-25 23:07:37 UTC (rev 55998)
@@ -0,0 +1,585 @@
+# -*- coding: utf-8 -*-
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in temporal GIS Python library package.
+
+Usage:
+
+>>> import grass.temporal as tgis
+>>> tmr = tgis.TemporalTopologyDatasetConnector()
+
+(C) 2008-2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+
+class TemporalTopologyDatasetConnector(object):
+    """!This class implements a temporal topology access structure to connect temporal related datasets
+
+       This object will be set up by temporal topology creation method provided by the 
+       SpatioTemporalTopologyBuilder.
+
+       If correctly initialize the calls next() and prev() 
+       let the user walk temporally forward and backward in time.
+
+       The following temporal relations with access methods are supported:
+       - equal
+       - follows
+       - precedes
+       - overlaps
+       - overlapped
+       - during (including starts, finishes)
+       - contains (including started, finished)
+       - starts
+       - started
+       - finishes
+       - finished
+
+
+       @code:
+       # We have build the temporal topology and we know the first map
+       start = first
+       while start:
+
+           # Print all maps this map temporally contains
+           dlist = start.get_contains()
+           for map in dlist:
+               map.print_info()
+
+           start = start.next()
+         @endcode  
+        
+        Usage:
+        
+        @code
+        
+        >>> import grass.temporal as tgis
+        >>> tgis.init()
+        >>> map = tgis.RasterDataset("a at P")
+        >>> tmr = tgis.TemporalTopologyDatasetConnector()
+        >>> tmr.set_next(map)
+        >>> tmr.set_prev(map)
+        >>> tmr.append_equal(map)
+        >>> tmr.append_follows(map)
+        >>> tmr.append_precedes(map)
+        >>> tmr.append_overlapped(map)
+        >>> tmr.append_overlaps(map)
+        >>> tmr.append_during(map)
+        >>> tmr.append_contains(map)
+        >>> tmr.append_starts(map)
+        >>> tmr.append_started(map)
+        >>> tmr.append_finishes(map)
+        >>> tmr.append_finished(map)
+        >>> tmr.print_temporal_topology_info()
+         +-------------------- Temporal Topology -------------------------------------+
+         | Next: ...................... a at P
+         | Previous: .................. a at P
+         | Equal:...................... a at P
+         | Follows: ................... a at P
+         | Precedes: .................. a at P
+         | Overlaps: .................. a at P
+         | Overlapped: ................ a at P
+         | During: .................... a at P
+         | Contains: .................. a at P
+         | Starts:.. .................. a at P
+         | Started:. .................. a at P
+         | Finishes:................... a at P
+         | Finished:................... a at P
+        >>> tmr.print_temporal_topology_shell_info()
+        next=a at P
+        prev=a at P
+        equal=a at P
+        follows=a at P
+        precedes=a at P
+        overlaps=a at P
+        overlapped=a at P
+        during=a at P
+        contains=a at P
+        starts=a at P
+        started=a at P
+        finishes=a at P
+        finished=a at P
+        
+        @endcode
+    """
+
+    def __init__(self):
+        self.reset_temporal_topology()
+
+    def reset_temporal_topology(self):
+        """!Reset any information about temporal topology"""
+        self._temporal_topology = {}
+        self._has_temporal_topology = False
+        
+    def get_number_of_temporal_relations(self):
+        """! Return a dictionary in which the keys are the relation names and the value
+        are the number of relations.
+        
+        The following relations are available:
+        - equal
+        - follows
+        - precedes
+        - overlaps
+        - overlapped
+        - during (including starts, finishes)
+        - contains (including started, finished)
+        - starts
+        - started
+        - finishes
+        - finished
+        
+        To access topological information the temporal topology must be build first
+        using the SpatioTemporalTopologyBuilder.
+        
+        @return the dictionary with relations as keys and number as values or None in case the topology wasn't build
+        """
+        if self._has_temporal_topology == False:
+            return None
+    
+        relations = {}
+        try:
+            relations["equal"] = len(self._temporal_topology["EQUAL"]) 
+        except:
+            relations["equal"] = 0
+        try: 
+            relations["follows"] = len(self._temporal_topology["FOLLOWS"]) 
+        except: 
+            relations["follows"] = 0
+        try: 
+            relations["precedes"] = len(self._temporal_topology["PRECEDES"])
+        except: 
+            relations["precedes"] = 0
+        try: 
+            relations["overlaps"] = len(self._temporal_topology["OVERLAPS"])
+        except: 
+            relations["overlaps"] = 0
+        try: 
+            relations["overlapped"] = len(self._temporal_topology["OVERLAPPED"])
+        except: 
+            relations["overlapped"] = 0
+        try: 
+            relations["during"] = len(self._temporal_topology["DURING"])
+        except: 
+            relations["during"] = 0
+        try: 
+            relations["contains"] = len(self._temporal_topology["CONTAINS"])
+        except: 
+            relations["contains"] = 0
+        try: 
+            relations["starts"] = len(self._temporal_topology["STARTS"])
+        except: 
+            relations["starts"] = 0
+        try:    
+            relations["started"] = len(self._temporal_topology["STARTED"])
+        except: 
+            relations["started"] = 0
+        try: 
+            relations["finishes"] = len(self._temporal_topology["FINISHES"])
+        except: 
+            relations["finishes"] = 0
+        try: 
+            relations["finished"] = len(self._temporal_topology["FINISHED"])
+        except: 
+            relations["finished"] = 0
+            
+        return relations
+
+    def set_temporal_topology_build_true(self):
+        """!Same as name"""
+        self._has_temporal_topology = True
+
+    def set_temporal_topology_build_false(self):
+        """!Same as name"""
+        self._has_temporal_topology = False
+
+    def is_temporal_topology_build(self):
+        """!Check if the temporal topology was build"""
+        return self._has_temporal_topology
+
+    def set_next(self, map):
+        """!Set the map that is temporally as closest located after this map.
+
+           Temporally located means that the start time of the "next" map is
+           temporally located AFTER the start time of this map, but temporally
+           near than other maps of the same dataset.
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        self._temporal_topology["NEXT"] = map
+
+    def set_prev(self, map):
+        """!Set the map that is temporally as closest located before this map.
+
+           Temporally located means that the start time of the "previous" map is
+           temporally located BEFORE the start time of this map, but temporally
+           near than other maps of the same dataset.
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        self._temporal_topology["PREV"] = map
+
+    def next(self):
+        """!Return the map with a start time temporally located after
+           the start time of this map, but temporal closer than other maps
+
+           @return A map object or None
+        """
+        if "NEXT" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["NEXT"]
+
+    def prev(self):
+        """!Return the map with a start time temporally located before
+           the start time of this map, but temporal closer than other maps
+
+           @return A map object or None
+        """
+        if "PREV" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["PREV"]
+
+    def append_equal(self, map):
+        """!Append a map with equivalent temporal extent as this map
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "EQUAL" not in self._temporal_topology:
+            self._temporal_topology["EQUAL"] = []
+        self._temporal_topology["EQUAL"].append(map)
+
+    def get_equal(self):
+        """!Return a list of map objects with equivalent temporal extent as this map
+
+           @return A list of map objects or None
+        """
+        if "EQUAL" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["EQUAL"]
+
+    def append_starts(self, map):
+        """!Append a map that this map temporally starts with
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "STARTS" not in self._temporal_topology:
+            self._temporal_topology["STARTS"] = []
+        self._temporal_topology["STARTS"].append(map)
+
+    def get_starts(self):
+        """!Return a list of map objects that this map temporally starts with
+
+           @return A list of map objects or None
+        """
+        if "STARTS" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["STARTS"]
+
+    def append_started(self, map):
+        """!Append a map that this map temporally started with
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "STARTED" not in self._temporal_topology:
+            self._temporal_topology["STARTED"] = []
+        self._temporal_topology["STARTED"].append(map)
+
+    def get_started(self):
+        """!Return a list of map objects that this map temporally started with
+
+           @return A list of map objects or None
+        """
+        if "STARTED" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["STARTED"]
+
+    def append_finishes(self, map):
+        """!Append a map that this map temporally finishes with
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "FINISHES" not in self._temporal_topology:
+            self._temporal_topology["FINISHES"] = []
+        self._temporal_topology["FINISHES"].append(map)
+
+    def get_finishes(self):
+        """!Return a list of map objects that this map temporally finishes with
+
+           @return A list of map objects or None
+        """
+        if "FINISHES" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["FINISHES"]
+
+    def append_finished(self, map):
+        """!Append a map that this map temporally finished with
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "FINISHED" not in self._temporal_topology:
+            self._temporal_topology["FINISHED"] = []
+        self._temporal_topology["FINISHED"].append(map)
+
+    def get_finished(self):
+        """!Return a list of map objects that this map temporally finished with
+
+           @return A list of map objects or None
+        """
+        if "FINISHED" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["FINISHED"]
+
+    def append_overlaps(self, map):
+        """!Append a map that this map temporally overlaps
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "OVERLAPS" not in self._temporal_topology:
+            self._temporal_topology["OVERLAPS"] = []
+        self._temporal_topology["OVERLAPS"].append(map)
+
+    def get_overlaps(self):
+        """!Return a list of map objects that this map temporally overlaps
+
+           @return A list of map objects or None
+        """
+        if "OVERLAPS" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["OVERLAPS"]
+
+    def append_overlapped(self, map):
+        """!Append a map that this map temporally overlapped
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "OVERLAPPED" not in self._temporal_topology:
+            self._temporal_topology["OVERLAPPED"] = []
+        self._temporal_topology["OVERLAPPED"].append(map)
+
+    def get_overlapped(self):
+        """!Return a list of map objects that this map temporally overlapped
+
+           @return A list of map objects or None
+        """
+        if "OVERLAPPED" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["OVERLAPPED"]
+
+    def append_follows(self, map):
+        """!Append a map that this map temporally follows
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "FOLLOWS" not in self._temporal_topology:
+            self._temporal_topology["FOLLOWS"] = []
+        self._temporal_topology["FOLLOWS"].append(map)
+
+    def get_follows(self):
+        """!Return a list of map objects that this map temporally follows
+
+           @return A list of map objects or None
+        """
+        if "FOLLOWS" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["FOLLOWS"]
+
+    def append_precedes(self, map):
+        """!Append a map that this map temporally precedes
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "PRECEDES" not in self._temporal_topology:
+            self._temporal_topology["PRECEDES"] = []
+        self._temporal_topology["PRECEDES"].append(map)
+
+    def get_precedes(self):
+        """!Return a list of map objects that this map temporally precedes
+
+           @return A list of map objects or None
+        """
+        if "PRECEDES" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["PRECEDES"]
+
+    def append_during(self, map):
+        """!Append a map that this map is temporally located during
+           This includes temporal relationships starts and finishes
+
+           @param map This object should be of type 
+                        AbstractMapDataset or derived classes
+        """
+        if "DURING" not in self._temporal_topology:
+            self._temporal_topology["DURING"] = []
+        self._temporal_topology["DURING"].append(map)
+
+    def get_during(self):
+        """!Return a list of map objects that this map is temporally located during
+           This includes temporally relationships starts and finishes
+
+           @return A list of map objects or None
+        """
+        if "DURING" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["DURING"]
+
+    def append_contains(self, map):
+        """!Append a map that this map temporally contains
+           This includes temporal relationships started and finished
+
+           @param map This object should be of type AbstractMapDataset 
+                        or derived classes
+        """
+        if "CONTAINS" not in self._temporal_topology:
+            self._temporal_topology["CONTAINS"] = []
+        self._temporal_topology["CONTAINS"].append(map)
+
+    def get_contains(self):
+        """!Return a list of map objects that this map temporally contains
+           This includes temporal relationships started and finished
+
+           @return A list of map objects or None
+        """
+        if "CONTAINS" not in self._temporal_topology:
+            return None
+        return self._temporal_topology["CONTAINS"]
+
+    def _generate_map_list_string(self, map_list, line_wrap=True):
+        count = 0
+        string = ""
+        for map_ in map_list:
+            if line_wrap and count > 0 and count % 3 == 0:
+                string += "\n | ............................ "
+                count = 0
+            if count == 0:
+                string += map_.get_id()
+            else:
+                string += ",%s" % map_.get_id()
+            count += 1
+
+        return string
+    
+    # Set the properties
+    equal = property(fget=get_equal, 
+                                       fset=append_equal)
+    follows = property(fget=get_follows, 
+                                    fset=append_follows)
+    precedes = property(fget=get_precedes, 
+                                     fset=append_precedes)
+    overlaps = property(fget=get_overlaps, 
+                                     fset=append_overlaps)
+    overlapped = property(fget=get_overlapped, 
+                                       fset=append_overlapped)
+    during = property(fget=get_during, 
+                                   fset=append_during)
+    contains = property(fget=get_contains, 
+                                     fset=append_contains)
+    starts = property(fget=get_starts, 
+                                     fset=append_starts)
+    started = property(fget=get_started, 
+                                     fset=append_started)
+    finishes = property(fget=get_finishes, 
+                                     fset=append_finishes)
+    finished = property(fget=get_finished, 
+                                     fset=append_finished)
+
+    def print_temporal_topology_info(self):
+        """!Print information about this class in human readable style"""
+        
+        print " +-------------------- Temporal Topology -------------------------------------+"
+        #          0123456789012345678901234567890
+        if self.next() is not None:
+            print " | Next: ...................... " + str(self.next().get_id())
+        if self.prev() is not None:
+            print " | Previous: .................. " + str(self.prev().get_id())
+        if self.equal is not None:
+            print " | Equal:...................... " + \
+                self._generate_map_list_string(self.equal)
+        if self.follows is not None:
+            print " | Follows: ................... " + \
+                self._generate_map_list_string(self.follows)
+        if self.precedes is not None:
+            print " | Precedes: .................. " + \
+                self._generate_map_list_string(self.precedes)
+        if self.overlaps is not None:
+            print " | Overlaps: .................. " + \
+                self._generate_map_list_string(self.overlaps)
+        if self.overlapped is not None:
+            print " | Overlapped: ................ " + \
+                self._generate_map_list_string(self.overlapped)
+        if self.during is not None:
+            print " | During: .................... " + \
+                self._generate_map_list_string(self.during)
+        if self.contains is not None:
+            print " | Contains: .................. " + \
+                self._generate_map_list_string(self.contains)
+        if self.starts is not None:
+            print " | Starts:.. .................. " + \
+                self._generate_map_list_string(self.starts)
+        if self.started is not None:
+            print " | Started:. .................. " + \
+                self._generate_map_list_string(self.started)
+        if self.finishes is not None:
+            print " | Finishes:................... " + \
+                self._generate_map_list_string(self.finishes)
+        if self.finished is not None:
+            print " | Finished:................... " + \
+                self._generate_map_list_string(self.finished)
+
+    def print_temporal_topology_shell_info(self):
+        """!Print information about this class in shell style"""
+        
+        if self.next() is not None:
+            print "next=" + self.next().get_id()
+        if self.prev() is not None:
+            print "prev=" + self.prev().get_id()
+        if self.equal is not None:
+            print "equal=" + self._generate_map_list_string(self.equal, False)
+        if self.follows is not None:
+            print "follows=" + self._generate_map_list_string(self.follows, False)
+        if self.precedes is not None:
+            print "precedes=" + self._generate_map_list_string(
+                self.precedes, False)
+        if self.overlaps is not None:
+            print "overlaps=" + self._generate_map_list_string(
+                self.overlaps, False)
+        if self.overlapped is not None:
+            print "overlapped=" + \
+                self._generate_map_list_string(self.overlapped, False)
+        if self.during is not None:
+            print "during=" + self._generate_map_list_string(self.during, False)
+        if self.contains is not None:
+            print "contains=" + self._generate_map_list_string(
+                self.contains, False)
+        if self.starts is not None:
+            print "starts=" + \
+                self._generate_map_list_string(self.starts)
+        if self.started is not None:
+            print "started=" + \
+                self._generate_map_list_string(self.started)
+        if self.finishes is not None:
+            print "finishes=" + \
+                self._generate_map_list_string(self.finishes)
+        if self.finished is not None:
+            print "finished=" + \
+                self._generate_map_list_string(self.finished)
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
\ No newline at end of file

Modified: grass/trunk/lib/python/temporal/unit_tests.py
===================================================================
--- grass/trunk/lib/python/temporal/unit_tests.py	2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/unit_tests.py	2013-04-25 23:07:37 UTC (rev 55998)
@@ -1392,7 +1392,7 @@
     _map.set_absolute_time(datetime(2001, 05, 01), datetime(2001, 06, 01))
     map_listA.append(copy.copy(_map))
 
-    tb = TemporalTopologyBuilder()
+    tb = SpatioTemporalTopologyBuilder()
     tb.build(map_listA)
 
     count = 0
@@ -1422,7 +1422,7 @@
     _map.set_absolute_time(datetime(2001, 05, 01), datetime(2001, 05, 14))
     map_listB.append(copy.copy(_map))
 
-    tb = TemporalTopologyBuilder()
+    tb = SpatioTemporalTopologyBuilder()
     tb.build(map_listB)
 
     # Probing some relations
@@ -1445,7 +1445,7 @@
                 (_map.get_id(), map_listB[count].get_id()))
         count += 1
 
-    tb = TemporalTopologyBuilder()
+    tb = SpatioTemporalTopologyBuilder()
     tb.build(map_listA, map_listB)
 
     count = 0



More information about the grass-commit mailing list