Преглед на файлове

TGIS registration modules for raster, raster3d and vector maps implemented.

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@48326 15284696-431f-4ddb-bdfa-cd5b030d7da7
Soeren Gebbert преди 13 години
родител
ревизия
e89aecb5b6
променени са 36 файла, в които са добавени 1434 реда и са изтрити 628 реда
  1. 1 0
      Makefile
  2. 1 0
      lib/Makefile
  3. 1 0
      lib/python/__init__.py
  4. 83 22
      lib/python/tgis_abstract_datasets.py
  5. 214 2
      lib/python/tgis_base.py
  6. 2 214
      lib/python/tgis_core.py
  7. 188 5
      lib/python/tgis_space_time_datasets.py
  8. 97 96
      lib/temporal/stds_map_register_table_template.sql
  9. 101 92
      lib/temporal/stds_raster3d_register_trigger_template.sql
  10. 101 76
      lib/temporal/stds_raster_register_trigger_template.sql
  11. 58 0
      lib/temporal/update_stds_spatial_temporal_extent_template.sql
  12. 51 0
      lib/temporal/update_str3ds_metadata_template.sql
  13. 43 0
      lib/temporal/update_strds_metadata_template.sql
  14. 6 0
      lib/temporal/update_stvds_metadata_template.sql
  15. 22 0
      temporal/Makefile
  16. 4 4
      temporal/t.list/t.list.py
  17. 12 12
      temporal/t.remove/t.remove.py
  18. 0 0
      temporal/tgisintro.html
  19. 23 0
      temporal/tr.register/register_ECAD_maps_temp_mean_1995_2010.py
  20. 4 2
      temporal/tr.register/test.tr.register.sh
  21. 7 70
      temporal/tr.register/tr.register.py
  22. 3 33
      temporal/tr.unregister/tr.unregister.py
  23. 7 0
      temporal/tr3.register/Makefile
  24. 61 0
      temporal/tr3.register/test.tr3.register.sh
  25. 0 0
      temporal/tr3.register/tr3.register.html
  26. 75 0
      temporal/tr3.register/tr3.register.py
  27. 7 0
      temporal/tr3.unregister/Makefile
  28. 0 0
      temporal/tr3.unregister/tr3.unregister.html
  29. 56 0
      temporal/tr3.unregister/tr3.unregister.py
  30. 7 0
      temporal/tv.register/Makefile
  31. 61 0
      temporal/tv.register/test.tv.register.sh
  32. 0 0
      temporal/tv.register/tv.register.html
  33. 75 0
      temporal/tv.register/tv.register.py
  34. 7 0
      temporal/tv.unregister/Makefile
  35. 0 0
      temporal/tv.unregister/tv.unregister.html
  36. 56 0
      temporal/tv.unregister/tv.unregister.py

+ 1 - 0
Makefile

@@ -35,6 +35,7 @@ DIRS = \
 	raster \
 	raster \
 	raster3d \
 	raster3d \
 	vector \
 	vector \
+	temporal \
 	misc \
 	misc \
 	imagery \
 	imagery \
 	ps \
 	ps \

+ 1 - 0
lib/Makefile

@@ -44,6 +44,7 @@ SUBDIRS = \
 	nviz \
 	nviz \
 	python \
 	python \
 	iostream \
 	iostream \
+	temporal \
 	manage
 	manage
 
 
 include $(MODULE_TOPDIR)/include/Make/Dir.make
 include $(MODULE_TOPDIR)/include/Make/Dir.make

+ 1 - 0
lib/python/__init__.py

@@ -4,6 +4,7 @@ from raster import *
 from raster3d import *
 from raster3d import *
 from vector import *
 from vector import *
 # Temporal GIS library functions
 # Temporal GIS library functions
+from tgis_core import *
 from tgis_base import *
 from tgis_base import *
 from tgis_temporal_extent import *
 from tgis_temporal_extent import *
 from tgis_spatial_extent import *
 from tgis_spatial_extent import *

+ 83 - 22
lib/python/tgis_abstract_datasets.py

@@ -156,7 +156,7 @@ class abstract_dataset(object):
 	    return None
 	    return None
 
 
     def temporal_relation(self, map):
     def temporal_relation(self, map):
-	"""Return the temporal relation of this and the provided temporal raster map"""
+	"""Return the temporal relation of this and the provided temporal map"""
 	if self.is_time_absolute() and map.is_time_absolute():
 	if self.is_time_absolute() and map.is_time_absolute():
 	    return self.absolute_time.temporal_relation(map.absolute_time)
 	    return self.absolute_time.temporal_relation(map.absolute_time)
         if self.is_time_relative() and map.is_time_relative():
         if self.is_time_relative() and map.is_time_relative():
@@ -168,8 +168,6 @@ class abstract_dataset(object):
 class abstract_map_dataset(abstract_dataset):
 class abstract_map_dataset(abstract_dataset):
     """This is the base class for all maps (raster, vector, raster3d) 
     """This is the base class for all maps (raster, vector, raster3d) 
        providing additional function to set the valid time and the spatial extent.
        providing additional function to set the valid time and the spatial extent.
-       
-       Valid time and spatial extent will be set automatically in the space-time datasets
     """
     """
       
       
     def get_new_stds_instance(self, ident):
     def get_new_stds_instance(self, ident):
@@ -280,9 +278,12 @@ class abstract_map_dataset(abstract_dataset):
                 for row in rows:
                 for row in rows:
                     # Create a space time dataset object to remove the map
                     # Create a space time dataset object to remove the map
                     # from its register
                     # from its register
-                    strds = self.get_new_stds_instance(row["id"])
-                    strds.select()
-                    strds.unregister_map(self)
+                    stds = self.get_new_stds_instance(row["id"])
+                    stds.select()
+                    stds.unregister_map(self)
+                    # Take care to update the space time dataset after
+                    # the map has been unregistred
+                    stds.update_from_registered_maps()
 
 
 ###############################################################################
 ###############################################################################
 
 
@@ -372,7 +373,8 @@ class abstract_space_time_dataset(abstract_dataset):
             This method takes care of the registration of a map
             This method takes care of the registration of a map
             in a space time dataset.
             in a space time dataset.
 
 
-            Break with a warning in case the map is already registered.
+            In case the map is already registered this function will break with a warning
+            and return False
         """
         """
 
 
         if map.is_in_db() == False:
         if map.is_in_db() == False:
@@ -408,8 +410,8 @@ class abstract_space_time_dataset(abstract_dataset):
             self.base.close()
             self.base.close()
             # In case of no entry make a new one
             # In case of no entry make a new one
             if row and row[0] == map_id:
             if row and row[0] == map_id:
-                core.warning("Map " + map_id + "is already registered. Will unregister map and register again.")
-                self.unregister_map(map)
+                core.warning("Map " + map_id + "is already registered.")
+                return False
 
 
         # Create tables
         # Create tables
         sql_path = get_sql_template_path()
         sql_path = get_sql_template_path()
@@ -449,21 +451,33 @@ class abstract_space_time_dataset(abstract_dataset):
             sql = sql.replace("SPACETIME_ID", self.base.get_id())
             sql = sql.replace("SPACETIME_ID", self.base.get_id())
             sql = sql.replace("STDS", self.get_type())
             sql = sql.replace("STDS", self.get_type())
 
 
+            sql_script = ""
+            sql_script += "BEGIN TRANSACTION;\n"
+            sql_script += sql
+            sql_script += "\n"
+            sql_script += "END TRANSACTION;"
+
             self.base.connect()
             self.base.connect()
-            self.base.cursor.executescript(sql)
+            self.base.cursor.executescript(sql_script)
             self.base.close()
             self.base.close()
 
 
-            # We need raster specific trigger
-            sql = open(os.path.join(sql_path, "stds_" + map.get_type() + "_register_trigger_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())
+            # 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())
 
 
-            self.base.connect()
-            self.base.cursor.executescript(sql)
-            self.base.close()
+            #sql_script = ""
+            #sql_script += "BEGIN TRANSACTION;\n"
+            #sql_script += sql
+            #sql_script += "\n"
+            #sql_script += "END TRANSACTION;"
+
+            #self.base.connect()
+            #self.base.cursor.executescript(sql_script)
+            #self.base.close()
 
 
             stds_register_table = stds_name + "_" + stds_mapset + "_" + map.get_type() + "_register"
             stds_register_table = stds_name + "_" + stds_mapset + "_" + map.get_type() + "_register"
 
 
@@ -499,10 +513,10 @@ class abstract_space_time_dataset(abstract_dataset):
         return True
         return True
 
 
     def unregister_map(self, map):
     def unregister_map(self, map):
-        """Remove a register a map from the space time dataset.
+        """Unregister a map from the space time dataset.
 
 
             This method takes care of the unregistration of a map
             This method takes care of the unregistration of a map
-            in a space time dataset.
+            from a space time dataset.
         """
         """
 
 
         if map.is_in_db() == False:
         if map.is_in_db() == False:
@@ -543,3 +557,50 @@ class abstract_space_time_dataset(abstract_dataset):
             self.base.connect()
             self.base.connect()
             self.base.cursor.execute(sql, (map_id,))
             self.base.cursor.execute(sql, (map_id,))
             self.base.close()
             self.base.close()
+
+    def update_from_registered_maps(self):
+        """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() + ">")
+
+        # 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;"
+
+        self.base.connect()
+        self.base.cursor.executescript(sql_script)
+        self.base.close()

+ 214 - 2
lib/python/tgis_base.py

@@ -2,11 +2,12 @@
 
 
 @brief GRASS Python scripting module (temporal GIS functions)
 @brief GRASS Python scripting module (temporal GIS functions)
 
 
-Temporal GIS basic functions and classes to be used in other
+Temporal GIS base classes to be used in other
 Python temporal gis packages.
 Python temporal gis packages.
 
 
 This packages includes all base classes to stor basic information like id, name,
 This packages includes all base classes to stor basic information like id, name,
-mapset creation and modification time.
+mapset creation and modification time as well as sql serialization and deserialization
+and the sqlite3 database interface.
 
 
 Usage:
 Usage:
 
 
@@ -27,6 +28,217 @@ for details.
 
 
 from tgis_core import *
 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@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):
+	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):
+	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):
+	self.connect()
+	sql = self.get_delete_statement()
+        #print sql
+        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):
+	self.connect()
+	sql = self.get_is_in_db_statement()
+        #print sql
+        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):
+	self.connect()
+	sql, args = self.get_select_statement()
+	#print sql
+	#print args
+	if len(args) == 0:
+            self.cursor.execute(sql)
+	else:
+            self.cursor.execute(sql, args)
+	row = self.cursor.fetchone()
+
+	# Nothing found
+	if row == None:
+	    return False
+
+	if len(row) > 0:
+	    self.deserialize(row)
+	else:
+	    raise IOError
+	self.close()
+
+	return True
+
+    def get_insert_statement(self):
+	return self.serialize("INSERT", self.get_table_name())
+
+    def insert(self):
+	self.connect()
+	sql, args = self.get_insert_statement()
+	#print sql
+	#print args
+        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):
+	if self.ident == None:
+	    raise IOError("Missing identifer");
+
+	sql, args = self.get_update_statement()
+	#print sql
+	#print args
+	self.connect()
+        self.cursor.execute(sql, args)
+	self.close()
+
+###############################################################################
+
 class dataset_base(sql_database_interface):
 class dataset_base(sql_database_interface):
     """This is the base class for all maps and spacetime datasets storing basic information"""
     """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,\
     def __init__(self, table=None, ident=None, name=None, mapset=None, creator=None, ctime=None,\

+ 2 - 214
lib/python/tgis_core.py

@@ -2,10 +2,7 @@
 
 
 @brief GRASS Python scripting module (temporal GIS functions)
 @brief GRASS Python scripting module (temporal GIS functions)
 
 
-Temporal GIS core functions to be used in Python tgis packages.
-
-This class provides the SQL interface for serialization and deserialization
-of map and space time dataset data.
+Temporal GIS core functions to be used in Python sripts.
 
 
 Usage:
 Usage:
 
 
@@ -109,7 +106,7 @@ def increment_datetime_by_string(mydate, increment, mult = 1):
 ###############################################################################
 ###############################################################################
 
 
 def increment_datetime(mydate, years=0, months=0, weeks=0, days=0, hours=0, minutes=0, seconds=0):
 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"""
+    """Return a new datetime object incremented with the provided relative dates and times"""
 
 
     tdelta_seconds = timedelta(seconds=seconds)
     tdelta_seconds = timedelta(seconds=seconds)
     tdelta_minutes = timedelta(minutes=minutes)
     tdelta_minutes = timedelta(minutes=minutes)
@@ -217,212 +214,3 @@ def create_temporal_database():
 
 
     connection.commit()
     connection.commit()
     cursor.close()
     cursor.close()
-
-###############################################################################
-
-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@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):
-	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):
-	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):
-	self.connect()
-	sql = self.get_delete_statement()
-        #print sql
-        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):
-	self.connect()
-	sql = self.get_is_in_db_statement()
-        #print sql
-        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):
-	self.connect()
-	sql, args = self.get_select_statement()
-	#print sql
-	#print args
-	if len(args) == 0:
-            self.cursor.execute(sql)
-	else:
-            self.cursor.execute(sql, args)
-	row = self.cursor.fetchone()
-
-	# Nothing found
-	if row == None:
-	    return False
-
-	if len(row) > 0:
-	    self.deserialize(row)
-	else:
-	    raise IOError
-	self.close()
-
-	return True
-
-    def get_insert_statement(self):
-	return self.serialize("INSERT", self.get_table_name())
-
-    def insert(self):
-	self.connect()
-	sql, args = self.get_insert_statement()
-	#print sql
-	#print args
-        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):
-	if self.ident == None:
-	    raise IOError("Missing identifer");
-
-	sql, args = self.get_update_statement()
-	#print sql
-	#print args
-	self.connect()
-        self.cursor.execute(sql, args)
-	self.close()

+ 188 - 5
lib/python/tgis_space_time_datasets.py

@@ -318,8 +318,9 @@ class space_time_raster3d_dataset(abstract_space_time_dataset):
 
 
 	self.base = str3ds_base(ident=ident)
 	self.base = str3ds_base(ident=ident)
 
 
-        self.base.set_name(self.ident.split("@")[0])
-        self.base.set_mapset(self.ident.split("@")[1])
+        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.base.set_creator(str(getpass.getuser()))
         self.absolute_time = str3ds_absolute_time(ident=ident)
         self.absolute_time = str3ds_absolute_time(ident=ident)
         self.relative_time = str3ds_relative_time(ident=ident)
         self.relative_time = str3ds_relative_time(ident=ident)
@@ -361,11 +362,193 @@ class space_time_vector_dataset(abstract_space_time_dataset):
 
 
 	self.base = stvds_base(ident=ident)
 	self.base = stvds_base(ident=ident)
 
 
-        self.base.set_name(self.ident.split("@")[0])
-        self.base.set_mapset(self.ident.split("@")[1])
+        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.base.set_creator(str(getpass.getuser()))
         self.absolute_time = stvds_absolute_time(ident=ident)
         self.absolute_time = stvds_absolute_time(ident=ident)
         self.relative_time = stvds_relative_time(ident=ident)
         self.relative_time = stvds_relative_time(ident=ident)
 	self.spatial_extent = stvds_spatial_extent(ident=ident)
 	self.spatial_extent = stvds_spatial_extent(ident=ident)
 	self.metadata = stvds_metadata(ident=ident)
 	self.metadata = stvds_metadata(ident=ident)
-        
+
+###############################################################################
+
+def register_maps_in_space_time_dataset(type, name, maps, start=None, increment=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)
+
+    # Read content from temporal database
+    sp.select()
+
+    if sp.is_in_db() == 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() == 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()
+            #  Put it into the temporal database
+            map.insert()
+        else:
+            map.select()
+            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(sp.get_temporal_type(), map, start, increment, count)
+
+        # Finally Register map in the space time dataset
+        sp.register_map(map)
+        count += 1
+
+    # Update the space time tables
+    sp.update_from_registered_maps()
+
+###############################################################################
+
+def unregister_maps_from_space_time_datasets(type, name, maps):
+    """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"]
+
+    # 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() == 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() == True:
+            if name:
+                sp.select()
+                sp.unregister_map(map)
+            else:
+                map.select()
+                map.unregister()
+
+    if name:
+        sp.update_from_registered_maps()
+
+def assign_valid_time_to_map(ttype, map, start, increment=None, mult=1):
+    """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, 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)
+       @multi A multiplier for the increment
+    """
+    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)
+        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 <" + map.get_id() + "> to " + str(start_time) + " - " + str(end_time))
+        map.update_absolute_time(start_time, end_time)
+    else:
+        if increment:
+            interval = float(start) + mult * float(increment)
+        else:
+            interval = float(start)
+        core.verbose("Set relative valid time for map <" + map.get_id() + "> to " + str(interval))
+        map.update_relative_time(interval)

+ 97 - 96
lib/temporal/stds_map_register_table_template.sql

@@ -21,99 +21,100 @@ CREATE TABLE  SPACETIME_NAME_GRASS_MAP_register (
   FOREIGN KEY (id) REFERENCES  GRASS_MAP_base (id) ON DELETE CASCADE
   FOREIGN KEY (id) REFERENCES  GRASS_MAP_base (id) ON DELETE CASCADE
 );
 );
 
 
-CREATE TRIGGER SPACETIME_NAME_GRASS_MAP_register_insert_trigger AFTER INSERT ON SPACETIME_NAME_GRASS_MAP_register 
-  BEGIN
-    UPDATE STDS_base SET modification_time = datetime("NOW") WHERE id = "SPACETIME_ID";
-    UPDATE STDS_base SET revision = (revision + 1) WHERE id = "SPACETIME_ID";
-    -- Number of registered maps
-    UPDATE STDS_metadata SET number_of_maps = 
-           (SELECT count(id) FROM SPACETIME_NAME_GRASS_MAP_register)
-           WHERE id = "SPACETIME_ID";
-    -- Update the temporal extent
-    UPDATE STDS_absolute_time SET start_time = 
-           (SELECT min(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";
-    UPDATE STDS_absolute_time SET end_time = 
-           (SELECT max(end_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";
-    -- Update the spatial extent
-    UPDATE STDS_spatial_extent SET north = 
-           (SELECT max(north) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE STDS_spatial_extent SET south = 
-           (SELECT min(south) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE STDS_spatial_extent SET east = 
-           (SELECT max(east) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE STDS_spatial_extent SET west = 
-           (SELECT min(west) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE STDS_spatial_extent SET top = 
-           (SELECT max(top) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE STDS_spatial_extent SET bottom = 
-           (SELECT min(bottom) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE STDS_spatial_extent SET proj = 
-           (SELECT min(proj) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-  END;
-
-CREATE TRIGGER SPACETIME_NAME_GRASS_MAP_register_delete_trigger AFTER DELETE ON SPACETIME_NAME_GRASS_MAP_register 
-  BEGIN
-    UPDATE STDS_base SET modification_time = datetime("NOW") WHERE id = "SPACETIME_ID";
-    UPDATE STDS_base SET revision = (revision + 1) WHERE id = "SPACETIME_ID";
-    -- Number of registered maps
-    UPDATE STDS_metadata SET number_of_maps = 
-           (SELECT count(id) FROM  SPACETIME_NAME_GRASS_MAP_register)
-           WHERE id = "SPACETIME_ID";
-    -- Update the temporal extent
-    UPDATE STDS_absolute_time SET start_time = 
-           (SELECT min(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";
-    UPDATE STDS_absolute_time SET end_time = 
-           (SELECT max(end_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";
-    -- Update the spatial extent
-    UPDATE STDS_spatial_extent SET north = 
-           (SELECT max(north) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE STDS_spatial_extent SET south = 
-           (SELECT min(south) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE STDS_spatial_extent SET east = 
-           (SELECT max(east) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE STDS_spatial_extent SET west = 
-           (SELECT min(west) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE STDS_spatial_extent SET top = 
-           (SELECT max(top) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE STDS_spatial_extent SET bottom = 
-           (SELECT min(bottom) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE STDS_spatial_extent SET proj = 
-           (SELECT min(proj) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
-			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
-           ) WHERE id = "SPACETIME_ID";
-  END;
-
+-- Triggers are disabled due to huge performance issues
+--CREATE TRIGGER SPACETIME_NAME_GRASS_MAP_register_insert_trigger AFTER INSERT ON SPACETIME_NAME_GRASS_MAP_register 
+--  BEGIN
+--    UPDATE STDS_base SET modification_time = datetime("NOW") WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_base SET revision = (revision + 1) WHERE id = "SPACETIME_ID";
+--    -- Number of registered maps
+--    UPDATE STDS_metadata SET number_of_maps = 
+--           (SELECT count(id) FROM SPACETIME_NAME_GRASS_MAP_register)
+--           WHERE id = "SPACETIME_ID";
+--    -- Update the temporal extent
+--    UPDATE STDS_absolute_time SET start_time = 
+--           (SELECT min(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";
+--    UPDATE STDS_absolute_time SET end_time = 
+--           (SELECT max(end_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";
+--    -- Update the spatial extent
+--    UPDATE STDS_spatial_extent SET north = 
+--           (SELECT max(north) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_spatial_extent SET south = 
+--           (SELECT min(south) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_spatial_extent SET east = 
+--           (SELECT max(east) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_spatial_extent SET west = 
+--           (SELECT min(west) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_spatial_extent SET top = 
+--           (SELECT max(top) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_spatial_extent SET bottom = 
+--           (SELECT min(bottom) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_spatial_extent SET proj = 
+--           (SELECT min(proj) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--  END;
+--
+--CREATE TRIGGER SPACETIME_NAME_GRASS_MAP_register_delete_trigger AFTER DELETE ON SPACETIME_NAME_GRASS_MAP_register 
+-- BEGIN
+--    UPDATE STDS_base SET modification_time = datetime("NOW") WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_base SET revision = (revision + 1) WHERE id = "SPACETIME_ID";
+--    -- Number of registered maps
+--    UPDATE STDS_metadata SET number_of_maps = 
+--           (SELECT count(id) FROM  SPACETIME_NAME_GRASS_MAP_register)
+--           WHERE id = "SPACETIME_ID";
+--    -- Update the temporal extent
+--    UPDATE STDS_absolute_time SET start_time = 
+--           (SELECT min(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";
+--    UPDATE STDS_absolute_time SET end_time = 
+--           (SELECT max(end_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";
+--    -- Update the spatial extent
+--    UPDATE STDS_spatial_extent SET north = 
+--           (SELECT max(north) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_spatial_extent SET south = 
+--           (SELECT min(south) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_spatial_extent SET east = 
+--           (SELECT max(east) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_spatial_extent SET west = 
+--           (SELECT min(west) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_spatial_extent SET top = 
+--           (SELECT max(top) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_spatial_extent SET bottom = 
+--           (SELECT min(bottom) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE STDS_spatial_extent SET proj = 
+--           (SELECT min(proj) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+--			(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+--           ) WHERE id = "SPACETIME_ID";
+--  END;
+--

+ 101 - 92
lib/temporal/stds_raster3d_register_trigger_template.sql

@@ -10,95 +10,104 @@
 
 
 PRAGMA foreign_keys = ON;
 PRAGMA foreign_keys = ON;
 
 
-CREATE TRIGGER SPACETIME_NAME_raster3d_metadata_register_insert_trigger AFTER INSERT ON SPACETIME_NAME_raster3d_register 
-  BEGIN
-    -- Update the min and max values
-    UPDATE str3ds_metadata SET min_min = 
-           (SELECT min(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET min_max = 
-           (SELECT max(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET max_min = 
-           (SELECT min(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET max_max = 
-           (SELECT max(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    -- Update the resolution
-    UPDATE str3ds_metadata SET nsres_min = 
-           (SELECT min(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET nsres_max = 
-           (SELECT max(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET ewres_min = 
-           (SELECT min(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET ewres_max = 
-           (SELECT max(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET tbres_min = 
-           (SELECT min(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET tbres_max = 
-           (SELECT max(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-  END;
-
-CREATE TRIGGER SPACETIME_NAME_raster3d_metadata_register_delete_trigger AFTER DELETE ON SPACETIME_NAME_raster3d_register 
-  BEGIN
-    -- Update the min and max values
-    UPDATE str3ds_metadata SET min_min = 
-           (SELECT min(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET min_max = 
-           (SELECT max(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET max_min = 
-           (SELECT min(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET max_max = 
-           (SELECT max(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    -- Update the resolution
-    UPDATE str3ds_metadata SET nsres_min = 
-           (SELECT min(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET nsres_max = 
-           (SELECT max(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET ewres_min = 
-           (SELECT min(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET ewres_max = 
-           (SELECT max(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET tbres_min = 
-           (SELECT min(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE str3ds_metadata SET tbres_max = 
-           (SELECT max(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster3d_register)
-           ) WHERE id = "SPACETIME_ID";
-  END;
-
+-- Triggers are disabled due to huge performance issues
+--CREATE TRIGGER SPACETIME_NAME_raster3d_metadata_register_insert_trigger AFTER INSERT ON SPACETIME_NAME_raster3d_register 
+--  BEGIN
+--    -- Update the min and max values
+--    UPDATE str3ds_metadata SET min_min = 
+--           (SELECT min(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET min_max = 
+--           (SELECT max(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET max_min = 
+--           (SELECT min(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET max_max = 
+--           (SELECT max(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    -- Update the resolution
+--    UPDATE str3ds_metadata SET nsres_min = 
+--           (SELECT min(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET nsres_max = 
+--           (SELECT max(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET ewres_min = 
+--           (SELECT min(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET ewres_max = 
+--           (SELECT max(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET tbres_min = 
+--           (SELECT min(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET tbres_max = 
+--           (SELECT max(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--  END;
+--
+--CREATE TRIGGER SPACETIME_NAME_raster3d_metadata_register_delete_trigger AFTER DELETE ON SPACETIME_NAME_raster3d_register 
+--  BEGIN
+--    -- Update the min and max values
+--    UPDATE str3ds_metadata SET min_min = 
+--           (SELECT min(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET min_max = 
+--           (SELECT max(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET max_min = 
+--           (SELECT min(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET max_max = 
+--           (SELECT max(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    -- Update the resolution
+--    UPDATE str3ds_metadata SET nsres_min = 
+--           (SELECT min(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET nsres_max = 
+--           (SELECT max(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET ewres_min = 
+--           (SELECT min(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET ewres_max = 
+--           (SELECT max(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET tbres_min = 
+--           (SELECT min(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE str3ds_metadata SET tbres_max = 
+--           (SELECT max(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster3d_register)
+--           ) WHERE id = "SPACETIME_ID";
+--  END;
+--
+--
+--
+--
+--
+--
+--
+--
+--

+ 101 - 76
lib/temporal/stds_raster_register_trigger_template.sql

@@ -10,79 +10,104 @@
 
 
 PRAGMA foreign_keys = ON;
 PRAGMA foreign_keys = ON;
 
 
-CREATE TRIGGER SPACETIME_NAME_raster_metadata_register_insert_trigger AFTER INSERT ON SPACETIME_NAME_raster_register 
-  BEGIN
-    -- Update the min and max values
-    UPDATE strds_metadata SET min_min = 
-           (SELECT min(min) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE strds_metadata SET min_max = 
-           (SELECT max(min) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE strds_metadata SET max_min = 
-           (SELECT min(max) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE strds_metadata SET max_max = 
-           (SELECT max(max) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    -- Update the resolution
-    UPDATE strds_metadata SET nsres_min = 
-           (SELECT min(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE strds_metadata SET nsres_max = 
-           (SELECT max(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE strds_metadata SET ewres_min = 
-           (SELECT min(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE strds_metadata SET ewres_max = 
-           (SELECT max(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-  END;
-
-CREATE TRIGGER SPACETIME_NAME_raster_metadata_register_delete_trigger AFTER DELETE ON SPACETIME_NAME_raster_register 
-  BEGIN
-    -- Update the min and max values
-    UPDATE strds_metadata SET min_min = 
-           (SELECT min(min) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE strds_metadata SET min_max = 
-           (SELECT max(min) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE strds_metadata SET max_min = 
-           (SELECT min(max) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE strds_metadata SET max_max = 
-           (SELECT max(max) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    -- Update the resolution
-    UPDATE strds_metadata SET nsres_min = 
-           (SELECT min(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE strds_metadata SET nsres_max = 
-           (SELECT max(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE strds_metadata SET ewres_min = 
-           (SELECT min(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-    UPDATE strds_metadata SET ewres_max = 
-           (SELECT max(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
-			(SELECT id FROM SPACETIME_NAME_raster_register)
-           ) WHERE id = "SPACETIME_ID";
-  END;
-
+-- Triggers are disabled due to huge performance issues
+--CREATE TRIGGER SPACETIME_NAME_raster_metadata_register_insert_trigger AFTER INSERT ON SPACETIME_NAME_raster_register 
+--  BEGIN
+--    -- Update the min and max values
+--    UPDATE strds_metadata SET min_min = 
+--           (SELECT min(min) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE strds_metadata SET min_max = 
+--           (SELECT max(min) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE strds_metadata SET max_min = 
+--           (SELECT min(max) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE strds_metadata SET max_max = 
+--           (SELECT max(max) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    -- Update the resolution
+--    UPDATE strds_metadata SET nsres_min = 
+--           (SELECT min(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE strds_metadata SET nsres_max = 
+--           (SELECT max(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE strds_metadata SET ewres_min = 
+--           (SELECT min(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE strds_metadata SET ewres_max = 
+--           (SELECT max(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--  END;
+--
+--CREATE TRIGGER SPACETIME_NAME_raster_metadata_register_delete_trigger AFTER DELETE ON SPACETIME_NAME_raster_register 
+--  BEGIN
+--    -- Update the min and max values
+--    UPDATE strds_metadata SET min_min = 
+--           (SELECT min(min) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE strds_metadata SET min_max = 
+--           (SELECT max(min) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE strds_metadata SET max_min = 
+--           (SELECT min(max) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE strds_metadata SET max_max = 
+--           (SELECT max(max) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    -- Update the resolution
+--    UPDATE strds_metadata SET nsres_min = 
+--           (SELECT min(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE strds_metadata SET nsres_max = 
+--           (SELECT max(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE strds_metadata SET ewres_min = 
+--           (SELECT min(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--    UPDATE strds_metadata SET ewres_max = 
+--           (SELECT max(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
+--			(SELECT id FROM SPACETIME_NAME_raster_register)
+--           ) WHERE id = "SPACETIME_ID";
+--  END;
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--
+--

+ 58 - 0
lib/temporal/update_stds_spatial_temporal_extent_template.sql

@@ -0,0 +1,58 @@
+--#############################################################################
+-- This SQL script is to update the spatial and temporal extent as well as 
+-- the modifcation time and revision of a space time dataset. This script
+-- should be called when maps inserted or deleted in a space time dataset.
+--
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
+
+-- SPACETIME_NAME is a placeholder for specific stds name (SQL compliant): name_mapset
+-- SPACETIME_ID is a placeholder for specific stds id: name@mapset
+-- GRASS_MAP is a placeholder for specific map type: raster, raster3d or vector
+-- STDS is a placeholder for specific space-time dataset type: strds, str3ds, stvds
+
+UPDATE STDS_base SET modification_time = datetime("NOW") WHERE id = "SPACETIME_ID";
+UPDATE STDS_base SET revision = (revision + 1) WHERE id = "SPACETIME_ID";
+-- Number of registered maps
+UPDATE STDS_metadata SET number_of_maps = 
+       (SELECT count(id) FROM SPACETIME_NAME_GRASS_MAP_register)
+       WHERE id = "SPACETIME_ID";
+-- Update the temporal extent
+UPDATE STDS_absolute_time SET start_time = 
+       (SELECT min(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";
+UPDATE STDS_absolute_time SET end_time = 
+       (SELECT max(end_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";
+-- Update the spatial extent
+UPDATE STDS_spatial_extent SET north = 
+       (SELECT max(north) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+    		(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE STDS_spatial_extent SET south = 
+       (SELECT min(south) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+    		(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE STDS_spatial_extent SET east = 
+       (SELECT max(east) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+    		(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE STDS_spatial_extent SET west = 
+       (SELECT min(west) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+    		(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE STDS_spatial_extent SET top = 
+       (SELECT max(top) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+    		(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE STDS_spatial_extent SET bottom = 
+       (SELECT min(bottom) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+    		(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE STDS_spatial_extent SET proj = 
+       (SELECT min(proj) FROM GRASS_MAP_spatial_extent WHERE GRASS_MAP_spatial_extent.id IN 
+    		(SELECT id FROM SPACETIME_NAME_GRASS_MAP_register)
+       ) WHERE id = "SPACETIME_ID";

+ 51 - 0
lib/temporal/update_str3ds_metadata_template.sql

@@ -0,0 +1,51 @@
+--#############################################################################
+-- This SQL script is to update a space-time raster3d dataset metadata
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
+
+-- SPACETIME_NAME is a placeholder for specific stds name (SQL compliant): name_mapset
+-- SPACETIME_ID is a placeholder for specific stds id: name@mapset
+
+-- Update the min and max values
+UPDATE str3ds_metadata SET min_min = 
+       (SELECT min(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster3d_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE str3ds_metadata SET min_max = 
+       (SELECT max(min) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster3d_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE str3ds_metadata SET max_min = 
+       (SELECT min(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster3d_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE str3ds_metadata SET max_max = 
+       (SELECT max(max) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster3d_register)
+       ) WHERE id = "SPACETIME_ID";
+-- Update the resolution
+UPDATE str3ds_metadata SET nsres_min = 
+       (SELECT min(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster3d_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE str3ds_metadata SET nsres_max = 
+       (SELECT max(nsres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster3d_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE str3ds_metadata SET ewres_min = 
+       (SELECT min(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster3d_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE str3ds_metadata SET ewres_max = 
+       (SELECT max(ewres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster3d_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE str3ds_metadata SET tbres_min = 
+       (SELECT min(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster3d_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE str3ds_metadata SET tbres_max = 
+       (SELECT max(tbres) FROM raster3d_metadata WHERE raster3d_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster3d_register)
+       ) WHERE id = "SPACETIME_ID";

+ 43 - 0
lib/temporal/update_strds_metadata_template.sql

@@ -0,0 +1,43 @@
+--#############################################################################
+-- This SQL is to update a space-time raster dataset metadata
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################
+
+-- SPACETIME_NAME is a placeholder for specific stds name (SQL compliant): name_mapset
+-- SPACETIME_ID is a placeholder for specific stds id: name@mapset
+
+-- Update the min and max values
+UPDATE strds_metadata SET min_min = 
+       (SELECT min(min) FROM raster_metadata WHERE raster_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE strds_metadata SET min_max = 
+       (SELECT max(min) FROM raster_metadata WHERE raster_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE strds_metadata SET max_min = 
+       (SELECT min(max) FROM raster_metadata WHERE raster_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE strds_metadata SET max_max = 
+       (SELECT max(max) FROM raster_metadata WHERE raster_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster_register)
+       ) WHERE id = "SPACETIME_ID";
+-- Update the resolution
+UPDATE strds_metadata SET nsres_min = 
+       (SELECT min(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE strds_metadata SET nsres_max = 
+       (SELECT max(nsres) FROM raster_metadata WHERE raster_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE strds_metadata SET ewres_min = 
+       (SELECT min(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster_register)
+       ) WHERE id = "SPACETIME_ID";
+UPDATE strds_metadata SET ewres_max = 
+       (SELECT max(ewres) FROM raster_metadata WHERE raster_metadata.id IN 
+    		(SELECT id FROM SPACETIME_NAME_raster_register)
+       ) WHERE id = "SPACETIME_ID";

+ 6 - 0
lib/temporal/update_stvds_metadata_template.sql

@@ -0,0 +1,6 @@
+--#############################################################################
+-- This SQL script is for now a placeholder, till the vector metadata
+-- concept is clear
+--
+-- Author: Soeren Gebbert soerengebbert <at> googlemail <dot> com
+--#############################################################################

+ 22 - 0
temporal/Makefile

@@ -0,0 +1,22 @@
+MODULE_TOPDIR = ..
+
+SUBDIRS = \
+	t.create \
+	t.list \
+	t.info \
+	t.remove \
+	tr.register \
+	tr3.register \
+	tv.register \
+	tr.unregister \
+	tr3.unregister \
+	tv.unregister \
+
+PGM = tgisintro
+
+include $(MODULE_TOPDIR)/include/Make/Dir.make
+
+default: htmldir
+
+htmldir: parsubdirs
+

+ 4 - 4
temporal/t.list/t.list.py

@@ -5,7 +5,7 @@
 # MODULE:	t.list
 # MODULE:	t.list
 # AUTHOR(S):	Soeren Gebbert
 # AUTHOR(S):	Soeren Gebbert
 #               
 #               
-# PURPOSE:	List space time datasets
+# PURPOSE:	List space time and map datasets
 # COPYRIGHT:	(C) 2011 by the GRASS Development Team
 # COPYRIGHT:	(C) 2011 by the GRASS Development Team
 #
 #
 #		This program is free software under the GNU General Public
 #		This program is free software under the GNU General Public
@@ -33,7 +33,7 @@
 #%option
 #%option
 #% key: sort
 #% key: sort
 #% type: string
 #% type: string
-#% description: Sort the space time dataset by category
+#% description: Sort the space time dataset by category. Columns number_of_maps and granularity only available fpr space time datasets
 #% required: no
 #% required: no
 #% multiple: yes
 #% multiple: yes
 #% options: id, name, creator, mapset, number_of_maps, creation_time, modification_time, start_time, end_time, interval, north, south, west, east, granularity
 #% options: id, name, creator, mapset, number_of_maps, creation_time, modification_time, start_time, end_time, interval, north, south, west, east, granularity
@@ -43,10 +43,10 @@
 #%option
 #%option
 #% key: columns
 #% key: columns
 #% type: string
 #% type: string
-#% description: Which columns should be printed to stdout
+#% description: Which columns should be printed to stdout. Columns number_of_maps and granularity only available fpr space time datasets
 #% required: no
 #% required: no
 #% multiple: yes
 #% multiple: yes
-#% options: id, name, creator, mapset, number_of_maps, creation_time, modification_time, start_time, end_time, interval, north, south, west, east, granularity, all
+#% options: id, name, creator, mapset, number_of_maps, creation_time, modification_time, revision, start_time, end_time, interval, north, south, west, east, granularity, all
 #% answer: id
 #% answer: id
 #%end
 #%end
 
 

+ 12 - 12
temporal/t.remove/t.remove.py

@@ -5,7 +5,7 @@
 # MODULE:	t.remove
 # MODULE:	t.remove
 # AUTHOR(S):	Soeren Gebbert
 # AUTHOR(S):	Soeren Gebbert
 #               
 #               
-# PURPOSE:	Remove a space time raster dataset
+# PURPOSE:	Remove space time or map dataset
 # COPYRIGHT:	(C) 2011 by the GRASS Development Team
 # COPYRIGHT:	(C) 2011 by the GRASS Development Team
 #
 #
 #		This program is free software under the GNU General Public
 #		This program is free software under the GNU General Public
@@ -15,7 +15,7 @@
 #############################################################################
 #############################################################################
 
 
 #%module
 #%module
-#% description: Remove a space time and map datasets from temporal database
+#% description: Remove space time or map datasets from temporal database
 #% keywords: spacetime
 #% keywords: spacetime
 #% keywords: dataset
 #% keywords: dataset
 #% keywords: remove
 #% keywords: remove
@@ -62,24 +62,24 @@ def main():
             id = name
             id = name
 
 
         if type == "strds":
         if type == "strds":
-            sp = grass.space_time_raster_dataset(id)
+            ds = grass.space_time_raster_dataset(id)
         if type == "str3ds":
         if type == "str3ds":
-            sp = grass.space_time_raster3d_dataset(id)
+            ds = grass.space_time_raster3d_dataset(id)
         if type == "stvds":
         if type == "stvds":
-            sp = grass.space_time_vector_dataset(id)
+            ds = grass.space_time_vector_dataset(id)
         if type == "raster":
         if type == "raster":
-            sp = grass.raster_dataset(id)
+            ds = grass.raster_dataset(id)
         if type == "raster3d":
         if type == "raster3d":
-            sp = grass.raster3d_dataset(id)
+            ds = grass.raster3d_dataset(id)
         if type == "vector":
         if type == "vector":
-            sp = grass.vector_dataset(id)
+            ds = grass.vector_dataset(id)
 
 
-        if sp.is_in_db() == False:
-            grass.fatal("Dataset <" + name + "> not found in temporal database")
+        if ds.is_in_db() == False:
+            grass.fatal(ds.get_type() + " dataset <" + name + "> not found in temporal database")
 
 
         # We need to read some data from the temporal database
         # We need to read some data from the temporal database
-        sp.select()
-        sp.delete()
+        ds.select()
+        ds.delete()
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
     options, flags = grass.core.parser()
     options, flags = grass.core.parser()

+ 0 - 0
temporal/tgisintro.html


+ 23 - 0
temporal/tr.register/register_ECAD_maps_temp_mean_1995_2010.py

@@ -0,0 +1,23 @@
+# This is an example script how to register imported ECA&D temperature data for Europe
+# in the temporal database of grass assigning valid time 
+
+import grass.script as grass
+
+# Create the space time raster dataset with t.create
+dataset = "temp_mean_1995_2010_daily"
+
+grass.run_command("t.create", type="strds", dataset=dataset, granularity="1 days", semantic="continuous", temporal="absolute", title="European mean temperature 1995-2010", description="The european daily mean temperature 1995 - 2010 from ECA&D ")
+
+name = "temp_mean."
+maps=""
+#for i in range(6025):
+for i in range(365):
+    inc = i + 1
+    map_name = name + str(inc)
+    if i == 0:
+        maps += map_name
+    else:
+        maps += "," + map_name
+    
+# Register all maps at once
+grass.run_command("tr.register", dataset=dataset, maps=maps, start="1995-01-01", increment="1 days")

+ 4 - 2
temporal/tr.register/test.tr.register.sh

@@ -17,7 +17,6 @@ r.mapcalc --o expr="prec_4 = rand(0, 510)"
 r.mapcalc --o expr="prec_5 = rand(0, 300)"
 r.mapcalc --o expr="prec_5 = rand(0, 300)"
 r.mapcalc --o expr="prec_6 = rand(0, 650)"
 r.mapcalc --o expr="prec_6 = rand(0, 650)"
 
 
-
 # The first @test
 # The first @test
 # We create the space time raster datasets and register the raster maps with absolute time interval
 # We create the space time raster datasets and register the raster maps with absolute time interval
 
 
@@ -53,7 +52,10 @@ t.info type=strds dataset=precip_abs6
 
 
 tr.register dataset=precip_abs7 maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 start="2001-01-01" increment="20 years, 3 months, 1 days, 4 hours"
 tr.register dataset=precip_abs7 maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 start="2001-01-01" increment="20 years, 3 months, 1 days, 4 hours"
 t.info type=strds dataset=precip_abs7
 t.info type=strds dataset=precip_abs7
+# Register with different valid time again
+tr.register dataset=precip_abs7 maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 start="2001-01-01" increment="99 years, 9 months, 9 days, 9 hours"
+t.info type=strds dataset=precip_abs7
 
 
 t.remove --v type=raster dataset=prec_1,prec_2,prec_3
 t.remove --v type=raster dataset=prec_1,prec_2,prec_3
 t.remove --v type=strds dataset=precip_abs1,precip_abs2,precip_abs3,precip_abs4,precip_abs5,precip_abs6,precip_abs7
 t.remove --v type=strds dataset=precip_abs1,precip_abs2,precip_abs3,precip_abs4,precip_abs5,precip_abs6,precip_abs7
-t.remove --v type=raster dataset=prec_4,prec_5,prec_6
+t.remove --v type=raster dataset=prec_4,prec_5,prec_6

+ 7 - 70
temporal/tr.register/tr.register.py

@@ -5,7 +5,7 @@
 # MODULE:	tr.register
 # MODULE:	tr.register
 # AUTHOR(S):	Soeren Gebbert
 # AUTHOR(S):	Soeren Gebbert
 #
 #
-# PURPOSE:	Register a raster map in a space time raster dataset
+# PURPOSE:	Register raster maps in a space time raster dataset
 # COPYRIGHT:	(C) 2011 by the GRASS Development Team
 # COPYRIGHT:	(C) 2011 by the GRASS Development Team
 #
 #
 #		This program is free software under the GNU General Public
 #		This program is free software under the GNU General Public
@@ -39,7 +39,7 @@
 #%option
 #%option
 #% key: start
 #% key: start
 #% type: string
 #% type: string
-#% description: 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", format relative 5.0)
+#% description: The valid start date and time of the first raster map, in case the map has no valid time (format absolute: "yyyy-mm-dd HH:MM:SS", format relative 5.0)
 #% required: no
 #% required: no
 #% multiple: no
 #% multiple: no
 #%end
 #%end
@@ -47,16 +47,14 @@
 #%option
 #%option
 #% key: increment
 #% key: increment
 #% type: string
 #% type: string
-#% description: Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
+#% description: Time increment between maps for valid time interval creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
 #% required: no
 #% required: no
 #% multiple: no
 #% multiple: no
 #%end
 #%end
 
 
-import datetime
 import grass.script as grass
 import grass.script as grass
-from copy import *
-#######################
-#####################################################
+
+############################################################################
 
 
 def main():
 def main():
 
 
@@ -68,70 +66,9 @@ def main():
 
 
     # Make sure the temporal database exists
     # Make sure the temporal database exists
     grass.create_temporal_database()
     grass.create_temporal_database()
-
-    mapset =  grass.gisenv()["MAPSET"]
-    id = name + "@" + mapset
-
-    sp = grass.space_time_raster_dataset(id)
-    # Insert content from db
-    sp.select()
+    # Register maps
+    grass.register_maps_in_space_time_dataset("raster", name, maps, start, increment)
     
     
-    if sp.is_in_db() == False:
-        grass.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:
-        mapid = mapname + "@" + mapset
-        map = grass.raster_dataset(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() == False:
-            map.load()
-            map.insert()
-        else:
-            map.select()
-            if map.get_temporal_type() != sp.get_temporal_type():
-                grass.fatal("Unable to register map <" + map.get_id() + ">. The temporal types are different.")
-
-        # Set the time interval
-        if start:
-            
-            if sp.is_time_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.datetime.strptime(start, time_format)
-                end_time = None
-
-                # Add the increment
-                if increment:
-                    start_time = grass.increment_datetime_by_string(start_time, increment, count)
-                    end_time = grass.increment_datetime_by_string(start_time, increment, 1)
-
-                grass.verbose("Set absolute time interval for map <" + mapid + "> to " + str(start_time) + " - " + str(end_time))
-                map.update_absolute_time(start_time, end_time)
-            else:
-                if increment:
-                    interval = float(start) + count * float(increment)
-                else:
-                    interval = float(start)
-                grass.verbose("Set relative time interval for map <" + mapid + "> to " + str(interval))
-                map.update_relative_time(interval)
-            
-        # Register map
-        sp.register_map(map)
-        count += 1
-
 if __name__ == "__main__":
 if __name__ == "__main__":
     options, flags = grass.core.parser()
     options, flags = grass.core.parser()
     main()
     main()

+ 3 - 33
temporal/tr.unregister/tr.unregister.py

@@ -15,7 +15,7 @@
 #############################################################################
 #############################################################################
 
 
 #%module
 #%module
-#% description: Unregister raster map(s) from a specific or all space time raster dataset in which it is registered
+#% description: Unregister raster map(s) from a specific or from all space time raster dataset in which it is registered
 #% keywords: spacetime raster dataset
 #% keywords: spacetime raster dataset
 #% keywords: raster
 #% keywords: raster
 #%end
 #%end
@@ -47,38 +47,8 @@ def main():
 
 
     # Make sure the temporal database exists
     # Make sure the temporal database exists
     grass.create_temporal_database()
     grass.create_temporal_database()
-
-    mapset =  grass.gisenv()["MAPSET"]
-    
-    # In case a space time raster dataset is specified
-    if name:
-    
-        id = name + "@" + mapset
-
-        sp = grass.space_time_raster_dataset(id)
-        # Read content from db
-        sp.select()
-
-        if sp.is_in_db() == False:
-            grass.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:
-        mapid = mapname + "@" + mapset
-        map = grass.raster_dataset(mapid)
-
-        # Unregister map if in database
-        if map.is_in_db() == True:
-            if name:
-                sp.unregister_map(map)
-            else:
-                map.select()
-                map.unregister()
+    # Unregister maps
+    grass.unregister_maps_from_space_time_datasets("raster", name, maps)
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
     options, flags = grass.core.parser()
     options, flags = grass.core.parser()

+ 7 - 0
temporal/tr3.register/Makefile

@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../../
+
+PGM = tr3.register
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script $(TEST_DST)

+ 61 - 0
temporal/tr3.register/test.tr3.register.sh

@@ -0,0 +1,61 @@
+# This is a test to register and unregister raster3d maps in
+# space time raster3d dataset.
+# The raster3d maps will be registered in different space time raster3d
+# datasets
+
+# We need to set a specific region in the
+# @preprocess step of this test. We generate
+# 3d raster with r3.mapcalc and create two space time raster3d datasets
+# with relative and absolute time
+# The region setting should work for UTM and LL test locations
+g.region s=0 n=80 w=0 e=120 b=0 t=50 res=10 res3=10 -p3
+
+r3.mapcalc --o expr="volume_1 = rand(0, 550)"
+r3.mapcalc --o expr="volume_2 = rand(0, 450)"
+r3.mapcalc --o expr="volume_3 = rand(0, 320)"
+r3.mapcalc --o expr="volume_4 = rand(0, 510)"
+r3.mapcalc --o expr="volume_5 = rand(0, 300)"
+r3.mapcalc --o expr="volume_6 = rand(0, 650)"
+
+# The first @test
+# We create the space time raster3d datasets and register the raster3d maps with absolute time interval
+
+t.create --v --o type=str3ds temporaltype=absolute dataset=volume_abs1 gran="1 senconds" title="A test" descr="A test"
+t.create --v --o type=str3ds temporaltype=absolute dataset=volume_abs2 gran="1 minutes" title="A test" descr="A test"
+t.create --v --o type=str3ds temporaltype=absolute dataset=volume_abs3 gran="1 hours" title="A test" descr="A test"
+t.create --v --o type=str3ds temporaltype=absolute dataset=volume_abs4 gran="1 days" title="A test" descr="A test"
+t.create --v --o type=str3ds temporaltype=absolute dataset=volume_abs5 gran="1 weeks" title="A test" descr="A test"
+t.create --v --o type=str3ds temporaltype=absolute dataset=volume_abs6 gran="1 months" title="A test" descr="A test"
+t.create --v --o type=str3ds temporaltype=absolute dataset=volume_abs7 gran="1 years" title="A test" descr="A test"
+
+tr3.register --v dataset=volume_abs1 maps=volume_1,volume_2,volume_3,volume_4,volume_5,volume_6 start="2001-01-01" increment="1 seconds"
+t.info type=str3ds dataset=volume_abs1
+tr3.unregister --v dataset=volume_abs1 maps=volume_1,volume_2,volume_3,volume_4,volume_5,volume_6
+t.info type=str3ds dataset=volume_abs1
+
+tr3.register --v dataset=volume_abs2 maps=volume_1,volume_2,volume_3,volume_4,volume_5,volume_6 start="2001-01-01" increment="20 seconds, 5 minutes"
+t.info type=str3ds dataset=volume_abs2
+
+tr3.register --v dataset=volume_abs3 maps=volume_1,volume_2,volume_3,volume_4,volume_5,volume_6 start="2001-01-01" increment="8 hours"
+t.info type=str3ds dataset=volume_abs3
+tr3.unregister --v maps=volume_1,volume_2,volume_3,volume_4,volume_5,volume_6
+t.info type=str3ds dataset=volume_abs3
+
+tr3.register dataset=volume_abs4 maps=volume_1,volume_2,volume_3,volume_4,volume_5,volume_6 start="2001-01-01" increment="3 days"
+t.info type=str3ds dataset=volume_abs4
+
+tr3.register dataset=volume_abs5 maps=volume_1,volume_2,volume_3,volume_4,volume_5,volume_6 start="2001-01-01" increment="4 weeks"
+t.info type=str3ds dataset=volume_abs5
+
+tr3.register dataset=volume_abs6 maps=volume_1,volume_2,volume_3,volume_4,volume_5,volume_6 start="2001-08-01" increment="2 months"
+t.info type=str3ds dataset=volume_abs6
+
+tr3.register dataset=volume_abs7 maps=volume_1,volume_2,volume_3,volume_4,volume_5,volume_6 start="2001-01-01" increment="20 years, 3 months, 1 days, 4 hours"
+t.info type=str3ds dataset=volume_abs7
+# Register with different valid time again
+tr3.register dataset=volume_abs7 maps=volume_1,volume_2,volume_3,volume_4,volume_5,volume_6 start="2001-01-01" increment="99 years, 9 months, 9 days, 9 hours"
+t.info type=str3ds dataset=volume_abs7
+
+t.remove --v type=raster3d dataset=volume_1,volume_2,volume_3
+t.remove --v type=str3ds dataset=volume_abs1,volume_abs2,volume_abs3,volume_abs4,volume_abs5,volume_abs6,volume_abs7
+t.remove --v type=raster3d dataset=volume_4,volume_5,volume_6

+ 0 - 0
temporal/tr3.register/tr3.register.html


+ 75 - 0
temporal/tr3.register/tr3.register.py

@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+############################################################################
+#
+# MODULE:	tr3.register
+# AUTHOR(S):	Soeren Gebbert
+#
+# PURPOSE:	Register raster3d maps in a space time raster3d dataset
+# COPYRIGHT:	(C) 2011 by the GRASS Development Team
+#
+#		This program is free software under the GNU General Public
+#		License (version 2). Read the file COPYING that comes with GRASS
+#		for details.
+#
+#############################################################################
+
+#%module
+#% description: Register raster3d maps in a space time raster3d dataset
+#% keywords: spacetime raster dataset
+#% keywords: raster
+#%end
+
+#%option
+#% key: dataset
+#% type: string
+#% description: Name of an existing space time raster3d dataset
+#% required: yes
+#% multiple: no
+#%end
+
+#%option
+#% key: maps
+#% type: string
+#% description: Name(s) of existing raster3d map(s), multiple maps must be provided in temporal order in case datetime should be attached
+#% required: yes
+#% multiple: yes
+#%end
+
+#%option
+#% key: start
+#% type: string
+#% description: The valid start date and time of the first raster3d map, in case the map has no valid time (format absolute: "yyyy-mm-dd HH:MM:SS", format relative 5.0)
+#% required: no
+#% multiple: no
+#%end
+
+#%option
+#% key: increment
+#% type: string
+#% description: Time increment between maps for valid time interval creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
+#% required: no
+#% multiple: no
+#%end
+
+import grass.script as grass
+
+############################################################################
+
+def main():
+
+    # Get the options
+    name = options["dataset"]
+    maps = options["maps"]
+    start = options["start"]
+    increment = options["increment"]
+
+    # Make sure the temporal database exists
+    grass.create_temporal_database()
+    # Register maps
+    grass.register_maps_in_space_time_dataset("raster3d", name, maps, start, increment)
+    
+if __name__ == "__main__":
+    options, flags = grass.core.parser()
+    main()
+

+ 7 - 0
temporal/tr3.unregister/Makefile

@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../../
+
+PGM = tr3.unregister
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script $(TEST_DST)

+ 0 - 0
temporal/tr3.unregister/tr3.unregister.html


+ 56 - 0
temporal/tr3.unregister/tr3.unregister.py

@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+############################################################################
+#
+# MODULE:	tr3.unregister
+# AUTHOR(S):	Soeren Gebbert
+#               
+# PURPOSE:	Unregister raster3d maps from space time raster3d datasets
+# COPYRIGHT:	(C) 2011 by the GRASS Development Team
+#
+#		This program is free software under the GNU General Public
+#		License (version 2). Read the file COPYING that comes with GRASS
+#		for details.
+#
+#############################################################################
+
+#%module
+#% description: Unregister raster3d map(s) from a specific or from all space time raster3d dataset in which it is registered
+#% keywords: spacetime raster3d dataset
+#% keywords: raster3d
+#%end
+
+#%option
+#% key: dataset
+#% type: string
+#% description: Name of an existing space time raster3d dataset. If no name is provided the raster3d map(s) are unregistered from all space time datasets in which they are registered.
+#% required: no
+#% multiple: no
+#%end
+
+#%option
+#% key: maps
+#% type: string
+#% description: Name(s) of existing raster3d map(s) to unregister
+#% required: yes
+#% multiple: yes
+#%end
+
+import grass.script as grass
+############################################################################
+
+def main():
+
+    # Get the options
+    name = options["dataset"]
+    maps = options["maps"]
+
+    # Make sure the temporal database exists
+    grass.create_temporal_database()
+    # Unregister maps
+    grass.unregister_maps_from_space_time_datasets("raster3d", name, maps)
+
+if __name__ == "__main__":
+    options, flags = grass.core.parser()
+    main()
+

+ 7 - 0
temporal/tv.register/Makefile

@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../../
+
+PGM = tv.register
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script $(TEST_DST)

+ 61 - 0
temporal/tv.register/test.tv.register.sh

@@ -0,0 +1,61 @@
+# This is a test to register and unregister vector maps in
+# space time vector dataset.
+# The vector maps will be registered in different space time vector
+# datasets
+
+# We need to set a specific region in the
+# @preprocess step of this test. We generate
+# vector with v.random and create several space time vector datasets
+# with absolute time
+# The region setting should work for UTM and LL test locations
+g.region s=0 n=80 w=0 e=120 b=0 t=50 res=10 res3=10 -p3
+
+v.random --o -z output=lidar_abs_1 n=20 zmin=0 zmax=100 column=height
+v.random --o -z output=lidar_abs_2 n=20 zmin=0 zmax=100 column=height
+v.random --o -z output=lidar_abs_3 n=20 zmin=0 zmax=100 column=height
+v.random --o -z output=lidar_abs_4 n=20 zmin=0 zmax=100 column=height
+v.random --o -z output=lidar_abs_5 n=20 zmin=0 zmax=100 column=height
+v.random --o -z output=lidar_abs_6 n=20 zmin=0 zmax=100 column=height
+
+# The first @test
+# We create the space time vector datasets and register the vector maps with absolute time interval
+
+t.create --v --o type=stvds temporaltype=absolute dataset=lidar_abs_ds1 gran="1 senconds" title="A test" descr="A test"
+t.create --v --o type=stvds temporaltype=absolute dataset=lidar_abs_ds2 gran="1 minutes" title="A test" descr="A test"
+t.create --v --o type=stvds temporaltype=absolute dataset=lidar_abs_ds3 gran="1 hours" title="A test" descr="A test"
+t.create --v --o type=stvds temporaltype=absolute dataset=lidar_abs_ds4 gran="1 days" title="A test" descr="A test"
+t.create --v --o type=stvds temporaltype=absolute dataset=lidar_abs_ds5 gran="1 weeks" title="A test" descr="A test"
+t.create --v --o type=stvds temporaltype=absolute dataset=lidar_abs_ds6 gran="1 months" title="A test" descr="A test"
+t.create --v --o type=stvds temporaltype=absolute dataset=lidar_abs_ds7 gran="1 years" title="A test" descr="A test"
+
+tv.register --v dataset=lidar_abs_ds1 maps=lidar_abs_1,lidar_abs_2,lidar_abs_3,lidar_abs_4,lidar_abs_5,lidar_abs_6 start="2001-01-01" increment="1 seconds"
+t.info type=stvds dataset=lidar_abs_ds1
+tv.unregister --v dataset=lidar_abs_ds1 maps=lidar_abs_1,lidar_abs_2,lidar_abs_3,lidar_abs_4,lidar_abs_5,lidar_abs_6
+t.info type=stvds dataset=lidar_abs_ds1
+
+tv.register --v dataset=lidar_abs_ds2 maps=lidar_abs_1,lidar_abs_2,lidar_abs_3,lidar_abs_4,lidar_abs_5,lidar_abs_6 start="2001-01-01" increment="20 seconds, 5 minutes"
+t.info type=stvds dataset=lidar_abs_ds2
+
+tv.register --v dataset=lidar_abs_ds3 maps=lidar_abs_1,lidar_abs_2,lidar_abs_3,lidar_abs_4,lidar_abs_5,lidar_abs_6 start="2001-01-01" increment="8 hours"
+t.info type=stvds dataset=lidar_abs_ds3
+tv.unregister --v maps=lidar_abs_1,lidar_abs_2,lidar_abs_3,lidar_abs_4,lidar_abs_5,lidar_abs_6
+t.info type=stvds dataset=lidar_abs_ds3
+
+tv.register dataset=lidar_abs_ds4 maps=lidar_abs_1,lidar_abs_2,lidar_abs_3,lidar_abs_4,lidar_abs_5,lidar_abs_6 start="2001-01-01" increment="3 days"
+t.info type=stvds dataset=lidar_abs_ds4
+
+tv.register dataset=lidar_abs_ds5 maps=lidar_abs_1,lidar_abs_2,lidar_abs_3,lidar_abs_4,lidar_abs_5,lidar_abs_6 start="2001-01-01" increment="4 weeks"
+t.info type=stvds dataset=lidar_abs_ds5
+
+tv.register dataset=lidar_abs_ds6 maps=lidar_abs_1,lidar_abs_2,lidar_abs_3,lidar_abs_4,lidar_abs_5,lidar_abs_6 start="2001-08-01" increment="2 months"
+t.info type=stvds dataset=lidar_abs_ds6
+
+tv.register dataset=lidar_abs_ds7 maps=lidar_abs_1,lidar_abs_2,lidar_abs_3,lidar_abs_4,lidar_abs_5,lidar_abs_6 start="2001-01-01" increment="20 years, 3 months, 1 days, 4 hours"
+t.info type=stvds dataset=lidar_abs_ds7
+# Register with different valid time again
+tv.register dataset=lidar_abs_ds7 maps=lidar_abs_1,lidar_abs_2,lidar_abs_3,lidar_abs_4,lidar_abs_5,lidar_abs_6 start="2001-01-01" increment="99 years, 9 months, 9 days, 9 hours"
+t.info type=stvds dataset=lidar_abs_ds7
+
+t.remove --v type=vector dataset=lidar_abs_1,lidar_abs_2,lidar_abs_3
+t.remove --v type=stvds dataset=lidar_abs_ds1,lidar_abs_ds2,lidar_abs_ds3,lidar_abs_ds4,lidar_abs_ds5,lidar_abs_ds6,lidar_abs_ds7
+t.remove --v type=vector dataset=lidar_abs_4,lidar_abs_5,lidar_abs_6

+ 0 - 0
temporal/tv.register/tv.register.html


+ 75 - 0
temporal/tv.register/tv.register.py

@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+############################################################################
+#
+# MODULE:	tv.register
+# AUTHOR(S):	Soeren Gebbert
+#
+# PURPOSE:	Register vector maps in a space time vector dataset
+# COPYRIGHT:	(C) 2011 by the GRASS Development Team
+#
+#		This program is free software under the GNU General Public
+#		License (version 2). Read the file COPYING that comes with GRASS
+#		for details.
+#
+#############################################################################
+
+#%module
+#% description: Register vector maps in a space time vector dataset
+#% keywords: spacetime vector dataset
+#% keywords: vector
+#%end
+
+#%option
+#% key: dataset
+#% type: string
+#% description: Name of an existing space time vector dataset
+#% required: yes
+#% multiple: no
+#%end
+
+#%option
+#% key: maps
+#% type: string
+#% description: Name(s) of existing vector map(s), multiple maps must be provided in temporal order in case datetime should be attached
+#% required: yes
+#% multiple: yes
+#%end
+
+#%option
+#% key: start
+#% type: string
+#% description: The valid start date and time of the first vector map, in case the map has no valid time (format absolute: "yyyy-mm-dd HH:MM:SS", format relative 5.0)
+#% required: no
+#% multiple: no
+#%end
+
+#%option
+#% key: increment
+#% type: string
+#% description: Time increment between maps for valid time interval creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
+#% required: no
+#% multiple: no
+#%end
+
+import grass.script as grass
+
+############################################################################
+
+def main():
+
+    # Get the options
+    name = options["dataset"]
+    maps = options["maps"]
+    start = options["start"]
+    increment = options["increment"]
+
+    # Make sure the temporal database exists
+    grass.create_temporal_database()
+    # Register maps
+    grass.register_maps_in_space_time_dataset("vector", name, maps, start, increment)
+    
+if __name__ == "__main__":
+    options, flags = grass.core.parser()
+    main()
+

+ 7 - 0
temporal/tv.unregister/Makefile

@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../../
+
+PGM = tv.unregister
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script $(TEST_DST)

+ 0 - 0
temporal/tv.unregister/tv.unregister.html


+ 56 - 0
temporal/tv.unregister/tv.unregister.py

@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+############################################################################
+#
+# MODULE:	tv.unregister
+# AUTHOR(S):	Soeren Gebbert
+#               
+# PURPOSE:	Unregister vector maps from space time vector datasets
+# COPYRIGHT:	(C) 2011 by the GRASS Development Team
+#
+#		This program is free software under the GNU General Public
+#		License (version 2). Read the file COPYING that comes with GRASS
+#		for details.
+#
+#############################################################################
+
+#%module
+#% description: Unregister vector map(s) from a specific or from all space time vector datasets in which it is registered
+#% keywords: spacetime vector dataset
+#% keywords: vector
+#%end
+
+#%option
+#% key: dataset
+#% type: string
+#% description: Name of an existing space time vector dataset. If no name is provided the vector map(s) are unregistered from all space time datasets in which they are registered.
+#% required: no
+#% multiple: no
+#%end
+
+#%option
+#% key: maps
+#% type: string
+#% description: Name(s) of existing vector map(s) to unregister
+#% required: yes
+#% multiple: yes
+#%end
+
+import grass.script as grass
+############################################################################
+
+def main():
+
+    # Get the options
+    name = options["dataset"]
+    maps = options["maps"]
+
+    # Make sure the temporal database exists
+    grass.create_temporal_database()
+    # Unregister maps
+    grass.unregister_maps_from_space_time_datasets("vector", name, maps)
+
+if __name__ == "__main__":
+    options, flags = grass.core.parser()
+    main()
+