[GRASS-SVN] r55711 - in grass/trunk: lib/python/temporal lib/temporal/SQL lib/temporal/lib temporal/t.topology

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Apr 11 17:05:17 PDT 2013


Author: huhabla
Date: 2013-04-11 17:05:17 -0700 (Thu, 11 Apr 2013)
New Revision: 55711

Added:
   grass/trunk/lib/python/temporal/abstract_temporal_dataset.py
Modified:
   grass/trunk/lib/python/temporal/Makefile
   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/core.py
   grass/trunk/lib/python/temporal/metadata.py
   grass/trunk/lib/python/temporal/space_time_datasets.py
   grass/trunk/lib/python/temporal/temporal_granularity.py
   grass/trunk/lib/python/temporal/temporal_relationships.py
   grass/trunk/lib/python/temporal/unit_tests.py
   grass/trunk/lib/temporal/SQL/str3ds_metadata_table.sql
   grass/trunk/lib/temporal/SQL/strds_metadata_table.sql
   grass/trunk/lib/temporal/SQL/stvds_metadata_table.sql
   grass/trunk/lib/temporal/lib/default_name.c
   grass/trunk/temporal/t.topology/t.topology.py
   grass/trunk/temporal/t.topology/test.t.topology.abstime.sh
Log:
Default temporal database will now be created in tgis/sqlite.db.
The temporal topology computation has been updated to use the 
GRASS RTree implementation.
The command history will now saved for space time datasets.
The "command" column has been added to the stds metadata tables.


Modified: grass/trunk/lib/python/temporal/Makefile
===================================================================
--- grass/trunk/lib/python/temporal/Makefile	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/python/temporal/Makefile	2013-04-12 00:05:17 UTC (rev 55711)
@@ -8,7 +8,7 @@
 GDIR = $(PYDIR)/grass
 DSTDIR = $(GDIR)/temporal
 
-MODULES = base core abstract_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets space_time_datasets_tools 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_temporal_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets space_time_datasets_tools metadata spatial_extent temporal_extent datetime_math temporal_granularity temporal_relationships unit_tests aggregation stds_export stds_import extract mapcalc univar_statistics
 
 PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
 PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)

Modified: grass/trunk/lib/python/temporal/abstract_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_dataset.py	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/python/temporal/abstract_dataset.py	2013-04-12 00:05:17 UTC (rev 55711)
@@ -46,6 +46,8 @@
     def __str__(self):
         return repr(self.msg)
     
+###############################################################################
+
 class AbstractDataset(object):
     """!This is the base class for all datasets 
        (raster, vector, raster3d, strds, stvds, str3ds)"""
@@ -114,8 +116,10 @@
         return self.base.get_mapset()
 
     def get_valid_time(self):
-        """!Returns a tuple of the start, the end valid time, 
-           this can be either datetime or double values
+        """!Returns a tuple of the valid start and end time
+        
+           Start and end time can be either of type datetime or of type double
+           depending on the temporal type
            @return A tuple of (start_time, end_time)
         """
 
@@ -145,7 +149,7 @@
         return (start, end, tz)
 
     def get_relative_time(self):
-        """!Returns the relative time interval (start_time, end_time, unit) 
+        """!Returns the valid relative time interval (start_time, end_time, unit) 
            or None if not present"""
 
         start = self.relative_time.get_start_time()
@@ -352,6 +356,102 @@
 
 ###############################################################################
 
+class AbstractDatasetComparisonKeyStartTime(object):
+    """!This comparison key can be used to sort lists of abstract datasets 
+       by start time
+
+        Example:
+
+        # Return all maps in a space time raster dataset as map objects
+        map_list = strds.get_registered_maps_as_objects()
+
+        # Sort the maps in the list by start time
+        sorted_map_list = sorted(
+            map_list, key=AbstractDatasetComparisonKeyStartTime)
+    """
+    def __init__(self, obj, *args):
+        self.obj = obj
+
+    def __lt__(self, other):
+        startA, endA = self.obj.get_valid_time()
+        startB, endB = other.obj.get_valid_time()
+        return startA < startB
+
+    def __gt__(self, other):
+        startA, endA = self.obj.get_valid_time()
+        startB, endB = other.obj.get_valid_time()
+        return startA > startB
+
+    def __eq__(self, other):
+        startA, endA = self.obj.get_valid_time()
+        startB, endB = other.obj.get_valid_time()
+        return startA == startB
+
+    def __le__(self, other):
+        startA, endA = self.obj.get_valid_time()
+        startB, endB = other.obj.get_valid_time()
+        return startA <= startB
+
+    def __ge__(self, other):
+        startA, endA = self.obj.get_valid_time()
+        startB, endB = other.obj.get_valid_time()
+        return startA >= startB
+
+    def __ne__(self, other):
+        startA, endA = self.obj.get_valid_time()
+        startB, endB = other.obj.get_valid_time()
+        return startA != startB
+
+###############################################################################
+
+class AbstractDatasetComparisonKeyEndTime(object):
+    """!This comparison key can be used to sort lists of abstract datasets 
+       by end time
+
+        Example:
+
+        # Return all maps in a space time raster dataset as map objects
+        map_list = strds.get_registered_maps_as_objects()
+
+        # Sort the maps in the list by end time
+        sorted_map_list = sorted(
+            map_list, key=AbstractDatasetComparisonKeyEndTime)
+    """
+    def __init__(self, obj, *args):
+        self.obj = obj
+
+    def __lt__(self, other):
+        startA, endA = self.obj.get_valid_time()
+        startB, endB = other.obj.get_valid_time()
+        return endA < endB
+
+    def __gt__(self, other):
+        startA, endA = self.obj.get_valid_time()
+        startB, endB = other.obj.get_valid_time()
+        return endA > endB
+
+    def __eq__(self, other):
+        startA, endA = self.obj.get_valid_time()
+        startB, endB = other.obj.get_valid_time()
+        return endA == endB
+
+    def __le__(self, other):
+        startA, endA = self.obj.get_valid_time()
+        startB, endB = other.obj.get_valid_time()
+        return endA <= endB
+
+    def __ge__(self, other):
+        startA, endA = self.obj.get_valid_time()
+        startB, endB = other.obj.get_valid_time()
+        return endA >= endB
+
+    def __ne__(self, other):
+        startA, endA = self.obj.get_valid_time()
+        startB, endB = other.obj.get_valid_time()
+        return endA != endB
+
+###############################################################################
+        
 if __name__ == "__main__":
     import doctest
     doctest.testmod()
\ No newline at end of file

Modified: grass/trunk/lib/python/temporal/abstract_map_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_map_dataset.py	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/python/temporal/abstract_map_dataset.py	2013-04-12 00:05:17 UTC (rev 55711)
@@ -8,7 +8,6 @@
 Usage:
 
 >>> import grass.temporal as tgis
->>> tmr = tgis.TemporalMapRelations()
 >>> amd = tgis.AbstractMapDataset()
 
 (C) 2008-2011 by the GRASS Development Team
@@ -18,371 +17,15 @@
 
 @author Soeren Gebbert
 """
-from abstract_dataset import *
+from abstract_temporal_dataset import *
 from datetime_math import *
 
-
-class TemporalMapRelations(AbstractDataset):
-    """!This class implements a temporal topology access structure
-
-       This object will be set up by temporal topology creation methods.
-
-       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)
-
-
-       @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
-        
-        >>> tmr = TemporalMapRelations()
-        >>> tmr.print_temporal_topology_info()
-         +-------------------- Temporal Topology -------------------------------------+
-        >>> tmr.print_temporal_topology_shell_info()
-        
-        @endcode
-    """
-
-    def __init__(self):
-        AbstractDataset.__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 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_temporal_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_temporal_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 temporal_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 temporal_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_temporal_equivalent(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_temporal_equivalent(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_temporal_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_temporal_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_temporal_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_temporal_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_temporal_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_temporal_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_temporal_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_temporal_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_temporal_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_temporal_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_temporal_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_temporal_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
-    temporal_equivalent = property(fget=get_temporal_equivalent, 
-                                       fset=append_temporal_equivalent)
-    temporal_follows = property(fget=get_temporal_follows, 
-                                    fset=append_temporal_follows)
-    temporal_precedes = property(fget=get_temporal_precedes, 
-                                     fset=append_temporal_precedes)
-    temporal_overlaps = property(fget=get_temporal_overlaps, 
-                                     fset=append_temporal_overlaps)
-    temporal_overlapped = property(fget=get_temporal_overlapped, 
-                                       fset=append_temporal_overlapped)
-    temporal_during = property(fget=get_temporal_during, 
-                                   fset=append_temporal_during)
-    temporal_contains = property(fget=get_temporal_contains, 
-                                     fset=append_temporal_contains)
-
-    def print_temporal_topology_info(self):
-        """!Print information about this class in human readable style"""
-        _next = self.temporal_next()
-        _prev = self.temporal_prev()
-        _equal = self.get_temporal_equivalent()
-        _follows = self.get_temporal_follows()
-        _precedes = self.get_temporal_precedes()
-        _overlaps = self.get_temporal_overlaps()
-        _overlapped = self.get_temporal_overlapped()
-        _during = self.get_temporal_during()
-        _contains = self.get_temporal_contains()
-
-        print " +-------------------- Temporal Topology -------------------------------------+"
-        #          0123456789012345678901234567890
-        if _next is not None:
-            print " | Next: ...................... " + str(_next.get_id())
-        if _prev is not None:
-            print " | Previous: .................. " + str(_prev.get_id())
-        if _equal is not None:
-            print " | Equivalent: ................ " + \
-                self._generate_map_list_string(_equal)
-        if _follows is not None:
-            print " | Follows: ................... " + \
-                self._generate_map_list_string(_follows)
-        if _precedes is not None:
-            print " | Precedes: .................. " + \
-                self._generate_map_list_string(_precedes)
-        if _overlaps is not None:
-            print " | Overlaps: .................. " + \
-                self._generate_map_list_string(_overlaps)
-        if _overlapped is not None:
-            print " | Overlapped: ................ " + \
-                self._generate_map_list_string(_overlapped)
-        if _during is not None:
-            print " | During: .................... " + \
-                self._generate_map_list_string(_during)
-        if _contains is not None:
-            print " | Contains: .................. " + \
-                self._generate_map_list_string(_contains)
-
-    def print_temporal_topology_shell_info(self):
-        """!Print information about this class in shell style"""
-
-        _next = self.temporal_next()
-        _prev = self.temporal_prev()
-        _equal = self.get_temporal_equivalent()
-        _follows = self.get_temporal_follows()
-        _precedes = self.get_temporal_precedes()
-        _overlaps = self.get_temporal_overlaps()
-        _overlapped = self.get_temporal_overlapped()
-        _during = self.get_temporal_during()
-        _contains = self.get_temporal_contains()
-
-        if _next is not None:
-            print "next=" + _next.get_id()
-        if _prev is not None:
-            print "prev=" + _prev.get_id()
-        if _equal is not None:
-            print "equivalent=" + self._generate_map_list_string(_equal, False)
-        if _follows is not None:
-            print "follows=" + self._generate_map_list_string(_follows, False)
-        if _precedes is not None:
-            print "precedes=" + self._generate_map_list_string(
-                _precedes, False)
-        if _overlaps is not None:
-            print "overlaps=" + self._generate_map_list_string(
-                _overlaps, False)
-        if _overlapped is not None:
-            print "overlapped=" + \
-                self._generate_map_list_string(_overlapped, False)
-        if _during is not None:
-            print "during=" + self._generate_map_list_string(_during, False)
-        if _contains is not None:
-            print "contains=" + self._generate_map_list_string(
-                _contains, False)
-
-###############################################################################
-
-
-class AbstractMapDataset(TemporalMapRelations):
+class AbstractMapDataset(AbstractTemporalDataset):
     """!This is the base class for all maps (raster, vector, raster3d)
        providing additional function to set the valid time and the spatial extent.
     """
     def __init__(self):
-        TemporalMapRelations.__init__(self)
+        AbstractTemporalDataset.__init__(self)
 
     def get_new_stds_instance(self, ident):
         """!Return a new space time dataset instance in which maps
@@ -552,6 +195,8 @@
             self.absolute_time.print_info()
         if self.is_time_relative():
             self.relative_time.print_info()
+        if self.is_topology_build():
+            self.print_topology_info()
         self.spatial_extent.print_info()
         self.metadata.print_info()
         datasets = self.get_registered_datasets()
@@ -568,8 +213,6 @@
                     string += ",%s" % ds["id"]
                 count += 1
         print " | Registered datasets ........ " + string
-        if self.is_temporal_topology_build():
-            self.print_temporal_topology_info()
         print " +----------------------------------------------------------------------------+"
 
     def print_shell_info(self):
@@ -593,8 +236,8 @@
                 count += 1
             print "registered_datasets=" + string
 
-        if self.is_temporal_topology_build():
-            self.print_temporal_topology_shell_info()
+        if self.is_topology_build():
+            self.print_topology_shell_info()
 
     def insert(self, dbif=None, execute=True):
         """!Insert temporal dataset entry into database from the internal structure

Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2013-04-12 00:05:17 UTC (rev 55711)
@@ -12,6 +12,7 @@
 
 @author Soeren Gebbert
 """
+import sys
 from abstract_dataset import *
 from temporal_granularity import *
 from temporal_relationships import *
@@ -121,7 +122,8 @@
 
     def set_initial_values(self, temporal_type, semantic_type,
                            title=None, description=None):
-        """!Set the initial values of the space time dataset
+        """!Set the initial values of the space time dataset and
+            the command creation string
 
            @param temporal_type: The temporal type of this space 
                                  time dataset (absolute or relative)
@@ -140,7 +142,44 @@
         self.base.set_semantic_type(semantic_type)
         self.metadata.set_title(title)
         self.metadata.set_description(description)
+        self.metadata.set_command(self.create_command_string())
+        
+    def create_command_string(self):
+        """!Create the command string that was used to create this
+           space time dataset.
+           
+           The command string should be set with self.metadata.set_command()
+           
+           @return The command history string
+           """
+        # The grass module
+        command = os.path.basename(sys.argv[0])
+        
+        # We will wrap the command line to fit into 80 character
+        length = len(command)
+        for token in sys.argv[1:]:
+            
+            # We need to remove specific characters
+            token = token.replace("\'", " ")
+            token = token.replace("\"", " ")
+            
+            # Check for sub strings
+            if token.find("=") > 0:
+                first = token.split("=")[0]
+                second = token.split("=")[1]
+                
+                if second.find(" ") >= 0:
+                    token = "%s=\"%s\""%(first, second)
+            
+            if length + len(token) >= 76:
+                command += "\n    %s"%(token)
+                length = len(token) + 4
+            else:
+                command += " %s"%(token)
+                length += len(token) + 1
 
+        return command
+
     def get_semantic_type(self):
         """!Return the semantic type of this dataset"""
         return self.base.get_semantic_type()
@@ -615,10 +654,14 @@
 
     def get_registered_maps_as_objects_by_granularity(self, gran=None, dbif=None):
         """!Return all registered maps as ordered (by start_time) object list with
-           "gap" map objects (id==None) for temporal topological operations using 
-           the granularity of the space time dataset as increment. 
+           "gap" map objects (id==None) for temporal topological operations 
+           that require the temporal extent only.
+           
            Each list entry is a list of map objects
            which are potentially located in the actual granule.
+           
+           The granularity of the space time dataset is used as increment in case 
+           the granule is not user defined.
 
            A valid temporal topology (no overlapping or inclusion allowed) 
            is needed to get correct results.
@@ -761,8 +804,10 @@
         return None
 
     def get_registered_maps_as_objects_with_gaps(self, where=None, dbif=None):
-        """!Return all registered maps as ordered (by start_time) object list with
-           "gap" map objects (id==None) for temporal topological operations
+        """!Return all or a subset of the registered maps as 
+           ordered (by start_time) object list with
+           "gap" map objects (id==None) for temporal topological operations 
+           that require the temporal extent only.
 
            Gaps between maps are identified as maps with id==None
 
@@ -813,12 +858,42 @@
 
         return obj_list
 
+    def get_registered_maps_as_objects_with_temporal_topology(self, where=None, order="start_time", 
+                                       dbif=None):
+        """!Return all or a subset of the registered maps as ordered object list with 
+           temporal topological relationship informations.
+
+           The objects are initialized with their id's' and the temporal extent 
+           (temporal type, start time, end time) and the temmporal topological information.
+           In case more map information are needed, use the select() 
+           method for each listed object.
+
+           @param where: The SQL where statement to select a subset of 
+                         the registered maps without "WHERE"
+           @param order: The SQL order statement to be used to order the 
+                         objects in the list without "ORDER BY"
+           @param dbif: The database interface to be used
+           @return The ordered map object list, 
+                   In case nothing found None is returned
+        """
+
+        dbif, connect = init_dbif(dbif)
+        obj_list = self.get_registered_maps_as_objects(where, order, dbif)
+
+        tb = TemporalTopologyBuilder()
+        tb.build(obj_list)
+    
+        if connect:
+            dbif.close()
+
+        return obj_list
+
     def get_registered_maps_as_objects(self, where=None, order="start_time", 
                                        dbif=None):
-        """!Return all registered maps as ordered object list for 
-           temporal topological operations
+        """!Return all or a subset of the registered maps as ordered object list for 
+           temporal topological operations that require the temporal extent only
 
-           The objects are initialized with the id and the temporal extent 
+           The objects are initialized with their id's' and the temporal extent 
            (temporal type, start time, end time).
            In case more map information are needed, use the select() 
            method for each listed object.
@@ -839,10 +914,8 @@
         rows = self.get_registered_maps(
             "id,start_time,end_time", where, order, dbif)
 
-        count = 0
         if rows is not None:
             for row in rows:
-                core.percent(count, len(rows), 1)
                 map = self.get_new_map_instance(row["id"])
                 if self.is_time_absolute():
                     map.set_absolute_time(row["start_time"], row["end_time"])
@@ -850,10 +923,7 @@
                     map.set_relative_time(row["start_time"], row["end_time"],
                                           self.get_relative_time_unit())
                 obj_list.append(copy.copy(map))
-                count += 1
 
-        core.percent(1, 1, 1)
-
         if connect:
             dbif.close()
 
@@ -1570,221 +1640,6 @@
 
 ###############################################################################
 
-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: 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()

Added: grass/trunk/lib/python/temporal/abstract_temporal_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_temporal_dataset.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/abstract_temporal_dataset.py	2013-04-12 00:05:17 UTC (rev 55711)
@@ -0,0 +1,574 @@
+# -*- 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
+        
+        >>> tmr = AbstractTemporalDataset()
+        >>> tmr.print_topology_info()
+         +-------------------- Temporal Topology -------------------------------------+
+        >>> tmr.print_topology_shell_info()
+        
+        @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_equivalent(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_equivalent(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
+    equivalent = property(fget=get_equivalent, 
+                                       fset=append_equivalent)
+    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"""
+        _next = self.next()
+        _prev = self.prev()
+        _equal = self.get_equivalent()
+        _follows = self.get_follows()
+        _precedes = self.get_precedes()
+        _overlaps = self.get_overlaps()
+        _overlapped = self.get_overlapped()
+        _during = self.get_during()
+        _contains = self.get_contains()
+        _starts = self.get_starts()
+        _started = self.get_started()
+        _finishes = self.get_finishes()
+        _finished = self.get_finished()
+        
+        print " +-------------------- Temporal Topology -------------------------------------+"
+        #          0123456789012345678901234567890
+        if _next is not None:
+            print " | Next: ...................... " + str(_next.get_id())
+        if _prev is not None:
+            print " | Previous: .................. " + str(_prev.get_id())
+        if _equal is not None:
+            print " | Equivalent: ................ " + \
+                self._generate_map_list_string(_equal)
+        if _follows is not None:
+            print " | Follows: ................... " + \
+                self._generate_map_list_string(_follows)
+        if _precedes is not None:
+            print " | Precedes: .................. " + \
+                self._generate_map_list_string(_precedes)
+        if _overlaps is not None:
+            print " | Overlaps: .................. " + \
+                self._generate_map_list_string(_overlaps)
+        if _overlapped is not None:
+            print " | Overlapped: ................ " + \
+                self._generate_map_list_string(_overlapped)
+        if _during is not None:
+            print " | During: .................... " + \
+                self._generate_map_list_string(_during)
+        if _contains is not None:
+            print " | Contains: .................. " + \
+                self._generate_map_list_string(_contains)
+        if _starts is not None:
+            print " | Starts:.. .................. " + \
+                self._generate_map_list_string(_starts)
+        if _started is not None:
+            print " | Started:. .................. " + \
+                self._generate_map_list_string(_started)
+        if _finishes is not None:
+            print " | Finishes:................... " + \
+                self._generate_map_list_string(_finishes)
+        if _finished is not None:
+            print " | Finished:................... " + \
+                self._generate_map_list_string(_finished)
+
+    def print_topology_shell_info(self):
+        """!Print information about this class in shell style"""
+
+        _next = self.next()
+        _prev = self.prev()
+        _equal = self.get_equivalent()
+        _follows = self.get_follows()
+        _precedes = self.get_precedes()
+        _overlaps = self.get_overlaps()
+        _overlapped = self.get_overlapped()
+        _during = self.get_during()
+        _contains = self.get_contains()
+        _starts = self.get_starts()
+        _started = self.get_started()
+        _finishes = self.get_finishes()
+        _finished = self.get_finished()
+        
+        if _next is not None:
+            print "next=" + _next.get_id()
+        if _prev is not None:
+            print "prev=" + _prev.get_id()
+        if _equal is not None:
+            print "equivalent=" + self._generate_map_list_string(_equal, False)
+        if _follows is not None:
+            print "follows=" + self._generate_map_list_string(_follows, False)
+        if _precedes is not None:
+            print "precedes=" + self._generate_map_list_string(
+                _precedes, False)
+        if _overlaps is not None:
+            print "overlaps=" + self._generate_map_list_string(
+                _overlaps, False)
+        if _overlapped is not None:
+            print "overlapped=" + \
+                self._generate_map_list_string(_overlapped, False)
+        if _during is not None:
+            print "during=" + self._generate_map_list_string(_during, False)
+        if _contains is not None:
+            print "contains=" + self._generate_map_list_string(
+                _contains, False)
+        if _starts is not None:
+            print "starts=" + \
+                self._generate_map_list_string(_starts)
+        if _started is not None:
+            print "started=" + \
+                self._generate_map_list_string(_started)
+        if _finishes is not None:
+            print "finishes=" + \
+                self._generate_map_list_string(_finishes)
+        if _finished is not None:
+            print "finished=" + \
+                self._generate_map_list_string(_finished)
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
\ No newline at end of file

Modified: grass/trunk/lib/python/temporal/core.py
===================================================================
--- grass/trunk/lib/python/temporal/core.py	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/python/temporal/core.py	2013-04-12 00:05:17 UTC (rev 55711)
@@ -110,7 +110,7 @@
 
 ###############################################################################
 
-def get_use_ctypes_map_access(use_ctype = True):
+def get_use_ctypes_map_access():
     """!Return true if ctypes is used for map access """
     global use_ctypes_map_access
     return use_ctypes_map_access
@@ -135,6 +135,7 @@
     """
     # We need to set the correct database backend from the environment variables
     global tgis_backed
+    global has_command_column
     
 
     core.run_command("t.connect", flags="c")
@@ -182,8 +183,24 @@
             name = cursor.fetchone()[0]
             if name == "raster_base":
                 db_exists = True
+            
+                # Try to add the command column to the space time dataset metadata tables
+                try:
+                    c.execute('ALTER TABLE strds_metadata ADD COLUMN command VARCHAR;')
+                except:
+                    pass
+                try:
+                    c.execute('ALTER TABLE str3ds_metadata ADD COLUMN command VARCHAR;')
+                except:
+                    pass
+                try:
+                    c.execute('ALTER TABLE stvds_metadata ADD COLUMN command VARCHAR;')
+                except:
+                    pass
+                
             connection.commit()
             cursor.close()
+            
     elif tgis_backed == "pg":
         # Connect to database
         connection = dbmi.connect(database)
@@ -192,6 +209,22 @@
         cursor.execute("SELECT EXISTS(SELECT * FROM information_schema.tables "
                        "WHERE table_name=%s)", ('raster_base',))
         db_exists = cursor.fetchone()[0]
+    
+        if db_exists:
+            # Try to add the command column to the space time dataset metadata tables
+            try:
+                c.execute('ALTER TABLE strds_metadata ADD COLUMN command VARCHAR;')
+            except:
+                pass
+            try:
+                c.execute('ALTER TABLE str3ds_metadata ADD COLUMN command VARCHAR;')
+            except:
+                pass
+            try:
+                c.execute('ALTER TABLE stvds_metadata ADD COLUMN command VARCHAR;')
+            except:
+                pass
+        
         connection.commit()
         cursor.close()
 
@@ -229,11 +262,17 @@
     stvds_tables_sql = stds_tables_template_sql.replace("STDS", "stvds")
     str3ds_tables_sql = stds_tables_template_sql.replace("STDS", "str3ds")
 
-    # Connect to database
-    connection = dbmi.connect(database)
-    cursor = connection.cursor()
 
     if tgis_backed == "sqlite":
+        
+        # We need to create the sqlite3 database path if it does not exists
+        tgis_dir = os.path.dirname(database)
+        if not os.path.exists(tgis_dir):
+            os.makedirs(tgis_dir)
+            
+        # Connect to database
+        connection = dbmi.connect(database)
+        cursor = connection.cursor()
 
         sqlite3_delete_trigger_sql = open(os.path.join(get_sql_template_path(
         ), "sqlite3_delete_trigger.sql"), 'r').read()
@@ -255,6 +294,9 @@
         cursor.executescript(str3ds_metadata_sql)
         cursor.executescript(sqlite3_delete_trigger_sql)
     elif tgis_backed == "pg":
+        # Connect to database
+        connection = dbmi.connect(database)
+        cursor = connection.cursor()
         # Execute the SQL statements for postgresql
         # Create the global tables for the native grass datatypes
         cursor.execute(raster_tables_sql)
@@ -276,7 +318,6 @@
 
 ###############################################################################
 
-
 class SQLDatabaseInterfaceConnection():
     """!This class represents the database interface connection
 

Modified: grass/trunk/lib/python/temporal/metadata.py
===================================================================
--- grass/trunk/lib/python/temporal/metadata.py	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/python/temporal/metadata.py	2013-04-12 00:05:17 UTC (rev 55711)
@@ -891,13 +891,14 @@
         
         @endcode
     """
-    def __init__(self, table=None, ident=None, title=None, description=None):
+    def __init__(self, table=None, ident=None, title=None, description=None, command=None):
 
         SQLDatabaseInterface.__init__(self, table, ident)
 
         self.set_id(ident)
         self.set_title(title)
         self.set_description(description)
+        self.set_command(command)
         # No setter for this
         self.D["number_of_maps"] = None
 
@@ -914,6 +915,10 @@
         """!Set the number of cols"""
         self.D["description"] = description
 
+    def set_command(self, command):
+        """!Set the number of cols"""
+        self.D["command"] = command
+        
     def get_id(self):
         """!Convenient method to get the unique identifier (primary key)
            @return None if not found
@@ -939,6 +944,14 @@
         else:
             return None
 
+    def get_command(self):
+        """!Get command
+           @return None if not found"""
+        if "command" in self.D:
+            return self.D["command"]
+        else:
+            return None
+            
     def get_number_of_maps(self):
         """!Get the number of registered maps, 
            this value is set in the database
@@ -963,6 +976,11 @@
         print " | " + str(self.get_title())
         print " | Description:"
         print " | " + str(self.get_description())
+        print " | Command of creation:"
+        command = self.get_command()
+        if command:
+            for token in command.split("\n"):
+                print " | " + str(token)
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""

Modified: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py	2013-04-12 00:05:17 UTC (rev 55711)
@@ -968,104 +968,6 @@
 
 ###############################################################################
 
-
-class AbstractDatasetComparisonKeyStartTime(object):
-    """!This comparison key can be used to sort lists of abstract datasets 
-       by start time
-
-        Example:
-
-        # Return all maps in a space time raster dataset as map objects
-        map_list = strds.get_registered_maps_as_objects()
-
-        # Sort the maps in the list by start time
-        sorted_map_list = sorted(
-            map_list, key=AbstractDatasetComparisonKeyStartTime)
-    """
-    def __init__(self, obj, *args):
-        self.obj = obj
-
-    def __lt__(self, other):
-        startA, endA = self.obj.get_valid_time()
-        startB, endB = other.obj.get_valid_time()
-        return startA < startB
-
-    def __gt__(self, other):
-        startA, endA = self.obj.get_valid_time()
-        startB, endB = other.obj.get_valid_time()
-        return startA > startB
-
-    def __eq__(self, other):
-        startA, endA = self.obj.get_valid_time()
-        startB, endB = other.obj.get_valid_time()
-        return startA == startB
-
-    def __le__(self, other):
-        startA, endA = self.obj.get_valid_time()
-        startB, endB = other.obj.get_valid_time()
-        return startA <= startB
-
-    def __ge__(self, other):
-        startA, endA = self.obj.get_valid_time()
-        startB, endB = other.obj.get_valid_time()
-        return startA >= startB
-
-    def __ne__(self, other):
-        startA, endA = self.obj.get_valid_time()
-        startB, endB = other.obj.get_valid_time()
-        return startA != startB
-
-###############################################################################
-
-
-class AbstractDatasetComparisonKeyEndTime(object):
-    """!This comparison key can be used to sort lists of abstract datasets 
-       by end time
-
-        Example:
-
-        # Return all maps in a space time raster dataset as map objects
-        map_list = strds.get_registered_maps_as_objects()
-
-        # Sort the maps in the list by end time
-        sorted_map_list = sorted(
-            map_list, key=AbstractDatasetComparisonKeyEndTime)
-    """
-    def __init__(self, obj, *args):
-        self.obj = obj
-
-    def __lt__(self, other):
-        startA, endA = self.obj.get_valid_time()
-        startB, endB = other.obj.get_valid_time()
-        return endA < endB
-
-    def __gt__(self, other):
-        startA, endA = self.obj.get_valid_time()
-        startB, endB = other.obj.get_valid_time()
-        return endA > endB
-
-    def __eq__(self, other):
-        startA, endA = self.obj.get_valid_time()
-        startB, endB = other.obj.get_valid_time()
-        return endA == endB
-
-    def __le__(self, other):
-        startA, endA = self.obj.get_valid_time()
-        startB, endB = other.obj.get_valid_time()
-        return endA <= endB
-
-    def __ge__(self, other):
-        startA, endA = self.obj.get_valid_time()
-        startB, endB = other.obj.get_valid_time()
-        return endA >= endB
-
-    def __ne__(self, other):
-        startA, endA = self.obj.get_valid_time()
-        startB, endB = other.obj.get_valid_time()
-        return endA != endB
-
-###############################################################################
-
 if __name__ == "__main__":
     import doctest
     doctest.testmod()

Modified: grass/trunk/lib/python/temporal/temporal_granularity.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_granularity.py	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/python/temporal/temporal_granularity.py	2013-04-12 00:05:17 UTC (rev 55711)
@@ -34,6 +34,7 @@
         Hence a correct temporal topology is required for computation.
 
         @param maps: a ordered by start_time list of map objects
+        @return An integer
     """
 
     # The interval time must be scaled to days resolution
@@ -84,8 +85,12 @@
         Attention: The computation of the granularity 
         is only correct in case of not overlapping intervals. 
         Hence a correct temporal topology is required for computation.
+        
+        The computed granularity is returned as number of seconds or minutes or hours
+        or days or months or years. 
 
         @param maps: a ordered by start_time list of map objects
+        @return The temporal topology as string "integer unit"
     """
 
     has_seconds = False

Modified: grass/trunk/lib/python/temporal/temporal_relationships.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_relationships.py	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/python/temporal/temporal_relationships.py	2013-04-12 00:05:17 UTC (rev 55711)
@@ -22,13 +22,17 @@
 """
 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 temporal_topology_builder(object):
+class TemporalTopologyBuilder(object):
     """!This class is designed to build the temporal topology 
-       based on a lists of maps
+       of temporally related abstract dataset objects.
+       
+       The abstract dataset objects must be provided as a single list, or in two lists.
 
         Example:
         @code
@@ -37,15 +41,17 @@
         maps = strds.get_registered_maps_as_objects()
 
         # Now lets build the temporal topology of the maps in the list
-        tb = temporal_topology_builder()
+        
+        identical = False
+        tb = TemporalTopologyBuilder()
+        
         tb.build(maps)
 
+        dbif, connected = init_dbif(None)
+            
         for _map in tb:
-            _map.print_temporal_topology_info()
-            _follows = _map.get_follows()
-            if _follows:
-                for f in _follows:
-                    f.print_temporal_topology_info()
+            _map.select(dbif)
+            _map.print_info()
 
         # Using the next and previous methods, we can iterate over the
         # topological related maps in this way
@@ -53,7 +59,7 @@
         _first = tb.get_first()
 
         while _first:
-            _first.print_temporal_topology_info()
+            _first.print_topology_info()
             _first = _first.next()
 
         # Dictionary like accessed
@@ -63,11 +69,13 @@
     """
     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._temporal_iteratable = False
+        self._iteratable = False
 
     def _set_first(self, first):
         self._first = first
@@ -78,7 +86,7 @@
             prev_ = self._store.values()[0]
             while prev_ is not None:
                 self._first = prev_
-                prev_ = prev_.temporal_prev()
+                prev_ = prev_.prev()
 
     def _insert(self, t):
         self._store[t.get_id()] = t
@@ -120,26 +128,62 @@
            @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])
+#        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 != "equivalent" and relation != "started":
+#                    maps[i].set_next(maps[j])
+#                    break
 
-                # Build the next reference
-                if relation != "equivalent" and relation != "started":
-                    maps[i].set_temporal_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 maps:
-            next_ = map_.temporal_next()
+        for map_ in sorted_maps:
+            next_ = map_.next()
             if next_:
-                next_.set_temporal_prev(map_)
-            map_.set_temporal_topology_build_true()
+                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"""
 
-    def build2(self, mapsA, mapsB):
+        tree = vector.RTreeCreateTree(-1, 0, 4)
+
+        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 
-           two ordered lists of maps
+           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, 
@@ -152,133 +196,150 @@
            The implemented iterator assures
            the chronological iteration over the mapsA.
 
-           @param mapsA: A sorted list (by start_time) of abstract_dataset 
+           @param mapsA: A list of abstract_dataset 
                          objects with initiated temporal extent
-           @param mapsB: A sorted list (by start_time) of abstract_dataset 
+           @param mapsB: An optional list of abstract_dataset 
                          objects with initiated temporal extent
         """
 
+        identical = False
         if mapsA == mapsB:
-            self.build(mapsA, True)
-            return
+            identical = True
+            
+        if mapsB == None:
+            mapsB = mapsA
+            idetnical = True
 
         for map_ in mapsA:
-            map_.reset_temporal_topology()
+            map_.reset_topology()
 
-        for map_ in mapsB:
-            map_.reset_temporal_topology()
+        if not identical:
+            for map_ in mapsB:
+                map_.reset_topology()
 
-        for i in xrange(len(mapsA)):
-            for j in xrange(len(mapsB)):
+        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])
-
-                if relation == "before":
-                    continue
-
+                
                 if relation == "equivalent":
-                    mapsB[j].append_temporal_equivalent(mapsA[i])
-                    mapsA[i].append_temporal_equivalent(mapsB[j])
+                    if mapsB[j].get_id() != mapsA[i].get_id():
+                        mapsB[j].append_equivalent(mapsA[i])
+                        mapsA[i].append_equivalent(mapsB[j])
                 elif relation == "follows":
-                    mapsB[j].append_temporal_follows(mapsA[i])
-                    mapsA[i].append_temporal_precedes(mapsB[j])
+                    if not mapsB[j].get_follows() or \
+                       (mapsB[j].get_follows() and \
+                       mapsA[i] not in mapsB[j].get_follows()):
+                        mapsB[j].append_follows(mapsA[i])
+                    if not mapsA[i].get_precedes() or \
+                       (mapsA[i].get_precedes() and
+                       mapsB[j] not in mapsA[i].get_precedes()):
+                        mapsA[i].append_precedes(mapsB[j])
                 elif relation == "precedes":
-                    mapsB[j].append_temporal_precedes(mapsA[i])
-                    mapsA[i].append_temporal_follows(mapsB[j])
+                    if not mapsB[j].get_precedes() or \
+                       (mapsB[j].get_precedes() and \
+                       mapsA[i] not in mapsB[j].get_precedes()):
+                        mapsB[j].append_precedes(mapsA[i])
+                    if not mapsA[i].get_follows() or \
+                       (mapsA[i].get_follows() and \
+                       mapsB[j] not in mapsA[i].get_follows()):
+                        mapsA[i].append_follows(mapsB[j])
                 elif relation == "during" or relation == "starts" or \
                      relation == "finishes":
-                    mapsB[j].append_temporal_during(mapsA[i])
-                    mapsA[i].append_temporal_contains(mapsB[j])
+                    if not mapsB[j].get_during() or \
+                       (mapsB[j].get_during() and \
+                       mapsA[i] not in mapsB[j].get_during()):
+                        mapsB[j].append_during(mapsA[i])
+                    if not mapsA[i].get_contains() or \
+                       (mapsA[i].get_contains() and \
+                       mapsB[j] not in mapsA[i].get_contains()):
+                        mapsA[i].append_contains(mapsB[j])
+                    if relation == "starts":
+                        if not mapsB[j].get_starts() or \
+                        (mapsB[j].get_starts() and \
+                        mapsA[i] not in mapsB[j].get_starts()):
+                            mapsB[j].append_starts(mapsA[i])
+                        if not mapsA[i].get_started() or \
+                        (mapsA[i].get_started() and \
+                        mapsB[j] not in mapsA[i].get_started()):
+                            mapsA[i].append_started(mapsB[j])
+                    if relation == "finishes":
+                        if not mapsB[j].get_finishes() or \
+                        (mapsB[j].get_finishes() and \
+                        mapsA[i] not in mapsB[j].get_finishes()):
+                            mapsB[j].append_finishes(mapsA[i])
+                        if not mapsA[i].get_finished() or \
+                        (mapsA[i].get_finished() and \
+                        mapsB[j] not in mapsA[i].get_finished()):
+                            mapsA[i].append_finished(mapsB[j])
                 elif relation == "contains" or relation == "started" or \
                      relation == "finished":
-                    mapsB[j].append_temporal_contains(mapsA[i])
-                    mapsA[i].append_temporal_during(mapsB[j])
+                    if not mapsB[j].get_contains() or \
+                       (mapsB[j].get_contains() and \
+                       mapsA[i] not in mapsB[j].get_contains()):
+                        mapsB[j].append_contains(mapsA[i])
+                    if not mapsA[i].get_during() or \
+                       (mapsA[i].get_during() and \
+                       mapsB[j] not in mapsA[i].get_during()):
+                        mapsA[i].append_during(mapsB[j])
+                    if relation == "started":
+                        if not mapsB[j].get_started() or \
+                        (mapsB[j].get_started() and \
+                        mapsA[i] not in mapsB[j].get_started()):
+                            mapsB[j].append_started(mapsA[i])
+                        if not mapsA[i].get_starts() or \
+                        (mapsA[i].get_starts() and \
+                        mapsB[j] not in mapsA[i].get_starts()):
+                            mapsA[i].append_starts(mapsB[j])
+                    if relation == "finished":
+                        if not mapsB[j].get_finished() or \
+                        (mapsB[j].get_finished() and \
+                        mapsA[i] not in mapsB[j].get_finished()):
+                            mapsB[j].append_finished(mapsA[i])
+                        if not mapsA[i].get_finishes() or \
+                        (mapsA[i].get_finishes() and \
+                        mapsB[j] not in mapsA[i].get_finishes()):
+                            mapsA[i].append_finishes(mapsB[j])
                 elif relation == "overlaps":
-                    mapsB[j].append_temporal_overlaps(mapsA[i])
-                    mapsA[i].append_temporal_overlapped(mapsB[j])
+                    if not mapsB[j].get_overlaps() or \
+                       (mapsB[j].get_overlaps() and \
+                       mapsA[i] not in mapsB[j].get_overlaps()):
+                        mapsB[j].append_overlaps(mapsA[i])
+                    if not mapsA[i].get_overlapped() or \
+                       (mapsA[i].get_overlapped() and \
+                       mapsB[j] not in mapsA[i].get_overlapped()):
+                        mapsA[i].append_overlapped(mapsB[j])
                 elif relation == "overlapped":
-                    mapsB[j].append_temporal_overlapped(mapsA[i])
-                    mapsA[i].append_temporal_overlaps(mapsB[j])
+                    if not mapsB[j].get_overlapped() or \
+                       (mapsB[j].get_overlapped() and \
+                       mapsA[i] not in mapsB[j].get_overlapped()):
+                        mapsB[j].append_overlapped(mapsA[i])
+                    if not mapsA[i].get_overlaps() or \
+                       (mapsA[i].get_overlaps() and \
+                       mapsB[j] not in mapsA[i].get_overlaps()):
+                        mapsA[i].append_overlaps(mapsB[j])
 
-                # Break if the next map follows and the over-next maps is after
-                if relation == "follows":
-                    if j < len(mapsB) - 1:
-                        relation = mapsB[j + 1].temporal_relation(mapsA[i])
-                        if relation == "after":
-                            break
-                # Break if the the next map is after
-                if relation == "after":
-                    break
-
         self._build_internal_iteratable(mapsA)
-        self._build_iteratable(mapsB)
+        if not identical and mapsB != None:
+            self._build_iteratable(mapsB)
+        
+        vector.RTreeDestroyTree(tree)
 
-    def build(self, maps):
-        """!Build the temporal topology structure
-
-           This method builds the temporal topology based on 
-           all maps in the provided map list.
-           The temporal topology structure of each map, 
-           defined in class temporal_map_relations,
-           will be reseted and rebuild.
-
-           After building the temporal topology the 
-           modified map objects can be accessed
-           in the same way as a dictionary using there id. 
-           The implemented iterator assures
-           the chronological iteration over the maps.
-
-           @param maps: A sorted list (by start_time) of abstract_dataset 
-                        objects with initiated temporal extent
-        """
-        for map_ in maps:
-            map_.reset_temporal_topology()
-
-        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])
-
-                # The start time of map j is equal or later than map i
-                if relation == "equivalent":
-                    maps[j].append_temporal_equivalent(maps[i])
-                    maps[i].append_temporal_equivalent(maps[j])
-                elif relation == "follows":
-                    maps[j].append_temporal_follows(maps[i])
-                    maps[i].append_temporal_precedes(maps[j])
-                elif relation == "during" or relation == "starts" or \
-                     relation == "finishes":
-                    maps[j].append_temporal_during(maps[i])
-                    maps[i].append_temporal_contains(maps[j])
-                elif relation == "started":
-                    # Consider equal start time, in case 
-                    # "started" map j contains map i
-                    maps[j].append_temporal_contains(maps[i])
-                    maps[i].append_temporal_during(maps[j])
-                elif relation == "overlaps":
-                    maps[j].append_temporal_overlaps(maps[i])
-                    maps[i].append_temporal_overlapped(maps[j])
-
-                # Break if the last map follows
-                if relation == "follows":
-                    if j < len(maps) - 1:
-                        relation = maps[j + 1].temporal_relation(maps[i])
-                        if relation == "after":
-                            break
-                # Break if the the next map is after
-                if relation == "after":
-                    break
-
-        self._build_internal_iteratable(maps)
-
     def __iter__(self):
         start_ = self._first
         while start_ is not None:
             yield start_
-            start_ = start_.temporal_next()
+            start_ = start_.next()
 
     def __getitem__(self, index):
         return self._store[index.get_id()]
@@ -289,97 +350,280 @@
     def __contains__(self, _map):
         return _map in self._store.values()
 
-
 ###############################################################################
 
-def print_temporal_topology_relationships(maps1, maps2):
-    """!Print the temporal relation matrix of the temporal ordered 
+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 sorted (by start_time) list of abstract_dataset 
+        @param maps1: A list of abstract_dataset 
                       objects with initiated temporal extent
-        @param maps2: A sorted (by start_time) list of abstract_dataset 
+        @param maps2: An optional list of abstract_dataset 
                       objects with initiated temporal extent
+        @param dbif: The database interface to be used
     """
+                    
+    tb = TemporalTopologyBuilder()
 
-    identical = False
-    use_id = True
+    tb.build(maps1, maps2)
 
-    if maps1 == maps2:
-        identical = True
-        use_id = False
+    dbif, connected = init_dbif(dbif)
+        
+    for _map in tb:
+        _map.select(dbif)
+        _map.print_info()
+        
+    if connected:
+        dbif.close()
+        
+    return
 
-    for i in range(len(maps1)):
-        if identical == True:
-            start = i + 1
-        else:
-            start = 0
-        for j in range(start, len(maps2)):
-            relation = maps1[j].temporal_relation(maps2[i])
-
-            if use_id == False:
-                print maps2[j].base.get_name(
-                ), relation, maps1[i].base.get_name()
-            else:
-                print maps2[j].base.get_id(), relation, maps1[i].base.get_id()
-
-            # Break if the last map follows
-            if relation == "follows":
-                if j < len(maps1) - 1:
-                    relation = maps1[j + 1].temporal_relation(maps2[i])
-                    if relation == "after":
-                        break
-            # Break if the the next map is after
-            if relation == "after":
-                break
-
 ###############################################################################
 
+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
 
-def count_temporal_topology_relationships(maps1, maps2):
-    """!Count the temporal relations between the two lists of maps
 
-        The map lists must be ordered by start time. 
-        Temporal relations are counted by analyzing the sparse 
-        (upper right side in case maps1 == maps2) temporal relationships matrix.
-
-        @param maps1: A sorted (by start_time) list of abstract_dataset 
+        @param maps1: A list of abstract_dataset 
                       objects with initiated temporal extent
-        @param maps2: A sorted (by start_time) list of abstract_dataset 
+        @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
     """
 
-    tcount = {}
-    identical = False
+    
+    tb = TemporalTopologyBuilder()
+    tb.build(maps1, maps2)
 
-    if maps1 == maps2:
-        identical = True
+    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()
 
-    for i in range(len(maps1)):
-        if identical:
-            start = i + 1
+    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: 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:
-            start = 0
-        for j in range(start, len(maps2)):
-            relation = maps1[j].temporal_relation(maps2[i])
+            where += "(start_time >= %i and start_time < %i) " % (start, end)
 
-            if relation == "before":
-                continue
+    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 relation in tcount:
-                tcount[relation] = tcount[relation] + 1
-            else:
-                tcount[relation] = 1
+    if use_overlap:
+        if use_start or use_during:
+            where += " OR "
 
-            # Break if the last map follows
-            if relation == "follows":
-                if j < len(maps1) - 1:
-                    relation = maps1[j + 1].temporal_relation(maps2[i])
-                    if relation == "after":
-                        break
-            # Break if the the next map is after
-            if relation == "after":
-                break
+        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)
 
-    return tcount
+    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
\ 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-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/python/temporal/unit_tests.py	2013-04-12 00:05:17 UTC (rev 55711)
@@ -1626,19 +1626,18 @@
 
     for i in xrange(10):
         
-        rect = vector.RTree_Rect()
-        # Allocate the boundary
-        vector.RTreeAllocBoundary(byref(rect), tree)
-        vector.RTreeSetRect1D(byref(rect), tree, float(i - 2), float(i + 2))
-        vector.RTreeInsertRect(byref(rect), i + 1, tree)
+        rect = vector.RTreeAllocRect(tree)
+        vector.RTreeSetRect1D(rect, tree, float(i - 2), float(i + 2))
+        vector.RTreeInsertRect(rect, i + 1, tree)
 
-    rect = vector.RTree_Rect()
-    vector.RTreeAllocBoundary(byref(rect), tree)
-    vector.RTreeSetRect1D(byref(rect), tree, 2.0, 7.0)
+    rect = vector.RTreeAllocRect(tree)
+    vector.RTreeSetRect1D(rect, tree, 2.0, 7.0)
 
     list_ = gis.ilist()
 
-    num = vector.RTreeSearch2(tree, byref(rect), byref(list_))
+    num = vector.RTreeSearch2(tree, rect, byref(list_))
+    
+    vector.RTreeFreeRect(rect)
 
     # print rectangle ids
     print "Number of overlapping rectangles", num
@@ -1656,22 +1655,21 @@
 
     for i in xrange(10):
         
-        rect = vector.RTree_Rect()
-        # Allocate the boundary
-        vector.RTreeAllocBoundary(byref(rect), tree)
+        
+        rect = vector.RTreeAllocRect(tree)
 
-        vector.RTreeSetRect2D(byref(rect), tree, 
+        vector.RTreeSetRect2D(rect, tree, 
                               float(i - 2), float(i + 2), 
                               float(i - 2), float(i + 2))
-        vector.RTreeInsertRect(byref(rect), i + 1, tree)
+        vector.RTreeInsertRect(rect, i + 1, tree)
+    
+    rect = vector.RTreeAllocRect(tree)
+    vector.RTreeSetRect2D(rect, tree, 2.0, 7.0, 2.0, 7.0)
 
-    rect = vector.RTree_Rect()
-    vector.RTreeAllocBoundary(byref(rect), tree)
-    vector.RTreeSetRect2D(byref(rect), tree, 2.0, 7.0, 2.0, 7.0)
-
     list_ = gis.ilist()
 
-    num = vector.RTreeSearch2(tree, byref(rect), byref(list_))
+    num = vector.RTreeSearch2(tree, rect, byref(list_))
+    vector.RTreeFreeRect(rect)
 
     # print rectangle ids
     print "Number of overlapping rectangles", num
@@ -1689,26 +1687,24 @@
 
     for i in xrange(10):
         
-        rect = vector.RTree_Rect()
-        # Allocate the boundary
-        vector.RTreeAllocBoundary(byref(rect), tree)
-        vector.RTreeSetRect3D(byref(rect), tree, 
+        rect = vector.RTreeAllocRect(tree)
+        vector.RTreeSetRect3D(rect, tree, 
                               float(i - 2), float(i + 2), 
                               float(i - 2), float(i + 2), 
                               float(i - 2), float(i + 2))
-        vector.RTreeInsertRect(byref(rect), i + 1, tree)
+        vector.RTreeInsertRect(rect, i + 1, tree)
         print i + 1
-        vector.RTreePrintRect(byref(rect), 1, tree)
+        vector.RTreePrintRect(rect, 1, tree)
 
-    rect = vector.RTree_Rect()
-    vector.RTreeAllocBoundary(byref(rect), tree)
-    vector.RTreeSetRect3D(byref(rect), tree, 2.0, 7.0, 2.0, 7.0, 2.0, 7.0)
+    rect = vector.RTreeAllocRect(tree)
+    vector.RTreeSetRect3D(rect, tree, 2.0, 7.0, 2.0, 7.0, 2.0, 7.0)
     print "Select"
-    vector.RTreePrintRect(byref(rect), 1, tree)
+    vector.RTreePrintRect(rect, 1, tree)
         
     list_ = gis.ilist()
 
-    num = vector.RTreeSearch2(tree, byref(rect), byref(list_))
+    num = vector.RTreeSearch2(tree, rect, byref(list_))
+    vector.RTreeFreeRect(rect)
 
     # print rectangle ids
     print "Number of overlapping rectangles", num
@@ -1758,7 +1754,7 @@
     test_increment_datetime_by_string()
     test_adjust_datetime_to_granularity()
     test_spatial_extent_intersection()
-    #test_compute_relative_time_granularity()
+    test_compute_relative_time_granularity()
     test_compute_absolute_time_granularity()
     test_compute_datetime_delta()
     test_spatial_extent_intersection()

Modified: grass/trunk/lib/temporal/SQL/str3ds_metadata_table.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/str3ds_metadata_table.sql	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/temporal/SQL/str3ds_metadata_table.sql	2013-04-12 00:05:17 UTC (rev 55711)
@@ -1,5 +1,5 @@
 --#############################################################################
--- This SQL script generates the space time raster3d dataset metadata table,
+-- This SQL script generates the space time 3D raster dataset metadata table,
 -- view and trigger
 --
 -- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
@@ -8,21 +8,22 @@
 --PRAGMA foreign_keys = ON;
 
 CREATE TABLE  str3ds_metadata (
-  id VARCHAR NOT NULL,          -- Id of the space-time raster3d dataset, this is the primary foreign key
-  raster3d_register VARCHAR,    -- The id of the table in which the raster3d maps are registered for this dataset
-  number_of_maps INTEGER,       -- The number of registered raster3d maps
-  max_min DOUBLE PRECISION,     -- The minimal maximum of the registered raster3d maps
-  min_min DOUBLE PRECISION,     -- The minimal minimum of the registered raster3d maps
-  max_max DOUBLE PRECISION,     -- The maximal maximum of the registered raster3d maps
-  min_max DOUBLE PRECISION,     -- The maximal minimum of the registered raster3d maps
-  nsres_min DOUBLE PRECISION,   -- The lowest north-south resolution of the registered raster3d maps
-  nsres_max DOUBLE PRECISION,   -- The highest north-south resolution of the registered raster3d maps
-  ewres_min DOUBLE PRECISION,   -- The lowest east-west resolution of the registered raster3d maps
-  ewres_max DOUBLE PRECISION,   -- The highest east-west resolution of the registered raster3d maps
-  tbres_min DOUBLE PRECISION,   -- The lowest top-bottom resolution of the registered raster3d maps
-  tbres_max DOUBLE PRECISION,   -- The highest top-bottom resolution of the registered raster3d maps
-  title VARCHAR,                -- Title of the space-time raster3d dataset
-  description VARCHAR,          -- Detailed description of the space-time raster3d dataset
+  id VARCHAR NOT NULL,          -- Id of the space time 3D raster dataset, this is the primary foreign key
+  raster3d_register VARCHAR,    -- The id of the table in which the 3D raster maps are registered for this dataset
+  number_of_maps INTEGER,       -- The number of registered 3D raster maps
+  max_min DOUBLE PRECISION,     -- The minimal maximum of the registered 3D raster maps
+  min_min DOUBLE PRECISION,     -- The minimal minimum of the registered 3D raster maps
+  max_max DOUBLE PRECISION,     -- The maximal maximum of the registered 3D raster maps
+  min_max DOUBLE PRECISION,     -- The maximal minimum of the registered 3D raster maps
+  nsres_min DOUBLE PRECISION,   -- The lowest north-south resolution of the registered 3D raster maps
+  nsres_max DOUBLE PRECISION,   -- The highest north-south resolution of the registered 3D raster maps
+  ewres_min DOUBLE PRECISION,   -- The lowest east-west resolution of the registered 3D raster maps
+  ewres_max DOUBLE PRECISION,   -- The highest east-west resolution of the registered 3D raster maps
+  tbres_min DOUBLE PRECISION,   -- The lowest top-bottom resolution of the registered 3D raster maps
+  tbres_max DOUBLE PRECISION,   -- The highest top-bottom resolution of the registered 3D raster maps
+  title VARCHAR,                -- Title of the space time 3D raster dataset
+  description VARCHAR,          -- Detailed description of the space time 3D raster dataset
+  command VARCHAR,              -- The command that was used to create the space time 3D raster dataset
   PRIMARY KEY (id),  
   FOREIGN KEY (id) REFERENCES  str3ds_base (id) ON DELETE CASCADE
 );
@@ -44,7 +45,7 @@
             A4.tbres_min, A4.tbres_max, 
 	    A4.min_min, A4.min_max,
 	    A4.max_min, A4.max_max,
-            A4.title, A4.description	
+            A4.title, A4.description, A4.command
 	    FROM str3ds_base A1, str3ds_absolute_time A2,  
             str3ds_spatial_extent A3, str3ds_metadata A4 WHERE A1.id = A2.id AND 
 	    A1.id = A3.id AND A1.id = A4.id;
@@ -65,7 +66,7 @@
             A4.tbres_min, A4.tbres_max, 
 	    A4.min_min, A4.min_max,
 	    A4.max_min, A4.max_max,
-            A4.title, A4.description	
+            A4.title, A4.description, A4.command
 	    FROM str3ds_base A1, str3ds_relative_time A2,  
             str3ds_spatial_extent A3, str3ds_metadata A4 WHERE A1.id = A2.id AND 
 	    A1.id = A3.id AND A1.id = A4.id;

Modified: grass/trunk/lib/temporal/SQL/strds_metadata_table.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/strds_metadata_table.sql	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/temporal/SQL/strds_metadata_table.sql	2013-04-12 00:05:17 UTC (rev 55711)
@@ -21,6 +21,7 @@
   ewres_max DOUBLE PRECISION,   -- The highest east-west resolution of the registered raster maps
   title VARCHAR,                -- Title of the space-time raster dataset
   description VARCHAR,          -- Detailed description of the space-time raster dataset
+  command VARCHAR,              -- The command that was used to create the space time raster dataset
   PRIMARY KEY (id),  
   FOREIGN KEY (id) REFERENCES  strds_base (id) ON DELETE CASCADE
 );
@@ -41,7 +42,7 @@
             A4.nsres_max, A4.ewres_max, 
 	    A4.min_min, A4.min_max,
 	    A4.max_min, A4.max_max,
-            A4.title, A4.description	
+            A4.title, A4.description, A4.command	
 	    FROM strds_base A1, strds_absolute_time A2,  
             strds_spatial_extent A3, strds_metadata A4 WHERE A1.id = A2.id AND 
 	    A1.id = A3.id AND A1.id = A4.id;
@@ -61,7 +62,7 @@
             A4.nsres_max, A4.ewres_max, 
 	    A4.min_min, A4.min_max,
 	    A4.max_min, A4.max_max,
-            A4.title, A4.description	
+            A4.title, A4.description, A4.command
 	    FROM strds_base A1, strds_relative_time A2,  
             strds_spatial_extent A3, strds_metadata A4 WHERE A1.id = A2.id AND 
 	    A1.id = A3.id AND A1.id = A4.id;

Modified: grass/trunk/lib/temporal/SQL/stvds_metadata_table.sql
===================================================================
--- grass/trunk/lib/temporal/SQL/stvds_metadata_table.sql	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/temporal/SQL/stvds_metadata_table.sql	2013-04-12 00:05:17 UTC (rev 55711)
@@ -8,11 +8,12 @@
 --PRAGMA foreign_keys = ON;
 
 CREATE TABLE  stvds_metadata (
-  id VARCHAR NOT NULL,                -- Name of the space-time vector dataset, this is the primary foreign key
-  vector_register VARCHAR,                    -- The id of the table in which the vector maps are registered for this dataset
-  number_of_maps INTEGER,          -- The number of registered vector maps
-  title VARCHAR,                              -- Title of the space-time vector dataset
-  description VARCHAR,                        -- Detailed description of the space-time vector dataset
+  id VARCHAR NOT NULL,    -- Name of the space-time vector dataset, this is the primary foreign key
+  vector_register VARCHAR,-- The id of the table in which the vector maps are registered for this dataset
+  number_of_maps INTEGER, -- The number of registered vector maps
+  title VARCHAR,          -- Title of the space-time vector dataset
+  description VARCHAR,    -- Detailed description of the space-time vector dataset
+  command VARCHAR,        -- The command that was used to create the space time vector dataset
   points INTEGER,         -- The number of points accumulated from all registered maps
   lines INTEGER,          -- The number of lines accumulated from all registered maps
   boundaries INTEGER,     -- The number of boundaries accumulated from all registered maps
@@ -42,7 +43,7 @@
 	    A3.north, A3.south, A3.east, A3.west, A3.proj,
 	    A4.vector_register,
 	    A4.number_of_maps, 
-            A4.title, A4.description, A4.points, A4.lines,
+            A4.title, A4.description, A4.command, A4.points, A4.lines,
             A4.boundaries, A4.centroids, A4.faces, A4.kernels,
             A4.primitives, A4.nodes, A4.areas, A4.islands,
             A4.holes, A4.volumes
@@ -61,7 +62,7 @@
 	    A3.north, A3.south, A3.east, A3.west, A3.proj,
 	    A4.vector_register,
 	    A4.number_of_maps, 
-            A4.title, A4.description, A4.points, A4.lines,
+            A4.title, A4.description, A4.command, A4.points, A4.lines,
             A4.boundaries, A4.centroids, A4.faces, A4.kernels,
             A4.primitives, A4.nodes, A4.areas, A4.islands,
             A4.holes, A4.volumes

Modified: grass/trunk/lib/temporal/lib/default_name.c
===================================================================
--- grass/trunk/lib/temporal/lib/default_name.c	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/lib/temporal/lib/default_name.c	2013-04-12 00:05:17 UTC (rev 55711)
@@ -66,7 +66,7 @@
 
 	connection.driverName = "sqlite";
 	connection.databaseName =
-	    "$GISDBASE/$LOCATION_NAME/PERMANENT/tgis.db";
+	    "$GISDBASE/$LOCATION_NAME/PERMANENT/tgis/sqlite.db";
 	tgis_set_connection(&connection);
     }
     else

Modified: grass/trunk/temporal/t.topology/t.topology.py
===================================================================
--- grass/trunk/temporal/t.topology/t.topology.py	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/temporal/t.topology/t.topology.py	2013-04-12 00:05:17 UTC (rev 55711)
@@ -94,16 +94,16 @@
         #      0123456789012345678901234567890
         print " | Temporal topology is: ...... invalid"
 
-    dict = sp.count_temporal_types(maps)
+    dict_ = sp.count_temporal_types(maps)
 
-    for key in dict.keys():
+    for key in dict_.keys():
         if key == "interval":
             #      0123456789012345678901234567890
-            print " | Number of intervals: ....... %s" % (dict[key])
+            print " | Number of intervals: ....... %s" % (dict_[key])
         if key == "point":
-            print " | Number of points: .......... %s" % (dict[key])
+            print " | Number of points: .......... %s" % (dict_[key])
         if key == "invalid":
-            print " | Invalid time stamps: ....... %s" % (dict[key])
+            print " | Invalid time stamps: ....... %s" % (dict_[key])
 
     #      0123456789012345678901234567890
     print " | Number of gaps: ............ %i" % sp.count_gaps(maps)
@@ -115,36 +115,37 @@
     print " | Granularity: ............... %s" % str(gran)
 
     print " +-------------------- Topological relations ---------------------------------+"
-    dict = sp.count_temporal_relations(maps)
+    dict_ = sp.count_temporal_relations(maps)
 
-    for key in dict.keys():
-        if key == "equivalent":
-            #      0123456789012345678901234567890
-            print " | Equivalent: ................ %s" % (dict[key])
-        if key == "during":
-            print " | During: .................... %s" % (dict[key])
-        if key == "contains":
-            print " | Contains: .................. %s" % (dict[key])
-        if key == "overlaps":
-            print " | Overlaps: .................. %s" % (dict[key])
-        if key == "overlapped":
-            print " | Overlapped: ................ %s" % (dict[key])
-        if key == "after":
-            print " | After: ..................... %s" % (dict[key])
-        if key == "before":
-            print " | Before: .................... %s" % (dict[key])
-        if key == "starts":
-            print " | Starts: .................... %s" % (dict[key])
-        if key == "finishes":
-            print " | Finishes: .................. %s" % (dict[key])
-        if key == "started":
-            print " | Started: ................... %s" % (dict[key])
-        if key == "finished":
-            print " | Finished: .................. %s" % (dict[key])
-        if key == "follows":
-            print " | Follows: ................... %s" % (dict[key])
-        if key == "precedes":
-            print " | Precedes: .................. %s" % (dict[key])
+    if dict_:
+        for key in dict_.keys():
+            if key == "equivalent":
+                #      0123456789012345678901234567890
+                print " | Equivalent: ................ %s" % (dict_[key])
+            if key == "during":
+                print " | During: .................... %s" % (dict_[key])
+            if key == "contains":
+                print " | Contains: .................. %s" % (dict_[key])
+            if key == "overlaps":
+                print " | Overlaps: .................. %s" % (dict_[key])
+            if key == "overlapped":
+                print " | Overlapped: ................ %s" % (dict_[key])
+            if key == "after":
+                print " | After: ..................... %s" % (dict_[key])
+            if key == "before":
+                print " | Before: .................... %s" % (dict_[key])
+            if key == "starts":
+                print " | Starts: .................... %s" % (dict_[key])
+            if key == "finishes":
+                print " | Finishes: .................. %s" % (dict_[key])
+            if key == "started":
+                print " | Started: ................... %s" % (dict_[key])
+            if key == "finished":
+                print " | Finished: .................. %s" % (dict_[key])
+            if key == "follows":
+                print " | Follows: ................... %s" % (dict_[key])
+            if key == "precedes":
+                print " | Precedes: .................. %s" % (dict_[key])
     print " +----------------------------------------------------------------------------+"
 
 if __name__ == "__main__":

Modified: grass/trunk/temporal/t.topology/test.t.topology.abstime.sh
===================================================================
--- grass/trunk/temporal/t.topology/test.t.topology.abstime.sh	2013-04-11 22:43:54 UTC (rev 55710)
+++ grass/trunk/temporal/t.topology/test.t.topology.abstime.sh	2013-04-12 00:05:17 UTC (rev 55711)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Tests the temporaly topology module of space time datasets 
+# Tests the temporal topology module of space time datasets 
 
 # We need to set a specific region in the
 # @preprocess step of this test. 
@@ -44,10 +44,10 @@
 
 cat > "${n3}" << EOF
 prec_1|2001-01-01|2001-04-01
-prec_2|2001-05-01|2001-07-01
+prec_2|2001-05-01|2001-10-01
 prec_3|2001-08-01|2001-10-01
 prec_4|2001-11-01|2002-01-01
-prec_5|2002-02-01|2002-04-01
+prec_5|2001-11-01|2002-04-01
 prec_6|2002-05-01|2002-07-01
 EOF
 



More information about the grass-commit mailing list