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

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Oct 13 18:37:03 EDT 2011


Author: huhabla
Date: 2011-10-13 15:37:03 -0700 (Thu, 13 Oct 2011)
New Revision: 48788

Removed:
   grass/trunk/lib/python/temporal/abstract_datasets.py
Modified:
   grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
Log:
New temporal topology functions. Removed redundant file.


Deleted: grass/trunk/lib/python/temporal/abstract_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_datasets.py	2011-10-13 22:36:08 UTC (rev 48787)
+++ grass/trunk/lib/python/temporal/abstract_datasets.py	2011-10-13 22:37:03 UTC (rev 48788)
@@ -1,1122 +0,0 @@
-"""!@package grass.temporal
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related functions to be used in temporal GIS Python library package.
-
-Usage:
-
- at code
-import grass.temporal as tgis
-
-...
- 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
-import copy
-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
-
-           @param ident: The identifier of the dataset
-        """
-	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
-
-           @param ident: The identifier of the dataset
-        """
-        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
-	   excluding None variables
-	"""
-	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 update_all(self, dbif=None):
-	"""Update temporal dataset entry of database from the internal structure
-	   and include None varuables.
-
-           @param dbif: The database interface to be used
-	"""
-	self.base.update_all(dbif)
-	if self.is_time_absolute():
-	    self.absolute_time.update_all(dbif)
-        if self.is_time_relative():
-	    self.relative_time.update_all(dbif)
-	self.spatial_extent.update_all(dbif)
-	self.metadata.update_all(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
-
-           @param ident: The identifier of the dataset
-        """
-        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.
-        
-           This table stores all space time datasets in which this map is registered.
-
-           @param ident: The name of the register table
-        """
-        raise IOError("This method must be implemented in the subclasses")
-        
-    def set_absolute_time(self, start_time, end_time=None, timezone=None):
-        """Set the absolute time interval with start time and end time
-        
-           @param start_time: a datetime object specifying the start time of the map
-           @param end_time: a datetime object specifying the end time of the map
-           @param timezone: Thee timezone of the map
-        
-        """
-        if start_time != 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
-
-           @param start_time: a datetime object specifying the start time of the map
-           @param end_time: a datetime object specifying the end time of the map
-           @param timezone: Thee timezone of the map
-        """
-        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_all(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 
-        
-           @param start_time: A double value in days
-           @param 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):
-        """Update the relative time interval
-
-           @param start_time: A double value in days
-           @param end_time: A double value in days
-           @param dbif: The database interface to be used
-        """
-        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_all(dbif)
-        self.base.update(dbif)
-        dbif.connection.commit()
-
-        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
-
-           @param north: The northern edge
-           @param south: The southern edge
-           @param east: The eastern edge
-           @param west: The western edge
-           @param top: The top edge
-           @param bottom: The bottom ege
-        """
-        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
-            
-           @param dbif: The database interface to be used
-        """
-
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        if self.is_in_db(dbif):
- 
-            # SELECT all needed informations from the database
-            self.select(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 <%s>") % (self.get_stds_register()))
-
-            core.verbose(_("Delete %s dataset <%s> from temporal database") % (self.get_type(), self.get_id()))
-
-            # Delete yourself from the database, trigger functions will take care of dependencies
-            self.base.delete(dbif)
-
-        self.reset(None)
-        dbif.connection.commit()
-
-        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
-
-           @param dbif: The database interface to be used
-        """
-
-        core.verbose(_("Unregister %s dataset <%s> from space time datasets") % (self.get_type(), self.get_id()))
-        
-        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)
-
-        dbif.connection.commit()
-
-        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
-           dictionary like rows with column "id" or None if this map is not registered in any
-           space time dataset.
-
-           @param dbif: The database interface to be used
-        """
-        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 <%s>") % (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 in 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=None):
-        """Return a new instance with the type of this class
-
-           @param ident: The unique identifier of the new object
-        """
-        raise IOError("This method must be implemented in the subclasses")
-
-    def get_new_map_instance(self, ident=None):
-        """Return a new instance of a map dataset which is associated with the type of this class
-
-           @param ident: The unique identifier of the new object
-        """
-        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
-
-        This table stores all map names which are registered in this space time dataset.
-
-           @param name: The name of the 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):
-        """Set the initial values of the space time dataset
-
-           @param granularity: The temporal granularity of this dataset. This value
-                               should be computed by the space time dataset itself,
-                               based on the granularity of the registered maps
-           @param temporal_type: The temporal type of this space time dataset (absolute or relative)
-           @param semantic_type: The semantic type of this dataset
-           @param title: The title
-           @param description: The description of this dataset
-        """
-
-        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 \"%s\"") % (temporal_type))
-
-        self.base.set_semantic_type(semantic_type)
-        self.metadata.set_title(title)
-        self.metadata.set_description(description)
-
-    def get_initial_values(self):
-        """Return the initial values: granularity, temporal_type, semantic_type, title, description"""
-        
-        temporal_type = self.get_temporal_type()
-
-        if temporal_type == "absolute":
-            granularity   = self.absolute_time.get_granularity()
-        elif temporal_type == "relative":
-            granularity = self.relative_time.get_granularity()
-
-        semantic_type = self.base.get_semantic_type()
-        title = self.metadata.get_title()
-        description = self.metadata.get_description()
-
-        return granularity, temporal_type, semantic_type, title, description
-
-    def get_temporal_relation_matrix(self, dbif=None):
-        """Return the temporal relation matrix of all registered maps as listof lists
-
-           The temproal relation matrix includes the temporal relations between
-           all registered maps. The relations are strings stored in a list of lists.
-           
-           @param dbif: The database interface to be used
-        """
-
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        matrix = []
-
-        maps = self.get_registered_maps_as_objects(where=None, order="start_time", dbif=dbif)
-
-        # Create the temporal relation matrix
-        # Add the map names first
-        row = []
-        for map in maps:
-            row.append(map.get_id())
-        matrix.append(row)
-
-        for mapA in maps:
-            row = []
-            for mapB in maps:
-                row.append(mapA.temporal_relation(mapB))
-            matrix.append(row)
-
-        if connect == True:
-            dbif.close()
-
-        return matrix
-
-    def get_registered_maps_as_objects(self, where = None, order = None, dbif=None):
-        """Return all registered maps as ordered object list
-
-           @param where: The SQL where statement to select a subset of the registered maps without "WHERE"
-           @param order: The SQL order statement to be used to order the objects in the list without "ORDER BY"
-           @param dbif: The database interface to be used
-
-           In case nothing found None is returned
-        """
-
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        obj_list = []
-        
-        rows = self.get_registered_maps("id", where, order, dbif)
-
-        if rows:
-            for row in rows:
-                map = self.get_new_map_instance(row["id"])
-                map.select(dbif)
-                obj_list.append(copy.copy(map))
-
-        if connect == True:
-            dbif.close()
-
-        return obj_list
-
-    def get_registered_maps(self, columns=None, where = None, order = None, dbif=None):
-        """Return sqlite rows of all registered maps.
-        
-           Each row includes all columns specified in the datatype specific view
-
-           @param columns: Columns to be selected as SQL compliant string
-           @param where: The SQL where statement to select a subset of the registered maps without "WHERE"
-           @param order: The SQL order statement to be used to order the objects in the list without "ORDER BY"
-           @param dbif: The database interface to be used
-
-           In case nothing found None is returned
-        """
-
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        rows = None
-
-        if self.get_map_register():
-            # Use the correct temporal table
-            if self.get_temporal_type() == "absolute":
-                map_view = self.get_new_map_instance(None).get_type() + "_view_abs_time"
-            else:
-                map_view = self.get_new_map_instance(None).get_type() + "_view_rel_time"
-
-            if columns:
-                sql = "SELECT %s FROM %s  WHERE %s.id IN (SELECT id FROM %s)" % (columns, map_view, map_view, self.get_map_register())
-            else:
-                sql = "SELECT * FROM %s  WHERE %s.id IN (SELECT id FROM %s)" % (map_view, map_view, self.get_map_register())
-
-            if where:
-                sql += " AND %s" % (where)
-            if order:
-                sql += " ORDER BY %s" % (order)
-
-            try:
-                dbif.cursor.execute(sql)
-                rows = dbif.cursor.fetchall()
-            except:
-                if connect == True:
-                    dbif.close()
-                core.error(_("Unable to get map ids from register table <%s>") % (self.get_map_register()))
-                raise
-
-        if connect == True:
-            dbif.close()
-
-        return rows
-
-    def delete(self, dbif=None):
-        """Delete a space time dataset from the temporal database
-
-           This method removes the space time dataset from the temporal database and drops its map register table
-
-           @param dbif: The database interface to be used
-        """
-        # First we need to check if maps are registered in this dataset and
-        # unregister them
-
-        core.verbose(_("Delete space time %s  dataset <%s> from temporal database") % (self.get_new_map_instance(ident=None).get_type(), self.get_id()))
-
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        # SELECT all needed informations from the database
-        self.select(dbif)
-
-        core.verbose(_("Drop map register table: %s") %  (self.get_map_register()))
-        if self.get_map_register():
-            rows = self.get_registered_maps("id", None, None, dbif)
-            # 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)
-            try:
-                # Drop the map register table
-                sql = "DROP TABLE " + self.get_map_register()
-                dbif.cursor.execute(sql)
-                dbif.connection.commit()
-            except:
-                if connect == True:
-                    dbif.close()
-                core.error(_("Unable to drop table <%s>") % (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
-
-           @param dbif: The database interface to be used
-        """
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        if map.is_in_db(dbif) == False:
-            dbif.close()
-            core.fatal(_("Only maps with absolute or relative valid time can be registered"))
-
-        core.verbose(_("Register %s map <%s> in space time %s dataset <%s>") %  (map.get_type(), map.get_id(), map.get_type(), 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:
-            dbif.close()
-            core.fatal(_("Only maps from the same mapset can be registered"))
-
-        # Check if map is already registred
-        if stds_register_table:
-	    if dbmi.paramstyle == "qmark":
-		sql = "SELECT id FROM " + stds_register_table + " WHERE id = (?)"
-	    else:
-		sql = "SELECT id FROM " + stds_register_table + " WHERE id = (%s)"
-            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:
-                if connect == True:
-                    dbif.close()
-                core.warning(_("Map <%s> is already registered.") % (map_id))
-                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("-", "")
-
-            map_register_table = uuid_rand + "_" + self.get_type() + "_register"
-            
-            # 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:
-		if dbmi.__name__ == "sqlite3":
-		    dbif.cursor.executescript(sql)
-		else:
-		    dbif.cursor.execute(sql)
-            except:
-                if connect == True:
-                    dbif.close()
-                core.error(_("Unable to create the space time %s dataset register table for <%s>") % \
-                            (map.get_type(), map.get_id()))
-                raise
-
-            # 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 <%s> for %s map <%s>") % \
-                          (map_register_table, map.get_type(), map.get_id()))
-
-        # We need to create the table and register it
-        if stds_register_table == None:
-            # Create table name
-            stds_register_table = stds_name + "_" + stds_mapset + "_" + map.get_type() + "_register"
-            # 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:
-		if dbmi.__name__ == "sqlite3":
-		    dbif.cursor.executescript(sql_script)
-		else:
-		    dbif.cursor.execute(sql_script)
-                dbif.connection.commit()
-            except:
-                if connect == True:
-                    dbif.close()
-                core.error(_("Unable to create the space time %s dataset register table for <%s>") % \
-                            (map.get_type(), map.get_id()))
-                raise
-
-            # 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 <%s> for space time %s  dataset <%s>") % \
-                          (stds_register_table, map.get_type(), self.get_id()))
-
-        # Register the stds in the map stds register table
-        # Check if the entry is already there
-	if dbmi.paramstyle == "qmark":
-	    sql = "SELECT id FROM " + map_register_table + " WHERE id = ?"
-	else:
-	    sql = "SELECT id FROM " + map_register_table + " WHERE id = %s"
-        dbif.cursor.execute(sql, (self.base.get_id(),))
-      	row = dbif.cursor.fetchone()
-
-        # In case of no entry make a new one
-        if row == None:
-	    if dbmi.paramstyle == "qmark":
-		sql = "INSERT INTO " + map_register_table + " (id) " + "VALUES (?)"
-	    else:
-		sql = "INSERT INTO " + map_register_table + " (id) " + "VALUES (%s)"
-            #print sql
-            dbif.cursor.execute(sql, (self.base.get_id(),))
-
-        # Now put the raster name in the stds map register table
-	if dbmi.paramstyle == "qmark":
-	    sql = "INSERT INTO " + stds_register_table + " (id) " + "VALUES (?)"
-	else:
-	    sql = "INSERT INTO " + stds_register_table + " (id) " + "VALUES (%s)"
-        #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.
-
-           @param map: The map object to unregister
-           @param dbif: The database interface to be used
-        """
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        if map.is_in_db(dbif) == False:
-            dbif.close()
-            core.fatal(_("Unable to find map <%s> in temporal database") % (map.get_id()))
-
-        core.verbose(_("Unregister %s map <%s>") % (map.get_type(), 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()
-        stds_register_table = self.get_map_register()
-
-        # Check if the map is registered in the space time raster dataset
-	if dbmi.paramstyle == "qmark":
-	    sql = "SELECT id FROM " + map_register_table + " WHERE id = ?"
-	else:
-	    sql = "SELECT id FROM " + map_register_table + " WHERE id = %s"
-        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 <%s> is not registered in space time dataset") %(map_id, self.base.get_id()))
-            if connect == True:
-                dbif.close()
-            return False
-
-        # Remove the space time raster dataset from the raster dataset register
-        if map_register_table != None:
-	    if dbmi.paramstyle == "qmark":
-		sql = "DELETE FROM " + map_register_table + " WHERE id = ?"
-	    else:
-		sql = "DELETE FROM " + map_register_table + " WHERE id = %s"
-            dbif.cursor.execute(sql, (self.base.get_id(),))
-
-        # Remove the raster map from the space time raster dataset register
-        if stds_register_table != None:
-	    if dbmi.paramstyle == "qmark":
-		sql = "DELETE FROM " + stds_register_table + " WHERE id = ?"
-	    else:
-		sql = "DELETE FROM " + stds_register_table + " WHERE id = %s"
-            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.
-
-           The update of the temporal extent checks if the end time is set correctly.
-           In case the registered maps have no valid end time (None) the maximum start time
-           will be used. If the end time is earlier than the maximum start time, it will
-           be replaced by the maximum start time.
-
-           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).
-           
-           @param dbif: The database interface to be used
-        """
-        core.verbose(_("Update metadata, spatial and temporal extent from all registered maps of <%s>") % (self.get_id()))
-
-        # Nothing to do if the register is not present
-        if not self.get_map_register():
-            return
-
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        map_time = None
-
-        use_start_time = False
-
-        # 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;"
-
-	if dbmi.__name__ == "sqlite3":
-	    dbif.cursor.executescript(sql_script)
-	else:
-	    dbif.cursor.execute(sql_script)
-	    
-        # Read and validate the selected end time
-        self.select()
-
-        if self.is_time_absolute():
-            start_time, end_time, tz = self.get_absolute_time()
-        else:
-            start_time, end_time = self.get_relative_time()
-
-        # In case no end time is set, use the maximum start time of all registered maps as end time
-        if end_time == None:
-            use_start_time = True
-        else:
-            # Check if the end time is smaller than the maximum start time
-            if self.is_time_absolute():
-                sql = """SELECT max(start_time) FROM GRASS_MAP_absolute_time WHERE GRASS_MAP_absolute_time.id IN
-                        (SELECT id FROM SPACETIME_NAME_GRASS_MAP_register);"""
-                sql = sql.replace("GRASS_MAP", self.get_new_map_instance(None).get_type())
-                sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
-            else:
-                sql = """SELECT max(start_time) FROM GRASS_MAP_relative_time WHERE GRASS_MAP_relative_time.id IN
-                        (SELECT id FROM SPACETIME_NAME_GRASS_MAP_register);"""
-                sql = sql.replace("GRASS_MAP", self.get_new_map_instance(None).get_type())
-                sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
-
-            dbif.cursor.execute(sql)
-            row = dbif.cursor.fetchone()
-
-            if row != None:
-                # This seems to be a bug in sqlite3 Python driver
-		if dbmi.__name__ == "sqlite3":
-		    tstring = row[0]
-		    # Convert the unicode string into the datetime format
-		    if tstring.find(":") > 0:
-			time_format = "%Y-%m-%d %H:%M:%S"
-		    else:
-			time_format = "%Y-%m-%d"
-
-		    max_start_time = datetime.strptime(tstring, time_format)
-		else:
-		    max_start_time = row[0]
-
-		if end_time < max_start_time:
-                    map_time = "mixed"
-		    use_start_time = True
-                else:
-                    map_time = "interval"
-		    
-        # Set the maximum start time as end time
-        if use_start_time:
-            if self.is_time_absolute():
-                sql = """UPDATE STDS_absolute_time SET end_time =
-               (SELECT max(start_time) FROM GRASS_MAP_absolute_time WHERE GRASS_MAP_absolute_time.id IN
-                        (SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-               ) WHERE id = 'SPACETIME_ID';"""
-                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())
-            elif self.is_time_relative():
-                sql = """UPDATE STDS_relative_time SET end_time =
-               (SELECT max(start_time) FROM GRASS_MAP_relative_time WHERE GRASS_MAP_relative_time.id IN
-                        (SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-               ) WHERE id = 'SPACETIME_ID';"""
-                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())
-
-	    if dbmi.__name__ == "sqlite3":
-		dbif.cursor.executescript(sql)
-	    else:
-		dbif.cursor.execute(sql)
-
-            if end_time == None:
-                map_time = "point"
-
-        # Set the map time type
-        if self.is_time_absolute():
-            self.absolute_time.select(dbif)
-            self.metadata.select(dbif)
-            if self.metadata.get_number_of_maps() > 0:
-                self.absolute_time.set_map_time(map_time)
-            else:
-                self.absolute_time.set_map_time(None)
-            self.absolute_time.update_all(dbif)
-        else:
-            self.relative_time.select(dbif)
-            self.metadata.select(dbif)
-            if self.metadata.get_number_of_maps() > 0:
-                self.relative_time.set_map_time(map_time)
-            else:
-                self.relative_time.set_map_time(None)
-            self.relative_time.update_all(dbif)
-
-        # TODO: Compute the granularity of the dataset and update the database entry
-
-        if connect == True:
-            dbif.close()

Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2011-10-13 22:36:08 UTC (rev 48787)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2011-10-13 22:37:03 UTC (rev 48788)
@@ -107,7 +107,7 @@
 
         return granularity, temporal_type, semantic_type, title, description
 
-    def print_temporal_relation_matrix(self, dbif=None):
+    def print_temporal_relation_matrix(self, maps):
         """Print the temporal relation matrix of all registered maps to stdout
 
            The temproal relation matrix includes the temporal relations between
@@ -116,17 +116,6 @@
            @param dbif: The database interface to be used
         """
 
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
-        matrix = []
-
-        maps = self.get_registered_maps_as_objects(where=None, order="start_time", dbif=dbif)
-
         for map in maps:
             print map.get_id(),
         print " "    
@@ -136,29 +125,19 @@
                 print mapA.temporal_relation(mapB),
             print " "
 
-        if connect == True:
-            dbif.close()
-
-    def get_temporal_relation_matrix(self, dbif=None):
+    def get_temporal_relation_matrix(self, maps):
         """Return the temporal relation matrix of all registered maps as listof lists
 
+           The map list must be ordered by start time
+
            The temproal relation matrix includes the temporal relations between
            all registered maps. The relations are strings stored in a list of lists.
            
            @param dbif: The database interface to be used
         """
 
-        connect = False
-
-        if dbif == None:
-            dbif = sql_database_interface()
-            dbif.connect()
-            connect = True
-
         matrix = []
 
-        maps = self.get_registered_maps_as_objects(where=None, order="start_time", dbif=dbif)
-
         # Create the temporal relation matrix
         # Add the map names first
         row = []
@@ -172,12 +151,86 @@
                 row.append(mapA.temporal_relation(mapB))
             matrix.append(row)
 
-        if connect == True:
-            dbif.close()
-
         return matrix
 
-    def get_registered_maps_as_objects(self, where = None, order = None, dbif=None):
+    def get_temporal_map_type_count(self, maps):
+        """Return the temporal type of the registered maps as dictionary
+
+           The map list must be ordered by start time
+
+           The temporal type can be:
+           * point    -> only the start time is present
+           * interval -> start and end time
+           * invalid  -> No valid time point or interval found
+           * holes    -> In case the maps are interval
+
+           @param dbif: The database interface to be used
+        """
+
+        time_invalid = 0
+        time_point = 0
+        time_interval = 0
+
+        tcount = {}
+        for i in range(len(maps)):
+            # Check for point and interval data
+            if maps[i].is_time_absolute():
+                start, end, tz = maps[i].get_absolute_time()
+            if maps[i].is_time_relative():
+                start, end = maps[i].get_relative_time()
+
+            if start and end:
+                time_interval += 1
+                # Check for holes
+                if i < len(maps) - 1:
+                    relation = maps[i + 1].temporal_relation(maps[i])
+                    if relation != "follows":
+                        holes += 1
+            elif start and not end:
+                time_point += 1
+            else:
+                time_invalid += 1
+
+        tcount["point"] = time_point
+        tcount["interval"] = time_interval
+        tcount["invalid"] = time_invalid
+
+        holes = 0
+
+        # Check for holes
+        if time_interval > 0 and time_point == 0 and time_invalid == 0:
+            for i in range(len(maps)):
+                if i < len(maps) - 1:
+                    relation = maps[i + 1].temporal_relation(maps[i])
+                    if relation != "follows":
+                        holes += 1
+
+        tcount["holes"] = holes
+
+        return tcount
+
+    def get_temporal_relations_count(self, maps):
+        """Count the temporal relations between the registered maps.
+
+           The map list must be ordered by start time
+
+           @param dbif: The database interface to be used
+        """
+
+        tcount = {}
+        for i in range(len(maps)):
+            # Check for point and interval data
+            for j in range(i + 1, len(maps)):
+                relation = maps[j].temporal_relation(maps[i])
+
+                if tcount.has_key(relation):
+                    tcount[relation] = tcount[relation] + 1
+                else:
+                    tcount[relation] = 1
+
+        return tcount
+
+    def get_registered_maps_as_objects(self, where=None, order="start_time", dbif=None):
         """Return all registered maps as ordered object list
 
            @param where: The SQL where statement to select a subset of the registered maps without "WHERE"



More information about the grass-commit mailing list