Просмотр исходного кода

Fixed missing imports. Added two new modules for temporally shifting and snapping. Improved doxygen docs.

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@55928 15284696-431f-4ddb-bdfa-cd5b030d7da7
Soeren Gebbert 12 лет назад
Родитель
Сommit
89c3a2022b

+ 19 - 5
lib/python/temporal/abstract_dataset.py

@@ -401,17 +401,31 @@ class AbstractDataset(object):
         else:
         else:
             return None
             return None
 
 
-    def temporal_relation(self, map):
+    def temporal_relation(self, dataset):
         """!Return the temporal relation of self and the provided dataset
         """!Return the temporal relation of self and the provided dataset
         
         
             @return The temporal relation as string
             @return The temporal relation as string
         """
         """
-        if self.is_time_absolute() and map.is_time_absolute():
-            return self.absolute_time.temporal_relation(map.absolute_time)
-        if self.is_time_relative() and map.is_time_relative():
-            return self.relative_time.temporal_relation(map.relative_time)
+        if self.is_time_absolute() and dataset.is_time_absolute():
+            return self.absolute_time.temporal_relation(dataset.absolute_time)
+        if self.is_time_relative() and dataset.is_time_relative():
+            return self.relative_time.temporal_relation(dataset.relative_time)
         return None
         return None
 
 
+    def temporal_intersection(self, dataset):
+        """!Intersect self with the provided datasetand
+           return a new temporal extent with the new start and end time
+           
+           @param dataset The abstract dataset to temporal intersect with
+           @return The new temporal extent with start and end time, 
+                   or None in case of no intersection
+        """
+        if self.is_time_absolute() and dataset.is_time_absolute():
+            return self.absolute_time.intersect(dataset.absolute_time)
+        if self.is_time_relative() and dataset.is_time_relative():
+            return self.relative_time.intersect(dataset.relative_time)
+        return None
+        
 ###############################################################################
 ###############################################################################
 
 
 class AbstractDatasetComparisonKeyStartTime(object):
 class AbstractDatasetComparisonKeyStartTime(object):

+ 136 - 2
lib/python/temporal/abstract_space_time_dataset.py

@@ -19,7 +19,6 @@ from temporal_relationships import *
 
 
 ###############################################################################
 ###############################################################################
 
 
-
 class AbstractSpaceTimeDataset(AbstractDataset):
 class AbstractSpaceTimeDataset(AbstractDataset):
     """!Abstract space time dataset class
     """!Abstract space time dataset class
 
 
@@ -1079,7 +1078,142 @@ class AbstractSpaceTimeDataset(AbstractDataset):
             dbif.close()
             dbif.close()
 
 
         return rows
         return rows
-
+        
+    def shift(self, gran, dbif=None):
+        """!Temporally shift each registered map with the provided granularity
+        
+           @param gran The granularity to be used for shifting
+           @param dbif The database interface to be used
+           @return True something to shift, False nothing to shift or wrong granularity
+        
+        """
+        if not check_granularity_string(gran, self.get_temporal_type()):
+            self.error(_("Wrong granularity format: %s"%(gran)))
+            return False
+            
+        dbif, connected = init_dbif(dbif)
+        
+        maps = self.get_registered_maps_as_objects(dbif=dbif)
+        
+        if maps is None:
+            return False
+            
+        date_list = []
+        
+        # We need to make a dry run to avoid a break 
+        # in the middle of the update process when the increment
+        # results in wrong number of days in a month
+        for map in maps:
+            start, end = map.get_valid_time()
+            
+            if self.is_time_absolute():
+                start = increment_datetime_by_string(start, gran)
+                if end is not None:
+                    end = increment_datetime_by_string(end, gran)
+            elif self.is_time_relative():
+                start = start + int(gran)
+                if end is not None:
+                    end = end + int(gran)
+                    
+            date_list.append((start, end))
+            
+        self. _update_map_timestamps(maps, date_list, dbif)
+            
+        if connected:
+            dbif.close()
+            
+        return True
+        
+    def snap(self, dbif=None):
+        """!For each registered map snap the end time to the start time of its 
+           temporal nearest neighbor in the future
+           
+           Maps with equal time stamps are not snapped
+        
+           @param dbif The database interface to be used
+        
+        """
+        dbif, connected = init_dbif(dbif)
+        
+        maps = self.get_registered_maps_as_objects(dbif=dbif)
+        
+        if maps is None:
+            return
+            
+        date_list = []
+        
+        for i in range(len(maps) - 1):
+            start, end = maps[i].get_valid_time()
+            start_next, end = maps[i + 1].get_valid_time()
+            
+            # Maps with equal time stamps can not be snapped
+            if start != start_next:
+                date_list.append((start, start_next))
+            else:
+                # Keep the original time stamps
+                date_list.append((start, end))
+        
+        # Last map
+        start, end = maps[-1].get_valid_time()
+        # We increment the start time with the dataset 
+        # granularity if the end time is None
+        if end is None:
+            if self.is_time_absolute():
+                end =  increment_datetime_by_string(start, self.get_granularity())
+            elif self.is_time_relative():
+                end = start + self.get_granularity()
+        
+        date_list.append((start, end))
+        
+        self. _update_map_timestamps(maps, date_list, dbif)
+        
+        if connected:
+            dbif.close()
+            
+    def _update_map_timestamps(self, maps, date_list, dbif):
+        """!Update the timestamps of maps with the start and end time
+           stored in the date_list.
+           
+           The number of dates in the list must be equal to the number
+           of maps.
+           
+           @param maps A list of map objects
+           @param date_list A list with date tuples (start_time, end_time)
+           @param dbif The database interface to be used
+        """
+    
+        datatsets_to_modify = {}
+        # Now update the maps
+        count = 0
+        for map in maps:
+            start = date_list[count][0]
+            end   = date_list[count][1]
+            map.select(dbif)
+            count += 1
+            
+            if self.is_time_absolute():
+                map.update_absolute_time(start_time=start, end_time=end, dbif=dbif)
+            elif self.is_time_relative():
+                map.update_relative_time(start_time=start, end_time=end,
+                                         unit=self.get_relative_time_unit(), dbif=dbif)
+                
+            # Save the datasets that must be updated
+            datasets = map.get_registered_datasets(dbif)
+            if datasets:
+                for dataset in datasets:
+                    datatsets_to_modify[dataset["id"]] = dataset["id"]
+        
+        self.update_from_registered_maps(dbif)
+        
+        # Update affected datasets
+        if datatsets_to_modify:
+            for dataset in datatsets_to_modify:
+                if dataset != self.get_id():
+                    ds = self.get_new_instance(ident=dataset)
+                    ds.select(dbif)
+                    ds.update_from_registered_maps(dbif)
+            
+        
     def rename(self, ident, dbif=None):
     def rename(self, ident, dbif=None):
         """!Rename the space time dataset
         """!Rename the space time dataset
 
 

+ 1 - 0
lib/python/temporal/create.py

@@ -23,6 +23,7 @@ for details.
 """
 """
 
 
 from space_time_datasets import *
 from space_time_datasets import *
+from factory import *
 
 
 ###############################################################################
 ###############################################################################
 
 

+ 6 - 1
lib/python/temporal/datetime_math.py

@@ -186,7 +186,12 @@ def increment_datetime(mydate, years=0, months=0, weeks=0, days=0, hours=0,
         if residual_months == 0:
         if residual_months == 0:
             residual_months = 1
             residual_months = 1
 
 
-        dt1 = dt1.replace(year=year + years_to_add, month=residual_months)
+        try:
+            dt1 = dt1.replace(year=year + years_to_add, month=residual_months)
+        except:
+            core.fatal(_("Unable to increment the datetime %s. "\
+                         "Please check that the yearly or monthly increment does not result in wrong number of days."%(mydate)))
+
         tdelta_months = dt1 - mydate
         tdelta_months = dt1 - mydate
 
 
     if years > 0:
     if years > 0:

+ 1 - 0
lib/python/temporal/gui_support.py

@@ -14,6 +14,7 @@ for details.
 """
 """
 
 
 from space_time_datasets import *
 from space_time_datasets import *
+from factory import *
 
 
 ###############################################################################
 ###############################################################################
 
 

+ 1 - 0
lib/python/temporal/list.py

@@ -23,6 +23,7 @@ for details.
 """
 """
 
 
 from space_time_datasets import *
 from space_time_datasets import *
+from factory import *
 
 
 ###############################################################################
 ###############################################################################
 
 

+ 31 - 0
lib/python/temporal/pythontemporallib.dox

@@ -204,6 +204,37 @@ dbif.close()
     
     
 \endcode
 \endcode
 
 
+\subsevtion PythonTGISExamplesShifting Temporal shifting
+
+\code
+
+import grass.script as grass
+import grass.temporal as tgis
+
+id="test@PERMANENT"
+type="strds"
+
+# Make sure the temporal database exists
+tgis.init()
+
+dbif = tgis.SQLDatabaseInterfaceConnection()
+dbif.connect()
+
+stds = tgis.dataset_factory(type, id)
+
+if stds.is_in_db(dbif) == False:
+    dbif.close()
+    grass.fatal(_("Space time dataset <%s> not found in temporal database") % (id))
+
+stds.select(dbif=dbif)
+
+stds.snap(dbif=dbif)
+
+stds.update_command_string(dbif=dbif)
+dbif.close()
+
+\endcode
+
 \section PythonTGISAuthors Authors
 \section PythonTGISAuthors Authors
 
 
 Soeren Gebbert
 Soeren Gebbert

+ 1 - 0
lib/python/temporal/register.py

@@ -23,6 +23,7 @@ for details.
 """
 """
 
 
 from space_time_datasets import *
 from space_time_datasets import *
+from factory import *
 
 
 ###############################################################################
 ###############################################################################
 
 

+ 1 - 0
lib/python/temporal/sampling.py

@@ -23,6 +23,7 @@ for details.
 """
 """
 
 
 from space_time_datasets import *
 from space_time_datasets import *
+from factory import *
 
 
 ###############################################################################
 ###############################################################################
 
 

+ 3 - 1
lib/python/temporal/stds_export.py

@@ -32,7 +32,9 @@ import shutil
 import os
 import os
 import tarfile
 import tarfile
 import tempfile
 import tempfile
-from space_time_datasets_tools import *
+
+from space_time_datasets import *
+from factory import *
 
 
 proj_file_name = "proj.txt"
 proj_file_name = "proj.txt"
 init_file_name = "init.txt"
 init_file_name = "init.txt"

+ 7 - 3
lib/python/temporal/stds_import.py

@@ -39,8 +39,12 @@ import tarfile
 import tempfile
 import tempfile
 import time
 import time
 import filecmp
 import filecmp
-import space_time_datasets_tools
-from space_time_datasets_tools import *
+
+import core
+from space_time_datasets import *
+from register import *
+import factory
+from factory import *
 
 
 proj_file_name = "proj.txt"
 proj_file_name = "proj.txt"
 init_file_name = "init.txt"
 init_file_name = "init.txt"
@@ -249,7 +253,7 @@ def import_stds(
 
 
     try:
     try:
         # Make sure the temporal database exists
         # Make sure the temporal database exists
-        space_time_datasets_tools.init()
+        factory.init()
 
 
         fs = "|"
         fs = "|"
         maplist = []
         maplist = []

+ 128 - 15
lib/python/temporal/temporal_extent.py

@@ -83,6 +83,119 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
         self.set_start_time(start_time)
         self.set_start_time(start_time)
         self.set_end_time(end_time)
         self.set_end_time(end_time)
 
 
+    def intersect(self, extent):
+        """!Intersect this temporal extent with the provided temporal extent and
+           return a new temporal extent with the new start and end time
+           
+           @param extent The temporal extent to intersect with
+           @return The new temporal extent with start and end time, 
+                   or None in case of no intersection
+           
+           Usage:
+           
+           @code
+
+           >>> A = AbstractTemporalExtent(start_time=5, end_time=6 )
+           >>> inter = A.intersect(A)
+           >>> inter.print_info()
+            | Start time:................. 5
+            | End time:................... 6
+            
+           >>> A = AbstractTemporalExtent(start_time=5, end_time=6 )
+           >>> B = AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> inter = A.intersect(B)
+           >>> inter.print_info()
+            | Start time:................. 5
+            | End time:................... 6
+           >>> inter = B.intersect(A)
+           >>> inter.print_info()
+            | Start time:................. 5
+            | End time:................... 6
+             
+           >>> A = AbstractTemporalExtent(start_time=3, end_time=6 )
+           >>> B = AbstractTemporalExtent(start_time=5, end_time=7 )
+           >>> inter = A.intersect(B)
+           >>> inter.print_info()
+            | Start time:................. 5
+            | End time:................... 6
+           >>> inter = B.intersect(A)
+           >>> inter.print_info()
+            | Start time:................. 5
+            | End time:................... 6
+             
+           >>> A = AbstractTemporalExtent(start_time=3, end_time=8 )
+           >>> B = AbstractTemporalExtent(start_time=5, end_time=6 )
+           >>> inter = A.intersect(B)
+           >>> inter.print_info()
+            | Start time:................. 5
+            | End time:................... 6
+           >>> inter = B.intersect(A)
+           >>> inter.print_info()
+            | Start time:................. 5
+            | End time:................... 6
+            
+           >>> A = AbstractTemporalExtent(start_time=5, end_time=8 )
+           >>> B = AbstractTemporalExtent(start_time=3, end_time=6 )
+           >>> inter = A.intersect(B)
+           >>> inter.print_info()
+            | Start time:................. 5
+            | End time:................... 6
+           >>> inter = B.intersect(A)
+           >>> inter.print_info()
+            | Start time:................. 5
+            | End time:................... 6
+
+           >>> A = AbstractTemporalExtent(start_time=5, end_time=None )
+           >>> B = AbstractTemporalExtent(start_time=3, end_time=6 )
+           >>> inter = A.intersect(B)
+           >>> inter.print_info()
+            | Start time:................. 5
+            | End time:................... None
+           >>> inter = B.intersect(A)
+           >>> inter.print_info()
+            | Start time:................. 5
+            | End time:................... None
+            
+           >>> A = AbstractTemporalExtent(start_time=5, end_time=8 )
+           >>> B = AbstractTemporalExtent(start_time=3, end_time=4 )
+           >>> inter = A.intersect(B)
+           >>> print inter
+           None
+           
+           >>> A = AbstractTemporalExtent(start_time=5, end_time=8 )
+           >>> B = AbstractTemporalExtent(start_time=3, end_time=None )
+           >>> inter = A.intersect(B)
+           >>> print inter
+           None
+           
+           @endcode
+        """
+        relation = self.temporal_relation(extent)
+        
+        if relation == "after" or relation == "before":
+            return None
+        
+        if self.D["end_time"] is None:
+            return AbstractTemporalExtent(start_time=self.D["start_time"])
+            
+        if extent.D["end_time"] is None:
+            return AbstractTemporalExtent(start_time=extent.D["start_time"])
+        
+        start = None
+        end = None
+        
+        if self.D["start_time"] > extent.D["start_time"]:
+            start = self.D["start_time"]
+        else:
+            start = extent.D["start_time"]
+            
+        if self.D["end_time"] > extent.D["end_time"]:
+            end = extent.D["end_time"]
+        else:
+            end = self.D["end_time"]
+        
+        return AbstractTemporalExtent(start_time=start, end_time=end)
+        
     def starts(self, extent):
     def starts(self, extent):
         """!Return True if this temporal extent (A) starts at the start of the 
         """!Return True if this temporal extent (A) starts at the start of the 
            provided temporal extent (B) and finishes within it
            provided temporal extent (B) and finishes within it
@@ -91,7 +204,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B  |---------|
            B  |---------|
            @endverbatim
            @endverbatim
            
            
-           @param extent: The temporal extent object with which this extent starts
+           @param extent The temporal extent object with which this extent starts
            
            
            Usage:
            Usage:
            
            
@@ -123,7 +236,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B  |-----|
            B  |-----|
            @endverbatim
            @endverbatim
            
            
-           @param extent: The temporal extent object with which this extent started
+           @param extent The temporal extent object with which this extent started
            
            
            Usage:
            Usage:
            
            
@@ -155,7 +268,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B  |---------|
            B  |---------|
            @endverbatim
            @endverbatim
            
            
-           @param extent: The temporal extent object with which this extent finishes
+           @param extent The temporal extent object with which this extent finishes
            
            
            Usage:
            Usage:
            
            
@@ -187,7 +300,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B      |-----|
            B      |-----|
            @endverbatim
            @endverbatim
            
            
-           @param extent: The temporal extent object with which this extent finishes
+           @param extent The temporal extent object with which this extent finishes
            
            
            Usage:
            Usage:
            
            
@@ -219,7 +332,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B  |---------|
            B  |---------|
            @endverbatim
            @endverbatim
            
            
-           @param extent: The temporal extent object that is located before this extent
+           @param extent The temporal extent object that is located before this extent
            
            
            Usage:
            Usage:
            
            
@@ -253,7 +366,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B             |---------|
            B             |---------|
            @endverbatim
            @endverbatim
            
            
-           @param extent: The temporal extent object that is located after this extent
+           @param extent The temporal extent object that is located after this extent
            
            
            Usage:
            Usage:
            
            
@@ -289,7 +402,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B            |---------|
            B            |---------|
            @endverbatim
            @endverbatim
            
            
-           @param extent: The temporal extent object that is a meeting neighbor
+           @param extent The temporal extent object that is a meeting neighbor
                           of this extent
                           of this extent
            
            
            Usage:
            Usage:
@@ -328,7 +441,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B  |---------|
            B  |---------|
            @endverbatim
            @endverbatim
            
            
-           @param extent: The temporal extent object that is the predecessor
+           @param extent The temporal extent object that is the predecessor
                           of this extent
                           of this extent
            
            
            Usage:
            Usage:
@@ -360,7 +473,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B            |---------|
            B            |---------|
            @endverbatim
            @endverbatim
            
            
-           @param extent: The temporal extent object that is the successor
+           @param extent The temporal extent object that is the successor
                           of this extent
                           of this extent
            
            
            Usage:
            Usage:
@@ -392,7 +505,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B  |---------|
            B  |---------|
            @endverbatim
            @endverbatim
                       
                       
-           @param extent: The temporal extent object that contains this extent
+           @param extent The temporal extent object that contains this extent
            
            
            Usage:
            Usage:
            
            
@@ -433,7 +546,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B   |-------|
            B   |-------|
            @endverbatim
            @endverbatim
            
            
-           @param extent: The temporal extent object that is located 
+           @param extent The temporal extent object that is located 
                           during this extent
                           during this extent
            
            
            Usage:
            Usage:
@@ -475,7 +588,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B  |---------|
            B  |---------|
            @endverbatim
            @endverbatim
            
            
-           @param extent: The temporal extent object that is equal 
+           @param extent The temporal extent object that is equal 
                           during this extent
                           during this extent
            
            
            Usage:
            Usage:
@@ -513,7 +626,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            A  |---------|
            A  |---------|
            B    |---------|
            B    |---------|
            @endverbatim
            @endverbatim
-           @param extent: The temporal extent object that is overlaps 
+           @param extent The temporal extent object that is overlaps 
                           this extent
                           this extent
            
            
            Usage:
            Usage:
@@ -547,7 +660,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
            B  |---------|
            B  |---------|
            @endverbatim
            @endverbatim
            
            
-           @param extent: The temporal extent object that is overlapped 
+           @param extent The temporal extent object that is overlapped 
                           this extent
                           this extent
            
            
            Usage:
            Usage:
@@ -594,7 +707,7 @@ class AbstractTemporalExtent(SQLDatabaseInterface):
                - follows
                - follows
                - precedes
                - precedes
            
            
-           @param extent: The temporal extent 
+           @param extent The temporal extent 
            @return The name of the temporal relation or None if no relation found
            @return The name of the temporal relation or None if no relation found
         """
         """
 
 

+ 2 - 1
lib/python/temporal/univar_statistics.py

@@ -23,7 +23,8 @@ for details.
 @author Soeren Gebbert
 @author Soeren Gebbert
 """
 """
 
 
-from space_time_datasets_tools import *
+from space_time_datasets import *
+from factory import *
 
 
 ###############################################################################
 ###############################################################################
 
 

+ 2 - 0
temporal/Makefile

@@ -29,6 +29,8 @@ SUBDIRS = \
 	t.rast3d.mapcalc \
 	t.rast3d.mapcalc \
 	t.rast3d.univar \
 	t.rast3d.univar \
 	t.rename \
 	t.rename \
+	t.snap \
+	t.shift \
 	t.vect.list \
 	t.vect.list \
 	t.vect.db.select \
 	t.vect.db.select \
 	t.vect.export \
 	t.vect.export \

+ 2 - 2
temporal/t.info/t.info.py

@@ -64,7 +64,7 @@ def main():
     tgis.init()
     tgis.init()
     
     
     dbif = tgis.SQLDatabaseInterfaceConnection()
     dbif = tgis.SQLDatabaseInterfaceConnection()
-
+    
     if system and not shellstyle:
     if system and not shellstyle:
         #      0123456789012345678901234567890
         #      0123456789012345678901234567890
         print " +------------------- Temporal DBMI backend information ----------------------+"
         print " +------------------- Temporal DBMI backend information ----------------------+"
@@ -80,7 +80,7 @@ def main():
         print "dbmi_init_string=" + str(tgis.get_temporal_dbmi_init_string())
         print "dbmi_init_string=" + str(tgis.get_temporal_dbmi_init_string())
         print "sql_template_path=" + str(tgis.get_sql_template_path())
         print "sql_template_path=" + str(tgis.get_sql_template_path())
         return
         return
-
+        
     if not system and not name:
     if not system and not name:
         grass.fatal(_("Please specify %s=") % ("name"))
         grass.fatal(_("Please specify %s=") % ("name"))
 
 

+ 7 - 0
temporal/t.shift/Makefile

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

+ 188 - 0
temporal/t.shift/t.shift.html

@@ -0,0 +1,188 @@
+<h2>DESCRIPTION</h2>
+
+<em>t.shift</em> is designed to temporally shift all registered maps in a space time dataset
+with a user defined granularity. Raster, 3D raster and vector space time datasets are supported.
+<p>
+The format of the absolute time granularity is "number unit". Number is an integer, unit is the temporal
+unit that can be one of year(s), month(s), week(s), day(s), hour(s), minute(s) or second(s).
+<p>
+The granularity in case of relative time is an integer. The temporal unit is the unit of the space time dataset
+and can not be modified.
+
+<h2>Note</h2>
+Be careful when shifting space time datasets with absolute time.
+The temporal granularity may change if you shift a space time dataset with a unit that is
+different from the space time dataset granularity. Be aware that the shifting with months and years
+may result in incorrect days per month. Shifting the date 20012-03-31 with a granularity 
+of one month will result in 2012-04-31 which is incorrect. In this case an error will raise
+and the shifting will not performed for the whole dataset.
+<p>
+You can use the extraction module to shift only a subset of maps from a space time dataset.
+Be aware that the shifting of maps affect all space time datasets in which they are registered.
+
+<h2>EXAMPLE</h2>
+
+We create 6 raster maps and register them in a space time raster dataset using an increment of one day.
+Then we shift the time intervals with a granularity of 12 hours.
+
+<div class="code"><pre>
+
+r.mapcalc expr="prec_1 = rand(0, 550)"
+r.mapcalc expr="prec_2 = rand(0, 450)"
+r.mapcalc expr="prec_3 = rand(0, 320)"
+r.mapcalc expr="prec_4 = rand(0, 510)"
+r.mapcalc expr="prec_5 = rand(0, 300)"
+r.mapcalc expr="prec_6 = rand(0, 650)"
+
+t.create type=strds temporaltype=absolute \
+         output=precipitation_daily \
+         title="Daily precipitation" \
+         description="Test dataset with daily precipitation"
+
+t.register -i type=rast input=precipitation_daily \
+           maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 \
+           start=2012-01-01 increment="1 day"
+
+t.info type=strds input=precipitation_daily
+
+ +-------------------- Space Time Raster Dataset -----------------------------+
+ |                                                                            |
+ +-------------------- Basic information -------------------------------------+
+ | Id: ........................ precipitation_daily@soeren
+ | Name: ...................... precipitation_daily
+ | Mapset: .................... soeren
+ | Creator: ................... soeren
+ | Creation time: ............. 2013-04-20 14:41:55.392394
+ | Temporal type: ............. absolute
+ | Semantic type:.............. mean
+ +-------------------- Absolute time -----------------------------------------+
+ | Start time:................. 2012-01-01 00:00:00
+ | End time:................... 2012-01-07 00:00:00
+ | Granularity:................ 1 day
+ | Temporal type of maps:...... interval
+ +-------------------- Spatial extent ----------------------------------------+
+ | North:...................... 80.0
+ | South:...................... 0.0
+ | East:.. .................... 120.0
+ | West:....................... 0.0
+ | Top:........................ 0.0
+ | Bottom:..................... 0.0
+ +-------------------- Metadata information ----------------------------------+
+ | Number of registered maps:.. 6
+ | Title:
+ | Daily precipitation
+ | Description:
+ | Test dataset with daily precipitation
+ | Commands of creation:
+ | - 2013-04-20 14:41:55 -
+ | t.create type="strds" temporaltype="absolute"
+ |     output="precipitation_daily" title="Daily precipitation"
+ |     description="Test dataset with daily precipitation"
+ | - 2013-04-20 14:41:55 -
+ | t.register -i type="rast"
+ |     input="precipitation_daily"
+ |     maps="prec_1,prec_2,prec_3,prec_4,prec_5,prec_6" start="2012-01-01"
+ |     increment="1 day"
+ | 
+ | North-South resolution min:. 10.0
+ | North-South resolution max:. 10.0
+ | East-west resolution min:... 10.0
+ | East-west resolution max:... 10.0
+ | Minimum value min:.......... 0.0
+ | Minimum value max:.......... 0.0
+ | Maximum value min:.......... 296.0
+ | Maximum value max:.......... 648.0
+ | Raster register table:...... precipitation_daily_soeren_raster_register
+ +----------------------------------------------------------------------------+
+ 
+t.rast.list input=precipitation_daily
+
+prec_1  soeren  2012-01-01 00:00:00 2012-01-02 00:00:00
+prec_2  soeren  2012-01-02 00:00:00 2012-01-03 00:00:00
+prec_3  soeren  2012-01-03 00:00:00 2012-01-04 00:00:00
+prec_4  soeren  2012-01-04 00:00:00 2012-01-05 00:00:00
+prec_5  soeren  2012-01-05 00:00:00 2012-01-06 00:00:00
+prec_6  soeren  2012-01-06 00:00:00 2012-01-07 00:00:00
+
+t.shift type=strds input=precipitation_daily granularity="12 hours"
+
+t.info type=strds input=precipitation_daily
+
+ +-------------------- Space Time Raster Dataset -----------------------------+
+ |                                                                            |
+ +-------------------- Basic information -------------------------------------+
+ | Id: ........................ precipitation_daily@soeren
+ | Name: ...................... precipitation_daily
+ | Mapset: .................... soeren
+ | Creator: ................... soeren
+ | Creation time: ............. 2013-04-20 14:41:55.392394
+ | Temporal type: ............. absolute
+ | Semantic type:.............. mean
+ +-------------------- Absolute time -----------------------------------------+
+ | Start time:................. 2012-01-01 12:00:00
+ | End time:................... 2012-01-07 12:00:00
+ | Granularity:................ 24 hours
+ | Temporal type of maps:...... interval
+ +-------------------- Spatial extent ----------------------------------------+
+ | North:...................... 80.0
+ | South:...................... 0.0
+ | East:.. .................... 120.0
+ | West:....................... 0.0
+ | Top:........................ 0.0
+ | Bottom:..................... 0.0
+ +-------------------- Metadata information ----------------------------------+
+ | Number of registered maps:.. 6
+ | Title:
+ | Daily precipitation
+ | Description:
+ | Test dataset with daily precipitation
+ | Commands of creation:
+ | - 2013-04-20 14:41:55 -
+ | t.create type="strds" temporaltype="absolute"
+ |     output="precipitation_daily" title="Daily precipitation"
+ |     description="Test dataset with daily precipitation"
+ | - 2013-04-20 14:41:55 -
+ | t.register -i type="rast"
+ |     input="precipitation_daily"
+ |     maps="prec_1,prec_2,prec_3,prec_4,prec_5,prec_6" start="2012-01-01"
+ |     increment="1 day"
+ | - 2013-04-20 14:42:21 -
+ | t.shift type="strds" input="precipitation_daily"
+ |     granularity="12 hours"
+ | 
+ | North-South resolution min:. 10.0
+ | North-South resolution max:. 10.0
+ | East-west resolution min:... 10.0
+ | East-west resolution max:... 10.0
+ | Minimum value min:.......... 0.0
+ | Minimum value max:.......... 0.0
+ | Maximum value min:.......... 296.0
+ | Maximum value max:.......... 648.0
+ | Raster register table:...... precipitation_daily_soeren_raster_register
+ +----------------------------------------------------------------------------+
+
+t.rast.list input=precipitation_daily
+
+prec_1  soeren  2012-01-01 12:00:00 2012-01-02 12:00:00
+prec_2  soeren  2012-01-02 12:00:00 2012-01-03 12:00:00
+prec_3  soeren  2012-01-03 12:00:00 2012-01-04 12:00:00
+prec_4  soeren  2012-01-04 12:00:00 2012-01-05 12:00:00
+prec_5  soeren  2012-01-05 12:00:00 2012-01-06 12:00:00
+prec_6  soeren  2012-01-06 12:00:00 2012-01-07 12:00:00
+
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="t.create.html">t.create</a>,
+<a href="t.register.html">t.register</a>,
+<a href="t.snap.html">t.snap</a>
+</em>
+
+<h2>AUTHOR</h2>
+
+S&ouml;ren Gebbert
+
+<p><i>Last changed: $Date: 2013-01-22 14:44:08 +0100 (Di, 22. Jan 2013) $</i>
+

+ 89 - 0
temporal/t.shift/t.shift.py

@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+############################################################################
+#
+# MODULE:	t.shift
+# AUTHOR(S):	Soeren Gebbert
+#
+# PURPOSE:	Temporally shift the maps of a space time dataset.
+# COPYRIGHT:	(C) 2013 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: Temporally shift the maps of a space time dataset.
+#% keywords: temporal
+#% keywords: shift
+#%end
+
+#%option G_OPT_STDS_INPUT
+#% description: Name of an existing space time dataset
+#%end
+
+#%option
+#% key: type
+#% type: string
+#% description: Type of the dataset, default is strds (space time raster dataset)
+#% required: no
+#% guidependency: input
+#% guisection: Required
+#% options: strds, str3ds, stvds
+#% answer: strds
+#%end
+
+#%option
+#% key: granularity
+#% type: string
+#% description: Shift granularity, format absolute time "x years, x months, x weeks, x days, x hours, x minutes, x seconds" or an integer value for relative time
+#% required: yes
+#% multiple: no
+#%end
+
+import grass.script as grass
+import grass.temporal as tgis
+
+############################################################################
+
+
+def main():
+
+    name = options["input"]
+    type = options["type"]
+    gran = options["granularity"]
+
+    # Make sure the temporal database exists
+    tgis.init()
+    
+    dbif = tgis.SQLDatabaseInterfaceConnection()
+    dbif.connect()
+
+    if name.find("@") >= 0:
+        id = name
+    else:
+        mapset = grass.gisenv()["MAPSET"]
+        id = name + "@" + mapset
+
+    stds = tgis.dataset_factory(type, id)
+
+    if stds.is_in_db(dbif) == False:
+        dbif.close()
+        grass.fatal(_("Space time dataset <%s> not found in temporal database") % (id))
+
+    stds.select(dbif)
+    check = stds.shift(gran=gran, dbif=dbif)
+
+    if check == False:
+        dbif.close()
+        grass.fatal(_("Unable to temporally shift the space time %s dataset <%s>") % \
+                     (stds.get_new_map_instance(None).get_type(), id))
+        
+    stds.update_command_string(dbif=dbif)
+    dbif.close()
+    
+if __name__ == "__main__":
+    options, flags = grass.parser()
+    main()

+ 45 - 0
temporal/t.shift/test.t.shift.absolue.sh

@@ -0,0 +1,45 @@
+#!/bin/sh
+# Space time raster dataset temporal shifting
+# We need to set a specific region in the
+# @preprocess step of this test. 
+# 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
+# Generate data
+r.mapcalc --o expr="prec_1 = rand(0, 550)"
+r.mapcalc --o expr="prec_2 = rand(0, 450)"
+r.mapcalc --o expr="prec_3 = rand(0, 320)"
+r.mapcalc --o expr="prec_4 = rand(0, 510)"
+r.mapcalc --o expr="prec_5 = rand(0, 300)"
+r.mapcalc --o expr="prec_6 = rand(0, 650)"
+
+t.create --o type=strds temporaltype=absolute output=precip_abs title="A test" descr="A test"
+t.register -i --o type=rast input=precip_abs maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 \
+    start="2001-01-01 12:00:00" increment="14 days"
+
+t.rast.list input=precip_abs
+
+# The first @test
+t.shift --o input=precip_abs granularity="3 years"
+t.info type=strds input=precip_abs
+t.rast.list input=precip_abs
+t.shift --o input=precip_abs granularity="12 months"
+t.info type=strds input=precip_abs
+t.rast.list input=precip_abs
+t.shift --o input=precip_abs granularity="2 days"
+t.info type=strds input=precip_abs
+t.rast.list input=precip_abs
+t.shift --o input=precip_abs granularity="3 hours"
+t.info type=strds input=precip_abs
+t.rast.list input=precip_abs
+t.shift --o input=precip_abs granularity="30 minutes"
+t.info type=strds input=precip_abs
+t.rast.list input=precip_abs
+t.shift --o input=precip_abs granularity="5 seconds"
+t.info type=strds input=precip_abs
+t.rast.list input=precip_abs
+# This should give an error because of the monthly increment 
+# that will result in wrong number of days in the next month
+t.shift --o input=precip_abs granularity="1 month"
+
+t.unregister type=rast maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6
+t.remove type=strds input=precip_abs

+ 31 - 0
temporal/t.shift/test.t.shift.relative.sh

@@ -0,0 +1,31 @@
+#!/bin/sh
+# Space time raster dataset temporal shifting with relative time
+# We need to set a specific region in the
+# @preprocess step of this test. 
+# 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
+# Generate data
+r.mapcalc --o expr="prec_1 = rand(0, 550)"
+r.mapcalc --o expr="prec_2 = rand(0, 450)"
+r.mapcalc --o expr="prec_3 = rand(0, 320)"
+r.mapcalc --o expr="prec_4 = rand(0, 510)"
+r.mapcalc --o expr="prec_5 = rand(0, 300)"
+r.mapcalc --o expr="prec_6 = rand(0, 650)"
+
+t.create --o type=strds temporaltype=relative output=precip_rel title="A test" descr="A test"
+t.register -i --o type=rast unit=days input=precip_rel maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 \
+    start=0 increment=1
+
+t.info type=strds input=precip_rel
+t.rast.list input=precip_rel
+
+# The first @test
+t.shift --o input=precip_rel granularity=3
+t.info type=strds input=precip_rel
+t.rast.list input=precip_rel
+t.shift --o input=precip_rel granularity=10000
+t.info type=strds input=precip_rel
+t.rast.list input=precip_rel
+
+t.unregister type=rast maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6
+t.remove type=strds input=precip_rel

+ 7 - 0
temporal/t.snap/Makefile

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

+ 176 - 0
temporal/t.snap/t.snap.html

@@ -0,0 +1,176 @@
+<h2>DESCRIPTION</h2>
+
+<em>t.snap</em> is designed to convert time instances of maps into time intervals or to 
+create valid temporal topologies for space time datasets. Raster, 3D raster and vector space time datasets are supported
+with absolute and relative time.
+<p>
+This module "snaps" the end time of each registered map of a space time dataset to the start time
+of the map that is the temporal nearest neighbour in the future. Maps with equal time stamps
+are not modified and must be removed or modified to create a valid temporal topology.
+In case the last map in the space time dataset is a time instance, the granularity of the space time
+dataset will be used to create the time interval.
+
+<h2>EXAMPLE</h2>
+
+We create 6 raster maps and register them using absolute time 
+in a space time raster dataset using an increment of one month.
+Then we snap the created time instances resulting in time intervals.
+
+<div class="code"><pre>
+
+r.mapcalc expr="prec_1 = rand(0, 550)"
+r.mapcalc expr="prec_2 = rand(0, 450)"
+r.mapcalc expr="prec_3 = rand(0, 320)"
+r.mapcalc expr="prec_4 = rand(0, 510)"
+r.mapcalc expr="prec_5 = rand(0, 300)"
+r.mapcalc expr="prec_6 = rand(0, 650)"
+
+t.create type=strds temporaltype=absolute \
+         output=precipitation_daily \
+         title="Daily precipitation" \
+         description="Test dataset with daily precipitation"
+
+t.register type=rast input=precipitation_daily \
+           maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 \
+           start=2012-01-01 increment="1 day"
+
+t.info type=strds input=precipitation_daily
+
+ +-------------------- Space Time Raster Dataset -----------------------------+
+ |                                                                            |
+ +-------------------- Basic information -------------------------------------+
+ | Id: ........................ precipitation_daily@soeren
+ | Name: ...................... precipitation_daily
+ | Mapset: .................... soeren
+ | Creator: ................... soeren
+ | Creation time: ............. 2013-04-20 14:39:07.136253
+ | Temporal type: ............. absolute
+ | Semantic type:.............. mean
+ +-------------------- Absolute time -----------------------------------------+
+ | Start time:................. 2012-01-01 00:00:00
+ | End time:................... 2012-01-06 00:00:00
+ | Granularity:................ 1 day
+ | Temporal type of maps:...... point
+ +-------------------- Spatial extent ----------------------------------------+
+ | North:...................... 80.0
+ | South:...................... 0.0
+ | East:.. .................... 120.0
+ | West:....................... 0.0
+ | Top:........................ 0.0
+ | Bottom:..................... 0.0
+ +-------------------- Metadata information ----------------------------------+
+ | Number of registered maps:.. 6
+ | Title:
+ | Daily precipitation
+ | Description:
+ | Test dataset with daily precipitation
+ | Commands of creation:
+ | - 2013-04-20 14:39:07 -
+ | t.create type="strds" temporaltype="absolute"
+ |     output="precipitation_daily" title="Daily precipitation"
+ |     description="Test dataset with daily precipitation"
+ | - 2013-04-20 14:39:07 -
+ | t.register type="rast" input="precipitation_daily"
+ |     maps="prec_1,prec_2,prec_3,prec_4,prec_5,prec_6" start="2012-01-01"
+ |     increment="1 day"
+ | 
+ | North-South resolution min:. 10.0
+ | North-South resolution max:. 10.0
+ | East-west resolution min:... 10.0
+ | East-west resolution max:... 10.0
+ | Minimum value min:.......... 0.0
+ | Minimum value max:.......... 0.0
+ | Maximum value min:.......... 296.0
+ | Maximum value max:.......... 648.0
+ | Raster register table:...... precipitation_daily_soeren_raster_register
+ +----------------------------------------------------------------------------+
+ 
+t.rast.list input=precipitation_daily
+
+prec_1  soeren  2012-01-01 00:00:00 None
+prec_2  soeren  2012-01-02 00:00:00 None
+prec_3  soeren  2012-01-03 00:00:00 None
+prec_4  soeren  2012-01-04 00:00:00 None
+prec_5  soeren  2012-01-05 00:00:00 None
+prec_6  soeren  2012-01-06 00:00:00 None
+
+t.snap type=strds input=precipitation_daily
+
+t.info type=strds input=precipitation_daily
+
+ +-------------------- Space Time Raster Dataset -----------------------------+
+ |                                                                            |
+ +-------------------- Basic information -------------------------------------+
+ | Id: ........................ precipitation_daily@soeren
+ | Name: ...................... precipitation_daily
+ | Mapset: .................... soeren
+ | Creator: ................... soeren
+ | Creation time: ............. 2013-04-20 14:39:07.136253
+ | Temporal type: ............. absolute
+ | Semantic type:.............. mean
+ +-------------------- Absolute time -----------------------------------------+
+ | Start time:................. 2012-01-01 00:00:00
+ | End time:................... 2012-01-07 00:00:00
+ | Granularity:................ 1 day
+ | Temporal type of maps:...... interval
+ +-------------------- Spatial extent ----------------------------------------+
+ | North:...................... 80.0
+ | South:...................... 0.0
+ | East:.. .................... 120.0
+ | West:....................... 0.0
+ | Top:........................ 0.0
+ | Bottom:..................... 0.0
+ +-------------------- Metadata information ----------------------------------+
+ | Number of registered maps:.. 6
+ | Title:
+ | Daily precipitation
+ | Description:
+ | Test dataset with daily precipitation
+ | Commands of creation:
+ | - 2013-04-20 14:39:07 -
+ | t.create type="strds" temporaltype="absolute"
+ |     output="precipitation_daily" title="Daily precipitation"
+ |     description="Test dataset with daily precipitation"
+ | - 2013-04-20 14:39:07 -
+ | t.register type="rast" input="precipitation_daily"
+ |     maps="prec_1,prec_2,prec_3,prec_4,prec_5,prec_6" start="2012-01-01"
+ |     increment="1 day"
+ | - 2013-04-20 14:39:54 -
+ | t.snap type="strds" input="precipitation_daily"
+ | 
+ | North-South resolution min:. 10.0
+ | North-South resolution max:. 10.0
+ | East-west resolution min:... 10.0
+ | East-west resolution max:... 10.0
+ | Minimum value min:.......... 0.0
+ | Minimum value max:.......... 0.0
+ | Maximum value min:.......... 296.0
+ | Maximum value max:.......... 648.0
+ | Raster register table:...... precipitation_daily_soeren_raster_register
+ +----------------------------------------------------------------------------+
+
+t.rast.list input=precipitation_daily
+
+prec_1  soeren  2012-01-01 00:00:00 2012-01-02 00:00:00
+prec_2  soeren  2012-01-02 00:00:00 2012-01-03 00:00:00
+prec_3  soeren  2012-01-03 00:00:00 2012-01-04 00:00:00
+prec_4  soeren  2012-01-04 00:00:00 2012-01-05 00:00:00
+prec_5  soeren  2012-01-05 00:00:00 2012-01-06 00:00:00
+prec_6  soeren  2012-01-06 00:00:00 2012-01-07 00:00:00
+
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="t.shift.html">t.shift</a>,
+<a href="t.create.html">t.create</a>,
+<a href="t.register.html">t.register</a>
+</em>
+
+<h2>AUTHOR</h2>
+
+S&ouml;ren Gebbert
+
+<p><i>Last changed: $Date: 2013-01-22 14:44:08 +0100 (Di, 22. Jan 2013) $</i>
+

+ 75 - 0
temporal/t.snap/t.snap.py

@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+############################################################################
+#
+# MODULE:   t.snap
+# AUTHOR(S):    Soeren Gebbert
+#
+# PURPOSE:  Temporally snap the maps of a space time dataset.
+# COPYRIGHT:    (C) 2013 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: Temporally snap the maps of a space time dataset.
+#% keywords: temporal
+#% keywords: snap
+#%end
+
+#%option G_OPT_STDS_INPUT
+#% description: Name of an existing space time dataset
+#%end
+
+#%option
+#% key: type
+#% type: string
+#% description: Type of the dataset, default is strds (space time raster dataset)
+#% required: no
+#% guidependency: input
+#% guisection: Required
+#% options: strds, str3ds, stvds
+#% answer: strds
+#%end
+
+import grass.script as grass
+import grass.temporal as tgis
+
+############################################################################
+
+
+def main():
+
+    name = options["input"]
+    type = options["type"]
+
+    # Make sure the temporal database exists
+    tgis.init()
+    
+    dbif = tgis.SQLDatabaseInterfaceConnection()
+    dbif.connect()
+
+    if name.find("@") >= 0:
+        id = name
+    else:
+        mapset = grass.gisenv()["MAPSET"]
+        id = name + "@" + mapset
+
+    stds = tgis.dataset_factory(type, id)
+
+    if stds.is_in_db(dbif) == False:
+        dbif.close()
+        grass.fatal(_("Space time dataset <%s> not found in temporal database") % (id))
+
+    stds.select(dbif)
+    stds.snap(dbif=dbif)
+        
+    stds.update_command_string(dbif=dbif)
+    dbif.close()
+    
+if __name__ == "__main__":
+    options, flags = grass.parser()
+    main()

+ 52 - 0
temporal/t.snap/test.t.snap.absolute.sh

@@ -0,0 +1,52 @@
+#!/bin/sh
+# Space time raster dataset temporal snapping with absolute time
+# We need to set a specific region in the
+# @preprocess step of this test. 
+# 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
+# Generate data
+r.mapcalc --o expr="prec_1 = rand(0, 550)"
+r.mapcalc --o expr="prec_2 = rand(0, 450)"
+r.mapcalc --o expr="prec_3 = rand(0, 320)"
+r.mapcalc --o expr="prec_4 = rand(0, 510)"
+r.mapcalc --o expr="prec_5 = rand(0, 300)"
+r.mapcalc --o expr="prec_6 = rand(0, 650)"
+
+n1=`g.tempfile pid=1 -d` 
+
+cat > "${n1}" << EOF
+prec_1|2001-01-01|2001-07-01
+prec_2|2001-02-01|2001-04-01
+prec_3|2001-03-01|2001-04-01
+prec_4|2001-04-01|2001-06-01
+prec_5|2001-05-01|2001-06-01
+prec_6|2001-06-01|2001-07-01
+EOF
+
+t.create --o type=strds temporaltype=absolute output=precip_abs title="A test" descr="A test"
+t.register --o type=rast input=precip_abs maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 \
+    start="2001-01-01 12:00:00" increment="14 days"
+
+# The first @test
+t.info type=strds input=precip_abs
+t.rast.list input=precip_abs
+
+t.snap --o input=precip_abs 
+
+t.info type=strds input=precip_abs
+t.rast.list input=precip_abs
+
+# The second @test
+# Creating a valid topology
+t.register --o type=rast input=precip_abs file=${n1}
+
+t.rast.list input=precip_abs
+t.topology input=precip_abs
+
+t.snap --o input=precip_abs 
+
+t.rast.list input=precip_abs
+t.topology input=precip_abs
+
+t.unregister type=rast maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6
+t.remove type=strds input=precip_abs

+ 29 - 0
temporal/t.snap/test.t.snap.relative.sh

@@ -0,0 +1,29 @@
+#!/bin/sh
+# Space time raster dataset temporal snapping with relative time
+# We need to set a specific region in the
+# @preprocess step of this test. 
+# 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
+# Generate data
+r.mapcalc --o expr="prec_1 = rand(0, 550)"
+r.mapcalc --o expr="prec_2 = rand(0, 450)"
+r.mapcalc --o expr="prec_3 = rand(0, 320)"
+r.mapcalc --o expr="prec_4 = rand(0, 510)"
+r.mapcalc --o expr="prec_5 = rand(0, 300)"
+r.mapcalc --o expr="prec_6 = rand(0, 650)"
+
+t.create --o type=strds temporaltype=relative output=precip_rel title="A test" descr="A test"
+t.register --o type=rast input=precip_rel unit="days" \
+    maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 \
+    start=0 increment=14
+
+t.info type=strds input=precip_rel
+t.rast.list input=precip_rel
+
+# The first @test
+t.snap --o input=precip_rel 
+t.info type=strds input=precip_rel
+t.rast.list input=precip_rel
+
+t.unregister type=rast maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6
+t.remove type=strds input=precip_rel

+ 3 - 3
temporal/t.topology/t.topology.py

@@ -5,7 +5,7 @@
 # MODULE:	t.topology
 # MODULE:	t.topology
 # AUTHOR(S):	Soeren Gebbert
 # AUTHOR(S):	Soeren Gebbert
 #
 #
-# PURPOSE:	List and modify temporal topology of a space time dataset
+# PURPOSE:	List temporal topology of a space time 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: Lists and modifies temporal topology of a space time dataset.
+#% description: Lists temporal topology of a space time dataset.
 #% keywords: temporal
 #% keywords: temporal
 #% keywords: topology
 #% keywords: topology
 #%end
 #%end
@@ -33,7 +33,7 @@
 
 
 #%flag
 #%flag
 #% key: m
 #% key: m
-#% description: Print temporal relation matrix and exit
+#% description: Print temporal relationships and exit
 #%end
 #%end
 
 
 import grass.script as grass
 import grass.script as grass