[GRASS-SVN] r48399 - in grass/trunk: lib/python lib/python/temporal lib/temporal temporal/t.create temporal/t.info temporal/t.list temporal/t.remove temporal/t.time.abs temporal/t.time.rel temporal/tr.register temporal/tr.unregister temporal/tr3.register temporal/tr3.unregister temporal/tv.register temporal/tv.unregister

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Sep 21 17:06:55 EDT 2011


Author: huhabla
Date: 2011-09-21 14:06:55 -0700 (Wed, 21 Sep 2011)
New Revision: 48399

Added:
   grass/trunk/lib/python/temporal/
   grass/trunk/lib/python/temporal/abstract_datasets.py
   grass/trunk/lib/python/temporal/base.py
   grass/trunk/lib/python/temporal/core.py
   grass/trunk/lib/python/temporal/metadata.py
   grass/trunk/lib/python/temporal/space_time_datasets.py
   grass/trunk/lib/python/temporal/spatial_extent.py
   grass/trunk/lib/python/temporal/temporal_extent.py
Removed:
   grass/trunk/lib/python/tgis_abstract_datasets.py
   grass/trunk/lib/python/tgis_base.py
   grass/trunk/lib/python/tgis_core.py
   grass/trunk/lib/python/tgis_metadata.py
   grass/trunk/lib/python/tgis_space_time_datasets.py
   grass/trunk/lib/python/tgis_spatial_extent.py
   grass/trunk/lib/python/tgis_temporal_extent.py
Modified:
   grass/trunk/lib/python/Makefile
   grass/trunk/lib/temporal/Makefile
   grass/trunk/temporal/t.create/t.create.py
   grass/trunk/temporal/t.info/t.info.py
   grass/trunk/temporal/t.list/t.list.py
   grass/trunk/temporal/t.remove/t.remove.py
   grass/trunk/temporal/t.time.abs/t.time.abs.py
   grass/trunk/temporal/t.time.rel/t.time.rel.py
   grass/trunk/temporal/tr.register/tr.register.py
   grass/trunk/temporal/tr.unregister/tr.unregister.py
   grass/trunk/temporal/tr3.register/tr3.register.py
   grass/trunk/temporal/tr3.unregister/tr3.unregister.py
   grass/trunk/temporal/tv.register/tv.register.py
   grass/trunk/temporal/tv.unregister/tv.unregister.py
Log:
Moved the temporal GIS code from grass.script into a separate library structure named grass.temporal.

Modified: grass/trunk/lib/python/Makefile
===================================================================
--- grass/trunk/lib/python/Makefile	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/Makefile	2011-09-21 21:06:55 UTC (rev 48399)
@@ -8,16 +8,17 @@
 GDIR = $(PYDIR)/grass
 DSTDIR = $(GDIR)/script
 
-MODULES = core db raster raster3d vector array setup task tgis_base tgis_core tgis_abstract_datasets tgis_space_time_datasets tgis_metadata tgis_spatial_extent tgis_temporal_extent
+MODULES = core db raster raster3d vector array setup task 
 
 PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
 PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)
 
-CLEAN_SUBDIRS = ctypes
+CLEAN_SUBDIRS = ctypes temporal
 EXTRA_CLEAN_FILES = setup.py
 
 default: $(PYFILES) $(PYCFILES) $(GDIR)/__init__.py $(GDIR)/__init__.pyc
 	-$(MAKE) -C ctypes || echo $(CURDIR)/ctypes >> $(ERRORLOG)
+	-$(MAKE) -C temporal || echo $(CURDIR)/temporal >> $(ERRORLOG)
 
 $(PYDIR):
 	$(MKDIR) $@

Added: grass/trunk/lib/python/temporal/abstract_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_datasets.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/abstract_datasets.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,758 @@
+"""!@package grass.script.tgis_abstract_datasets
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in temporal GIS Python library package.
+
+Usage:
+
+ at code
+from grass.script import tgis_abstract_datasets as grass
+
+...
+ at endcode
+
+(C) 2008-2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+import uuid
+from temporal_extent import *
+from spatial_extent import *
+from metadata import *
+
+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"""
+	raise IOError("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")
+    
+    def get_new_instance(self, ident):
+        """Return a new instance with the type of this class"""
+        raise IOError("This method must be implemented in the subclasses")
+
+    def get_id(self):
+        return self.base.get_id()
+
+    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) or None if not present"""
+
+        start = self.relative_time.get_start_time()
+        end = self.relative_time.get_end_time()
+
+        return (start, end)
+
+    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)
+        
+    def select(self, dbif=None):
+	"""Select temporal dataset entry from database and fill up the internal structure"""
+	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)
+        
+    def is_in_db(self, dbif=None):
+	"""Check if the temporal dataset entry is in the database"""
+	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")
+
+    def insert(self, dbif=None):
+	"""Insert temporal dataset entry into database from the internal structure"""
+	self.base.insert(dbif)
+	if self.is_time_absolute():
+	    self.absolute_time.insert(dbif)
+        if self.is_time_relative():
+	    self.relative_time.insert(dbif)
+	self.spatial_extent.insert(dbif)
+	self.metadata.insert(dbif)
+
+    def update(self, dbif=None):
+	"""Update temporal dataset entry of database from the internal structure"""
+	self.base.update(dbif)
+	if self.is_time_absolute():
+	    self.absolute_time.update(dbif)
+        if self.is_time_relative():
+	    self.relative_time.update(dbif)
+	self.spatial_extent.update(dbif)
+	self.metadata.update(dbif)
+
+    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()
+        if self.is_time_relative():
+	    self.relative_time.print_self()
+	self.spatial_extent.print_self()
+	self.metadata.print_self()
+
+    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
+            print ""
+            print " +-------------------- Raster Dataset ----------------------------------------+"
+        if self.get_type() == "raster3d":
+            #                1         2         3         4         5         6         7
+            #      0123456789012345678901234567890123456789012345678901234567890123456789012345678
+            print ""
+            print " +-------------------- Raster3d Dataset --------------------------------------+"
+        if self.get_type() == "vector":
+            #                1         2         3         4         5         6         7
+            #      0123456789012345678901234567890123456789012345678901234567890123456789012345678
+            print ""
+            print " +-------------------- Vector Dataset ----------------------------------------+"
+        if self.get_type() == "strds":
+            #                1         2         3         4         5         6         7
+            #      0123456789012345678901234567890123456789012345678901234567890123456789012345678
+            print ""
+            print " +-------------------- Space Time Raster Dataset -----------------------------+"
+        if self.get_type() == "str3ds":
+            #                1         2         3         4         5         6         7
+            #      0123456789012345678901234567890123456789012345678901234567890123456789012345678
+            print ""
+            print " +-------------------- Space Time Raster3d Dataset ---------------------------+"
+        if self.get_type() == "stvds":
+            #                1         2         3         4         5         6         7
+            #      0123456789012345678901234567890123456789012345678901234567890123456789012345678
+            print ""
+            print " +-------------------- Space Time Vector Dataset -----------------------------+"
+        print " |                                                                            |"
+	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()
+        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()
+        if self.is_time_relative():
+	    self.relative_time.print_shell_info()
+	self.spatial_extent.print_shell_info()
+	self.metadata.print_shell_info()
+
+    def set_time_to_absolute(self):
+	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"
+        else:
+	    return None
+
+    def is_time_relative(self):
+	if self.base.D.has_key("temporal_type"):
+	    return self.base.get_ttype() == "relative"
+        else:
+	    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)
+        if self.is_time_relative() and map.is_time_relative():
+	    return self.relative_time.temporal_relation(map.relative_time)
+    	return None
+
+###############################################################################
+
+class abstract_map_dataset(abstract_dataset):
+    """This is the base class for all maps (raster, vector, raster3d) 
+       providing additional function to set the valid time and the spatial extent.
+    """
+      
+    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"""
+        raise IOError("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")
+        
+    def set_stds_register(self, name):
+        """Set 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")
+        
+    def set_absolute_time(self, start_time, end_time=None, timezone=None):
+        """Set the absolute time interval with start time and end time
+        
+           @start_time a datetime object specifying the start time of the map
+           @end_time a datetime object specifying the end time of the map
+           @timezone Thee timezone of the map
+        
+        """
+        if start_time != None and not isinstance(start_time, datetime) :
+            core.fatal(_("Start time must be of type datetime"))
+
+        if end_time != None and not isinstance(end_time, datetime) :
+            core.fatal(_("End time must be of type datetime"))
+
+        if start_time != None and end_time != None:
+            if start_time >= end_time:
+                core.error(_("End time must be later than start time"))
+                return False
+
+        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)
+
+        return True
+
+    def update_absolute_time(self, start_time, end_time=None, timezone=None, dbif = None):
+        """Update the absolute time
+
+           @start_time a datetime object specifying the start time of the map
+           @end_time a datetime object specifying the end time of the map
+           @timezone Thee timezone of the map
+        """
+        connect = False
+
+        if dbif == None:
+            dbif = sql_database_interface()
+            dbif.connect()
+            connect = True
+
+        self.set_absolute_time(start_time, end_time, timezone)
+        self.absolute_time.update(dbif)
+        self.base.update(dbif)
+
+        if connect == True:
+            dbif.close()
+
+    def set_relative_time(self, start_time, end_time=None):
+        """Set the relative time interval 
+        
+           @start_time A double value in days
+           @end_time A double value in days
+
+        """
+        if start_time != None and end_time != None:
+            if abs(float(start_time)) >= abs(float(end_time)):
+                core.error(_("End time must be greater than start time"))
+                return False
+
+        self.base.set_ttype("relative")
+        
+        self.relative_time.set_start_time(float(start_time))
+        if end_time != None:
+            self.relative_time.set_end_time(float(end_time))
+        else:
+            self.relative_time.set_end_time(None)
+
+        return True
+
+    def update_relative_time(self, start_time, end_time=None, dbif = None):
+        """Set the relative time interval
+
+           @interval A double value in days
+
+        """
+        connect = False
+
+        if dbif == None:
+            dbif = sql_database_interface()
+            dbif.connect()
+            connect = True
+
+        self.set_relative_time(start_time, end_time)
+        self.relative_time.update(dbif)
+        self.base.update(dbif)
+
+        if connect == True:
+            dbif.close()
+
+    def set_spatial_extent(self, north, south, east, west, top=0, bottom=0):
+        """Set the spatial extent of the map"""
+        self.spatial_extent.set_spatial_extent(north, south, east, west, top, bottom)
+        
+    def delete(self, dbif=None):
+	"""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
+        """
+
+        connect = False
+
+        if dbif == None:
+            dbif = sql_database_interface()
+            dbif.connect()
+            connect = True
+
+        if self.is_in_db(dbif):
+            
+            # First we unregister from all dependent space time datasets
+            self.unregister(dbif)
+
+            # Remove the strds register table
+            if self.get_stds_register():
+                sql = "DROP TABLE " + self.get_stds_register()
+                #print sql
+                try:
+                    dbif.cursor.execute(sql)
+                except:
+                    core.error("Unable to remove space time dataset register table " + self.get_stds_register())
+
+            core.verbose("Delete " + self.get_type() + " dataset <" + self.get_id() + "> from temporal database")
+
+            # Delete yourself from the database, trigger functions will take care of dependencies
+            self.base.delete(dbif)
+
+        self.reset(None)
+
+        if connect == True:
+            dbif.close()
+
+    def unregister(self, dbif=None):
+	""" Remove the map entry in each space time dataset in which this map is registered
+        """
+
+        core.verbose("Unregister " + self.get_type() + " dataset <" + self.get_id() + "> from space time datasets")
+        
+        connect = False
+
+        if dbif == None:
+            dbif = sql_database_interface()
+            dbif.connect()
+            connect = True
+
+        # Get all datasets in which this map is registered
+        rows = self.get_registered_datasets(dbif)
+
+        # For each stds in which the map is registered
+        if rows:
+            for row in rows:
+                # Create a space time dataset object to remove the map
+                # from its register
+                stds = self.get_new_stds_instance(row["id"])
+                stds.select(dbif)
+                stds.unregister_map(self, dbif)
+                # Take care to update the space time dataset after
+                # the map has been unregistred
+                stds.update_from_registered_maps(dbif)
+
+        if connect == True:
+            dbif.close()
+            
+    def get_registered_datasets(self, dbif=None):
+        """Return all space time dataset ids in which this map is registered as
+          sqlite3 rows with column "id" or None if this map is not registered in any
+          space time dataset.
+        """
+        connect = False
+
+        if dbif == None:
+            dbif = sql_database_interface()
+            dbif.connect()
+            connect = True
+
+        rows = None
+
+        try:
+            if self.get_stds_register() != None:
+                # Select all stds tables in which this map is registered
+                sql = "SELECT id FROM " + self.get_stds_register()
+                dbif.cursor.execute(sql)
+                rows = dbif.cursor.fetchall()
+        except:
+            core.error("Unable to select space time dataset register table " + self.get_stds_register())
+
+        if connect == True:
+            dbif.close()
+            
+        return rows
+
+###############################################################################
+
+class abstract_space_time_dataset(abstract_dataset):
+    """Abstract space time dataset class
+
+       This class represents a space time dataset. Convenient functions
+       to select, update, insert or delete objects of this type int the SQL
+       temporal database exists as well as functions to register or unregister
+       raster maps.
+
+       Parts of the temporal logic are implemented in the SQL temporal database,
+       like the computation of the temporal and spatial extent as well as the
+       collecting of metadata.
+    """
+    def __init__(self, ident):
+	self.reset(ident)
+
+    def get_new_instance(self, ident):
+        """Return a new instance with the type of this class"""
+        raise IOError("This method must be implemented in the subclasses")
+
+    def get_new_map_instance(self, ident):
+        """Return a new instance of a map dataset which is associated with the type of this class"""
+        raise IOError("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")
+
+    def set_map_register(self, name):
+        """Set the name of the map register table"""
+        raise IOError("This method must be implemented in the subclasses")
+
+    def set_initial_values(self, granularity, temporal_type, semantic_type, \
+                           title=None, description=None):
+
+        if temporal_type == "absolute":
+            self.set_time_to_absolute()
+            self.absolute_time.set_granularity(granularity)
+        elif temporal_type == "relative":
+            self.set_time_to_relative()
+            self.relative_time.set_granularity(granularity)
+        else:
+            core.fatal("Unknown temporal type \"" + temporal_type + "\"")
+
+        self.base.set_semantic_type(semantic_type)
+        self.metadata.set_title(title)
+        self.metadata.set_description(description)
+
+    def delete(self, dbif=None):
+        """Delete a space time dataset from the database"""
+        # First we need to check if maps are registered in this dataset and
+        # unregister them
+
+        core.verbose("Delete space time " + self.get_new_map_instance(ident=None).get_type() + " dataset <" + self.get_id() + "> from temporal database")
+
+        connect = False
+
+        if dbif == None:
+            dbif = sql_database_interface()
+            dbif.connect()
+            connect = True
+
+        if self.get_map_register():
+            sql = "SELECT id FROM " + self.get_map_register()
+            try:
+                dbif.cursor.execute(sql)
+                rows = dbif.cursor.fetchall()
+                # Unregister each registered map in the table
+                if rows:
+                    for row in rows:
+                        # Unregister map
+                        map = self.get_new_map_instance(row["id"])
+                        self.unregister_map(map, dbif)
+
+                # Drop remove the map register table
+                sql = "DROP TABLE " + self.get_map_register()
+                dbif.cursor.execute(sql)
+            except:
+                core.error("Unable to unregister maps from register table <" + self.get_map_register() + ">")
+                raise
+
+        # Remove the primary key, the foreign keys will be removed by trigger
+        self.base.delete(dbif)
+        self.reset(None)
+
+        if connect == True:
+            dbif.close()
+            
+    def register_map(self, map, dbif=None):
+        """Register a map in the space time dataset.
+
+            This method takes care of the registration of a map
+            in a space time dataset.
+
+            In case the map is already registered this function will break with a warning
+            and return False
+        """
+
+        connect = False
+
+        if dbif == None:
+            dbif = sql_database_interface()
+            dbif.connect()
+            connect = True
+
+        if map.is_in_db(dbif) == False:
+            core.fatal("Only maps with absolute or relative valid time can be registered")
+
+        core.verbose("Register " + map.get_type() + " map: " + map.get_id() + " in space time " + map.get_type() + " dataset <" + self.get_id() + ">")
+
+        # First select all data from the database
+        map.select(dbif)
+        map_id = map.base.get_id()
+        map_name = map.base.get_name()
+        map_mapset = map.base.get_mapset()
+        map_register_table = map.get_stds_register()
+
+        #print "Map register table", map_register_table
+
+        # Get basic info
+        stds_name = self.base.get_name()
+        stds_mapset = self.base.get_mapset()
+        stds_register_table = self.get_map_register()
+
+        #print "STDS register table", stds_register_table
+
+        if stds_mapset != map_mapset:
+            core.fatal("Only maps from the same mapset can be registered")
+
+        # Check if map is already registred
+        if stds_register_table:
+            sql = "SELECT id FROM " + stds_register_table + " WHERE id = (?)"
+            dbif.cursor.execute(sql, (map_id,))
+            row = dbif.cursor.fetchone()
+            # In case of no entry make a new one
+            if row and row[0] == map_id:
+                core.warning("Map " + map_id + "is already registered.")
+                return False
+
+        # Create tables
+        sql_path = get_sql_template_path()
+
+        # We need to create the stmap raster register table bevor we can register the map
+        if map_register_table == None:
+            # Create a unique id
+            uuid_rand = "map_" + str(uuid.uuid4()).replace("-", "")
+
+            # Read the SQL template
+            sql = open(os.path.join(sql_path, "map_stds_register_table_template.sql"), 'r').read()
+            # Create the raster, raster3d and vector tables
+            sql = sql.replace("GRASS_MAP", map.get_type())
+            sql = sql.replace("MAP_NAME", map_name + "_" + map_mapset )
+            sql = sql.replace("TABLE_NAME", uuid_rand )
+            sql = sql.replace("MAP_ID", map_id)
+            sql = sql.replace("STDS", self.get_type())
+            try:
+                dbif.cursor.executescript(sql)
+            except:
+                core.error("Unable to create the space time " + map.get_type() +\
+                " dataset register table for " + map.get_type() + " map <" + map.get_id())
+                raise
+
+            map_register_table = uuid_rand + "_" + self.get_type() + "_register"
+            # Set the stds register table name and put it into the DB
+            map.set_stds_register(map_register_table)
+            map.metadata.update(dbif)
+            
+            core.verbose("Created register table <" +  map_register_table + "> for " + map.get_type() + " map <" + map.get_id() + ">")
+
+        # We need to create the table and register it
+        if stds_register_table == None:
+            # Read the SQL template
+            sql = open(os.path.join(sql_path, "stds_map_register_table_template.sql"), 'r').read()
+            # Create the raster, raster3d and vector tables
+            sql = sql.replace("GRASS_MAP", map.get_type())
+            sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
+            sql = sql.replace("SPACETIME_ID", self.base.get_id())
+            sql = sql.replace("STDS", self.get_type())
+
+            sql_script = ""
+            #sql_script += "BEGIN TRANSACTION;\n"
+            sql_script += sql
+            #sql_script += "\n"
+            #sql_script += "END TRANSACTION;"
+            try:
+                dbif.cursor.executescript(sql_script)
+            except:
+                core.error("Unable to create the " + map.get_type() +\
+                " map register table for space time " + map.get_type() + " dataset <" + map.get_id())
+                raise
+
+            # Trigger have been disabled due to peformance issues while registration
+            ## We need raster specific trigger
+            #sql = open(os.path.join(sql_path, "stds_" + map.get_type() + "_register_trigger_template.sql"), 'r').read()
+            #sql = sql.replace("GRASS_MAP", map.get_type())
+            #sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
+            #sql = sql.replace("SPACETIME_ID", self.base.get_id())
+            #sql = sql.replace("STDS", self.get_type())
+
+            #sql_script = ""
+            #sql_script += "BEGIN TRANSACTION;\n"
+            #sql_script += sql
+            #sql_script += "\n"
+            #sql_script += "END TRANSACTION;"
+
+            #dbif.cursor.executescript(sql_script)
+
+            stds_register_table = stds_name + "_" + stds_mapset + "_" + map.get_type() + "_register"
+
+            # Set the map register table name and put it into the DB
+            self.set_map_register(stds_register_table)
+            self.metadata.update(dbif)
+
+            core.verbose("Created register table <" +  stds_register_table + "> for space time " + map.get_type() + " dataset <" + self.get_id() + ">")
+
+        # Register the stds in the map stds register table
+        # Check if the entry is already there
+        sql = "SELECT id FROM " + map_register_table + " WHERE id = ?"
+        dbif.cursor.execute(sql, (self.base.get_id(),))
+      	row = dbif.cursor.fetchone()
+
+        # In case of no entry make a new one
+        if row == None:
+            sql = "INSERT INTO " + map_register_table + " (id) " + "VALUES (?)"
+            #print sql
+            dbif.cursor.execute(sql, (self.base.get_id(),))
+
+        # Now put the raster name in the stds map register table
+        sql = "INSERT INTO " + stds_register_table + " (id) " + "VALUES (?)"
+        #print sql
+        dbif.cursor.execute(sql, (map_id,))
+
+        if connect == True:
+            dbif.close()
+            
+        return True
+
+    def unregister_map(self, map, dbif = None):
+        """Unregister a map from the space time dataset.
+
+            This method takes care of the unregistration of a map
+            from a space time dataset.
+        """
+        connect = False
+
+        if dbif == None:
+            dbif = sql_database_interface()
+            dbif.connect()
+            connect = True
+
+        if map.is_in_db(dbif) == False:
+            core.fatal("Unable to find map <" + map.get_id() + "> in temporal database")
+
+        core.info("Unregister " + map.get_type() + " map: " + map.get_id())
+
+        # First select all data from the database
+        map.select(dbif)
+        map_id = map.base.get_id()
+        map_register_table = map.get_stds_register()
+
+        # Get basic info
+        stds_register_table = self.get_map_register()
+
+        # Check if the map is registered in the space time raster dataset
+        sql = "SELECT id FROM " + map_register_table + " WHERE id = ?"
+        dbif.cursor.execute(sql, (self.base.get_id(),))
+      	row = dbif.cursor.fetchone()
+
+        # Break if the map is not registered
+        if row == None:
+            core.warning("Map " + map_id + " is not registered in space time dataset " + self.base.get_id())
+            return False
+
+        # Remove the space time raster dataset from the raster dataset register
+        if map_register_table != None:
+            sql = "DELETE FROM " + map_register_table + " WHERE id = ?"
+            dbif.cursor.execute(sql, (self.base.get_id(),))
+
+        # Remove the raster map from the space time raster dataset register
+        if stds_register_table != None:
+            sql = "DELETE FROM " + stds_register_table + " WHERE id = ?"
+            dbif.cursor.execute(sql, (map_id,))
+
+        if connect == True:
+            dbif.close()
+            
+    def update_from_registered_maps(self, dbif = None):
+        """This methods updates the spatial and temporal extent as well as
+           type specific metadata. It should always been called after maps are registered
+           or unregistered/deleted from the space time dataset.
+
+           An other solution to automate this is to use the diactivated trigger
+           in the SQL files. But this will result in a huge performance issue
+           in case many maps are registred (>1000).
+        """
+        core.info("Update metadata, spatial and temporal extent from all registered maps of <" + self.get_id() + ">")
+
+        connect = False
+
+        if dbif == None:
+            dbif = sql_database_interface()
+            dbif.connect()
+            connect = True
+
+        # Get basic info
+        stds_name = self.base.get_name()
+        stds_mapset = self.base.get_mapset()
+        sql_path = get_sql_template_path()
+
+        #We create a transaction
+        sql_script = ""
+        sql_script += "BEGIN TRANSACTION;\n"
+        
+        # Update the spatial and temporal extent from registered maps
+        # Read the SQL template
+        sql = open(os.path.join(sql_path, "update_stds_spatial_temporal_extent_template.sql"), 'r').read()
+        sql = sql.replace("GRASS_MAP", self.get_new_map_instance(None).get_type())
+        sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
+        sql = sql.replace("SPACETIME_ID", self.base.get_id())
+        sql = sql.replace("STDS", self.get_type())
+
+        sql_script += sql
+        sql_script += "\n"
+
+        # Update type specific metadata
+        sql = open(os.path.join(sql_path, "update_" + self.get_type() + "_metadata_template.sql"), 'r').read()
+        sql = sql.replace("GRASS_MAP", self.get_new_map_instance(None).get_type())
+        sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
+        sql = sql.replace("SPACETIME_ID", self.base.get_id())
+        sql = sql.replace("STDS", self.get_type())
+
+        sql_script += sql
+        sql_script += "\n"
+
+        sql_script += "END TRANSACTION;"
+
+        dbif.cursor.executescript(sql_script)
+
+        if connect == True:
+            dbif.close()

Added: grass/trunk/lib/python/temporal/base.py
===================================================================
--- grass/trunk/lib/python/temporal/base.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/base.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,477 @@
+"""!@package grass.script.tgis_base
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS base classes to be used in other
+Python temporal gis packages.
+
+This packages includes all base classes to stor basic information like id, name,
+mapset creation and modification time as well as sql serialization and deserialization
+and the sqlite3 database interface.
+
+Usage:
+
+ at code
+from grass.script import tgis_core as grass
+
+rbase = grass.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
+for details.
+
+ at author Soeren Gebbert
+"""
+
+from core import *
+
+###############################################################################
+
+class dict_sql_serializer(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 colum names and the values are the row entries
+
+	   @type must be SELECT. INSERT, UPDATE
+	   @table The name of the table to select, insert or update
+	   @where The optinal where statment
+	   @return the sql string
+	"""
+
+	sql = ""
+	args = []
+
+	# Create ordered select statement
+	if type == "SELECT":
+	    sql += 'SELECT '
+	    count = 0
+            for key in self.D.keys():
+		if count == 0:
+                    sql += ' %s ' % key
+		else:
+                    sql += ' , %s ' % key
+		count += 1
+            sql += ' FROM ' + table + ' '
+	    if where:
+	        sql += where
+
+	# Create insert statement
+	if type =="INSERT":
+	    count = 0
+	    sql += 'INSERT INTO ' + table + ' ('
+            for key in self.D.keys():
+		if count == 0:
+                    sql += ' %s ' % key
+		else:
+                    sql += ' ,%s ' % key
+		count += 1
+
+	    count = 0
+	    sql += ') VALUES ('
+            for key in self.D.keys():
+		if count == 0:
+                    sql += '?'
+		else:
+                    sql += ',?'
+		count += 1
+		args.append(self.D[key])
+	    sql += ') '
+
+	    if where:
+	        sql += where
+
+	# Create update statement
+	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:
+                        sql += ' %s = ? ' % key
+		    else:
+                        sql += ' ,%s = ? ' % key
+		    count += 1
+	            args.append(self.D[key])
+	    if where:
+	        sql += where
+
+    	return sql, tuple(args)
+
+    def deserialize(self, row):
+	"""Convert the content of the sqlite row into the internal dictionary"""
+	self.D = {}
+	for key in row.keys():
+	    self.D[key] = row[key]
+
+    def clear(self):
+	"""Remove all the content of this class"""
+	self.D = {}
+
+    def print_self(self):
+        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):
+    """This is the sql database interface to sqlite3"""
+    def __init__(self, table=None, ident=None, database=None):
+        dict_sql_serializer.__init__(self)
+
+        self.table = table # Name of the table, set in the subclass
+        if database == None:
+            self.database = get_grass_location_db_path()
+        else:
+            self.database = database
+        self.ident = ident
+
+    def get_table_name(self):
+        return self.table
+
+    def connect(self):
+        #print "Connect to",  self.database
+	self.connection = sqlite3.connect(self.database, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
+	self.connection.row_factory = sqlite3.Row
+        self.cursor = self.connection.cursor()
+
+    def close(self):
+        #print "Close connection to",  self.database
+	self.connection.commit()
+        self.cursor.close()
+
+    def get_delete_statement(self):
+	return "DELETE FROM " + self.get_table_name() + " WHERE id = \"" + str(self.ident) + "\""
+
+    def delete(self, dbif=None):
+	sql = self.get_delete_statement()
+        #print sql
+        
+        if dbif:
+            dbif.cursor.execute(sql)
+        else:
+            self.connect()
+            self.cursor.execute(sql)
+            self.close()
+
+    def get_is_in_db_statement(self):
+	return "SELECT id FROM " + self.get_table_name() + " WHERE id = \"" + str(self.ident) + "\""
+
+    def is_in_db(self, dbif=None):
+
+	sql = self.get_is_in_db_statement()
+        #print sql
+
+        if dbif:
+            dbif.cursor.execute(sql)
+            row = dbif.cursor.fetchone()
+        else:
+            self.connect()
+            self.cursor.execute(sql)
+            row = self.cursor.fetchone()
+            self.close()
+
+	# Nothing found
+	if row == None:
+	    return False
+
+	return True
+
+    def get_select_statement(self):
+	return self.serialize("SELECT", self.get_table_name(), "WHERE id = \"" + str(self.ident) + "\"")
+
+    def select(self, dbif=None):
+	sql, args = self.get_select_statement()
+	#print sql
+	#print args
+
+        if dbif:
+            if len(args) == 0:
+                dbif.cursor.execute(sql)
+            else:
+                dbif.cursor.execute(sql, args)
+            row = dbif.cursor.fetchone()
+        else:
+            self.connect()
+            if len(args) == 0:
+                self.cursor.execute(sql)
+            else:
+                self.cursor.execute(sql, args)
+            row = self.cursor.fetchone()
+            self.close()
+
+	# Nothing found
+	if row == None:
+	    return False
+
+	if len(row) > 0:
+	    self.deserialize(row)
+	else:
+	    raise IOError
+
+	return True
+
+    def get_insert_statement(self):
+	return self.serialize("INSERT", self.get_table_name())
+
+    def insert(self, dbif=None):
+	sql, args = self.get_insert_statement()
+	#print sql
+	#print args
+
+        if dbif:
+            dbif.cursor.execute(sql, args)
+        else:
+            self.connect()
+            self.cursor.execute(sql, args)
+            self.close()
+
+    def get_update_statement(self):
+	return self.serialize("UPDATE", self.get_table_name(), "WHERE id = \"" + str(self.ident) + "\"")
+
+    def update(self, dbif=None):
+	if self.ident == None:
+	    raise IOError("Missing identifer");
+
+	sql, args = self.get_update_statement()
+	#print sql
+	#print args
+
+        if dbif:
+            dbif.cursor.execute(sql, args)
+        else:
+            self.connect()
+            self.cursor.execute(sql, args)
+            self.close()
+
+###############################################################################
+
+class dataset_base(sql_database_interface):
+    """This is the base class for all maps and spacetime datasets storing basic 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)
+
+	self.set_id(ident)
+	self.set_name(name)
+	self.set_mapset(mapset)
+	self.set_creator(creator)
+	self.set_ctime(ctime)
+	self.set_mtime(mtime)
+	self.set_ttype(ttype)
+	self.set_revision(revision)
+
+    def set_id(self, ident):
+	"""Convenient method to set the unique identifier (primary key)"""
+	self.ident = ident
+	self.D["id"] = ident
+
+    def set_name(self, name):
+	"""Set the name of the map"""
+	self.D["name"] = name
+
+    def set_mapset(self, mapset):
+	"""Set the mapset of the map"""
+	self.D["mapset"] = mapset
+
+    def set_creator(self, creator):
+	"""Set the creator of the map"""
+	self.D["creator"] = creator
+
+    def set_ctime(self, ctime=None):
+	"""Set the creation time of the map, if nothing set the current time is used"""
+	if ctime == None:
+            self.D["creation_time"] = datetime.now()
+	else:
+            self.D["creation_time"] = ctime
+
+    def set_mtime(self, 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:
+            self.D["modification_time"] = mtime
+
+    def set_ttype(self, ttype):
+	"""Set the temporal type of the map: absolute or relative, if nothing set absolute time will assumed"""
+	if ttype == None or (ttype != "absolute" and ttype != "relative"):
+	    self.D["temporal_type"] = "absolute"
+        else:
+	    self.D["temporal_type"] = ttype
+
+    def set_revision(self, revision=1):
+	"""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"]
+        else:
+	    return None
+
+    def get_name(self):
+	"""Get the name of the map
+	   @return None if not found"""
+	if self.D.has_key("name"):
+	    return self.D["name"]
+        else:
+	    return None
+
+    def get_mapset(self):
+	"""Get the mapset of the map
+	   @return None if not found"""
+	if self.D.has_key("mapset"):
+	    return self.D["mapset"]
+        else:
+	    return None
+
+    def get_creator(self):
+	"""Get the creator of the map
+	   @return None if not found"""
+	if self.D.has_key("creator"):
+	    return self.D["creator"]
+        else:
+	    return None
+
+    def get_ctime(self):
+	"""Get the creation time of the map, datatype is datetime
+	   @return None if not found"""
+	if self.D.has_key("creation_time"):
+	    return self.D["creation_time"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    return None
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        #      0123456789012345678901234567890
+        print " +-------------------- Basic information -------------------------------------+"
+        print " | Id: ........................ " + str(self.get_id())
+        print " | Name: ...................... " + str(self.get_name())
+        print " | Mapset: .................... " + str(self.get_mapset())
+        print " | Creator: ................... " + str(self.get_creator())
+        print " | Creation time: ............. " + str(self.get_ctime())
+        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())
+        print "creator=" + str(self.get_creator())
+        print "creation_time=" + str(self.get_ctime())
+        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 vector_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, "vector_base", ident, name, mapset, creator, creation_time,\
+	            modification_time, temporal_type, revision)
+
+###############################################################################
+
+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)
+
+    def set_semantic_type(self, 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"]
+        else:
+	    return None
+
+###############################################################################
+
+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 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)
+

Added: grass/trunk/lib/python/temporal/core.py
===================================================================
--- grass/trunk/lib/python/temporal/core.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/core.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,216 @@
+"""!@package grass.script.tgis_core
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS core functions to be used in Python sripts.
+
+Usage:
+
+ at code
+from grass.script import tgis_core as grass
+
+grass.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
+for details.
+
+ at author Soeren Gebbert
+"""
+import os
+import sqlite3
+import grass.script.core as core
+import copy
+from datetime import datetime, date, time, timedelta
+
+###############################################################################
+
+def get_grass_location_db_path():
+    grassenv = core.gisenv()
+    dbpath = os.path.join(grassenv["GISDBASE"], grassenv["LOCATION_NAME"])
+    return os.path.join(dbpath, "grass.db")
+
+###############################################################################
+
+def get_sql_template_path():
+    base = os.getenv("GISBASE")
+    base_etc  = os.path.join(base, "etc")
+    return os.path.join(base_etc, "sql")
+
+def test_increment_datetime_by_string():
+
+    dt = datetime(2001, 9, 1, 0, 0, 0)
+    string = "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
+
+    dt1 = datetime(2003,2,18,12,5,0)
+    dt2 = increment_datetime_by_string(dt, string)
+
+    delta = dt1 -dt2
+
+    if delta.days != 0 or delta.seconds != 0:
+        core.fatal("increment computation is wrong")
+
+def increment_datetime_by_string(mydate, increment, mult = 1):
+    """Return a new datetime object incremented with the provided relative dates specified as string.
+       Additional a multiplier can be specified to multiply the increment bevor adding to the provided datetime object.
+
+       @mydate A datetime object to incremented
+       @increment A string providing increment information:
+                  The string may include comma separated values of type seconds, minutes, hours, days, weeks, months and years
+                  Example: Increment the datetime 2001-01-01 00:00:00 with "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
+                  will result in the datetime 2003-02-18 12:05:00
+        @mult A multiplier, default is 1
+    """
+
+    if increment:
+
+        seconds = 0
+        minutes = 0
+        hours = 0
+        days = 0
+        weeks = 0
+        months = 0
+        years = 0
+
+        inclist = []
+        # Split the increment string
+        incparts = increment.split(",")
+        for incpart in incparts:
+            inclist.append(incpart.strip().split(" "))
+
+        for inc in inclist:
+            if inc[1].find("seconds") >= 0:
+                seconds = mult * int(inc[0])
+            elif inc[1].find("minutes") >= 0:
+                minutes = mult * int(inc[0])
+            elif inc[1].find("hours") >= 0:
+                hours = mult * int(inc[0])
+            elif inc[1].find("days") >= 0:
+                days = mult * int(inc[0])
+            elif inc[1].find("weeks") >= 0:
+                weeks = mult * int(inc[0])
+            elif inc[1].find("months") >= 0:
+                months = mult * int(inc[0])
+            elif inc[1].find("years") >= 0:
+                years = mult * int(inc[0])
+            else:
+                core.fatal("Wrong increment format: " + increment)
+
+        return increment_datetime(mydate, years, months, weeks, days, hours, minutes, seconds)
+    
+    return mydate
+
+###############################################################################
+
+def increment_datetime(mydate, years=0, months=0, weeks=0, days=0, hours=0, minutes=0, seconds=0):
+    """Return a new datetime object incremented with the provided relative dates and times"""
+
+    tdelta_seconds = timedelta(seconds=seconds)
+    tdelta_minutes = timedelta(minutes=minutes)
+    tdelta_hours = timedelta(hours=hours)
+    tdelta_days = timedelta(days=days)
+    tdelta_weeks = timedelta(weeks=weeks)
+    tdelta_months = timedelta(0)
+    tdelta_years = timedelta(0)
+
+    if months > 0:
+        # Compute the actual number of days in the month to add as timedelta
+        year = mydate.year
+        month = mydate.month
+
+        all_months = int(months + month)
+
+        years_to_add = int(all_months/12)
+        residual_months = all_months%12
+
+        # Make a deep copy of the datetime object
+        dt1 = copy.copy(mydate)
+
+        # Make sure the montha starts with a 1
+        if residual_months == 0:
+            residual_months = 1
+
+        dt1 = dt1.replace(year = year + years_to_add, month = residual_months)
+        tdelta_months = dt1 - mydate
+
+    if years > 0:
+        # Make a deep copy of the datetime object
+        dt1 = copy.copy(mydate)
+        # Compute the number of days
+        dt1 = dt1.replace(year=mydate.year + int(years))
+        tdelta_years = dt1 - mydate
+
+    return mydate + tdelta_seconds + tdelta_minutes + tdelta_hours + \
+                    tdelta_days + tdelta_weeks + tdelta_months + tdelta_years
+
+###############################################################################
+
+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"""
+    
+    database = get_grass_location_db_path()
+
+    # Check if it already exists
+    if os.path.exists(database):
+        return False
+
+    # 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()
+
+    # 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")
+  
+    # 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")
+    str3ds_tables_sql = stds_tables_template_sql.replace("STDS", "str3ds")
+
+    # Check for completion
+    sqlite3.complete_statement(raster_tables_sql)
+    sqlite3.complete_statement(vector_tables_sql)
+    sqlite3.complete_statement(raster3d_tables_sql)
+    sqlite3.complete_statement(raster_metadata_sql)
+    sqlite3.complete_statement(vector_metadata_sql)
+    sqlite3.complete_statement(raster3d_metadata_sql)
+    sqlite3.complete_statement(strds_tables_sql)
+    sqlite3.complete_statement(stvds_tables_sql)
+    sqlite3.complete_statement(str3ds_tables_sql)
+    sqlite3.complete_statement(strds_metadata_sql)
+    sqlite3.complete_statement(stvds_metadata_sql)
+    sqlite3.complete_statement(str3ds_metadata_sql)
+
+    # Connect to database
+    connection = sqlite3.connect(database)
+    cursor = connection.cursor()
+
+    # Execute the SQL statements
+    # 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)
+
+    connection.commit()
+    cursor.close()

Added: grass/trunk/lib/python/temporal/metadata.py
===================================================================
--- grass/trunk/lib/python/temporal/metadata.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/metadata.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,640 @@
+"""!@package grass.script.tgis_metadata
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related metadata functions to be used in Python scripts and tgis packages.
+
+Usage:
+
+ at code
+from grass.script import tgis_metadata as grass
+
+meta = grass.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
+for details.
+
+ at author Soeren Gebbert
+"""
+from base import *
+
+###############################################################################
+
+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)
+
+	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
+
+    def set_datatype(self, datatype):
+	"""Set the datatype"""
+	self.D["datatype"] = datatype
+
+    def set_cols(self, cols):
+	"""Set the number of cols"""
+	self.D["cols"] = cols
+
+    def set_rows(self, rows):
+	"""Set the number of rows"""
+	self.D["rows"] = rows
+
+    def set_number_of_cells(self, number_of_cells):
+	"""Set the number of cells"""
+	self.D["number_of_cells"] = number_of_cells
+
+    def set_nsres(self, nsres):
+	"""Set the north-south resolution"""
+	self.D["nsres"] = nsres
+
+    def set_ewres(self, ewres):
+	"""Set the east-west resolution"""
+	self.D["ewres"] = ewres
+
+    def set_min(self, min):
+	"""Set the minimum raster value"""
+	self.D["min"] = min
+
+    def set_max(self, max):
+	"""Set the maximum raster value"""
+	self.D["max"] = max
+
+    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    return None
+
+    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 " | North-South resolution:..... " + str(self.get_nsres())
+        print " | East-west resolution:....... " + str(self.get_ewres())
+        print " | Minimum value:.............. " + str(self.get_min())
+        print " | Maximum value:.............. " + str(self.get_max())
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        print "datatype=" + str(self.get_datatype())
+        print "cols=" + str(self.get_cols())
+        print "rows=" + str(self.get_rows())
+        print "number_of_cells=" + str(self.get_number_of_cells())
+        print "nsres=" + str(self.get_nsres())
+        print "ewres=" + str(self.get_ewres())
+        print "min=" + str(self.get_min())
+        print "max=" + str(self.get_max())
+
+###############################################################################
+
+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)
+
+	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
+
+    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"]
+        else:
+	    return None
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        print " +-------------------- Metadata information ----------------------------------+"
+        #      0123456789012345678901234567890
+        print " | STRDS register table ....... " + str(self.get_strds_register())
+        raster_metadata_base.print_info(self)
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        raster_metadata_base.print_shell_info(self)
+
+###############################################################################
+
+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)
+
+	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
+
+    def set_depths(self, depths):
+	"""Set the number of depths"""
+	self.D["depths"] = depths
+
+    def set_tbres(self, tbres):
+	"""Set the top-bottom resolution"""
+	self.D["tbres"] = tbres
+
+    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    return None
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        print " +-------------------- Metadata information ----------------------------------+"
+        #      0123456789012345678901234567890
+        print " | STR3DS register table ...... " + str(self.get_str3ds_register())
+        raster_metadata_base.print_info(self)
+        #      0123456789012345678901234567890
+        print " | Number of depths:........... " + str(self.get_depths())
+        print " | Top-Bottom resolution:...... " + str(self.get_tbres())
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        raster_metadata_base.print_shell_info(self)
+        print "depths=" + str(self.get_depths())
+        print "tbres=" + str(self.get_tbres())
+        
+###############################################################################
+
+class vector_metadata(sql_database_interface):
+    """This is the vector metadata class"""
+    def __init__(self, ident=None, stvds_register=None):
+
+	sql_database_interface.__init__(self, "vector_metadata", ident)
+
+	self.set_id(ident)
+	self.set_stvds_register(stvds_register)
+
+    def set_id(self, 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
+
+    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"]
+        else:
+	    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"]
+        else:
+	    return None
+
+
+    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())
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        print "stvds_register=" + str(self.get_stvds_register())
+
+###############################################################################
+
+class stds_metadata_base(sql_database_interface):
+    """This is the space time dataset metadata base class for strds, stvds and str3ds datasets
+       setting/getting the id, the title and the description
+    """
+    def __init__(self, table=None, ident=None, title=None, description=None):
+
+	sql_database_interface.__init__(self, table, ident)
+
+	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
+
+    def set_title(self, title):
+	"""Set the title"""
+	self.D["title"] = title
+
+    def set_description(self, 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"]
+        else:
+	    return None
+
+    def get_title(self):
+	"""Get the title 
+	   @return None if not found"""
+	if self.D.has_key("title"):
+	    return self.D["title"]
+        else:
+	    return None
+
+    def get_description(self):
+	"""Get description 
+	   @return None if not found"""
+	if self.D.has_key("description"):
+	    return self.D["description"]
+        else:
+	    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"]
+        else:
+	    return None
+
+    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 " | Title:"
+        print " | " + str(self.get_title())
+        print " | Description:"
+        print " | " + str(self.get_description())
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        print "number_of_maps=" + str(self.get_number_of_maps())
+
+###############################################################################
+    
+class stds_raster_metadata_base(stds_metadata_base):
+    """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 of voxel maps are added. Therefor only some set- an many get-functions 
+       are available.
+    """
+    def __init__(self, table=None, ident=None, title=None, description=None):
+
+	stds_metadata_base.__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
+        self.D["min_min"] = None
+        self.D["max_min"] = None
+        self.D["nsres_min"] = None
+        self.D["nsres_max"] = None
+        self.D["ewres_min"] = None
+        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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    return None
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        stds_metadata_base.print_info(self)
+        #      0123456789012345678901234567890
+        print " | North-South resolution min:. " + str(self.get_nsres_min())
+        print " | North-South resolution max:. " + str(self.get_nsres_max())
+        print " | East-west resolution min:... " + str(self.get_ewres_min())
+        print " | East-west resolution max:... " + str(self.get_ewres_max())
+        print " | Minimum value min:.......... " + str(self.get_min_min())
+        print " | Minimum value max:.......... " + str(self.get_min_max())
+        print " | Maximum value min:.......... " + str(self.get_max_min())
+        print " | Maximum value max:.......... " + str(self.get_max_max())
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        stds_metadata_base.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())
+        print "ewres_max=" + str(self.get_ewres_max())
+        print "min_min=" + str(self.get_min_min())
+        print "min_max=" + str(self.get_min_max())
+        print "max_min=" + str(self.get_max_min())
+        print "max_max=" + str(self.get_max_max())
+
+
+###############################################################################
+
+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):
+
+	stds_raster_metadata_base.__init__(self, "strds_metadata", ident, title, description)
+
+	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
+
+    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"]
+        else:
+	    return None
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        print " +-------------------- Metadata information ----------------------------------+"
+        #      0123456789012345678901234567890
+        print " | Raster register table:...... " + str(self.get_raster_register())
+        stds_raster_metadata_base.print_info(self)
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        stds_raster_metadata_base.print_shell_info(self)
+
+###############################################################################
+
+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)
+
+	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
+
+    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    return None
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        print " +-------------------- Metadata information ----------------------------------+"
+        #      0123456789012345678901234567890
+        print " | Raster3d register table:.... " + str(self.get_raster3d_register())
+        stds_raster_metadata_base.print_info(self)
+        #      0123456789012345678901234567890
+        print " | Top-bottom resolution min:.. " + str(self.get_ewres_min())
+        print " | Top-bottom resolution max:.. " + str(self.get_ewres_max())
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        stds_raster_metadata_base.print_shell_info(self)
+        print "tbres_min=" + str(self.get_tbres_min())
+        print "tbres_max=" + str(self.get_tbres_max())
+
+###############################################################################
+
+class stvds_metadata(stds_metadata_base):
+    """This is the raster metadata class"""
+    def __init__(self, ident=None, vector_register=None,  title=None, description=None):
+
+	stds_metadata_base.__init__(self, "stvds_metadata", ident, title, description)
+
+	self.set_vector_register(vector_register)
+
+    def set_vector_register(self, vector_register):
+	"""Set the vector map register table name"""
+	self.D["vector_register"] = vector_register
+
+    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"]
+        else:
+	    return None
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        print " +-------------------- Metadata information ----------------------------------+"
+        #      0123456789012345678901234567890
+        print " | Vector register table:...... " + str(self.get_vector_register())
+        stds_metadata_base.print_info(self)
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        stds_metadata_base.print_shell_info(self)

Added: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,687 @@
+"""!@package grass.script.tgis_space_time_dataset
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in Python scripts.
+
+Usage:
+
+ at code
+from grass.script import tgis_space_time_dataset as grass
+
+strds = grass.space_time_raster_dataset("soils_1950_2010")
+
+...
+ at endcode
+
+(C) 2008-2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+import getpass
+import grass.script.raster as raster
+import grass.script.vector as vector
+import grass.script.raster3d as raster3d
+from abstract_datasets import *
+
+
+###############################################################################
+
+class raster_dataset(abstract_map_dataset):
+    """Raster dataset class
+
+       This class provides functions to select, update, insert or delete raster
+       map informations and valid time stamps into the SQL temporal database.
+    """
+    def __init__(self, ident):
+	self.reset(ident)
+
+    def get_type(self):
+        return "raster"
+
+    def get_new_instance(self, ident):
+        """Return a new instance with the type of this class"""
+        return raster_dataset(ident)
+
+    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 space_time_raster_dataset(ident)
+
+    def get_stds_register(self):
+        """Return the space time dataset register table name in which stds are listed in which this map is registered"""
+        return self.metadata.get_strds_register()
+
+    def set_stds_register(self, name):
+        """Set the space time dataset register table name in which stds are listed in which this map is registered"""
+        self.metadata.set_strds_register(name)
+
+    def reset(self, ident):
+	"""Reset the internal structure and set the identifier"""
+	self.ident = ident
+
+	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)
+
+    def load(self):
+        """Load all info from an existing raster map into the internal structure"""
+
+        # Get the data from an existing raster map
+        kvp = raster.raster_info(self.ident)
+
+        # Fill base information
+
+        self.base.set_name(self.ident.split("@")[0])
+        self.base.set_mapset(self.ident.split("@")[1])
+        self.base.set_creator(str(getpass.getuser()))
+
+        # Fill spatial extent
+
+        self.set_spatial_extent(north=kvp["north"], south=kvp["south"], \
+                                east=kvp["east"],   west=kvp["west"])
+
+        # Fill metadata
+
+        self.metadata.set_nsres(kvp["nsres"])
+        self.metadata.set_ewres(kvp["ewres"])
+        self.metadata.set_datatype(kvp["datatype"])
+        self.metadata.set_min(kvp["min"])
+        self.metadata.set_max(kvp["max"])
+
+        rows = int((kvp["north"] - kvp["south"])/kvp["nsres"] + 0.5)
+        cols = int((kvp["east"] - kvp["west"])/kvp["ewres"] + 0.5)
+
+        ncells = cols * rows
+
+        self.metadata.set_cols(cols)
+        self.metadata.set_rows(rows)
+        self.metadata.set_number_of_cells(ncells)
+
+###############################################################################
+
+class raster3d_dataset(abstract_map_dataset):
+    """Raster3d dataset class
+
+       This class provides functions to select, update, insert or delete raster3d
+       map informations and valid time stamps into the SQL temporal database.
+    """
+    def __init__(self, ident):
+	self.reset(ident)
+
+    def get_type(self):
+        return "raster3d"
+
+    def get_new_instance(self, ident):
+        """Return a new instance with the type of this class"""
+        return raster3d_dataset(ident)
+
+    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 space_time_raster3d_dataset(ident)
+
+    def get_stds_register(self):
+        """Return the space time dataset register table name in which stds are listed in which this map is registered"""
+        return self.metadata.get_str3ds_register()
+
+    def set_stds_register(self, name):
+        """Set the space time dataset register table name in which stds are listed in which this map is registered"""
+        self.metadata.set_str3ds_register(name)
+
+    def reset(self, ident):
+	"""Reset the internal structure and set the identifier"""
+	self.ident = ident
+
+	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)
+
+    def load(self):
+        """Load all info from an existing raster3d map into the internal structure"""
+
+        # Get the data from an existing raster map
+        kvp = raster3d.raster3d_info(self.ident)
+
+        # Fill base information
+
+        self.base.set_name(self.ident.split("@")[0])
+        self.base.set_mapset(self.ident.split("@")[1])
+        self.base.set_creator(str(getpass.getuser()))
+
+        # Fill spatial extent
+
+        self.set_spatial_extent(north=kvp["north"], south=kvp["south"], \
+                                east=kvp["east"],   west=kvp["west"],\
+                                top=kvp["top"], bottom=kvp["bottom"])
+
+        # Fill metadata
+
+        self.metadata.set_nsres(kvp["nsres"])
+        self.metadata.set_ewres(kvp["ewres"])
+        self.metadata.set_tbres(kvp["tbres"])
+        self.metadata.set_datatype(kvp["datatype"])
+        self.metadata.set_min(kvp["min"])
+        self.metadata.set_max(kvp["max"])
+
+        rows = int((kvp["north"] - kvp["south"])/kvp["nsres"] + 0.5)
+        cols = int((kvp["east"] - kvp["west"])/kvp["ewres"] + 0.5)
+        depths = int((kvp["top"] - kvp["bottom"])/kvp["tbres"] + 0.5)
+
+        ncells = cols * rows * depths
+
+        self.metadata.set_cols(cols)
+        self.metadata.set_rows(rows)
+        self.metadata.set_depths(depths)
+        self.metadata.set_number_of_cells(ncells)
+
+###############################################################################
+
+class vector_dataset(abstract_map_dataset):
+    """Vector dataset class
+
+       This class provides functions to select, update, insert or delete vector
+       map informations and valid time stamps into the SQL temporal database.
+    """
+    def __init__(self, ident):
+	self.reset(ident)
+
+    def get_type(self):
+        return "vector"
+
+    def get_new_instance(self, ident):
+        """Return a new instance with the type of this class"""
+        return vector_dataset(ident)
+
+    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 space_time_vector_dataset(ident)
+
+    def get_stds_register(self):
+        """Return the space time dataset register table name in which stds are listed in which this map is registered"""
+        return self.metadata.get_stvds_register()
+
+    def set_stds_register(self, name):
+        """Set the space time dataset register table name in which stds are listed in which this map is registered"""
+        self.metadata.set_stvds_register(name)
+
+    def reset(self, ident):
+	"""Reset the internal structure and set the identifier"""
+	self.ident = ident
+
+	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)
+
+    def load(self):
+        """Load all info from an existing vector map into the internal structure"""
+
+        # Get the data from an existing raster map
+        kvp = vector.vector_info(self.ident)
+
+        # Fill base information
+
+        self.base.set_name(self.ident.split("@")[0])
+        self.base.set_mapset(self.ident.split("@")[1])
+        self.base.set_creator(str(getpass.getuser()))
+
+        # Fill spatial extent
+
+        self.set_spatial_extent(north=kvp["north"], south=kvp["south"], \
+                                east=kvp["east"],   west=kvp["west"],\
+                                top=kvp["top"], bottom=kvp["bottom"])
+
+        # Fill metadata .. no metadata yet
+
+###############################################################################
+
+class space_time_raster_dataset(abstract_space_time_dataset):
+    """Space time raster dataset class
+    """
+    def __init__(self, ident):
+        abstract_space_time_dataset.__init__(self, ident)
+
+    def get_type(self):
+        return "strds"
+
+    def get_new_instance(self, ident):
+        """Return a new instance with the type of this class"""
+        return space_time_raster_dataset(ident)
+
+    def get_new_map_instance(self, ident):
+        """Return a new instance of a map dataset which is associated with the type of this class"""
+        return raster_dataset(ident)
+
+    def get_map_register(self):
+        """Return the name of the map register table"""
+        return self.metadata.get_raster_register()
+
+    def set_map_register(self, name):
+        """Set the name of the map register table"""
+        self.metadata.set_raster_register(name)
+
+    def reset(self, ident):
+
+	"""Reset the internal structure and set the identifier"""
+	self.ident = ident
+
+	self.base = strds_base(ident=ident)
+
+        if ident != None:
+            self.base.set_name(self.ident.split("@")[0])
+            self.base.set_mapset(self.ident.split("@")[1])
+        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)
+
+###############################################################################
+
+class space_time_raster3d_dataset(abstract_space_time_dataset):
+    """Space time raster3d dataset class
+    """
+
+    def __init__(self, ident):
+        abstract_space_time_dataset.__init__(self, ident)
+
+    def get_type(self):
+        return "str3ds"
+
+    def get_new_instance(self, ident):
+        """Return a new instance with the type of this class"""
+        return space_time_raster3d_dataset(ident)
+
+    def get_new_map_instance(self, ident):
+        """Return a new instance of a map dataset which is associated with the type of this class"""
+        return raster3d_dataset(ident)
+
+    def get_map_register(self):
+        """Return the name of the map register table"""
+        return self.metadata.get_raster3d_register()
+
+    def set_map_register(self, name):
+        """Set the name of the map register table"""
+        self.metadata.set_raster3d_register(name)
+
+    def reset(self, ident):
+
+	"""Reset the internal structure and set the identifier"""
+	self.ident = ident
+
+	self.base = str3ds_base(ident=ident)
+
+        if ident != None:
+            self.base.set_name(self.ident.split("@")[0])
+            self.base.set_mapset(self.ident.split("@")[1])
+        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)
+
+###############################################################################
+
+class space_time_vector_dataset(abstract_space_time_dataset):
+    """Space time vector dataset class
+    """
+
+    def __init__(self, ident):
+        abstract_space_time_dataset.__init__(self, ident)
+
+    def get_type(self):
+        return "stvds"
+
+    def get_new_instance(self, ident):
+        """Return a new instance with the type of this class"""
+        return space_time_vector_dataset(ident)
+
+    def get_new_map_instance(self, ident):
+        """Return a new instance of a map dataset which is associated with the type of this class"""
+        return vector_dataset(ident)
+
+    def get_map_register(self):
+        """Return the name of the map register table"""
+        return self.metadata.get_vector_register()
+
+    def set_map_register(self, name):
+        """Set the name of the map register table"""
+        self.metadata.set_vector_register(name)
+
+    def reset(self, ident):
+
+	"""Reset the internal structure and set the identifier"""
+	self.ident = ident
+
+	self.base = stvds_base(ident=ident)
+
+        if ident != None:
+            self.base.set_name(self.ident.split("@")[0])
+            self.base.set_mapset(self.ident.split("@")[1])
+        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)
+
+###############################################################################
+
+def register_maps_in_space_time_dataset(type, name, maps, start=None, increment=None, dbif = None):
+    """Use this method to register maps in space time datasets. This function is generic and
+       can handle raster, vector and raster3d maps as well as there space time datasets.
+
+       Additionally a start time string and an increment string can be specified
+       to assign a time interval automatically to the maps.
+
+       It takes care of the correct update of the space time datasets from all
+       registered maps.
+
+       @type The type of the maps raster, raster3d or vector
+       @name The name of the space time dataset
+       @maps A comma separated list of map names
+       @start The start date and time of the first raster map, in case the map has no date (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
+       @increment Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
+    """
+
+    # We may need the mapset
+    mapset =  core.gisenv()["MAPSET"]
+
+    # Check if the dataset name contains the mapset as well
+    if name.find("@") < 0:
+        id = name + "@" + mapset
+    else:
+        id = name
+
+    if type == "raster":
+        sp = space_time_raster_dataset(id)
+    if type == "raster3d":
+        sp = space_time_raster3d_dataset(id)
+    if type == "vector":
+        sp = space_time_vector_dataset(id)
+
+    connect = False
+
+    if dbif == None:
+        dbif = sql_database_interface()
+        dbif.connect()
+        connect = True
+
+    # Read content from temporal database
+    sp.select(dbif)
+
+    if sp.is_in_db(dbif) == False:
+        core.fatal("Space time " + sp.get_new_map_instance(None).get_type() + " dataset <" + name + "> not found")
+
+    if maps.find(",") == -1:
+        maplist = (maps,)
+    else:
+        maplist = tuple(maps.split(","))
+
+    count = 0
+    for mapname in maplist:
+        mapname = mapname.strip()
+        # Check if the map name contains the mapset as well
+        if mapname.find("@") < 0:
+            mapid = mapname + "@" + mapset
+        else:
+            mapid = mapname
+        # Get a new instance of the space time dataset map type
+        map = sp.get_new_map_instance(mapid)
+
+        # In case the map is already registered print a message and continue to the next map
+
+        # Put the map into the database
+        if map.is_in_db(dbif) == False:
+            # Break in case no valid time is provided
+            if start == "" or start == None:
+                core.fatal("Unable to register " + map.get_type() + " map <" + map.get_id() + ">. The map has no valid time and the start time is not set.")
+            # Load the data from the grass file database
+            map.load()
+
+            if sp.get_temporal_type() == "absolute":
+                map.set_time_to_absolute()
+            else:
+                map.set_time_to_relative()
+            #  Put it into the temporal database
+            map.insert(dbif)
+        else:
+            map.select(dbif)
+            if map.get_temporal_type() != sp.get_temporal_type():
+                core.fatal("Unable to register " + map.get_type() + " map <" + map.get_id() + ">. The temporal types are different.")
+
+        # Set the valid time
+        if start:
+            assign_valid_time_to_map(ttype=sp.get_temporal_type(), map=map, start=start, end=None, increment=increment, mult=count, dbif=dbif)
+
+        # Finally Register map in the space time dataset
+        sp.register_map(map, dbif)
+        count += 1
+
+    # Update the space time tables
+    sp.update_from_registered_maps(dbif)
+
+    if connect == True:
+        dbif.close()
+        
+###############################################################################
+
+def unregister_maps_from_space_time_datasets(type, name, maps, dbif = None):
+    """Unregister maps from a single space time dataset or, in case no dataset name is provided,
+       unregister from all datasets within the maps are registered.
+
+       @type The type of the maps raster, vector or raster3d
+       @name Name of an existing space time raster dataset. If no name is provided the raster map(s) are unregistered from all space time datasets in which they are registered.
+       @maps Name(s) of existing map(s) to unregister
+    """
+    mapset =  core.gisenv()["MAPSET"]
+
+    if dbif == None:
+        dbif = sql_database_interface()
+        dbif.connect()
+        connect = True
+
+    # In case a space time dataset is specified
+    if name:
+        # Check if the dataset name contains the mapset as well
+        if name.find("@") < 0:
+            id = name + "@" + mapset
+        else:
+            id = name
+
+        if type == "raster":
+            sp = space_time_raster_dataset(id)
+        if type == "raster3d":
+            sp = space_time_raster3d_dataset(id)
+        if type == "vector":
+            sp = space_time_vector_dataset(id)
+
+        if sp.is_in_db(dbif) == False:
+            core.fatal("Space time " + sp.get_new_map_instance(None).get_type() + " dataset <" + name + "> not found")
+
+    # Build the list of maps
+    if maps.find(",") == -1:
+        maplist = (maps,)
+    else:
+        maplist = tuple(maps.split(","))
+
+    for mapname in maplist:
+        mapname = mapname.strip()
+        # Check if the map name contains the mapset as well
+        if mapname.find("@") < 0:
+            mapid = mapname + "@" + mapset
+        else:
+            mapid = mapname
+            
+        # Create a new instance with the map type
+        if type == "raster":
+            map = raster_dataset(mapid)
+        if type == "raster3d":
+            map = raster3d_dataset(mapid)
+        if type == "vector":
+            map = vector_dataset(mapid)
+
+        # Unregister map if in database
+        if map.is_in_db(dbif) == True:
+            if name:
+                sp.select(dbif)
+                sp.unregister_map(map, dbif)
+            else:
+                map.select(dbif)
+                map.unregister(dbif)
+
+    if name:
+        sp.update_from_registered_maps(dbif)
+
+    if connect == True:
+        dbif.close()
+
+###############################################################################
+
+def assign_valid_time_to_maps(type, maps, ttype, start, end=None, increment=None, dbif = None):
+    """Use this method to assign valid time (absolute or relative) to raster,
+       raster3d and vector datasets.
+
+       It takes care of the correct update of the space time datasets from all
+       registered maps.
+
+       Valid end time and increment are mutual exclusive.
+
+       @type The type of the maps raster, raster3d or vector
+       @maps A comma separated list of map names
+       @start The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
+       @end The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
+       @increment Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
+    """
+
+    if end and increment:
+        core.fatal("Valid end time and increment are mutual exclusive")
+
+    # List of space time datasets to be updated
+    splist = {}
+
+    # We may need the mapset
+    mapset =  core.gisenv()["MAPSET"]
+
+    if dbif == None:
+        dbif = sql_database_interface()
+        dbif.connect()
+        connect = True
+
+    if maps.find(",") == -1:
+        maplist = (maps,)
+    else:
+        maplist = tuple(maps.split(","))
+
+    count = 0
+    for mapname in maplist:
+        mapname = mapname.strip()
+        # Check if the map name contains the mapset as well
+        if mapname.find("@") < 0:
+            mapid = mapname + "@" + mapset
+        else:
+            mapid = mapname
+            
+        if type == "raster":
+            map = raster_dataset(mapid)
+        if type == "raster3d":
+            map = raster3d_dataset(mapid)
+        if type == "vector":
+            map = vector_dataset(mapid)
+
+        if map.is_in_db(dbif) == False:
+            # Load the data from the grass file database
+            map.load()
+            if ttype == "absolute":
+                map.set_time_to_absolute()
+            else:
+                map.set_time_to_relative()
+            #  Put it into the temporal database
+            map.insert(dbif)
+        else:
+            map.select(dbif)
+            sprows = map.get_registered_datasets(dbif)
+            # Make an entry in the dataset list, using a dict make sure that
+            # each dataset is listed only once
+            if sprows != None:
+                for dataset in sprows:
+                    splist[dataset["id"]] = True
+            
+        # Set the valid time
+        assign_valid_time_to_map(ttype=ttype, map=map, start=start, end=end, increment=increment, mult=count, dbif=dbif)
+
+        count += 1
+
+    # Update all the space time datasets in which registered maps are changed there valid time
+    for name in splist.keys():
+        sp = map.get_new_stds_instance(name)
+        sp.select(dbif)
+        sp.update_from_registered_maps(dbif)
+
+    if connect == True:
+        dbif.close()
+
+
+###############################################################################
+
+def assign_valid_time_to_map(ttype, map, start, end, increment=None, mult=1, dbif = None):
+    """Assign the valid time to a map dataset
+
+       @ttype The temporal type which should be assigned and which the time format is of
+       @map A map dataset object derived from abstract_map_dataset
+       @start The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
+       @end The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
+       @increment Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
+       @multi A multiplier for the increment
+    """
+    
+    connect = False
+
+    if dbif == None:
+        dbif = sql_database_interface()
+        dbif.connect()
+        connect = True
+
+    if ttype == "absolute":
+        # Create the start time object
+        if start.find(":") > 0:
+            time_format = "%Y-%m-%d %H:%M:%S"
+        else:
+            time_format = "%Y-%m-%d"
+
+        start_time = datetime.strptime(start, time_format)
+        if end:
+            end_time = datetime.strptime(end, time_format)
+        else:
+            end_time = None
+
+        # Add the increment
+        if increment:
+            start_time = increment_datetime_by_string(start_time, increment, mult)
+            end_time = increment_datetime_by_string(start_time, increment, 1)
+
+        core.verbose(_("Set absolute valid time for map <%s> to %s - %s") % (map.get_id(), str(start_time), str(end_time)))
+        map.update_absolute_time(start_time, end_time, None, dbif)
+    else:
+        start_time = float(start)
+
+        if end:
+            end_time = float(end)
+        else:
+            end_time = None
+
+        if increment:
+            start_time = start_time + mult * float(increment)
+            end_time = start_time + float(increment)
+
+        core.verbose(_("Set relative valid time for map <%s> to %f - %s") % (map.get_id(), start_time,  str(end_time)))
+        map.update_relative_time(start_time, end_time, dbif)
+
+    if connect == True:
+        dbif.close()

Added: grass/trunk/lib/python/temporal/spatial_extent.py
===================================================================
--- grass/trunk/lib/python/temporal/spatial_extent.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/spatial_extent.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,290 @@
+"""!@package grass.script.tgis_spatial_extent
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related spatial extent functions to be used in Python scripts and tgis packages.
+
+Usage:
+
+ at code
+from grass.script import tgis_spatial_extent as grass
+
+extent = grass.raster_spatial_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
+for details.
+
+ at author Soeren Gebbert
+"""
+from base import *
+
+class spatial_extent(sql_database_interface):
+    """This is the spatial extent base class for all maps and spacetime 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)
+        self.set_id(ident)
+        self.set_spatial_extent(north, south, east, west, top, bottom)
+	self.set_projection(proj)
+        
+    def overlap_2d(self, extent):
+        """Return True if the 2d extents overlap. Code is lend from wind_overlap.c in lib/gis"""  
+        
+        if self.get_projection() != extent.get_projection():
+            core.error("Projections are different. Unable to compute overlap_2d for spatial extents")
+        
+        N = extent.get_north()
+        S = extent.get_south()
+        E = extent.get_east()
+        W = extent.get_west()
+        
+        if(self.get_north() <= S):
+            return False
+        
+        if(self.get_south() >= N):
+            return False
+        
+        # Adjust the east and west in case of LL projection
+        if self.get_proj() == "LL":
+            while E < self.get_west():
+                E += 360.0
+                W += 360.0
+
+            while W > self.get_east():
+                E -= 360.0
+                W -= 360.0
+            
+        if self.get_east() <= W:
+            return False
+        
+        if self.get_west() >= E:
+            return False
+        
+        return True
+
+    def overlap(self, extent):
+        """Return True if the extents overlap."""  
+        
+        if self.overlap_2d(extent) == False:
+            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 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)        
+        
+    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"):
+            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)
+
+    def set_id(self, 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
+
+    def set_south(self, sourth):
+	"""Set the sourthern edge of the map"""
+	self.D["south"] = sourth
+
+    def set_west(self, west):
+	"""Set the western edge of the map"""
+	self.D["west"] = west
+
+    def set_east(self, east):
+	"""Set the eastern edge of the map"""
+	self.D["east"] = east
+
+    def set_top(self, top):
+	"""Set the top edge of the map"""
+	self.D["top"] = top
+
+    def set_bottom(self, bottom):
+	"""Set the bottom edge of the map"""
+	self.D["bottom"] = bottom
+
+    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"]
+        else:
+	    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"""
+
+        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
+       
+    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
+    
+    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())
+                
+    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    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"]
+        else:
+	    return None
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        #      0123456789012345678901234567890
+        print " +-------------------- Spatial extent ----------------------------------------+"
+        print " | North:...................... " + str(self.get_north())
+        print " | South:...................... " + str(self.get_south())
+        print " | East:.. .................... " + str(self.get_east())
+        print " | West:....................... " + str(self.get_west())
+        print " | Top:........................ " + str(self.get_top())
+        print " | Bottom:..................... " + str(self.get_bottom())
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        print "north=" + str(self.get_north())
+        print "south=" + str(self.get_south())
+        print "east=" + str(self.get_east())
+        print "west=" + str(self.get_west())
+        print "top=" + str(self.get_top())
+        print "bottom=" + str(self.get_bottom())
+
+
+###############################################################################
+
+class raster_spatial_extent(spatial_extent):
+    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)
+
+class raster3d_spatial_extent(spatial_extent):
+    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)
+
+class vector_spatial_extent(spatial_extent):
+    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)
+
+class strds_spatial_extent(spatial_extent):
+    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)
+
+class str3ds_spatial_extent(spatial_extent):
+    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)
+
+class stvds_spatial_extent(spatial_extent):
+    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)

Added: grass/trunk/lib/python/temporal/temporal_extent.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_extent.py	                        (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_extent.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,438 @@
+"""!@package grass.script.tgis_temporal_extent
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related temporal extent functions to be used in Python scripts and tgis packages.
+
+Usage:
+
+ at code
+from grass.script import tgis_temporal_extent as grass
+
+grass.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
+for details.
+
+ at author Soeren Gebbert
+"""
+from base import *
+
+###############################################################################
+
+class abstract_temporal_extent(sql_database_interface):
+    """This is the abstract time base class for relative and absolute time objects"""
+    def __init__(self, table=None, ident=None, start_time=None, end_time=None):
+
+	sql_database_interface.__init__(self, table, ident)
+
+	self.set_id(ident)
+	self.set_start_time(start_time)
+	self.set_end_time(end_time)
+
+    def starts(self, map):
+	"""Return True if this absolute time object starts at the start of the provided absolute time object and finishes within it
+	   A  |-----|
+	   B  |---------|
+	"""
+	if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] < map.D["end_time"]:
+	    return True
+        else:
+	    return False
+
+    def started(self, map):
+	"""Return True if this absolute time object is started at the start of the provided absolute time object
+	   A  |---------|
+	   B  |-----|
+	"""
+	if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] > map.D["end_time"]:
+	    return True
+        else:
+	    return False
+
+    def finishes(self, map):
+	"""Return True if this absolute time object finishes at the end and within of the provided absolute time object
+	   A      |-----|
+	   B  |---------|
+	"""
+	if self.D["end_time"] == map.D["end_time"] and  self.D["start_time"] > map.D["start_time"] :
+	    return True
+        else:
+	    return False
+
+    def finished(self, map):
+	"""Return True if this absolute time object finished at the end of the provided absolute time object
+	   A  |---------|
+	   B      |-----|
+	"""
+	if self.D["end_time"] == map.D["end_time"] and  self.D["start_time"] < map.D["start_time"] :
+	    return True
+        else:
+	    return False
+
+    def after(self, map):
+	"""Return True if this absolute time object is temporal located after the provided absolute time object
+	   A             |---------|
+	   B  |---------|
+	"""
+	if self.D["start_time"] > map.D["end_time"]:
+	    return True
+        else:
+	    return False
+
+    def before(self, map):
+	"""Return True if this absolute time object is temporal located bevor the provided absolute time object
+	   A  |---------|
+	   B             |---------|
+	"""
+	if self.D["end_time"] < map.D["start_time"]:
+	    return True
+        else:
+	    return False
+
+    def adjacent(self, map):
+	"""Return True if this absolute time object is a meeting neighbour the provided absolute time object
+	   A            |---------|
+	   B  |---------|
+	   A  |---------|
+	   B            |---------|
+	"""
+	if (self.D["start_time"] == map.D["end_time"]) or (self.D["end_time"] == map.D["start_time"]):
+	    return True
+        else:
+	    return False
+
+    def follows(self, map):
+	"""Return True if this absolute time object is temporal follows the provided absolute time object
+	   A            |---------|
+	   B  |---------|
+	"""
+	if self.D["start_time"] == map.D["end_time"]:
+	    return True
+        else:
+	    return False
+
+    def precedes(self, map):
+	"""Return True if this absolute time object is temporal precedes the provided absolute time object
+	   A  |---------|
+	   B            |---------|
+	"""
+	if self.D["end_time"] == map.D["start_time"]:
+	    return True
+        else:
+	    return False
+
+    def during(self, map):
+	"""Return True if this absolute time object is temporal located during the provided absolute time object
+	   A   |-------|
+	   B  |---------|
+	"""
+	if self.D["start_time"] > map.D["start_time"] and self.D["end_time"] < map.D["end_time"]:
+	    return True
+        else:
+	    return False
+
+    def contains(self, map):
+	"""Return True if this absolute time object is temporal located during the provided absolute time object
+	   A  |---------|
+	   B   |-------|
+	"""
+	if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] > map.D["end_time"]:
+	    return True
+        else:
+	    return False
+
+    def equivalent(self, map):
+	"""Return True if this absolute time object is temporal located equivalent the provided absolute time object
+	   A  |---------|
+	   B  |---------|
+	"""
+	if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] == map.D["end_time"]:
+	    return True
+        else:
+	    return False
+
+    def overlaps(self, map):
+	"""Return True if this absolute time object is temporal overlaps the provided absolute time object
+           A  |---------|
+	   B    |---------|
+	"""
+	if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] < map.D["end_time"] and\
+	   self.D["end_time"] > map.D["start_time"]:
+	    return True
+        else:
+	    return False
+
+    def overlapped(self, map):
+	"""Return True if this absolute time object is temporal overlaped by the provided absolute time object
+	   A    |---------|
+           B  |---------|
+	"""
+	if self.D["start_time"] > map.D["start_time"] and self.D["end_time"] > map.D["end_time"] and\
+	   self.D["start_time"] < map.D["end_time"]:
+	    return True
+        else:
+	    return False
+
+    def temporal_relation(self, map):
+	"""Returns the temporal relation between absolute time temporal objects
+	   Temporal relationsships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
+	"""
+	if self.equivalent(map):
+	    return "equivalent"
+	if self.during(map):
+	    return "during"
+	if self.contains(map):
+	    return "contains"
+	if self.overlaps(map):
+	    return "overlaps"
+	if self.overlapped(map):
+	    return "overlapped"
+	if self.after(map):
+	    return "after"
+	if self.before(map):
+	    return "before"
+	if self.starts(map):
+	    return "starts"
+	if self.finishes(map):
+	    return "finishes"
+	if self.started(map):
+	    return "started"
+	if self.finished(map):
+	    return "finished"
+	if self.equivalent(map):
+	    return "equivalent"
+	if self.follows(map):
+	    return "follows"
+	if self.precedes(map):
+	    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
+
+    def set_start_time(self, start_time):
+	"""Set the valid start time of the map"""
+	self.D["start_time"] = start_time
+
+    def set_end_time(self, end_time):
+	"""Set the valid end time of the map"""
+	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"]
+        else:
+	    return None
+
+    def get_start_time(self):
+	"""Get the valid start time of the map
+	   @return None if not found"""
+	if self.D.has_key("start_time"):
+	    return self.D["start_time"]
+        else:
+	    return None
+
+    def get_end_time(self):
+	"""Get the valid end time of the map
+	   @return None if not found"""
+	if self.D.has_key("end_time"):
+	    return self.D["end_time"]
+        else:
+	    return None
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        #      0123456789012345678901234567890
+        print " | Start time:................. " + str(self.get_start_time())
+        print " | End time:................... " + str(self.get_end_time())
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        print "start_time=" + str(self.get_start_time())
+        print "end_time=" + str(self.get_end_time())
+
+###############################################################################
+
+class absolute_temporal_extent(abstract_temporal_extent):
+    """This is the absolute time class for all maps and spacetime datasets
+
+       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):
+
+	abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
+
+	self.set_timezone(timezone)
+
+    def set_timezone(self, timezone):
+	"""Set the timezone of the map, integer from 1 - 24"""
+	self.D["timezone"] = timezone
+
+    def get_timezone(self):
+	"""Get the timezone of the map
+	   @return None if not found"""
+	if self.D.has_key("timezone"):
+	    return self.D["timezone"]
+        else:
+	    return None
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        #      0123456789012345678901234567890
+        print " +-------------------- Absolute time -----------------------------------------+"
+        abstract_temporal_extent.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)
+        print "timezone=" + str(self.get_timezone())
+
+###############################################################################
+
+class raster_absolute_time(absolute_temporal_extent):
+    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)
+
+class raster3d_absolute_time(absolute_temporal_extent):
+    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)
+
+class vector_absolute_time(absolute_temporal_extent):
+    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)
+
+###############################################################################
+
+class stds_absolute_time(absolute_temporal_extent):
+    def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
+        absolute_temporal_extent.__init__(self, table, ident, start_time, end_time, timezone)
+
+	self.set_granularity(granularity)
+
+    def set_granularity(self, granularity):
+	"""Set the granularity of the space time dataset"""
+	self.D["granularity"] = granularity
+
+    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"]
+        else:
+	    return None
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        absolute_temporal_extent.print_info(self)
+        #      0123456789012345678901234567890
+        print " | Granularity:................ " + str(self.get_granularity())
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        absolute_temporal_extent.print_shell_info(self)
+        print "granularity=" + str(self.get_granularity())
+
+###############################################################################
+
+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 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 relative_temporal_extent(abstract_temporal_extent):
+    """This is the relative time class for all maps and spacetime datasets
+
+       start_time and end_time must be of type datetime
+    """
+    def __init__(self, table=None, ident=None, start_time=None, end_time=None):
+
+	abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
+
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        #      0123456789012345678901234567890
+        print " +-------------------- Reltive time ------------------------------------------+"
+        abstract_temporal_extent.print_info(self)
+
+
+###############################################################################
+
+class raster_relative_time(relative_temporal_extent):
+    def __init__(self, ident=None, start_time=None, end_time=None):
+        relative_temporal_extent.__init__(self, "raster_relative_time", ident, start_time, end_time)
+
+class raster3d_relative_time(relative_temporal_extent):
+    def __init__(self, ident=None, start_time=None, end_time=None):
+        relative_temporal_extent.__init__(self, "raster3d_relative_time", ident, start_time, end_time)
+
+class vector_relative_time(relative_temporal_extent):
+    def __init__(self, ident=None, start_time=None, end_time=None):
+        relative_temporal_extent.__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):
+        relative_temporal_extent.__init__(self, table, ident, start_time, end_time)
+
+	self.set_granularity(granularity)
+
+    def set_granularity(self, granularity):
+	"""Set the granularity of the space time dataset"""
+	self.D["granularity"] = granularity
+
+    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"]
+        else:
+	    return None
+
+    def print_info(self):
+        """Print information about this class in human readable style"""
+        relative_temporal_extent.print_info(self)
+        #      0123456789012345678901234567890
+        print " | Granularity:................ " + str(self.get_granularity())
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        relative_temporal_extent.print_shell_info(self)
+        print "granularity=" + str(self.get_granularity())
+
+###############################################################################
+
+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 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)
+

Deleted: grass/trunk/lib/python/tgis_abstract_datasets.py
===================================================================
--- grass/trunk/lib/python/tgis_abstract_datasets.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_abstract_datasets.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,758 +0,0 @@
-"""!@package grass.script.tgis_abstract_datasets
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related functions to be used in temporal GIS Python library package.
-
-Usage:
-
- at code
-from grass.script import tgis_abstract_datasets as grass
-
-...
- at endcode
-
-(C) 2008-2011 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Soeren Gebbert
-"""
-import uuid
-from tgis_temporal_extent import *
-from tgis_spatial_extent import *
-from tgis_metadata import *
-
-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"""
-	raise IOError("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")
-    
-    def get_new_instance(self, ident):
-        """Return a new instance with the type of this class"""
-        raise IOError("This method must be implemented in the subclasses")
-
-    def get_id(self):
-        return self.base.get_id()
-
-    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) or None if not present"""
-
-        start = self.relative_time.get_start_time()
-        end = self.relative_time.get_end_time()
-
-        return (start, end)
-
-    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)
-        
-    def select(self, dbif=None):
-	"""Select temporal dataset entry from database and fill up the internal structure"""
-	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)
-        
-    def is_in_db(self, dbif=None):
-	"""Check if the temporal dataset entry is in the database"""
-	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")
-
-    def insert(self, dbif=None):
-	"""Insert temporal dataset entry into database from the internal structure"""
-	self.base.insert(dbif)
-	if self.is_time_absolute():
-	    self.absolute_time.insert(dbif)
-        if self.is_time_relative():
-	    self.relative_time.insert(dbif)
-	self.spatial_extent.insert(dbif)
-	self.metadata.insert(dbif)
-
-    def update(self, dbif=None):
-	"""Update temporal dataset entry of database from the internal structure"""
-	self.base.update(dbif)
-	if self.is_time_absolute():
-	    self.absolute_time.update(dbif)
-        if self.is_time_relative():
-	    self.relative_time.update(dbif)
-	self.spatial_extent.update(dbif)
-	self.metadata.update(dbif)
-
-    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()
-        if self.is_time_relative():
-	    self.relative_time.print_self()
-	self.spatial_extent.print_self()
-	self.metadata.print_self()
-
-    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
-            print ""
-            print " +-------------------- Raster Dataset ----------------------------------------+"
-        if self.get_type() == "raster3d":
-            #                1         2         3         4         5         6         7
-            #      0123456789012345678901234567890123456789012345678901234567890123456789012345678
-            print ""
-            print " +-------------------- Raster3d Dataset --------------------------------------+"
-        if self.get_type() == "vector":
-            #                1         2         3         4         5         6         7
-            #      0123456789012345678901234567890123456789012345678901234567890123456789012345678
-            print ""
-            print " +-------------------- Vector Dataset ----------------------------------------+"
-        if self.get_type() == "strds":
-            #                1         2         3         4         5         6         7
-            #      0123456789012345678901234567890123456789012345678901234567890123456789012345678
-            print ""
-            print " +-------------------- Space Time Raster Dataset -----------------------------+"
-        if self.get_type() == "str3ds":
-            #                1         2         3         4         5         6         7
-            #      0123456789012345678901234567890123456789012345678901234567890123456789012345678
-            print ""
-            print " +-------------------- Space Time Raster3d Dataset ---------------------------+"
-        if self.get_type() == "stvds":
-            #                1         2         3         4         5         6         7
-            #      0123456789012345678901234567890123456789012345678901234567890123456789012345678
-            print ""
-            print " +-------------------- Space Time Vector Dataset -----------------------------+"
-        print " |                                                                            |"
-	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()
-        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()
-        if self.is_time_relative():
-	    self.relative_time.print_shell_info()
-	self.spatial_extent.print_shell_info()
-	self.metadata.print_shell_info()
-
-    def set_time_to_absolute(self):
-	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"
-        else:
-	    return None
-
-    def is_time_relative(self):
-	if self.base.D.has_key("temporal_type"):
-	    return self.base.get_ttype() == "relative"
-        else:
-	    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)
-        if self.is_time_relative() and map.is_time_relative():
-	    return self.relative_time.temporal_relation(map.relative_time)
-    	return None
-
-###############################################################################
-
-class abstract_map_dataset(abstract_dataset):
-    """This is the base class for all maps (raster, vector, raster3d) 
-       providing additional function to set the valid time and the spatial extent.
-    """
-      
-    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"""
-        raise IOError("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")
-        
-    def set_stds_register(self, name):
-        """Set 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")
-        
-    def set_absolute_time(self, start_time, end_time=None, timezone=None):
-        """Set the absolute time interval with start time and end time
-        
-           @start_time a datetime object specifying the start time of the map
-           @end_time a datetime object specifying the end time of the map
-           @timezone Thee timezone of the map
-        
-        """
-        if start_time != None and not isinstance(start_time, datetime) :
-            core.fatal(_("Start time must be of type datetime"))
-
-        if end_time != None and not isinstance(end_time, datetime) :
-            core.fatal(_("End time must be of type datetime"))
-
-        if start_time != None and end_time != None:
-            if start_time >= end_time:
-                core.error(_("End time must be later than start time"))
-                return False
-
-        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)
-
-        return True
-
-    def update_absolute_time(self, start_time, end_time=None, timezone=None, dbif = None):
-        """Update the absolute time
-
-           @start_time a datetime object specifying the start time of the map
-           @end_time a datetime object specifying the end time of the map
-           @timezone Thee timezone of the map
-        """
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        self.set_absolute_time(start_time, end_time, timezone)
-        self.absolute_time.update(dbif)
-        self.base.update(dbif)
-
-        if connect == True:
-            dbif.close()
-
-    def set_relative_time(self, start_time, end_time=None):
-        """Set the relative time interval 
-        
-           @start_time A double value in days
-           @end_time A double value in days
-
-        """
-        if start_time != None and end_time != None:
-            if abs(float(start_time)) >= abs(float(end_time)):
-                core.error(_("End time must be greater than start time"))
-                return False
-
-        self.base.set_ttype("relative")
-        
-        self.relative_time.set_start_time(float(start_time))
-        if end_time != None:
-            self.relative_time.set_end_time(float(end_time))
-        else:
-            self.relative_time.set_end_time(None)
-
-        return True
-
-    def update_relative_time(self, start_time, end_time=None, dbif = None):
-        """Set the relative time interval
-
-           @interval A double value in days
-
-        """
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        self.set_relative_time(start_time, end_time)
-        self.relative_time.update(dbif)
-        self.base.update(dbif)
-
-        if connect == True:
-            dbif.close()
-
-    def set_spatial_extent(self, north, south, east, west, top=0, bottom=0):
-        """Set the spatial extent of the map"""
-        self.spatial_extent.set_spatial_extent(north, south, east, west, top, bottom)
-        
-    def delete(self, dbif=None):
-	"""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
-        """
-
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        if self.is_in_db(dbif):
-            
-            # First we unregister from all dependent space time datasets
-            self.unregister(dbif)
-
-            # Remove the strds register table
-            if self.get_stds_register():
-                sql = "DROP TABLE " + self.get_stds_register()
-                #print sql
-                try:
-                    dbif.cursor.execute(sql)
-                except:
-                    core.error("Unable to remove space time dataset register table " + self.get_stds_register())
-
-            core.verbose("Delete " + self.get_type() + " dataset <" + self.get_id() + "> from temporal database")
-
-            # Delete yourself from the database, trigger functions will take care of dependencies
-            self.base.delete(dbif)
-
-        self.reset(None)
-
-        if connect == True:
-            dbif.close()
-
-    def unregister(self, dbif=None):
-	""" Remove the map entry in each space time dataset in which this map is registered
-        """
-
-        core.verbose("Unregister " + self.get_type() + " dataset <" + self.get_id() + "> from space time datasets")
-        
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        # Get all datasets in which this map is registered
-        rows = self.get_registered_datasets(dbif)
-
-        # For each stds in which the map is registered
-        if rows:
-            for row in rows:
-                # Create a space time dataset object to remove the map
-                # from its register
-                stds = self.get_new_stds_instance(row["id"])
-                stds.select(dbif)
-                stds.unregister_map(self, dbif)
-                # Take care to update the space time dataset after
-                # the map has been unregistred
-                stds.update_from_registered_maps(dbif)
-
-        if connect == True:
-            dbif.close()
-            
-    def get_registered_datasets(self, dbif=None):
-        """Return all space time dataset ids in which this map is registered as
-          sqlite3 rows with column "id" or None if this map is not registered in any
-          space time dataset.
-        """
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        rows = None
-
-        try:
-            if self.get_stds_register() != None:
-                # Select all stds tables in which this map is registered
-                sql = "SELECT id FROM " + self.get_stds_register()
-                dbif.cursor.execute(sql)
-                rows = dbif.cursor.fetchall()
-        except:
-            core.error("Unable to select space time dataset register table " + self.get_stds_register())
-
-        if connect == True:
-            dbif.close()
-            
-        return rows
-
-###############################################################################
-
-class abstract_space_time_dataset(abstract_dataset):
-    """Abstract space time dataset class
-
-       This class represents a space time dataset. Convenient functions
-       to select, update, insert or delete objects of this type int the SQL
-       temporal database exists as well as functions to register or unregister
-       raster maps.
-
-       Parts of the temporal logic are implemented in the SQL temporal database,
-       like the computation of the temporal and spatial extent as well as the
-       collecting of metadata.
-    """
-    def __init__(self, ident):
-	self.reset(ident)
-
-    def get_new_instance(self, ident):
-        """Return a new instance with the type of this class"""
-        raise IOError("This method must be implemented in the subclasses")
-
-    def get_new_map_instance(self, ident):
-        """Return a new instance of a map dataset which is associated with the type of this class"""
-        raise IOError("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")
-
-    def set_map_register(self, name):
-        """Set the name of the map register table"""
-        raise IOError("This method must be implemented in the subclasses")
-
-    def set_initial_values(self, granularity, temporal_type, semantic_type, \
-                           title=None, description=None):
-
-        if temporal_type == "absolute":
-            self.set_time_to_absolute()
-            self.absolute_time.set_granularity(granularity)
-        elif temporal_type == "relative":
-            self.set_time_to_relative()
-            self.relative_time.set_granularity(granularity)
-        else:
-            core.fatal("Unknown temporal type \"" + temporal_type + "\"")
-
-        self.base.set_semantic_type(semantic_type)
-        self.metadata.set_title(title)
-        self.metadata.set_description(description)
-
-    def delete(self, dbif=None):
-        """Delete a space time dataset from the database"""
-        # First we need to check if maps are registered in this dataset and
-        # unregister them
-
-        core.verbose("Delete space time " + self.get_new_map_instance(ident=None).get_type() + " dataset <" + self.get_id() + "> from temporal database")
-
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        if self.get_map_register():
-            sql = "SELECT id FROM " + self.get_map_register()
-            try:
-                dbif.cursor.execute(sql)
-                rows = dbif.cursor.fetchall()
-                # Unregister each registered map in the table
-                if rows:
-                    for row in rows:
-                        # Unregister map
-                        map = self.get_new_map_instance(row["id"])
-                        self.unregister_map(map, dbif)
-
-                # Drop remove the map register table
-                sql = "DROP TABLE " + self.get_map_register()
-                dbif.cursor.execute(sql)
-            except:
-                core.error("Unable to unregister maps from register table <" + self.get_map_register() + ">")
-                raise
-
-        # Remove the primary key, the foreign keys will be removed by trigger
-        self.base.delete(dbif)
-        self.reset(None)
-
-        if connect == True:
-            dbif.close()
-            
-    def register_map(self, map, dbif=None):
-        """Register a map in the space time dataset.
-
-            This method takes care of the registration of a map
-            in a space time dataset.
-
-            In case the map is already registered this function will break with a warning
-            and return False
-        """
-
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        if map.is_in_db(dbif) == False:
-            core.fatal("Only maps with absolute or relative valid time can be registered")
-
-        core.verbose("Register " + map.get_type() + " map: " + map.get_id() + " in space time " + map.get_type() + " dataset <" + self.get_id() + ">")
-
-        # First select all data from the database
-        map.select(dbif)
-        map_id = map.base.get_id()
-        map_name = map.base.get_name()
-        map_mapset = map.base.get_mapset()
-        map_register_table = map.get_stds_register()
-
-        #print "Map register table", map_register_table
-
-        # Get basic info
-        stds_name = self.base.get_name()
-        stds_mapset = self.base.get_mapset()
-        stds_register_table = self.get_map_register()
-
-        #print "STDS register table", stds_register_table
-
-        if stds_mapset != map_mapset:
-            core.fatal("Only maps from the same mapset can be registered")
-
-        # Check if map is already registred
-        if stds_register_table:
-            sql = "SELECT id FROM " + stds_register_table + " WHERE id = (?)"
-            dbif.cursor.execute(sql, (map_id,))
-            row = dbif.cursor.fetchone()
-            # In case of no entry make a new one
-            if row and row[0] == map_id:
-                core.warning("Map " + map_id + "is already registered.")
-                return False
-
-        # Create tables
-        sql_path = get_sql_template_path()
-
-        # We need to create the stmap raster register table bevor we can register the map
-        if map_register_table == None:
-            # Create a unique id
-            uuid_rand = "map_" + str(uuid.uuid4()).replace("-", "")
-
-            # Read the SQL template
-            sql = open(os.path.join(sql_path, "map_stds_register_table_template.sql"), 'r').read()
-            # Create the raster, raster3d and vector tables
-            sql = sql.replace("GRASS_MAP", map.get_type())
-            sql = sql.replace("MAP_NAME", map_name + "_" + map_mapset )
-            sql = sql.replace("TABLE_NAME", uuid_rand )
-            sql = sql.replace("MAP_ID", map_id)
-            sql = sql.replace("STDS", self.get_type())
-            try:
-                dbif.cursor.executescript(sql)
-            except:
-                core.error("Unable to create the space time " + map.get_type() +\
-                " dataset register table for " + map.get_type() + " map <" + map.get_id())
-                raise
-
-            map_register_table = uuid_rand + "_" + self.get_type() + "_register"
-            # Set the stds register table name and put it into the DB
-            map.set_stds_register(map_register_table)
-            map.metadata.update(dbif)
-            
-            core.verbose("Created register table <" +  map_register_table + "> for " + map.get_type() + " map <" + map.get_id() + ">")
-
-        # We need to create the table and register it
-        if stds_register_table == None:
-            # Read the SQL template
-            sql = open(os.path.join(sql_path, "stds_map_register_table_template.sql"), 'r').read()
-            # Create the raster, raster3d and vector tables
-            sql = sql.replace("GRASS_MAP", map.get_type())
-            sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
-            sql = sql.replace("SPACETIME_ID", self.base.get_id())
-            sql = sql.replace("STDS", self.get_type())
-
-            sql_script = ""
-            #sql_script += "BEGIN TRANSACTION;\n"
-            sql_script += sql
-            #sql_script += "\n"
-            #sql_script += "END TRANSACTION;"
-            try:
-                dbif.cursor.executescript(sql_script)
-            except:
-                core.error("Unable to create the " + map.get_type() +\
-                " map register table for space time " + map.get_type() + " dataset <" + map.get_id())
-                raise
-
-            # Trigger have been disabled due to peformance issues while registration
-            ## We need raster specific trigger
-            #sql = open(os.path.join(sql_path, "stds_" + map.get_type() + "_register_trigger_template.sql"), 'r').read()
-            #sql = sql.replace("GRASS_MAP", map.get_type())
-            #sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
-            #sql = sql.replace("SPACETIME_ID", self.base.get_id())
-            #sql = sql.replace("STDS", self.get_type())
-
-            #sql_script = ""
-            #sql_script += "BEGIN TRANSACTION;\n"
-            #sql_script += sql
-            #sql_script += "\n"
-            #sql_script += "END TRANSACTION;"
-
-            #dbif.cursor.executescript(sql_script)
-
-            stds_register_table = stds_name + "_" + stds_mapset + "_" + map.get_type() + "_register"
-
-            # Set the map register table name and put it into the DB
-            self.set_map_register(stds_register_table)
-            self.metadata.update(dbif)
-
-            core.verbose("Created register table <" +  stds_register_table + "> for space time " + map.get_type() + " dataset <" + self.get_id() + ">")
-
-        # Register the stds in the map stds register table
-        # Check if the entry is already there
-        sql = "SELECT id FROM " + map_register_table + " WHERE id = ?"
-        dbif.cursor.execute(sql, (self.base.get_id(),))
-      	row = dbif.cursor.fetchone()
-
-        # In case of no entry make a new one
-        if row == None:
-            sql = "INSERT INTO " + map_register_table + " (id) " + "VALUES (?)"
-            #print sql
-            dbif.cursor.execute(sql, (self.base.get_id(),))
-
-        # Now put the raster name in the stds map register table
-        sql = "INSERT INTO " + stds_register_table + " (id) " + "VALUES (?)"
-        #print sql
-        dbif.cursor.execute(sql, (map_id,))
-
-        if connect == True:
-            dbif.close()
-            
-        return True
-
-    def unregister_map(self, map, dbif = None):
-        """Unregister a map from the space time dataset.
-
-            This method takes care of the unregistration of a map
-            from a space time dataset.
-        """
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        if map.is_in_db(dbif) == False:
-            core.fatal("Unable to find map <" + map.get_id() + "> in temporal database")
-
-        core.info("Unregister " + map.get_type() + " map: " + map.get_id())
-
-        # First select all data from the database
-        map.select(dbif)
-        map_id = map.base.get_id()
-        map_register_table = map.get_stds_register()
-
-        # Get basic info
-        stds_register_table = self.get_map_register()
-
-        # Check if the map is registered in the space time raster dataset
-        sql = "SELECT id FROM " + map_register_table + " WHERE id = ?"
-        dbif.cursor.execute(sql, (self.base.get_id(),))
-      	row = dbif.cursor.fetchone()
-
-        # Break if the map is not registered
-        if row == None:
-            core.warning("Map " + map_id + " is not registered in space time dataset " + self.base.get_id())
-            return False
-
-        # Remove the space time raster dataset from the raster dataset register
-        if map_register_table != None:
-            sql = "DELETE FROM " + map_register_table + " WHERE id = ?"
-            dbif.cursor.execute(sql, (self.base.get_id(),))
-
-        # Remove the raster map from the space time raster dataset register
-        if stds_register_table != None:
-            sql = "DELETE FROM " + stds_register_table + " WHERE id = ?"
-            dbif.cursor.execute(sql, (map_id,))
-
-        if connect == True:
-            dbif.close()
-            
-    def update_from_registered_maps(self, dbif = None):
-        """This methods updates the spatial and temporal extent as well as
-           type specific metadata. It should always been called after maps are registered
-           or unregistered/deleted from the space time dataset.
-
-           An other solution to automate this is to use the diactivated trigger
-           in the SQL files. But this will result in a huge performance issue
-           in case many maps are registred (>1000).
-        """
-        core.info("Update metadata, spatial and temporal extent from all registered maps of <" + self.get_id() + ">")
-
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        # Get basic info
-        stds_name = self.base.get_name()
-        stds_mapset = self.base.get_mapset()
-        sql_path = get_sql_template_path()
-
-        #We create a transaction
-        sql_script = ""
-        sql_script += "BEGIN TRANSACTION;\n"
-        
-        # Update the spatial and temporal extent from registered maps
-        # Read the SQL template
-        sql = open(os.path.join(sql_path, "update_stds_spatial_temporal_extent_template.sql"), 'r').read()
-        sql = sql.replace("GRASS_MAP", self.get_new_map_instance(None).get_type())
-        sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
-        sql = sql.replace("SPACETIME_ID", self.base.get_id())
-        sql = sql.replace("STDS", self.get_type())
-
-        sql_script += sql
-        sql_script += "\n"
-
-        # Update type specific metadata
-        sql = open(os.path.join(sql_path, "update_" + self.get_type() + "_metadata_template.sql"), 'r').read()
-        sql = sql.replace("GRASS_MAP", self.get_new_map_instance(None).get_type())
-        sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
-        sql = sql.replace("SPACETIME_ID", self.base.get_id())
-        sql = sql.replace("STDS", self.get_type())
-
-        sql_script += sql
-        sql_script += "\n"
-
-        sql_script += "END TRANSACTION;"
-
-        dbif.cursor.executescript(sql_script)
-
-        if connect == True:
-            dbif.close()

Deleted: grass/trunk/lib/python/tgis_base.py
===================================================================
--- grass/trunk/lib/python/tgis_base.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_base.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,477 +0,0 @@
-"""!@package grass.script.tgis_base
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS base classes to be used in other
-Python temporal gis packages.
-
-This packages includes all base classes to stor basic information like id, name,
-mapset creation and modification time as well as sql serialization and deserialization
-and the sqlite3 database interface.
-
-Usage:
-
- at code
-from grass.script import tgis_core as grass
-
-rbase = grass.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
-for details.
-
- at author Soeren Gebbert
-"""
-
-from tgis_core import *
-
-###############################################################################
-
-class dict_sql_serializer(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 colum names and the values are the row entries
-
-	   @type must be SELECT. INSERT, UPDATE
-	   @table The name of the table to select, insert or update
-	   @where The optinal where statment
-	   @return the sql string
-	"""
-
-	sql = ""
-	args = []
-
-	# Create ordered select statement
-	if type == "SELECT":
-	    sql += 'SELECT '
-	    count = 0
-            for key in self.D.keys():
-		if count == 0:
-                    sql += ' %s ' % key
-		else:
-                    sql += ' , %s ' % key
-		count += 1
-            sql += ' FROM ' + table + ' '
-	    if where:
-	        sql += where
-
-	# Create insert statement
-	if type =="INSERT":
-	    count = 0
-	    sql += 'INSERT INTO ' + table + ' ('
-            for key in self.D.keys():
-		if count == 0:
-                    sql += ' %s ' % key
-		else:
-                    sql += ' ,%s ' % key
-		count += 1
-
-	    count = 0
-	    sql += ') VALUES ('
-            for key in self.D.keys():
-		if count == 0:
-                    sql += '?'
-		else:
-                    sql += ',?'
-		count += 1
-		args.append(self.D[key])
-	    sql += ') '
-
-	    if where:
-	        sql += where
-
-	# Create update statement
-	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:
-                        sql += ' %s = ? ' % key
-		    else:
-                        sql += ' ,%s = ? ' % key
-		    count += 1
-	            args.append(self.D[key])
-	    if where:
-	        sql += where
-
-    	return sql, tuple(args)
-
-    def deserialize(self, row):
-	"""Convert the content of the sqlite row into the internal dictionary"""
-	self.D = {}
-	for key in row.keys():
-	    self.D[key] = row[key]
-
-    def clear(self):
-	"""Remove all the content of this class"""
-	self.D = {}
-
-    def print_self(self):
-        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):
-    """This is the sql database interface to sqlite3"""
-    def __init__(self, table=None, ident=None, database=None):
-        dict_sql_serializer.__init__(self)
-
-        self.table = table # Name of the table, set in the subclass
-        if database == None:
-            self.database = get_grass_location_db_path()
-        else:
-            self.database = database
-        self.ident = ident
-
-    def get_table_name(self):
-        return self.table
-
-    def connect(self):
-        #print "Connect to",  self.database
-	self.connection = sqlite3.connect(self.database, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
-	self.connection.row_factory = sqlite3.Row
-        self.cursor = self.connection.cursor()
-
-    def close(self):
-        #print "Close connection to",  self.database
-	self.connection.commit()
-        self.cursor.close()
-
-    def get_delete_statement(self):
-	return "DELETE FROM " + self.get_table_name() + " WHERE id = \"" + str(self.ident) + "\""
-
-    def delete(self, dbif=None):
-	sql = self.get_delete_statement()
-        #print sql
-        
-        if dbif:
-            dbif.cursor.execute(sql)
-        else:
-            self.connect()
-            self.cursor.execute(sql)
-            self.close()
-
-    def get_is_in_db_statement(self):
-	return "SELECT id FROM " + self.get_table_name() + " WHERE id = \"" + str(self.ident) + "\""
-
-    def is_in_db(self, dbif=None):
-
-	sql = self.get_is_in_db_statement()
-        #print sql
-
-        if dbif:
-            dbif.cursor.execute(sql)
-            row = dbif.cursor.fetchone()
-        else:
-            self.connect()
-            self.cursor.execute(sql)
-            row = self.cursor.fetchone()
-            self.close()
-
-	# Nothing found
-	if row == None:
-	    return False
-
-	return True
-
-    def get_select_statement(self):
-	return self.serialize("SELECT", self.get_table_name(), "WHERE id = \"" + str(self.ident) + "\"")
-
-    def select(self, dbif=None):
-	sql, args = self.get_select_statement()
-	#print sql
-	#print args
-
-        if dbif:
-            if len(args) == 0:
-                dbif.cursor.execute(sql)
-            else:
-                dbif.cursor.execute(sql, args)
-            row = dbif.cursor.fetchone()
-        else:
-            self.connect()
-            if len(args) == 0:
-                self.cursor.execute(sql)
-            else:
-                self.cursor.execute(sql, args)
-            row = self.cursor.fetchone()
-            self.close()
-
-	# Nothing found
-	if row == None:
-	    return False
-
-	if len(row) > 0:
-	    self.deserialize(row)
-	else:
-	    raise IOError
-
-	return True
-
-    def get_insert_statement(self):
-	return self.serialize("INSERT", self.get_table_name())
-
-    def insert(self, dbif=None):
-	sql, args = self.get_insert_statement()
-	#print sql
-	#print args
-
-        if dbif:
-            dbif.cursor.execute(sql, args)
-        else:
-            self.connect()
-            self.cursor.execute(sql, args)
-            self.close()
-
-    def get_update_statement(self):
-	return self.serialize("UPDATE", self.get_table_name(), "WHERE id = \"" + str(self.ident) + "\"")
-
-    def update(self, dbif=None):
-	if self.ident == None:
-	    raise IOError("Missing identifer");
-
-	sql, args = self.get_update_statement()
-	#print sql
-	#print args
-
-        if dbif:
-            dbif.cursor.execute(sql, args)
-        else:
-            self.connect()
-            self.cursor.execute(sql, args)
-            self.close()
-
-###############################################################################
-
-class dataset_base(sql_database_interface):
-    """This is the base class for all maps and spacetime datasets storing basic 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)
-
-	self.set_id(ident)
-	self.set_name(name)
-	self.set_mapset(mapset)
-	self.set_creator(creator)
-	self.set_ctime(ctime)
-	self.set_mtime(mtime)
-	self.set_ttype(ttype)
-	self.set_revision(revision)
-
-    def set_id(self, ident):
-	"""Convenient method to set the unique identifier (primary key)"""
-	self.ident = ident
-	self.D["id"] = ident
-
-    def set_name(self, name):
-	"""Set the name of the map"""
-	self.D["name"] = name
-
-    def set_mapset(self, mapset):
-	"""Set the mapset of the map"""
-	self.D["mapset"] = mapset
-
-    def set_creator(self, creator):
-	"""Set the creator of the map"""
-	self.D["creator"] = creator
-
-    def set_ctime(self, ctime=None):
-	"""Set the creation time of the map, if nothing set the current time is used"""
-	if ctime == None:
-            self.D["creation_time"] = datetime.now()
-	else:
-            self.D["creation_time"] = ctime
-
-    def set_mtime(self, 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:
-            self.D["modification_time"] = mtime
-
-    def set_ttype(self, ttype):
-	"""Set the temporal type of the map: absolute or relative, if nothing set absolute time will assumed"""
-	if ttype == None or (ttype != "absolute" and ttype != "relative"):
-	    self.D["temporal_type"] = "absolute"
-        else:
-	    self.D["temporal_type"] = ttype
-
-    def set_revision(self, revision=1):
-	"""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"]
-        else:
-	    return None
-
-    def get_name(self):
-	"""Get the name of the map
-	   @return None if not found"""
-	if self.D.has_key("name"):
-	    return self.D["name"]
-        else:
-	    return None
-
-    def get_mapset(self):
-	"""Get the mapset of the map
-	   @return None if not found"""
-	if self.D.has_key("mapset"):
-	    return self.D["mapset"]
-        else:
-	    return None
-
-    def get_creator(self):
-	"""Get the creator of the map
-	   @return None if not found"""
-	if self.D.has_key("creator"):
-	    return self.D["creator"]
-        else:
-	    return None
-
-    def get_ctime(self):
-	"""Get the creation time of the map, datatype is datetime
-	   @return None if not found"""
-	if self.D.has_key("creation_time"):
-	    return self.D["creation_time"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    return None
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        #      0123456789012345678901234567890
-        print " +-------------------- Basic information -------------------------------------+"
-        print " | Id: ........................ " + str(self.get_id())
-        print " | Name: ...................... " + str(self.get_name())
-        print " | Mapset: .................... " + str(self.get_mapset())
-        print " | Creator: ................... " + str(self.get_creator())
-        print " | Creation time: ............. " + str(self.get_ctime())
-        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())
-        print "creator=" + str(self.get_creator())
-        print "creation_time=" + str(self.get_ctime())
-        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 vector_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, "vector_base", ident, name, mapset, creator, creation_time,\
-	            modification_time, temporal_type, revision)
-
-###############################################################################
-
-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)
-
-    def set_semantic_type(self, 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"]
-        else:
-	    return None
-
-###############################################################################
-
-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 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)
-

Deleted: grass/trunk/lib/python/tgis_core.py
===================================================================
--- grass/trunk/lib/python/tgis_core.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_core.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,216 +0,0 @@
-"""!@package grass.script.tgis_core
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS core functions to be used in Python sripts.
-
-Usage:
-
- at code
-from grass.script import tgis_core as grass
-
-grass.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
-for details.
-
- at author Soeren Gebbert
-"""
-import os
-import sqlite3
-import core
-import copy
-from datetime import datetime, date, time, timedelta
-
-###############################################################################
-
-def get_grass_location_db_path():
-    grassenv = core.gisenv()
-    dbpath = os.path.join(grassenv["GISDBASE"], grassenv["LOCATION_NAME"])
-    return os.path.join(dbpath, "grass.db")
-
-###############################################################################
-
-def get_sql_template_path():
-    base = os.getenv("GISBASE")
-    base_etc  = os.path.join(base, "etc")
-    return os.path.join(base_etc, "sql")
-
-def test_increment_datetime_by_string():
-
-    dt = datetime(2001, 9, 1, 0, 0, 0)
-    string = "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
-
-    dt1 = datetime(2003,2,18,12,5,0)
-    dt2 = increment_datetime_by_string(dt, string)
-
-    delta = dt1 -dt2
-
-    if delta.days != 0 or delta.seconds != 0:
-        core.fatal("increment computation is wrong")
-
-def increment_datetime_by_string(mydate, increment, mult = 1):
-    """Return a new datetime object incremented with the provided relative dates specified as string.
-       Additional a multiplier can be specified to multiply the increment bevor adding to the provided datetime object.
-
-       @mydate A datetime object to incremented
-       @increment A string providing increment information:
-                  The string may include comma separated values of type seconds, minutes, hours, days, weeks, months and years
-                  Example: Increment the datetime 2001-01-01 00:00:00 with "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
-                  will result in the datetime 2003-02-18 12:05:00
-        @mult A multiplier, default is 1
-    """
-
-    if increment:
-
-        seconds = 0
-        minutes = 0
-        hours = 0
-        days = 0
-        weeks = 0
-        months = 0
-        years = 0
-
-        inclist = []
-        # Split the increment string
-        incparts = increment.split(",")
-        for incpart in incparts:
-            inclist.append(incpart.strip().split(" "))
-
-        for inc in inclist:
-            if inc[1].find("seconds") >= 0:
-                seconds = mult * int(inc[0])
-            elif inc[1].find("minutes") >= 0:
-                minutes = mult * int(inc[0])
-            elif inc[1].find("hours") >= 0:
-                hours = mult * int(inc[0])
-            elif inc[1].find("days") >= 0:
-                days = mult * int(inc[0])
-            elif inc[1].find("weeks") >= 0:
-                weeks = mult * int(inc[0])
-            elif inc[1].find("months") >= 0:
-                months = mult * int(inc[0])
-            elif inc[1].find("years") >= 0:
-                years = mult * int(inc[0])
-            else:
-                core.fatal("Wrong increment format: " + increment)
-
-        return increment_datetime(mydate, years, months, weeks, days, hours, minutes, seconds)
-    
-    return mydate
-
-###############################################################################
-
-def increment_datetime(mydate, years=0, months=0, weeks=0, days=0, hours=0, minutes=0, seconds=0):
-    """Return a new datetime object incremented with the provided relative dates and times"""
-
-    tdelta_seconds = timedelta(seconds=seconds)
-    tdelta_minutes = timedelta(minutes=minutes)
-    tdelta_hours = timedelta(hours=hours)
-    tdelta_days = timedelta(days=days)
-    tdelta_weeks = timedelta(weeks=weeks)
-    tdelta_months = timedelta(0)
-    tdelta_years = timedelta(0)
-
-    if months > 0:
-        # Compute the actual number of days in the month to add as timedelta
-        year = mydate.year
-        month = mydate.month
-
-        all_months = int(months + month)
-
-        years_to_add = int(all_months/12)
-        residual_months = all_months%12
-
-        # Make a deep copy of the datetime object
-        dt1 = copy.copy(mydate)
-
-        # Make sure the montha starts with a 1
-        if residual_months == 0:
-            residual_months = 1
-
-        dt1 = dt1.replace(year = year + years_to_add, month = residual_months)
-        tdelta_months = dt1 - mydate
-
-    if years > 0:
-        # Make a deep copy of the datetime object
-        dt1 = copy.copy(mydate)
-        # Compute the number of days
-        dt1 = dt1.replace(year=mydate.year + int(years))
-        tdelta_years = dt1 - mydate
-
-    return mydate + tdelta_seconds + tdelta_minutes + tdelta_hours + \
-                    tdelta_days + tdelta_weeks + tdelta_months + tdelta_years
-
-###############################################################################
-
-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"""
-    
-    database = get_grass_location_db_path()
-
-    # Check if it already exists
-    if os.path.exists(database):
-        return False
-
-    # 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()
-
-    # 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")
-  
-    # 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")
-    str3ds_tables_sql = stds_tables_template_sql.replace("STDS", "str3ds")
-
-    # Check for completion
-    sqlite3.complete_statement(raster_tables_sql)
-    sqlite3.complete_statement(vector_tables_sql)
-    sqlite3.complete_statement(raster3d_tables_sql)
-    sqlite3.complete_statement(raster_metadata_sql)
-    sqlite3.complete_statement(vector_metadata_sql)
-    sqlite3.complete_statement(raster3d_metadata_sql)
-    sqlite3.complete_statement(strds_tables_sql)
-    sqlite3.complete_statement(stvds_tables_sql)
-    sqlite3.complete_statement(str3ds_tables_sql)
-    sqlite3.complete_statement(strds_metadata_sql)
-    sqlite3.complete_statement(stvds_metadata_sql)
-    sqlite3.complete_statement(str3ds_metadata_sql)
-
-    # Connect to database
-    connection = sqlite3.connect(database)
-    cursor = connection.cursor()
-
-    # Execute the SQL statements
-    # 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)
-
-    connection.commit()
-    cursor.close()

Deleted: grass/trunk/lib/python/tgis_metadata.py
===================================================================
--- grass/trunk/lib/python/tgis_metadata.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_metadata.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,640 +0,0 @@
-"""!@package grass.script.tgis_metadata
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related metadata functions to be used in Python scripts and tgis packages.
-
-Usage:
-
- at code
-from grass.script import tgis_metadata as grass
-
-meta = grass.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
-for details.
-
- at author Soeren Gebbert
-"""
-from tgis_base import *
-
-###############################################################################
-
-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)
-
-	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
-
-    def set_datatype(self, datatype):
-	"""Set the datatype"""
-	self.D["datatype"] = datatype
-
-    def set_cols(self, cols):
-	"""Set the number of cols"""
-	self.D["cols"] = cols
-
-    def set_rows(self, rows):
-	"""Set the number of rows"""
-	self.D["rows"] = rows
-
-    def set_number_of_cells(self, number_of_cells):
-	"""Set the number of cells"""
-	self.D["number_of_cells"] = number_of_cells
-
-    def set_nsres(self, nsres):
-	"""Set the north-south resolution"""
-	self.D["nsres"] = nsres
-
-    def set_ewres(self, ewres):
-	"""Set the east-west resolution"""
-	self.D["ewres"] = ewres
-
-    def set_min(self, min):
-	"""Set the minimum raster value"""
-	self.D["min"] = min
-
-    def set_max(self, max):
-	"""Set the maximum raster value"""
-	self.D["max"] = max
-
-    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    return None
-
-    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 " | North-South resolution:..... " + str(self.get_nsres())
-        print " | East-west resolution:....... " + str(self.get_ewres())
-        print " | Minimum value:.............. " + str(self.get_min())
-        print " | Maximum value:.............. " + str(self.get_max())
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        print "datatype=" + str(self.get_datatype())
-        print "cols=" + str(self.get_cols())
-        print "rows=" + str(self.get_rows())
-        print "number_of_cells=" + str(self.get_number_of_cells())
-        print "nsres=" + str(self.get_nsres())
-        print "ewres=" + str(self.get_ewres())
-        print "min=" + str(self.get_min())
-        print "max=" + str(self.get_max())
-
-###############################################################################
-
-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)
-
-	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
-
-    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"]
-        else:
-	    return None
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        print " +-------------------- Metadata information ----------------------------------+"
-        #      0123456789012345678901234567890
-        print " | STRDS register table ....... " + str(self.get_strds_register())
-        raster_metadata_base.print_info(self)
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        raster_metadata_base.print_shell_info(self)
-
-###############################################################################
-
-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)
-
-	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
-
-    def set_depths(self, depths):
-	"""Set the number of depths"""
-	self.D["depths"] = depths
-
-    def set_tbres(self, tbres):
-	"""Set the top-bottom resolution"""
-	self.D["tbres"] = tbres
-
-    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    return None
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        print " +-------------------- Metadata information ----------------------------------+"
-        #      0123456789012345678901234567890
-        print " | STR3DS register table ...... " + str(self.get_str3ds_register())
-        raster_metadata_base.print_info(self)
-        #      0123456789012345678901234567890
-        print " | Number of depths:........... " + str(self.get_depths())
-        print " | Top-Bottom resolution:...... " + str(self.get_tbres())
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        raster_metadata_base.print_shell_info(self)
-        print "depths=" + str(self.get_depths())
-        print "tbres=" + str(self.get_tbres())
-        
-###############################################################################
-
-class vector_metadata(sql_database_interface):
-    """This is the vector metadata class"""
-    def __init__(self, ident=None, stvds_register=None):
-
-	sql_database_interface.__init__(self, "vector_metadata", ident)
-
-	self.set_id(ident)
-	self.set_stvds_register(stvds_register)
-
-    def set_id(self, 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
-
-    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"]
-        else:
-	    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"]
-        else:
-	    return None
-
-
-    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())
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        print "stvds_register=" + str(self.get_stvds_register())
-
-###############################################################################
-
-class stds_metadata_base(sql_database_interface):
-    """This is the space time dataset metadata base class for strds, stvds and str3ds datasets
-       setting/getting the id, the title and the description
-    """
-    def __init__(self, table=None, ident=None, title=None, description=None):
-
-	sql_database_interface.__init__(self, table, ident)
-
-	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
-
-    def set_title(self, title):
-	"""Set the title"""
-	self.D["title"] = title
-
-    def set_description(self, 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"]
-        else:
-	    return None
-
-    def get_title(self):
-	"""Get the title 
-	   @return None if not found"""
-	if self.D.has_key("title"):
-	    return self.D["title"]
-        else:
-	    return None
-
-    def get_description(self):
-	"""Get description 
-	   @return None if not found"""
-	if self.D.has_key("description"):
-	    return self.D["description"]
-        else:
-	    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"]
-        else:
-	    return None
-
-    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 " | Title:"
-        print " | " + str(self.get_title())
-        print " | Description:"
-        print " | " + str(self.get_description())
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        print "number_of_maps=" + str(self.get_number_of_maps())
-
-###############################################################################
-    
-class stds_raster_metadata_base(stds_metadata_base):
-    """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 of voxel maps are added. Therefor only some set- an many get-functions 
-       are available.
-    """
-    def __init__(self, table=None, ident=None, title=None, description=None):
-
-	stds_metadata_base.__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
-        self.D["min_min"] = None
-        self.D["max_min"] = None
-        self.D["nsres_min"] = None
-        self.D["nsres_max"] = None
-        self.D["ewres_min"] = None
-        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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    return None
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        stds_metadata_base.print_info(self)
-        #      0123456789012345678901234567890
-        print " | North-South resolution min:. " + str(self.get_nsres_min())
-        print " | North-South resolution max:. " + str(self.get_nsres_max())
-        print " | East-west resolution min:... " + str(self.get_ewres_min())
-        print " | East-west resolution max:... " + str(self.get_ewres_max())
-        print " | Minimum value min:.......... " + str(self.get_min_min())
-        print " | Minimum value max:.......... " + str(self.get_min_max())
-        print " | Maximum value min:.......... " + str(self.get_max_min())
-        print " | Maximum value max:.......... " + str(self.get_max_max())
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        stds_metadata_base.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())
-        print "ewres_max=" + str(self.get_ewres_max())
-        print "min_min=" + str(self.get_min_min())
-        print "min_max=" + str(self.get_min_max())
-        print "max_min=" + str(self.get_max_min())
-        print "max_max=" + str(self.get_max_max())
-
-
-###############################################################################
-
-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):
-
-	stds_raster_metadata_base.__init__(self, "strds_metadata", ident, title, description)
-
-	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
-
-    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"]
-        else:
-	    return None
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        print " +-------------------- Metadata information ----------------------------------+"
-        #      0123456789012345678901234567890
-        print " | Raster register table:...... " + str(self.get_raster_register())
-        stds_raster_metadata_base.print_info(self)
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        stds_raster_metadata_base.print_shell_info(self)
-
-###############################################################################
-
-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)
-
-	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
-
-    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    return None
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        print " +-------------------- Metadata information ----------------------------------+"
-        #      0123456789012345678901234567890
-        print " | Raster3d register table:.... " + str(self.get_raster3d_register())
-        stds_raster_metadata_base.print_info(self)
-        #      0123456789012345678901234567890
-        print " | Top-bottom resolution min:.. " + str(self.get_ewres_min())
-        print " | Top-bottom resolution max:.. " + str(self.get_ewres_max())
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        stds_raster_metadata_base.print_shell_info(self)
-        print "tbres_min=" + str(self.get_tbres_min())
-        print "tbres_max=" + str(self.get_tbres_max())
-
-###############################################################################
-
-class stvds_metadata(stds_metadata_base):
-    """This is the raster metadata class"""
-    def __init__(self, ident=None, vector_register=None,  title=None, description=None):
-
-	stds_metadata_base.__init__(self, "stvds_metadata", ident, title, description)
-
-	self.set_vector_register(vector_register)
-
-    def set_vector_register(self, vector_register):
-	"""Set the vector map register table name"""
-	self.D["vector_register"] = vector_register
-
-    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"]
-        else:
-	    return None
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        print " +-------------------- Metadata information ----------------------------------+"
-        #      0123456789012345678901234567890
-        print " | Vector register table:...... " + str(self.get_vector_register())
-        stds_metadata_base.print_info(self)
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        stds_metadata_base.print_shell_info(self)

Deleted: grass/trunk/lib/python/tgis_space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/tgis_space_time_datasets.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_space_time_datasets.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,687 +0,0 @@
-"""!@package grass.script.tgis_space_time_dataset
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related functions to be used in Python scripts.
-
-Usage:
-
- at code
-from grass.script import tgis_space_time_dataset as grass
-
-strds = grass.space_time_raster_dataset("soils_1950_2010")
-
-...
- at endcode
-
-(C) 2008-2011 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Soeren Gebbert
-"""
-import getpass
-import raster
-import vector
-import raster3d
-from tgis_abstract_datasets import *
-
-
-###############################################################################
-
-class raster_dataset(abstract_map_dataset):
-    """Raster dataset class
-
-       This class provides functions to select, update, insert or delete raster
-       map informations and valid time stamps into the SQL temporal database.
-    """
-    def __init__(self, ident):
-	self.reset(ident)
-
-    def get_type(self):
-        return "raster"
-
-    def get_new_instance(self, ident):
-        """Return a new instance with the type of this class"""
-        return raster_dataset(ident)
-
-    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 space_time_raster_dataset(ident)
-
-    def get_stds_register(self):
-        """Return the space time dataset register table name in which stds are listed in which this map is registered"""
-        return self.metadata.get_strds_register()
-
-    def set_stds_register(self, name):
-        """Set the space time dataset register table name in which stds are listed in which this map is registered"""
-        self.metadata.set_strds_register(name)
-
-    def reset(self, ident):
-	"""Reset the internal structure and set the identifier"""
-	self.ident = ident
-
-	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)
-
-    def load(self):
-        """Load all info from an existing raster map into the internal structure"""
-
-        # Get the data from an existing raster map
-        kvp = raster.raster_info(self.ident)
-
-        # Fill base information
-
-        self.base.set_name(self.ident.split("@")[0])
-        self.base.set_mapset(self.ident.split("@")[1])
-        self.base.set_creator(str(getpass.getuser()))
-
-        # Fill spatial extent
-
-        self.set_spatial_extent(north=kvp["north"], south=kvp["south"], \
-                                east=kvp["east"],   west=kvp["west"])
-
-        # Fill metadata
-
-        self.metadata.set_nsres(kvp["nsres"])
-        self.metadata.set_ewres(kvp["ewres"])
-        self.metadata.set_datatype(kvp["datatype"])
-        self.metadata.set_min(kvp["min"])
-        self.metadata.set_max(kvp["max"])
-
-        rows = int((kvp["north"] - kvp["south"])/kvp["nsres"] + 0.5)
-        cols = int((kvp["east"] - kvp["west"])/kvp["ewres"] + 0.5)
-
-        ncells = cols * rows
-
-        self.metadata.set_cols(cols)
-        self.metadata.set_rows(rows)
-        self.metadata.set_number_of_cells(ncells)
-
-###############################################################################
-
-class raster3d_dataset(abstract_map_dataset):
-    """Raster3d dataset class
-
-       This class provides functions to select, update, insert or delete raster3d
-       map informations and valid time stamps into the SQL temporal database.
-    """
-    def __init__(self, ident):
-	self.reset(ident)
-
-    def get_type(self):
-        return "raster3d"
-
-    def get_new_instance(self, ident):
-        """Return a new instance with the type of this class"""
-        return raster3d_dataset(ident)
-
-    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 space_time_raster3d_dataset(ident)
-
-    def get_stds_register(self):
-        """Return the space time dataset register table name in which stds are listed in which this map is registered"""
-        return self.metadata.get_str3ds_register()
-
-    def set_stds_register(self, name):
-        """Set the space time dataset register table name in which stds are listed in which this map is registered"""
-        self.metadata.set_str3ds_register(name)
-
-    def reset(self, ident):
-	"""Reset the internal structure and set the identifier"""
-	self.ident = ident
-
-	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)
-
-    def load(self):
-        """Load all info from an existing raster3d map into the internal structure"""
-
-        # Get the data from an existing raster map
-        kvp = raster3d.raster3d_info(self.ident)
-
-        # Fill base information
-
-        self.base.set_name(self.ident.split("@")[0])
-        self.base.set_mapset(self.ident.split("@")[1])
-        self.base.set_creator(str(getpass.getuser()))
-
-        # Fill spatial extent
-
-        self.set_spatial_extent(north=kvp["north"], south=kvp["south"], \
-                                east=kvp["east"],   west=kvp["west"],\
-                                top=kvp["top"], bottom=kvp["bottom"])
-
-        # Fill metadata
-
-        self.metadata.set_nsres(kvp["nsres"])
-        self.metadata.set_ewres(kvp["ewres"])
-        self.metadata.set_tbres(kvp["tbres"])
-        self.metadata.set_datatype(kvp["datatype"])
-        self.metadata.set_min(kvp["min"])
-        self.metadata.set_max(kvp["max"])
-
-        rows = int((kvp["north"] - kvp["south"])/kvp["nsres"] + 0.5)
-        cols = int((kvp["east"] - kvp["west"])/kvp["ewres"] + 0.5)
-        depths = int((kvp["top"] - kvp["bottom"])/kvp["tbres"] + 0.5)
-
-        ncells = cols * rows * depths
-
-        self.metadata.set_cols(cols)
-        self.metadata.set_rows(rows)
-        self.metadata.set_depths(depths)
-        self.metadata.set_number_of_cells(ncells)
-
-###############################################################################
-
-class vector_dataset(abstract_map_dataset):
-    """Vector dataset class
-
-       This class provides functions to select, update, insert or delete vector
-       map informations and valid time stamps into the SQL temporal database.
-    """
-    def __init__(self, ident):
-	self.reset(ident)
-
-    def get_type(self):
-        return "vector"
-
-    def get_new_instance(self, ident):
-        """Return a new instance with the type of this class"""
-        return vector_dataset(ident)
-
-    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 space_time_vector_dataset(ident)
-
-    def get_stds_register(self):
-        """Return the space time dataset register table name in which stds are listed in which this map is registered"""
-        return self.metadata.get_stvds_register()
-
-    def set_stds_register(self, name):
-        """Set the space time dataset register table name in which stds are listed in which this map is registered"""
-        self.metadata.set_stvds_register(name)
-
-    def reset(self, ident):
-	"""Reset the internal structure and set the identifier"""
-	self.ident = ident
-
-	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)
-
-    def load(self):
-        """Load all info from an existing vector map into the internal structure"""
-
-        # Get the data from an existing raster map
-        kvp = vector.vector_info(self.ident)
-
-        # Fill base information
-
-        self.base.set_name(self.ident.split("@")[0])
-        self.base.set_mapset(self.ident.split("@")[1])
-        self.base.set_creator(str(getpass.getuser()))
-
-        # Fill spatial extent
-
-        self.set_spatial_extent(north=kvp["north"], south=kvp["south"], \
-                                east=kvp["east"],   west=kvp["west"],\
-                                top=kvp["top"], bottom=kvp["bottom"])
-
-        # Fill metadata .. no metadata yet
-
-###############################################################################
-
-class space_time_raster_dataset(abstract_space_time_dataset):
-    """Space time raster dataset class
-    """
-    def __init__(self, ident):
-        abstract_space_time_dataset.__init__(self, ident)
-
-    def get_type(self):
-        return "strds"
-
-    def get_new_instance(self, ident):
-        """Return a new instance with the type of this class"""
-        return space_time_raster_dataset(ident)
-
-    def get_new_map_instance(self, ident):
-        """Return a new instance of a map dataset which is associated with the type of this class"""
-        return raster_dataset(ident)
-
-    def get_map_register(self):
-        """Return the name of the map register table"""
-        return self.metadata.get_raster_register()
-
-    def set_map_register(self, name):
-        """Set the name of the map register table"""
-        self.metadata.set_raster_register(name)
-
-    def reset(self, ident):
-
-	"""Reset the internal structure and set the identifier"""
-	self.ident = ident
-
-	self.base = strds_base(ident=ident)
-
-        if ident != None:
-            self.base.set_name(self.ident.split("@")[0])
-            self.base.set_mapset(self.ident.split("@")[1])
-        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)
-
-###############################################################################
-
-class space_time_raster3d_dataset(abstract_space_time_dataset):
-    """Space time raster3d dataset class
-    """
-
-    def __init__(self, ident):
-        abstract_space_time_dataset.__init__(self, ident)
-
-    def get_type(self):
-        return "str3ds"
-
-    def get_new_instance(self, ident):
-        """Return a new instance with the type of this class"""
-        return space_time_raster3d_dataset(ident)
-
-    def get_new_map_instance(self, ident):
-        """Return a new instance of a map dataset which is associated with the type of this class"""
-        return raster3d_dataset(ident)
-
-    def get_map_register(self):
-        """Return the name of the map register table"""
-        return self.metadata.get_raster3d_register()
-
-    def set_map_register(self, name):
-        """Set the name of the map register table"""
-        self.metadata.set_raster3d_register(name)
-
-    def reset(self, ident):
-
-	"""Reset the internal structure and set the identifier"""
-	self.ident = ident
-
-	self.base = str3ds_base(ident=ident)
-
-        if ident != None:
-            self.base.set_name(self.ident.split("@")[0])
-            self.base.set_mapset(self.ident.split("@")[1])
-        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)
-
-###############################################################################
-
-class space_time_vector_dataset(abstract_space_time_dataset):
-    """Space time vector dataset class
-    """
-
-    def __init__(self, ident):
-        abstract_space_time_dataset.__init__(self, ident)
-
-    def get_type(self):
-        return "stvds"
-
-    def get_new_instance(self, ident):
-        """Return a new instance with the type of this class"""
-        return space_time_vector_dataset(ident)
-
-    def get_new_map_instance(self, ident):
-        """Return a new instance of a map dataset which is associated with the type of this class"""
-        return vector_dataset(ident)
-
-    def get_map_register(self):
-        """Return the name of the map register table"""
-        return self.metadata.get_vector_register()
-
-    def set_map_register(self, name):
-        """Set the name of the map register table"""
-        self.metadata.set_vector_register(name)
-
-    def reset(self, ident):
-
-	"""Reset the internal structure and set the identifier"""
-	self.ident = ident
-
-	self.base = stvds_base(ident=ident)
-
-        if ident != None:
-            self.base.set_name(self.ident.split("@")[0])
-            self.base.set_mapset(self.ident.split("@")[1])
-        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)
-
-###############################################################################
-
-def register_maps_in_space_time_dataset(type, name, maps, start=None, increment=None, dbif = None):
-    """Use this method to register maps in space time datasets. This function is generic and
-       can handle raster, vector and raster3d maps as well as there space time datasets.
-
-       Additionally a start time string and an increment string can be specified
-       to assign a time interval automatically to the maps.
-
-       It takes care of the correct update of the space time datasets from all
-       registered maps.
-
-       @type The type of the maps raster, raster3d or vector
-       @name The name of the space time dataset
-       @maps A comma separated list of map names
-       @start The start date and time of the first raster map, in case the map has no date (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
-       @increment Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
-    """
-
-    # We may need the mapset
-    mapset =  core.gisenv()["MAPSET"]
-
-    # Check if the dataset name contains the mapset as well
-    if name.find("@") < 0:
-        id = name + "@" + mapset
-    else:
-        id = name
-
-    if type == "raster":
-        sp = space_time_raster_dataset(id)
-    if type == "raster3d":
-        sp = space_time_raster3d_dataset(id)
-    if type == "vector":
-        sp = space_time_vector_dataset(id)
-
-    connect = False
-
-    if dbif == None:
-        dbif = sql_database_interface()
-        dbif.connect()
-        connect = True
-
-    # Read content from temporal database
-    sp.select(dbif)
-
-    if sp.is_in_db(dbif) == False:
-        core.fatal("Space time " + sp.get_new_map_instance(None).get_type() + " dataset <" + name + "> not found")
-
-    if maps.find(",") == -1:
-        maplist = (maps,)
-    else:
-        maplist = tuple(maps.split(","))
-
-    count = 0
-    for mapname in maplist:
-        mapname = mapname.strip()
-        # Check if the map name contains the mapset as well
-        if mapname.find("@") < 0:
-            mapid = mapname + "@" + mapset
-        else:
-            mapid = mapname
-        # Get a new instance of the space time dataset map type
-        map = sp.get_new_map_instance(mapid)
-
-        # In case the map is already registered print a message and continue to the next map
-
-        # Put the map into the database
-        if map.is_in_db(dbif) == False:
-            # Break in case no valid time is provided
-            if start == "" or start == None:
-                core.fatal("Unable to register " + map.get_type() + " map <" + map.get_id() + ">. The map has no valid time and the start time is not set.")
-            # Load the data from the grass file database
-            map.load()
-
-            if sp.get_temporal_type() == "absolute":
-                map.set_time_to_absolute()
-            else:
-                map.set_time_to_relative()
-            #  Put it into the temporal database
-            map.insert(dbif)
-        else:
-            map.select(dbif)
-            if map.get_temporal_type() != sp.get_temporal_type():
-                core.fatal("Unable to register " + map.get_type() + " map <" + map.get_id() + ">. The temporal types are different.")
-
-        # Set the valid time
-        if start:
-            assign_valid_time_to_map(ttype=sp.get_temporal_type(), map=map, start=start, end=None, increment=increment, mult=count, dbif=dbif)
-
-        # Finally Register map in the space time dataset
-        sp.register_map(map, dbif)
-        count += 1
-
-    # Update the space time tables
-    sp.update_from_registered_maps(dbif)
-
-    if connect == True:
-        dbif.close()
-        
-###############################################################################
-
-def unregister_maps_from_space_time_datasets(type, name, maps, dbif = None):
-    """Unregister maps from a single space time dataset or, in case no dataset name is provided,
-       unregister from all datasets within the maps are registered.
-
-       @type The type of the maps raster, vector or raster3d
-       @name Name of an existing space time raster dataset. If no name is provided the raster map(s) are unregistered from all space time datasets in which they are registered.
-       @maps Name(s) of existing map(s) to unregister
-    """
-    mapset =  core.gisenv()["MAPSET"]
-
-    if dbif == None:
-        dbif = sql_database_interface()
-        dbif.connect()
-        connect = True
-
-    # In case a space time dataset is specified
-    if name:
-        # Check if the dataset name contains the mapset as well
-        if name.find("@") < 0:
-            id = name + "@" + mapset
-        else:
-            id = name
-
-        if type == "raster":
-            sp = space_time_raster_dataset(id)
-        if type == "raster3d":
-            sp = space_time_raster3d_dataset(id)
-        if type == "vector":
-            sp = space_time_vector_dataset(id)
-
-        if sp.is_in_db(dbif) == False:
-            core.fatal("Space time " + sp.get_new_map_instance(None).get_type() + " dataset <" + name + "> not found")
-
-    # Build the list of maps
-    if maps.find(",") == -1:
-        maplist = (maps,)
-    else:
-        maplist = tuple(maps.split(","))
-
-    for mapname in maplist:
-        mapname = mapname.strip()
-        # Check if the map name contains the mapset as well
-        if mapname.find("@") < 0:
-            mapid = mapname + "@" + mapset
-        else:
-            mapid = mapname
-            
-        # Create a new instance with the map type
-        if type == "raster":
-            map = raster_dataset(mapid)
-        if type == "raster3d":
-            map = raster3d_dataset(mapid)
-        if type == "vector":
-            map = vector_dataset(mapid)
-
-        # Unregister map if in database
-        if map.is_in_db(dbif) == True:
-            if name:
-                sp.select(dbif)
-                sp.unregister_map(map, dbif)
-            else:
-                map.select(dbif)
-                map.unregister(dbif)
-
-    if name:
-        sp.update_from_registered_maps(dbif)
-
-    if connect == True:
-        dbif.close()
-
-###############################################################################
-
-def assign_valid_time_to_maps(type, maps, ttype, start, end=None, increment=None, dbif = None):
-    """Use this method to assign valid time (absolute or relative) to raster,
-       raster3d and vector datasets.
-
-       It takes care of the correct update of the space time datasets from all
-       registered maps.
-
-       Valid end time and increment are mutual exclusive.
-
-       @type The type of the maps raster, raster3d or vector
-       @maps A comma separated list of map names
-       @start The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
-       @end The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
-       @increment Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
-    """
-
-    if end and increment:
-        core.fatal("Valid end time and increment are mutual exclusive")
-
-    # List of space time datasets to be updated
-    splist = {}
-
-    # We may need the mapset
-    mapset =  core.gisenv()["MAPSET"]
-
-    if dbif == None:
-        dbif = sql_database_interface()
-        dbif.connect()
-        connect = True
-
-    if maps.find(",") == -1:
-        maplist = (maps,)
-    else:
-        maplist = tuple(maps.split(","))
-
-    count = 0
-    for mapname in maplist:
-        mapname = mapname.strip()
-        # Check if the map name contains the mapset as well
-        if mapname.find("@") < 0:
-            mapid = mapname + "@" + mapset
-        else:
-            mapid = mapname
-            
-        if type == "raster":
-            map = raster_dataset(mapid)
-        if type == "raster3d":
-            map = raster3d_dataset(mapid)
-        if type == "vector":
-            map = vector_dataset(mapid)
-
-        if map.is_in_db(dbif) == False:
-            # Load the data from the grass file database
-            map.load()
-            if ttype == "absolute":
-                map.set_time_to_absolute()
-            else:
-                map.set_time_to_relative()
-            #  Put it into the temporal database
-            map.insert(dbif)
-        else:
-            map.select(dbif)
-            sprows = map.get_registered_datasets(dbif)
-            # Make an entry in the dataset list, using a dict make sure that
-            # each dataset is listed only once
-            if sprows != None:
-                for dataset in sprows:
-                    splist[dataset["id"]] = True
-            
-        # Set the valid time
-        assign_valid_time_to_map(ttype=ttype, map=map, start=start, end=end, increment=increment, mult=count, dbif=dbif)
-
-        count += 1
-
-    # Update all the space time datasets in which registered maps are changed there valid time
-    for name in splist.keys():
-        sp = map.get_new_stds_instance(name)
-        sp.select(dbif)
-        sp.update_from_registered_maps(dbif)
-
-    if connect == True:
-        dbif.close()
-
-
-###############################################################################
-
-def assign_valid_time_to_map(ttype, map, start, end, increment=None, mult=1, dbif = None):
-    """Assign the valid time to a map dataset
-
-       @ttype The temporal type which should be assigned and which the time format is of
-       @map A map dataset object derived from abstract_map_dataset
-       @start The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
-       @end The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
-       @increment Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
-       @multi A multiplier for the increment
-    """
-    
-    connect = False
-
-    if dbif == None:
-        dbif = sql_database_interface()
-        dbif.connect()
-        connect = True
-
-    if ttype == "absolute":
-        # Create the start time object
-        if start.find(":") > 0:
-            time_format = "%Y-%m-%d %H:%M:%S"
-        else:
-            time_format = "%Y-%m-%d"
-
-        start_time = datetime.strptime(start, time_format)
-        if end:
-            end_time = datetime.strptime(end, time_format)
-        else:
-            end_time = None
-
-        # Add the increment
-        if increment:
-            start_time = increment_datetime_by_string(start_time, increment, mult)
-            end_time = increment_datetime_by_string(start_time, increment, 1)
-
-        core.verbose(_("Set absolute valid time for map <%s> to %s - %s") % (map.get_id(), str(start_time), str(end_time)))
-        map.update_absolute_time(start_time, end_time, None, dbif)
-    else:
-        start_time = float(start)
-
-        if end:
-            end_time = float(end)
-        else:
-            end_time = None
-
-        if increment:
-            start_time = start_time + mult * float(increment)
-            end_time = start_time + float(increment)
-
-        core.verbose(_("Set relative valid time for map <%s> to %f - %s") % (map.get_id(), start_time,  str(end_time)))
-        map.update_relative_time(start_time, end_time, dbif)
-
-    if connect == True:
-        dbif.close()

Deleted: grass/trunk/lib/python/tgis_spatial_extent.py
===================================================================
--- grass/trunk/lib/python/tgis_spatial_extent.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_spatial_extent.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,290 +0,0 @@
-"""!@package grass.script.tgis_spatial_extent
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related spatial extent functions to be used in Python scripts and tgis packages.
-
-Usage:
-
- at code
-from grass.script import tgis_spatial_extent as grass
-
-extent = grass.raster_spatial_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
-for details.
-
- at author Soeren Gebbert
-"""
-from tgis_base import *
-
-class spatial_extent(sql_database_interface):
-    """This is the spatial extent base class for all maps and spacetime 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)
-        self.set_id(ident)
-        self.set_spatial_extent(north, south, east, west, top, bottom)
-	self.set_projection(proj)
-        
-    def overlap_2d(self, extent):
-        """Return True if the 2d extents overlap. Code is lend from wind_overlap.c in lib/gis"""  
-        
-        if self.get_projection() != extent.get_projection():
-            core.error("Projections are different. Unable to compute overlap_2d for spatial extents")
-        
-        N = extent.get_north()
-        S = extent.get_south()
-        E = extent.get_east()
-        W = extent.get_west()
-        
-        if(self.get_north() <= S):
-            return False
-        
-        if(self.get_south() >= N):
-            return False
-        
-        # Adjust the east and west in case of LL projection
-        if self.get_proj() == "LL":
-            while E < self.get_west():
-                E += 360.0
-                W += 360.0
-
-            while W > self.get_east():
-                E -= 360.0
-                W -= 360.0
-            
-        if self.get_east() <= W:
-            return False
-        
-        if self.get_west() >= E:
-            return False
-        
-        return True
-
-    def overlap(self, extent):
-        """Return True if the extents overlap."""  
-        
-        if self.overlap_2d(extent) == False:
-            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 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)        
-        
-    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"):
-            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)
-
-    def set_id(self, 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
-
-    def set_south(self, sourth):
-	"""Set the sourthern edge of the map"""
-	self.D["south"] = sourth
-
-    def set_west(self, west):
-	"""Set the western edge of the map"""
-	self.D["west"] = west
-
-    def set_east(self, east):
-	"""Set the eastern edge of the map"""
-	self.D["east"] = east
-
-    def set_top(self, top):
-	"""Set the top edge of the map"""
-	self.D["top"] = top
-
-    def set_bottom(self, bottom):
-	"""Set the bottom edge of the map"""
-	self.D["bottom"] = bottom
-
-    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"]
-        else:
-	    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"""
-
-        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
-       
-    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
-    
-    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())
-                
-    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    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"]
-        else:
-	    return None
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        #      0123456789012345678901234567890
-        print " +-------------------- Spatial extent ----------------------------------------+"
-        print " | North:...................... " + str(self.get_north())
-        print " | South:...................... " + str(self.get_south())
-        print " | East:.. .................... " + str(self.get_east())
-        print " | West:....................... " + str(self.get_west())
-        print " | Top:........................ " + str(self.get_top())
-        print " | Bottom:..................... " + str(self.get_bottom())
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        print "north=" + str(self.get_north())
-        print "south=" + str(self.get_south())
-        print "east=" + str(self.get_east())
-        print "west=" + str(self.get_west())
-        print "top=" + str(self.get_top())
-        print "bottom=" + str(self.get_bottom())
-
-
-###############################################################################
-
-class raster_spatial_extent(spatial_extent):
-    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)
-
-class raster3d_spatial_extent(spatial_extent):
-    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)
-
-class vector_spatial_extent(spatial_extent):
-    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)
-
-class strds_spatial_extent(spatial_extent):
-    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)
-
-class str3ds_spatial_extent(spatial_extent):
-    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)
-
-class stvds_spatial_extent(spatial_extent):
-    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)

Deleted: grass/trunk/lib/python/tgis_temporal_extent.py
===================================================================
--- grass/trunk/lib/python/tgis_temporal_extent.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_temporal_extent.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,438 +0,0 @@
-"""!@package grass.script.tgis_temporal_extent
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related temporal extent functions to be used in Python scripts and tgis packages.
-
-Usage:
-
- at code
-from grass.script import tgis_temporal_extent as grass
-
-grass.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
-for details.
-
- at author Soeren Gebbert
-"""
-from tgis_base import *
-
-###############################################################################
-
-class abstract_temporal_extent(sql_database_interface):
-    """This is the abstract time base class for relative and absolute time objects"""
-    def __init__(self, table=None, ident=None, start_time=None, end_time=None):
-
-	sql_database_interface.__init__(self, table, ident)
-
-	self.set_id(ident)
-	self.set_start_time(start_time)
-	self.set_end_time(end_time)
-
-    def starts(self, map):
-	"""Return True if this absolute time object starts at the start of the provided absolute time object and finishes within it
-	   A  |-----|
-	   B  |---------|
-	"""
-	if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] < map.D["end_time"]:
-	    return True
-        else:
-	    return False
-
-    def started(self, map):
-	"""Return True if this absolute time object is started at the start of the provided absolute time object
-	   A  |---------|
-	   B  |-----|
-	"""
-	if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] > map.D["end_time"]:
-	    return True
-        else:
-	    return False
-
-    def finishes(self, map):
-	"""Return True if this absolute time object finishes at the end and within of the provided absolute time object
-	   A      |-----|
-	   B  |---------|
-	"""
-	if self.D["end_time"] == map.D["end_time"] and  self.D["start_time"] > map.D["start_time"] :
-	    return True
-        else:
-	    return False
-
-    def finished(self, map):
-	"""Return True if this absolute time object finished at the end of the provided absolute time object
-	   A  |---------|
-	   B      |-----|
-	"""
-	if self.D["end_time"] == map.D["end_time"] and  self.D["start_time"] < map.D["start_time"] :
-	    return True
-        else:
-	    return False
-
-    def after(self, map):
-	"""Return True if this absolute time object is temporal located after the provided absolute time object
-	   A             |---------|
-	   B  |---------|
-	"""
-	if self.D["start_time"] > map.D["end_time"]:
-	    return True
-        else:
-	    return False
-
-    def before(self, map):
-	"""Return True if this absolute time object is temporal located bevor the provided absolute time object
-	   A  |---------|
-	   B             |---------|
-	"""
-	if self.D["end_time"] < map.D["start_time"]:
-	    return True
-        else:
-	    return False
-
-    def adjacent(self, map):
-	"""Return True if this absolute time object is a meeting neighbour the provided absolute time object
-	   A            |---------|
-	   B  |---------|
-	   A  |---------|
-	   B            |---------|
-	"""
-	if (self.D["start_time"] == map.D["end_time"]) or (self.D["end_time"] == map.D["start_time"]):
-	    return True
-        else:
-	    return False
-
-    def follows(self, map):
-	"""Return True if this absolute time object is temporal follows the provided absolute time object
-	   A            |---------|
-	   B  |---------|
-	"""
-	if self.D["start_time"] == map.D["end_time"]:
-	    return True
-        else:
-	    return False
-
-    def precedes(self, map):
-	"""Return True if this absolute time object is temporal precedes the provided absolute time object
-	   A  |---------|
-	   B            |---------|
-	"""
-	if self.D["end_time"] == map.D["start_time"]:
-	    return True
-        else:
-	    return False
-
-    def during(self, map):
-	"""Return True if this absolute time object is temporal located during the provided absolute time object
-	   A   |-------|
-	   B  |---------|
-	"""
-	if self.D["start_time"] > map.D["start_time"] and self.D["end_time"] < map.D["end_time"]:
-	    return True
-        else:
-	    return False
-
-    def contains(self, map):
-	"""Return True if this absolute time object is temporal located during the provided absolute time object
-	   A  |---------|
-	   B   |-------|
-	"""
-	if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] > map.D["end_time"]:
-	    return True
-        else:
-	    return False
-
-    def equivalent(self, map):
-	"""Return True if this absolute time object is temporal located equivalent the provided absolute time object
-	   A  |---------|
-	   B  |---------|
-	"""
-	if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] == map.D["end_time"]:
-	    return True
-        else:
-	    return False
-
-    def overlaps(self, map):
-	"""Return True if this absolute time object is temporal overlaps the provided absolute time object
-           A  |---------|
-	   B    |---------|
-	"""
-	if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] < map.D["end_time"] and\
-	   self.D["end_time"] > map.D["start_time"]:
-	    return True
-        else:
-	    return False
-
-    def overlapped(self, map):
-	"""Return True if this absolute time object is temporal overlaped by the provided absolute time object
-	   A    |---------|
-           B  |---------|
-	"""
-	if self.D["start_time"] > map.D["start_time"] and self.D["end_time"] > map.D["end_time"] and\
-	   self.D["start_time"] < map.D["end_time"]:
-	    return True
-        else:
-	    return False
-
-    def temporal_relation(self, map):
-	"""Returns the temporal relation between absolute time temporal objects
-	   Temporal relationsships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
-	"""
-	if self.equivalent(map):
-	    return "equivalent"
-	if self.during(map):
-	    return "during"
-	if self.contains(map):
-	    return "contains"
-	if self.overlaps(map):
-	    return "overlaps"
-	if self.overlapped(map):
-	    return "overlapped"
-	if self.after(map):
-	    return "after"
-	if self.before(map):
-	    return "before"
-	if self.starts(map):
-	    return "starts"
-	if self.finishes(map):
-	    return "finishes"
-	if self.started(map):
-	    return "started"
-	if self.finished(map):
-	    return "finished"
-	if self.equivalent(map):
-	    return "equivalent"
-	if self.follows(map):
-	    return "follows"
-	if self.precedes(map):
-	    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
-
-    def set_start_time(self, start_time):
-	"""Set the valid start time of the map"""
-	self.D["start_time"] = start_time
-
-    def set_end_time(self, end_time):
-	"""Set the valid end time of the map"""
-	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"]
-        else:
-	    return None
-
-    def get_start_time(self):
-	"""Get the valid start time of the map
-	   @return None if not found"""
-	if self.D.has_key("start_time"):
-	    return self.D["start_time"]
-        else:
-	    return None
-
-    def get_end_time(self):
-	"""Get the valid end time of the map
-	   @return None if not found"""
-	if self.D.has_key("end_time"):
-	    return self.D["end_time"]
-        else:
-	    return None
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        #      0123456789012345678901234567890
-        print " | Start time:................. " + str(self.get_start_time())
-        print " | End time:................... " + str(self.get_end_time())
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        print "start_time=" + str(self.get_start_time())
-        print "end_time=" + str(self.get_end_time())
-
-###############################################################################
-
-class absolute_temporal_extent(abstract_temporal_extent):
-    """This is the absolute time class for all maps and spacetime datasets
-
-       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):
-
-	abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
-
-	self.set_timezone(timezone)
-
-    def set_timezone(self, timezone):
-	"""Set the timezone of the map, integer from 1 - 24"""
-	self.D["timezone"] = timezone
-
-    def get_timezone(self):
-	"""Get the timezone of the map
-	   @return None if not found"""
-	if self.D.has_key("timezone"):
-	    return self.D["timezone"]
-        else:
-	    return None
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        #      0123456789012345678901234567890
-        print " +-------------------- Absolute time -----------------------------------------+"
-        abstract_temporal_extent.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)
-        print "timezone=" + str(self.get_timezone())
-
-###############################################################################
-
-class raster_absolute_time(absolute_temporal_extent):
-    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)
-
-class raster3d_absolute_time(absolute_temporal_extent):
-    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)
-
-class vector_absolute_time(absolute_temporal_extent):
-    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)
-
-###############################################################################
-
-class stds_absolute_time(absolute_temporal_extent):
-    def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
-        absolute_temporal_extent.__init__(self, table, ident, start_time, end_time, timezone)
-
-	self.set_granularity(granularity)
-
-    def set_granularity(self, granularity):
-	"""Set the granularity of the space time dataset"""
-	self.D["granularity"] = granularity
-
-    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"]
-        else:
-	    return None
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        absolute_temporal_extent.print_info(self)
-        #      0123456789012345678901234567890
-        print " | Granularity:................ " + str(self.get_granularity())
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        absolute_temporal_extent.print_shell_info(self)
-        print "granularity=" + str(self.get_granularity())
-
-###############################################################################
-
-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 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 relative_temporal_extent(abstract_temporal_extent):
-    """This is the relative time class for all maps and spacetime datasets
-
-       start_time and end_time must be of type datetime
-    """
-    def __init__(self, table=None, ident=None, start_time=None, end_time=None):
-
-	abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
-
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        #      0123456789012345678901234567890
-        print " +-------------------- Reltive time ------------------------------------------+"
-        abstract_temporal_extent.print_info(self)
-
-
-###############################################################################
-
-class raster_relative_time(relative_temporal_extent):
-    def __init__(self, ident=None, start_time=None, end_time=None):
-        relative_temporal_extent.__init__(self, "raster_relative_time", ident, start_time, end_time)
-
-class raster3d_relative_time(relative_temporal_extent):
-    def __init__(self, ident=None, start_time=None, end_time=None):
-        relative_temporal_extent.__init__(self, "raster3d_relative_time", ident, start_time, end_time)
-
-class vector_relative_time(relative_temporal_extent):
-    def __init__(self, ident=None, start_time=None, end_time=None):
-        relative_temporal_extent.__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):
-        relative_temporal_extent.__init__(self, table, ident, start_time, end_time)
-
-	self.set_granularity(granularity)
-
-    def set_granularity(self, granularity):
-	"""Set the granularity of the space time dataset"""
-	self.D["granularity"] = granularity
-
-    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"]
-        else:
-	    return None
-
-    def print_info(self):
-        """Print information about this class in human readable style"""
-        relative_temporal_extent.print_info(self)
-        #      0123456789012345678901234567890
-        print " | Granularity:................ " + str(self.get_granularity())
-
-    def print_shell_info(self):
-        """Print information about this class in shell style"""
-        relative_temporal_extent.print_shell_info(self)
-        print "granularity=" + str(self.get_granularity())
-
-###############################################################################
-
-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 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)
-

Modified: grass/trunk/lib/temporal/Makefile
===================================================================
--- grass/trunk/lib/temporal/Makefile	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/temporal/Makefile	2011-09-21 21:06:55 UTC (rev 48399)
@@ -6,10 +6,9 @@
 
 SQLFILES:= $(wildcard *.sql)
 
-default: copy_sql_files
+DSTFILES := $(patsubst %.sql,$(SQLDIR)/%.sql,$(SQLFILES))
 
-copy_sql_files: $(SQLDIR)
-	for i in $(SQLFILES); do $(INSTALL_DATA) $$i $(SQLDIR)/; done
+default: $(DSTFILES)
 
-$(SQLDIR): 
-	$(MKDIR) $@
\ No newline at end of file
+$(SQLDIR)/%.sql: %.sql | $(SQLDIR)
+	$(INSTALL_DATA) $< $@

Modified: grass/trunk/temporal/t.create/t.create.py
===================================================================
--- grass/trunk/temporal/t.create/t.create.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/t.create/t.create.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -81,6 +81,7 @@
 #% multiple: no
 #%end
 
+import grass.temporal as tgis
 import grass.script as grass
 
 ############################################################################
@@ -97,7 +98,7 @@
     gran = options["granularity"]
 
     # Make sure the temporal database exists
-    grass.create_temporal_database()
+    tgis.create_temporal_database()
 
     #Get the current mapset to create the id of the space time dataset
 
@@ -105,13 +106,13 @@
     id = name + "@" + mapset
 
     if type == "strds":
-        sp = grass.space_time_raster_dataset(id)
+        sp = tgis.space_time_raster_dataset(id)
     if type == "str3ds":
-        sp = grass.space_time_raster3d_dataset(id)
+        sp = tgis.space_time_raster3d_dataset(id)
     if type == "stvds":
-        sp = grass.space_time_vector_dataset(id)
+        sp = tgis.space_time_vector_dataset(id)
 
-    dbif = grass.sql_database_interface()
+    dbif = tgis.sql_database_interface()
     dbif.connect()
 
     if sp.is_in_db(dbif) and grass.overwrite() == False:
@@ -130,6 +131,6 @@
     dbif.close()
 
 if __name__ == "__main__":
-    options, flags = grass.core.parser()
+    options, flags = grass.parser()
     main()
 

Modified: grass/trunk/temporal/t.info/t.info.py
===================================================================
--- grass/trunk/temporal/t.info/t.info.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/t.info/t.info.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -43,6 +43,7 @@
 #%end
 
 import grass.script as grass
+import grass.temporal as tgis
 
 ############################################################################
 
@@ -54,7 +55,7 @@
     shellstyle = flags['g']
 
   # Make sure the temporal database exists
-    grass.create_temporal_database()
+    tgis.create_temporal_database()
 
     #Get the current mapset to create the id of the space time dataset
 
@@ -65,17 +66,17 @@
         id = name + "@" + mapset
 
     if type == "strds":
-        sp = grass.space_time_raster_dataset(id)
+        sp = tgis.space_time_raster_dataset(id)
     if type == "str3ds":
-        sp = grass.space_time_raster3d_dataset(id)
+        sp = tgis.space_time_raster3d_dataset(id)
     if type == "stvds":
-        sp = grass.space_time_vector_dataset(id)
+        sp = tgis.space_time_vector_dataset(id)
     if type == "raster":
-        sp = grass.raster_dataset(id)
+        sp = tgis.raster_dataset(id)
     if type == "raster3d":
-        sp = grass.raster3d_dataset(id)
+        sp = tgis.raster3d_dataset(id)
     if type == "vector":
-        sp = grass.vector_dataset(id)
+        sp = tgis.vector_dataset(id)
 
     if sp.is_in_db() == False:
         grass.fatal("Dataset <" + name + "> not found in temporal database")
@@ -89,6 +90,6 @@
         sp.print_info()
 
 if __name__ == "__main__":
-    options, flags = grass.core.parser()
+    options, flags = grass.parser()
     main()
 

Modified: grass/trunk/temporal/t.list/t.list.py
===================================================================
--- grass/trunk/temporal/t.list/t.list.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/t.list/t.list.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -80,6 +80,7 @@
 #%end
 
 import grass.script as grass
+import grass.temporal as tgis
 
 ############################################################################
 
@@ -95,24 +96,24 @@
     colhead = flags['c']
 
     # Make sure the temporal database exists
-    grass.create_temporal_database()
+    tgis.create_temporal_database()
 
     id = None
 
     if type == "strds":
-        sp = grass.space_time_raster_dataset(id)
+        sp = tgis.space_time_raster_dataset(id)
     if type == "str3ds":
-        sp = grass.space_time_raster3d_dataset(id)
+        sp = tgis.space_time_raster3d_dataset(id)
     if type == "stvds":
-        sp = grass.space_time_vector_dataset(id)
+        sp = tgis.space_time_vector_dataset(id)
     if type == "raster":
-        sp = grass.raster_dataset(id)
+        sp = tgis.raster_dataset(id)
     if type == "raster3d":
-        sp = grass.raster3d_dataset(id)
+        sp = tgis.raster3d_dataset(id)
     if type == "vector":
-        sp = grass.vector_dataset(id)
+        sp = tgis.vector_dataset(id)
 
-    dbif = grass.sql_database_interface()
+    dbif = tgis.sql_database_interface()
     dbif.connect()
 
     # Insert content from db
@@ -170,5 +171,5 @@
             print output
 
 if __name__ == "__main__":
-    options, flags = grass.core.parser()
+    options, flags = grass.parser()
     main()

Modified: grass/trunk/temporal/t.remove/t.remove.py
===================================================================
--- grass/trunk/temporal/t.remove/t.remove.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/t.remove/t.remove.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -39,6 +39,7 @@
 #%end
 
 import grass.script as grass
+import grass.temporal as tgis
 
 ############################################################################
 
@@ -49,11 +50,11 @@
     type = options["type"]
 
     # Make sure the temporal database exists
-    grass.create_temporal_database()
+    tgis.create_temporal_database()
     
     mapset =  grass.gisenv()["MAPSET"]
 
-    dbif = grass.sql_database_interface()
+    dbif = tgis.sql_database_interface()
     dbif.connect()
 
     for name in names.split(","):
@@ -65,17 +66,17 @@
             id = name
 
         if type == "strds":
-            ds = grass.space_time_raster_dataset(id)
+            ds = tgis.space_time_raster_dataset(id)
         if type == "str3ds":
-            ds = grass.space_time_raster3d_dataset(id)
+            ds = tgis.space_time_raster3d_dataset(id)
         if type == "stvds":
-            ds = grass.space_time_vector_dataset(id)
+            ds = tgis.space_time_vector_dataset(id)
         if type == "raster":
-            ds = grass.raster_dataset(id)
+            ds = tgis.raster_dataset(id)
         if type == "raster3d":
-            ds = grass.raster3d_dataset(id)
+            ds = tgis.raster3d_dataset(id)
         if type == "vector":
-            ds = grass.vector_dataset(id)
+            ds = tgis.vector_dataset(id)
 
         if ds.is_in_db(dbif) == False:
             grass.fatal(ds.get_type() + " dataset <" + name + "> not found in temporal database")
@@ -87,6 +88,6 @@
     dbif.close()
 
 if __name__ == "__main__":
-    options, flags = grass.core.parser()
+    options, flags = grass.parser()
     main()
 

Modified: grass/trunk/temporal/t.time.abs/t.time.abs.py
===================================================================
--- grass/trunk/temporal/t.time.abs/t.time.abs.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/t.time.abs/t.time.abs.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -56,6 +56,7 @@
 #%end
 
 import grass.script as grass
+import grass.temporal as tgis
 
 ############################################################################
 
@@ -68,12 +69,12 @@
     increment = options["increment"]
 
     # Make sure the temporal database exists
-    grass.create_temporal_database()
+    tgis.create_temporal_database()
     # Set valid absolute time to maps
-    grass.assign_valid_time_to_maps(type="raster", maps=maps, ttype="absolute", \
-                                    start=start, end=end, increment=increment, dbif=None)
+    tgis.assign_valid_time_to_maps(type="raster", maps=maps, ttype="absolute", \
+                                   start=start, end=end, increment=increment, dbif=None)
     
 if __name__ == "__main__":
-    options, flags = grass.core.parser()
+    options, flags = grass.parser()
     main()
 

Modified: grass/trunk/temporal/t.time.rel/t.time.rel.py
===================================================================
--- grass/trunk/temporal/t.time.rel/t.time.rel.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/t.time.rel/t.time.rel.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -56,6 +56,7 @@
 #%end
 
 import grass.script as grass
+import grass.temporal as tgis
 
 ############################################################################
 
@@ -68,12 +69,12 @@
     increment = options["increment"]
 
     # Make sure the temporal database exists
-    grass.create_temporal_database()
+    tgis.create_temporal_database()
     # Set valid relative time to maps
-    grass.assign_valid_time_to_maps(type="raster", maps=maps, ttype="relative", \
+    tgis.assign_valid_time_to_maps(type="raster", maps=maps, ttype="relative", \
                                     start=start, end=end, increment=increment, dbif=None)
 
 if __name__ == "__main__":
-    options, flags = grass.core.parser()
+    options, flags = grass.parser()
     main()
 

Modified: grass/trunk/temporal/tr.register/tr.register.py
===================================================================
--- grass/trunk/temporal/tr.register/tr.register.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/tr.register/tr.register.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -53,6 +53,7 @@
 #%end
 
 import grass.script as grass
+import grass.temporal as tgis
 
 ############################################################################
 
@@ -65,11 +66,11 @@
     increment = options["increment"]
 
     # Make sure the temporal database exists
-    grass.create_temporal_database()
+    tgis.create_temporal_database()
     # Register maps
-    grass.register_maps_in_space_time_dataset("raster", name, maps, start, increment)
+    tgis.register_maps_in_space_time_dataset("raster", name, maps, start, increment)
     
 if __name__ == "__main__":
-    options, flags = grass.core.parser()
+    options, flags = grass.parser()
     main()
 

Modified: grass/trunk/temporal/tr.unregister/tr.unregister.py
===================================================================
--- grass/trunk/temporal/tr.unregister/tr.unregister.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/tr.unregister/tr.unregister.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -37,6 +37,8 @@
 #%end
 
 import grass.script as grass
+import grass.temporal as tgis
+
 ############################################################################
 
 def main():
@@ -46,11 +48,11 @@
     maps = options["maps"]
 
     # Make sure the temporal database exists
-    grass.create_temporal_database()
+    tgis.create_temporal_database()
     # Unregister maps
-    grass.unregister_maps_from_space_time_datasets("raster", name, maps)
+    tgis.unregister_maps_from_space_time_datasets("raster", name, maps)
 
 if __name__ == "__main__":
-    options, flags = grass.core.parser()
+    options, flags = grass.parser()
     main()
 

Modified: grass/trunk/temporal/tr3.register/tr3.register.py
===================================================================
--- grass/trunk/temporal/tr3.register/tr3.register.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/tr3.register/tr3.register.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -53,6 +53,7 @@
 #%end
 
 import grass.script as grass
+import grass.temporal as tgis
 
 ############################################################################
 
@@ -65,11 +66,11 @@
     increment = options["increment"]
 
     # Make sure the temporal database exists
-    grass.create_temporal_database()
+    tgis.create_temporal_database()
     # Register maps
-    grass.register_maps_in_space_time_dataset("raster3d", name, maps, start, increment)
+    tgis.register_maps_in_space_time_dataset("raster3d", name, maps, start, increment)
     
 if __name__ == "__main__":
-    options, flags = grass.core.parser()
+    options, flags = grass.parser()
     main()
 

Modified: grass/trunk/temporal/tr3.unregister/tr3.unregister.py
===================================================================
--- grass/trunk/temporal/tr3.unregister/tr3.unregister.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/tr3.unregister/tr3.unregister.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -37,6 +37,8 @@
 #%end
 
 import grass.script as grass
+import grass.temporal as tgis
+
 ############################################################################
 
 def main():
@@ -46,11 +48,11 @@
     maps = options["maps"]
 
     # Make sure the temporal database exists
-    grass.create_temporal_database()
+    tgis.create_temporal_database()
     # Unregister maps
-    grass.unregister_maps_from_space_time_datasets("raster3d", name, maps)
+    tgis.unregister_maps_from_space_time_datasets("raster3d", name, maps)
 
 if __name__ == "__main__":
-    options, flags = grass.core.parser()
+    options, flags = grass.parser()
     main()
 

Modified: grass/trunk/temporal/tv.register/tv.register.py
===================================================================
--- grass/trunk/temporal/tv.register/tv.register.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/tv.register/tv.register.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -53,6 +53,7 @@
 #%end
 
 import grass.script as grass
+import grass.temporal as tgis
 
 ############################################################################
 
@@ -65,11 +66,11 @@
     increment = options["increment"]
 
     # Make sure the temporal database exists
-    grass.create_temporal_database()
+    tgis.create_temporal_database()
     # Register maps
-    grass.register_maps_in_space_time_dataset("vector", name, maps, start, increment)
+    tgis.register_maps_in_space_time_dataset("vector", name, maps, start, increment)
     
 if __name__ == "__main__":
-    options, flags = grass.core.parser()
+    options, flags = grass.parser()
     main()
 

Modified: grass/trunk/temporal/tv.unregister/tv.unregister.py
===================================================================
--- grass/trunk/temporal/tv.unregister/tv.unregister.py	2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/tv.unregister/tv.unregister.py	2011-09-21 21:06:55 UTC (rev 48399)
@@ -37,6 +37,8 @@
 #%end
 
 import grass.script as grass
+import grass.temporal as tgis
+
 ############################################################################
 
 def main():
@@ -46,11 +48,11 @@
     maps = options["maps"]
 
     # Make sure the temporal database exists
-    grass.create_temporal_database()
+    tgis.create_temporal_database()
     # Unregister maps
-    grass.unregister_maps_from_space_time_datasets("vector", name, maps)
+    tgis.unregister_maps_from_space_time_datasets("vector", name, maps)
 
 if __name__ == "__main__":
-    options, flags = grass.core.parser()
+    options, flags = grass.parser()
     main()
 



More information about the grass-commit mailing list