[GRASS-SVN] r52621 - in grass/trunk: lib/python/temporal temporal/t.create temporal/t.list temporal/t.rast.aggregate temporal/t.rast.aggregate.ds temporal/t.rast.gapfill temporal/t.remove temporal/t.support temporal/t.unregister temporal/t.vect.observe.strds temporal/t.vect.what.strds

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Aug 10 07:48:01 PDT 2012


Author: huhabla
Date: 2012-08-10 07:48:01 -0700 (Fri, 10 Aug 2012)
New Revision: 52621

Modified:
   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/base.py
   grass/trunk/lib/python/temporal/core.py
   grass/trunk/lib/python/temporal/extract.py
   grass/trunk/lib/python/temporal/mapcalc.py
   grass/trunk/lib/python/temporal/metadata.py
   grass/trunk/lib/python/temporal/space_time_datasets.py
   grass/trunk/lib/python/temporal/space_time_datasets_tools.py
   grass/trunk/lib/python/temporal/spatial_extent.py
   grass/trunk/lib/python/temporal/temporal_extent.py
   grass/trunk/lib/python/temporal/temporal_relationships.py
   grass/trunk/lib/python/temporal/univar_statistics.py
   grass/trunk/temporal/t.create/t.create.py
   grass/trunk/temporal/t.list/t.list.py
   grass/trunk/temporal/t.rast.aggregate.ds/t.rast.aggregate.ds.py
   grass/trunk/temporal/t.rast.aggregate/t.rast.aggregate.py
   grass/trunk/temporal/t.rast.gapfill/t.rast.gapfill.py
   grass/trunk/temporal/t.remove/t.remove.py
   grass/trunk/temporal/t.support/t.support.py
   grass/trunk/temporal/t.unregister/t.unregister.py
   grass/trunk/temporal/t.vect.observe.strds/t.vect.observe.strds.py
   grass/trunk/temporal/t.vect.what.strds/t.vect.what.strds.py
Log:
Major code review and application of pep8 coding standard.
Several doctests added to temporal base classes.


Modified: grass/trunk/lib/python/temporal/abstract_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_dataset.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/abstract_dataset.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -7,12 +7,18 @@
 
 Usage:
 
- at code
-import grass.temporal as tgis
+>>> import grass.temporal as tgis
+>>> ad = abstract_dataset()
+>>> ad.reset(ident="soil at PERMANENT")
+Traceback (most recent call last):
+  File "/usr/lib/python2.7/doctest.py", line 1289, in __run
+    compileflags, 1) in test.globs
+  File "<doctest __main__[2]>", line 1, in <module>
+    ad.reset(ident="soil at PERMANENT")
+  File "abstract_dataset.py", line 53, in reset
+    raise ImplementationError("This method must be implemented in the subclasses")
+ImplementationError: 'This method must be implemented in the subclasses'
 
-...
- at endcode
-
 (C) 2008-2011 by the GRASS Development Team
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
@@ -26,74 +32,84 @@
 from spatial_extent import *
 from metadata import *
 
+
+class ImplementationError(Exception):
+    """!Exception raised for the calling of methods that should be implemented in
+       sub classes.
+    """
+    def __init__(self, msg):
+        self.msg = msg
+    def __str__(self):
+        return repr(self.msg)
+    
 class abstract_dataset(object):
     """!This is the base class for all datasets (raster, vector, raster3d, strds, stvds, str3ds)"""
 
     def reset(self, ident):
-	"""!Reset the internal structure and set the identifier
+        """!Reset the internal structure and set the identifier
 
            @param ident: The identifier of the dataset
         """
-	raise IOError("This method must be implemented in the subclasses")
+        raise ImplementationError("This method must be implemented in the subclasses")
 
     def get_type(self):
         """!Return the type of this class"""
-        raise IOError("This method must be implemented in the subclasses")
-    
+        raise ImplementationError("This method must be implemented in the subclasses")
+
     def get_new_instance(self, ident):
         """!Return a new instance with the type of this class
 
            @param ident: The identifier of the dataset
         """
-        raise IOError("This method must be implemented in the subclasses")
+        raise ImplementationError("This method must be implemented in the subclasses")
 
     def spatial_overlapping(self, dataset):
         """!Return True if the spatial extents are overlapping"""
 
-        raise IOError("This method must be implemented in the subclasses")
+        raise ImplementationError("This method must be implemented in the subclasses")
 
     def spatial_relation(self, dataset):
         """Return the spatial relationship between self and dataset"""
 
-        raise IOError("This method must be implemented in the subclasses")
-    
+        raise ImplementationError("This method must be implemented in the subclasses")
+
     def print_info(self):
         """!Print information about this class in human readable style"""
-	raise IOError("This method must be implemented in the subclasses")
-        
+        raise ImplementationError("This method must be implemented in the subclasses")
+
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-	raise IOError("This method must be implemented in the subclasses")
- 
+        raise ImplementationError("This method must be implemented in the subclasses")
+
     def print_self(self):
-	"""!Print the content of the internal structure to stdout"""
-	self.base.print_self()
-	if self.is_time_absolute():
-	    self.absolute_time.print_self()
+        """!Print the content of the internal structure to stdout"""
+        self.base.print_self()
+        if self.is_time_absolute():
+            self.absolute_time.print_self()
         if self.is_time_relative():
-	    self.relative_time.print_self()
-	self.spatial_extent.print_self()
-	self.metadata.print_self()
-	
+            self.relative_time.print_self()
+        self.spatial_extent.print_self()
+        self.metadata.print_self()
+
     def set_id(self, ident):
-	self.base.set_id(ident)
-	if self.is_time_absolute():
-	    self.absolute_time.set_id(ident)
+        self.base.set_id(ident)
+        if self.is_time_absolute():
+            self.absolute_time.set_id(ident)
         if self.is_time_relative():
-	    self.relative_time.set_id(ident)
-	self.spatial_extent.set_id(ident)
-	self.metadata.set_id(ident)
+            self.relative_time.set_id(ident)
+        self.spatial_extent.set_id(ident)
+        self.metadata.set_id(ident)
 
     def get_id(self):
-	"""!Return the unique identifier of the dataset"""
+        """!Return the unique identifier of the dataset"""
         return self.base.get_id()
 
     def get_name(self):
-	"""!Return the name"""
+        """!Return the name"""
         return self.base.get_name()
 
     def get_mapset(self):
-	"""!Return the mapset"""
+        """!Return the mapset"""
         return self.base.get_mapset()
 
     def get_valid_time(self):
@@ -103,27 +119,27 @@
 
         start = None
         end = None
-               
-	if self.is_time_absolute():
+
+        if self.is_time_absolute():
             start = self.absolute_time.get_start_time()
             end = self.absolute_time.get_end_time()
         if self.is_time_relative():
             start = self.relative_time.get_start_time()
             end = self.relative_time.get_end_time()
-        
+
         return (start, end)
- 
+
     def get_absolute_time(self):
         """!Returns a tuple of the start, the end valid time and the timezone of the map
            @return A tuple of (start_time, end_time, timezone)
         """
-               
+
         start = self.absolute_time.get_start_time()
         end = self.absolute_time.get_end_time()
         tz = self.absolute_time.get_timezone()
-        
+
         return (start, end, tz)
-    
+
     def get_relative_time(self):
         """!Returns the relative time interval (start_time, end_time, unit) or None if not present"""
 
@@ -132,7 +148,7 @@
         unit = self.relative_time.get_unit()
 
         return (start, end, unit)
- 
+
     def get_relative_time_unit(self):
         """!Returns the relative time unit or None if not present"""
 
@@ -142,57 +158,49 @@
 
     def check_relative_time_unit(self, unit):
         """!Check if unit is of type  years, months, days, hours, minutes or seconds
-        
-           Return True if success or False otherwise 
+
+           Return True if success or False otherwise
         """
         # Check unit
-        units = ["years","months","days","hours","minutes","seconds"]
+        units = ["years", "months", "days", "hours", "minutes", "seconds"]
         if unit not in units:
             return False
         return True
- 
+
     def get_temporal_type(self):
         """!Return the temporal type of this dataset"""
         return self.base.get_ttype()
-    
+
     def get_spatial_extent(self):
         """!Return a tuple of spatial extent (north, south, east, west, top, bottom) """
-        
-        north = self.spatial_extent.get_north()
-        south = self.spatial_extent.get_south()
-        east = self.spatial_extent.get_east()
-        west = self.spatial_extent.get_west()
-        top = self.spatial_extent.get_top()
-        bottom = self.spatial_extent.get_bottom()
-        
-        return (north, south, east, west, top, bottom)
-    
+        return self.spatial_extent.get_spatial_extent()
+
     def select(self, dbif=None):
-	"""!Select temporal dataset entry from database and fill up the internal structure"""
+        """!Select temporal dataset entry from database and fill up the internal structure"""
 
         dbif, connect = init_dbif(dbif)
 
-	self.base.select(dbif)
-	if self.is_time_absolute():
-	    self.absolute_time.select(dbif)
+        self.base.select(dbif)
+        if self.is_time_absolute():
+            self.absolute_time.select(dbif)
         if self.is_time_relative():
-	    self.relative_time.select(dbif)
-	self.spatial_extent.select(dbif)
-	self.metadata.select(dbif)
+            self.relative_time.select(dbif)
+        self.spatial_extent.select(dbif)
+        self.metadata.select(dbif)
 
         if connect:
             dbif.close()
 
     def is_in_db(self, dbif=None):
         """!Check if the temporal dataset entry is in the database
-        
+
            @param dbif: The database interface to be used
         """
         return self.base.is_in_db(dbif)
 
     def delete(self):
-	"""!Delete temporal dataset entry from database if it exists"""
-        raise IOError("This method must be implemented in the subclasses")
+        """!Delete temporal dataset entry from database if it exists"""
+        raise ImplementationError("This method must be implemented in the subclasses")
 
     def insert(self, dbif=None, execute=True):
         """!Insert temporal dataset entry into database from the internal structure
@@ -204,20 +212,22 @@
         """
 
         dbif, connect = init_dbif(dbif)
-        
+
         # Build the INSERT SQL statement
         statement = self.base.get_insert_statement_mogrified(dbif)
         if self.is_time_absolute():
-            statement += self.absolute_time.get_insert_statement_mogrified(dbif)
+            statement += self.absolute_time.get_insert_statement_mogrified(
+                dbif)
         if self.is_time_relative():
-            statement += self.relative_time.get_insert_statement_mogrified(dbif)
+            statement += self.relative_time.get_insert_statement_mogrified(
+                dbif)
         statement += self.spatial_extent.get_insert_statement_mogrified(dbif)
         statement += self.metadata.get_insert_statement_mogrified(dbif)
 
         if execute == True:
             dbif.execute_transaction(statement)
-	    if connect:
-		dbif.close()
+            if connect:
+                dbif.close()
             return ""
 
         if connect:
@@ -225,59 +235,64 @@
         return statement
 
     def update(self, dbif=None, execute=True):
-	"""!Update temporal dataset entry of database from the internal structure
-	   excluding None variables
+        """!Update temporal dataset entry of database from the internal structure
+           excluding None variables
 
            @param dbif: The database interface to be used
            @param execute: If True the SQL statements will be executed.
                            If False the prepared SQL statements are returned and must be executed by the caller.
-	"""
+        """
 
         dbif, connect = init_dbif(dbif)
-        
+
         # Build the UPDATE SQL statement
         statement = self.base.get_update_statement_mogrified(dbif)
-	if self.is_time_absolute():
-            statement += self.absolute_time.get_update_statement_mogrified(dbif)
+        if self.is_time_absolute():
+            statement += self.absolute_time.get_update_statement_mogrified(
+                dbif)
         if self.is_time_relative():
-            statement += self.relative_time.get_update_statement_mogrified(dbif)
+            statement += self.relative_time.get_update_statement_mogrified(
+                dbif)
         statement += self.spatial_extent.get_update_statement_mogrified(dbif)
         statement += self.metadata.get_update_statement_mogrified(dbif)
 
         if execute == True:
             dbif.execute_transaction(statement)
-	    if connect:
-		dbif.close()
+            if connect:
+                dbif.close()
             return ""
 
         if connect:
             dbif.close()
         return statement
- 
+
     def update_all(self, dbif=None, execute=True):
-	"""!Update temporal dataset entry of database from the internal structure
-	   and include None varuables.
+        """!Update temporal dataset entry of database from the internal structure
+           and include None variables.
 
            @param dbif: The database interface to be used
            @param execute: If True the SQL statements will be executed.
                            If False the prepared SQL statements are returned and must be executed by the caller.
-	"""
+        """
 
         dbif, connect = init_dbif(dbif)
-        
+
         # Build the UPDATE SQL statement
         statement = self.base.get_update_all_statement_mogrified(dbif)
-	if self.is_time_absolute():
-            statement += self.absolute_time.get_update_all_statement_mogrified(dbif)
+        if self.is_time_absolute():
+            statement += self.absolute_time.get_update_all_statement_mogrified(
+                dbif)
         if self.is_time_relative():
-            statement += self.relative_time.get_update_all_statement_mogrified(dbif)
-        statement += self.spatial_extent.get_update_all_statement_mogrified(dbif)
+            statement += self.relative_time.get_update_all_statement_mogrified(
+                dbif)
+        statement += self.spatial_extent.get_update_all_statement_mogrified(
+            dbif)
         statement += self.metadata.get_update_all_statement_mogrified(dbif)
 
         if execute == True:
             dbif.execute_transaction(statement)
-	    if connect:
-		dbif.close()
+            if connect:
+                dbif.close()
             return ""
 
         if connect:
@@ -285,107 +300,33 @@
         return statement
 
     def set_time_to_absolute(self):
-	self.base.set_ttype("absolute")
+        self.base.set_ttype("absolute")
 
     def set_time_to_relative(self):
         self.base.set_ttype("relative")
 
     def is_time_absolute(self):
-	if self.base.D.has_key("temporal_type"):
-	    return self.base.get_ttype() == "absolute"
+        if "temporal_type" in self.base.D:
+            return self.base.get_ttype() == "absolute"
         else:
-	    return None
+            return None
 
     def is_time_relative(self):
-	if self.base.D.has_key("temporal_type"):
-	    return self.base.get_ttype() == "relative"
+        if "temporal_type" in self.base.D:
+            return self.base.get_ttype() == "relative"
         else:
-	    return None
+            return None
 
     def temporal_relation(self, map):
-	"""!Return the temporal relation of this and the provided temporal map"""
-	if self.is_time_absolute() and map.is_time_absolute():
-	    return self.absolute_time.temporal_relation(map.absolute_time)
+        """!Return the temporal relation of this and the provided temporal map"""
+        if self.is_time_absolute() and map.is_time_absolute():
+            return self.absolute_time.temporal_relation(map.absolute_time)
         if self.is_time_relative() and map.is_time_relative():
-	    return self.relative_time.temporal_relation(map.relative_time)
-    	return None
+            return self.relative_time.temporal_relation(map.relative_time)
+        return None
 
 ###############################################################################
-	
-class abstract_dataset_comparison_key_start_time(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=abstract_dataset_comparison_key_start_time)
-    """
-    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 abstract_dataset_comparison_key_end_time(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=abstract_dataset_comparison_key_end_time)
-    """
-    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
\ No newline at end of file
+
+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	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/abstract_map_dataset.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -23,14 +23,15 @@
 from abstract_dataset import *
 from datetime_math import *
 
-class temporal_map_relations(abstract_dataset):
+
+class TemporalMapRelations(abstract_dataset):
     """!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
@@ -39,322 +40,355 @@
        * 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
+
+           # Print all maps this map temporally contains
            dlist = start.get_contains()
            for _map in dlist:
                _map.print_info()
-               
-           start = start.next()       
+
+           start = start.next()
     """
 
     def __init__(self):
         self.reset_temporal_topology()
-        
+
     def reset_temporal_topology(self):
-	"""!Reset any information about temporal topology"""
+        """!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
-	
+        """!Same as name"""
+        self._has_temporal_topology = True
+
     def set_temporal_topology_build_false(self):
-	"""!Same as name"""
-	self._has_temporal_topology = False
+        """!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
+        """!Check if the temporal topology was build"""
+        return self._has_temporal_topology
 
-    def set_next(self, _map):
-	"""!Set the map that is temporally as closest located after this map.
-	
-	   Temporally located means that the start time of the "next" map is 
-	   temporally located AFTER the start time of this map, but temporally 
-	   near than other maps of the same dataset.
-	   
-	   @param _map: This object should be of type abstract_map_dataset or derived classes
-	"""
+    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 abstract_map_dataset or derived classes
+        """
         self._temporal_topology["NEXT"] = _map
 
-    def set_prev(self, _map):
-	"""!Set the map that is temporally as closest located before this map.
-	
-	   Temporally located means that the start time of the "previous" map is 
-	   temporally located BEFORE the start time of this map, but temporally 
-	   near than other maps of the same dataset.
-	   
-	   @param _map: This object should be of type abstract_map_dataset or derived classes
-	"""
+    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 abstract_map_dataset or derived classes
+        """
         self._temporal_topology["PREV"] = _map
 
-    def next(self):
-	"""!Return the map with a start time temporally located after
-	   the start time of this map, but temporal closer than other maps
-	   
-	   @return A map object or None
-	"""
-        if not self._temporal_topology.has_key("NEXT"):
+    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 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 not self._temporal_topology.has_key("PREV"):
+    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_equivalent(self, _map): 
-	"""!Append a map with equivalent temporal extent as this map
-	
-	   @param _map: This object should be of type abstract_map_dataset or derived classes
-	"""
-        if not self._temporal_topology.has_key("EQUAL"):
+    def append_temporal_equivalent(self, _map):
+        """!Append a map with equivalent temporal extent as this map
+
+           @param _map: This object should be of type abstract_map_dataset or derived classes
+        """
+        if "EQUAL" not in self._temporal_topology:
             self._temporal_topology["EQUAL"] = []
         self._temporal_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 not self._temporal_topology.has_key("EQUAL"):
+    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_overlaps(self, _map): 
-	"""!Append a map that this map temporally overlaps
-	
-	   @param _map: This object should be of type abstract_map_dataset or derived classes
-	"""
-        if not self._temporal_topology.has_key("OVERLAPS"):
+    def append_temporal_overlaps(self, _map):
+        """!Append a map that this map temporally overlaps
+
+           @param _map: This object should be of type abstract_map_dataset or derived classes
+        """
+        if "OVERLAPS" not in self._temporal_topology:
             self._temporal_topology["OVERLAPS"] = []
         self._temporal_topology["OVERLAPS"].append(_map)
 
-    def get_overlaps(self): 
-	"""!Return a list of map objects that this map temporally overlaps
-	
-	   @return A list of map objects or None
-	"""
-        if not self._temporal_topology.has_key("OVERLAPS"):
+    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_overlapped(self, _map): 
-	"""!Append a map that this map temporally overlapped
-	
-	   @param _map: This object should be of type abstract_map_dataset or derived classes
-	""" 
-        if not self._temporal_topology.has_key("OVERLAPPED"):
+    def append_temporal_overlapped(self, _map):
+        """!Append a map that this map temporally overlapped
+
+           @param _map: This object should be of type abstract_map_dataset or derived classes
+        """
+        if "OVERLAPPED" not in self._temporal_topology:
             self._temporal_topology["OVERLAPPED"] = []
         self._temporal_topology["OVERLAPPED"].append(_map)
 
-    def get_overlapped(self): 
-	"""!Return a list of map objects that this map temporally overlapped
-	
-	   @return A list of map objects or None
-	"""
-        if not self._temporal_topology.has_key("OVERLAPPED"):
+    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_follows(self, _map): 
-	"""!Append a map that this map temporally follows
-	
-	   @param _map: This object should be of type abstract_map_dataset or derived classes
-	""" 
-        if not self._temporal_topology.has_key("FOLLOWS"):
+
+    def append_temporal_follows(self, _map):
+        """!Append a map that this map temporally follows
+
+           @param _map: This object should be of type abstract_map_dataset or derived classes
+        """
+        if "FOLLOWS" not in self._temporal_topology:
             self._temporal_topology["FOLLOWS"] = []
         self._temporal_topology["FOLLOWS"].append(_map)
 
-    def get_follows(self): 
-	"""!Return a list of map objects that this map temporally follows
-	
-	   @return A list of map objects or None
-	"""
-        if not self._temporal_topology.has_key("FOLLOWS"):
+    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_precedes(self, _map): 
-	"""!Append a map that this map temporally precedes
-	
-	   @param _map: This object should be of type abstract_map_dataset or derived classes
-	""" 
-        if not self._temporal_topology.has_key("PRECEDES"):
+
+    def append_temporal_precedes(self, _map):
+        """!Append a map that this map temporally precedes
+
+           @param _map: This object should be of type abstract_map_dataset or derived classes
+        """
+        if "PRECEDES" not in self._temporal_topology:
             self._temporal_topology["PRECEDES"] = []
         self._temporal_topology["PRECEDES"].append(_map)
 
-    def get_precedes(self): 
-	"""!Return a list of map objects that this map temporally precedes
-	
-	   @return A list of map objects or None
-	"""
-        if not self._temporal_topology.has_key("PRECEDES"):
+    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_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 abstract_map_dataset or derived classes
-	""" 
-        if not self._temporal_topology.has_key("DURING"):
+
+    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 abstract_map_dataset or derived classes
+        """
+        if "DURING" not in self._temporal_topology:
             self._temporal_topology["DURING"] = []
         self._temporal_topology["DURING"].append(_map)
 
-    def get_during(self): 
-	"""!Return a list of map objects that this map is temporally located during
-	   This includes temporally relationships starts and finishes
-	
-	   @return A list of map objects or None
-	"""
-        if not self._temporal_topology.has_key("DURING"):
+    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_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 abstract_map_dataset or derived classes
-	""" 
-        if not self._temporal_topology.has_key("CONTAINS"):
+
+    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 abstract_map_dataset or derived classes
+        """
+        if "CONTAINS" not in self._temporal_topology:
             self._temporal_topology["CONTAINS"] = []
         self._temporal_topology["CONTAINS"].append(_map)
 
-    def get_contains(self): 
-	"""!Return a list of map objects that this map temporally contains
-	   This includes temporal relationships started and finished
-	
-	   @return A list of map objects or None
-	"""
-        if not self._temporal_topology.has_key("CONTAINS"):
+    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
-                
+    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 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()
-        
+        """!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:
-	    print " | Next: ...................... " + str(_next.get_id())
+            print " | Next: ...................... " + str(_next.get_id())
         if _prev:
-	    print " | Previous: .................. " + str(_prev.get_id())
+            print " | Previous: .................. " + str(_prev.get_id())
         if _equal:
-	    print " | Equivalent: ................ " + self._generate_map_list_string(_equal)
+            print " | Equivalent: ................ " + \
+                self._generate_map_list_string(_equal)
         if _follows:
-	    print " | Follows: ................... " + self._generate_map_list_string(_follows)
+            print " | Follows: ................... " + \
+                self._generate_map_list_string(_follows)
         if _precedes:
-	    print " | Precedes: .................. " + self._generate_map_list_string(_precedes)
+            print " | Precedes: .................. " + \
+                self._generate_map_list_string(_precedes)
         if _overlaps:
-	    print " | Overlaps: .................. " + self._generate_map_list_string(_overlaps)
+            print " | Overlaps: .................. " + \
+                self._generate_map_list_string(_overlaps)
         if _overlapped:
-	    print " | Overlapped: ................ " + self._generate_map_list_string(_overlapped)
+            print " | Overlapped: ................ " + \
+                self._generate_map_list_string(_overlapped)
         if _during:
-	    print " | During: .................... " + self._generate_map_list_string(_during)
+            print " | During: .................... " + \
+                self._generate_map_list_string(_during)
         if _contains:
-	    print " | Contains: .................. " + self._generate_map_list_string(_contains)
-         
+            print " | Contains: .................. " + \
+                self._generate_map_list_string(_contains)
+
     def print_temporal_topology_shell_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()
-        
+        """!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:
-	    print "next=" + _next.get_id()
+            print "next=" + _next.get_id()
         if _prev:
-	    print "prev=" + _prev.get_id()
+            print "prev=" + _prev.get_id()
         if _equal:
-	    print "equivalent=" +self._generate_map_list_string(_equal, False)
+            print "equivalent=" + self._generate_map_list_string(_equal, False)
         if _follows:
-	    print "follows=" +self._generate_map_list_string(_follows, False)
+            print "follows=" + self._generate_map_list_string(_follows, False)
         if _precedes:
-	    print "precedes=" +self._generate_map_list_string(_precedes, False)
+            print "precedes=" + self._generate_map_list_string(
+                _precedes, False)
         if _overlaps:
-	    print "overlaps=" +self._generate_map_list_string(_overlaps, False)
+            print "overlaps=" + self._generate_map_list_string(
+                _overlaps, False)
         if _overlapped:
-	    print "overlapped=" +self._generate_map_list_string(_overlapped, False)
+            print "overlapped=" + \
+                self._generate_map_list_string(_overlapped, False)
         if _during:
-	    print "during=" +self._generate_map_list_string(_during, False)
+            print "during=" + self._generate_map_list_string(_during, False)
         if _contains:
-	    print "contains=" +self._generate_map_list_string(_contains, False)
-                
+            print "contains=" + self._generate_map_list_string(
+                _contains, False)
+
 ###############################################################################
 
-class abstract_map_dataset(temporal_map_relations):
-    """!This is the base class for all maps (raster, vector, raster3d) 
+
+class abstract_map_dataset(TemporalMapRelations):
+    """!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):
-	temporal_map_relations.__init__(self)
-	
+        TemporalMapRelations.__init__(self)
+
     def get_new_stds_instance(self, ident):
-        """!Return a new space time dataset instance in which maps are stored with the type of this class
+        """!Return a new space time dataset instance in which maps
+           are stored with the type of this class
 
            @param ident: The identifier of the dataset
         """
-        raise IOError("This method must be implemented in the subclasses")
-    
+        raise ImplementationError(
+            "This method must be implemented in the subclasses")
+
     def get_stds_register(self):
-        """!Return the space time dataset register table name in which stds are listed in which this map is registered"""
-        raise IOError("This method must be implemented in the subclasses")
+        """!Return the space time dataset register table name in which stds
+           are listed in which this map is registered"""
+        raise ImplementationError(
+            "This method must be implemented in the subclasses")
 
     def set_stds_register(self, name):
         """!Set the space time dataset register table name.
-        
+
            This table stores all space time datasets in which this map is registered.
 
            @param ident: The name of the register table
         """
-        raise IOError("This method must be implemented in the subclasses")
- 
+        raise ImplementationError(
+            "This method must be implemented in the subclasses")
+
     def check_resolution_with_current_region(self):
         """!Check if the raster or voxel resolution is finer than the current resolution
            Return "finer" in case the raster/voxel resolution is finer than the current region
@@ -362,104 +396,111 @@
 
            Vector maps are alwyas finer than the current region
         """
-        raise IOError("This method must be implemented in the subclasses")
-	
+        raise ImplementationError(
+            "This method must be implemented in the subclasses")
+
     def has_grass_timestamp(self):
-        """!Check if a grass file bsased time stamp exists for this map. 
+        """!Check if a grass file bsased time stamp exists for this map.
         """
-        raise IOError("This method must be implemented in the subclasses")
-    
+        raise ImplementationError(
+            "This method must be implemented in the subclasses")
+
     def write_timestamp_to_grass(self):
         """!Write the timestamp of this map into the map metadata in the grass file system based spatial
-           database. 
+           database.
         """
-        raise IOError("This method must be implemented in the subclasses")
-    
+        raise ImplementationError(
+            "This method must be implemented in the subclasses")
+
     def remove_timestamp_from_grass(self):
         """!Remove the timestamp from the grass file system based spatial database
         """
-        raise IOError("This method must be implemented in the subclasses")
-	
+        raise ImplementationError(
+            "This method must be implemented in the subclasses")
+
     def map_exists(self):
         """!Return True in case the map exists in the grass spatial database
-        
+
            @return True if map exists, False otherwise
-        """        
-        raise IOError("This method must be implemented in the subclasses")
-	        
+        """
+        raise ImplementationError(
+            "This method must be implemented in the subclasses")
+
     def read_info(self):
-        """!Read the map info from the grass file system based database and store the content 
+        """!Read the map info from the grass file system based database and store the content
            into a dictionary
         """
-        raise IOError("This method must be implemented in the subclasses")
+        raise ImplementationError(
+            "This method must be implemented in the subclasses")
 
     def load(self):
         """!Load the content of this object from the grass file system based database"""
-        raise IOError("This method must be implemented in the subclasses")
-	
+        raise ImplementationError(
+            "This method must be implemented in the subclasses")
+
     def _convert_timestamp(self):
-	"""!Convert the valid time into a grass datetime library compatible timestamp string
-	    
-	    This methods works for reltaive and absolute time
-	    
-	    @return the grass timestamp string
-	"""
-	start = ""
-        
+        """!Convert the valid time into a grass datetime library compatible timestamp string
+
+            This methods works for reltaive and absolute time
+
+            @return the grass timestamp string
+        """
+        start = ""
+
         if self.is_time_absolute():
-	    start_time, end_time, tz = self.get_absolute_time()
-	    start = datetime_to_grass_datetime_string(start_time)
-	    if end_time:
-		end = datetime_to_grass_datetime_string(end_time)
-		start += " / %s"%(end)
-	else:
-	    start_time, end_time, unit = self.get_relative_time()
-	    start = "%i %s"%(int(start_time), unit)
-	    if end_time != None:
-		end = "%i %s"%(int(end_time), unit)
-		start += " / %s"%(end)
+            start_time, end_time, tz = self.get_absolute_time()
+            start = datetime_to_grass_datetime_string(start_time)
+            if end_time:
+                end = datetime_to_grass_datetime_string(end_time)
+                start += " / %s" % (end)
+        else:
+            start_time, end_time, unit = self.get_relative_time()
+            start = "%i %s" % (int(start_time), unit)
+            if end_time is not None:
+                end = "%i %s" % (int(end_time), unit)
+                start += " / %s" % (end)
 
-	return start
-		        
+        return start
+
     def get_map_id(self):
-	"""!Return the map id. The map id is the unique map identifier in grass and must not be equal to the 
-	   primary key identifier (id) of the map in the database. Since vector maps may have layer information,
-	   the unique id is a combination of name, layer and mapset.
-	   
-	   Use get_map_id() every time your need to access the grass map in the file system but not to identify
-	   map information in the temporal database.
-	
-	"""
+        """!Return the map id. The map id is the unique map identifier in grass and must not be equal to the
+           primary key identifier (id) of the map in the database. Since vector maps may have layer information,
+           the unique id is a combination of name, layer and mapset.
+
+           Use get_map_id() every time your need to access the grass map in the file system but not to identify
+           map information in the temporal database.
+
+        """
         return self.base.get_map_id()
 
     def build_id(self, name, mapset, layer=None):
-	"""!Convenient method to build the unique identifier
-	
-	    Existing layer and mapset definitions in the name string will be reused
+        """!Convenient method to build the unique identifier
 
+            Existing layer and mapset definitions in the name string will be reused
+
            @param return the id of the vector map as name(:layer)@mapset while layer is optional
         """
-        
+
         # Check if the name includes any mapset
-	if name.find("@") >= 0:
-	    name, mapset = name.split("@")
+        if name.find("@") >= 0:
+            name, mapset = name.split("@")
 
         # Check for layer number in map name
-	if name.find(":") >= 0:
-	    name, layer = name.split(":")
-	    
-        if layer:	    
-	    return "%s:%s@%s"%(name, layer, mapset)
-	else:
-	    return "%s@%s"%(name, mapset)
-	    
+        if name.find(":") >= 0:
+            name, layer = name.split(":")
+
+        if layer:
+            return "%s:%s@%s" % (name, layer, mapset)
+        else:
+            return "%s@%s" % (name, mapset)
+
     def get_layer(self):
-	"""!Return the layer of the map or None in case no layer is defined"""
-	return self.base.get_layer()
-        
+        """!Return the layer of the map or None in case no layer is defined"""
+        return self.base.get_layer()
+
     def print_info(self):
         """!Print information about this class in human readable style"""
-        
+
         if self.get_type() == "raster":
             #                1         2         3         4         5         6         7
             #      0123456789012345678901234567890123456789012345678901234567890123456789012345678
@@ -476,13 +517,13 @@
             print ""
             print " +-------------------- Vector Dataset ----------------------------------------+"
         print " |                                                                            |"
-	self.base.print_info()
-	if self.is_time_absolute():
-	    self.absolute_time.print_info()
+        self.base.print_info()
+        if self.is_time_absolute():
+            self.absolute_time.print_info()
         if self.is_time_relative():
-	    self.relative_time.print_info()
-	self.spatial_extent.print_info()
-	self.metadata.print_info()
+            self.relative_time.print_info()
+        self.spatial_extent.print_info()
+        self.metadata.print_info()
         datasets = self.get_registered_datasets()
         count = 0
         string = ""
@@ -498,38 +539,38 @@
                 count += 1
         print " | Registered datasets ........ " + string
         if self.is_temporal_topology_build():
-	    self.print_temporal_topology_info()
+            self.print_temporal_topology_info()
         print " +----------------------------------------------------------------------------+"
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-	self.base.print_shell_info()
-	if self.is_time_absolute():
-	    self.absolute_time.print_shell_info()
+        self.base.print_shell_info()
+        if self.is_time_absolute():
+            self.absolute_time.print_shell_info()
         if self.is_time_relative():
-	    self.relative_time.print_shell_info()
-	self.spatial_extent.print_shell_info()
-	self.metadata.print_shell_info()
+            self.relative_time.print_shell_info()
+        self.spatial_extent.print_shell_info()
+        self.metadata.print_shell_info()
         datasets = self.get_registered_datasets()
         count = 0
         string = ""
         if datasets:
-	    for ds in datasets:
-		if count == 0:
-		    string += ds["id"]
-		else:
-		    string += ",%s" % ds["id"]
-		count += 1
-	    print "registered_datasets=" + string
+            for ds in datasets:
+                if count == 0:
+                    string += ds["id"]
+                else:
+                    string += ",%s" % ds["id"]
+                count += 1
+            print "registered_datasets=" + string
 
         if self.is_temporal_topology_build():
-	    self.print_temporal_topology_shell_info()
-	    
+            self.print_temporal_topology_shell_info()
+
     def insert(self, dbif=None, execute=True):
         """!Insert temporal dataset entry into database from the internal structure
 
-	   This functions assures that the timetsamp is written to the grass file system based database
-	    
+           This functions assures that the timetsamp is written to the grass file system based database
+
            @param dbif: The database interface to be used
            @param execute: If True the SQL statements will be executed.
                            If False the prepared SQL statements are returned and must be executed by the caller.
@@ -538,72 +579,72 @@
         return abstract_dataset.insert(self, dbif, execute)
 
     def update(self, dbif=None, execute=True):
-	"""!Update temporal dataset entry of database from the internal structure
-	   excluding None variables
-	   
-	   This functions assures that the timetsamp is written to the grass file system based database
+        """!Update temporal dataset entry of database from the internal structure
+           excluding None variables
 
+           This functions assures that the timetsamp is written to the grass file system based database
+
            @param dbif: The database interface to be used
            @param execute: If True the SQL statements will be executed.
                            If False the prepared SQL statements are returned and must be executed by the caller.
-	"""
+        """
         self.write_timestamp_to_grass()
         return abstract_dataset.update(self, dbif, execute)
 
     def update_all(self, dbif=None, execute=True):
-	"""!Update temporal dataset entry of database from the internal structure
-	   and include None varuables.
-	   
-	   This functions assures that the timetsamp is written to the grass file system based database
+        """!Update temporal dataset entry of database from the internal structure
+           and include None varuables.
 
+           This functions assures that the timetsamp is written to the grass file system based database
+
            @param dbif: The database interface to be used
            @param execute: If True the SQL statements will be executed.
                            If False the prepared SQL statements are returned and must be executed by the caller.
-	"""
+        """
         self.write_timestamp_to_grass()
         return abstract_dataset.update_all(self, dbif, execute)
-        
+
     def set_absolute_time(self, start_time, end_time=None, timezone=None):
         """!Set the absolute time interval with start time and end time
-        
+
            @param start_time: a datetime object specifying the start time of the map
            @param end_time: a datetime object specifying the end time of the map
            @param timezone: Thee timezone of the map
-        
+
         """
-        if start_time and not isinstance(start_time, datetime) :
-	    if self.get_layer():
-		core.fatal(_("Start time must be of type datetime for %s map <%s> with layer: %s") % (self.get_type(), self.get_map_id(), self.get_layer()))
-	    else:
-		core.fatal(_("Start time must be of type datetime for %s map <%s>") % (self.get_type(), self.get_map_id()))
+        if start_time and not isinstance(start_time, datetime):
+            if self.get_layer():
+                core.fatal(_("Start time must be of type datetime for %s map <%s> with layer: %s") % (self.get_type(), self.get_map_id(), self.get_layer()))
+            else:
+                core.fatal(_("Start time must be of type datetime for %s map <%s>") % (self.get_type(), self.get_map_id()))
 
-        if end_time and not isinstance(end_time, datetime) :
-	    if self.get_layer():
-		core.fatal(_("End time must be of type datetime for %s map <%s> with layer: %s") % (self.get_type(), self.get_map_id(), self.get_layer()))
-	    else:
-		core.fatal(_("End time must be of type datetime for %s map <%s>") % (self.get_type(), self.get_map_id()))
+        if end_time and not isinstance(end_time, datetime):
+            if self.get_layer():
+                core.fatal(_("End time must be of type datetime for %s map <%s> with layer: %s") % (self.get_type(), self.get_map_id(), self.get_layer()))
+            else:
+                core.fatal(_("End time must be of type datetime for %s map <%s>") % (self.get_type(), self.get_map_id()))
 
         if start_time and end_time:
             if start_time > end_time:
-		if self.get_layer():
-		    core.fatal(_("End time must be greater than start time for %s map <%s> with layer: %s") % (self.get_type(), self.get_map_id(), self.get_layer()))
-		else:
-		    core.fatal(_("End time must be greater than start time for %s map <%s>") % (self.get_type(), self.get_map_id()))
+                if self.get_layer():
+                    core.fatal(_("End time must be greater than start time for %s map <%s> with layer: %s") % (self.get_type(), self.get_map_id(), self.get_layer()))
+                else:
+                    core.fatal(_("End time must be greater than start time for %s map <%s>") % (self.get_type(), self.get_map_id()))
             else:
                 # Do not create an interval in case start and end time are equal
                 if start_time == end_time:
                     end_time = None
 
         self.base.set_ttype("absolute")
-        
+
         self.absolute_time.set_start_time(start_time)
         self.absolute_time.set_end_time(end_time)
         self.absolute_time.set_timezone(timezone)
 
-    def update_absolute_time(self, start_time, end_time=None, timezone=None, dbif = None):
+    def update_absolute_time(self, start_time, end_time=None, timezone=None, dbif=None):
         """!Update the absolute time
 
-	   This functions assures that the timetsamp is written to the grass file system based database
+           This functions assures that the timetsamp is written to the grass file system based database
 
            @param start_time: a datetime object specifying the start time of the map
            @param end_time: a datetime object specifying the end time of the map
@@ -619,12 +660,12 @@
             dbif.close()
 
         self.write_timestamp_to_grass()
-        
+
     def set_relative_time(self, start_time, end_time, unit):
-        """!Set the relative time interval 
-        
-           @param start_time: A double value 
-           @param end_time: A double value 
+        """!Set the relative time interval
+
+           @param start_time: A double value
+           @param end_time: A double value
            @param unit: The unit of the relative time. Supported units: years, months, days, hours, minutes, seconds
 
            Return True for success and False otherwise
@@ -632,19 +673,18 @@
         """
 
         if not self.check_relative_time_unit(unit):
-	    if self.get_layer():
-		core.error(_("Unsupported relative time unit type for %s map <%s> with layer %s: %s") % (self.get_type(), self.get_id(), self.get_layer(), unit))
-	    else:
-		core.error(_("Unsupported relative time unit type for %s map <%s>: %s") % (self.get_type(), self.get_id(), unit))
+            if self.get_layer():
+                core.error(_("Unsupported relative time unit type for %s map <%s> with layer %s: %s") % (self.get_type(), self.get_id(), self.get_layer(), unit))
+            else:
+                core.error(_("Unsupported relative time unit type for %s map <%s>: %s") % (self.get_type(), self.get_id(), unit))
             return False
-        
 
-        if start_time != None and end_time != None:
+        if start_time is not None and end_time is not None:
             if int(start_time) > int(end_time):
-		if self.get_layer():
-		    core.error(_("End time must be greater than start time for %s map <%s> with layer %s") % (self.get_type(), self.get_id(), self.get_layer()))
-		else:
-		    core.error(_("End time must be greater than start time for %s map <%s>") % (self.get_type(), self.get_id()))
+                if self.get_layer():
+                    core.error(_("End time must be greater than start time for %s map <%s> with layer %s") % (self.get_type(), self.get_id(), self.get_layer()))
+                else:
+                    core.error(_("End time must be greater than start time for %s map <%s>") % (self.get_type(), self.get_id()))
                 return False
             else:
                 # Do not create an interval in case start and end time are equal
@@ -652,23 +692,23 @@
                     end_time = None
 
         self.base.set_ttype("relative")
-        
+
         self.relative_time.set_unit(unit)
         self.relative_time.set_start_time(int(start_time))
-        if end_time != None:
+        if end_time is not None:
             self.relative_time.set_end_time(int(end_time))
         else:
             self.relative_time.set_end_time(None)
 
         return True
 
-    def update_relative_time(self, start_time, end_time, unit, dbif = None):
+    def update_relative_time(self, start_time, end_time, unit, dbif=None):
         """!Update the relative time interval
 
-	   This functions assures that the timetsamp is written to the grass file system based database
-	    
-           @param start_time: A double value 
-           @param end_time: A double value 
+           This functions assures that the timetsamp is written to the grass file system based database
+
+           @param start_time: A double value
+           @param end_time: A double value
            @param dbif: The database interface to be used
         """
         dbif, connect = init_dbif(dbif)
@@ -692,8 +732,9 @@
            @param top: The top edge
            @param bottom: The bottom edge
         """
-        self.spatial_extent.set_spatial_extent(north, south, east, west, top, bottom)
-        
+        self.spatial_extent.set_spatial_extent(
+            north, south, east, west, top, bottom)
+
     def check_valid_time(self):
         """!Check for correct valid time"""
         if self.is_time_absolute():
@@ -701,29 +742,30 @@
         else:
             start, end, unit = self.get_relative_time()
 
-        if start != None:
-            if end != None:
+        if start is not None:
+            if end is not None:
                 if start >= end:
-		    if self.get_layer():
-			core.error(_("Map <%s> with layer %s has incorrect time interval, start time is greater than end time") % (self.get_map_id(), self.get_layer()))
-		    else:
-			core.error(_("Map <%s> has incorrect time interval, start time is greater than end time") % (self.get_map_id()))
+                    if self.get_layer():
+                        core.error(_("Map <%s> with layer %s has incorrect time interval, start time is greater than end time") % (self.get_map_id(), self.get_layer()))
+                    else:
+                        core.error(_("Map <%s> has incorrect time interval, start time is greater than end time") % (self.get_map_id()))
                     return False
         else:
-            core.error(_("Map <%s> has incorrect start time") % (self.get_map_id()))
+            core.error(_("Map <%s> has incorrect start time") %
+                       (self.get_map_id()))
             return False
 
         return True
 
-    def delete(self, dbif=None, update=True, execute = True):
-	"""!Delete a map entry from database if it exists
-        
+    def delete(self, dbif=None, update=True, execute=True):
+        """!Delete a map entry from database if it exists
+
             Remove dependent entries:
             * Remove the map entry in each space time dataset in which this map is registered
             * Remove the space time dataset register table
-            
+
            @param dbif: The database interface to be used
-           @param update: Call for each unregister statement the update from registered maps 
+           @param update: Call for each unregister statement the update from registered maps
                           of the space time dataset. This can slow down the un-registration process significantly.
            @param execute: If True the SQL DELETE and DROP table statements will be executed.
                            If False the prepared SQL statements are returned and must be executed by the caller.
@@ -735,18 +777,20 @@
         statement = ""
 
         if self.is_in_db(dbif):
- 
+
             # SELECT all needed information from the database
             self.metadata.select(dbif)
 
             # First we unregister from all dependent space time datasets
-            statement += self.unregister(dbif=dbif, update=update, execute=False)
+            statement += self.unregister(
+                dbif=dbif, update=update, execute=False)
 
             # Remove the strds register table
             if self.get_stds_register():
                 statement += "DROP TABLE " + self.get_stds_register() + ";\n"
 
-            core.verbose(_("Delete %s dataset <%s> from temporal database") % (self.get_type(), self.get_id()))
+            core.verbose(_("Delete %s dataset <%s> from temporal database")
+                         % (self.get_type(), self.get_id()))
 
             # Delete yourself from the database, trigger functions will take care of dependencies
             statement += self.base.get_delete_statement()
@@ -756,22 +800,22 @@
 
         # Remove the timestamp from the file system
         self.remove_timestamp_from_grass()
-        
+
         self.reset(None)
 
         if connect == True:
             dbif.close()
- 
+
         if execute:
             return ""
 
         return statement
 
     def unregister(self, dbif=None, update=True, execute=True):
-	"""! Remove the map entry in each space time dataset in which this map is registered
+        """! Remove the map entry in each space time dataset in which this map is registered
 
            @param dbif: The database interface to be used
-           @param update: Call for each unregister statement the update from registered maps 
+           @param update: Call for each unregister statement the update from registered maps
                           of the space time dataset. This can slow down the un-registration process significantly.
            @param execute: If True the SQL DELETE and DROP table statements will be executed.
                            If False the prepared SQL statements are returned and must be executed by the caller.
@@ -779,15 +823,16 @@
            @return The SQL statements if execute == False, else an empty string
         """
 
-	if self.get_layer():
-	    core.verbose(_("Unregister %s map <%s> with layer %s from space time datasets") % \
-	                   (self.get_type(), self.get_map_id(), self.get_layer()))
-	else:
-	    core.verbose(_("Unregister %s map <%s> from space time datasets") % (self.get_type(), self.get_map_id()))
-        
+        if self.get_layer():
+            core.verbose(_("Unregister %s map <%s> with layer %s from space time datasets") %
+                         (self.get_type(), self.get_map_id(), self.get_layer()))
+        else:
+            core.verbose(_("Unregister %s map <%s> from space time datasets")
+                         % (self.get_type(), self.get_map_id()))
+
         statement = ""
         dbif, connect = init_dbif(dbif)
-        
+
         # Get all datasets in which this map is registered
         rows = self.get_registered_datasets(dbif)
 
@@ -809,7 +854,7 @@
                     stds.update_from_registered_maps(dbif)
 
             core.percent(1, 1, 1)
-            
+
         if execute == True:
             dbif.execute_transaction(statement)
 
@@ -820,7 +865,7 @@
             return ""
 
         return statement
-            
+
     def get_registered_datasets(self, dbif=None):
         """!Return all space time dataset ids in which this map is registered as
            dictionary like rows with column "id" or None if this map is not registered in any
@@ -833,7 +878,7 @@
         rows = None
 
         try:
-            if self.get_stds_register() != None:
+            if self.get_stds_register() is not None:
                 # Select all stds tables in which this map is registered
                 sql = "SELECT id FROM " + self.get_stds_register()
                 dbif.cursor.execute(sql)
@@ -843,6 +888,5 @@
 
         if connect == True:
             dbif.close()
-            
+
         return rows
-

Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -47,11 +47,11 @@
 
            @param ident: The unique identifier of the new object
         """
-        raise IOError("This method must be implemented in the subclasses")
+        raise ImplementationError("This method must be implemented in the subclasses")
 
     def get_map_register(self):
         """!Return the name of the map register table"""
-        raise IOError("This method must be implemented in the subclasses")
+        raise ImplementationError("This method must be implemented in the subclasses")
 
     def set_map_register(self, name):
         """!Set the name of the map register table
@@ -60,7 +60,7 @@
 
            @param name: The name of the register table
         """
-        raise IOError("This method must be implemented in the subclasses")
+        raise ImplementationError("This method must be implemented in the subclasses")
  
     def print_self(self):
 	"""!Print the content of the internal structure to stdout"""

Modified: grass/trunk/lib/python/temporal/base.py
===================================================================
--- grass/trunk/lib/python/temporal/base.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/base.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -11,13 +11,14 @@
 
 Usage:
 
- at code
-import grass.temporal as tgis
+>>> import grass.temporal as tgis
+>>> rbase = tgis.RasterBase(ident="soil at PERMANENT")
+>>> vbase = tgis.VectorBase(ident="soil:1 at PERMANENT")
+>>> r3base = tgis.Raster3DBase(ident="soil at PERMANENT")
+>>> strdsbase = tgis.STRDSBase(ident="soil at PERMANENT")
+>>> stvdsbase = tgis.STVDSBase(ident="soil at PERMANENT")
+>>> str3dsbase = tgis.STR3DSBase(ident="soil at PERMANENT")
 
-rbase = tgis.raster_base(ident="soil")
-...
- at endcode
-
 (C) 2008-2011 by the GRASS Development Team
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
@@ -26,168 +27,205 @@
 @author Soeren Gebbert
 """
 
+from datetime import datetime, date, time, timedelta
 from core import *
 
 ###############################################################################
 
-class dict_sql_serializer(object):
+
+class DictSQLSerializer(object):
     def __init__(self):
         self.D = {}
+
     def serialize(self, type, table, where=None):
-	"""!Convert the internal dictionary into a string of semicolon separated SQL statements
-	   The keys are the column names and the values are the row entries
+        """!Convert the internal dictionary into a string of semicolon separated SQL statements
+            The keys are the column names and the values are the row entries
+            
+            >>> import grass.temporal as tgis
+            >>> from datetime import datetime, date, time, timedelta
+            >>> t = tgis.DictSQLSerializer()
+            >>> t.D["id"] = "soil at PERMANENT"
+            >>> t.D["name"] = "soil"
+            >>> t.D["mapset"] = "PERMANENT"
+            >>> t.D["creator"] = "soeren"
+            >>> t.D["creation_time"] = datetime(2001,1,1)
+            >>> t.D["modification_time"] = datetime(2001,1,1)
+            >>> t.serialize(type="SELECT", table="raster_base")
+            ('SELECT  name  , creator  , creation_time  , modification_time  , mapset  , id  FROM raster_base ;\\n', ())
+            >>> t.serialize(type="INSERT", table="raster_base")
+            ('INSERT INTO raster_base ( name  ,creator  ,creation_time  ,modification_time  ,mapset  ,id ) VALUES (? ,? ,? ,? ,? ,?) ;\\n', ('soil', 'soeren', datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil at PERMANENT'))
+            >>> t.serialize(type="UPDATE", table="raster_base")
+            ('UPDATE raster_base SET  name = ?  ,creator = ?  ,creation_time = ?  ,modification_time = ?  ,mapset = ?  ,id = ? ;\\n', ('soil', 'soeren', datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil at PERMANENT'))
+            >>> t.serialize(type="UPDATE ALL", table="raster_base")
+            ('UPDATE raster_base SET  name = ?  ,creator = ?  ,creation_time = ?  ,modification_time = ?  ,mapset = ?  ,id = ? ;\\n', ('soil', 'soeren', datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil at PERMANENT'))
+            
+            @type must be SELECT. INSERT, UPDATE
+            @table The name of the table to select, insert or update
+            @where The optional where statement
+            @return a tuple containing the SQL string and the arguments
+        """
 
-	   @param type must be SELECT. INSERT, UPDATE
-	   @param table The name of the table to select, insert or update
-	   @param where The optional where statement
-	   @return the sql string
-	"""
+        sql = ""
+        args = []
 
-	sql = ""
-	args = []
-
-	# Create ordered select statement
-	if type == "SELECT":
-	    sql += 'SELECT '
-	    count = 0
+        # Create ordered select statement
+        if type == "SELECT":
+            sql += 'SELECT '
+            count = 0
             for key in self.D.keys():
-		if count == 0:
+                if count == 0:
                     sql += ' %s ' % key
-		else:
+                else:
                     sql += ' , %s ' % key
-		count += 1
+                count += 1
             sql += ' FROM ' + table + ' '
-	    if where:
-	        sql += where
+            if where:
+                sql += where
             sql += ";\n"
 
-	# Create insert statement
-	if type =="INSERT":
-	    count = 0
-	    sql += 'INSERT INTO ' + table + ' ('
+        # Create insert statement
+        if type == "INSERT":
+            count = 0
+            sql += 'INSERT INTO ' + table + ' ('
             for key in self.D.keys():
-		if count == 0:
+                if count == 0:
                     sql += ' %s ' % key
-		else:
+                else:
                     sql += ' ,%s ' % key
-		count += 1
+                count += 1
 
-	    count = 0
-	    sql += ') VALUES ('
+            count = 0
+            sql += ') VALUES ('
             for key in self.D.keys():
-		if count == 0:
-		    if dbmi.paramstyle == "qmark":
-			sql += '?'
-		    else:
-			sql += '%s'
-		else:
-		    if dbmi.paramstyle == "qmark":
-			sql += ' ,?'
-		    else:
-			sql += ' ,%s'
-		count += 1
-		args.append(self.D[key])
-	    sql += ') '
+                if count == 0:
+                    if dbmi.paramstyle == "qmark":
+                        sql += '?'
+                    else:
+                        sql += '%s'
+                else:
+                    if dbmi.paramstyle == "qmark":
+                        sql += ' ,?'
+                    else:
+                        sql += ' ,%s'
+                count += 1
+                args.append(self.D[key])
+            sql += ') '
 
-	    if where:
-	        sql += where
+            if where:
+                sql += where
             sql += ";\n"
 
-	# Create update statement for existing entries
-	if type =="UPDATE":
-	    count = 0
-	    sql += 'UPDATE ' + table + ' SET '
+        # Create update statement for existing entries
+        if type == "UPDATE":
+            count = 0
+            sql += 'UPDATE ' + table + ' SET '
             for key in self.D.keys():
-		# Update only entries which are not None
-		if self.D[key] != None:
-		    if count == 0:
-			if dbmi.paramstyle == "qmark":
-			    sql += ' %s = ? ' % key
-			else:
-			    sql += ' %s ' % key
-			    sql += '= %s '
-		    else:
-			if dbmi.paramstyle == "qmark":
-			    sql += ' ,%s = ? ' % key
-			else:
-			    sql += ' ,%s ' % key
-			    sql += '= %s '
-		    count += 1
-	            args.append(self.D[key])
-	    if where:
-	        sql += where
+                # Update only entries which are not None
+                if self.D[key] is not None:
+                    if count == 0:
+                        if dbmi.paramstyle == "qmark":
+                            sql += ' %s = ? ' % key
+                        else:
+                            sql += ' %s ' % key
+                            sql += '= %s '
+                    else:
+                        if dbmi.paramstyle == "qmark":
+                            sql += ' ,%s = ? ' % key
+                        else:
+                            sql += ' ,%s ' % key
+                            sql += '= %s '
+                    count += 1
+                    args.append(self.D[key])
+            if where:
+                sql += where
             sql += ";\n"
 
-	# Create update statement for all entries
-	if type =="UPDATE ALL":
-	    count = 0
-	    sql += 'UPDATE ' + table + ' SET '
+        # Create update statement for all entries
+        if type == "UPDATE ALL":
+            count = 0
+            sql += 'UPDATE ' + table + ' SET '
             for key in self.D.keys():
                 if count == 0:
-		    if dbmi.paramstyle == "qmark":
-			sql += ' %s = ? ' % key
-		    else:
-			sql += ' %s ' % key
-			sql += '= %s '
+                    if dbmi.paramstyle == "qmark":
+                        sql += ' %s = ? ' % key
+                    else:
+                        sql += ' %s ' % key
+                        sql += '= %s '
                 else:
-		    if dbmi.paramstyle == "qmark":
-	                sql += ' ,%s = ? ' % key
-		    else:
-			sql += ' ,%s ' % key
-			sql += '= %s '
+                    if dbmi.paramstyle == "qmark":
+                        sql += ' ,%s = ? ' % key
+                    else:
+                        sql += ' ,%s ' % key
+                        sql += '= %s '
                 count += 1
                 args.append(self.D[key])
-	    if where:
-	        sql += where
+            if where:
+                sql += where
             sql += ";\n"
 
-    	return sql, tuple(args)
+        return sql, tuple(args)
 
     def deserialize(self, row):
-	"""!Convert the content of the dbmi dictionary like row into the internal dictionary
+        """!Convert the content of the dbmi dictionary like row into the internal dictionary
 
            @param row: The dictionary like row to store in the internal dict
         """
-	self.D = {}
-	for key in row.keys():
-	    self.D[key] = row[key]
+        self.D = {}
+        for key in row.keys():
+            self.D[key] = row[key]
 
     def clear(self):
-	"""!Initialize the internal storage"""
-	self.D = {}
+        """!Initialize the internal storage"""
+        self.D = {}
 
     def print_self(self):
+        """!Print the content of the internal dictionary to stdout
+        """
         print self.D
 
-    def test(self):
-        t = dict_sql_serializer()
-	t.D["id"] = "soil at PERMANENT"
-	t.D["name"] = "soil"
-	t.D["mapset"] = "PERMANENT"
-	t.D["creator"] = "soeren"
-	t.D["creation_time"] = datetime.now()
-	t.D["modification_time"] = datetime.now()
-	t.D["revision"] = 1
-	sql, values = t.serialize(type="SELECT", table="raster_base")
-	print sql, '\n', values
-	sql, values = t.serialize(type="INSERT", table="raster_base")
-	print sql, '\n', values
-	sql, values = t.serialize(type="UPDATE", table="raster_base")
-	print sql, '\n', values
-
 ###############################################################################
 
-class sql_database_interface(dict_sql_serializer):
+class SQLDatabaseInterface(DictSQLSerializer):
     """!This class represents the SQL database interface
 
        Functions to insert, select and update the internal structure of this class
-       in the temporal database are implemented. 
+       in the temporal database are implemented.
        This is the base class for raster, raster3d, vector and space time datasets
        data management classes:
        * Identification information (base)
        * Spatial extent
        * Temporal extent
        * Metadata
+       
+       Usage:
+       
+        >>> import grass.temporal as tgis
+        >>> from datetime import datetime, date, time, timedelta
+        >>> t = tgis.SQLDatabaseInterface("raster", "soil at PERMANENT")
+        >>> t.D["name"] = "soil"
+        >>> t.D["mapset"] = "PERMANENT"
+        >>> t.D["creator"] = "soeren"
+        >>> t.D["creation_time"] = datetime(2001,1,1)
+        >>> t.get_delete_statement()
+        "DELETE FROM raster WHERE id = 'soil at PERMANENT';\\n"
+        >>> t.get_is_in_db_statement()
+        "SELECT id FROM raster WHERE id = 'soil at PERMANENT';\\n"
+        >>> t.get_select_statement()
+        ("SELECT  creation_time  , mapset  , name  , creator  FROM raster WHERE id = 'soil at PERMANENT';\\n", ())
+        >>> t.get_select_statement_mogrified()
+        "SELECT  creation_time  , mapset  , name  , creator  FROM raster WHERE id = 'soil at PERMANENT';\\n"
+        >>> t.get_insert_statement()
+        ('INSERT INTO raster ( creation_time  ,mapset  ,name  ,creator ) VALUES (? ,? ,? ,?) ;\\n', (datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil', 'soeren'))
+        >>> t.get_insert_statement_mogrified()
+        "INSERT INTO raster ( creation_time  ,mapset  ,name  ,creator ) VALUES ('2001-01-01 00:00:00' ,'PERMANENT' ,'soil' ,'soeren') ;\\n"
+        >>> t.get_update_statement()
+        ("UPDATE raster SET  creation_time = ?  ,mapset = ?  ,name = ?  ,creator = ? WHERE id = 'soil at PERMANENT';\\n", (datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil', 'soeren'))
+        >>> t.get_update_statement_mogrified()
+        "UPDATE raster SET  creation_time = '2001-01-01 00:00:00'  ,mapset = 'PERMANENT'  ,name = 'soil'  ,creator = 'soeren' WHERE id = 'soil at PERMANENT';\\n"
+        >>> t.get_update_all_statement()
+        ("UPDATE raster SET  creation_time = ?  ,mapset = ?  ,name = ?  ,creator = ? WHERE id = 'soil at PERMANENT';\\n", (datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil', 'soeren'))
+        >>> t.get_update_all_statement_mogrified()
+        "UPDATE raster SET  creation_time = '2001-01-01 00:00:00'  ,mapset = 'PERMANENT'  ,name = 'soil'  ,creator = 'soeren' WHERE id = 'soil at PERMANENT';\\n"
     """
     def __init__(self, table=None, ident=None):
         """!Constructor of this class
@@ -195,9 +233,9 @@
            @param table: The name of the table
            @param ident: The identifier (primary key) of this object in the database table
         """
-        dict_sql_serializer.__init__(self)
+        DictSQLSerializer.__init__(self)
 
-        self.table = table # Name of the table, set in the subclass
+        self.table = table  # Name of the table, set in the subclass
         self.ident = ident
 
     def get_table_name(self):
@@ -206,27 +244,27 @@
 
     def get_delete_statement(self):
         """!Return the delete string"""
-	return "DELETE FROM " + self.get_table_name() + " WHERE id = \'" + str(self.ident) + "\';\n"
+        return "DELETE FROM " + self.get_table_name() + " WHERE id = \'" + str(self.ident) + "\';\n"
 
     def delete(self, dbif=None):
         """!Delete the entry of this object from the temporal database
 
            @param dbif: The database interface to be used, if None a temporary connection will be established
         """
-	sql = self.get_delete_statement()
+        sql = self.get_delete_statement()
         #print sql
-        
-	if dbif:
-	    dbif.cursor.execute(sql)
-	else:
-	    dbif = sql_database_interface_connection()
-	    dbif.connect()
-	    dbif.cursor.execute(sql)
-	    dbif.close()
 
+        if dbif:
+            dbif.cursor.execute(sql)
+        else:
+            dbif = SQLDatabaseInterfaceConnection()
+            dbif.connect()
+            dbif.cursor.execute(sql)
+            dbif.close()
+
     def get_is_in_db_statement(self):
         """Return the selection string"""
-	return "SELECT id FROM " + self.get_table_name() + " WHERE id = \'" + str(self.ident) + "\';\n"
+        return "SELECT id FROM " + self.get_table_name() + " WHERE id = \'" + str(self.ident) + "\';\n"
 
     def is_in_db(self, dbif=None):
         """!Check if this object is present in the temporal database
@@ -234,48 +272,48 @@
            @param dbif: The database interface to be used, if None a temporary connection will be established
         """
 
-	sql = self.get_is_in_db_statement()
+        sql = self.get_is_in_db_statement()
         #print sql
 
-	if dbif:
-	    dbif.cursor.execute(sql)
-	    row = dbif.cursor.fetchone()
-	else:
-	    dbif = sql_database_interface_connection()
-	    dbif.connect()
-	    dbif.cursor.execute(sql)
-	    row = dbif.cursor.fetchone()
-	    dbif.close()
+        if dbif:
+            dbif.cursor.execute(sql)
+            row = dbif.cursor.fetchone()
+        else:
+            dbif = SQLDatabaseInterfaceConnection()
+            dbif.connect()
+            dbif.cursor.execute(sql)
+            row = dbif.cursor.fetchone()
+            dbif.close()
 
-	# Nothing found
-	if row == None:
-	    return False
+        # Nothing found
+        if row is None:
+            return False
 
-	return True
+        return True
 
     def get_select_statement(self):
         """!Return the sql statement and the argument list in database specific style"""
-	return self.serialize("SELECT", self.get_table_name(), "WHERE id = \'" + str(self.ident) + "\'")
-    
+        return self.serialize("SELECT", self.get_table_name(), "WHERE id = \'" + str(self.ident) + "\'")
+
     def get_select_statement_mogrified(self, dbif=None):
         """!Return the select statement as mogrified string
 
            @param dbif: The database interface to be used, if None a temporary connection will be established
         """
         if not dbif:
-	    dbif = sql_database_interface_connection()
-	    
+            dbif = SQLDatabaseInterfaceConnection()
+
         return dbif.mogrify_sql_statement(self.get_select_statement())
-                
+
     def select(self, dbif=None):
         """!Select the content from the temporal database and store it
            in the internal dictionary structure
 
            @param dbif: The database interface to be used, if None a temporary connection will be established
         """
-	sql, args = self.get_select_statement()
-	#print sql
-	#print args
+        sql, args = self.get_select_statement()
+        #print sql
+        #print args
 
         if dbif:
             if len(args) == 0:
@@ -284,38 +322,39 @@
                 dbif.cursor.execute(sql, args)
             row = dbif.cursor.fetchone()
         else:
-	    dbif = sql_database_interface_connection()
-	    dbif.connect()
-	    if len(args) == 0:
-		dbif.cursor.execute(sql)
-	    else:
-		dbif.cursor.execute(sql, args)
-	    row = dbif.cursor.fetchone()
-	    dbif.close()
+            dbif = SQLDatabaseInterfaceConnection()
+            dbif.connect()
+            if len(args) == 0:
+                dbif.cursor.execute(sql)
+            else:
+                dbif.cursor.execute(sql, args)
+            row = dbif.cursor.fetchone()
+            dbif.close()
 
-	# Nothing found
-	if row == None:
-	    return False
+        # Nothing found
+        if row is None:
+            return False
 
-	if len(row) > 0:
-	    self.deserialize(row)
-	else:
-            core.fatal(_("Object <%s> not found in the temporal database") % self.get_id())
+        if len(row) > 0:
+            self.deserialize(row)
+        else:
+            core.fatal(_("Object <%s> not found in the temporal database")
+                       % self.get_id())
 
-	return True
+        return True
 
     def get_insert_statement(self):
         """!Return the sql statement and the argument list in database specific style"""
-	return self.serialize("INSERT", self.get_table_name())
-    
+        return self.serialize("INSERT", self.get_table_name())
+
     def get_insert_statement_mogrified(self, dbif=None):
         """!Return the insert statement as mogrified string
 
            @param dbif: The database interface to be used, if None a temporary connection will be established
         """
         if not dbif:
-	    dbif = sql_database_interface_connection()
-	    
+            dbif = SQLDatabaseInterfaceConnection()
+
         return dbif.mogrify_sql_statement(self.get_insert_statement())
 
     def insert(self, dbif=None):
@@ -324,30 +363,30 @@
 
            @param dbif: The database interface to be used, if None a temporary connection will be established
         """
-	sql, args = self.get_insert_statement()
-	#print sql
-	#print args
+        sql, args = self.get_insert_statement()
+        #print sql
+        #print args
 
-	if dbif:
-	    dbif.cursor.execute(sql, args)
-	else:
-	    dbif = sql_database_interface_connection()
-	    dbif.connect()
-	    dbif.cursor.execute(sql, args)
-	    dbif.close()
+        if dbif:
+            dbif.cursor.execute(sql, args)
+        else:
+            dbif = SQLDatabaseInterfaceConnection()
+            dbif.connect()
+            dbif.cursor.execute(sql, args)
+            dbif.close()
 
     def get_update_statement(self):
         """!Return the sql statement and the argument list in database specific style"""
-	return self.serialize("UPDATE", self.get_table_name(), "WHERE id = \'" + str(self.ident) + "\'")
+        return self.serialize("UPDATE", self.get_table_name(), "WHERE id = \'" + str(self.ident) + "\'")
 
-    def get_update_statement_mogrified(self,dbif=None):
+    def get_update_statement_mogrified(self, dbif=None):
         """!Return the update statement as mogrified string
 
            @param dbif: The database interface to be used, if None a temporary connection will be established
         """
         if not dbif:
-	    dbif = sql_database_interface_connection()
-	    
+            dbif = SQLDatabaseInterfaceConnection()
+
         return dbif.mogrify_sql_statement(self.get_update_statement())
 
     def update(self, dbif=None):
@@ -358,24 +397,24 @@
 
            @param dbif: The database interface to be used, if None a temporary connection will be established
         """
-	if self.ident == None:
-	    raise IOError("Missing identifer");
+        if self.ident is None:
+            raise IOError("Missing identifer")
 
-	sql, args = self.get_update_statement()
-	#print sql
-	#print args
+        sql, args = self.get_update_statement()
+        #print sql
+        #print args
 
-	if dbif:
-	    dbif.cursor.execute(sql, args)
-	else:
-	    dbif = sql_database_interface_connection()
-	    dbif.connect()
-	    dbif.cursor.execute(sql, args)
-	    dbif.close()
+        if dbif:
+            dbif.cursor.execute(sql, args)
+        else:
+            dbif = SQLDatabaseInterfaceConnection()
+            dbif.connect()
+            dbif.cursor.execute(sql, args)
+            dbif.close()
 
     def get_update_all_statement(self):
         """!Return the sql statement and the argument list in database specific style"""
-	return self.serialize("UPDATE ALL", self.get_table_name(), "WHERE id = \'" + str(self.ident) + "\'")
+        return self.serialize("UPDATE ALL", self.get_table_name(), "WHERE id = \'" + str(self.ident) + "\'")
 
     def get_update_all_statement_mogrified(self, dbif=None):
         """!Return the update all statement as mogrified string
@@ -383,8 +422,8 @@
            @param dbif: The database interface to be used, if None a temporary connection will be established
         """
         if not dbif:
-	    dbif = sql_database_interface_connection()
-	    
+            dbif = SQLDatabaseInterfaceConnection()
+
         return dbif.mogrify_sql_statement(self.get_update_all_statement())
 
     def update_all(self, dbif=None):
@@ -393,213 +432,278 @@
 
            @param dbif: The database interface to be used, if None a temporary connection will be established
         """
-	if self.ident == None:
-	    raise IOError("Missing identifer");
+        if self.ident is None:
+            raise IOError("Missing identifer")
 
-	sql, args = self.get_update_all_statement()
-	#print sql
-	#print args
+        sql, args = self.get_update_all_statement()
+        #print sql
+        #print args
 
-	if dbif:
-	    dbif.cursor.execute(sql, args)
-	else:
-	    dbif = sql_database_interface_connection()
-	    dbif.connect()
-	    dbif.cursor.execute(sql, args)
-	    dbif.close()
+        if dbif:
+            dbif.cursor.execute(sql, args)
+        else:
+            dbif = SQLDatabaseInterfaceConnection()
+            dbif.connect()
+            dbif.cursor.execute(sql, args)
+            dbif.close()
 
 ###############################################################################
 
-class dataset_base(sql_database_interface):
-    """!This is the base class for all maps and spacetime datasets storing basic identification information"""
-    def __init__(self, table=None, ident=None, name=None, mapset=None, creator=None, ctime=None,\
-		    mtime=None, ttype=None, revision=1):
 
-	sql_database_interface.__init__(self, table, ident)
+class DatasetBase(SQLDatabaseInterface):
+    """!This is the base class for all maps and spacetime datasets storing 
+        basic identification information
+        
+        Usage:
 
-	self.set_id(ident)
-        if ident != None and name == None and mapset == None:
+        >>> import grass.temporal as tgis
+        >>> from datetime import datetime, date, time, timedelta
+        >>> t = tgis.DatasetBase("raster", "soil at PERMANENT", creator="soeren", ctime=datetime(2001,1,1), ttype="absolute")
+        >>> t.id
+        'soil at PERMANENT'
+        >>> t.name
+        'soil'
+        >>> t.mapset
+        'PERMANENT'
+        >>> t.creator
+        'soeren'
+        >>> t.ctime
+        datetime.datetime(2001, 1, 1, 0, 0)
+        >>> t.ttype
+        'absolute'
+        >>> t.print_info()
+         +-------------------- Basic information -------------------------------------+
+         | Id: ........................ soil at PERMANENT
+         | Name: ...................... soil
+         | Mapset: .................... PERMANENT
+         | Creator: ................... soeren
+         | Creation time: ............. 2001-01-01 00:00:00
+         | Temporal type: ............. absolute
+        >>> t.print_shell_info()
+        id=soil at PERMANENT
+        name=soil
+        mapset=PERMANENT
+        creator=soeren
+        creation_time=2001-01-01 00:00:00
+        temporal_type=absolute
+    """
+    
+    def __init__(self, table=None, ident=None, name=None, mapset=None, 
+                 creator=None, ctime=None,ttype=None):
+        """!Constructor
+        
+            @param table: The name of the temporal database table that should be used to store the values
+            @param ident: The unique identifier must be a combination of the dataset name, 
+                          layer name and the mapset name at mapset or name:1 at mapset
+                          used as as primary key in the temporal database
+            @param name: The name of the map or dataset
+            @param mapset: The name of the mapset 
+            @param creator: The name of the creator
+            @param ctime: The creation datetime object
+            @param ttype: The temporal type
+                * "absolute" Identifier for absolute time
+                * "relative" Identifier for relative time
+        """
+
+        SQLDatabaseInterface.__init__(self, table, ident)
+
+        self.set_id(ident)
+        if ident is not None and name is None and mapset is None:
             if ident.find("@") >= 0:
                 name, mapset = ident.split("@")
             if name.find(":") >= 0:
                 name, layer = ident.split(":")
-	self.set_name(name)
-	self.set_mapset(mapset)
-	self.set_creator(creator)
-	self.set_ctime(ctime)
-	self.set_ttype(ttype)
-	#self.set_mtime(mtime)
-	#self.set_revision(revision)
+        self.set_name(name)
+        self.set_mapset(mapset)
+        self.set_creator(creator)
+        self.set_ctime(ctime)
+        self.set_ttype(ttype)
+        # Commented out for performance reasons
+        #self.set_mtime(mtime)
+        #self.set_revision(revision)
 
     def set_id(self, ident):
-	"""!Convenient method to set the unique identifier (primary key)
+        """!Convenient method to set the unique identifier (primary key)
 
-           @param ident: The unique identifier should be a combination of the dataset name, layer name and the mapset name at mapset
+           @param ident: The unique identifier must be a combination of the dataset name, 
+                         layer name and the mapset name at mapset or name:1 at mapset
         """
-	self.ident = ident
-	self.D["id"] = ident
-	
-        if ident != None:
+        self.ident = ident
+        self.D["id"] = ident
+
+        if ident is not None:
             if ident.find("@") >= 0:
                 name, mapset = ident.split("@")
-		self.set_mapset(mapset)
+                self.set_mapset(mapset)
+                self.set_name(name)
+            else:
+                core.fatal(_("Wrong identifier, the mapset is missing"))
             if name.find(":") >= 0:
                 name, layer = ident.split(":")
-		self.set_layer(layer)
-	    
-	    self.set_name(name)
+                self.set_layer(layer)
+            self.set_name(name)
 
+
     def set_name(self, name):
-	"""!Set the name of the dataset
+        """!Set the name of the dataset
 
            @param name: The name of the dataset
         """
-	self.D["name"] = name
+        self.D["name"] = name
 
     def set_mapset(self, mapset):
-	"""!Set the mapset of the dataset
+        """!Set the mapset of the dataset
 
            @param mapsets: The name of the mapset in which this dataset is stored
         """
-	self.D["mapset"] = mapset
+        self.D["mapset"] = mapset
 
     def set_layer(self, layer):
-	"""!Convenient method to set the layer of the map (part of primary key)
-	
-	   Layer are currently supported for vector maps
+        """!Convenient method to set the layer of the map (part of primary key)
 
+           Layer are supported for vector maps
+
            @param layer: The layer of the map
         """
-	self.D["layer"] = layer
+        self.D["layer"] = layer
 
     def set_creator(self, creator):
-	"""!Set the creator of the dataset
+        """!Set the creator of the dataset
 
            @param creator: The name of the creator
         """
-	self.D["creator"] = creator
+        self.D["creator"] = creator
 
     def set_ctime(self, ctime=None):
-	"""!Set the creation time of the dataset, if nothing set the current time is used
+        """!Set the creation time of the dataset, if nothing set the current time is used
 
            @param ctime: The current time of type datetime
         """
-	if ctime == None:
+        if ctime is None:
             self.D["creation_time"] = datetime.now()
-	else:
+        else:
             self.D["creation_time"] = ctime
 
     def set_ttype(self, ttype):
-	"""!Set the temporal type of the dataset: absolute or relative, if nothing set absolute time will assumed
+        """!Set the temporal type of the dataset: absolute or relative, 
+           if nothing set absolute time will assumed
 
            @param ttype: The temporal type of the dataset "absolute or relative"
         """
-	if ttype == None or (ttype != "absolute" and ttype != "relative"):
-	    self.D["temporal_type"] = "absolute"
+        if ttype is None or (ttype != "absolute" and ttype != "relative"):
+            self.D["temporal_type"] = "absolute"
         else:
-	    self.D["temporal_type"] = ttype
+            self.D["temporal_type"] = ttype
 
 #    def set_mtime(self, mtime=None):
-#	"""!Set the modification time of the map, if nothing set the current time is used"""
-#	if mtime == None:
+#       """!Set the modification time of the map, if nothing set the current time is used"""
+#       if mtime == None:
 #            self.D["modification_time"] = datetime.now()
-#	else:
+#       else:
 #            self.D["modification_time"] = mtime
 
 #    def set_revision(self, revision=1):
-#	"""!Set the revision of the map: if nothing set revision 1 will assumed"""
-#	self.D["revision"] = revision
+#       """!Set the revision of the map: if nothing set revision 1 will assumed"""
+#       self.D["revision"] = revision
 
     def get_id(self):
-	"""!Convenient method to get the unique identifier (primary key)
-        
-	   @return None if not found
-	"""
-	if self.D.has_key("id"):
-	    return self.D["id"]
+        """!Convenient method to get the unique identifier (primary key)
+
+           @return None if not found
+        """
+        if "id" in self.D:
+            return self.D["id"]
         else:
-	    return None
+            return None
 
     def get_map_id(self):
-	"""!Convenient method to get the unique map identifier without layer information
+        """!Convenient method to get the unique map identifier without layer information
 
            @param return the name of the vector map as name at mapset
         """
-        id = self.get_id()
-        if id.find(":") >= 0:
-	    # Remove the layer identifier from the id
-	    return id.split("@")[0].split(":")[0] + "@" + id.split("@")[1]
-	else:
-	    return id
-	    
+        if self.id.find(":") >= 0:
+            # Remove the layer identifier from the id
+            return iself.d.split("@")[0].split(":")[0] + "@" + self.id.split("@")[1]
+        else:
+            return self.id
+
     def get_layer(self):
-	"""!Convenient method to get the layer of the map (part of primary key)
-	
-	   Layer are currently supported for vector maps
-        
-	   @return None if not found
-	"""
-	if self.D.has_key("layer"):
-	    return self.D["layer"]
+        """!Convenient method to get the layer of the map (part of primary key)
+
+           Layer are currently supported for vector maps
+
+           @return None if not found
+        """
+        if "layer" in self.D:
+            return self.D["layer"]
         else:
-	    return None
+            return None
 
     def get_name(self):
-	"""!Get the name of the dataset
-	   @return None if not found"""
-	if self.D.has_key("name"):
-	    return self.D["name"]
+        """!Get the name of the dataset
+           @return None if not found"""
+        if "name" in self.D:
+            return self.D["name"]
         else:
-	    return None
+            return None
 
     def get_mapset(self):
-	"""!Get the name of mapset of this dataset
-	   @return None if not found"""
-	if self.D.has_key("mapset"):
-	    return self.D["mapset"]
+        """!Get the name of mapset of this dataset
+           @return None if not found"""
+        if "mapset" in self.D:
+            return self.D["mapset"]
         else:
-	    return None
+            return None
 
     def get_creator(self):
-	"""!Get the creator of the dataset
-	   @return None if not found"""
-	if self.D.has_key("creator"):
-	    return self.D["creator"]
+        """!Get the creator of the dataset
+           @return None if not found"""
+        if "creator" in self.D:
+            return self.D["creator"]
         else:
-	    return None
+            return None
 
     def get_ctime(self):
-	"""!Get the creation time of the dataset, datatype is datetime
-	   @return None if not found"""
-	if self.D.has_key("creation_time"):
-	    return self.D["creation_time"]
+        """!Get the creation time of the dataset, datatype is datetime
+           @return None if not found"""
+        if "creation_time" in self.D:
+            return self.D["creation_time"]
         else:
-	    return None
+            return None
 
     def get_ttype(self):
-	"""!Get the temporal type of the map
-	   @return None if not found"""
-	if self.D.has_key("temporal_type"):
-	    return self.D["temporal_type"]
+        """!Get the temporal type of the map
+           @return None if not found"""
+        if "temporal_type" in self.D:
+            return self.D["temporal_type"]
         else:
-	    return None
+            return None
 
 #    def get_mtime(self):
-#	"""!Get the modification time of the map, datatype is datetime
-#	   @return None if not found"""
-#	if self.D.has_key("modification_time"):
-#	    return self.D["modification_time"]
+#       """!Get the modification time of the map, datatype is datetime
+#          @return None if not found"""
+#       if self.D.has_key("modification_time"):
+#           return self.D["modification_time"]
 #       else:
-#	    return None
+#           return None
 
 #    def get_revision(self):
-#	"""!Get the revision of the map
-#	   @return None if not found"""
-#	if self.D.has_key("revision"):
-#	    return self.D["revision"]
+#       """!Get the revision of the map
+#          @return None if not found"""
+#       if self.D.has_key("revision"):
+#           return self.D["revision"]
 #       else:
-#	    return None
+#           return None
 
+    # Properties of this class
+    id = property(fget=get_id, fset=set_id)
+    map_id = property(fget=get_map_id, fset=None)
+    name = property(fget=get_name, fset=set_name)
+    mapset = property(fget=get_mapset, fset=set_mapset)
+    ctime = property(fget=get_ctime, fset=set_ctime)
+    ttype = property(fget=get_ttype, fset=set_ttype)
+    creator = property(fget=get_creator, fset=set_creator)
+
     def print_info(self):
         """!Print information about this class in human readable style"""
         #      0123456789012345678901234567890
@@ -608,109 +712,167 @@
         print " | Name: ...................... " + str(self.get_name())
         print " | Mapset: .................... " + str(self.get_mapset())
         if self.get_layer():
-	    print " | Layer:...................... " + str(self.get_layer())
+            print " | Layer:...................... " + str(self.get_layer())
         print " | Creator: ................... " + str(self.get_creator())
         print " | Creation time: ............. " + str(self.get_ctime())
+        print " | Temporal type: ............. " + str(self.get_ttype())
 #        print " | Modification time: ......... " + str(self.get_mtime())
-        print " | Temporal type: ............. " + str(self.get_ttype())
 #        print " | Revision in database: ...... " + str(self.get_revision())
-        
+
     def print_shell_info(self):
         """!Print information about this class in shell style"""
         print "id=" + str(self.get_id())
         print "name=" + str(self.get_name())
         print "mapset=" + str(self.get_mapset())
         if self.get_layer():
-	    print "layer=" + str(self.get_layer())
+            print "layer=" + str(self.get_layer())
         print "creator=" + str(self.get_creator())
         print "creation_time=" + str(self.get_ctime())
+        print "temporal_type=" + str(self.get_ttype())
 #        print "modification_time=" + str(self.get_mtime())
-        print "temporal_type=" + str(self.get_ttype())
 #        print "revision=" + str(self.get_revision())
 
 ###############################################################################
 
-class raster_base(dataset_base):
-    def __init__(self, ident=None, name=None, mapset=None, creator=None, creation_time=None,\
-		    modification_time=None, temporal_type=None, revision=1):
-        dataset_base.__init__(self, "raster_base", ident, name, mapset, creator, creation_time,\
-	            modification_time, temporal_type, revision)
 
-class raster3d_base(dataset_base):
-    def __init__(self, ident=None, name=None, mapset=None, creator=None, creation_time=None,\
-		    modification_time=None, temporal_type=None, revision=1):
-        dataset_base.__init__(self, "raster3d_base", ident, name, mapset, creator, creation_time,\
-	            modification_time, temporal_type, revision)
+class RasterBase(DatasetBase):
+    """!Time stamped raster map base information class"""
+    def __init__(self, ident=None, name=None, mapset=None, creator=None, 
+                 creation_time=None, temporal_type=None):
+        DatasetBase.__init__(self, "raster_base", ident, name, mapset, 
+                              creator, creation_time, temporal_type)
 
-class vector_base(dataset_base):
-    def __init__(self, ident=None, name=None, mapset=None, layer=None, creator=None, creation_time=None,\
-		    modification_time=None, temporal_type=None, revision=1):
-        dataset_base.__init__(self, "vector_base", ident, name, mapset, creator, creation_time,\
-	            modification_time, temporal_type, revision)
 
-	self.set_id(ident)
-        if ident != None and name == None and mapset == None:
+class Raster3DBase(DatasetBase):
+    """!Time stamped 3D raster map base information class"""
+    def __init__(self, ident=None, name=None, mapset=None, creator=None, 
+                 creation_time=None, temporal_type=None,):
+        DatasetBase.__init__(self, "raster3d_base", ident, name, 
+                              mapset, creator, creation_time, 
+                              temporal_type)
+
+
+class VectorBase(DatasetBase):
+    """!Time stamped vector map base information class"""
+    def __init__(self, ident=None, name=None, mapset=None, layer=None, 
+                 creator=None, creation_time=None, temporal_type=None):
+        DatasetBase.__init__(self, "vector_base", ident, name, mapset,
+                              creator, creation_time, temporal_type)
+
+        self.set_id(ident)
+        if ident is not None and name is None and mapset is None:
             if ident.find("@") >= 0:
                 name, mapset = ident.split("@")
-            if layer == None:
-		if name.find(":") >= 0:
-		    name, layer = name.split(":")
-	self.set_name(name)
-	self.set_mapset(mapset)
-	# Layer currently only in use by vector maps
-	self.set_layer(layer)
+            if layer is None:
+                if name.find(":") >= 0:
+                    name, layer = name.split(":")
+        self.set_name(name)
+        self.set_mapset(mapset)
+        # Layer currently only in use by vector maps
+        self.set_layer(layer)
 
 ###############################################################################
 
-class stds_base(dataset_base):
-    def __init__(self, table=None, ident=None, name=None, mapset=None, semantic_type=None, creator=None, creation_time=None,\
-		    modification_time=None, temporal_type=None, revision=1):
-        dataset_base.__init__(self, table, ident, name, mapset, creator, creation_time,\
-	            modification_time, temporal_type, revision)
 
-	self.set_semantic_type(semantic_type)
+class STDSBase(DatasetBase):
+    """!Base class for space time datasets
+    
+       This class adds the semantic type member variable to the dataset 
+       base class.
+       
+    Usage:
 
+    >>> import grass.temporal as tgis
+    >>> from datetime import datetime, date, time, timedelta
+    >>> t = tgis.STDSBase("stds", "soil at PERMANENT", semantic_type="average", creator="soeren", ctime=datetime(2001,1,1), ttype="absolute")
+    >>> t.semantic_type
+    'average'
+    >>> t.print_info()
+     +-------------------- Basic information -------------------------------------+
+     | Id: ........................ soil at PERMANENT
+     | Name: ...................... soil
+     | Mapset: .................... PERMANENT
+     | Creator: ................... soeren
+     | Creation time: ............. 2001-01-01 00:00:00
+     | Temporal type: ............. absolute
+     | Semantic type:.............. average
+    >>> t.print_shell_info()
+    id=soil at PERMANENT
+    name=soil
+    mapset=PERMANENT
+    creator=soeren
+    creation_time=2001-01-01 00:00:00
+    temporal_type=absolute
+    semantic_type=average
+    """
+    def __init__(self, table=None, ident=None, name=None, mapset=None, 
+                 semantic_type=None, creator=None, ctime=None,
+                 ttype=None):
+        DatasetBase.__init__(self, table, ident, name, mapset, creator,
+                              ctime, ttype)
+
+        self.set_semantic_type(semantic_type)
+
     def set_semantic_type(self, semantic_type):
-	"""!Set the semantic type of the space time dataset"""
-	self.D["semantic_type"] = semantic_type
+        """!Set the semantic type of the space time dataset"""
+        self.D["semantic_type"] = semantic_type
 
     def get_semantic_type(self):
-	"""!Get the semantic type of the space time dataset
-	   @return None if not found"""
-	if self.D.has_key("semantic_type"):
-	    return self.D["semantic_type"]
+        """!Get the semantic type of the space time dataset
+           @return None if not found"""
+        if "semantic_type" in self.D:
+            return self.D["semantic_type"]
         else:
-	    return None
+            return None
 
+    semantic_type = property(fget=get_semantic_type, fset=set_semantic_type)
+    
     def print_info(self):
         """!Print information about this class in human readable style"""
-        dataset_base.print_info(self)
+        DatasetBase.print_info(self)
         #      0123456789012345678901234567890
-        print " | Semantic type:.............. " + str(self.get_semantic_type())
+        print " | Semantic type:.............. " + str(
+            self.get_semantic_type())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-        dataset_base.print_shell_info(self)
+        DatasetBase.print_shell_info(self)
         print "semantic_type=" + str(self.get_semantic_type())
 
 ###############################################################################
 
-class strds_base(stds_base):
-    def __init__(self, ident=None, name=None, mapset=None, semantic_type=None,  creator=None, creation_time=None,\
-		    modification_time=None, temporal_type=None, revision=1):
-        stds_base.__init__(self, "strds_base", ident, name, mapset, semantic_type, creator, creation_time,\
-	            modification_time, temporal_type, revision)
 
-class str3ds_base(stds_base):
-    def __init__(self, ident=None, name=None, mapset=None, semantic_type=None,  creator=None, creation_time=None,\
-		    modification_time=None, temporal_type=None, revision=1):
-        stds_base.__init__(self, "str3ds_base", ident, name, mapset, semantic_type, creator, creation_time,\
-	            modification_time, temporal_type, revision)
+class STRDSBase(STDSBase):
+    """!Space time raster dataset base information class"""
+    def __init__(self, ident=None, name=None, mapset=None, 
+                 semantic_type=None, creator=None, ctime=None,
+                 ttype=None):
+        STDSBase.__init__(self, "strds_base", ident, name, mapset, 
+                           semantic_type, creator, ctime,
+                           ttype)
 
-class stvds_base(stds_base):
-    def __init__(self, ident=None, name=None, mapset=None, semantic_type=None,  creator=None, creation_time=None,\
-		    modification_time=None, temporal_type=None, revision=1):
-        stds_base.__init__(self, "stvds_base", ident, name, mapset, semantic_type, creator, creation_time,\
-	            modification_time, temporal_type, revision)
 
+class STR3DSBase(STDSBase):
+    """!Space time 3D raster dataset base information class"""
+    def __init__(self, ident=None, name=None, mapset=None, 
+                 semantic_type=None, creator=None, ctime=None,
+                 ttype=None):
+        STDSBase.__init__(self, "str3ds_base", ident, name, mapset, 
+                           semantic_type, creator, ctime,
+                           ttype)
 
+
+class STVDSBase(STDSBase):
+    """!Space time vector dataset base information class"""
+    def __init__(self, ident=None, name=None, mapset=None, 
+                 semantic_type=None, creator=None, ctime=None,
+                 ttype=None):
+        STDSBase.__init__(self, "stvds_base", ident, name, mapset, 
+                           semantic_type, creator, ctime,
+                           ttype)
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()

Modified: grass/trunk/lib/python/temporal/core.py
===================================================================
--- grass/trunk/lib/python/temporal/core.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/core.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -2,17 +2,26 @@
 
 @brief GRASS Python scripting module (temporal GIS functions)
 
-Temporal GIS core functions to be used in Python scripts.
+Temporal GIS core functions to be used in library modules and scripts.
 
+This module provides the functionality to create the temporal
+SQL database and to establish a connection to the database.
+
 Usage:
 
- at code
-import grass.temporal as tgis
+>>> import grass.temporal as tgis
+>>> # Create the temporal database
+>>> tgis.create_temporal_database()
+>>> # Establish a database connection
+>>> dbif, connected = tgis.init_dbif(None)
+>>> dbif.connect()
+>>> # Execute a SQL statement
+>>> dbif.execute_transaction("SELECT datetime(0, 'unixepoch', 'localtime');")
+>>> # Mogrify an SQL statement
+>>> dbif.mogrify_sql_statement(["SELECT name from raster_base where name = ?", ("precipitation",)])
+"SELECT name from raster_base where name = 'precipitation'"
+>>> dbif.close()
 
-tgis.create_temporal_database()
-...
- at endcode
-
 (C) 2008-2011 by the GRASS Development Team
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
@@ -22,7 +31,6 @@
 """
 import os
 import copy
-from datetime import datetime, date, time, timedelta
 import grass.script.core as core
 
 ###############################################################################
@@ -31,7 +39,7 @@
 # Check the grass environment before import
 core.run_command("t.connect", flags="c")
 kv = core.parse_command("t.connect", flags="pg")
-if kv.has_key("driver"):
+if "driver" in kv:
     if kv["driver"] == "sqlite":
         import sqlite3 as dbmi
     elif kv["driver"] == "pg":
@@ -47,50 +55,54 @@
 
 ###############################################################################
 
+
 def get_temporal_dbmi_init_string():
     kv = core.parse_command("t.connect", flags="pg")
     grassenv = core.gisenv()
     if dbmi.__name__ == "sqlite3":
-        if kv.has_key("database"):
-            string =  kv["database"]
+        if "database" in kv:
+            string = kv["database"]
             string = string.replace("$GISDBASE", grassenv["GISDBASE"])
-            string = string.replace("$LOCATION_NAME", grassenv["LOCATION_NAME"])
+            string = string.replace(
+                "$LOCATION_NAME", grassenv["LOCATION_NAME"])
             return string
         else:
             core.fatal(_("Unable to initialize the temporal GIS DBMI interface. Use t.connect to specify the driver and the database string"))
     elif dbmi.__name__ == "psycopg2":
-        if kv.has_key("database"):
-            string =  kv["database"]
+        if "database" in kv:
+            string = kv["database"]
             return string
         else:
             core.fatal(_("Unable to initialize the temporal GIS DBMI interface. Use t.connect to specify the driver and the database string"))
-	    return "dbname=grass_test user=soeren password=abcdefgh"
+            return "dbname=grass_test user=soeren password=abcdefgh"
 
 ###############################################################################
 
+
 def get_sql_template_path():
     base = os.getenv("GISBASE")
-    base_etc  = os.path.join(base, "etc")
+    base_etc = os.path.join(base, "etc")
     return os.path.join(base_etc, "sql")
 
 ###############################################################################
 
+
 def create_temporal_database():
     """!This function creates the grass location database structure for raster, vector and raster3d maps
        as well as for the space-time datasets strds, str3ds and stvds
 
-       This functions must be called before any spatio-temporal processing is started
+       This functions must be called before any spatio-temporal processing can be started
     """
-    
+
     database = get_temporal_dbmi_init_string()
-    
+
     db_exists = False
 
     # Check if the database already exists
     if dbmi.__name__ == "sqlite3":
-	# Check path of the sqlite database
-	if os.path.exists(database):
-	    db_exists = True
+        # Check path of the sqlite database
+        if os.path.exists(database):
+            db_exists = True
     elif dbmi.__name__ == "psycopg2":
         # Connect to database
         connection = dbmi.connect(database)
@@ -102,25 +114,34 @@
         cursor.close()
 
     if db_exists == True:
-	return
-    
-    core.message(_("Create temporal database: %s"%(database)))
-    
+        return
+
+    core.message(_("Create temporal database: %s" % (database)))
+
     # Read all SQL scripts and templates
-    map_tables_template_sql = open(os.path.join(get_sql_template_path(), "map_tables_template.sql"), 'r').read()
-    raster_metadata_sql = open(os.path.join(get_sql_template_path(), "raster_metadata_table.sql"), 'r').read()
-    raster3d_metadata_sql = open(os.path.join(get_sql_template_path(), "raster3d_metadata_table.sql"), 'r').read()
-    vector_metadata_sql = open(os.path.join(get_sql_template_path(), "vector_metadata_table.sql"), 'r').read()
-    stds_tables_template_sql = open(os.path.join(get_sql_template_path(), "stds_tables_template.sql"), 'r').read()
-    strds_metadata_sql = open(os.path.join(get_sql_template_path(), "strds_metadata_table.sql"), 'r').read()
-    str3ds_metadata_sql = open(os.path.join(get_sql_template_path(), "str3ds_metadata_table.sql"), 'r').read()
-    stvds_metadata_sql = open(os.path.join(get_sql_template_path(), "stvds_metadata_table.sql"), 'r').read()
-    
+    map_tables_template_sql = open(os.path.join(
+        get_sql_template_path(), "map_tables_template.sql"), 'r').read()
+    raster_metadata_sql = open(os.path.join(
+        get_sql_template_path(), "raster_metadata_table.sql"), 'r').read()
+    raster3d_metadata_sql = open(os.path.join(get_sql_template_path(
+        ), "raster3d_metadata_table.sql"), 'r').read()
+    vector_metadata_sql = open(os.path.join(
+        get_sql_template_path(), "vector_metadata_table.sql"), 'r').read()
+    stds_tables_template_sql = open(os.path.join(
+        get_sql_template_path(), "stds_tables_template.sql"), 'r').read()
+    strds_metadata_sql = open(os.path.join(
+        get_sql_template_path(), "strds_metadata_table.sql"), 'r').read()
+    str3ds_metadata_sql = open(os.path.join(
+        get_sql_template_path(), "str3ds_metadata_table.sql"), 'r').read()
+    stvds_metadata_sql = open(os.path.join(
+        get_sql_template_path(), "stvds_metadata_table.sql"), 'r').read()
+
     # Create the raster, raster3d and vector tables
     raster_tables_sql = map_tables_template_sql.replace("GRASS_MAP", "raster")
     vector_tables_sql = map_tables_template_sql.replace("GRASS_MAP", "vector")
-    raster3d_tables_sql = map_tables_template_sql.replace("GRASS_MAP", "raster3d")
-  
+    raster3d_tables_sql = map_tables_template_sql.replace(
+        "GRASS_MAP", "raster3d")
+
     # Create the space-time raster, raster3d and vector dataset tables
     strds_tables_sql = stds_tables_template_sql.replace("STDS", "strds")
     stvds_tables_sql = stds_tables_template_sql.replace("STDS", "stvds")
@@ -131,58 +152,60 @@
     cursor = connection.cursor()
 
     if dbmi.__name__ == "sqlite3":
-	
-	sqlite3_delete_trigger_sql = open(os.path.join(get_sql_template_path(), "sqlite3_delete_trigger.sql"), 'r').read()
-	
-	# Execute the SQL statements for sqlite
-	# Create the global tables for the native grass datatypes
-	cursor.executescript(raster_tables_sql)
-	cursor.executescript(raster_metadata_sql)
-	cursor.executescript(vector_tables_sql)
-	cursor.executescript(vector_metadata_sql)
-	cursor.executescript(raster3d_tables_sql)
-	cursor.executescript(raster3d_metadata_sql)
-	# Create the tables for the new space-time datatypes
-	cursor.executescript(strds_tables_sql)
-	cursor.executescript(strds_metadata_sql)
-	cursor.executescript(stvds_tables_sql)
-	cursor.executescript(stvds_metadata_sql)
-	cursor.executescript(str3ds_tables_sql)
-	cursor.executescript(str3ds_metadata_sql)
-	cursor.executescript(sqlite3_delete_trigger_sql)
+
+        sqlite3_delete_trigger_sql = open(os.path.join(get_sql_template_path(
+        ), "sqlite3_delete_trigger.sql"), 'r').read()
+
+        # Execute the SQL statements for sqlite
+        # Create the global tables for the native grass datatypes
+        cursor.executescript(raster_tables_sql)
+        cursor.executescript(raster_metadata_sql)
+        cursor.executescript(vector_tables_sql)
+        cursor.executescript(vector_metadata_sql)
+        cursor.executescript(raster3d_tables_sql)
+        cursor.executescript(raster3d_metadata_sql)
+        # Create the tables for the new space-time datatypes
+        cursor.executescript(strds_tables_sql)
+        cursor.executescript(strds_metadata_sql)
+        cursor.executescript(stvds_tables_sql)
+        cursor.executescript(stvds_metadata_sql)
+        cursor.executescript(str3ds_tables_sql)
+        cursor.executescript(str3ds_metadata_sql)
+        cursor.executescript(sqlite3_delete_trigger_sql)
     elif dbmi.__name__ == "psycopg2":
-	# Execute the SQL statements for postgresql
-	# Create the global tables for the native grass datatypes
-	cursor.execute(raster_tables_sql)
-	cursor.execute(raster_metadata_sql)
-	cursor.execute(vector_tables_sql)
-	cursor.execute(vector_metadata_sql)
-	cursor.execute(raster3d_tables_sql)
-	cursor.execute(raster3d_metadata_sql)
-	# Create the tables for the new space-time datatypes
-	cursor.execute(strds_tables_sql)
-	cursor.execute(strds_metadata_sql)
-	cursor.execute(stvds_tables_sql)
-	cursor.execute(stvds_metadata_sql)
-	cursor.execute(str3ds_tables_sql)
-	cursor.execute(str3ds_metadata_sql)
+        # Execute the SQL statements for postgresql
+        # Create the global tables for the native grass datatypes
+        cursor.execute(raster_tables_sql)
+        cursor.execute(raster_metadata_sql)
+        cursor.execute(vector_tables_sql)
+        cursor.execute(vector_metadata_sql)
+        cursor.execute(raster3d_tables_sql)
+        cursor.execute(raster3d_metadata_sql)
+        # Create the tables for the new space-time datatypes
+        cursor.execute(strds_tables_sql)
+        cursor.execute(strds_metadata_sql)
+        cursor.execute(stvds_tables_sql)
+        cursor.execute(stvds_metadata_sql)
+        cursor.execute(str3ds_tables_sql)
+        cursor.execute(str3ds_metadata_sql)
 
     connection.commit()
     cursor.close()
 
 ###############################################################################
 
-class sql_database_interface_connection():
+
+class SQLDatabaseInterfaceConnection():
     """!This class represents the database interface connection
-    
+
        The following DBMS are supported:
        * sqlite via the sqlite3 standard library
        * postgresql via psycopg2
 
     """
     def __init__(self):
-	self.connected = False
-	
+        self.connected = False
+
     def connect(self):
         """!Connect to the DBMI to execute SQL statements
 
@@ -191,24 +214,25 @@
         init = get_temporal_dbmi_init_string()
         #print "Connect to",  self.database
         if dbmi.__name__ == "sqlite3":
-	    self.connection = dbmi.connect(init, detect_types=dbmi.PARSE_DECLTYPES|dbmi.PARSE_COLNAMES)
-	    self.connection.row_factory = dbmi.Row
+            self.connection = dbmi.connect(init, detect_types=dbmi.PARSE_DECLTYPES | dbmi.PARSE_COLNAMES)
+            self.connection.row_factory = dbmi.Row
             self.connection.isolation_level = None
-	    self.cursor = self.connection.cursor()
+            self.cursor = self.connection.cursor()
             self.cursor.execute("PRAGMA synchronous = OFF")
             self.cursor.execute("PRAGMA journal_mode = MEMORY")
         elif dbmi.__name__ == "psycopg2":
-	    self.connection = dbmi.connect(init)
-	    #self.connection.set_isolation_level(dbmi.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
-	    self.cursor = self.connection.cursor(cursor_factory=dbmi.extras.DictCursor)
-	self.connected = True
-	
+            self.connection = dbmi.connect(init)
+            #self.connection.set_isolation_level(dbmi.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
+            self.cursor = self.connection.cursor(
+                cursor_factory=dbmi.extras.DictCursor)
+        self.connected = True
+
     def close(self):
         """!Close the DBMI connection"""
         #print "Close connection to",  self.database
-	self.connection.commit()
+        self.connection.commit()
         self.cursor.close()
-	self.connected = False
+        self.connected = False
 
     def mogrify_sql_statement(self, content):
         """!Return the SQL statement and arguments as executable SQL string
@@ -231,16 +255,16 @@
                     statement = self.cursor.mogrify(sql, args)
                     self.close()
                     return statement
-                    
+
         elif dbmi.__name__ == "sqlite3":
             if len(args) == 0:
                 return sql
             else:
-                # Unfortunately as sqlite does not support 
+                # Unfortunately as sqlite does not support
                 # the transformation of sql strings and qmarked or
                 # named arguments we must make our hands dirty
                 # and do it by ourself. :(
-                # Doors are open for SQL injection because of the 
+                # Doors are open for SQL injection because of the
                 # limited python sqlite3 implementation!!!
                 pos = 0
                 count = 0
@@ -251,56 +275,59 @@
                     pos = statement.find("?", pos + 1)
                     if pos == -1:
                         break
-                    
-                    if args[count] == None:
-                        statement = "%sNULL%s"%(statement[0:pos], statement[pos+1:])
+
+                    if args[count] is None:
+                        statement = "%sNULL%s" % (statement[0:
+                                                            pos], statement[pos + 1:])
                     elif isinstance(args[count], (int, long)):
-                        statement = "%s%d%s"%(statement[0:pos], args[count],statement[pos+1:])
+                        statement = "%s%d%s" % (statement[0:pos], args[count],
+                                                statement[pos + 1:])
                     elif isinstance(args[count], float):
-                        statement = "%s%f%s"%(statement[0:pos], args[count],statement[pos+1:])
+                        statement = "%s%f%s" % (statement[0:pos], args[count],
+                                                statement[pos + 1:])
                     else:
                         # Default is a string, this works for datetime objects too
-                        statement = "%s\'%s\'%s"%(statement[0:pos], str(args[count]),statement[pos+1:])
+                        statement = "%s\'%s\'%s" % (statement[0:pos], str(args[count]), statement[pos + 1:])
                     count += 1
 
                 return statement
-                
+
     def execute_transaction(self, statement):
-	"""!Execute a transactional SQL statement
+        """!Execute a transactional SQL statement
 
-	    The BEGIN and END TRANSACTION statements will be added automatically
-	    to the sql statement
+            The BEGIN and END TRANSACTION statements will be added automatically
+            to the sql statement
 
-	    @param statement The executable SQL statement or SQL script
-	"""
-	connect = False
-	if self.connected == False:
-	    self.connect()
-	    connect = True
+            @param statement The executable SQL statement or SQL script
+        """
+        connect = False
+        if self.connected == False:
+            self.connect()
+            connect = True
 
-	sql_script = ""
-	sql_script += "BEGIN TRANSACTION;\n"
-	sql_script += statement
-	sql_script += "END TRANSACTION;"
-	try:
-	    if dbmi.__name__ == "sqlite3":
-		self.cursor.executescript(statement)
-	    else:
-		self.cursor.execute(statement)
-	    self.connection.commit()
-	except:
-	    if connect == True:
-		self.close()
-	    core.error(_("Unable to execute transaction:\n %s") % (statement))
-	    raise
+        sql_script = ""
+        sql_script += "BEGIN TRANSACTION;\n"
+        sql_script += statement
+        sql_script += "END TRANSACTION;"
+        try:
+            if dbmi.__name__ == "sqlite3":
+                self.cursor.executescript(statement)
+            else:
+                self.cursor.execute(statement)
+            self.connection.commit()
+        except:
+            if connect == True:
+                self.close()
+            core.error(_("Unable to execute transaction:\n %s") % (statement))
+            raise
 
-	if connect:
-	    self.close()
-	    
+        if connect:
+            self.close()
+
 ###############################################################################
 
 def init_dbif(dbif):
-    """!This method checks if the database interface connection exists, if not a new one 
+    """!This method checks if the database interface connection exists, if not a new one
         will be created, connected and True will be returned
 
         Usage code sample:
@@ -308,9 +335,15 @@
         if connect:
             dbif.close()
     """
-    if dbif == None:
-        dbif = sql_database_interface_connection()
+    if dbif is None:
+        dbif = SQLDatabaseInterfaceConnection()
         dbif.connect()
         return dbif, True
 
     return dbif, False
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()

Modified: grass/trunk/lib/python/temporal/extract.py
===================================================================
--- grass/trunk/lib/python/temporal/extract.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/extract.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -62,7 +62,7 @@
 	
     dummy = sp.get_new_map_instance(None)
 	
-    dbif = sql_database_interface_connection()
+    dbif = ()
     dbif.connect()
     
     if sp.is_in_db(dbif) == False:

Modified: grass/trunk/lib/python/temporal/mapcalc.py
===================================================================
--- grass/trunk/lib/python/temporal/mapcalc.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/mapcalc.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -42,7 +42,7 @@
     """
     
     # We need a database interface for fast computation
-    dbif = sql_database_interface_connection()
+    dbif = ()
     dbif.connect()
 
     mapset =  core.gisenv()["MAPSET"]

Modified: grass/trunk/lib/python/temporal/metadata.py
===================================================================
--- grass/trunk/lib/python/temporal/metadata.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/metadata.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -6,13 +6,14 @@
 
 Usage:
 
- at code
-import grass.temporal as tgis
+>>> import grass.temporal as tgis
+>>> meta = tgis.RasterMetadata()
+>>> meta = tgis.Raster3DMetadata()
+>>> meta = tgis.VectorMetadata()
+>>> meta = tgis.STRDSMetadata()
+>>> meta = tgis.STR3DSMetadata()
+>>> meta = tgis.STVDSMetadata()
 
-meta = tgis.raster_metadata()
-...
- at endcode
-
 (C) 2008-2011 by the GRASS Development Team
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
@@ -24,139 +25,217 @@
 
 ###############################################################################
 
-class raster_metadata_base(sql_database_interface):
-    """!This is the raster metadata base class for raster and raster3d maps"""
-    def __init__(self, table=None, ident=None, datatype=None, cols=None, rows=None, number_of_cells=None, nsres=None, ewres=None, min=None, max=None):
 
-	sql_database_interface.__init__(self, table, ident)
+class RasterMetadataBase(SQLDatabaseInterface):
+    """!This is the metadata base class for time stamped raster and raster3d maps
+    
+        Usage:
+        
+        >>> import grass.temporal as tgis
+        >>> meta = tgis.RasterMetadataBase(table="metadata", ident="soil at PERMANENT",
+        ... datatype="CELL", cols=100, rows=100, number_of_cells=10000, nsres=0.1,
+        ... ewres=0.1, min=0, max=100)
+        >>> meta.datatype
+        'CELL'
+        >>> meta.cols
+        100
+        >>> meta.rows
+        100
+        >>> meta.number_of_cells
+        10000
+        >>> meta.nsres
+        0.1
+        >>> meta.ewres
+        0.1
+        >>> meta.min
+        0.0
+        >>> meta.max
+        100.0
+        >>> meta.print_info()
+         | Datatype:................... CELL
+         | Number of columns:.......... 100
+         | Number of rows:............. 100
+         | Number of cells:............ 10000
+         | North-South resolution:..... 0.1
+         | East-west resolution:....... 0.1
+         | Minimum value:.............. 0.0
+         | Maximum value:.............. 100.0
+        >>> meta.print_shell_info()
+        datatype=CELL
+        cols=100
+        rows=100
+        number_of_cells=10000
+        nsres=0.1
+        ewres=0.1
+        min=0.0
+        max=100.0
+    
+    """
+    def __init__(self, table=None, ident=None, datatype=None, cols=None, 
+		rows=None, number_of_cells=None, nsres=None, ewres=None, 
+		min=None, max=None):
 
-	self.set_id(ident)
-	self.set_datatype(datatype)
-	self.set_cols(cols)
-	self.set_rows(rows)
-	self.set_number_of_cells(number_of_cells)
-	self.set_nsres(nsres)
-	self.set_ewres(ewres)
-	self.set_min(min)
-	self.set_max(max)
+        SQLDatabaseInterface.__init__(self, table, ident)
 
+        self.set_id(ident)
+        self.set_datatype(datatype)
+        self.set_cols(cols)
+        self.set_rows(rows)
+        self.set_number_of_cells(number_of_cells)
+        self.set_nsres(nsres)
+        self.set_ewres(ewres)
+        self.set_min(min)
+        self.set_max(max)
+
     def set_id(self, ident):
-	"""!Convenient method to set the unique identifier (primary key)"""
-	self.ident = ident
-	self.D["id"] = ident
+        """!Convenient method to set the unique identifier (primary key)"""
+        self.ident = ident
+        self.D["id"] = ident
 
     def set_datatype(self, datatype):
-	"""!Set the datatype"""
-	self.D["datatype"] = datatype
+        """!Set the datatype"""
+        self.D["datatype"] = datatype
 
     def set_cols(self, cols):
-	"""!Set the number of cols"""
-	self.D["cols"] = cols
+        """!Set the number of cols"""
+        if cols is not None:
+            self.D["cols"] = int(cols)
+        else:
+            self.D["cols"] = None
 
     def set_rows(self, rows):
-	"""!Set the number of rows"""
-	self.D["rows"] = rows
+        """!Set the number of rows"""
+        if rows is not None:
+            self.D["rows"] = int(rows)
+        else:
+            self.D["rows"] = None
 
     def set_number_of_cells(self, number_of_cells):
-	"""!Set the number of cells"""
-	self.D["number_of_cells"] = number_of_cells
+        """!Set the number of cells"""
+        if number_of_cells is not None:
+            self.D["number_of_cells"] = int(number_of_cells)
+        else:
+            self.D["number_of_cells"] = None
 
     def set_nsres(self, nsres):
-	"""!Set the north-south resolution"""
-	self.D["nsres"] = nsres
+        """!Set the north-south resolution"""
+        if nsres is not None:
+            self.D["nsres"] = float(nsres)
+        else:
+            self.D["nsres"] = None
 
     def set_ewres(self, ewres):
-	"""!Set the east-west resolution"""
-	self.D["ewres"] = ewres
+        """!Set the east-west resolution"""
+        if ewres is not None:
+            self.D["ewres"] = float(ewres)
+        else:
+            self.D["ewres"] = None
 
     def set_min(self, min):
-	"""!Set the minimum raster value"""
-	self.D["min"] = min
+        """!Set the minimum raster value"""
+        if min is not None:
+            self.D["min"] = float(min)
+        else:
+            self.D["min"] = None
 
     def set_max(self, max):
-	"""!Set the maximum raster value"""
-	self.D["max"] = max
+        """!Set the maximum raster value"""
+        if max is not None:
+            self.D["max"] = float(max)
+        else:
+            self.D["max"] = None
 
     def get_id(self):
-	"""!Convenient method to get the unique identifier (primary key)
-	   @return None if not found
-	"""
-	if self.D.has_key("id"):
-	    return self.D["id"]
+        """!Convenient method to get the unique identifier (primary key)
+           @return None if not found
+        """
+        if "id" in self.D:
+            return self.D["id"]
         else:
-	    return None
+            return None
 
     def get_datatype(self):
-	"""!Get the map type 
-	   @return None if not found"""
-	if self.D.has_key("datatype"):
-	    return self.D["datatype"]
+        """!Get the map type
+           @return None if not found"""
+        if "datatype" in self.D:
+            return self.D["datatype"]
         else:
-	    return None
+            return None
 
     def get_cols(self):
-	"""!Get number of cols 
-	   @return None if not found"""
-	if self.D.has_key("cols"):
-	    return self.D["cols"]
+        """!Get number of cols
+           @return None if not found"""
+        if "cols" in self.D:
+            return self.D["cols"]
         else:
-	    return None
+            return None
 
     def get_rows(self):
-	"""!Get number of rows
-	   @return None if not found"""
-	if self.D.has_key("rows"):
-	    return self.D["rows"]
+        """!Get number of rows
+           @return None if not found"""
+        if "rows" in self.D:
+            return self.D["rows"]
         else:
-	    return None
+            return None
 
     def get_number_of_cells(self):
-	"""!Get number of cells 
-	   @return None if not found"""
-	if self.D.has_key("number_of_cells"):
-	    return self.D["number_of_cells"]
+        """!Get number of cells
+           @return None if not found"""
+        if "number_of_cells" in self.D:
+            return self.D["number_of_cells"]
         else:
-	    return None
+            return None
 
     def get_nsres(self):
-	"""!Get the north-south resolution
-	   @return None if not found"""
-	if self.D.has_key("nsres"):
-	    return self.D["nsres"]
+        """!Get the north-south resolution
+           @return None if not found"""
+        if "nsres" in self.D:
+            return self.D["nsres"]
         else:
-	    return None
+            return None
 
     def get_ewres(self):
-	"""!Get east-west resolution
-	   @return None if not found"""
-	if self.D.has_key("ewres"):
-	    return self.D["ewres"]
+        """!Get east-west resolution
+           @return None if not found"""
+        if "ewres" in self.D:
+            return self.D["ewres"]
         else:
-	    return None
+            return None
 
     def get_min(self):
-	"""!Get the minimum cell value 
-	   @return None if not found"""
-	if self.D.has_key("min"):
-	    return self.D["min"]
+        """!Get the minimum cell value
+           @return None if not found"""
+        if "min" in self.D:
+            return self.D["min"]
         else:
-	    return None
+            return None
 
     def get_max(self):
-	"""!Get the maximum cell value 
-	   @return None if not found"""
-	if self.D.has_key("max"):
-	    return self.D["max"]
+        """!Get the maximum cell value
+           @return None if not found"""
+        if "max" in self.D:
+            return self.D["max"]
         else:
-	    return None
-
+            return None
+    
+    # Properties
+    datatype = property(fget=get_datatype, fset=set_datatype)
+    cols = property(fget=get_cols, fset=set_cols)
+    rows = property(fget=get_rows, fset=set_rows)
+    number_of_cells = property(fget=get_number_of_cells, fset=set_number_of_cells)
+    nsres = property(fget=get_nsres, fset=set_nsres)
+    ewres = property(fget=get_ewres, fset=set_ewres)
+    min = property(fget=get_min, fset=set_min)
+    max = property(fget=get_max, fset=set_max)
+    
     def print_info(self):
         """!Print information about this class in human readable style"""
         #      0123456789012345678901234567890
         print " | Datatype:................... " + str(self.get_datatype())
         print " | Number of columns:.......... " + str(self.get_cols())
         print " | Number of rows:............. " + str(self.get_rows())
-        print " | Number of cells:............ " + str(self.get_number_of_cells())
+        print " | Number of cells:............ " + str(
+            self.get_number_of_cells())
         print " | North-South resolution:..... " + str(self.get_nsres())
         print " | East-west resolution:....... " + str(self.get_ewres())
         print " | Minimum value:.............. " + str(self.get_min())
@@ -175,413 +254,695 @@
 
 ###############################################################################
 
-class raster_metadata(raster_metadata_base):
-    """!This is the raster metadata class"""
-    def __init__(self, ident=None, strds_register=None, datatype=None, cols=None, rows=None, number_of_cells=None, nsres=None, ewres=None, min=None, max=None):
 
-	raster_metadata_base.__init__(self, "raster_metadata", ident, datatype, cols, rows, number_of_cells, nsres, ewres, min, max)
+class RasterMetadata(RasterMetadataBase):
+    """!This is the raster metadata class
+       
+        This class is the interface to the raster_metadata table in the
+        temporal database that stores the metadata of all registered raster maps.
+        
+        The metadata includes the datatype, number of cols, rows and cells and
+        the north-south and east west resolution of the map. Additionally the 
+        minimum and maximum values and the name of the space time raster dataset
+        register table is stored.
+       
+        Usage:
+       
+        >>> import grass.temporal as tgis
+        >>> meta = tgis.RasterMetadata(ident="soil at PERMANENT",
+        ... datatype="CELL", cols=100, rows=100, number_of_cells=10000, nsres=0.1,
+        ... ewres=0.1, min=0, max=100)
+        >>> meta.datatype
+        'CELL'
+        >>> meta.cols
+        100
+        >>> meta.rows
+        100
+        >>> meta.number_of_cells
+        10000
+        >>> meta.nsres
+        0.1
+        >>> meta.ewres
+        0.1
+        >>> meta.min
+        0.0
+        >>> meta.max
+        100.0
+        >>> meta.strds_register
+        >>> meta.print_info()
+         +-------------------- Metadata information ----------------------------------+
+         | Datatype:................... CELL
+         | Number of columns:.......... 100
+         | Number of rows:............. 100
+         | Number of cells:............ 10000
+         | North-South resolution:..... 0.1
+         | East-west resolution:....... 0.1
+         | Minimum value:.............. 0.0
+         | Maximum value:.............. 100.0
+         | STRDS register table ....... None
+        >>> meta.print_shell_info()
+        datatype=CELL
+        cols=100
+        rows=100
+        number_of_cells=10000
+        nsres=0.1
+        ewres=0.1
+        min=0.0
+        max=100.0
+        strds_register=None
+    """
+    def __init__(self, ident=None, strds_register=None, datatype=None, 
+		 cols=None, rows=None, number_of_cells=None, nsres=None, 
+		 ewres=None, min=None, max=None):
 
-	self.set_strds_register(strds_register)
+        RasterMetadataBase.__init__(self, "raster_metadata", ident, datatype,
+                                      cols, rows, number_of_cells, nsres, 
+                                      ewres, min, max)
 
+        self.set_strds_register(strds_register)
+
     def set_strds_register(self, strds_register):
-	"""!Set the space time raster dataset register table name"""
-	self.D["strds_register"] = strds_register
+        """!Set the space time raster dataset register table name"""
+        self.D["strds_register"] = strds_register
 
     def get_strds_register(self):
-	"""!Get the space time raster dataset register table name
-	   @return None if not found"""
-	if self.D.has_key("strds_register"):
-	    return self.D["strds_register"]
+        """!Get the space time raster dataset register table name
+           @return None if not found"""
+        if "strds_register" in self.D:
+            return self.D["strds_register"]
         else:
-	    return None
+            return None
+        
+    strds_register = property(fget=get_strds_register, fset=set_strds_register)
 
     def print_info(self):
         """!Print information about this class in human readable style"""
         print " +-------------------- Metadata information ----------------------------------+"
         #      0123456789012345678901234567890
-        raster_metadata_base.print_info(self)
-        print " | STRDS register table ....... " + str(self.get_strds_register())
+        RasterMetadataBase.print_info(self)
+        print " | STRDS register table ....... " + str(
+            self.get_strds_register())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-        raster_metadata_base.print_shell_info(self)
+        RasterMetadataBase.print_shell_info(self)
         print "strds_register=" + str(self.get_strds_register())
 
 ###############################################################################
 
-class raster3d_metadata(raster_metadata_base):
-    """!This is the raster3d metadata class"""
-    def __init__(self, ident=None, str3ds_register=None, datatype=None, cols=None, rows=None, depths=None, number_of_cells=None, nsres=None, ewres=None, tbres=None, min=None, max=None):
 
-	raster_metadata_base.__init__(self, "raster3d_metadata", ident, datatype, cols, rows, number_of_cells, nsres, ewres, min, max)
+class Raster3DMetadata(RasterMetadataBase):
+    """!This is the raster3d metadata class
+       
+        This class is the interface to the raster3d_metadata table in the
+        temporal database that stores the metadata of all registered 
+        3D raster maps.
+        
+        The metadata includes all raster metadata variables and additional
+        the number of depths, the top-bottom resolution and the space time 3D
+        raster dataset register table is stored.
+       
+        Usage:
+       
+        >>> import grass.temporal as tgis
+        >>> meta = tgis.Raster3DMetadata(ident="soil at PERMANENT",
+        ... datatype="FCELL", cols=100, rows=100, depths=100,
+        ... number_of_cells=1000000, nsres=0.1, ewres=0.1, tbres=0.1,
+        ... min=0, max=100)
+        >>> meta.datatype
+        'FCELL'
+        >>> meta.cols
+        100
+        >>> meta.rows
+        100
+        >>> meta.depths
+        100
+        >>> meta.number_of_cells
+        1000000
+        >>> meta.nsres
+        0.1
+        >>> meta.ewres
+        0.1
+        >>> meta.tbres
+        0.1
+        >>> meta.min
+        0.0
+        >>> meta.max
+        100.0
+        >>> meta.str3ds_register
+        >>> meta.print_info()
+         +-------------------- Metadata information ----------------------------------+
+         | Datatype:................... FCELL
+         | Number of columns:.......... 100
+         | Number of rows:............. 100
+         | Number of cells:............ 1000000
+         | North-South resolution:..... 0.1
+         | East-west resolution:....... 0.1
+         | Minimum value:.............. 0.0
+         | Maximum value:.............. 100.0
+         | Number of depths:........... 100
+         | Top-Bottom resolution:...... 0.1
+         | STR3DS register table ...... None
+        >>> meta.print_shell_info()
+        datatype=FCELL
+        cols=100
+        rows=100
+        number_of_cells=1000000
+        nsres=0.1
+        ewres=0.1
+        min=0.0
+        max=100.0
+        str3ds_register=None
+        depths=100
+        tbres=0.1
+    """
+    def __init__(self, ident=None, str3ds_register=None, datatype=None, 
+		 cols=None, rows=None, depths=None, number_of_cells=None, 
+		 nsres=None, ewres=None, tbres=None, min=None, max=None):
 
-	self.set_str3ds_register(str3ds_register)
-	self.set_tbres(tbres)
-	self.set_depths(depths)
+        RasterMetadataBase.__init__(self, "raster3d_metadata", ident, 
+				datatype, cols, rows, number_of_cells, nsres, 
+				ewres, min, max)
 
+        self.set_str3ds_register(str3ds_register)
+        self.set_tbres(tbres)
+        self.set_depths(depths)
+
     def set_str3ds_register(self, str3ds_register):
-	"""!Set the space time raster3d dataset register table name"""
-	self.D["str3ds_register"] = str3ds_register
+        """!Set the space time raster3d dataset register table name"""
+        self.D["str3ds_register"] = str3ds_register
 
     def set_depths(self, depths):
-	"""!Set the number of depths"""
-	self.D["depths"] = depths
+        """!Set the number of depths"""
+        if depths is not None:
+            self.D["depths"] = int(depths)
+        else:
+            self.D["depths"] = None
 
     def set_tbres(self, tbres):
-	"""!Set the top-bottom resolution"""
-	self.D["tbres"] = tbres
+        """!Set the top-bottom resolution"""
+        if tbres is not None:
+            self.D["tbres"] = float(tbres)
+        else:
+            self.D["tbres"] = None
 
     def get_str3ds_register(self):
-	"""!Get the space time raster3d dataset register table name
-	   @return None if not found"""
-	if self.D.has_key("str3ds_register"):
-	    return self.D["str3ds_register"]
+        """!Get the space time raster3d dataset register table name
+           @return None if not found"""
+        if "str3ds_register" in self.D:
+            return self.D["str3ds_register"]
         else:
-	    return None
+            return None
 
     def get_depths(self):
-	"""!Get number of depths
-	   @return None if not found"""
-	if self.D.has_key("depths"):
-	    return self.D["depths"]
+        """!Get number of depths
+           @return None if not found"""
+        if "depths" in self.D:
+            return self.D["depths"]
         else:
-	    return None
+            return None
 
     def get_tbres(self):
-	"""!Get top-bottom resolution
-	   @return None if not found"""
-	if self.D.has_key("tbres"):
-	    return self.D["tbres"]
+        """!Get top-bottom resolution
+           @return None if not found"""
+        if "tbres" in self.D:
+            return self.D["tbres"]
         else:
-	    return None
+            return None
 
+    depths = property(fget=get_depths, fset=set_depths)
+    tbres = property(fget=get_tbres, fset=set_tbres)
+    str3ds_register = property(fget=get_str3ds_register, fset=set_str3ds_register)
+    
     def print_info(self):
         """!Print information about this class in human readable style"""
         print " +-------------------- Metadata information ----------------------------------+"
         #      0123456789012345678901234567890
-        raster_metadata_base.print_info(self)
+        RasterMetadataBase.print_info(self)
         #      0123456789012345678901234567890
         print " | Number of depths:........... " + str(self.get_depths())
         print " | Top-Bottom resolution:...... " + str(self.get_tbres())
-        print " | STR3DS register table ...... " + str(self.get_str3ds_register())
+        print " | STR3DS register table ...... " + str(
+                                                self.get_str3ds_register())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
+        RasterMetadataBase.print_shell_info(self)
         print "str3ds_register=" + str(self.get_str3ds_register())
         print "depths=" + str(self.get_depths())
         print "tbres=" + str(self.get_tbres())
-        raster_metadata_base.print_shell_info(self)
-        
+
 ###############################################################################
 
-class vector_metadata(sql_database_interface):
-    """!This is the vector metadata class"""
-    def __init__(self, ident=None, stvds_register=None, is_3d=False, points=None, lines=None, boundaries=None,\
-                 centroids=None, faces=None, kernels=None, primitives=None, nodes=None, areas=None, \
-                 islands=None, holes=None, volumes=None):
 
-	sql_database_interface.__init__(self, "vector_metadata", ident)
+class VectorMetadata(SQLDatabaseInterface):
+    """!This is the vector metadata class
+       
+        This class is the interface to the vector_metadata table in the
+        temporal database that stores the metadata of all registered 
+        3D raster maps.
+        
+        The metadata includes all raster metadata variables and additional
+        the number of depths, the top-bottom resolution and the space time 3D
+        raster dataset register table is stored.
+       
+        Usage:
+       
+        >>> import grass.temporal as tgis
+        >>> meta = VectorMetadata(ident="lidar at PERMANENT", is_3d=True, 
+        ... number_of_points=1, number_of_lines=2, number_of_boundaries=3,
+        ... number_of_centroids=4, number_of_faces=5, number_of_kernels=6, 
+        ... number_of_primitives=7, number_of_nodes=8, number_of_areas=9,
+        ... number_of_islands=10, number_of_holes=11, number_of_volumes=12)
+        >>> meta.id
+        'lidar at PERMANENT'
+        >>> meta.is_3d
+        True
+        >>> meta.number_of_points
+        1
+        >>> meta.number_of_lines
+        2
+        >>> meta.number_of_boundaries
+        3
+        >>> meta.number_of_centroids
+        4
+        >>> meta.number_of_faces
+        5
+        >>> meta.number_of_kernels
+        6
+        >>> meta.number_of_primitives
+        7
+        >>> meta.number_of_nodes
+        8
+        >>> meta.number_of_areas
+        9
+        >>> meta.number_of_islands
+        10
+        >>> meta.number_of_holes
+        11
+        >>> meta.number_of_volumes
+        12
+        >>> meta.print_info()
+         +-------------------- Metadata information ----------------------------------+
+         | STVDS register table ....... None
+         | Is map 3d .................. True
+         | Number of points ........... 1
+         | Number of lines ............ 2
+         | Number of boundaries ....... 3
+         | Number of centroids ........ 4
+         | Number of faces ............ 5
+         | Number of kernels .......... 6
+         | Number of primitives ....... 7
+         | Number of nodes ............ 8
+         | Number of areas ............ 9
+         | Number of islands .......... 10
+         | Number of holes ............ 11
+         | Number of volumes .......... 12
+        >>> meta.print_shell_info()
+        stvds_register=None
+        is_3d=True
+        points=1
+        lines=2
+        boundaries=3
+        centroids=4
+        faces=5
+        kernels=6
+        primitives=7
+        nodes=8
+        areas=9
+        islands=10
+        holes=11
+        volumes=12
+    """
+    def __init__(
+        self, ident=None, stvds_register=None, is_3d=False, 
+        number_of_points=None, number_of_lines=None, number_of_boundaries=None,
+        number_of_centroids=None, number_of_faces=None, number_of_kernels=None, 
+        number_of_primitives=None, number_of_nodes=None, number_of_areas=None,
+        number_of_islands=None, number_of_holes=None, number_of_volumes=None):
 
-	self.set_id(ident)
-	self.set_stvds_register(stvds_register)
-	self.set_3d_info(is_3d)
-	self.set_points(points)
-	self.set_lines(lines)
-	self.set_boundaries(boundaries)
-	self.set_centroids(centroids)
-	self.set_faces(faces)
-	self.set_kernels(kernels)
-	self.set_primitives(primitives)
-	self.set_nodes(nodes)
-	self.set_areas(areas)
-	self.set_islands(islands)
-	self.set_holes(holes)
-	self.set_volumes(volumes)
+        SQLDatabaseInterface.__init__(self, "vector_metadata", ident)
 
+        self.set_id(ident)
+        self.set_stvds_register(stvds_register)
+        self.set_3d_info(is_3d)
+        self.set_number_of_points(number_of_points)
+        self.set_number_of_lines(number_of_lines)
+        self.set_number_of_boundaries(number_of_boundaries)
+        self.set_number_of_centroids(number_of_centroids)
+        self.set_number_of_faces(number_of_faces)
+        self.set_number_of_kernels(number_of_kernels)
+        self.set_number_of_primitives(number_of_primitives)
+        self.set_number_of_nodes(number_of_nodes)
+        self.set_number_of_areas(number_of_areas)
+        self.set_number_of_islands(number_of_islands)
+        self.set_number_of_holes(number_of_holes)
+        self.set_number_of_volumes(number_of_volumes)
+
     def set_id(self, ident):
-	"""!Convenient method to set the unique identifier (primary key)"""
-	self.ident = ident
-	self.D["id"] = ident
+        """!Convenient method to set the unique identifier (primary key)"""
+        self.ident = ident
+        self.D["id"] = ident
 
     def set_stvds_register(self, stvds_register):
-	"""!Set the space time vector dataset register table name"""
-	self.D["stvds_register"] = stvds_register
+        """!Set the space time vector dataset register table name"""
+        self.D["stvds_register"] = stvds_register
 
     def set_3d_info(self, is_3d):
-	"""!Set True if the vector map is three dimensional"""
-	self.D["is_3d"] = is_3d
+        """!Set True if the vector map is three dimensional"""
+        self.D["is_3d"] = is_3d
 
-    def set_points(self, points):
-	"""!Set the number of points of the vector map"""
-	self.D["points"] = points
+    def set_number_of_points(self, number_of_points):
+        """!Set the number of points of the vector map"""
+        self.D["points"] = number_of_points
 
-    def set_lines(self, lines):
-	"""!Set the number of lines of the vector map"""
-	self.D["lines"] = lines
+    def set_number_of_lines(self, number_of_lines):
+        """!Set the number of lines of the vector map"""
+        self.D["lines"] = number_of_lines
 
-    def set_boundaries(self, boundaries):
-	"""!Set the number of boundaries of the vector map"""
-	self.D["boundaries"] = boundaries
+    def set_number_of_boundaries(self, number_of_boundaries):
+        """!Set the number of boundaries of the vector map"""
+        self.D["boundaries"] = number_of_boundaries
 
-    def set_centroids(self, centroids):
-	"""!Set the number of centroids of the vector map"""
-	self.D["centroids"] = centroids
+    def set_number_of_centroids(self, number_of_centroids):
+        """!Set the number of centroids of the vector map"""
+        self.D["centroids"] = number_of_centroids
 
-    def set_faces(self, faces):
-	"""!Set the number of faces of the vector map"""
-	self.D["faces"] = faces
+    def set_number_of_faces(self, number_of_faces):
+        """!Set the number of faces of the vector map"""
+        self.D["faces"] = number_of_faces
 
-    def set_kernels(self, kernels):
-	"""!Set the number of kernels of the vector map"""
-	self.D["kernels"] = kernels
+    def set_number_of_kernels(self, number_of_kernels):
+        """!Set the number of kernels of the vector map"""
+        self.D["kernels"] = number_of_kernels
 
-    def set_primitives(self, primitives):
-	"""!Set the number of primitives of the vector map"""
-	self.D["primitives"] = primitives
+    def set_number_of_primitives(self, number_of_primitives):
+        """!Set the number of primitives of the vector map"""
+        self.D["primitives"] = number_of_primitives
 
-    def set_nodes(self, nodes):
-	"""!Set the number of nodes of the vector map"""
-	self.D["nodes"] = nodes
+    def set_number_of_nodes(self, number_of_nodes):
+        """!Set the number of nodes of the vector map"""
+        self.D["nodes"] = number_of_nodes
 
-    def set_areas(self, areas):
-	"""!Set the number of areas of the vector map"""
-	self.D["areas"] = areas
-	
-    def set_islands(self, islands):
-	"""!Set the number of islands of the vector map"""
-	self.D["islands"] = islands
-	
-    def set_holes(self, holes):
-	"""!Set the number of holes of the vector map"""
-	self.D["holes"] = holes
-	
-    def set_volumes(self, volumes):
-	"""!Set the number of volumes of the vector map"""
-	self.D["volumes"] = volumes
+    def set_number_of_areas(self, number_of_areas):
+        """!Set the number of areas of the vector map"""
+        self.D["areas"] = number_of_areas
 
+    def set_number_of_islands(self, number_of_islands):
+        """!Set the number of islands of the vector map"""
+        self.D["islands"] = number_of_islands
+
+    def set_number_of_holes(self, number_of_holes):
+        """!Set the number of holes of the vector map"""
+        self.D["holes"] = number_of_holes
+
+    def set_number_of_volumes(self, number_of_volumes):
+        """!Set the number of volumes of the vector map"""
+        self.D["volumes"] = number_of_volumes
+
     def get_id(self):
-	"""!Convenient method to get the unique identifier (primary key)
-	   @return None if not found
-	"""
-	if self.D.has_key("id"):
-	    return self.D["id"]
+        """!Convenient method to get the unique identifier (primary key)
+           @return None if not found
+        """
+        if "id" in self.D:
+            return self.D["id"]
         else:
-	    return None
+            return None
 
     def get_stvds_register(self):
-	"""!Get the space time vector dataset register table name
-	   @return None if not found"""
-	if self.D.has_key("stvds_register"):
-	    return self.D["stvds_register"]
+        """!Get the space time vector dataset register table name
+           @return None if not found"""
+        if "stvds_register" in self.D:
+            return self.D["stvds_register"]
         else:
-	    return None
-    
+            return None
+
     def get_3d_info(self):
-	"""!Return True if the map is three dimensional, False if not and None if not info was found"""
-	if self.D.has_key("is_3d"):
-	    return self.D["is_3d"]
+        """!Return True if the map is three dimensional, False if not and None if not info was found"""
+        if "is_3d" in self.D:
+            return self.D["is_3d"]
         else:
-	    return None
+            return None
 
-    def get_points(self):
-	"""!Get the number of points of the vector map
-	   @return None if not found"""
-	if self.D.has_key("points"):
-	    return self.D["points"]
+    def get_number_of_points(self):
+        """!Get the number of points of the vector map
+           @return None if not found"""
+        if "points" in self.D:
+            return self.D["points"]
         else:
-	    return None
-	    
-    def get_lines(self):
-	"""!Get the number of lines of the vector map
-	   @return None if not found"""
-	if self.D.has_key("lines"):
-	    return self.D["lines"]
+            return None
+
+    def get_number_of_lines(self):
+        """!Get the number of lines of the vector map
+           @return None if not found"""
+        if "lines" in self.D:
+            return self.D["lines"]
         else:
-	    return None
-	    
-    def get_boundaries(self):
-	"""!Get the number of boundaries of the vector map
-	   @return None if not found"""
-	if self.D.has_key("boundaries"):
-	    return self.D["boundaries"]
+            return None
+
+    def get_number_of_boundaries(self):
+        """!Get the number of boundaries of the vector map
+           @return None if not found"""
+        if "boundaries" in self.D:
+            return self.D["boundaries"]
         else:
-	    return None
-	    
-    def get_centroids(self):
-	"""!Get the number of centroids of the vector map
-	   @return None if not found"""
-	if self.D.has_key("centroids"):
-	    return self.D["centroids"]
+            return None
+
+    def get_number_of_centroids(self):
+        """!Get the number of centroids of the vector map
+           @return None if not found"""
+        if "centroids" in self.D:
+            return self.D["centroids"]
         else:
-	    return None
-	    
-    def get_faces(self):
-	"""!Get the number of faces of the vector map
-	   @return None if not found"""
-	if self.D.has_key("faces"):
-	    return self.D["faces"]
+            return None
+
+    def get_number_of_faces(self):
+        """!Get the number of faces of the vector map
+           @return None if not found"""
+        if "faces" in self.D:
+            return self.D["faces"]
         else:
-	    return None
-	    
-    def get_kernels(self):
-	"""!Get the number of kernels of the vector map
-	   @return None if not found"""
-	if self.D.has_key("kernels"):
-	    return self.D["kernels"]
+            return None
+
+    def get_number_of_kernels(self):
+        """!Get the number of kernels of the vector map
+           @return None if not found"""
+        if "kernels" in self.D:
+            return self.D["kernels"]
         else:
-	    return None
-	    
-    def get_primitives(self):
-	"""!Get the number of primitives of the vector map
-	   @return None if not found"""
-	if self.D.has_key("primitives"):
-	    return self.D["primitives"]
+            return None
+
+    def get_number_of_primitives(self):
+        """!Get the number of primitives of the vector map
+           @return None if not found"""
+        if "primitives" in self.D:
+            return self.D["primitives"]
         else:
-	    return None
-	    
-    def get_nodes(self):
-	"""!Get the number of nodes of the vector map
-	   @return None if not found"""
-	if self.D.has_key("nodes"):
-	    return self.D["nodes"]
+            return None
+
+    def get_number_of_nodes(self):
+        """!Get the number of nodes of the vector map
+           @return None if not found"""
+        if "nodes" in self.D:
+            return self.D["nodes"]
         else:
-	    return None
-	    
-    def get_areas(self):
-	"""!Get the number of areas of the vector map
-	   @return None if not found"""
-	if self.D.has_key("areas"):
-	    return self.D["areas"]
+            return None
+
+    def get_number_of_areas(self):
+        """!Get the number of areas of the vector map
+           @return None if not found"""
+        if "areas" in self.D:
+            return self.D["areas"]
         else:
-	    return None
-	    
-    def get_islands(self):
-	"""!Get the number of islands of the vector map
-	   @return None if not found"""
-	if self.D.has_key("islands"):
-	    return self.D["islands"]
+            return None
+
+    def get_number_of_islands(self):
+        """!Get the number of islands of the vector map
+           @return None if not found"""
+        if "islands" in self.D:
+            return self.D["islands"]
         else:
-	    return None
-	    
-    def get_holes(self):
-	"""!Get the number of holes of the vector map
-	   @return None if not found"""
-	if self.D.has_key("holes"):
-	    return self.D["holes"]
+            return None
+
+    def get_number_of_holes(self):
+        """!Get the number of holes of the vector map
+           @return None if not found"""
+        if "holes" in self.D:
+            return self.D["holes"]
         else:
-	    return None
-	    
-    def get_volumes(self):
-	"""!Get the number of volumes of the vector map
-	   @return None if not found"""
-	if self.D.has_key("volumes"):
-	    return self.D["volumes"]
+            return None
+
+    def get_number_of_volumes(self):
+        """!Get the number of volumes of the vector map
+           @return None if not found"""
+        if "volumes" in self.D:
+            return self.D["volumes"]
         else:
-	    return None
-
+            return None
+    
+    # Set the properties
+    id  = property(fget=get_id, fset=set_id)
+    stvds_register  = property(fget=get_stvds_register, 
+                               fset=set_stvds_register)
+    is_3d  = property(fget=get_3d_info, fset=set_3d_info)
+    number_of_points = property(fget=get_number_of_points, 
+                                fset=set_number_of_points)
+    number_of_lines = property(fget=get_number_of_lines, 
+                               fset=set_number_of_lines)
+    number_of_boundaries = property(fget=get_number_of_boundaries, 
+                                    fset=set_number_of_boundaries)
+    number_of_centroids = property(fget=get_number_of_centroids, 
+                                   fset=set_number_of_centroids)
+    number_of_faces = property(fget=get_number_of_faces, 
+                               fset=set_number_of_faces)
+    number_of_kernels = property(fget=get_number_of_kernels, 
+                                 fset=set_number_of_kernels)
+    number_of_primitives = property(fget=get_number_of_primitives, 
+                                    fset=set_number_of_primitives)
+    number_of_nodes = property(fget=get_number_of_nodes, 
+                               fset=set_number_of_nodes)
+    number_of_areas = property(fget=get_number_of_areas, 
+                               fset=set_number_of_areas)
+    number_of_islands = property(fget=get_number_of_islands, 
+                                 fset=set_number_of_islands)
+    number_of_holes = property(fget=get_number_of_holes, 
+                               fset=set_number_of_holes)
+    number_of_volumes = property(fget=get_number_of_volumes, 
+                                 fset=set_number_of_volumes)
+        
     def print_info(self):
         """!Print information about this class in human readable style"""
         #      0123456789012345678901234567890
         print " +-------------------- Metadata information ----------------------------------+"
-        print " | STVDS register table ....... " + str(self.get_stvds_register())
+        print " | STVDS register table ....... " + str(
+            self.get_stvds_register())
         print " | Is map 3d .................. " + str(self.get_3d_info())
-        print " | Number of points ........... " + str(self.get_points())
-        print " | Number of lines ............ " + str(self.get_lines())
-        print " | Number of boundaries ....... " + str(self.get_boundaries())
-        print " | Number of centroids ........ " + str(self.get_centroids())
-        print " | Number of faces ............ " + str(self.get_faces())
-        print " | Number of kernels .......... " + str(self.get_kernels())
-        print " | Number of primitives ....... " + str(self.get_primitives())
-        print " | Number of nodes ............ " + str(self.get_nodes())
-        print " | Number of areas ............ " + str(self.get_areas())
-        print " | Number of islands .......... " + str(self.get_islands())
-        print " | Number of holes ............ " + str(self.get_holes())
-        print " | Number of volumes .......... " + str(self.get_volumes())
+        print " | Number of points ........... " + str(self.get_number_of_points())
+        print " | Number of lines ............ " + str(self.get_number_of_lines())
+        print " | Number of boundaries ....... " + str(self.get_number_of_boundaries())
+        print " | Number of centroids ........ " + str(self.get_number_of_centroids())
+        print " | Number of faces ............ " + str(self.get_number_of_faces())
+        print " | Number of kernels .......... " + str(self.get_number_of_kernels())
+        print " | Number of primitives ....... " + str(self.get_number_of_primitives())
+        print " | Number of nodes ............ " + str(self.get_number_of_nodes())
+        print " | Number of areas ............ " + str(self.get_number_of_areas())
+        print " | Number of islands .......... " + str(self.get_number_of_islands())
+        print " | Number of holes ............ " + str(self.get_number_of_holes())
+        print " | Number of volumes .......... " + str(self.get_number_of_volumes())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
         print "stvds_register=" + str(self.get_stvds_register())
         print "is_3d=" + str(self.get_3d_info())
-        print "points=" + str(self.get_points())
-        print "lines=" + str(self.get_lines())
-        print "boundaries=" + str(self.get_boundaries())
-        print "centroids=" + str(self.get_centroids())
-        print "faces=" + str(self.get_faces())
-        print "kernels=" + str(self.get_kernels())
-        print "primitives=" + str(self.get_primitives())
-        print "nodes=" + str(self.get_nodes())
-        print "areas=" + str(self.get_areas())
-        print "islands=" + str(self.get_islands())
-        print "holes=" + str(self.get_holes())
-        print "volumes=" + str(self.get_volumes())
+        print "points=" + str(self.get_number_of_points())
+        print "lines=" + str(self.get_number_of_lines())
+        print "boundaries=" + str(self.get_number_of_boundaries())
+        print "centroids=" + str(self.get_number_of_centroids())
+        print "faces=" + str(self.get_number_of_faces())
+        print "kernels=" + str(self.get_number_of_kernels())
+        print "primitives=" + str(self.get_number_of_primitives())
+        print "nodes=" + str(self.get_number_of_nodes())
+        print "areas=" + str(self.get_number_of_areas())
+        print "islands=" + str(self.get_number_of_islands())
+        print "holes=" + str(self.get_number_of_holes())
+        print "volumes=" + str(self.get_number_of_volumes())
 
 ###############################################################################
 
-class stds_metadata_base(sql_database_interface):
+
+class STDSMetadataBase(SQLDatabaseInterface):
     """!This is the space time dataset metadata base class for strds, stvds and str3ds datasets
        setting/getting the id, the title and the description
+       
+        Usage:
+        
+        >>> import grass.temporal as tgis
+        >>> meta = tgis.STDSMetadataBase(ident="soils at PERMANENT",
+        ... title="Soils", description="Soils 1950 - 2010")
+        >>> meta.id
+        'soils at PERMANENT'
+        >>> meta.title
+        'Soils'
+        >>> meta.description
+        'Soils 1950 - 2010'
+        >>> meta.number_of_maps
+        >>> meta.print_info()
+         | Number of registered maps:.. None
+         | Title:
+         | Soils
+         | Description:
+         | Soils 1950 - 2010
+        >>> meta.print_shell_info()
+        number_of_maps=None
     """
     def __init__(self, table=None, ident=None, title=None, description=None):
 
-	sql_database_interface.__init__(self, table, ident)
+        SQLDatabaseInterface.__init__(self, table, ident)
 
-	self.set_id(ident)
-	self.set_title(title)
-	self.set_description(description)
+        self.set_id(ident)
+        self.set_title(title)
+        self.set_description(description)
         # No setter for this
         self.D["number_of_maps"] = None
 
     def set_id(self, ident):
-	"""!Convenient method to set the unique identifier (primary key)"""
-	self.ident = ident
-	self.D["id"] = ident
+        """!Convenient method to set the unique identifier (primary key)"""
+        self.ident = ident
+        self.D["id"] = ident
 
     def set_title(self, title):
-	"""!Set the title"""
-	self.D["title"] = title
+        """!Set the title"""
+        self.D["title"] = title
 
     def set_description(self, description):
-	"""!Set the number of cols"""
-	self.D["description"] = description
+        """!Set the number of cols"""
+        self.D["description"] = description
 
     def get_id(self):
-	"""!Convenient method to get the unique identifier (primary key)
-	   @return None if not found
-	"""
-	if self.D.has_key("id"):
-	    return self.D["id"]
+        """!Convenient method to get the unique identifier (primary key)
+           @return None if not found
+        """
+        if "id" in self.D:
+            return self.D["id"]
         else:
-	    return None
+            return None
 
     def get_title(self):
-	"""!Get the title 
-	   @return None if not found"""
-	if self.D.has_key("title"):
-	    return self.D["title"]
+        """!Get the title
+           @return None if not found"""
+        if "title" in self.D:
+            return self.D["title"]
         else:
-	    return None
+            return None
 
     def get_description(self):
-	"""!Get description 
-	   @return None if not found"""
-	if self.D.has_key("description"):
-	    return self.D["description"]
+        """!Get description
+           @return None if not found"""
+        if "description" in self.D:
+            return self.D["description"]
         else:
-	    return None
+            return None
 
     def get_number_of_maps(self):
-	"""!Get the number of registered maps, this value is set in the database
-           automatically via SQL trigger, so no setter exists
-	   @return None if not found"""
-	if self.D.has_key("number_of_maps"):
-	    return self.D["number_of_maps"]
+        """!Get the number of registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "number_of_maps" in self.D:
+            return self.D["number_of_maps"]
         else:
-	    return None
-
+            return None
+        
+    id  = property(fget=get_id, fset=set_id)
+    title  = property(fget=get_title, fset=set_title)
+    description  = property(fget=get_description, fset=set_description)
+    number_of_maps  = property(fget=get_number_of_maps)
+    
     def print_info(self):
         """!Print information about this class in human readable style"""
         #      0123456789012345678901234567890
-        print " | Number of registered maps:.. " + str(self.get_number_of_maps())
+        print " | Number of registered maps:.. " + str(
+            self.get_number_of_maps())
         print " | Title:"
         print " | " + str(self.get_title())
         print " | Description:"
@@ -592,18 +953,64 @@
         print "number_of_maps=" + str(self.get_number_of_maps())
 
 ###############################################################################
-    
-class stds_raster_metadata_base(stds_metadata_base):
+
+
+class STDSRasterMetadataBase(STDSMetadataBase):
     """!This is the space time dataset metadata base class for strds and str3ds datasets
+
+       Most of the metadata values are set by triggers in the database when
+       new raster or voxel maps are added. Therefor only some set- an many get-functions
+       are available.
        
-       Most of the metadata values are set by triggers in the database when 
-       new raster of voxel maps are added. Therefor only some set- an many get-functions 
-       are available.
+        Usage:
+        
+        >>> import grass.temporal as tgis
+        >>> meta = tgis.STDSRasterMetadataBase(ident="soils at PERMANENT",
+        ... title="Soils", description="Soils 1950 - 2010")
+        >>> meta.id
+        'soils at PERMANENT'
+        >>> meta.title
+        'Soils'
+        >>> meta.description
+        'Soils 1950 - 2010'
+        >>> meta.number_of_maps
+        >>> meta.min_max
+        >>> meta.max_max
+        >>> meta.min_min
+        >>> meta.max_min
+        >>> meta.nsres_min
+        >>> meta.nsres_max
+        >>> meta.ewres_min
+        >>> meta.ewres_max
+        >>> meta.print_info()
+         | Number of registered maps:.. None
+         | Title:
+         | Soils
+         | Description:
+         | Soils 1950 - 2010
+         | North-South resolution min:. None
+         | North-South resolution max:. None
+         | East-west resolution min:... None
+         | East-west resolution max:... None
+         | Minimum value min:.......... None
+         | Minimum value max:.......... None
+         | Maximum value min:.......... None
+         | Maximum value max:.......... None
+        >>> meta.print_shell_info()
+        number_of_maps=None
+        nsres_min=None
+        nsres_max=None
+        ewres_min=None
+        ewres_max=None
+        min_min=None
+        min_max=None
+        max_min=None
+        max_max=None
     """
     def __init__(self, table=None, ident=None, title=None, description=None):
 
-	stds_metadata_base.__init__(self, table, ident, title, description)
-        
+        STDSMetadataBase.__init__(self, table, ident, title, description)
+
         # Initialize the dict to select all values from the db
         self.D["min_max"] = None
         self.D["max_max"] = None
@@ -615,80 +1022,97 @@
         self.D["ewres_max"] = None
 
     def get_max_min(self):
-	"""!Get the minimal maximum of all registered maps, this value is set in the database
-           automatically via SQL trigger, so no setter exists
-	   @return None if not found"""
-	if self.D.has_key("max_min"):
-	    return self.D["max_min"]
+        """!Get the minimal maximum of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "max_min" in self.D:
+            return self.D["max_min"]
         else:
-	    return None
+            return None
 
     def get_min_min(self):
-	"""!Get the minimal minimum of all registered maps, this value is set in the database
-           automatically via SQL trigger, so no setter exists
-	   @return None if not found"""
-	if self.D.has_key("min_min"):
-	    return self.D["min_min"]
+        """!Get the minimal minimum of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "min_min" in self.D:
+            return self.D["min_min"]
         else:
-	    return None
+            return None
 
     def get_max_max(self):
-	"""!Get the maximal maximum of all registered maps, this value is set in the database
-           automatically via SQL trigger, so no setter exists
-	   @return None if not found"""
-	if self.D.has_key("max_max"):
-	    return self.D["max_max"]
+        """!Get the maximal maximum of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "max_max" in self.D:
+            return self.D["max_max"]
         else:
-	    return None
+            return None
 
     def get_min_max(self):
-	"""!Get the maximal minimum of all registered maps, this value is set in the database
-           automatically via SQL trigger, so no setter exists
-	   @return None if not found"""
-	if self.D.has_key("min_max"):
-	    return self.D["min_max"]
+        """!Get the maximal minimum of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "min_max" in self.D:
+            return self.D["min_max"]
         else:
-	    return None
+            return None
 
     def get_nsres_min(self):
-	"""!Get the minimal north-south resolution of all registered maps, this value is set in the database
-           automatically via SQL trigger, so no setter exists
-	   @return None if not found"""
-	if self.D.has_key("nsres_min"):
-	    return self.D["nsres_min"]
+        """!Get the minimal north-south resolution of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "nsres_min" in self.D:
+            return self.D["nsres_min"]
         else:
-	    return None
+            return None
 
     def get_nsres_max(self):
-	"""!Get the maximal north-south resolution of all registered maps, this value is set in the database
-           automatically via SQL trigger, so no setter exists
-	   @return None if not found"""
-	if self.D.has_key("nsres_max"):
-	    return self.D["nsres_max"]
+        """!Get the maximal north-south resolution of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "nsres_max" in self.D:
+            return self.D["nsres_max"]
         else:
-	    return None
+            return None
 
     def get_ewres_min(self):
-	"""!Get the minimal east-west resolution of all registered maps, this value is set in the database
-           automatically via SQL trigger, so no setter exists
-	   @return None if not found"""
-	if self.D.has_key("ewres_min"):
-	    return self.D["ewres_min"]
+        """!Get the minimal east-west resolution of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "ewres_min" in self.D:
+            return self.D["ewres_min"]
         else:
-	    return None
+            return None
 
     def get_ewres_max(self):
-	"""!Get the maximal east-west resolution of all registered maps, this value is set in the database
-           automatically via SQL trigger, so no setter exists
-	   @return None if not found"""
-	if self.D.has_key("ewres_max"):
-	    return self.D["ewres_max"]
+        """!Get the maximal east-west resolution of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "ewres_max" in self.D:
+            return self.D["ewres_max"]
         else:
-	    return None
-
+            return None
+    
+    nsres_min = property(fget=get_nsres_min)
+    nsres_max = property(fget=get_nsres_max)
+    ewres_min = property(fget=get_ewres_min)
+    ewres_max = property(fget=get_ewres_max)
+    min_min = property(fget=get_min_min)
+    min_max = property(fget=get_min_max)
+    max_min = property(fget=get_max_min)
+    max_max = property(fget=get_max_max)
+    
     def print_info(self):
         """!Print information about this class in human readable style"""
-        stds_metadata_base.print_info(self)
+        STDSMetadataBase.print_info(self)
         #      0123456789012345678901234567890
         print " | North-South resolution min:. " + str(self.get_nsres_min())
         print " | North-South resolution max:. " + str(self.get_nsres_max())
@@ -701,7 +1125,7 @@
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-        stds_metadata_base.print_shell_info(self)
+        STDSMetadataBase.print_shell_info(self)
         print "nsres_min=" + str(self.get_nsres_min())
         print "nsres_max=" + str(self.get_nsres_max())
         print "ewres_min=" + str(self.get_ewres_min())
@@ -714,312 +1138,500 @@
 
 ###############################################################################
 
-class strds_metadata(stds_raster_metadata_base):
-    """!This is the raster metadata class"""
-    def __init__(self, ident=None, raster_register=None,  title=None, description=None):
+class STRDSMetadata(STDSRasterMetadataBase):
+    """!This is the raster metadata class
+        
+        This class is the interface to the strds_metadata table in the
+        temporal database that stores the metadata of all registered 
+        space time raster datasets
+        
+        Usage:
+        
+        >>> import grass.temporal as tgis
+        >>> meta = tgis.STRDSMetadata(ident="soils at PERMANENT",
+        ... title="Soils", description="Soils 1950 - 2010")
+        >>> meta.id
+        'soils at PERMANENT'
+        >>> meta.title
+        'Soils'
+        >>> meta.description
+        'Soils 1950 - 2010'
+        >>> meta.number_of_maps
+        >>> meta.min_max
+        >>> meta.max_max
+        >>> meta.min_min
+        >>> meta.max_min
+        >>> meta.nsres_min
+        >>> meta.nsres_max
+        >>> meta.ewres_min
+        >>> meta.ewres_max
+        >>> meta.raster_register
+        >>> meta.print_info()
+         +-------------------- Metadata information ----------------------------------+
+         | Number of registered maps:.. None
+         | Title:
+         | Soils
+         | Description:
+         | Soils 1950 - 2010
+         | North-South resolution min:. None
+         | North-South resolution max:. None
+         | East-west resolution min:... None
+         | East-west resolution max:... None
+         | Minimum value min:.......... None
+         | Minimum value max:.......... None
+         | Maximum value min:.......... None
+         | Maximum value max:.......... None
+         | Raster register table:...... None
+        >>> meta.print_shell_info()
+        number_of_maps=None
+        nsres_min=None
+        nsres_max=None
+        ewres_min=None
+        ewres_max=None
+        min_min=None
+        min_max=None
+        max_min=None
+        max_max=None
+        raster_register=None
+    """
+    def __init__(self, ident=None, raster_register=None, title=None, description=None):
 
-	stds_raster_metadata_base.__init__(self, "strds_metadata", ident, title, description)
+        STDSRasterMetadataBase.__init__(
+            self, "strds_metadata", ident, title, description)
 
-	self.set_raster_register(raster_register)
+        self.set_raster_register(raster_register)
 
     def set_raster_register(self, raster_register):
-	"""!Set the raster map register table name"""
-	self.D["raster_register"] = raster_register
+        """!Set the raster map register table name"""
+        self.D["raster_register"] = raster_register
 
     def get_raster_register(self):
-	"""!Get the raster map register table name
-	   @return None if not found"""
-	if self.D.has_key("raster_register"):
-	    return self.D["raster_register"]
+        """!Get the raster map register table name
+           @return None if not found"""
+        if "raster_register" in self.D:
+            return self.D["raster_register"]
         else:
-	    return None
+            return None
+    
+    raster_register = property(fget=get_raster_register, 
+                               fset=set_raster_register)
 
     def print_info(self):
         """!Print information about this class in human readable style"""
         print " +-------------------- Metadata information ----------------------------------+"
         #      0123456789012345678901234567890
-        stds_raster_metadata_base.print_info(self)
-        print " | Raster register table:...... " + str(self.get_raster_register())
+        STDSRasterMetadataBase.print_info(self)
+        print " | Raster register table:...... " + str(
+            self.get_raster_register())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-        stds_raster_metadata_base.print_shell_info(self)
+        STDSRasterMetadataBase.print_shell_info(self)
         print "raster_register=" + str(self.get_raster_register())
 
 ###############################################################################
 
-class str3ds_metadata(stds_raster_metadata_base):
-    """!This is the space time raster3d metadata class"""
-    def __init__(self, ident=None, raster3d_register=None,  title=None, description=None):
 
-	stds_raster_metadata_base.__init__(self, "str3ds_metadata", ident, title, description)
+class STR3DSMetadata(STDSRasterMetadataBase):
+    """!This is the space time raster3d metadata class
+    
+        This class is the interface to the str3ds_metadata table in the
+        temporal database that stores the metadata of all registered 
+        space time 3D raster datasets
+        
+        Usage:
+        
+        >>> import grass.temporal as tgis
+        >>> meta = tgis.STR3DSMetadata(ident="soils at PERMANENT",
+        ... title="Soils", description="Soils 1950 - 2010")
+        >>> meta.id
+        'soils at PERMANENT'
+        >>> meta.title
+        'Soils'
+        >>> meta.description
+        'Soils 1950 - 2010'
+        >>> meta.number_of_maps
+        >>> meta.min_max
+        >>> meta.max_max
+        >>> meta.min_min
+        >>> meta.max_min
+        >>> meta.nsres_min
+        >>> meta.nsres_max
+        >>> meta.ewres_min
+        >>> meta.ewres_max
+        >>> meta.tbres_min
+        >>> meta.tbres_max
+        >>> meta.raster3d_register
+        >>> meta.print_info()
+         +-------------------- Metadata information ----------------------------------+
+         | Number of registered maps:.. None
+         | Title:
+         | Soils
+         | Description:
+         | Soils 1950 - 2010
+         | North-South resolution min:. None
+         | North-South resolution max:. None
+         | East-west resolution min:... None
+         | East-west resolution max:... None
+         | Minimum value min:.......... None
+         | Minimum value max:.......... None
+         | Maximum value min:.......... None
+         | Maximum value max:.......... None
+         | Top-bottom resolution min:.. None
+         | Top-bottom resolution max:.. None
+         | 3D raster register table:... None
+        >>> meta.print_shell_info()
+        number_of_maps=None
+        nsres_min=None
+        nsres_max=None
+        ewres_min=None
+        ewres_max=None
+        min_min=None
+        min_max=None
+        max_min=None
+        max_max=None
+        tbres_min=None
+        tbres_max=None
+        raster3d_register=None
+        """
+    def __init__(self, ident=None, raster3d_register=None, title=None, description=None):
 
-	self.set_raster3d_register(raster3d_register)
+        STDSRasterMetadataBase.__init__(
+            self, "str3ds_metadata", ident, title, description)
+
+        self.set_raster3d_register(raster3d_register)
         self.D["tbres_min"] = None
         self.D["tbres_max"] = None
 
     def set_raster3d_register(self, raster3d_register):
-	"""!Set the raster map register table name"""
-	self.D["raster3d_register"] = raster3d_register
+        """!Set the raster map register table name"""
+        self.D["raster3d_register"] = raster3d_register
 
     def get_raster3d_register(self):
-	"""!Get the raster3d map register table name
-	   @return None if not found"""
-	if self.D.has_key("raster3d_register"):
-	    return self.D["raster3d_register"]
+        """!Get the raster3d map register table name
+           @return None if not found"""
+        if "raster3d_register" in self.D:
+            return self.D["raster3d_register"]
         else:
-	    return None
+            return None
 
     def get_tbres_min(self):
-	"""!Get the minimal top-bottom resolution of all registered maps, this value is set in the database
-           automatically via SQL trigger, so no setter exists
-	   @return None if not found"""
-	if self.D.has_key("tbres_min"):
-	    return self.D["tbres_min"]
+        """!Get the minimal top-bottom resolution of all registered maps,
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "tbres_min" in self.D:
+            return self.D["tbres_min"]
         else:
-	    return None
+            return None
 
     def get_tbres_max(self):
-	"""!Get the maximal top-bottom resolution of all registered maps, this value is set in the database
-           automatically via SQL trigger, so no setter exists
-	   @return None if not found"""
-	if self.D.has_key("tbres_max"):
-	    return self.D["tbres_max"]
+        """!Get the maximal top-bottom resolution of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "tbres_max" in self.D:
+            return self.D["tbres_max"]
         else:
-	    return None
+            return None
 
+    raster3d_register = property(fget=get_raster3d_register, 
+                               fset=set_raster3d_register)
+    tbres_min = property(fget=get_tbres_min)
+    tbres_max = property(fget=get_tbres_max)
+    
     def print_info(self):
         """!Print information about this class in human readable style"""
         print " +-------------------- Metadata information ----------------------------------+"
         #      0123456789012345678901234567890
-        stds_raster_metadata_base.print_info(self)
+        STDSRasterMetadataBase.print_info(self)
         #      0123456789012345678901234567890
         print " | Top-bottom resolution min:.. " + str(self.get_ewres_min())
         print " | Top-bottom resolution max:.. " + str(self.get_ewres_max())
-        print " | Raster3d register table:.... " + str(self.get_raster3d_register())
+        print " | 3D raster register table:... " + str(
+            self.get_raster3d_register())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-        stds_raster_metadata_base.print_shell_info(self)
+        STDSRasterMetadataBase.print_shell_info(self)
         print "tbres_min=" + str(self.get_tbres_min())
         print "tbres_max=" + str(self.get_tbres_max())
         print "raster3d_register=" + str(self.get_raster3d_register())
 
 ###############################################################################
 
-class stvds_metadata(stds_metadata_base):
-    """!This is the raster metadata class"""
-    def __init__(self, ident=None, vector_register=None,  title=None, description=None, \
-                 points=None, lines=None, boundaries=None,\
-                 centroids=None, faces=None, kernels=None, primitives=None, nodes=None, areas=None, \
-                 islands=None, holes=None, volumes=None):
+class STVDSMetadata(STDSMetadataBase):
+    """!This is the space time vector dataset metadata class
+    
+       Most of the metadata values are set by triggers in the database when
+       new vector maps are added. Therefor only some set- an many get-functions
+       are available.
+       
+        >>> import grass.temporal as tgis
+        >>> meta = tgis.STVDSMetadata(ident="lidars at PERMANENT",
+        ... title="LIDARS", description="LIDARS 2008 - 2010")
+        >>> meta.id
+        'lidars at PERMANENT'
+        >>> meta.title
+        'LIDARS'
+        >>> meta.description
+        'LIDARS 2008 - 2010'
+        >>> meta.number_of_maps
+        >>> meta.number_of_points
+        >>> meta.number_of_lines
+        >>> meta.number_of_boundaries
+        >>> meta.number_of_centroids
+        >>> meta.number_of_faces
+        >>> meta.number_of_kernels
+        >>> meta.number_of_primitives
+        >>> meta.number_of_nodes
+        >>> meta.number_of_areas
+        >>> meta.number_of_islands
+        >>> meta.number_of_holes
+        >>> meta.number_of_volumes
+        >>> meta.print_info()
+         +-------------------- Metadata information ----------------------------------+
+         | Number of registered maps:.. None
+         | Title:
+         | LIDARS
+         | Description:
+         | LIDARS 2008 - 2010
+         | Vector register table:...... None
+         | Number of points ........... None
+         | Number of lines ............ None
+         | Number of boundaries ....... None
+         | Number of centroids ........ None
+         | Number of faces ............ None
+         | Number of kernels .......... None
+         | Number of primitives ....... None
+         | Number of nodes ............ None
+         | Number of areas ............ None
+         | Number of islands .......... None
+         | Number of holes ............ None
+         | Number of volumes .......... None
+        >>> meta.print_shell_info()
+        number_of_maps=None
+        vector_register=None
+        points=None
+        lines=None
+        boundaries=None
+        centroids=None
+        faces=None
+        kernels=None
+        primitives=None
+        nodes=None
+        areas=None
+        islands=None
+        holes=None
+        volumes=None
+    """
+    def __init__(
+        self, ident=None, vector_register=None, title=None, description=None):
 
-	stds_metadata_base.__init__(self, "stvds_metadata", ident, title, description)
+        STDSMetadataBase.__init__(
+            self, "stvds_metadata", ident, title, description)
 
-	self.set_vector_register(vector_register)
-	self.set_points(points)
-	self.set_lines(lines)
-	self.set_boundaries(boundaries)
-	self.set_centroids(centroids)
-	self.set_faces(faces)
-	self.set_kernels(kernels)
-	self.set_primitives(primitives)
-	self.set_nodes(nodes)
-	self.set_areas(areas)
-	self.set_islands(islands)
-	self.set_holes(holes)
-	self.set_volumes(volumes)
-
+        self.set_vector_register(vector_register)
+        self.D["points"] = None
+        self.D["lines"] = None
+        self.D["boundaries"] = None
+        self.D["centroids"] = None
+        self.D["faces"] = None
+        self.D["kernels"] = None
+        self.D["primitives"] = None
+        self.D["nodes"] = None
+        self.D["areas"] = None
+        self.D["islands"] = None
+        self.D["holes"] = None
+        self.D["volumes"] = None
+        
     def set_vector_register(self, vector_register):
-	"""!Set the vector map register table name"""
-	self.D["vector_register"] = vector_register
+        """!Set the vector map register table name"""
+        self.D["vector_register"] = vector_register
 
-    def set_points(self, points):
-	"""!Set the number of points of the vector map"""
-	self.D["points"] = points
-
-    def set_lines(self, lines):
-	"""!Set the number of lines of the vector map"""
-	self.D["lines"] = lines
-
-    def set_boundaries(self, boundaries):
-	"""!Set the number of boundaries of the vector map"""
-	self.D["boundaries"] = boundaries
-
-    def set_centroids(self, centroids):
-	"""!Set the number of centroids of the vector map"""
-	self.D["centroids"] = centroids
-
-    def set_faces(self, faces):
-	"""!Set the number of faces of the vector map"""
-	self.D["faces"] = faces
-
-    def set_kernels(self, kernels):
-	"""!Set the number of kernels of the vector map"""
-	self.D["kernels"] = kernels
-
-    def set_primitives(self, primitives):
-	"""!Set the number of primitives of the vector map"""
-	self.D["primitives"] = primitives
-
-    def set_nodes(self, nodes):
-	"""!Set the number of nodes of the vector map"""
-	self.D["nodes"] = nodes
-
-    def set_areas(self, areas):
-	"""!Set the number of areas of the vector map"""
-	self.D["areas"] = areas
-	
-    def set_islands(self, islands):
-	"""!Set the number of islands of the vector map"""
-	self.D["islands"] = islands
-	
-    def set_holes(self, holes):
-	"""!Set the number of holes of the vector map"""
-	self.D["holes"] = holes
-	
-    def set_volumes(self, volumes):
-	"""!Set the number of volumes of the vector map"""
-	self.D["volumes"] = volumes
-
     def get_vector_register(self):
-	"""!Get the vector map register table name
-	   @return None if not found"""
-	if self.D.has_key("vector_register"):
-	    return self.D["vector_register"]
+        """!Get the vector map register table name
+           @return None if not found"""
+        if "vector_register" in self.D:
+            return self.D["vector_register"]
         else:
-	    return None
+            return None
 
-    def get_points(self):
-	"""!Get the number of points of the vector map
-	   @return None if not found"""
-	if self.D.has_key("points"):
-	    return self.D["points"]
+    def get_number_of_points(self):
+        """!Get the number of points of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "points" in self.D:
+            return self.D["points"]
         else:
-	    return None
-	    
-    def get_lines(self):
-	"""!Get the number of lines of the vector map
-	   @return None if not found"""
-	if self.D.has_key("lines"):
-	    return self.D["lines"]
+            return None
+
+    def get_number_of_lines(self):
+        """!Get the number of lines of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "lines" in self.D:
+            return self.D["lines"]
         else:
-	    return None
-	    
-    def get_boundaries(self):
-	"""!Get the number of boundaries of the vector map
-	   @return None if not found"""
-	if self.D.has_key("boundaries"):
-	    return self.D["boundaries"]
+            return None
+
+    def get_number_of_boundaries(self):
+        """!Get the number of boundaries of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "boundaries" in self.D:
+            return self.D["boundaries"]
         else:
-	    return None
-	    
-    def get_centroids(self):
-	"""!Get the number of centroids of the vector map
-	   @return None if not found"""
-	if self.D.has_key("centroids"):
-	    return self.D["centroids"]
+            return None
+
+    def get_number_of_centroids(self):
+        """!Get the number of centroids of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "centroids" in self.D:
+            return self.D["centroids"]
         else:
-	    return None
-	    
-    def get_faces(self):
-	"""!Get the number of faces of the vector map
-	   @return None if not found"""
-	if self.D.has_key("faces"):
-	    return self.D["faces"]
+            return None
+
+    def get_number_of_faces(self):
+        """!Get the number of faces of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "faces" in self.D:
+            return self.D["faces"]
         else:
-	    return None
-	    
-    def get_kernels(self):
-	"""!Get the number of kernels of the vector map
-	   @return None if not found"""
-	if self.D.has_key("kernels"):
-	    return self.D["kernels"]
+            return None
+
+    def get_number_of_kernels(self):
+        """!Get the number of kernels of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "kernels" in self.D:
+            return self.D["kernels"]
         else:
-	    return None
-	    
-    def get_primitives(self):
-	"""!Get the number of primitives of the vector map
-	   @return None if not found"""
-	if self.D.has_key("primitives"):
-	    return self.D["primitives"]
+            return None
+
+    def get_number_of_primitives(self):
+        """!Get the number of primitives of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "primitives" in self.D:
+            return self.D["primitives"]
         else:
-	    return None
-	    
-    def get_nodes(self):
-	"""!Get the number of nodes of the vector map
-	   @return None if not found"""
-	if self.D.has_key("nodes"):
-	    return self.D["nodes"]
+            return None
+
+    def get_number_of_nodes(self):
+        """!Get the number of nodes of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "nodes" in self.D:
+            return self.D["nodes"]
         else:
-	    return None
-	    
-    def get_areas(self):
-	"""!Get the number of areas of the vector map
-	   @return None if not found"""
-	if self.D.has_key("areas"):
-	    return self.D["areas"]
+            return None
+
+    def get_number_of_areas(self):
+        """!Get the number of areas of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "areas" in self.D:
+            return self.D["areas"]
         else:
-	    return None
-	    
-    def get_islands(self):
-	"""!Get the number of islands of the vector map
-	   @return None if not found"""
-	if self.D.has_key("islands"):
-	    return self.D["islands"]
+            return None
+
+    def get_number_of_islands(self):
+        """!Get the number of islands of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "islands" in self.D:
+            return self.D["islands"]
         else:
-	    return None
-	    
-    def get_holes(self):
-	"""!Get the number of holes of the vector map
-	   @return None if not found"""
-	if self.D.has_key("holes"):
-	    return self.D["holes"]
+            return None
+
+    def get_number_of_holes(self):
+        """!Get the number of holes of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "holes" in self.D:
+            return self.D["holes"]
         else:
-	    return None
-	    
-    def get_volumes(self):
-	"""!Get the number of volumes of the vector map
-	   @return None if not found"""
-	if self.D.has_key("volumes"):
-	    return self.D["volumes"]
+            return None
+
+    def get_number_of_volumes(self):
+        """!Get the number of volumes of all registered maps, 
+           this value is set in the database
+           automatically via SQL, so no setter exists
+           @return None if not found"""
+        if "volumes" in self.D:
+            return self.D["volumes"]
         else:
-	    return None
+            return None
+    
+    # Set the properties
+    vector_register  = property(fget=get_vector_register,
+                                fset=set_vector_register)
+    number_of_points = property(fget=get_number_of_points)
+    number_of_lines = property(fget=get_number_of_lines)
+    number_of_boundaries = property(fget=get_number_of_boundaries)
+    number_of_centroids = property(fget=get_number_of_centroids)
+    number_of_faces = property(fget=get_number_of_faces)
+    number_of_kernels = property(fget=get_number_of_kernels)
+    number_of_primitives = property(fget=get_number_of_primitives)
+    number_of_nodes = property(fget=get_number_of_nodes)
+    number_of_areas = property(fget=get_number_of_areas)
+    number_of_islands = property(fget=get_number_of_islands)
+    number_of_holes = property(fget=get_number_of_holes)
+    number_of_volumes = property(fget=get_number_of_volumes)
 
     def print_info(self):
         """!Print information about this class in human readable style"""
         print " +-------------------- Metadata information ----------------------------------+"
         #      0123456789012345678901234567890
-        stds_metadata_base.print_info(self)
-        print " | Vector register table:...... " + str(self.get_vector_register())
-        print " | Number of points ........... " + str(self.get_points())
-        print " | Number of lines ............ " + str(self.get_lines())
-        print " | Number of boundaries ....... " + str(self.get_boundaries())
-        print " | Number of centroids ........ " + str(self.get_centroids())
-        print " | Number of faces ............ " + str(self.get_faces())
-        print " | Number of kernels .......... " + str(self.get_kernels())
-        print " | Number of primitives ....... " + str(self.get_primitives())
-        print " | Number of nodes ............ " + str(self.get_nodes())
-        print " | Number of areas ............ " + str(self.get_areas())
-        print " | Number of islands .......... " + str(self.get_islands())
-        print " | Number of holes ............ " + str(self.get_holes())
-        print " | Number of volumes .......... " + str(self.get_volumes())
-        
+        STDSMetadataBase.print_info(self)
+        print " | Vector register table:...... " + str(
+            self.get_vector_register())
+        print " | Number of points ........... " + str(self.get_number_of_points())
+        print " | Number of lines ............ " + str(self.get_number_of_lines())
+        print " | Number of boundaries ....... " + str(self.get_number_of_boundaries())
+        print " | Number of centroids ........ " + str(self.get_number_of_centroids())
+        print " | Number of faces ............ " + str(self.get_number_of_faces())
+        print " | Number of kernels .......... " + str(self.get_number_of_kernels())
+        print " | Number of primitives ....... " + str(self.get_number_of_primitives())
+        print " | Number of nodes ............ " + str(self.get_number_of_nodes())
+        print " | Number of areas ............ " + str(self.get_number_of_areas())
+        print " | Number of islands .......... " + str(self.get_number_of_islands())
+        print " | Number of holes ............ " + str(self.get_number_of_holes())
+        print " | Number of volumes .......... " + str(self.get_number_of_volumes())
+
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-        stds_metadata_base.print_shell_info(self)
+        STDSMetadataBase.print_shell_info(self)
         print "vector_register=" + str(self.get_vector_register())
-        print "points=" + str(self.get_points())
-        print "lines=" + str(self.get_lines())
-        print "boundaries=" + str(self.get_boundaries())
-        print "centroids=" + str(self.get_centroids())
-        print "faces=" + str(self.get_faces())
-        print "kernels=" + str(self.get_kernels())
-        print "primitives=" + str(self.get_primitives())
-        print "nodes=" + str(self.get_nodes())
-        print "areas=" + str(self.get_areas())
-        print "islands=" + str(self.get_islands())
-        print "holes=" + str(self.get_holes())
-        print "volumes=" + str(self.get_volumes())
+        print "points=" + str(self.get_number_of_points())
+        print "lines=" + str(self.get_number_of_lines())
+        print "boundaries=" + str(self.get_number_of_boundaries())
+        print "centroids=" + str(self.get_number_of_centroids())
+        print "faces=" + str(self.get_number_of_faces())
+        print "kernels=" + str(self.get_number_of_kernels())
+        print "primitives=" + str(self.get_number_of_primitives())
+        print "nodes=" + str(self.get_number_of_nodes())
+        print "areas=" + str(self.get_number_of_areas())
+        print "islands=" + str(self.get_number_of_islands())
+        print "holes=" + str(self.get_number_of_holes())
+        print "volumes=" + str(self.get_number_of_volumes())
 
+###############################################################################
 
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
\ No newline at end of file

Modified: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -98,11 +98,11 @@
 	
     def reset(self, ident):
 	"""!Reset the internal structure and set the identifier"""
-	self.base = raster_base(ident=ident)
-	self.absolute_time = raster_absolute_time(ident=ident)
-	self.relative_time = raster_relative_time(ident=ident)
-	self.spatial_extent = raster_spatial_extent(ident=ident)
-	self.metadata = raster_metadata(ident=ident)
+	self.base = RasterBase(ident=ident)
+	self.absolute_time = RasterAbslouteTime(ident=ident)
+	self.relative_time = RasterRelativeTime(ident=ident)
+	self.spatial_extent = RasterSpatialExtent(ident=ident)
+	self.metadata = RasterMetadata(ident=ident)
 		
     def has_grass_timestamp(self):
         """!Check if a grass file bsased time stamp exists for this map. 
@@ -306,11 +306,11 @@
         
     def reset(self, ident):
 	"""!Reset the internal structure and set the identifier"""
-	self.base = raster3d_base(ident=ident)
-	self.absolute_time = raster3d_absolute_time(ident=ident)
-	self.relative_time = raster3d_relative_time(ident=ident)
-	self.spatial_extent = raster3d_spatial_extent(ident=ident)
-	self.metadata = raster3d_metadata(ident=ident)
+	self.base = Raster3DBase(ident=ident)
+	self.absolute_time = Raster3DAbslouteTime(ident=ident)
+	self.relative_time = Raster3DRelativeTime(ident=ident)
+	self.spatial_extent = Raster3DSpatialExtent(ident=ident)
+	self.metadata = Raster3DMetadata(ident=ident)
 
     def has_grass_timestamp(self):
         """!Check if a grass file bsased time stamp exists for this map. 
@@ -515,11 +515,11 @@
 	
     def reset(self, ident):
 	"""!Reset the internal structure and set the identifier"""
-	self.base = vector_base(ident=ident)
-	self.absolute_time = vector_absolute_time(ident=ident)
-	self.relative_time = vector_relative_time(ident=ident)
-	self.spatial_extent = vector_spatial_extent(ident=ident)
-	self.metadata = vector_metadata(ident=ident)
+	self.base = VectorBase(ident=ident)
+	self.absolute_time = VectorAbslouteTime(ident=ident)
+	self.relative_time = VectorRelativeTime(ident=ident)
+	self.spatial_extent = VectorSpatialExtent(ident=ident)
+	self.metadata = VectorMetadata(ident=ident)
 
     def has_grass_timestamp(self):
         """!Check if a grass file bsased time stamp exists for this map. 
@@ -724,12 +724,12 @@
     def reset(self, ident):
 
 	"""!Reset the internal structure and set the identifier"""
-	self.base = strds_base(ident=ident)
+	self.base = STRDSBase(ident=ident)
         self.base.set_creator(str(getpass.getuser()))
-        self.absolute_time = strds_absolute_time(ident=ident)
-        self.relative_time = strds_relative_time(ident=ident)
-	self.spatial_extent = strds_spatial_extent(ident=ident)
-	self.metadata = strds_metadata(ident=ident)
+        self.absolute_time = STRDSAbslouteTime(ident=ident)
+        self.relative_time = STRDSRelativeTime(ident=ident)
+	self.spatial_extent = STRDSSpatialExtent(ident=ident)
+	self.metadata = STRDSMetadata(ident=ident)
 
 ###############################################################################
 
@@ -778,12 +778,12 @@
     def reset(self, ident):
 
 	"""!Reset the internal structure and set the identifier"""
-	self.base = str3ds_base(ident=ident)
+	self.base = STR3DSBase(ident=ident)
         self.base.set_creator(str(getpass.getuser()))
-        self.absolute_time = str3ds_absolute_time(ident=ident)
-        self.relative_time = str3ds_relative_time(ident=ident)
-	self.spatial_extent = str3ds_spatial_extent(ident=ident)
-	self.metadata = str3ds_metadata(ident=ident)
+        self.absolute_time = STR3DSAbslouteTime(ident=ident)
+        self.relative_time = STR3DSRelativeTime(ident=ident)
+	self.spatial_extent = STR3DSSpatialExtent(ident=ident)
+	self.metadata = STR3DSMetadata(ident=ident)
 
 ###############################################################################
 
@@ -826,10 +826,104 @@
     def reset(self, ident):
 
 	"""!Reset the internal structure and set the identifier"""
-	self.base = stvds_base(ident=ident)
+	self.base = STVDSBase(ident=ident)
         self.base.set_creator(str(getpass.getuser()))
-        self.absolute_time = stvds_absolute_time(ident=ident)
-        self.relative_time = stvds_relative_time(ident=ident)
-	self.spatial_extent = stvds_spatial_extent(ident=ident)
-	self.metadata = stvds_metadata(ident=ident)
+        self.absolute_time = STVDSAbslouteTime(ident=ident)
+        self.relative_time = STVDSRelativeTime(ident=ident)
+	self.spatial_extent = STVDSSpatialExtent(ident=ident)
+	self.metadata = STVDSMetadata(ident=ident)
 
+###############################################################################
+
+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
+

Modified: grass/trunk/lib/python/temporal/space_time_datasets_tools.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets_tools.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/space_time_datasets_tools.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -541,7 +541,7 @@
 
     sst = dataset_factory(sampletype, sid)
 
-    dbif = sql_database_interface_connection()
+    dbif = ()
     dbif.connect()
 
     for st in sts:

Modified: grass/trunk/lib/python/temporal/spatial_extent.py
===================================================================
--- grass/trunk/lib/python/temporal/spatial_extent.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/spatial_extent.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -6,12 +6,26 @@
 
 Usage:
 
- at code
-import grass.temporal as tgis
+>>> import grass.temporal as tgis
+>>> extent = tgis.RasterSpatialExtent( 
+... ident="raster at PERMANENT", north=90, south=90, east=180, west=180,
+... top=100, bottom=-20)
+>>> extent = tgis.Raster3DSpatialExtent( 
+... ident="raster3d at PERMANENT", north=90, south=90, east=180, west=180,
+... top=100, bottom=-20)
+>>> extent = tgis.VectorSpatialExtent( 
+... ident="vector at PERMANENT", north=90, south=90, east=180, west=180,
+... top=100, bottom=-20)
+>>> extent = tgis.STRDSSpatialExtent( 
+... ident="strds at PERMANENT", north=90, south=90, east=180, west=180,
+... top=100, bottom=-20)
+>>> extent = tgis.STR3DSSpatialExtent( 
+... ident="str3ds at PERMANENT", north=90, south=90, east=180, west=180,
+... top=100, bottom=-20)
+>>> extent = tgis.STVDSSpatialExtent( 
+... ident="stvds at PERMANENT", north=90, south=90, east=180, west=180,
+... top=100, bottom=-20)
 
-extent = tgis.raster_spatial_extent()
-...
- at endcode
 
 (C) 2008-2011 by the GRASS Development Team
 This program is free software under the GNU General Public
@@ -22,35 +36,76 @@
 """
 from base import *
 
-class spatial_extent(sql_database_interface):
-    """!This is the spatial extent base class for all maps and space time datasets"""
-    def __init__(self, table=None, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None, proj="XY"):
 
-	sql_database_interface.__init__(self, table, ident)
+class SpatialExtent(SQLDatabaseInterface):
+    """!This is the spatial extent base class for all maps and space time datasets
+        
+        This class implements a three dimensional axis aligned bounding box
+        and functions to compute topological relationships
+        
+        >>> import grass.temporal as tgis
+        >>> extent = tgis.SpatialExtent(table="raster_spatial_extent", 
+        ... ident="soil at PERMANENT", north=90, south=90, east=180, west=180,
+        ... top=100, bottom=-20)
+        >>> extent.id
+        'soil at PERMANENT'
+        >>> extent.north
+        90.0
+        >>> extent.south
+        90.0
+        >>> extent.east
+        180.0
+        >>> extent.west
+        180.0
+        >>> extent.top
+        100.0
+        >>> extent.bottom
+        -20.0
+        >>> extent.print_info()
+         +-------------------- Spatial extent ----------------------------------------+
+         | North:...................... 90.0
+         | South:...................... 90.0
+         | East:.. .................... 180.0
+         | West:....................... 180.0
+         | Top:........................ 100.0
+         | Bottom:..................... -20.0
+        >>> extent.print_shell_info()
+        north=90.0
+        south=90.0
+        east=180.0
+        west=180.0
+        top=100.0
+        bottom=-20.0
+    """
+    def __init__(self, table=None, ident=None, north=None, south=None, 
+                 east=None, west=None, top=None, bottom=None, proj="XY"):
+
+        SQLDatabaseInterface.__init__(self, table, ident)
         self.set_id(ident)
         self.set_spatial_extent(north, south, east, west, top, bottom)
-	self.set_projection(proj)
-        
+        self.set_projection(proj)
+
     def overlapping_2d(self, extent):
-        """!Return True if the two dimensional extents overlap. Code is lend from wind_overlap.c in lib/gis
-        
-	   Overlapping includes the spatial relations:
-	   * contain
-	   * in
-	   * cover
-	   * covered
-	   * equivalent
-	"""  
-        
+        """!Return True if the two dimensional extents overlap. 
+           Code is lend from wind_overlap.c in lib/gis
+
+           Overlapping includes the spatial relations:
+           * contain
+           * in
+           * cover
+           * covered
+           * equivalent
+        """
+
         if self.get_projection() != extent.get_projection():
             core.error(_("Projections are different. Unable to compute overlapping_2d for spatial extents"))
             return False
-        
+
         N = extent.get_north()
         S = extent.get_south()
         E = extent.get_east()
         W = extent.get_west()
-        
+
         # Adjust the east and west in case of LL projection
         if self.get_projection() == "LL":
             while E < self.get_west():
@@ -60,64 +115,72 @@
             while W > self.get_east():
                 E -= 360.0
                 W -= 360.0
-                
+
         if(self.get_north() <= S):
             return False
-        
+
         if(self.get_south() >= N):
             return False
-            
+
         if self.get_east() <= W:
             return False
-        
+
         if self.get_west() >= E:
             return False
-        
+
         return True
 
     def overlapping(self, extent):
         """!Return True if the three dimensional extents overlap
+
+       Overlapping includes the spatial relations:
+       * contain
+       * in
+       * cover
+       * covered
+       * equivalent
+           
+        Usage:
         
-	   Overlapping includes the spatial relations:
-	   * contain
-	   * in
-	   * cover
-	   * covered
-	   * equivalent
-        """  
-        
+        >>> import grass.temporal as tgis
+        >>> A = tgis.SpatialExtent(north=80, south=20, east=60, west=10, bottom=-50, top=50)
+        >>> B = tgis.SpatialExtent(north=80, south=20, east=60, west=10, bottom=-50, top=50)
+        >>> A.overlapping(B)
+        True
+        """
+
         if not self.overlapping_2d(extent):
             return False
-            
+
         T = extent.get_top()
         B = extent.get_bottom()
-        
+
         if self.get_top() <= B:
             return False
-        
+
         if self.get_bottom() >= T:
             return False
-        
+
         return True
 
     def intersect_2d(self, extent):
-	"""!Return the two dimensional intersection as spatial_extent object or None
-	   in case no intersection was found.
-	"""
-	
-	if not self.overlapping_2d(extent):
-	    return None
-	    
-	eN = extent.get_north()
+        """!Return the two dimensional intersection as spatial_extent object or None
+           in case no intersection was found.
+        """
+
+        if not self.overlapping_2d(extent):
+            return None
+
+        eN = extent.get_north()
         eS = extent.get_south()
         eE = extent.get_east()
         eW = extent.get_west()
-        
-	N = self.get_north()
+
+        N = self.get_north()
         S = self.get_south()
         E = self.get_east()
         W = self.get_west()
-        
+
         # Adjust the east and west in case of LL projection
         if self.get_projection() == "LL":
             while eE < W:
@@ -126,79 +189,133 @@
 
             while eW > E:
                 eE -= 360.0
-                eW -= 360.0	
-                
+                eW -= 360.0
+
         # Compute the extent
         nN = N
         nS = S
         nE = E
         nW = W
-        
+
         if W < eW:
-	    nW = eW
-	if E > eE:
-	    nE = eE
-	if N > eN:
-	    nN = eN
-	if S < eS:
-	    nS = eS
-	
-	
-	new = spatial_extent(north=nN, south=nS, east=nE, west=nW, top=0, bottom=0, proj=self.get_projection())
-	return new
+            nW = eW
+        if E > eE:
+            nE = eE
+        if N > eN:
+            nN = eN
+        if S < eS:
+            nS = eS
 
+        new = SpatialExtent(north=nN, south=nS, east=nE, west=nW,
+                             top=0, bottom=0, proj=self.get_projection())
+        return new
+
     def intersect(self, extent):
-	"""!Return the three dimensional intersection as spatial_extent object or None
-	   in case no intersection was found.
-	"""
-	
-	if not self.overlapping(extent):
-	    return None
-	    
-	new = self.intersect_2d(extent)
-	
-	eT = extent.get_top()
-	eB = extent.get_bottom()
-	
-	T = self.get_top()
-	B = self.get_bottom()
-	
-	nT = T
-	nB = B
-	
-	if B < eB:
-	    nB = eB
-	if T > eT:
-	    nT = eT
-	
-	new.set_top(nT)
-	new.set_bottom(nB)
-	
-	return new
+        """!Return the three dimensional intersection as spatial_extent object or None
+        in case no intersection was found.
+        
+        Usage:
+        
+        >>> import grass.temporal as tgis
+        >>> A = tgis.SpatialExtent(north=80, south=20, east=60, west=10, bottom=-50, top=50)
+        >>> B = tgis.SpatialExtent(north=80, south=20, east=60, west=10, bottom=-50, top=50)
+        >>> C = A.intersect(B)
+        >>> C.print_info()
+         +-------------------- Spatial extent ----------------------------------------+
+         | North:...................... 80.0
+         | South:...................... 20.0
+         | East:.. .................... 60.0
+         | West:....................... 10.0
+         | Top:........................ 50.0
+         | Bottom:..................... -50.0
+        >>> B = tgis.SpatialExtent(north=40, south=30, east=60, west=10, bottom=-50, top=50)
+        >>> C = A.intersect(B)
+        >>> C.print_info()
+         +-------------------- Spatial extent ----------------------------------------+
+         | North:...................... 40.0
+         | South:...................... 30.0
+         | East:.. .................... 60.0
+         | West:....................... 10.0
+         | Top:........................ 50.0
+         | Bottom:..................... -50.0
+        >>> B = tgis.SpatialExtent(north=40, south=30, east=60, west=30, bottom=-50, top=50)
+        >>> C = A.intersect(B)
+        >>> C.print_info()
+         +-------------------- Spatial extent ----------------------------------------+
+         | North:...................... 40.0
+         | South:...................... 30.0
+         | East:.. .................... 60.0
+         | West:....................... 30.0
+         | Top:........................ 50.0
+         | Bottom:..................... -50.0
+        >>> B = tgis.SpatialExtent(north=40, south=30, east=60, west=30, bottom=-30, top=50)
+        >>> C = A.intersect(B)
+        >>> C.print_info()
+         +-------------------- Spatial extent ----------------------------------------+
+         | North:...................... 40.0
+         | South:...................... 30.0
+         | East:.. .................... 60.0
+         | West:....................... 30.0
+         | Top:........................ 50.0
+         | Bottom:..................... -30.0
+        >>> B = tgis.SpatialExtent(north=40, south=30, east=60, west=30, bottom=-30, top=30)
+        >>> C = A.intersect(B)
+        >>> C.print_info()
+         +-------------------- Spatial extent ----------------------------------------+
+         | North:...................... 40.0
+         | South:...................... 30.0
+         | East:.. .................... 60.0
+         | West:....................... 30.0
+         | Top:........................ 30.0
+         | Bottom:..................... -30.0
+        """
 
+        if not self.overlapping(extent):
+            return None
+
+        new = self.intersect_2d(extent)
+
+        eT = extent.get_top()
+        eB = extent.get_bottom()
+
+        T = self.get_top()
+        B = self.get_bottom()
+
+        nT = T
+        nB = B
+
+        if B < eB:
+            nB = eB
+        if T > eT:
+            nT = eT
+
+        new.set_top(nT)
+        new.set_bottom(nB)
+
+        return new
+
     def is_in_2d(self, extent):
-	"""Check two dimensional if the self is located in extent 
-	
-         _____	
-	|A _  |
-	| |_| |
-	|_____|
-	
-	"""
+        """Check two dimensional if the self is located in extent
+
+         _____
+        |A _  |
+        | |_| |
+        |_____|B 
+        """
         if self.get_projection() != extent.get_projection():
             core.error(_("Projections are different. Unable to compute is_in_2d for spatial extents"))
             return False
-            
-	eN = extent.get_north()
+
+        eN = extent.get_north()
         eS = extent.get_south()
         eE = extent.get_east()
         eW = extent.get_west()
-        
-	N = self.get_north()
+
+        N = self.get_north()
         S = self.get_south()
         E = self.get_east()
         W = self.get_west()
-        
+
         # Adjust the east and west in case of LL projection
         if self.get_projection() == "LL":
             while eE < W:
@@ -207,62 +324,73 @@
 
             while eW > E:
                 eE -= 360.0
-                eW -= 360.0	
-               
+                eW -= 360.0
+
         if W <= eW:
-	    return False
-	if E >= eE:
-	    return False
-	if N >= eN:
-	    return False
-	if S <= eS:
-	    return False
-	
-	return True
-	
+            return False
+        if E >= eE:
+            return False
+        if N >= eN:
+            return False
+        if S <= eS:
+            return False
+
+        return True
+
     def is_in(self, extent):
-	"""Check three dimensional if the self is located in extent """
-	if not self.is_in_2d(extent):
-	    return False
-	
-	eT = extent.get_top()
-	eB = extent.get_bottom()
-	
-	T = self.get_top()
-	B = self.get_bottom()
-	
-	if B <= eB:
-	    return False
-	if T >= eT:
-	    return False
-	    
-	return True
+        """Check three dimensional if the self is located in extent 
+        
+        Usage:
+        
+        >>> import grass.temporal as tgis
+        >>> A = tgis.SpatialExtent(north=79, south=21, east=59, west=11, bottom=-49, top=49)
+        >>> B = tgis.SpatialExtent(north=80, south=20, east=60, west=10, bottom=-50, top=50)
+        >>> A.is_in(B)
+        True
+        >>> B.is_in(A)
+        False
+        """
+        if not self.is_in_2d(extent):
+            return False
 
+        eT = extent.get_top()
+        eB = extent.get_bottom()
+
+        T = self.get_top()
+        B = self.get_bottom()
+
+        if B <= eB:
+            return False
+        if T >= eT:
+            return False
+
+        return True
+
     def contain_2d(self, extent):
-	"""Check two dimensional if self contains extent """
-	return extent.is_in_2d(self)
-	
+        """Check two dimensional if self contains extent """
+        return extent.is_in_2d(self)
+
     def contain(self, extent):
-	"""Check three dimensional if self contains extent """
-	return extent.is_in(self)
-        	
+        """Check three dimensional if self contains extent """
+        return extent.is_in(self)
+
     def equivalent_2d(self, extent):
-	"""Check two dimensional if self is equivalent to extent """
+        """Check two dimensional if self is equivalent to extent """
 
         if self.get_projection() != extent.get_projection():
             core.error(_("Projections are different. Unable to compute equivalent_2d for spatial extents"))
             return False
-            
-	eN = extent.get_north()
+
+        eN = extent.get_north()
         eS = extent.get_south()
         eE = extent.get_east()
         eW = extent.get_west()
-        
-	N = self.get_north()
+
+        N = self.get_north()
         S = self.get_south()
         E = self.get_east()
         W = self.get_west()
-        
+
         # Adjust the east and west in case of LL projection
         if self.get_projection() == "LL":
             while eE < W:
@@ -271,80 +399,79 @@
 
             while eW > E:
                 eE -= 360.0
-                eW -= 360.0	
-               
+                eW -= 360.0
+
         if W != eW:
-	    return False
-	if E != eE:
-	    return False
-	if N != eN:
-	    return False
-	if S != eS:
-	    return False
-	
-	return True
-	
+            return False
+        if E != eE:
+            return False
+        if N != eN:
+            return False
+        if S != eS:
+            return False
+
+        return True
+
     def equivalent(self, extent):
-	"""Check three dimensional if self is equivalent to extent """
+        """Check three dimensional if self is equivalent to extent """
 
-	if not self.equivalent_2d(extent):
-	    return False
-	
-	eT = extent.get_top()
-	eB = extent.get_bottom()
-	
-	T = self.get_top()
-	B = self.get_bottom()
-	
-	if B != eB:
-	    return False
-	if T != eT:
-	    return False
-	    
-	return True
+        if not self.equivalent_2d(extent):
+            return False
 
+        eT = extent.get_top()
+        eB = extent.get_bottom()
+
+        T = self.get_top()
+        B = self.get_bottom()
+
+        if B != eB:
+            return False
+        if T != eT:
+            return False
+
+        return True
+
     def cover_2d(self, extent):
-        """Return True if two dimensional self covers extent 
+        """Return True if two dimensional self covers extent
             _____    _____    _____    _____
            |A  __|  |__  A|  |A | B|  |B | A|
            |  |B |  | B|  |  |  |__|  |__|  |
            |__|__|  |__|__|  |_____|  |_____|
-           
+
             _____    _____    _____    _____
            |A|B| |  |A  __|  |A _  |  |__  A|
            | |_| |  |  |__|B | |B| | B|__|  |
            |_____|  |_____|  |_|_|_|  |_____|
-           
+
             _____    _____    _____    _____
            |A|B  |  |_____|A |A|B|A|  |_____|A
            | |   |  |B    |  | | | |  |_____|B
            |_|___|  |_____|  |_|_|_|  |_____|A
-                            
+
            The following cases are excluded:
-	   * contain
-	   * in
-	   * equivalent
-        """    
-        
+           * contain
+           * in
+           * equivalent
+        """
+
         if self.get_projection() != extent.get_projection():
             core.error(_("Projections are different. Unable to compute cover_2d for spatial extents"))
             return False
-	    
-	# Exclude equivalent_2d
+
+        # Exclude equivalent_2d
         if self.equivalent_2d(extent):
-	    return False
-        
-	eN = extent.get_north()
+            return False
+
+        eN = extent.get_north()
         eS = extent.get_south()
         eE = extent.get_east()
         eW = extent.get_west()
-        
-	N = self.get_north()
+
+        N = self.get_north()
         S = self.get_south()
         E = self.get_east()
         W = self.get_west()
-        
-        
+
         # Adjust the east and west in case of LL projection
         if self.get_projection() == "LL":
             while eE < W:
@@ -353,71 +480,71 @@
 
             while eW > E:
                 eE -= 360.0
-                eW -= 360.0	
-                
-	# Edges of extent located outside of self are not allowed 
+                eW -= 360.0
+
+        # Edges of extent located outside of self are not allowed
         if E < eW:
-	    return False
-	if W > eE:
-	    return False
-	if N < eS:
-	    return False
-	if S > eN:
-	    return False
-         
+            return False
+        if W > eE:
+            return False
+        if N < eS:
+            return False
+        if S > eN:
+            return False
+
         # First we check that at least one edge of extent meets an edge of self
         if W != eW and E != eE and N != eN and S != eS:
-	    return False
-	    
-	# We check that at least one edge of extent is located in self
-	edge_count = 0
-	if W < eW and E > eW:
-	    edge_count += 1
-	if E > eE and W < eE:
-	    edge_count += 1
-	if N > eN and S < eN:
-	    edge_count += 1
-	if S < eS and N > eS:
-	    edge_count += 1
-	
-	if edge_count == 0:
-	    return False
-	
-	return True
-	
+            return False
+
+        # We check that at least one edge of extent is located in self
+        edge_count = 0
+        if W < eW and E > eW:
+            edge_count += 1
+        if E > eE and W < eE:
+            edge_count += 1
+        if N > eN and S < eN:
+            edge_count += 1
+        if S < eS and N > eS:
+            edge_count += 1
+
+        if edge_count == 0:
+            return False
+
+        return True
+
     def cover(self, extent):
-        """Return True if three dimensional self covers extent 
-     
+        """Return True if three dimensional self covers extent
+
            The following cases are excluded:
-	   * contain
-	   * in
-	   * equivalent
-        """ 
-        	    
+           * contain
+           * in
+           * equivalent
+        """
+
         if self.get_projection() != extent.get_projection():
             core.error(_("Projections are different. Unable to compute cover for spatial extents"))
             return False
-	    
-	# Exclude equivalent_2d
+
+        # Exclude equivalent_2d
         if self.equivalent_2d(extent):
-	    return False
-        
-	eN = extent.get_north()
+            return False
+
+        eN = extent.get_north()
         eS = extent.get_south()
         eE = extent.get_east()
         eW = extent.get_west()
-        
+
         eT = extent.get_top()
-	eB = extent.get_bottom()
-        
-	N = self.get_north()
+        eB = extent.get_bottom()
+
+        N = self.get_north()
         S = self.get_south()
         E = self.get_east()
         W = self.get_west()
-	
-	T = self.get_top()
-	B = self.get_bottom()
-        
+
+        T = self.get_top()
+        B = self.get_bottom()
+
         # Adjust the east and west in case of LL projection
         if self.get_projection() == "LL":
             while eE < W:
@@ -426,60 +553,60 @@
 
             while eW > E:
                 eE -= 360.0
-                eW -= 360.0	
-                
-	# Edges of extent located outside of self are not allowed 
+                eW -= 360.0
+
+        # Edges of extent located outside of self are not allowed
         if E <= eW:
-	    return False
-	if W >= eE:
-	    return False
-	if N <= eS:
-	    return False
-	if S >= eN:
-	    return False
-	if T <= eB:
-	    return False
-	if B >= eT:
-	    return False
-         
+            return False
+        if W >= eE:
+            return False
+        if N <= eS:
+            return False
+        if S >= eN:
+            return False
+        if T <= eB:
+            return False
+        if B >= eT:
+            return False
+
         # First we check that at least one edge of extent meets an edge of self
         if W != eW and E != eE and N != eN and S != eS and B != eB and T != eT:
-	    return False
-	    
-	# We check that at least one edge of extent is located in self
-	edge_count = 0
-	if W < eW and E > eW:
-	    edge_count += 1
-	if E > eE and W < eE:
-	    edge_count += 1
-	if N > eN and S < eN:
-	    edge_count += 1
-	if S < eS and N > eS:
-	    edge_count += 1
-	if N > eN and S < eN:
-	    edge_count += 1
-	if S < eS and N > eS:
-	    edge_count += 1
-	if T > eT and B < eT:
-	    edge_count += 1
-	if B < eB and T > eB:
-	    edge_count += 1
-	
-	if edge_count == 0:
-	    return False
-	
-	return True
-        
+            return False
+
+        # We check that at least one edge of extent is located in self
+        edge_count = 0
+        if W < eW and E > eW:
+            edge_count += 1
+        if E > eE and W < eE:
+            edge_count += 1
+        if N > eN and S < eN:
+            edge_count += 1
+        if S < eS and N > eS:
+            edge_count += 1
+        if N > eN and S < eN:
+            edge_count += 1
+        if S < eS and N > eS:
+            edge_count += 1
+        if T > eT and B < eT:
+            edge_count += 1
+        if B < eB and T > eB:
+            edge_count += 1
+
+        if edge_count == 0:
+            return False
+
+        return True
+
     def covered_2d(self, extent):
-	"""Check two dimensional if self is covered by  extent """
+        """Check two dimensional if self is covered by  extent """
 
-	return extent.cover_2d(self)
-	
+        return extent.cover_2d(self)
+
     def covered(self, extent):
-	"""Check three dimensional if self is covered by extent """
-	
-	return extent.cover(self)
-        	
+        """Check three dimensional if self is covered by extent """
+
+        return extent.cover(self)
+
     def overlap_2d(self, extent):
         """Return True if the two dimensional extents overlap. Code is lend from wind_overlap.c in lib/gis
             _____
@@ -487,35 +614,35 @@
            |  |  | B|
            |__|__|  |
               |_____|
-              
+
            The following cases are excluded:
-	   * contain
-	   * in
-	   * cover
-	   * covered
-	   * equivalent
-        """    
-        
+           * contain
+           * in
+           * cover
+           * covered
+           * equivalent
+        """
+
         if self.contain_2d(extent):
-	    return False
-	    
+            return False
+
         if self.is_in_2d(extent):
-	    return False
-	    
+            return False
+
         if self.cover_2d(extent):
-	    return False
-	    
+            return False
+
         if self.covered_2d(extent):
-	    return False
-	    
+            return False
+
         if self.equivalent_2d(extent):
-	    return False
-        
+            return False
+
         N = extent.get_north()
         S = extent.get_south()
         E = extent.get_east()
         W = extent.get_west()
-        
+
         # Adjust the east and west in case of LL projection
         if self.get_projection() == "LL":
             while E < self.get_west():
@@ -525,54 +652,54 @@
             while W > self.get_east():
                 E -= 360.0
                 W -= 360.0
-                
+
         if(self.get_north() <= S):
             return False
-        
+
         if(self.get_south() >= N):
             return False
-        
+
         if self.get_east() <= W:
             return False
-        
+
         if self.get_west() >= E:
             return False
-        
+
         return True
 
     def overlap(self, extent):
         """Return True if the three dimensional extents overlap
-        
+
            The following cases are excluded:
-	   * contain
-	   * in
-	   * cover
-	   * covered
-	   * equivalent
-        """   
+           * contain
+           * in
+           * cover
+           * covered
+           * equivalent
+        """
 
         if self.is_in(extent):
-	    return False
+            return False
 
         if self.contain(extent):
-	    return False
+            return False
 
         if self.cover(extent):
-	    return False
+            return False
 
         if self.covered(extent):
-	    return False
+            return False
 
         if self.equivalent(extent):
-	    return False
-        
+            return False
+
         N = extent.get_north()
         S = extent.get_south()
         E = extent.get_east()
         W = extent.get_west()
         T = extent.get_top()
         B = extent.get_bottom()
-        
+
         # Adjust the east and west in case of LL projection
         if self.get_projection() == "LL":
             while E < self.get_west():
@@ -582,60 +709,60 @@
             while W > self.get_east():
                 E -= 360.0
                 W -= 360.0
-                
+
         if(self.get_north() <= S):
             return False
-        
+
         if(self.get_south() >= N):
             return False
-            
+
         if self.get_east() <= W:
             return False
-        
+
         if self.get_west() >= E:
             return False
-        
+
         if self.get_top() <= B:
             return False
-        
+
         if self.get_bottom() >= T:
             return False
-        
+
         return True
-        
-    def meet_2d(self,extent):
-	""" Check if self and extent meet each other in two dimensions
-	  _____ _____    _____ _____
-	 |  A  |  B  |  |  B  |  A  |
-	 |_____|     |  |     |     |
-	       |_____|  |_____|_____|
-	       	       
-	         ___
-	        | A |
-	        |   |
-	        |___|    _____
-	       |  B  |  |  B  |
-	       |     |  |     |
-	       |_____|  |_____|_
-	                  |  A  |
-	                  |     |
-	                  |_____|
-	                  
-	"""
-	
-	eN = extent.get_north()
+
+    def meet_2d(self, extent):
+        """ Check if self and extent meet each other in two dimensions
+          _____ _____    _____ _____
+         |  A  |  B  |  |  B  |  A  |
+         |_____|     |  |     |     |
+               |_____|  |_____|_____|
+
+                 ___
+                | A |
+                |   |
+                |___|    _____
+               |  B  |  |  B  |
+               |     |  |     |
+               |_____|  |_____|_
+                          |  A  |
+                          |     |
+                          |_____|
+
+        """
+
+        eN = extent.get_north()
         eS = extent.get_south()
         eE = extent.get_east()
         eW = extent.get_west()
-        
+
         eT = extent.get_top()
-	eB = extent.get_bottom()
-        
-	N = self.get_north()
+        eB = extent.get_bottom()
+
+        N = self.get_north()
         S = self.get_south()
         E = self.get_east()
         W = self.get_west()
-	        
+
         # Adjust the east and west in case of LL projection
         if self.get_projection() == "LL":
             while eE < W:
@@ -644,57 +771,57 @@
 
             while eW > E:
                 eE -= 360.0
-                eW -= 360.0	
-                
+                eW -= 360.0
+
         edge = None
         edge_count = 0
-        
+
         if E == eW:
-	    edge = "E"
-	    edge_count += 1
+            edge = "E"
+            edge_count += 1
         if W == eE:
-	    edge = "W"
-	    edge_count += 1
+            edge = "W"
+            edge_count += 1
         if N == eS:
-	    edge = "N"
-	    edge_count += 1
+            edge = "N"
+            edge_count += 1
         if S == eN:
-	    edge = "S"
-	    edge_count += 1
-	
-	# Meet a a single edge only
-	if edge_count != 1:
-	    return False
-	
-	# Check boundaries of the faces
-	if edge == "E" or edge == "W":
-	    if N < eS or S > eN:
-		return False
-		
-	if edge == "N" or edge == "S":
-	    if E < eW or W > eE:
-		return False
-	
-	return True
+            edge = "S"
+            edge_count += 1
 
-    def meet(self,extent):
-	""" Check if self and extent meet each other in three dimensions"""
-	eN = extent.get_north()
+        # Meet a a single edge only
+        if edge_count != 1:
+            return False
+
+        # Check boundaries of the faces
+        if edge == "E" or edge == "W":
+            if N < eS or S > eN:
+                return False
+
+        if edge == "N" or edge == "S":
+            if E < eW or W > eE:
+                return False
+
+        return True
+
+    def meet(self, extent):
+        """ Check if self and extent meet each other in three dimensions"""
+        eN = extent.get_north()
         eS = extent.get_south()
         eE = extent.get_east()
         eW = extent.get_west()
-        
+
         eT = extent.get_top()
-	eB = extent.get_bottom()
-        
-	N = self.get_north()
+        eB = extent.get_bottom()
+
+        N = self.get_north()
         S = self.get_south()
         E = self.get_east()
         W = self.get_west()
-	
-	T = self.get_top()
-	B = self.get_bottom()
-        
+
+        T = self.get_top()
+        B = self.get_bottom()
+
         # Adjust the east and west in case of LL projection
         if self.get_projection() == "LL":
             while eE < W:
@@ -703,295 +830,476 @@
 
             while eW > E:
                 eE -= 360.0
-                eW -= 360.0	
-                
+                eW -= 360.0
+
         edge = None
         edge_count = 0
-        
+
         if E == eW:
-	    edge = "E"
-	    edge_count += 1
+            edge = "E"
+            edge_count += 1
         if W == eE:
-	    edge = "W"
-	    edge_count += 1
+            edge = "W"
+            edge_count += 1
         if N == eS:
-	    edge = "N"
-	    edge_count += 1
+            edge = "N"
+            edge_count += 1
         if S == eN:
-	    edge = "S"
-	    edge_count += 1
+            edge = "S"
+            edge_count += 1
         if T == eB:
-	    edge = "T"
-	    edge_count += 1
+            edge = "T"
+            edge_count += 1
         if B == eT:
-	    edge = "B"
-	    edge_count += 1	
-	
-	# Meet a single edge only
-	if edge_count != 1:
-	    return False
-	
-	# Check boundaries of the faces
-	if edge == "E" or edge == "W":
-	    if N < eS or S > eN:
-		return False
-	    if T < eB or B > eT:
-		return False
-		
-	if edge == "N" or edge == "S":
-	    if E < eW or W > eE:
-		return False
-	    if T < eB or B > eT:
-		return False
-		
-	if edge == "T" or edge == "B":
-	    if E < eW or W > eE:
-		return False
-	    if N < eS or S > eN:
-		return False
-	
-	return True
+            edge = "B"
+            edge_count += 1
 
+        # Meet a single edge only
+        if edge_count != 1:
+            return False
+
+        # Check boundaries of the faces
+        if edge == "E" or edge == "W":
+            if N < eS or S > eN:
+                return False
+            if T < eB or B > eT:
+                return False
+
+        if edge == "N" or edge == "S":
+            if E < eW or W > eE:
+                return False
+            if T < eB or B > eT:
+                return False
+
+        if edge == "T" or edge == "B":
+            if E < eW or W > eE:
+                return False
+            if N < eS or S > eN:
+                return False
+
+        return True
+
     def disjoint_2d(self, extent):
-        """Return True if the two dimensional extents are disjoint 
-        """  
-        
+        """Return True if the two dimensional extents are disjoint
+        """
+
         if self.overlapping_2d(extent) or self.meet_2d(extent):
-	    return False
-	return True
+            return False
+        return True
 
     def disjoint(self, extent):
-        """Return True if the three dimensional extents are disjoint 
-        """  
-        
+        """Return True if the three dimensional extents are disjoint
+        """
+
         if self.overlapping(extent) or self.meet(extent):
-	    return False
-	return True
-                
+            return False
+        return True
+
     def spatial_relation_2d(self, extent):
-	"""Returns the two dimensional spatial relation between self and extent
-	
-	    Spatial relations are:
-	    * disjoint
-	    * meet
-	    * overlap
-	    * cover
-	    * covered
-	    * in
-	    * contain
-	    * equivalent
-	"""
+        """Returns the two dimensional spatial relation between self and extent
+
+        Spatial relations are:
+        * disjoint
+        * meet
+        * overlap
+        * cover
+        * covered
+        * in
+        * contain
+        * equivalent
         
-	if self.equivalent_2d(extent):
-	    return "equivalent"
-	if self.contain_2d(extent):
-	    return "contain"
-	if self.is_in_2d(extent):
-	    return "in"
-	if self.cover_2d(extent):
-	    return "cover"
-	if self.covered_2d(extent):
-	    return "covered"
-	if self.overlap_2d(extent):
-	    return "overlap"
-	if self.meet_2d(extent):
-	    return "meet"
-	if self.disjoint_2d(extent):
-	    return "disjoint"
-	    
+        Usage: see self.spatial_relation()
+        """
+
+        if self.equivalent_2d(extent):
+            return "equivalent"
+        if self.contain_2d(extent):
+            return "contain"
+        if self.is_in_2d(extent):
+            return "in"
+        if self.cover_2d(extent):
+            return "cover"
+        if self.covered_2d(extent):
+            return "covered"
+        if self.overlap_2d(extent):
+            return "overlap"
+        if self.meet_2d(extent):
+            return "meet"
+        if self.disjoint_2d(extent):
+            return "disjoint"
+
         return "unknown"
-        
+
     def spatial_relation(self, extent):
-	"""Returns the three dimensional spatial relation between self and extent
-	
-	    Spatial relations are:
-	    * disjoint
-	    * meet
-	    * overlap
-	    * cover
-	    * covered
-	    * in
-	    * contain
-	    * equivalent
-	"""
+        """Returns the three dimensional spatial relation between self and extent
+
+        Spatial relations are:
+        * disjoint
+        * meet
+        * overlap
+        * cover
+        * covered
+        * in
+        * contain
+        * equivalent
+            
         
-	if self.equivalent(extent):
-	    return "equivalent"
-	if self.contain(extent):
-	    return "contain"
-	if self.is_in(extent):
-	    return "in"
-	if self.cover(extent):
-	    return "cover"
-	if self.covered(extent):
-	    return "covered"
-	if self.overlap(extent):
-	    return "overlap"
-	if self.meet(extent):
-	    return "meet"
-	if self.disjoint(extent):
-	    return "disjoint"
-	    
+        Usage:
+        
+        >>> import grass.temporal as tgis
+        >>> A = tgis.SpatialExtent(north=80, south=20, east=60, west=10, bottom=-50, top=50)
+        >>> B = tgis.SpatialExtent(north=80, south=20, east=60, west=10, bottom=-50, top=50)
+        >>> A.spatial_relation(B)
+        'equivalent'
+        >>> B.spatial_relation(A)
+        'equivalent'
+        >>> B = tgis.SpatialExtent(north=70, south=20, east=60, west=10, bottom=-50, top=50)
+        >>> A.spatial_relation_2d(B)
+        'cover'
+        >>> A.spatial_relation(B)
+        'cover'
+        >>> B = tgis.SpatialExtent(north=70, south=30, east=60, west=10, bottom=-50, top=50)
+        >>> A.spatial_relation_2d(B)
+        'cover'
+        >>> A.spatial_relation(B)
+        'cover'
+        >>> B.spatial_relation_2d(A)
+        'covered'
+        >>> B.spatial_relation(A)
+        'covered'
+        >>> B = tgis.SpatialExtent(north=70, south=30, east=50, west=10, bottom=-50, top=50)
+        >>> A.spatial_relation_2d(B)
+        'cover'
+        >>> B.spatial_relation_2d(A)
+        'covered'
+        >>> A.spatial_relation(B)
+        'cover'
+        >>> B = tgis.SpatialExtent(north=70, south=30, east=50, west=20, bottom=-50, top=50)
+        >>> B.spatial_relation(A)
+        'covered'
+        >>> B = tgis.SpatialExtent(north=70, south=30, east=50, west=20, bottom=-50, top=50)
+        >>> A.spatial_relation_2d(B)
+        'contain'
+        >>> A.spatial_relation(B)
+        'cover'
+        >>> B = tgis.SpatialExtent(north=70, south=30, east=50, west=20, bottom=-40, top=50)
+        >>> A.spatial_relation(B)
+        'cover'
+        >>> B = tgis.SpatialExtent(north=70, south=30, east=50, west=20, bottom=-40, top=40)
+        >>> A.spatial_relation(B)
+        'contain'
+        >>> B.spatial_relation(A)
+        'in'
+        >>> B = tgis.SpatialExtent(north=90, south=30, east=50, west=20, bottom=-40, top=40)
+        >>> A.spatial_relation_2d(B)
+        'overlap'
+        >>> A.spatial_relation(B)
+        'overlap'
+        >>> B = tgis.SpatialExtent(north=90, south=5, east=70, west=5, bottom=-40, top=40)
+        >>> A.spatial_relation_2d(B)
+        'in'
+        >>> A.spatial_relation(B)
+        'overlap'
+        >>> B = tgis.SpatialExtent(north=90, south=5, east=70, west=5, bottom=-40, top=60)
+        >>> A.spatial_relation(B)
+        'overlap'
+        >>> B = tgis.SpatialExtent(north=90, south=5, east=70, west=5, bottom=-60, top=60)
+        >>> A.spatial_relation(B)
+        'in'
+        >>> A = tgis.SpatialExtent(north=80, south=60, east=60, west=10, bottom=-50, top=50)
+        >>> B = tgis.SpatialExtent(north=60, south=20, east=60, west=10, bottom=-50, top=50)
+        >>> A.spatial_relation_2d(B)
+        'meet'
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=60, south=40, east=60, west=10, bottom=-50, top=50)
+        >>> B = tgis.SpatialExtent(north=80, south=60, east=60, west=10, bottom=-50, top=50)
+        >>> A.spatial_relation_2d(B)
+        'meet'
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=60, west=40, bottom=-50, top=50)
+        >>> B = tgis.SpatialExtent(north=80, south=40, east=40, west=20, bottom=-50, top=50)
+        >>> A.spatial_relation_2d(B)
+        'meet'
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=40, west=20, bottom=-50, top=50)
+        >>> B = tgis.SpatialExtent(north=90, south=30, east=60, west=40, bottom=-50, top=50)
+        >>> A.spatial_relation_2d(B)
+        'meet'
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=40, west=20, bottom=-50, top=50)
+        >>> B = tgis.SpatialExtent(north=70, south=50, east=60, west=40, bottom=-50, top=50)
+        >>> A.spatial_relation_2d(B)
+        'meet'
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=40, west=20, bottom=-50, top=50)
+        >>> B = tgis.SpatialExtent(north=60, south=20, east=60, west=40, bottom=-50, top=50)
+        >>> A.spatial_relation_2d(B)
+        'meet'
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=40, west=20, bottom=-50, top=50)
+        >>> B = tgis.SpatialExtent(north=40, south=20, east=60, west=40, bottom=-50, top=50)
+        >>> A.spatial_relation_2d(B)
+        'disjoint'
+        >>> A.spatial_relation(B)
+        'disjoint'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=40, west=20, bottom=-50, top=50)
+        >>> B = tgis.SpatialExtent(north=60, south=20, east=60, west=40, bottom=-60, top=60)
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=40, west=20, bottom=-50, top=50)
+        >>> B = tgis.SpatialExtent(north=90, south=30, east=60, west=40, bottom=-40, top=40)
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=60, west=20, bottom=0, top=50)
+        >>> B = tgis.SpatialExtent(north=80, south=40, east=60, west=20, bottom=-50, top=0)
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=60, west=20, bottom=0, top=50)
+        >>> B = tgis.SpatialExtent(north=80, south=50, east=60, west=30, bottom=-50, top=0)
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=60, west=20, bottom=0, top=50)
+        >>> B = tgis.SpatialExtent(north=70, south=50, east=50, west=30, bottom=-50, top=0)
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=60, west=20, bottom=0, top=50)
+        >>> B = tgis.SpatialExtent(north=90, south=30, east=70, west=10, bottom=-50, top=0)
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=60, west=20, bottom=0, top=50)
+        >>> B = tgis.SpatialExtent(north=70, south=30, east=50, west=10, bottom=-50, top=0)
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=60, west=20, bottom=-50, top=0)
+        >>> B = tgis.SpatialExtent(north=80, south=40, east=60, west=20, bottom=0, top=50)
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=60, west=20, bottom=-50, top=0)
+        >>> B = tgis.SpatialExtent(north=80, south=50, east=60, west=30, bottom=0, top=50)
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=60, west=20, bottom=-50, top=0)
+        >>> B = tgis.SpatialExtent(north=70, south=50, east=50, west=30, bottom=0, top=50)
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=60, west=20, bottom=-50, top=0)
+        >>> B = tgis.SpatialExtent(north=90, south=30, east=70, west=10, bottom=0, top=50)
+        >>> A.spatial_relation(B)
+        'meet'
+        >>> A = tgis.SpatialExtent(north=80, south=40, east=60, west=20, bottom=-50, top=0)
+        >>> B = tgis.SpatialExtent(north=70, south=30, east=50, west=10, bottom=0, top=50)
+        >>> A.spatial_relation(B)
+        'meet'
+        """
+
+        if self.equivalent(extent):
+            return "equivalent"
+        if self.contain(extent):
+            return "contain"
+        if self.is_in(extent):
+            return "in"
+        if self.cover(extent):
+            return "cover"
+        if self.covered(extent):
+            return "covered"
+        if self.overlap(extent):
+            return "overlap"
+        if self.meet(extent):
+            return "meet"
+        if self.disjoint(extent):
+            return "disjoint"
+
         return "unknown"
-        
+
     def set_spatial_extent(self, north, south, east, west, top, bottom):
         """Set the spatial extent"""
 
-	self.set_north(north)
-	self.set_south(south)
-	self.set_east(east)
-	self.set_west(west)
-	self.set_top(top)
-	self.set_bottom(bottom)        
-        
+        self.set_north(north)
+        self.set_south(south)
+        self.set_east(east)
+        self.set_west(west)
+        self.set_top(top)
+        self.set_bottom(bottom)
+
     def set_projection(self, proj):
         """Set the projection of the spatial extent it should be XY or LL.
            As default the projection is XY
         """
-        if proj == None or (proj != "XY" and proj != "LL"):
+        if proj is None or (proj != "XY" and proj != "LL"):
             self.D["proj"] = "XY"
         else:
             self.D["proj"] = proj
 
     def set_spatial_extent_2d(self, north, south, east, west):
 
-	self.set_id(ident)
-	self.set_north(north)
-	self.set_south(south)
-	self.set_east(east)
-	self.set_west(west)
-	self.set_top(0)
-	self.set_bottom(0)
+        self.set_north(north)
+        self.set_south(south)
+        self.set_east(east)
+        self.set_west(west)
 
     def set_id(self, ident):
-	"""Convenient method to set the unique identifier (primary key)"""
-	self.ident = ident
-	self.D["id"] = ident
+        """Convenient method to set the unique identifier (primary key)"""
+        self.ident = ident
+        self.D["id"] = ident
 
     def set_north(self, north):
-	"""Set the northern edge of the map"""
-	self.D["north"] = north
+        """Set the northern edge of the map"""
+        if north is not None:
+            self.D["north"] = float(north)
+        else:
+            self.D["north"] = None
 
-    def set_south(self, sourth):
-	"""Set the southern edge of the map"""
-	self.D["south"] = sourth
+    def set_south(self, south):
+        """Set the southern edge of the map"""
+        if south is not None:
+            self.D["south"] = float(south)
+        else:
+            self.D["south"] = None
 
     def set_west(self, west):
-	"""Set the western edge of the map"""
-	self.D["west"] = west
+        """Set the western edge of the map"""
+        if west is not None:
+            self.D["west"] = float(west)
+        else:
+            self.D["west"] = None
 
     def set_east(self, east):
-	"""Set the eastern edge of the map"""
-	self.D["east"] = east
+        """Set the eastern edge of the map"""
+        if east is not None:
+            self.D["east"] = float(east)
+        else:
+            self.D["east"] = None
 
     def set_top(self, top):
-	"""Set the top edge of the map"""
-	self.D["top"] = top
+        """Set the top edge of the map"""
+        if top is not None:
+            self.D["top"] = float(top)
+        else:
+            self.D["top"] = None
 
     def set_bottom(self, bottom):
-	"""Set the bottom edge of the map"""
-	self.D["bottom"] = bottom
+        """Set the bottom edge of the map"""
+        if bottom is not None:
+            self.D["bottom"] = float(bottom)
+        else:
+            self.D["bottom"] = None
 
     def get_id(self):
-	"""Convenient method to get the unique identifier (primary key)
-	   @return None if not found
-	"""
-	if self.D.has_key("id"):
-	    return self.D["id"]
+        """Convenient method to get the unique identifier (primary key)
+           @return None if not found
+        """
+        if "id" in self.D:
+            return self.D["id"]
         else:
-	    return None
+            return None
 
     def get_projection(self):
         """Get the projection of the spatial extent"""
         return self.D["proj"]
-    
+
     def get_volume(self):
-        """Compute the volume of the extent, in case z is zero (top == bottom or top - bottom = 1) the area is returned"""
+        """Compute the volume of the extent, in case z is zero 
+           (top == bottom or top - bottom = 1) the area is returned"""
 
         if self.get_projection() == "LL":
             core.error(_("Volume computation is not supported for LL projections"))
-        
+
         area = self.get_area()
-        
+
         bbox = self.get_spatial_extent()
-        
+
         z = abs(bbox[4] - bbox[5])
-        
+
         if z == 0:
             z = 1.0
-            
-        return area*z
-       
+
+        return area * z
+
     def get_area(self):
         """Compute the area of the extent, extent in z direction is ignored"""
-        
+
         if self.get_projection() == "LL":
             core.error(_("Area computation is not supported for LL projections"))
-        
+
         bbox = self.get_spatial_extent()
-        
+
         y = abs(bbox[0] - bbox[1])
         x = abs(bbox[2] - bbox[3])
-                    
-        return x*y
-    
+
+        return x * y
+
     def get_spatial_extent(self):
         """Return a tuple (north, south, east, west, top, bottom) of the spatial extent"""
-        
-        return (self.get_north(), self.get_south, self.get_east(), self.get_west(), \
-                self.get_top(), self.get_bottom())
-                
+
+        return (
+            self.get_north(), self.get_south, self.get_east(), self.get_west(),
+            self.get_top(), self.get_bottom())
+
     def get_spatial_extent_2d(self):
         """Return a tuple (north, south, east, west,) of the 2d spatial extent"""
         return (self.get_north(), self.get_south, self.get_east(), self.get_west())
-    
+
     def get_north(self):
-	"""Get the northern edge of the map
-	   @return None if not found"""
-	if self.D.has_key("north"):
-	    return self.D["north"]
+        """Get the northern edge of the map
+           @return None if not found"""
+        if "north" in self.D:
+            return self.D["north"]
         else:
-	    return None
+            return None
 
     def get_south(self):
-	"""Get the southern edge of the map
-	   @return None if not found"""
-	if self.D.has_key("south"):
-	    return self.D["south"]
+        """Get the southern edge of the map
+           @return None if not found"""
+        if "south" in self.D:
+            return self.D["south"]
         else:
-	    return None
+            return None
 
     def get_east(self):
-	"""Get the eastern edge of the map
-	   @return None if not found"""
-	if self.D.has_key("east"):
-	    return self.D["east"]
+        """Get the eastern edge of the map
+           @return None if not found"""
+        if "east" in self.D:
+            return self.D["east"]
         else:
-	    return None
+            return None
 
     def get_west(self):
-	"""Get the western edge of the map
-	   @return None if not found"""
-	if self.D.has_key("west"):
-	    return self.D["west"]
+        """Get the western edge of the map
+           @return None if not found"""
+        if "west" in self.D:
+            return self.D["west"]
         else:
-	    return None
+            return None
 
     def get_top(self):
-	"""Get the top edge of the map
-	   @return None if not found"""
-	if self.D.has_key("top"):
-	    return self.D["top"]
+        """Get the top edge of the map
+           @return None if not found"""
+        if "top" in self.D:
+            return self.D["top"]
         else:
-	    return None
+            return None
 
     def get_bottom(self):
-	"""Get the bottom edge of the map
-	   @return None if not found"""
-	if self.D.has_key("bottom"):
-	    return self.D["bottom"]
+        """Get the bottom edge of the map
+           @return None if not found"""
+        if "bottom" in self.D:
+            return self.D["bottom"]
         else:
-	    return None
+            return None
+    
+    id = property(fget=get_id, fset=set_id)
+    north = property(fget=get_north, fset=set_north)
+    south = property(fget=get_south, fset=set_south)
+    east = property(fget=get_east, fset=set_east)
+    west = property(fget=get_west, fset=set_west)
+    top = property(fget=get_top, fset=set_top)
+    bottom= property(fget=get_bottom, fset=set_bottom)
 
     def print_info(self):
         """Print information about this class in human readable style"""
@@ -1016,26 +1324,43 @@
 
 ###############################################################################
 
-class raster_spatial_extent(spatial_extent):
+class RasterSpatialExtent(SpatialExtent):
     def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
-        spatial_extent.__init__(self, "raster_spatial_extent", ident, north, south, east, west, top, bottom)
+        SpatialExtent.__init__(self, "raster_spatial_extent",
+                                ident, north, south, east, west, top, bottom)
 
-class raster3d_spatial_extent(spatial_extent):
+
+class Raster3DSpatialExtent(SpatialExtent):
     def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
-        spatial_extent.__init__(self, "raster3d_spatial_extent", ident, north, south, east, west, top, bottom)
+        SpatialExtent.__init__(self, "raster3d_spatial_extent",
+                                ident, north, south, east, west, top, bottom)
 
-class vector_spatial_extent(spatial_extent):
+
+class VectorSpatialExtent(SpatialExtent):
     def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
-        spatial_extent.__init__(self, "vector_spatial_extent", ident, north, south, east, west, top, bottom)
+        SpatialExtent.__init__(self, "vector_spatial_extent",
+                                ident, north, south, east, west, top, bottom)
 
-class strds_spatial_extent(spatial_extent):
+
+class STRDSSpatialExtent(SpatialExtent):
     def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
-        spatial_extent.__init__(self, "strds_spatial_extent", ident, north, south, east, west, top, bottom)
+        SpatialExtent.__init__(self, "strds_spatial_extent",
+                                ident, north, south, east, west, top, bottom)
 
-class str3ds_spatial_extent(spatial_extent):
+
+class STR3DSSpatialExtent(SpatialExtent):
     def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
-        spatial_extent.__init__(self, "str3ds_spatial_extent", ident, north, south, east, west, top, bottom)
+        SpatialExtent.__init__(self, "str3ds_spatial_extent",
+                                ident, north, south, east, west, top, bottom)
 
-class stvds_spatial_extent(spatial_extent):
+
+class STVDSSpatialExtent(SpatialExtent):
     def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
-        spatial_extent.__init__(self, "stvds_spatial_extent", ident, north, south, east, west, top, bottom)
+        SpatialExtent.__init__(self, "stvds_spatial_extent",
+                                ident, north, south, east, west, top, bottom)
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
\ No newline at end of file

Modified: grass/trunk/lib/python/temporal/temporal_extent.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_extent.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/temporal_extent.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -6,13 +6,11 @@
 
 Usage:
 
- at code
-import grass.temporal as tgis
+>>> import grass.temporal as tgis
+>>> from datetime import datetime
+>>> t = tgis.RasterRelativeTime()
+>>> t = tgis.RasterAbsoluteTime()
 
-tgis.raster_temporal_extent()
-...
- at endcode
-
 (C) 2008-2011 by the GRASS Development Team
 This program is free software under the GNU General Public
 License (>=v2). Read the file COPYING that comes with GRASS
@@ -24,313 +22,585 @@
 
 ###############################################################################
 
-class abstract_temporal_extent(sql_database_interface):
-    """!This is the abstract time base class for relative and absolute time objects"""
+class AbstractTemporalExtent(SQLDatabaseInterface):
+    """!This is the abstract time base class for relative and absolute time objects
+    
+        It abstract class implements the interface to absolute and relative time.
+        Absolute time is represented by datetime time stamps,
+        relative time is represented by a unit an integer value.
+        
+        This class implements temporal topology relationships computation
+        after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic].
+        
+        Usage:
+        
+        >>> import grass.temporal as tgis
+        >>> A = tgis.AbstractTemporalExtent(table="raster_absolute_time",
+        ... ident="soil at PERMANENT", start_time=datetime(2001, 01, 01),
+        ... end_time=datetime(2005,01,01) )
+        >>> A.id
+        'soil at PERMANENT'
+        >>> A.start_time
+        datetime.datetime(2001, 1, 1, 0, 0)
+        >>> A.end_time
+        datetime.datetime(2005, 1, 1, 0, 0)
+        >>> A.print_info()
+         | Start time:................. 2001-01-01 00:00:00
+         | End time:................... 2005-01-01 00:00:00
+        >>> A.print_shell_info()
+        start_time=2001-01-01 00:00:00
+        end_time=2005-01-01 00:00:00
+        >>> # relative time
+        >>> A = tgis.AbstractTemporalExtent(table="raster_absolute_time",
+        ... ident="soil at PERMANENT", start_time=0, end_time=1 )
+        >>> A.id
+        'soil at PERMANENT'
+        >>> A.start_time
+        0
+        >>> A.end_time
+        1
+        >>> A.print_info()
+         | Start time:................. 0
+         | End time:................... 1
+        >>> A.print_shell_info()
+        start_time=0
+        end_time=1
+    """
     def __init__(self, table=None, ident=None, start_time=None, end_time=None):
 
-	sql_database_interface.__init__(self, table, ident)
+        SQLDatabaseInterface.__init__(self, table, ident)
 
-	self.set_id(ident)
-	self.set_start_time(start_time)
-	self.set_end_time(end_time)
+        self.set_id(ident)
+        self.set_start_time(start_time)
+        self.set_end_time(end_time)
 
     def starts(self, extent):
-	"""!Return True if this time object starts at the start of the provided time object and finishes within it
-	   A  |-----|
-	   B  |---------|
-	"""
-        if  self.D["end_time"] == None or extent.D["end_time"] == None :
+        """!Return True if this temporal extent (A) starts at the start of the 
+           provided temporal extent (B) and finishes within it
+           A  |-----|
+           B  |---------|
+           
+           @param extent: The temporal extent object with which this extent starts
+           
+           Usage:
+           
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=5, end_time=6 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> A.starts(B)
+           True
+           >>> B.starts(A)
+           False
+        """
+        if  self.D["end_time"] is None or extent.D["end_time"] is None:
             return False
-            
-	if self.D["start_time"] == extent.D["start_time"] and self.D["end_time"] < extent.D["end_time"]:
-	    return True
+
+        if self.D["start_time"] == extent.D["start_time"] and \
+           self.D["end_time"] < extent.D["end_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def started(self, extent):
-	"""!Return True if this time object is started at the start of the provided time object
-	   A  |---------|
-	   B  |-----|
-	"""
-        if  self.D["end_time"] == None or extent.D["end_time"] == None :
+        """!Return True if this temporal extent (A) started at the start of the 
+           provided temporal extent (B) and finishes after it
+           A  |---------|
+           B  |-----|
+           
+           @param extent: The temporal extent object with which this extent started
+           
+           Usage:
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=5, end_time=6 )
+           >>> A.started(B)
+           True
+           >>> B.started(A)
+           False
+        """
+        if  self.D["end_time"] is None or extent.D["end_time"] is None:
             return False
 
-	if self.D["start_time"] == extent.D["start_time"] and self.D["end_time"] > extent.D["end_time"]:
-	    return True
+        if self.D["start_time"] == extent.D["start_time"] and \
+           self.D["end_time"] > extent.D["end_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def finishes(self, extent):
-	"""!Return True if this time object finishes at the end and within of the provided time object
-	   A      |-----|
-	   B  |---------|
-	"""
-        if  self.D["end_time"] == None or extent.D["end_time"] == None :
+        """!Return True if this temporal extent (A) starts after the start of the 
+           provided temporal extent (B) and finishes with it
+           A      |-----|
+           B  |---------|
+           
+           @param extent: The temporal extent object with which this extent finishes
+           
+           Usage:
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=6, end_time=7 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> A.finishes(B)
+           True
+           >>> B.finishes(A)
+           False
+        """
+        if  self.D["end_time"] is None or extent.D["end_time"] is None:
             return False
 
-	if self.D["end_time"] == extent.D["end_time"] and  self.D["start_time"] > extent.D["start_time"] :
-	    return True
+        if self.D["end_time"] == extent.D["end_time"] and \
+           self.D["start_time"] > extent.D["start_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def finished(self, extent):
-	"""!Return True if this time object finished at the end of the provided time object
-	   A  |---------|
-	   B      |-----|
-	"""
-        if  self.D["end_time"] == None or extent.D["end_time"] == None :
+        """!Return True if this temporal extent (A) starts before the start of the 
+           provided temporal extent (B) and finishes with it
+           A  |---------|
+           B      |-----|
+           
+           @param extent: The temporal extent object with which this extent finishes
+           
+           Usage:
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=6, end_time=7 )
+           >>> A.finished(B)
+           True
+           >>> B.finished(A)
+           False
+        """
+        if  self.D["end_time"] is None or extent.D["end_time"] is None:
             return False
 
-	if self.D["end_time"] == extent.D["end_time"] and  self.D["start_time"] < extent.D["start_time"] :
-	    return True
+        if self.D["end_time"] == extent.D["end_time"] and \
+           self.D["start_time"] < extent.D["start_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def after(self, extent):
-	"""!Return True if this time object is temporal located after the provided time object
-	   A             |---------|
-	   B  |---------|
-	"""
-        if extent.D["end_time"] == None:
+        """!Return True if this temporal extent (A) is located after the  
+           provided temporal extent (B)
+           A             |---------|
+           B  |---------|
+           
+           @param extent: The temporal extent object that is located before this extent
+           
+           Usage:
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=8, end_time=9 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=6, end_time=7 )
+           >>> A.after(B)
+           True
+           >>> B.after(A)
+           False
+        """
+        if extent.D["end_time"] is None:
             if self.D["start_time"] > extent.D["start_time"]:
                 return True
             else:
                 return False
 
-	if self.D["start_time"] > extent.D["end_time"]:
-	    return True
+        if self.D["start_time"] > extent.D["end_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def before(self, extent):
-	"""!Return True if this time object is temporal located before the provided time object
-	   A  |---------|
-	   B             |---------|
-	"""
-        if self.D["end_time"] == None:
+        """!Return True if this temporal extent (A) is located before the  
+           provided temporal extent (B)
+           A  |---------|
+           B             |---------|
+           
+           @param extent: The temporal extent object that is located after this extent
+           
+           Usage:
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=6, end_time=7 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=8, end_time=9 )
+           >>> A.before(B)
+           True
+           >>> B.before(A)
+           False
+        """
+        if self.D["end_time"] is None:
             if self.D["start_time"] < extent.D["start_time"]:
                 return True
             else:
                 return False
 
-	if self.D["end_time"] < extent.D["start_time"]:
-	    return True
+        if self.D["end_time"] < extent.D["start_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def adjacent(self, extent):
-	"""!Return True if this time object is a meeting neighbour the provided time object
-	   A            |---------|
-	   B  |---------|
-	   A  |---------|
-	   B            |---------|
-	"""
-        if  self.D["end_time"] == None and extent.D["end_time"] == None :
+        """!Return True if this temporal extent (A) is a meeting neighbor the 
+           provided temporal extent (B)
+           A            |---------|
+           B  |---------|
+           A  |---------|
+           B            |---------|
+           
+           @param extent: The temporal extent object that is a meeting neighbor
+                          of this extent
+           
+           Usage:
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=7, end_time=9 )
+           >>> A.adjacent(B)
+           True
+           >>> B.adjacent(A)
+           True
+           >>> A = tgis.AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=3, end_time=5 )
+           >>> A.adjacent(B)
+           True
+           >>> B.adjacent(A)
+           True
+        """
+        if  self.D["end_time"] is None and extent.D["end_time"] is None:
             return False
-        
-	if (self.D["start_time"] == extent.D["end_time"]) or (self.D["end_time"] == extent.D["start_time"]):
-	    return True
+
+        if (self.D["start_time"] == extent.D["end_time"]) or \
+           (self.D["end_time"] == extent.D["start_time"]):
+            return True
         else:
-	    return False
+            return False
 
     def follows(self, extent):
-	"""!Return True if this time object temporally follows the provided time object
-	   A            |---------|
-	   B  |---------|
-	"""
-        if  extent.D["end_time"] == None :
+        """!Return True if this temporal extent (A) follows the  
+           provided temporal extent (B)
+           A            |---------|
+           B  |---------|
+           
+           @param extent: The temporal extent object that is the predecessor
+                          of this extent
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=3, end_time=5 )
+           >>> A.follows(B)
+           True
+           >>> B.follows(A)
+           False
+        """
+        if  extent.D["end_time"] is None:
             return False
 
-	if self.D["start_time"] == extent.D["end_time"]:
-	    return True
+        if self.D["start_time"] == extent.D["end_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def precedes(self, extent):
-	"""!Return True if this time object is temporal precedes the provided time object
-	   A  |---------|
-	   B            |---------|
-	"""
-        if  self.D["end_time"] == None:
+        """!Return True if this temporal extent (A) precedes the provided 
+           temporal extent (B)
+           A  |---------|
+           B            |---------|
+           
+           @param extent: The temporal extent object that is the successor
+                          of this extent
+           
+           Usage:
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=7, end_time=9 )
+           >>> A.precedes(B)
+           True
+           >>> B.precedes(A)
+           False
+        """
+        if  self.D["end_time"] is None:
             return False
 
-	if self.D["end_time"] == extent.D["start_time"]:
-	    return True
+        if self.D["end_time"] == extent.D["start_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def during(self, extent):
-	"""!Return True if this time object is temporal located during the provided time object
-	   A   |-------|
-	   B  |---------|
-	"""
+        """!Return True if this temporal extent (A) is located during the provided 
+           temporal extent (B)
+           A   |-------|
+           B  |---------|
+           
+           @param extent: The temporal extent object that contains this extent
+           
+           Usage:
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=4, end_time=9 )
+           >>> A.during(B)
+           True
+           >>> B.during(A)
+           False
+        """
         # Check single point of time in interval
-        if  extent.D["end_time"] == None:
-                return False
+        if  extent.D["end_time"] is None:
+            return False
 
         # Check single point of time in interval
-        if  self.D["end_time"] == None:
-            if self.D["start_time"] > extent.D["start_time"] and self.D["start_time"] < extent.D["end_time"]:
+        if  self.D["end_time"] is None:
+            if self.D["start_time"] > extent.D["start_time"] and \
+               self.D["start_time"] < extent.D["end_time"]:
                 return True
             else:
                 return False
 
-	if self.D["start_time"] > extent.D["start_time"] and self.D["end_time"] < extent.D["end_time"]:
-	    return True
+        if self.D["start_time"] > extent.D["start_time"] and \
+           self.D["end_time"] < extent.D["end_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def contains(self, extent):
-	"""!Return True if this time object contains the provided time object
-	   A  |---------|
-	   B   |-------|
-	"""
+        """!Return True if this temporal extent (A) contains the provided 
+           temporal extent (B)
+           A  |---------|
+           B   |-------|
+           
+           @param extent: The temporal extent object that is located 
+                          during this extent
+           
+           Usage:
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=4, end_time=9 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=5, end_time=8 )
+           >>> A.contains(B)
+           True
+           >>> B.contains(A)
+           False
+        """
         # Check single point of time in interval
-        if  self.D["end_time"] == None:
-                return False
+        if  self.D["end_time"] is None:
+            return False
 
         # Check single point of time in interval
-        if  extent.D["end_time"] == None:
-            if self.D["start_time"] < extent.D["start_time"] and self.D["end_time"] > extent.D["start_time"]:
+        if  extent.D["end_time"] is None:
+            if self.D["start_time"] < extent.D["start_time"] and \
+               self.D["end_time"] > extent.D["start_time"]:
                 return True
             else:
                 return False
 
-	if self.D["start_time"] < extent.D["start_time"] and self.D["end_time"] > extent.D["end_time"]:
-	    return True
+        if self.D["start_time"] < extent.D["start_time"] and \
+           self.D["end_time"] > extent.D["end_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def equivalent(self, extent):
-	"""!Return True if this time object is temporal located equivalent the provided time object
-	   A  |---------|
-	   B  |---------|
-	"""
-        if  self.D["end_time"] == None and extent.D["end_time"] == None :
+        """!Return True if this temporal extent (A) is equivalent to the provided 
+           temporal extent (B)
+           A  |---------|
+           B  |---------|
+           
+           @param extent: The temporal extent object that is equivalent 
+                          during this extent
+           
+           Usage:
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=5, end_time=6 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=5, end_time=6 )
+           >>> A.equivalent(B)
+           True
+           >>> B.equivalent(A)
+           True
+        """
+        if  self.D["end_time"] is None and extent.D["end_time"] is None:
             if self.D["start_time"] == extent.D["start_time"]:
                 return True
             else:
                 return False
 
-        if  self.D["end_time"] == None or extent.D["end_time"] == None :
+        if  self.D["end_time"] is None or extent.D["end_time"] is None:
             return False
 
-	if self.D["start_time"] == extent.D["start_time"] and self.D["end_time"] == extent.D["end_time"]:
-	    return True
+        if self.D["start_time"] == extent.D["start_time"] and \
+           self.D["end_time"] == extent.D["end_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def overlapped(self, extent):
-	"""!Return True if this time object temporally overlapped the provided time object
+        """!Return True if this temporal extent (A) overlapped the provided 
+           temporal extent (B)
            A  |---------|
-	   B    |---------|
-	"""
-        if  self.D["end_time"] == None or extent.D["end_time"] == None :
+           B    |---------|
+           
+           @param extent: The temporal extent object that is overlaps 
+                          this extent
+           
+           Usage:
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=6, end_time=8 )
+           >>> A.overlapped(B)
+           True
+           >>> B.overlapped(A)
+           False
+        """
+        if  self.D["end_time"] is None or extent.D["end_time"] is None:
             return False
 
-	if self.D["start_time"] < extent.D["start_time"] and self.D["end_time"] < extent.D["end_time"] and\
-	   self.D["end_time"] > extent.D["start_time"]:
-	    return True
+        if self.D["start_time"] < extent.D["start_time"] and \
+           self.D["end_time"] < extent.D["end_time"] and \
+           self.D["end_time"] > extent.D["start_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def overlaps(self, extent):
-	"""!Return True if this time object temporally overlaps the provided time object
-	   A    |---------|
+        """!Return True if this temporal extent (A) overlapps the provided 
+           temporal extent (B)
+           A    |---------|
            B  |---------|
-	"""
-        if  self.D["end_time"] == None or extent.D["end_time"] == None :
+           
+           @param extent: The temporal extent object that is overlapped 
+                          this extent
+           
+           Usage:
+           
+           >>> import grass.temporal as tgis
+           >>> A = tgis.AbstractTemporalExtent(start_time=6, end_time=8 )
+           >>> B = tgis.AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> A.overlaps(B)
+           True
+           >>> B.overlaps(A)
+           False
+        """
+        if  self.D["end_time"] is None or extent.D["end_time"] is None:
             return False
-            
-	if self.D["start_time"] > extent.D["start_time"] and self.D["end_time"] > extent.D["end_time"] and\
-	   self.D["start_time"] < extent.D["end_time"]:
-	    return True
+
+        if self.D["start_time"] > extent.D["start_time"] and \
+           self.D["end_time"] > extent.D["end_time"] and \
+           self.D["start_time"] < extent.D["end_time"]:
+            return True
         else:
-	    return False
+            return False
 
     def temporal_relation(self, extent):
-	"""!Returns the temporal relation between temporal objects
-	   Temporal relationships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
-	"""
-        
+        """!Returns the temporal relation between temporal objects
+           Temporal relationships are implemented after 
+           [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
+           
+           The following temporal relationships are supported:
+           * equivalent
+           * during
+           * contains
+           * overlaps
+           * overlapped
+           * after
+           * before
+           * starts
+           * finishes
+           * started
+           * finished
+           * follows
+           * precedes
+           
+           @param extent: The temporal extent 
+           @return The name of the temporal relation or None if no relation found
+        """
+
         # First check for correct time
-        if not self.D.has_key("start_time"):
+        if "start_time" not in self.D:
             return None
-        if not self.D.has_key("end_time"):
+        if "end_time" not in self.D:
             return None
-        if not extent.D.has_key("start_time"):
+        if "start_time" not in extent.D:
             return None
-        if not extent.D.has_key("end_time"):
+        if "end_time" not in extent.D:
             return None
-
-        if self.D["start_time"] == None or extent.D["start_time"] == None:
+        # Return None if the start_time is undefined
+        if self.D["start_time"] is None or extent.D["start_time"] is None:
             return None
 
-	if self.equivalent(extent):
-	    return "equivalent"
-	if self.during(extent):
-	    return "during"
-	if self.contains(extent):
-	    return "contains"
-	if self.overlaps(extent):
-	    return "overlaps"
-	if self.overlapped(extent):
-	    return "overlapped"
-	if self.after(extent):
-	    return "after"
-	if self.before(extent):
-	    return "before"
-	if self.starts(extent):
-	    return "starts"
-	if self.finishes(extent):
-	    return "finishes"
-	if self.started(extent):
-	    return "started"
-	if self.finished(extent):
-	    return "finished"
-	if self.follows(extent):
-	    return "follows"
-	if self.precedes(extent):
-	    return "precedes"
+        if self.equivalent(extent):
+            return "equivalent"
+        if self.during(extent):
+            return "during"
+        if self.contains(extent):
+            return "contains"
+        if self.overlaps(extent):
+            return "overlaps"
+        if self.overlapped(extent):
+            return "overlapped"
+        if self.after(extent):
+            return "after"
+        if self.before(extent):
+            return "before"
+        if self.starts(extent):
+            return "starts"
+        if self.finishes(extent):
+            return "finishes"
+        if self.started(extent):
+            return "started"
+        if self.finished(extent):
+            return "finished"
+        if self.follows(extent):
+            return "follows"
+        if self.precedes(extent):
+            return "precedes"
         return None
 
     def set_id(self, ident):
-	"""!Convenient method to set the unique identifier (primary key)"""
-	self.ident = ident
-	self.D["id"] = ident
+        """!Convenient method to set the unique identifier (primary key)"""
+        self.ident = ident
+        self.D["id"] = ident
 
     def set_start_time(self, start_time):
-	"""!Set the valid start time of the extent"""
-	self.D["start_time"] = start_time
+        """!Set the valid start time of the extent"""
+        self.D["start_time"] = start_time
 
     def set_end_time(self, end_time):
-	"""!Set the valid end time of the extent"""
-	self.D["end_time"] = end_time
+        """!Set the valid end time of the extent"""
+        self.D["end_time"] = end_time
 
     def get_id(self):
-	"""!Convenient method to get the unique identifier (primary key)
-	   @return None if not found
-	"""
-	if self.D.has_key("id"):
-	    return self.D["id"]
+        """!Convenient method to get the unique identifier (primary key)
+           @return None if not found
+        """
+        if "id" in self.D:
+            return self.D["id"]
         else:
-	    return None
+            return None
 
     def get_start_time(self):
-	"""!Get the valid start time of the extent
-	   @return None if not found"""
-	if self.D.has_key("start_time"):
-	    return self.D["start_time"]
+        """!Get the valid start time of the extent
+           @return None if not found"""
+        if "start_time" in self.D:
+            return self.D["start_time"]
         else:
-	    return None
+            return None
 
     def get_end_time(self):
-	"""!Get the valid end time of the extent
-	   @return None if not found"""
-	if self.D.has_key("end_time"):
-	    return self.D["end_time"]
+        """!Get the valid end time of the extent
+           @return None if not found"""
+        if "end_time" in self.D:
+            return self.D["end_time"]
         else:
-	    return None
+            return None
+    
+    # Set the properties
+    id = property(fget=get_id, fset=set_id)
+    start_time = property(fget=get_start_time, fset=set_start_time)
+    end_time = property(fget=get_end_time, fset=set_end_time)
 
     def print_info(self):
         """!Print information about this class in human readable style"""
@@ -345,93 +615,139 @@
 
 ###############################################################################
 
-class absolute_temporal_extent(abstract_temporal_extent):
+
+class AbsoluteTemporalExtent(AbstractTemporalExtent):
     """!This is the absolute time class for all maps and spacetime datasets
 
-       start_time and end_time must be of type datetime
+        start_time and end_time must be of type datetime
     """
-    def __init__(self, table=None, ident=None, start_time=None, end_time=None, timezone=None):
+    def __init__(self, table=None, ident=None, start_time=None, end_time=None, 
+                 timezone=None):
 
-	abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
+        AbstractTemporalExtent.__init__(
+            self, table, ident, start_time, end_time)
 
-	self.set_timezone(timezone)
+        self.set_timezone(timezone)
 
     def set_timezone(self, timezone):
-	"""!Set the timezone of the map, the timezone is of type string.
-           Timezones are not supported yet, instead the timezone is set in the datetime string as offset in minutes.
+        """!Set the timezone of the map, the timezone is of type string.
+           Timezones are not supported yet, instead the timezone 
+           is set in the datetime string as offset in minutes.
         """
-	self.D["timezone"] = timezone
+        self.D["timezone"] = timezone
 
     def get_timezone(self):
-	"""!Get the timezone of the map
-           Timezones are not supported yet, instead the timezone is set in the datetime string as offset in minutes.
-	   @return None if not found"""
-	if self.D.has_key("timezone"):
-	    return self.D["timezone"]
+        """!Get the timezone of the map
+           Timezones are not supported yet, instead the timezone 
+           is set in the datetime string as offset in minutes.
+           @return None if not found"""
+        if "timezone" in self.D:
+            return self.D["timezone"]
         else:
-	    return None
-
+            return None
+        
+    timezone = property(fget=get_timezone, fset=set_timezone)
+    
     def print_info(self):
         """!Print information about this class in human readable style"""
         #      0123456789012345678901234567890
         print " +-------------------- Absolute time -----------------------------------------+"
-        abstract_temporal_extent.print_info(self)
+        AbstractTemporalExtent.print_info(self)
         #print " | Timezone:................... " + str(self.get_timezone())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-        abstract_temporal_extent.print_shell_info(self)
+        AbstractTemporalExtent.print_shell_info(self)
         #print "timezone=" + str(self.get_timezone())
 
 ###############################################################################
 
-class raster_absolute_time(absolute_temporal_extent):
+class RasterAbsoluteTime(AbsoluteTemporalExtent):
     def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
-        absolute_temporal_extent.__init__(self, "raster_absolute_time", ident, start_time, end_time, timezone)
+        AbsoluteTemporalExtent.__init__(self, "raster_absolute_time",
+            ident, start_time, end_time, timezone)
 
-class raster3d_absolute_time(absolute_temporal_extent):
+class Raster3DAbsoluteTime(AbsoluteTemporalExtent):
     def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
-        absolute_temporal_extent.__init__(self, "raster3d_absolute_time", ident, start_time, end_time, timezone)
+        AbsoluteTemporalExtent.__init__(self, "raster3d_absolute_time",
+            ident, start_time, end_time, timezone)
 
-class vector_absolute_time(absolute_temporal_extent):
+class VectorAbsoluteTime(AbsoluteTemporalExtent):
     def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
-        absolute_temporal_extent.__init__(self, "vector_absolute_time", ident, start_time, end_time, timezone)
+        AbsoluteTemporalExtent.__init__(self, "vector_absolute_time",
+            ident, start_time, end_time, timezone)
 
 ###############################################################################
 
-class stds_absolute_time(absolute_temporal_extent):
-    def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None, timezone=None, map_time=None):
-        absolute_temporal_extent.__init__(self, table, ident, start_time, end_time, timezone)
+class STDSAbsoluteTime(AbsoluteTemporalExtent):
+    """!This class implements the absolute time extent for space time dataset
+    
+        In addition to the existing functionality the granularity and the 
+        map_time are added.
+        
+        Usage:
+        
+        >>> import grass.temporal as tgis
+        >>> A = tgis.STDSAbsoluteTime(table="strds_absolute_time",
+        ... ident="strds at PERMANENT", start_time=datetime(2001, 01, 01),
+        ... end_time=datetime(2005,01,01), granularity="1 days",
+        ... map_time="interval")
+        >>> A.id
+        'strds at PERMANENT'
+        >>> A.start_time
+        datetime.datetime(2001, 1, 1, 0, 0)
+        >>> A.end_time
+        datetime.datetime(2005, 1, 1, 0, 0)
+        >>> A.granularity
+        '1 days'
+        >>> A.map_time
+        'interval'
+        >>> A.print_info()
+         +-------------------- Absolute time -----------------------------------------+
+         | Start time:................. 2001-01-01 00:00:00
+         | End time:................... 2005-01-01 00:00:00
+         | Granularity:................ 1 days
+         | Temporal type of maps:...... interval
+        >>> A.print_shell_info()
+        start_time=2001-01-01 00:00:00
+        end_time=2005-01-01 00:00:00
+        granularity=1 days
+        map_time=interval
+    """
+    def __init__(self, table=None, ident=None, start_time=None, end_time=None, 
+                 granularity=None, timezone=None, map_time=None):
+        AbsoluteTemporalExtent.__init__(
+            self, table, ident, start_time, end_time, timezone)
 
-	self.set_granularity(granularity)
+        self.set_granularity(granularity)
         self.set_map_time(map_time)
 
     def set_granularity(self, granularity):
-	"""!Set the granularity of the space time dataset"""
-	self.D["granularity"] = granularity
+        """!Set the granularity of the space time dataset"""
+        self.D["granularity"] = granularity
 
     def set_map_time(self, map_time):
-	"""!Set the type of the map time
+        """!Set the type of the map time
 
            Registered maps may have different types of time:
-           Single point of time "point"
-           Time intervals "interval"
-           Or single point and interval time "mixed"
+           * Single point of time "point"
+           * Time intervals "interval"
+           * Single point and interval time "mixed"
 
            This variable will be set automatically when maps are registered.
         """
-	self.D["map_time"] = map_time
+        self.D["map_time"] = map_time
 
     def get_granularity(self):
-	"""!Get the granularity of the space time dataset
-	   @return None if not found"""
-	if self.D.has_key("granularity"):
-	    return self.D["granularity"]
+        """!Get the granularity of the space time dataset
+           @return None if not found"""
+        if "granularity" in self.D:
+            return self.D["granularity"]
         else:
-	    return None
+            return None
 
     def get_map_time(self):
-	"""!Get the type of the map time
+        """!Get the type of the map time
 
            Registered maps may have different types of time:
            Single point of time "point"
@@ -440,49 +756,86 @@
 
            This variable will be set automatically when maps are registered.
         """
-	if self.D.has_key("map_time"):
-	    return self.D["map_time"]
+        if "map_time" in self.D:
+            return self.D["map_time"]
         else:
-	    return None
-
+            return None
+    
+    # Properties
+    granularity = property(fget=get_granularity, fset=set_granularity)
+    map_time = property(fget=get_map_time, fset=set_map_time)
+    
     def print_info(self):
         """!Print information about this class in human readable style"""
-        absolute_temporal_extent.print_info(self)
+        AbsoluteTemporalExtent.print_info(self)
         #      0123456789012345678901234567890
         print " | Granularity:................ " + str(self.get_granularity())
         print " | Temporal type of maps:...... " + str(self.get_map_time())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-        absolute_temporal_extent.print_shell_info(self)
+        AbsoluteTemporalExtent.print_shell_info(self)
         print "granularity=" + str(self.get_granularity())
         print "map_time=" + str(self.get_map_time())
 
 ###############################################################################
 
-class strds_absolute_time(stds_absolute_time):
-    def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
-        stds_absolute_time.__init__(self, "strds_absolute_time", ident, start_time, end_time, granularity, timezone)
+class STRDSAbsoluteTime(STDSAbsoluteTime):
+    def __init__(self, ident=None, start_time=None, end_time=None, 
+                 granularity=None, timezone=None):
+        STDSAbsoluteTime.__init__(self, "strds_absolute_time",
+            ident, start_time, end_time, granularity, timezone)
 
-class str3ds_absolute_time(stds_absolute_time):
-    def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
-        stds_absolute_time.__init__(self, "str3ds_absolute_time", ident, start_time, end_time, granularity, timezone)
 
-class stvds_absolute_time(stds_absolute_time):
-    def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
-        stds_absolute_time.__init__(self, "stvds_absolute_time", ident, start_time, end_time, granularity, timezone)
+class STR3DSAbsoluteTime(STDSAbsoluteTime):
+    def __init__(self, ident=None, start_time=None, end_time=None, 
+                 granularity=None, timezone=None):
+        STDSAbsoluteTime.__init__(self, "str3ds_absolute_time",
+            ident, start_time, end_time, granularity, timezone)
 
+
+class STVDSAbsoluteTime(STDSAbsoluteTime):
+    def __init__(self, ident=None, start_time=None, end_time=None, 
+                 granularity=None, timezone=None):
+        STDSAbsoluteTime.__init__(self, "RelativeTemporalExtent",
+            ident, start_time, end_time, granularity, timezone)
+
 ###############################################################################
 
-class relative_temporal_extent(abstract_temporal_extent):
+class RelativeTemporalExtent(AbstractTemporalExtent):
     """!This is the relative time class for all maps and spacetime datasets
 
-       start_time and end_time must be of type integer
+        start_time and end_time must be of type integer
+       
+        Usage:
+       
+        >>> import grass.temporal as tgis
+        >>> A = tgis.RelativeTemporalExtent(table="raster_absolute_time",
+        ... ident="soil at PERMANENT", start_time=0, end_time=1, unit="years")
+        >>> A.id
+        'soil at PERMANENT'
+        >>> A.start_time
+        0
+        >>> A.end_time
+        1
+        >>> A.unit
+        'years'
+        >>> A.print_info()
+         +-------------------- Relative time -----------------------------------------+
+         | Start time:................. 0
+         | End time:................... 1
+         | Relative time unit:......... years
+        >>> A.print_shell_info()
+        start_time=0
+        end_time=1
+        unit=years
     """
-    def __init__(self, table=None, ident=None, start_time=None, end_time=None, unit=None):
+    def __init__(self, table=None, ident=None, start_time=None, end_time=None, 
+                 unit=None):
 
-	abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
-	self.D["unit"] = unit
+        AbstractTemporalExtent.__init__(
+            self, table, ident, start_time, end_time)
+        self.D["unit"] = unit
 
     def set_unit(self, unit):
         """!Set the unit of the relative time. Valid units are:
@@ -493,74 +846,121 @@
            * minutes
            * seconds
         """
-	self.D["unit"] = unit
+        self.D["unit"] = unit
 
     def get_unit(self):
-	"""!Get the unit of the relative time
-	   @return None if not found"""
-	if self.D.has_key("unit"):
-	    return self.D["unit"]
+        """!Get the unit of the relative time
+           @return None if not found"""
+        if "unit" in self.D:
+            return self.D["unit"]
         else:
-	    return None
+            return None
 
     def temporal_relation(self, map):
-	"""!Returns the temporal relation between temporal objects
-	   Temporal relationships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
-	"""
-        
+        """!Returns the temporal relation between temporal objects
+           Temporal relationships are implemented after 
+           [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
+        """
+
         # Check units for relative time
-        if not self.D.has_key("unit"):
+        if "unit" not in self.D:
             return None
-        if not map.D.has_key("unit"):
+        if "unit" not in map.D:
             return None
 
         # Units must be equal
         if self.D["unit"] != map.D["unit"]:
             return None
 
-	return abstract_temporal_extent.temporal_relation(self, map)
+        return AbstractTemporalExtent.temporal_relation(self, map)
+    
+    # Properties
+    unit = property(fget=get_unit, fset=set_unit)
 
     def print_info(self):
         """!Print information about this class in human readable style"""
         #      0123456789012345678901234567890
         print " +-------------------- Relative time -----------------------------------------+"
-        abstract_temporal_extent.print_info(self)
+        AbstractTemporalExtent.print_info(self)
         print " | Relative time unit:......... " + str(self.get_unit())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-        abstract_temporal_extent.print_shell_info(self)
+        AbstractTemporalExtent.print_shell_info(self)
         print "unit=" + str(self.get_unit())
 
 ###############################################################################
 
-class raster_relative_time(relative_temporal_extent):
+class RasterRelativeTime(RelativeTemporalExtent):
     def __init__(self, ident=None, start_time=None, end_time=None):
-        relative_temporal_extent.__init__(self, "raster_relative_time", ident, start_time, end_time)
+        RelativeTemporalExtent.__init__(
+            self, "raster_relative_time", ident, start_time, end_time)
 
-class raster3d_relative_time(relative_temporal_extent):
+
+class Raster3DRelativeTime(RelativeTemporalExtent):
     def __init__(self, ident=None, start_time=None, end_time=None):
-        relative_temporal_extent.__init__(self, "raster3d_relative_time", ident, start_time, end_time)
+        RelativeTemporalExtent.__init__(self,
+            "raster3d_relative_time", ident, start_time, end_time)
 
-class vector_relative_time(relative_temporal_extent):
+
+class VectorRelativeTime(RelativeTemporalExtent):
     def __init__(self, ident=None, start_time=None, end_time=None):
-        relative_temporal_extent.__init__(self, "vector_relative_time", ident, start_time, end_time)
-        
+        RelativeTemporalExtent.__init__(
+            self, "vector_relative_time", ident, start_time, end_time)
+
 ###############################################################################
 
-class stds_relative_time(relative_temporal_extent):
-    def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None, map_time=None):
-        relative_temporal_extent.__init__(self, table, ident, start_time, end_time)
+class STDSRelativeTime(RelativeTemporalExtent):
+    """!This is the relative time class for all maps and spacetime datasets
 
-	self.set_granularity(granularity)
+        start_time and end_time must be of type integer
+       
+        Usage:
+       
+        >>> import grass.temporal as tgis
+        >>> A = tgis.STDSRelativeTime(table="raster_absolute_time",
+        ... ident="soil at PERMANENT", start_time=0, end_time=1, unit="years",
+        ... granularity=5, map_time="interval")
+        >>> A.id
+        'soil at PERMANENT'
+        >>> A.start_time
+        0
+        >>> A.end_time
+        1
+        >>> A.unit
+        'years'
+        >>> A.granularity
+        5
+        >>> A.map_time
+        'interval'
+        >>> A.print_info()
+         +-------------------- Relative time -----------------------------------------+
+         | Start time:................. 0
+         | End time:................... 1
+         | Relative time unit:......... years
+         | Granularity:................ 5
+         | Temporal type of maps:...... interval
+        >>> A.print_shell_info()
+        start_time=0
+        end_time=1
+        unit=years
+        granularity=5
+        map_time=interval
+    """
+    def __init__(self, table=None, ident=None, start_time=None, end_time=None, 
+                 unit=None, granularity=None, map_time=None):
+        RelativeTemporalExtent.__init__(
+            self, table, ident, start_time, end_time, unit)
+
+        self.set_granularity(granularity)
         self.set_map_time(map_time)
 
     def set_granularity(self, granularity):
-	"""!Set the granularity of the space time dataset"""
-	self.D["granularity"] = granularity
+        """!Set the granularity of the space time dataset"""
+        self.D["granularity"] = granularity
 
     def set_map_time(self, map_time):
-	"""!Set the type of the map time
+        """!Set the type of the map time
 
            Registered maps may have different types of time:
            Single point of time "point"
@@ -569,18 +969,18 @@
 
            This variable will be set automatically when maps are registered.
         """
-	self.D["map_time"] = map_time
+        self.D["map_time"] = map_time
 
     def get_granularity(self):
-	"""!Get the granularity of the space time dataset
-	   @return None if not found"""
-	if self.D.has_key("granularity"):
-	    return self.D["granularity"]
+        """!Get the granularity of the space time dataset
+           @return None if not found"""
+        if "granularity" in self.D:
+            return self.D["granularity"]
         else:
-	    return None
+            return None
 
     def get_map_time(self):
-	"""!Get the type of the map time
+        """!Get the type of the map time
 
            Registered maps may have different types of time:
            Single point of time "point"
@@ -589,34 +989,52 @@
 
            This variable will be set automatically when maps are registered.
         """
-	if self.D.has_key("map_time"):
-	    return self.D["map_time"]
+        if "map_time" in self.D:
+            return self.D["map_time"]
         else:
-	    return None
-
+            return None
+    
+    # Properties
+    granularity = property(fget=get_granularity, fset=set_granularity)
+    map_time = property(fget=get_map_time, fset=set_map_time)
+    
     def print_info(self):
         """!Print information about this class in human readable style"""
-        relative_temporal_extent.print_info(self)
+        RelativeTemporalExtent.print_info(self)
         #      0123456789012345678901234567890
         print " | Granularity:................ " + str(self.get_granularity())
         print " | Temporal type of maps:...... " + str(self.get_map_time())
 
     def print_shell_info(self):
         """!Print information about this class in shell style"""
-        relative_temporal_extent.print_shell_info(self)
+        RelativeTemporalExtent.print_shell_info(self)
         print "granularity=" + str(self.get_granularity())
         print "map_time=" + str(self.get_map_time())
 
 ###############################################################################
 
-class strds_relative_time(stds_relative_time):
-    def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
-        stds_relative_time.__init__(self, "strds_relative_time", ident, start_time, end_time, granularity)
+class STRDSRelativeTime(STDSRelativeTime):
+    def __init__(self, ident=None, start_time=None, end_time=None, 
+                 granularity=None):
+        STDSRelativeTime.__init__(self, "strds_relative_time",
+            ident, start_time, end_time, granularity)
 
-class str3ds_relative_time(stds_relative_time):
-    def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
-        stds_relative_time.__init__(self, "str3ds_relative_time", ident, start_time, end_time, granularity)
 
-class stvds_relative_time(stds_relative_time):
-    def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
-        stds_relative_time.__init__(self, "stvds_relative_time", ident, start_time, end_time, granularity)
+class STR3DSRelativeTime(STDSRelativeTime):
+    def __init__(self, ident=None, start_time=None, end_time=None, 
+                 granularity=None):
+        STDSRelativeTime.__init__(self, "str3ds_relative_time",
+            ident, start_time, end_time, granularity)
+
+
+class STVDSRelativeTime(STDSRelativeTime):
+    def __init__(self, ident=None, start_time=None, end_time=None, 
+                 granularity=None):
+        STDSRelativeTime.__init__(self, "stvds_relative_time",
+            ident, start_time, end_time, granularity)
+
+###############################################################################
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
\ No newline at end of file

Modified: grass/trunk/lib/python/temporal/temporal_relationships.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_relationships.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/temporal_relationships.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -29,7 +29,7 @@
     """!This class is designed to build the temporal topology based on a lists of maps
     
 	Example:
-	
+	@code
 	# We have a space time raster dataset and build a map list
 	# from all registered maps ordered by start time
 	maps = strds.get_registered_maps_as_objects()
@@ -56,7 +56,7 @@
 	
 	# Dictionary like accessed
 	_map = tb["name at mapset"]
-	       
+	@endcode
     
     """
     def __init__(self):

Modified: grass/trunk/lib/python/temporal/univar_statistics.py
===================================================================
--- grass/trunk/lib/python/temporal/univar_statistics.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/lib/python/temporal/univar_statistics.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -38,7 +38,7 @@
     """
     
     # We need a database interface
-    dbif = sql_database_interface_connection()
+    dbif = SQLDatabaseInterfaceConnection()
     dbif.connect()
    
     mapset =  core.gisenv()["MAPSET"]
@@ -115,7 +115,7 @@
     """
 
     # We need a database interface
-    dbif = sql_database_interface_connection()
+    dbif = SQLDatabaseInterfaceConnection()
     dbif.connect()
    
     mapset =  core.gisenv()["MAPSET"]

Modified: grass/trunk/temporal/t.create/t.create.py
===================================================================
--- grass/trunk/temporal/t.create/t.create.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/temporal/t.create/t.create.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -80,7 +80,7 @@
 
     sp = tgis.dataset_factory(type, id)
 
-    dbif = tgis.sql_database_interface_connection()
+    dbif = tgis.SQLDatabaseInterfaceConnection()
     dbif.connect()
 
     if sp.is_in_db(dbif) and grass.overwrite() == False:

Modified: grass/trunk/temporal/t.list/t.list.py
===================================================================
--- grass/trunk/temporal/t.list/t.list.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/temporal/t.list/t.list.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -89,7 +89,7 @@
     id = None
     sp = tgis.dataset_factory(type, id)
 
-    dbif = tgis.sql_database_interface_connection()
+    dbif = tgis.SQLDatabaseInterfaceConnection()
     dbif.connect()
 
     # Create the sql selection statement

Modified: grass/trunk/temporal/t.rast.aggregate/t.rast.aggregate.py
===================================================================
--- grass/trunk/temporal/t.rast.aggregate/t.rast.aggregate.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/temporal/t.rast.aggregate/t.rast.aggregate.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -85,7 +85,7 @@
     # Make sure the temporal database exists
     tgis.create_temporal_database()
     # We need a database interface
-    dbif = tgis.sql_database_interface_connection()
+    dbif = tgis.SQLDatabaseInterfaceConnection()
     dbif.connect()
    
     mapset =  grass.gisenv()["MAPSET"]

Modified: grass/trunk/temporal/t.rast.aggregate.ds/t.rast.aggregate.ds.py
===================================================================
--- grass/trunk/temporal/t.rast.aggregate.ds/t.rast.aggregate.ds.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/temporal/t.rast.aggregate.ds/t.rast.aggregate.ds.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -82,7 +82,7 @@
     # Make sure the temporal database exists
     tgis.create_temporal_database()
     # We need a database interface
-    dbif = tgis.sql_database_interface_connection()
+    dbif = tgis.SQLDatabaseInterfaceConnection()
     dbif.connect()
    
     mapset =  grass.gisenv()["MAPSET"]

Modified: grass/trunk/temporal/t.rast.gapfill/t.rast.gapfill.py
===================================================================
--- grass/trunk/temporal/t.rast.gapfill/t.rast.gapfill.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/temporal/t.rast.gapfill/t.rast.gapfill.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -73,7 +73,7 @@
         id = input + "@" + mapset
 
     # We need a database interface
-    dbif = tgis.sql_database_interface_connection()
+    dbif = tgis.SQLDatabaseInterfaceConnection()
     dbif.connect()
     
     sp = tgis.space_time_raster_dataset(id)

Modified: grass/trunk/temporal/t.remove/t.remove.py
===================================================================
--- grass/trunk/temporal/t.remove/t.remove.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/temporal/t.remove/t.remove.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -59,7 +59,7 @@
     # Make sure the temporal database exists
     tgis.create_temporal_database()
 
-    dbif = tgis.sql_database_interface_connection()
+    dbif = tgis.SQLDatabaseInterfaceConnection()
     dbif.connect()
 
     dataset_list = []

Modified: grass/trunk/temporal/t.support/t.support.py
===================================================================
--- grass/trunk/temporal/t.support/t.support.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/temporal/t.support/t.support.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -89,7 +89,7 @@
     else:
         id = name + "@" + mapset
         
-    dbif = tgis.sql_database_interface_connection()
+    dbif = tgis.SQLDatabaseInterfaceConnection()
     dbif.connect()
 
     stds = tgis.dataset_factory(type, id)

Modified: grass/trunk/temporal/t.unregister/t.unregister.py
===================================================================
--- grass/trunk/temporal/t.unregister/t.unregister.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/temporal/t.unregister/t.unregister.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -63,7 +63,7 @@
 
     mapset =  grass.gisenv()["MAPSET"]
 
-    dbif = tgis.sql_database_interface_connection()
+    dbif = tgis.SQLDatabaseInterfaceConnection()
     dbif.connect()
 
     # In case a space time dataset is specified

Modified: grass/trunk/temporal/t.vect.observe.strds/t.vect.observe.strds.py
===================================================================
--- grass/trunk/temporal/t.vect.observe.strds/t.vect.observe.strds.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/temporal/t.vect.observe.strds/t.vect.observe.strds.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -74,7 +74,7 @@
     # Make sure the temporal database exists
     tgis.create_temporal_database()
     # We need a database interface
-    dbif = tgis.sql_database_interface_connection()
+    dbif = tgis.SQLDatabaseInterfaceConnection()
     dbif.connect()
    
     mapset =  grass.gisenv()["MAPSET"]

Modified: grass/trunk/temporal/t.vect.what.strds/t.vect.what.strds.py
===================================================================
--- grass/trunk/temporal/t.vect.what.strds/t.vect.what.strds.py	2012-08-10 12:33:02 UTC (rev 52620)
+++ grass/trunk/temporal/t.vect.what.strds/t.vect.what.strds.py	2012-08-10 14:48:01 UTC (rev 52621)
@@ -80,7 +80,7 @@
     # Make sure the temporal database exists
     tgis.create_temporal_database()
     # We need a database interface
-    dbif = tgis.sql_database_interface_connection()
+    dbif = tgis.SQLDatabaseInterfaceConnection()
     dbif.connect()
    
     mapset =  grass.gisenv()["MAPSET"]



More information about the grass-commit mailing list