فهرست منبع

New relative time handling, compatible to the grass datetime library.
New database structure using different SQL datatypes.


git-svn-id: https://svn.osgeo.org/grass/grass/trunk@50343 15284696-431f-4ddb-bdfa-cd5b030d7da7

Soeren Gebbert 13 سال پیش
والد
کامیت
31b8bc123a
34فایلهای تغییر یافته به همراه477 افزوده شده و 238 حذف شده
  1. 21 2
      lib/python/temporal/abstract_dataset.py
  2. 59 22
      lib/python/temporal/abstract_map_dataset.py
  3. 44 5
      lib/python/temporal/abstract_space_time_dataset.py
  4. 2 2
      lib/python/temporal/aggregation.py
  5. 6 4
      lib/python/temporal/datetime_math.py
  6. 23 19
      lib/python/temporal/space_time_datasets_tools.py
  7. 50 4
      lib/python/temporal/temporal_extent.py
  8. 13 11
      lib/python/temporal/temporal_granularity.py
  9. 4 3
      lib/temporal/SQL/map_tables_template.sql
  10. 7 6
      lib/temporal/SQL/stds_tables_template.sql
  11. 2 0
      temporal/Makefile
  12. 13 13
      temporal/t.time.abs/test.t.time.abs.file.sh
  13. 17 6
      temporal/t.time.rel/t.time.rel.py
  14. 13 13
      temporal/t.time.rel/test.t.time.rel.file.sh
  15. 12 9
      temporal/t.time.rel/test.t.time.rel.sh
  16. 16 16
      temporal/t.topology/test.t.topology.abstime.sh
  17. 36 34
      temporal/t.topology/test.t.topology.reltime.sh
  18. 2 2
      temporal/tr.aggregate.ds/test.tr.aggregate.ds.sh
  19. 1 2
      temporal/tr.aggregate.ds/tr.aggregate.ds.py
  20. 30 0
      temporal/tr.aggregate/test.tr.aggregate.relative_time.sh
  21. 2 4
      temporal/tr.aggregate/test.tr.aggregate.sh
  22. 8 3
      temporal/tr.aggregate/tr.aggregate.py
  23. 2 2
      temporal/tr.export/test.tr.export.sh
  24. 11 11
      temporal/tr.list/test.tr.list.sh
  25. 7 7
      temporal/tr.register/ECAD_climate_analysis_1995_2010.py
  26. 12 12
      temporal/tr.register/test.tr.register.file.sh
  27. 13 2
      temporal/tr.register/tr.register.py
  28. 3 1
      temporal/tr.series/tr.series.py
  29. 3 5
      temporal/tr.univar/test.tr.univar.sh
  30. 6 0
      temporal/tr3.register/test.tr3.register.sh
  31. 13 2
      temporal/tr3.register/tr3.register.py
  32. 11 12
      temporal/tv.list/test.tv.list.sh
  33. 13 2
      temporal/tv.register/tv.register.py
  34. 2 2
      temporal/tv.what.rast/test.tv.what.rast.sh

+ 21 - 2
lib/python/temporal/abstract_dataset.py

@@ -97,13 +97,32 @@ class abstract_dataset(object):
         return (start, end, tz)
     
     def get_relative_time(self):
-        """Returns the relative time interval (start_time, end_time) or None if not present"""
+        """Returns the relative time interval (start_time, end_time, unit) or None if not present"""
 
         start = self.relative_time.get_start_time()
         end = self.relative_time.get_end_time()
+        unit = self.relative_time.get_unit()
 
-        return (start, end)
+        return (start, end, unit)
+ 
+    def get_relative_time_unit(self):
+        """Returns the relative time unit or None if not present"""
+
+        unit = self.relative_time.get_unit()
+
+        return unit
 
+    def check_relative_time_unit(self, unit):
+        """Check if unit is of type  years, months, days, hours, minutes or seconds
+        
+           Return True if success or False otherwise 
+        """
+        # Check unit
+        units = ["years","months","days","hours","minutes","seconds"]
+        if unit not in units:
+            return False
+        return True
+ 
     def get_temporal_type(self):
         """Return the temporal type of this dataset"""
         return self.base.get_ttype()

+ 59 - 22
lib/python/temporal/abstract_map_dataset.py

@@ -87,14 +87,15 @@ class abstract_map_dataset(abstract_dataset):
         datasets = self.get_registered_datasets()
         count = 0
         string = ""
-        for ds in datasets:
-            if count == 0:
-                string += ds["id"]
-            else:
-                string += ",%s" % ds["id"]
-            count += 1
-            if count > 2:
-                string += " | ............................ "
+        if datasets:
+            for ds in datasets:
+                if count == 0:
+                    string += ds["id"]
+                else:
+                    string += ",%s" % ds["id"]
+                count += 1
+                if count > 2:
+                    string += " | ............................ "
         print " | Registered datasets ........ " + string
         print " +----------------------------------------------------------------------------+"
 
@@ -149,6 +150,9 @@ class abstract_map_dataset(abstract_dataset):
     def update_absolute_time(self, start_time, end_time=None, timezone=None, dbif = None):
         """Update the absolute time
 
+           This method should always be used to set the absolute time. Do not use insert() or update()
+           to the the time. This update functions assures that the *.timestamp commands are invoked.
+
            @param start_time: a datetime object specifying the start time of the map
            @param end_time: a datetime object specifying the end time of the map
            @param timezone: Thee timezone of the map
@@ -167,7 +171,12 @@ class abstract_map_dataset(abstract_dataset):
         if connect == True:
             dbif.close()
 
-        # Start the grass C-module to set the time in the file system
+        self.write_absolute_time_to_file()
+
+    def write_absolute_time_to_file(self):
+        """Start the grass timestamp module to set the time in the file system"""
+
+        start_time, end_time, unit = self.get_absolute_time()
         start = datetime_to_grass_datetime_string(start_time)
         if end_time:
             end = datetime_to_grass_datetime_string(end_time)
@@ -175,16 +184,26 @@ class abstract_map_dataset(abstract_dataset):
 
         core.run_command(self.get_timestamp_module_name(), map=self.get_id(), date=start)
 
-    def set_relative_time(self, start_time, end_time=None):
+    def set_relative_time(self, start_time, end_time, unit):
         """Set the relative time interval 
         
-           @param start_time: A double value in days
-           @param end_time: A double value in days
+           @param start_time: A double value 
+           @param end_time: A double value 
+           @param unit: The unit of the relative time. Supported uits: years, months, days, hours, minutes, seconds
+
+           Return True for success and False otherwise
 
         """
+
+        if not self.check_relative_time_unit(unit):
+            core.error(_("Unsupported relative time unit type for %s map <%s>: %s") % (self.get_type(), self.get_id(), unit))
+            return False
+        
+
         if start_time != None and end_time != None:
-            if abs(float(start_time)) > abs(float(end_time)):
-                core.fatal(_("End time must be greater than start time for %s map <%s>") % (self.get_type(), self.get_id()))
+            if int(start_time) > int(end_time):
+                core.error(_("End time must be greater than start time for %s map <%s>") % (self.get_type(), self.get_id()))
+                return False
             else:
                 # Do not create an interval in case start and end time are equal
                 if start_time == end_time:
@@ -192,15 +211,21 @@ class abstract_map_dataset(abstract_dataset):
 
         self.base.set_ttype("relative")
         
-        self.relative_time.set_start_time(float(start_time))
+        self.relative_time.set_unit(unit)
+        self.relative_time.set_start_time(int(start_time))
         if end_time != None:
-            self.relative_time.set_end_time(float(end_time))
+            self.relative_time.set_end_time(int(end_time))
         else:
             self.relative_time.set_end_time(None)
 
-    def update_relative_time(self, start_time, end_time=None, dbif = None):
+        return True
+
+    def update_relative_time(self, start_time, end_time, unit, dbif = None):
         """Update the relative time interval
 
+           This method should always be used to set the absolute time. Do not use insert() or update()
+           to the the time. This update functions assures that the *.timestamp commands are invoked.
+
            @param start_time: A double value 
            @param end_time: A double value 
            @param dbif: The database interface to be used
@@ -212,14 +237,26 @@ class abstract_map_dataset(abstract_dataset):
             dbif.connect()
             connect = True
 
-        self.set_relative_time(start_time, end_time)
-        self.relative_time.update_all(dbif)
-        self.base.update(dbif)
-        dbif.connection.commit()
+        if self.set_relative_time(start_time, end_time, unit):
+            self.relative_time.update_all(dbif)
+            self.base.update(dbif)
+            dbif.connection.commit()
 
         if connect == True:
             dbif.close()
 
+        self.write_relative_time_to_file()
+
+    def write_relative_time_to_file(self):
+        """Start the grass timestamp module to set the time in the file system"""
+
+        start_time, end_time, unit = self.get_relative_time()
+        start = "%i %s"%(int(start_time), unit)
+        if end_time:
+            end = "%i %s"%(int(end_time), unit)
+            start += " / %s"%(end)
+        core.run_command(self.get_timestamp_module_name(), map=self.get_id(), date=start)
+
     def set_spatial_extent(self, north, south, east, west, top=0, bottom=0):
         """Set the spatial extent of the map
 
@@ -237,7 +274,7 @@ class abstract_map_dataset(abstract_dataset):
         if self.is_time_absolute():
             start, end, tz = self.get_absolute_time()
         else:
-            start, end = self.get_relative_time()
+            start, end, unit = self.get_relative_time()
 
         if start != None:
             if end != None:

+ 44 - 5
lib/python/temporal/abstract_space_time_dataset.py

@@ -39,6 +39,7 @@ class abstract_space_time_dataset(abstract_dataset):
     """
     def __init__(self, ident):
 	self.reset(ident)
+        self.map_counter = 0
 
     def get_new_map_instance(self, ident=None):
         """Return a new instance of a map dataset which is associated with the type of this class
@@ -168,6 +169,19 @@ class abstract_space_time_dataset(abstract_dataset):
         else:
             core.fatal(_("Unknown temporal type \"%s\"") % (temporal_type))
 
+    def set_relative_time_unit(self, unit):
+        """Set the relative time unit which may be of type: years, months, days, hours, minutes or seconds
+        
+           All maps registered in a (relative time) space time dataset must have the same unit
+        """
+
+        temporal_type = self.get_temporal_type()
+ 
+        if temporal_type == "relative":
+            if not self.check_relative_time_unit(unit):
+                core.fatal(_("Unsupported temporal unit: %s") % (unit))
+            self.relative_time.set_unit(unit)
+
     def get_map_time(self):
         """Return the type of the map time, interval, point, maixed or invalid"""
         
@@ -199,7 +213,7 @@ class abstract_space_time_dataset(abstract_dataset):
                 if count == 0:
                     relations = relation
                 else:
-                    relations += "," + relation
+                    relations += "," + str(relation)
                 count += 1
                 # Break if the the next map follows
                 if relation == "follows":
@@ -263,7 +277,7 @@ class abstract_space_time_dataset(abstract_dataset):
             if maps[i].is_time_absolute():
                 start, end, tz = maps[i].get_absolute_time()
             if maps[i].is_time_relative():
-                start, end = maps[i].get_relative_time()
+                start, end, unit = maps[i].get_relative_time()
 
             if start != None and end != None:
                 time_interval += 1
@@ -703,7 +717,7 @@ class abstract_space_time_dataset(abstract_dataset):
                 if self.is_time_absolute():
                     map.set_absolute_time(row["start_time"], row["end_time"])
                 elif self.is_time_relative():
-                    map.set_relative_time(row["start_time"], row["end_time"])
+                    map.set_relative_time(row["start_time"], row["end_time"], self.get_relative_time_unit())
                 obj_list.append(copy.copy(map))
                 count += 1
 
@@ -855,6 +869,8 @@ class abstract_space_time_dataset(abstract_dataset):
         map_name = map.base.get_name()
         map_mapset = map.base.get_mapset()
         map_register_table = map.get_stds_register()
+        map_rel_time_unit = map.get_relative_time_unit()
+        map_ttype = map.get_temporal_type()
 
         #print "Map register table", map_register_table
 
@@ -862,6 +878,23 @@ class abstract_space_time_dataset(abstract_dataset):
         stds_name = self.base.get_name()
         stds_mapset = self.base.get_mapset()
         stds_register_table = self.get_map_register()
+        stds_ttype = self.get_temporal_type()
+
+        # Check temporal types
+        if stds_ttype != map_ttype:
+            core.fatal(_("Temporal type of space time dataset <%s> and map <%s> are different") % (self.get_id(), map.get_id()))
+
+        # In case no map has been registered yet, set the relative time unit from the first map
+        if self.metadata.get_number_of_maps() == None and self.map_counter == 0 and self.is_time_relative():
+            self.set_relative_time_unit(map_rel_time_unit)
+            self.relative_time.update()
+            core.verbose(_("Set temporal unit for space time %s dataset <%s> to %s") %  (map.get_type(), self.get_id(), map_rel_time_unit))
+
+        stds_rel_time_unit = self.get_relative_time_unit()
+
+        # Check the relative time unit
+        if self.is_time_relative() and (stds_rel_time_unit != map_rel_time_unit):
+            core.fatal(_("Relative time units of space time dataset <%s> and map <%s> are different") % (self.get_id(), map.get_id()))
 
         #print "STDS register table", stds_register_table
 
@@ -887,7 +920,7 @@ class abstract_space_time_dataset(abstract_dataset):
         # Create tables
         sql_path = get_sql_template_path()
 
-        # We need to create the stmap raster register table bevor we can register the map
+        # We need to create the map raster register table bevor we can register the map
         if map_register_table == None:
             # Create a unique id
             uuid_rand = "map_" + str(uuid.uuid4()).replace("-", "")
@@ -987,6 +1020,9 @@ class abstract_space_time_dataset(abstract_dataset):
         if connect == True:
             dbif.close()
             
+        # increase the counter
+        self.map_counter += 1
+
         return True
 
     def unregister_map(self, map, dbif = None):
@@ -1050,6 +1086,9 @@ class abstract_space_time_dataset(abstract_dataset):
 
         if connect == True:
             dbif.close()
+
+        # decrease the counter
+        self.map_counter -= 1
             
     def update_from_registered_maps(self, dbif = None):
         """This methods updates the spatial and temporal extent as well as
@@ -1127,7 +1166,7 @@ class abstract_space_time_dataset(abstract_dataset):
         if self.is_time_absolute():
             start_time, end_time, tz = self.get_absolute_time()
         else:
-            start_time, end_time = self.get_relative_time()
+            start_time, end_time, unit = self.get_relative_time()
 
         # In case no end time is set, use the maximum start time of all registered maps as end time
         if end_time == None:

+ 2 - 2
lib/python/temporal/aggregation.py

@@ -68,7 +68,7 @@ def collect_map_names(sp, dbif, start, end, sampling):
 
     return names    
 
-def aggregate_raster_maps(dataset, mapset, inputs, base, start, end, count, method, register_null, dbif):
+def aggregate_raster_maps(orig_ds, dataset, mapset, inputs, base, start, end, count, method, register_null, dbif):
 
     core.verbose(_("Aggregate %s raster maps") %(len(inputs)))
     output = "%s_%i" % (base, count)
@@ -118,7 +118,7 @@ def aggregate_raster_maps(dataset, mapset, inputs, base, start, end, count, meth
     if dataset.is_time_absolute():
         new_map.set_absolute_time(start, end, None)
     else:
-        new_map.set_relative_time(start, end)
+        new_map.set_relative_time(start, end, orig_ds.get_relative_time_unit())
 
     # Insert map in temporal database
     new_map.insert(dbif)

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

@@ -25,7 +25,6 @@ import grass.script.core as core
 import copy
 from dateutil import parser
 
-
 ###############################################################################
 
 def relative_time_to_time_delta(value):
@@ -42,7 +41,7 @@ def relative_time_to_time_delta(value):
 ###############################################################################
 
 def time_delta_to_relative_time(delta):
-    """Convert the time delta into a 
+    """Convert the time delta into a
        double value, representing days.
     """
 
@@ -207,7 +206,10 @@ def adjust_datetime_to_granularity(mydate, granularity):
             seconds = 0
             minutes = 0
             hours = 0
-            days = days - weekday
+            if days > weekday:
+                days = days - weekday # this needs to be fixed
+            else:
+                days = days + weekday # this needs to be fixed
         elif has_months: # Start at the first day of the month at 00:00:00
             seconds = 0
             minutes = 0
@@ -341,7 +343,7 @@ def datetime_to_grass_datetime_string(dt):
     # Check for time zone infor in the datetime object
     if dt.tzinfo != None:
         string = "%.2i %s %.2i %.2i:%.2i:%.2i %+.4i"%(dt.day, month_names[dt.month], dt.year, \
-                 dt.hour, dt.minute, dt.second, dt.tzinfo._offset.seconds/3600*100)
+                 dt.hour, dt.minute, dt.second, dt.tzinfo._offset.seconds/60)
     else:
         string = "%.2i %s %.4i %.2i:%.2i:%.2i"%(dt.day, month_names[dt.month], dt.year, dt.hour, dt.minute, dt.second)
 

+ 23 - 19
lib/python/temporal/space_time_datasets_tools.py

@@ -26,7 +26,7 @@ from space_time_datasets import *
 
 ###############################################################################
 
-def register_maps_in_space_time_dataset(type, name, maps=None, file=None, start=None, end=None, increment=None, dbif = None, interval=False, fs="|"):
+def register_maps_in_space_time_dataset(type, name, maps=None, file=None, start=None, end=None, unit=None, increment=None, dbif = None, interval=False, fs="|"):
     """Use this method to register maps in space time datasets. This function is generic and
 
        Additionally a start time string and an increment string can be specified
@@ -39,7 +39,9 @@ def register_maps_in_space_time_dataset(type, name, maps=None, file=None, start=
        @param name: The name of the space time dataset
        @param maps: A comma separated list of map names
        @param file: Input file one map with optional start and end time, one per line
-       @param 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)
+       @param start: The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative is integer 5)
+       @param end: The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative is integer 5)
+       @param unit: The unit of the relative time: years, months, days, hours, minutes, seconds
        @param increment: Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
        @param dbif: The database interface to be used
        @param interval: If True, time intervals are created in case the start time and an increment is provided
@@ -182,7 +184,7 @@ def register_maps_in_space_time_dataset(type, name, maps=None, file=None, start=
 
         # Set the valid time
         if start:
-            assign_valid_time_to_map(ttype=sp.get_temporal_type(), map=map, start=start, end=end, increment=increment, mult=count, dbif=dbif, interval=interval)
+            assign_valid_time_to_map(ttype=sp.get_temporal_type(), map=map, start=start, end=end, unit=unit, increment=increment, mult=count, dbif=dbif, interval=interval)
 
         # Finally Register map in the space time dataset
         sp.register_map(map, dbif)
@@ -294,7 +296,7 @@ def unregister_maps_from_space_time_datasets(type, name, maps, file=None, dbif =
 
 ###############################################################################
 
-def assign_valid_time_to_maps(type, maps, ttype, start, end=None, file=file, increment=None, dbif = None, interval=False, fs="|"):
+def assign_valid_time_to_maps(type, maps, ttype, start, end=None, unit=None, file=file, increment=None, dbif = None, interval=False, fs="|"):
     """Use this method to assign valid time (absolute or relative) to raster,
        raster3d and vector datasets.
 
@@ -305,8 +307,9 @@ def assign_valid_time_to_maps(type, maps, ttype, start, end=None, file=file, inc
 
        @param type: The type of the maps raster, raster3d or vector
        @param maps: A comma separated list of map names
-       @param start: The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
-       @param end: The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
+       @param start: The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative is integer 5)
+       @param end: The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative is integer 5)
+       @param unit: The unit of the relative time: years, months, days, hours, minutes, seconds
        @param increment: Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
        @param file: Input file one map with optional start and end time, one per line
        @param dbif: The database interface to be used
@@ -437,7 +440,7 @@ def assign_valid_time_to_maps(type, maps, ttype, start, end=None, file=file, inc
             count = 1
 
         # Set the valid time
-        assign_valid_time_to_map(ttype=ttype, map=map, start=start, end=end, increment=increment, mult=count, dbif=dbif, interval=interval)
+        assign_valid_time_to_map(ttype=ttype, map=map, start=start, end=end, unit=unit, increment=increment, mult=count, dbif=dbif, interval=interval)
 
         count += 1
 
@@ -455,14 +458,15 @@ def assign_valid_time_to_maps(type, maps, ttype, start, end=None, file=file, inc
 
 ###############################################################################
 
-def assign_valid_time_to_map(ttype, map, start, end, increment=None, mult=1, dbif = None, interval=False):
+def assign_valid_time_to_map(ttype, map, start, end, unit, increment=None, mult=1, dbif = None, interval=False):
     """Assign the valid time to a map dataset
 
        @param ttype: The temporal type which should be assigned and which the time format is of
        @param map: A map dataset object derived from abstract_map_dataset
-       @param start: The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
-       @param end: The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
-       @param increment: Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
+       @param start: The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative is integer 5)
+       @param end: The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative is integer 5)
+       @param unit: The unit of the relative time: years, months, days, hours, minutes, seconds
+       @param increment: Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative is integer 1)
        @param multi: A multiplier for the increment
        @param dbif: The database interface to use for sql queries
        @param interval: If True, time intervals are created in case the start time and an increment is provided
@@ -479,14 +483,14 @@ def assign_valid_time_to_map(ttype, map, start, end, increment=None, mult=1, dbi
         start_time = string_to_datetime(start)
         if start_time == None:
             dbif.close()
-            core.fatal_error(_("Unable to convert string \"%s\"into a datetime object")%(start))
+            core.fatal(_("Unable to convert string \"%s\"into a datetime object")%(start))
         end_time = None
         
         if end:
             end_time = string_to_datetime(end)
             if end_time == None:
                 dbif.close()
-                core.fatal_error(_("Unable to convert string \"%s\"into a datetime object")%(end))
+                core.fatal(_("Unable to convert string \"%s\"into a datetime object")%(end))
 
         # Add the increment
         if increment:
@@ -497,19 +501,19 @@ def assign_valid_time_to_map(ttype, map, start, end, increment=None, mult=1, dbi
         core.verbose(_("Set absolute valid time for map <%s> to %s - %s") % (map.get_id(), str(start_time), str(end_time)))
         map.update_absolute_time(start_time, end_time, None, dbif)
     else:
-        start_time = float(start)
+        start_time = int(start)
         end_time = None
 
         if end:
-            end_time = float(end)
+            end_time = int(end)
 
         if increment:
-            start_time = start_time + mult * float(increment)
+            start_time = start_time + mult * int(increment)
             if interval:
-                end_time = start_time + float(increment)
+                end_time = start_time + int(increment)
 
-        core.verbose(_("Set relative valid time for map <%s> to %f - %s") % (map.get_id(), start_time,  str(end_time)))
-        map.update_relative_time(start_time, end_time, dbif)
+        core.verbose(_("Set relative valid time for map <%s> to %i - %s with unit %s") % (map.get_id(), start_time,  str(end_time), unit))
+        map.update_relative_time(start_time, end_time, unit, dbif)
 
     if connect == True:
         dbif.close()

+ 50 - 4
lib/python/temporal/temporal_extent.py

@@ -357,11 +357,14 @@ class absolute_temporal_extent(abstract_temporal_extent):
 	self.set_timezone(timezone)
 
     def set_timezone(self, timezone):
-	"""Set the timezone of the map, integer from 1 - 24"""
+	"""Set the timezone of the map, the timezone is of type string.
+           Timezones are not supported yet, instead the timezone is set in the datetime string as offset in minutes.
+        """
 	self.D["timezone"] = timezone
 
     def get_timezone(self):
 	"""Get the timezone of the map
+           Timezones are not supported yet, instead the timezone is set in the datetime string as offset in minutes.
 	   @return None if not found"""
 	if self.D.has_key("timezone"):
 	    return self.D["timezone"]
@@ -474,17 +477,60 @@ class stvds_absolute_time(stds_absolute_time):
 class relative_temporal_extent(abstract_temporal_extent):
     """This is the relative time class for all maps and spacetime datasets
 
-       start_time and end_time must be of type datetime
+       start_time and end_time must be of type integer
     """
-    def __init__(self, table=None, ident=None, start_time=None, end_time=None):
+    def __init__(self, table=None, ident=None, start_time=None, end_time=None, unit=None):
 
 	abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
+	self.D["unit"] = unit
+
+    def set_unit(self, unit):
+        """Set the unit of the relative time. Valid units are:
+           * years
+           * months
+           * days
+           * hours
+           * minutes
+           * seconds
+        """
+	self.D["unit"] = unit
+
+    def get_unit(self):
+	"""Get the unit of the relative time
+	   @return None if not found"""
+	if self.D.has_key("unit"):
+	    return self.D["unit"]
+        else:
+	    return None
+
+    def temporal_relation(self, map):
+	"""Returns the temporal relation between temporal objects
+	   Temporal relationsships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
+	"""
+        
+        # Check units for relative time
+        if not self.D.has_key("unit"):
+            return None
+        if not map.D.has_key("unit"):
+            return None
+
+        # Units must be equal
+        if self.D["unit"] != map.D["unit"]:
+            return None
+
+	return abstract_temporal_extent.temporal_relation(self, map)
 
     def print_info(self):
         """Print information about this class in human readable style"""
         #      0123456789012345678901234567890
-        print " +-------------------- Reltive time ------------------------------------------+"
+        print " +-------------------- Relative time -----------------------------------------+"
         abstract_temporal_extent.print_info(self)
+        print " | Relative time unit:......... " + str(self.get_unit())
+
+    def print_shell_info(self):
+        """Print information about this class in shell style"""
+        abstract_temporal_extent.print_shell_info(self)
+        print "unit=" + str(self.get_unit())
 
 ###############################################################################
 

+ 13 - 11
lib/python/temporal/temporal_granularity.py

@@ -26,6 +26,9 @@ from datetime_math import *
 ###############################################################################
 
 def compute_relative_time_granularity(maps):            
+    """ Compute the relative granularity"""
+
+    # The intervaltime must be scaled to days resoltuion
     granularity = None
 
     delta = []
@@ -33,9 +36,8 @@ def compute_relative_time_granularity(maps):
     for map in maps:
         start, end = map.get_valid_time()
         if start and end:
-            t =  relative_time_to_time_delta(abs(end - start))
-            full_seconds = t.days * 86400 + t.seconds
-            delta.append(full_seconds)
+            t =  abs(end - start)
+            delta.append(int(t))
 
     # Compute the timedelta of the gaps
     for i in range(len(maps)):
@@ -46,23 +48,23 @@ def compute_relative_time_granularity(maps):
                 start2, end2 = maps[i + 1].get_valid_time()
                 # Gaps are between intervals, intervals and points, points and points
                 if end1 and start2:
-                    t =  relative_time_to_time_delta(abs(end1 - start2))
-                    full_seconds = t.days * 86400 + t.seconds
-                    delta.append(full_seconds)
+                    t =  abs(end1 - start2)
+                    delta.append(int(t))
                 if  not end1 and start2:
-                    t =  relative_time_to_time_delta(abs(start1 - start2))
-                    full_seconds = t.days * 86400 + t.seconds
-                    delta.append(full_seconds)
+                    t =  abs(start1 - start2)
+                    delta.append(int(t))
 
     delta.sort()
     ulist = list(set(delta))
     if len(ulist) > 1:
         # Find greatest common divisor
         granularity = gcd_list(ulist)
-    else:
+    elif len(ulist) == 1:
         granularity = ulist[0]
+    else:
+        granularity = 0
 
-    return float(granularity / 86400.0)
+    return granularity
 
 ###############################################################################
 

+ 4 - 3
lib/temporal/SQL/map_tables_template.sql

@@ -30,8 +30,9 @@ CREATE TABLE  GRASS_MAP_base (
 -- Relative valid time interval with start and end time
 CREATE TABLE  GRASS_MAP_relative_time (
   id VARCHAR NOT NULL,          -- The id (PFK) is the unique identifier for all tables, it is based on name and mapset (name@mapset) and is used as primary foreign key
-  start_time DOUBLE PRECISION,  -- The relative valid start time in [days]
-  end_time DOUBLE PRECISION,    -- The relative valid end time in [days]
+  start_time INTEGER,  -- The relative valid start time in 
+  end_time INTEGER,    -- The relative valid end time in 
+  unit VARCHAR,                 -- The relative time unit, available are "years, months, days, minutes, seconds"
   PRIMARY KEY (id),
   FOREIGN KEY (id) REFERENCES  GRASS_MAP_base (id) ON DELETE CASCADE
 );
@@ -40,7 +41,7 @@ CREATE TABLE  GRASS_MAP_absolute_time (
   id VARCHAR NOT NULL,   -- The id (PFK) is the unique identifier for all tables, it is based on name and mapset (name@mapset) and is used as primary foreign key
   start_time TIMESTAMP,  --  Start of the valid time, can be NULL if no time information is available
   end_time TIMESTAMP,    --  End of the valid time, can be NULL if no time information is available or valid time is a single point in time
-  timezone SMALLINT,     -- The timezone of the valid time
+  timezone VARCHAR,      -- The timezone of the valid time stored as string. This is currently not in use. Instead the timezone is set in the datetime strings 
   PRIMARY KEY (id),
   FOREIGN KEY (id) REFERENCES  GRASS_MAP_base (id) ON DELETE CASCADE
 );

+ 7 - 6
lib/temporal/SQL/stds_tables_template.sql

@@ -15,7 +15,7 @@ CREATE TABLE  STDS_base (
   mapset VARCHAR NOT NULL,             -- mapset of the space-time dataset
   creator VARCHAR NOT NULL,            -- Name of the creator
   temporal_type VARCHAR NOT NULL,      -- The temporal type of the dataset "absolute" or "relative" 
-  semantic_type VARCHAR NOT NULL,      -- The semantic data description used for aggregation/decomposition algorithm selection
+  semantic_type VARCHAR NOT NULL,      -- The semantic data description used for aggregation/decomposition algorithm selection: min, max, mean or sum
   creation_time TIMESTAMP NOT NULL,    -- The time of creation of the space-time dataset
 -- Uncommented due to performance issues
 --  modification_time TIMESTAMP NOT NULL,  -- The time of the last modification of the grass map
@@ -25,9 +25,10 @@ CREATE TABLE  STDS_base (
 
 CREATE TABLE  STDS_relative_time (
   id VARCHAR NOT NULL,            -- Id of the space-time dataset, this is the primary foreign key
-  start_time DOUBLE PRECISION,    -- The relative valid start time in [days]
-  end_time DOUBLE PRECISION,      -- The relative valid end time in [days]
-  granularity DOUBLE PRECISION,   -- The granularity in [days]
+  start_time INTEGER,             -- The relative valid start time 
+  end_time INTEGER,               -- The relative valid end time 
+  granularity INTEGER,            -- The granularity 
+  unit VARCHAR,                   -- The relative time unit, available are "years, months, days, minutes, seconds"
   map_time VARCHAR,               -- The temporal type of the registered maps, may be interval, point or mixed
   PRIMARY KEY (id),  
   FOREIGN KEY (id) REFERENCES  STDS_base (id) ON DELETE CASCADE
@@ -37,8 +38,8 @@ CREATE TABLE  STDS_absolute_time (
   id VARCHAR NOT NULL,            -- Id of the space-time dataset, this is the primary foreign key
   start_time TIMESTAMP,           -- Start of the valid time, can be NULL if no map is registered
   end_time TIMESTAMP,             -- End of the valid time, can be NULL if no map is registered
-  granularity VARCHAR,            -- The granularity "NNN seconds, NNN minutes, NNN hours, NNN days, NNN weeks, NNN months, NNN years"
-  timezone SMALLINT,              -- The time zone number
+  granularity VARCHAR,            -- The granularity "NNN seconds, NNN minutes, NNN hours, NNN days, NNN months, NNN years"
+  timezone VARCHAR,      -- The timezone of the valid time stored as string. This is currently not in use. Instead the timezone is set in the datetime strings 
   map_time VARCHAR,               -- The temporal type of the registered maps, may be interval, point or mixed
   PRIMARY KEY (id),  
   FOREIGN KEY (id) REFERENCES  STDS_base (id) ON DELETE CASCADE

+ 2 - 0
temporal/Makefile

@@ -23,11 +23,13 @@ SUBDIRS = \
 	tr.out.vtk \
 	tr.import \
 	tr.extract \
+	tr3.extract \
 	tr3.register \
 	tv.register \
 	tr.unregister \
 	tr3.unregister \
 	tv.unregister \
+	tv.what.rast 
 
 PGM = tgisintro
 

+ 13 - 13
temporal/t.time.abs/test.t.time.abs.file.sh

@@ -17,7 +17,7 @@ n1=`g.tempfile pid=1 -d` # Only map names
 n2=`g.tempfile pid=2 -d` # Map names and start time
 n3=`g.tempfile pid=3 -d` # Map names start time and increment
 
-cat > $n1 << EOF
+cat > "${n1}" << EOF
 prec_1
 prec_2
 prec_3
@@ -25,9 +25,9 @@ prec_4
 prec_5
 prec_6
 EOF
-cat $n1
+cat "${n1}"
 
-cat > $n2 << EOF
+cat > "${n2}" << EOF
 prec_1|2001-01-01
 prec_2|2001-02-01
 prec_3|2001-03-01
@@ -35,9 +35,9 @@ prec_4|2001-04-01
 prec_5|2001-05-01
 prec_6|2001-06-01
 EOF
-cat $n2
+cat "${n2}"
 
-cat > $n3 << EOF
+cat > "${n3}" << EOF
 prec_1|2001-01-01|2001-04-01
 prec_2|2001-04-01|2001-07-01
 prec_3|2001-07-01|2001-10-01
@@ -45,7 +45,7 @@ prec_4|2001-10-01|2002-01-01
 prec_5|2002-01-01|2002-04-01
 prec_6|2002-04-01|2002-07-01
 EOF
-cat $n3
+cat "${n3}"
 
 # The first @test
 # We create the space time raster inputs and register the raster maps with absolute time interval
@@ -53,28 +53,28 @@ t.create --o type=strds temporaltype=absolute output=precip_abs8 title="A test w
 
 # Test with input files
 # File 1
-t.time.abs file=$n1 start="2001-01-01" increment="1 months"
+t.time.abs file="${n1}" start="2001-01-01" increment="1 months"
 
-tr.register input=precip_abs8 file=$n1
+tr.register input=precip_abs8 file="${n1}"
 t.info type=strds input=precip_abs8
 tr.list input=precip_abs8
 
 # File 1
-t.time.abs file=$n1 start="2001-01-01" 
+t.time.abs file="${n1}" start="2001-01-01" 
 t.info type=strds input=precip_abs8
 tr.list input=precip_abs8
 # File 2
-t.time.abs file=$n2 start=file
+t.time.abs file="${n2}" start=file
 t.info type=strds input=precip_abs8
 tr.list input=precip_abs8
 # File 2
-t.time.abs -i file=$n2 start=file increment="1 months"
+t.time.abs -i file="${n2}" start=file increment="1 months"
 t.info type=strds input=precip_abs8
 tr.list input=precip_abs8
 # File 3
-t.time.abs file=$n3 start=file end=file
+t.time.abs file="${n3}" start=file end=file
 t.info type=strds input=precip_abs8
 tr.list input=precip_abs8
 
 t.remove --v type=strds input=precip_abs8
-t.remove --v type=rast file=$n1
+t.remove --v type=rast file="${n1}"

+ 17 - 6
temporal/t.time.rel/t.time.rel.py

@@ -33,24 +33,34 @@
 
 #%option
 #% key: start
-#% type: string
-#% description: The valid start value in [days] for all maps, or file in case the start time is located in the input file 
+#% type: integer
+#% description: The valid integer start value for all maps, or file in case the start time is located in the input file 
 #% required: no
 #% multiple: no
 #%end
 
 #%option
 #% key: end
+#% type: integer
+#% description: The valid integer end value for all maps, or file in case the start time is located in the input file 
+#% required: no
+#% multiple: no
+#%end
+
+#%option
+#% key: unit
 #% type: string
-#% description: The valid end value in [days] for all maps, or file in case the start time is located in the input file 
+#% description: The unit of the relative time
 #% required: no
 #% multiple: no
+#% options: years,months,days,hours,minutes,seconds
+#% answer: days
 #%end
 
 #%option
 #% key: increment
-#% type: string
-#% description: Increment between maps for valid time interval creation in [days] e.g. 1.5
+#% type: integer
+#% description: Increment between maps for valid time interval creation 
 #% required: no
 #% multiple: no
 #%end
@@ -100,13 +110,14 @@ def main():
     increment = options["increment"]
     fs = options["fs"]
     type = options["type"]
+    unit = options["unit"]
     interval = flags["i"]
 
     # Make sure the temporal database exists
     tgis.create_temporal_database()
     # Set valid absolute time to maps
     tgis.assign_valid_time_to_maps(type=type, maps=maps, ttype="relative", \
-                                   start=start, end=end, file=file, increment=increment, \
+                                   start=start, end=end, unit=unit, file=file, increment=increment, \
                                    dbif=None, interval=interval, fs=fs)
     
 if __name__ == "__main__":

+ 13 - 13
temporal/t.time.rel/test.t.time.rel.file.sh

@@ -17,7 +17,7 @@ n1=`g.tempfile pid=1 -d` # Only map names
 n2=`g.tempfile pid=2 -d` # Map names and start time
 n3=`g.tempfile pid=3 -d` # Map names start time and increment
 
-cat > $n1 << EOF
+cat > "${n1}" << EOF
 prec_1
 prec_2
 prec_3
@@ -25,9 +25,9 @@ prec_4
 prec_5
 prec_6
 EOF
-cat $n1
+cat "${n1}"
 
-cat > $n2 << EOF
+cat > "${n2}" << EOF
 prec_1|1
 prec_2|2
 prec_3|3
@@ -35,9 +35,9 @@ prec_4|4
 prec_5|5
 prec_6|6
 EOF
-cat $n2
+cat "${n2}"
 
-cat > $n3 << EOF
+cat > "${n3}" << EOF
 prec_1|1|4
 prec_2|4|7
 prec_3|7|10
@@ -45,7 +45,7 @@ prec_4|10|11
 prec_5|11|14
 prec_6|14|17
 EOF
-cat $n3
+cat "${n3}"
 
 # The first @test
 # We create the space time raster inputs and register the raster maps with absolute time interval
@@ -53,28 +53,28 @@ t.create --o type=strds temporaltype=relative output=precip_rel title="A test wi
 
 # Test with input files
 # File 1
-t.time.rel -i file=$n1 start=20 increment=5
+t.time.rel -i file="${n1}" start=20 increment=5 unit=months
 
-tr.register input=precip_rel file=$n1
+tr.register input=precip_rel file="${n1}"
 t.info type=strds input=precip_rel
 tr.list input=precip_rel
 
 # File 1
-t.time.rel file=$n1 start=20
+t.time.rel file="${n1}" start=20 unit=months
 t.info type=strds input=precip_rel
 tr.list input=precip_rel
 # File 2
-t.time.rel file=$n2 start=file
+t.time.rel file="${n2}" start=file unit=months
 t.info type=strds input=precip_rel
 tr.list input=precip_rel
 # File 2
-t.time.rel -i file=$n2 start=file increment=5
+t.time.rel -i file="${n2}" start=file increment=5 unit=months
 t.info type=strds input=precip_rel
 tr.list input=precip_rel
 # File 3
-t.time.rel file=$n3 start=file end=file
+t.time.rel file="${n3}" start=file end=file unit=months
 t.info type=strds input=precip_rel
 tr.list input=precip_rel
 
 t.remove --v type=strds input=precip_rel
-t.remove --v type=rast file=$n1
+t.remove --v type=rast file="${n1}"

+ 12 - 9
temporal/t.time.rel/test.t.time.rel.sh

@@ -13,33 +13,36 @@ 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 --v --o type=strds temporaltype=relative output=precip_rel1 title="A test" descr="A test"
+t.create --v --o type=strds temporaltype=relative output=precip_rel1 title="A test" descr="A test" 
 t.create --v --o type=strds temporaltype=relative output=precip_rel2 title="A test" descr="A test"
 t.create --v --o type=strds temporaltype=relative output=precip_rel3 title="A test" descr="A test"
 
-t.time.rel --v input=prec_1,prec_2,prec_3 start=5 increment=2
+t.time.rel --v input=prec_1,prec_2,prec_3 start=5 increment=2 unit=days
 t.info type=rast input=prec_1
+r.info map=prec_1
 t.info type=rast input=prec_2
+r.info map=prec_2
 t.info type=rast input=prec_3
+r.info map=prec_3
 
-tr.register --v input=precip_rel1 maps=prec_1,prec_2,prec_3
-tr.register --v input=precip_rel2 maps=prec_1,prec_2,prec_3
-tr.register --v input=precip_rel3 maps=prec_1,prec_2,prec_3
+tr.register --v input=precip_rel1 maps=prec_1,prec_2,prec_3 unit=days
+tr.register --v input=precip_rel2 maps=prec_1,prec_2,prec_3 unit=days
+tr.register --v input=precip_rel3 maps=prec_1,prec_2,prec_3 unit=days
 # Check if the space time inputs are updated correctly
-t.time.rel --v input=prec_1,prec_2,prec_3 start=0 increment=1000
+t.time.rel --v input=prec_1,prec_2,prec_3 start=0 increment=1000 unit=days
 t.info type=strds input=precip_rel1
 t.topology type=strds input=precip_rel1
 t.topology -m type=strds input=precip_rel1
 
-t.time.rel --v -i input=prec_1,prec_2,prec_3 start=0 increment=1000 -i
+t.time.rel --v -i input=prec_1,prec_2,prec_3 start=0 increment=1000 unit=days
 t.info type=strds input=precip_rel1
 t.topology type=strds input=precip_rel1
 t.topology -m type=strds input=precip_rel1
 
-t.time.rel --v input=prec_4,prec_5 start=5000 end=6000
+t.time.rel --v input=prec_4,prec_5 start=5000 end=6000 unit=days
 t.info type=rast input=prec_4
 t.info type=rast input=prec_5
-t.time.rel --v input=prec_6 start=6000
+t.time.rel --v input=prec_6 start=6000 unit=days
 t.info type=rast input=prec_6
 
 t.remove --v type=rast input=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6

+ 16 - 16
temporal/t.topology/test.t.topology.abstime.sh

@@ -23,7 +23,7 @@ n3=`g.tempfile pid=3 -d`
 n4=`g.tempfile pid=4 -d`
 n5=`g.tempfile pid=5 -d`
 
-cat > $n1 << EOF
+cat > "${n1}" << EOF
 prec_1
 prec_2
 prec_3
@@ -32,7 +32,7 @@ prec_5
 prec_6
 EOF
 
-cat > $n2 << EOF
+cat > "${n2}" << EOF
 prec_1|2001-01-01
 prec_2|2001-02-01
 prec_3|2001-03-01
@@ -41,7 +41,7 @@ prec_5|2001-05-01
 prec_6|2001-06-01
 EOF
 
-cat > $n3 << EOF
+cat > "${n3}" << EOF
 prec_1|2001-01-01|2001-04-01
 prec_2|2001-05-01|2001-07-01
 prec_3|2001-08-01|2001-10-01
@@ -50,7 +50,7 @@ prec_5|2002-02-01|2002-04-01
 prec_6|2002-05-01|2002-07-01
 EOF
 
-cat > $n4 << EOF
+cat > "${n4}" << 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
@@ -59,7 +59,7 @@ prec_5|2001-05-01|2001-06-01
 prec_6|2001-06-01|2001-07-01
 EOF
 
-cat > $n5 << EOF
+cat > "${n5}" << EOF
 prec_1|2001-01-01|2001-03-11
 prec_2|2001-02-01|2001-04-01
 prec_3|2001-03-01|2001-06-02
@@ -73,30 +73,30 @@ EOF
 # We create the space time raster inputs and register the raster maps with absolute time interval
 t.create --o type=strds temporaltype=absolute output=precip_abs title="A test with input files" descr="A test with input files"
 
-tr.register -i input=precip_abs file=$n1 start="2001-01-01" increment="1 months"
-cat $n1
+tr.register -i input=precip_abs file="${n1}" start="2001-01-01" increment="1 months"
+cat "${n1}"
 t.topology    input=precip_abs
 t.topology -m input=precip_abs
 
-tr.register -i input=precip_abs file=$n2 start=file
-cat $n2
+tr.register -i input=precip_abs file="${n2}" start=file
+cat "${n2}"
 t.topology    input=precip_abs
 t.topology -m input=precip_abs
 
-tr.register -i input=precip_abs file=$n3 start=file end=file
-cat $n3
+tr.register -i input=precip_abs file="${n3}" start=file end=file
+cat "${n3}"
 t.topology    input=precip_abs
 t.topology -m input=precip_abs
 
-tr.register -i input=precip_abs file=$n4 start=file end=file
-cat $n4
+tr.register -i input=precip_abs file="${n4}" start=file end=file
+cat "${n4}"
 t.topology    input=precip_abs
 t.topology -m input=precip_abs
 
-tr.register -i input=precip_abs file=$n5 start=file end=file
-cat $n5
+tr.register -i input=precip_abs file="${n5}" start=file end=file
+cat "${n5}"
 t.topology    input=precip_abs
 t.topology -m input=precip_abs
 
 t.remove type=strds input=precip_abs
-t.remove type=rast file=$n1
+t.remove type=rast file="${n1}"

+ 36 - 34
temporal/t.topology/test.t.topology.reltime.sh

@@ -23,7 +23,7 @@ n3=`g.tempfile pid=3 -d`
 n4=`g.tempfile pid=4 -d`
 n5=`g.tempfile pid=5 -d`
 
-cat > $n1 << EOF
+cat > "${n1}" << EOF
 prec_1
 prec_2
 prec_3
@@ -32,7 +32,7 @@ prec_5
 prec_6
 EOF
 
-cat > $n2 << EOF
+cat > "${n2}" << EOF
 prec_1|1
 prec_2|2
 prec_3|3
@@ -41,7 +41,7 @@ prec_5|5
 prec_6|6
 EOF
 
-cat > $n3 << EOF
+cat > "${n3}" << EOF
 prec_1|1|4
 prec_2|5|7
 prec_3|8|10
@@ -50,7 +50,7 @@ prec_5|13|14
 prec_6|15|25
 EOF
 
-cat > $n4 << EOF
+cat > "${n4}" << EOF
 prec_1|2001|2007
 prec_2|2002|2004
 prec_3|2003|2004
@@ -59,7 +59,7 @@ prec_5|2005|2006
 prec_6|2006|2007
 EOF
 
-cat > $n5 << EOF
+cat > "${n5}" << EOF
 prec_1|2001|2003
 prec_2|2002|2004
 prec_3|2003|2006
@@ -71,32 +71,34 @@ EOF
 
 # The first @test
 # We create the space time raster inputs and register the raster maps with relolute time interval
-t.create --o type=strds temporaltype=relative output=precip_rel title="A test with input files" descr="A test with input files"
-
-tr.register -i --v input=precip_rel file=$n1 start=0 increment=1
-cat $n1
-t.topology    input=precip_rel
-t.topology -m input=precip_rel
-
-tr.register -i input=precip_rel file=$n2 start=file
-cat $n2
-t.topology    input=precip_rel
-t.topology -m input=precip_rel
-
-tr.register -i input=precip_rel file=$n3 start=file end=file
-cat $n3
-t.topology    input=precip_rel
-t.topology -m input=precip_rel
-
-tr.register -i input=precip_rel file=$n4 start=file end=file
-cat $n4
-t.topology    input=precip_rel
-t.topology -m input=precip_rel
-
-tr.register -i input=precip_rel file=$n5 start=file end=file
-cat $n5
-t.topology    input=precip_rel
-t.topology -m input=precip_rel
-
-t.remove type=strds input=precip_rel
-t.remove type=rast file=$n1
+t.create --o type=strds temporaltype=relative output=precip_rel_d title="A test with input files of unti days" descr="A test with input files"
+t.create --o type=strds temporaltype=relative output=precip_rel_y title="A test with input files of unit years" descr="A test with input files"
+
+tr.register -i --v input=precip_rel_d file="${n1}" start=0 increment=1 unit=days
+cat "${n1}"
+t.topology    input=precip_rel_d
+t.topology -m input=precip_rel_d
+
+tr.register -i input=precip_rel_d file="${n2}" start=file unit=days
+cat "${n2}"
+t.topology    input=precip_rel_d
+t.topology -m input=precip_rel_d
+
+tr.register -i input=precip_rel_d file="${n3}" start=file end=file unit=days
+cat "${n3}"
+t.topology    input=precip_rel_d
+t.topology -m input=precip_rel_d
+
+tr.register -i input=precip_rel_y file="${n4}" start=file end=file unit=years
+cat "${n4}"
+t.topology    input=precip_rel_y
+t.topology -m input=precip_rel_y
+
+tr.register -i input=precip_rel_y file="${n5}" start=file end=file unit=years
+cat "${n5}"
+t.topology    input=precip_rel_y
+t.topology -m input=precip_rel_y
+
+t.remove type=strds input=precip_rel_d
+t.remove type=strds input=precip_rel_y
+t.remove type=rast file="${n1}"

+ 2 - 2
temporal/tr.aggregate.ds/test.tr.aggregate.ds.sh

@@ -20,14 +20,14 @@ v.random --o -z output=soil_3 n=20 zmin=0 zmax=100 column=height
 
 n1=`g.tempfile pid=1 -d` 
 
-cat > $n1 << EOF
+cat > "${n1}" << EOF
 soil_1|2001-01-01|2001-04-01
 soil_2|2001-05-01|2001-07-01
 soil_3|2001-08-01|2001-12-01
 EOF
 
 t.create --o type=stvds temporaltype=absolute output=soil_abs1 title="A test" descr="A test"
-tv.register input=soil_abs1 file="$n1" start=file end=file
+tv.register input=soil_abs1 file="${n1}" start=file end=file
 
 t.create --o type=strds temporaltype=absolute output=precip_abs1 title="A test" descr="A test"
 tr.register -i input=precip_abs1 maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 start="2001-03-01 00:00:00" increment="1 months"

+ 1 - 2
temporal/tr.aggregate.ds/tr.aggregate.ds.py

@@ -186,8 +186,7 @@ def main():
         input_map_names = tgis.collect_map_names(sp, dbif, start, end, sampling)
 
         if input_map_names:
-            tgis.aggregate_raster_maps(new_sp, mapset, input_map_names, base, start, end, count, method, register_null, dbif)
-        
+            tgis.aggregate_raster_maps(sp, new_sp, mapset, input_map_names, base, start, end, count, method, register_null, dbif)
 
     # Update the spatio-temporal extent and the raster metadata table entries
     new_sp.update_from_registered_maps(dbif)

+ 30 - 0
temporal/tr.aggregate/test.tr.aggregate.relative_time.sh

@@ -0,0 +1,30 @@
+# Test the extraction of a subset of a space time raster input
+
+# 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
+# Data generation
+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_abs1 title="A test" descr="A test"
+tr.register -i input=precip_abs1 maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 start=0 unit=days increment=3
+
+# The first @test
+
+tr.aggregate --o --v input=precip_abs1 output=precip_abs2 base=prec_sum granularity=6 method=average sampling=start,during
+t.info type=strds input=precip_abs2
+tr.aggregate --o --v input=precip_abs1 output=precip_abs2 base=prec_sum granularity=9 method=maximum sampling=start,during
+t.info type=strds input=precip_abs2
+tr.aggregate --o --v input=precip_abs1 output=precip_abs2 base=prec_sum granularity=4 method=minimum sampling=start,during
+t.info type=strds input=precip_abs2
+tr.aggregate --o --v input=precip_abs1 output=precip_abs2 base=prec_sum granularity=5 method=sum sampling=start,during
+t.info type=strds input=precip_abs2
+
+t.remove type=rast input=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6
+t.remove type=strds input=precip_abs1,precip_abs2

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

@@ -1,12 +1,10 @@
 # Test the extraction of a subset of a space time raster input
 
 # We need to set a specific region in the
-# @preprocess step of this test. We generate
-# raster with r.mapcalc and create two space time raster inputs
-# with relative and absolute time
+# @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)"

+ 8 - 3
temporal/tr.aggregate/tr.aggregate.py

@@ -145,7 +145,12 @@ def main():
             grass.fatal(_("Space time raster dataset <%s> is empty") % out_id)
 
     # Modify the start time to fit the granularity
-    first_start_time = tgis.adjust_datetime_to_granularity( rows[0]["start_time"], gran)
+
+    if sp.is_time_absolute():
+        first_start_time = tgis.adjust_datetime_to_granularity( rows[0]["start_time"], gran)
+    else:
+        first_start_time = rows[0]["start_time"]
+
     last_start_time = rows[len(rows) - 1]["start_time"]
     next_start_time = first_start_time
 
@@ -155,13 +160,13 @@ def main():
         if sp.is_time_absolute():
             end = tgis.increment_datetime_by_string(next_start_time, gran)
         else:
-            end = next_start_time + gran
+            end = next_start_time + int(gran)
         next_start_time = end
 
         input_map_names = tgis.collect_map_names(sp, dbif, start, end, sampling)
 
         if input_map_names:
-            tgis.aggregate_raster_maps(new_sp, mapset, input_map_names, base, start, end, count, method, register_null, dbif)
+            tgis.aggregate_raster_maps(sp, new_sp, mapset, input_map_names, base, start, end, count, method, register_null, dbif)
 
         count += 1
 

+ 2 - 2
temporal/tr.export/test.tr.export.sh

@@ -15,7 +15,7 @@ r.mapcalc --o expr="prec_6 = rand(0, 650)"
 
 n1=`g.tempfile pid=1 -d` 
 
-cat > $n1 << EOF
+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
@@ -27,7 +27,7 @@ EOF
 t.create --o type=strds temporaltype=absolute output=precip_abs1 title="A test with input files" descr="A test with input files"
 
 # The first @test
-tr.register -i input=precip_abs1 file=$n1 start="2001-01-01" increment="1 months"
+tr.register -i input=precip_abs1 file="${n1}" start="2001-01-01" increment="1 months"
 tr.export input=precip_abs1 output=strds_export.tar.bz2 compression=bzip2 workdir=/tmp
 
 t.remove type=rast input=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6

+ 11 - 11
temporal/tr.list/test.tr.list.sh

@@ -19,7 +19,7 @@ n3=`g.tempfile pid=3 -d`
 n4=`g.tempfile pid=4 -d`
 n5=`g.tempfile pid=5 -d`
 
-cat > $n1 << EOF
+cat > "${n1}" << EOF
 prec_1
 prec_2
 prec_3
@@ -28,7 +28,7 @@ prec_5
 prec_6
 EOF
 
-cat > $n2 << EOF
+cat > "${n2}" << EOF
 prec_1|2001-01-01
 prec_2|2001-02-01
 prec_3|2001-03-01
@@ -37,7 +37,7 @@ prec_5|2001-05-01
 prec_6|2001-06-01
 EOF
 
-cat > $n3 << EOF
+cat > "${n3}" << EOF
 prec_1|2001-01-01|2001-04-01
 prec_2|2001-05-01|2001-07-01
 prec_3|2001-08-01|2001-10-01
@@ -46,7 +46,7 @@ prec_5|2002-02-01|2002-04-01
 prec_6|2002-05-01|2002-07-01
 EOF
 
-cat > $n4 << EOF
+cat > "${n4}" << 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
@@ -55,7 +55,7 @@ prec_5|2001-05-01|2001-06-01
 prec_6|2001-06-01|2001-07-01
 EOF
 
-cat > $n5 << EOF
+cat > "${n5}" << EOF
 prec_1|2001-01-01|2001-03-11
 prec_2|2001-02-01|2001-04-01
 prec_3|2001-03-01|2001-06-02
@@ -72,7 +72,7 @@ t.create --o type=strds temporaltype=absolute output=precip_abs4 title="A test w
 t.create --o type=strds temporaltype=absolute output=precip_abs5 title="A test with input files" descr="A test with input files"
 
 # The @test
-tr.register -i input=precip_abs0 file=$n1 start="2001-01-01" increment="1 months"
+tr.register -i input=precip_abs0 file="${n1}" start="2001-01-01" increment="1 months"
 tr.list    fs=" | " method=comma     input=precip_abs0
 tr.list -h input=precip_abs1
 tr.list -h fs=" | " method=cols      input=precip_abs0
@@ -80,7 +80,7 @@ tr.list -h fs=" | " method=delta     input=precip_abs0
 tr.list -h fs=" | " method=deltagaps input=precip_abs0
 tr.list -h fs=" | " method=gran      input=precip_abs0
 
-tr.register    input=precip_abs1 file=$n1 start="2001-01-01" increment="1 months"
+tr.register    input=precip_abs1 file="${n1}" start="2001-01-01" increment="1 months"
 tr.list    fs=" | " method=comma     input=precip_abs1
 tr.list -h input=precip_abs1
 tr.list -h fs=" | " method=cols      input=precip_abs1
@@ -88,7 +88,7 @@ tr.list -h fs=" | " method=delta     input=precip_abs1
 tr.list -h fs=" | " method=deltagaps input=precip_abs1
 tr.list -h fs=" | " method=gran      input=precip_abs1
 
-tr.register -i input=precip_abs2 file=$n2 start=file
+tr.register -i input=precip_abs2 file="${n2}" start=file
 tr.list    fs=" | " method=comma     input=precip_abs2
 tr.list -h input=precip_abs2
 tr.list -h fs=" | " method=cols      input=precip_abs2
@@ -96,19 +96,19 @@ tr.list -h fs=" | " method=delta     input=precip_abs2
 tr.list -h fs=" | " method=deltagaps input=precip_abs2
 tr.list -h fs=" | " method=gran      input=precip_abs2
 
-tr.register -i input=precip_abs3 file=$n3 start=file end=file
+tr.register -i input=precip_abs3 file="${n3}" start=file end=file
 tr.list    fs=" | " method=comma     input=precip_abs3
 tr.list -h fs=" | " method=delta     input=precip_abs3
 tr.list -h fs=" | " method=deltagaps input=precip_abs3
 tr.list -h fs=" | " method=gran      input=precip_abs3
 
-tr.register -i input=precip_abs4 file=$n4 start=file end=file
+tr.register -i input=precip_abs4 file="${n4}" start=file end=file
 tr.list    fs=" | " method=comma     input=precip_abs4
 tr.list -h fs=" | " method=delta     input=precip_abs4
 tr.list -h fs=" | " method=deltagaps input=precip_abs4
 tr.list -h fs=" | " method=gran      input=precip_abs4
 
-tr.register -i input=precip_abs5 file=$n5 start=file end=file
+tr.register -i input=precip_abs5 file="${n5}" start=file end=file
 tr.list    fs=" | " method=comma     input=precip_abs5
 tr.list -h input=precip_abs5
 tr.list -h fs=" | " method=cols      input=precip_abs5

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

@@ -6,16 +6,16 @@ import grass.script as grass
 # You need to download the european climate date from the ECA&D server http://eca.knmi.nl/ as netCDF time series
 # We only use the data from 1995 - 2010
 # First import the ECA&D data into GRASS GIS 
-input = "tg_0.25deg_reg_1995-2010_v4.0.nc"
+input = "tg_0.25deg_reg_1995-2011_v5.0.nc"
 output = "temp_mean"
 grass.run_command("r.in.gdal", flags="e", input=input, output=output, overwrite=True)
-input = "tn_0.25deg_reg_1995-2010_v4.0.nc"
+input = "tn_0.25deg_reg_1995-2011_v5.0.nc"
 output = "temp_min"
 grass.run_command("r.in.gdal", flags="e", input=input, output=output, overwrite=True)
-input = "tx_0.25deg_reg_1995-2010_v4.0.nc"
+input = "tx_0.25deg_reg_1995-2011_v5.0.nc"
 output = "temp_max"
 grass.run_command("r.in.gdal", flags="e", input=input, output=output, overwrite=True)
-input = "rr_0.25deg_reg_1995-2010_v4.0.nc"
+input = "rr_0.25deg_reg_1995-2011_v5.0.nc"
 output = "precip"
 grass.run_command("r.in.gdal", flags="e", input=input, output=output, overwrite=True)
 
@@ -25,12 +25,12 @@ num_maps = 5844
 
 # Daily mean temperatue
 
-dataset = "temp_mean_1995_2010_daily"
+dataset = "temp_mean_1995_2011_daily"
 
 grass.run_command("t.create", type="strds", output=dataset,\
                   semantic="continuous", temporal="absolute", \
-		  title="European mean temperature 1995-2010", \
-		  description="The european daily mean temperature 1995 - 2010 from ECA&D ", \
+		  title="European mean temperature 1995-2011", \
+		  description="The european daily mean temperature 1995 - 2011 from ECA&D ", \
 		  overwrite=True)
 
 name = "temp_mean."

+ 12 - 12
temporal/tr.register/test.tr.register.file.sh

@@ -21,7 +21,7 @@ n1=`g.tempfile pid=1 -d` # Only map names
 n2=`g.tempfile pid=2 -d` # Map names and start time
 n3=`g.tempfile pid=3 -d` # Map names start time and increment
 
-cat > $n1 << EOF
+cat > "${n1}" << EOF
 prec_1
 prec_2
 prec_3
@@ -29,9 +29,9 @@ prec_4
 prec_5
 prec_6
 EOF
-cat $n1
+cat "${n1}"
 
-cat > $n2 << EOF
+cat > "${n2}" << EOF
 prec_1|2001-01-01
 prec_2|2001-02-01
 prec_3|2001-03-01
@@ -39,9 +39,9 @@ prec_4|2001-04-01
 prec_5|2001-05-01
 prec_6|2001-06-01
 EOF
-cat $n2
+cat "${n2}"
 
-cat > $n3 << EOF
+cat > "${n3}" << EOF
 prec_1|2001-01-01|2001-04-01
 prec_2|2001-04-01|2001-07-01
 prec_3|2001-07-01|2001-10-01
@@ -49,7 +49,7 @@ prec_4|2001-10-01|2002-01-01
 prec_5|2002-01-01|2002-04-01
 prec_6|2002-04-01|2002-07-01
 EOF
-cat $n3
+cat "${n3}"
 
 # The first @test
 # We create the space time raster inputs and register the raster maps with absolute time interval
@@ -57,25 +57,25 @@ t.create --o type=strds temporaltype=absolute output=precip_abs8 title="A test w
 
 # Test with input files
 # File 1
-tr.register -i input=precip_abs8 file=$n1 start="2001-01-01" increment="1 months"
+tr.register -i input=precip_abs8 file="${n1}" start="2001-01-01" increment="1 months"
 t.info type=strds input=precip_abs8
 tr.list input=precip_abs8
 # File 1
-tr.register input=precip_abs8 file=$n1 start="2001-01-01" 
+tr.register input=precip_abs8 file="${n1}" start="2001-01-01" 
 t.info type=strds input=precip_abs8
 tr.list input=precip_abs8
 # File 2
-tr.register input=precip_abs8 file=$n2 start=file
+tr.register input=precip_abs8 file="${n2}" start=file
 t.info type=strds input=precip_abs8
 tr.list input=precip_abs8
 # File 2
-tr.register input=precip_abs8 file=$n2 start=file increment="1 months"
+tr.register input=precip_abs8 file="${n2}" start=file increment="1 months"
 t.info type=strds input=precip_abs8
 tr.list input=precip_abs8
 # File 3
-tr.register -i input=precip_abs8 file=$n3 start=file end=file
+tr.register -i input=precip_abs8 file="${n3}" start=file end=file
 t.info type=strds input=precip_abs8
 tr.list input=precip_abs8
 
 t.remove --v type=strds input=precip_abs8
-t.remove --v type=rast file=$n1
+t.remove --v type=rast file="${n1}"

+ 13 - 2
temporal/tr.register/tr.register.py

@@ -61,9 +61,19 @@
 #%end
 
 #%option
+#% key: unit
+#% type: string
+#% description: The unit of the relative time
+#% required: no
+#% multiple: no
+#% options: years,months,days,hours,minutes,seconds
+#% answer: days
+#%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), or "file" in case the increment is located in an input file
+#% description: Time increment between maps for valid time interval creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative is integer: 5), or "file" in case the increment is located in an input file
 #% required: no
 #% multiple: no
 #%end
@@ -95,6 +105,7 @@ def main():
     fs = options["fs"]
     start = options["start"]
     end = options["end"]
+    unit = options["unit"]
     increment = options["increment"]
     interval = flags["i"]
 
@@ -102,7 +113,7 @@ def main():
     tgis.create_temporal_database()
     # Register maps
     tgis.register_maps_in_space_time_dataset(type="strds", name=name, maps=maps, file=file, start=start, end=end, \
-                                             increment=increment, dbif=None, interval=interval, fs=fs)
+                                             unit=unit, increment=increment, dbif=None, interval=interval, fs=fs)
     
 if __name__ == "__main__":
     options, flags = grass.parser()

+ 3 - 1
temporal/tr.series/tr.series.py

@@ -120,12 +120,14 @@ def main():
                 id = output + "@" + mapset
 
             map = sp.get_new_map_instance(id)
-
             map.load()
+
             if sp.is_time_absolute():
                 map.set_absolute_time(start_time, end_time, tz)
+                map.write_absolute_time_to_file()
             else:
                 map.set_relative_time(start_time, end_time)
+                map.write_relative_time_to_file()
 
             # Register the map in the temporal database
             if map.is_in_db():

+ 3 - 5
temporal/tr.univar/test.tr.univar.sh

@@ -1,12 +1,10 @@
 # Test the extraction of a subset of a space time raster input
 
 # We need to set a specific region in the
-# @preprocess step of this test. We generate
-# raster with r.mapcalc and create two space time raster inputs
-# with relative and absolute time
+# @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
-
+# Data generation
 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)"
@@ -21,4 +19,4 @@ tr.register --v -i input=precip_abs1 maps=prec_1,prec_2,prec_3,prec_4,prec_5,pre
 tr.univar -he input=precip_abs1 
 
 t.remove type=rast input=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6
-t.remove type=strds input=precip_abs1,precip_abs2
+t.remove type=strds input=precip_abs1

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

@@ -35,6 +35,12 @@ t.info type=str3ds input=volume_abs1
 
 tr3.register --v -i input=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 input=volume_abs2
+r3.info volume_1
+r3.info volume_2
+r3.info volume_3
+r3.info volume_4
+r3.info volume_5
+r3.info volume_6
 
 tr3.register --v -i input=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 input=volume_abs3

+ 13 - 2
temporal/tr3.register/tr3.register.py

@@ -61,9 +61,19 @@
 #%end
 
 #%option
+#% key: unit
+#% type: string
+#% description: The unit of the relative time
+#% required: no
+#% multiple: no
+#% options: years,months,days,hours,minutes,seconds
+#% answer: days
+#%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), or "file" in case the increment is located in an input file
+#% description: Time increment between maps for valid time interval creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative is integer: 5), or "file" in case the increment is located in an input file
 #% required: no
 #% multiple: no
 #%end
@@ -95,6 +105,7 @@ def main():
     fs = options["fs"]
     start = options["start"]
     end = options["end"]
+    unit = options["unit"]
     increment = options["increment"]
     interval = flags["i"]
 
@@ -102,7 +113,7 @@ def main():
     tgis.create_temporal_database()
     # Register maps
     tgis.register_maps_in_space_time_dataset(type="str3ds", name=name, maps=maps, file=file, start=start, end=end, \
-                                             increment=increment, dbif=None, interval=interval, fs=fs)
+                                             unit=unit, increment=increment, dbif=None, interval=interval, fs=fs)
     
 if __name__ == "__main__":
     options, flags = grass.parser()

+ 11 - 12
temporal/tv.list/test.tv.list.sh

@@ -1,8 +1,7 @@
 # This is a test to list vecter maps of a space time vecter dataset
 
 # We need to set a specific region in the
-# @preprocess step of this test. We generate
-# vecter with r.mapcalc and create a space time vecter datasets
+# @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
 
@@ -19,7 +18,7 @@ n3=`g.tempfile pid=3 -d`
 n4=`g.tempfile pid=4 -d`
 n5=`g.tempfile pid=5 -d`
 
-cat > $n1 << EOF
+cat > "${n1}" << EOF
 lidar_1
 lidar_2
 lidar_3
@@ -28,7 +27,7 @@ lidar_5
 lidar_6
 EOF
 
-cat > $n2 << EOF
+cat > "${n2}" << EOF
 lidar_1|2001-01-01
 lidar_2|2001-02-01
 lidar_3|2001-03-01
@@ -37,7 +36,7 @@ lidar_5|2001-05-01
 lidar_6|2001-06-01
 EOF
 
-cat > $n3 << EOF
+cat > "${n3}" << EOF
 lidar_1|2001-01-01|2001-04-01
 lidar_2|2001-05-01|2001-07-01
 lidar_3|2001-08-01|2001-10-01
@@ -46,7 +45,7 @@ lidar_5|2002-02-01|2002-04-01
 lidar_6|2002-05-01|2002-07-01
 EOF
 
-cat > $n4 << EOF
+cat > "${n4}" << EOF
 lidar_1|2001-01-01|2001-07-01
 lidar_2|2001-02-01|2001-04-01
 lidar_3|2001-03-01|2001-04-01
@@ -55,7 +54,7 @@ lidar_5|2001-05-01|2001-06-01
 lidar_6|2001-06-01|2001-07-01
 EOF
 
-cat > $n5 << EOF
+cat > "${n5}" << EOF
 lidar_1|2001-01-01|2001-03-11
 lidar_2|2001-02-01|2001-04-01
 lidar_3|2001-03-01|2001-06-02
@@ -71,31 +70,31 @@ t.create --o type=stvds temporaltype=absolute output=lidar_abs4 title="A test wi
 t.create --o type=stvds temporaltype=absolute output=lidar_abs5 title="A test with input files" descr="A test with input files"
 
 # The first @test
-tv.register    input=lidar_abs1 file=$n1 start="2001-01-01" increment="1 months"
+tv.register    input=lidar_abs1 file="${n1}" start="2001-01-01" increment="1 months"
 tv.list    fs=" | " method=comma     input=lidar_abs1
 tv.list -h input=lidar_abs1
 tv.list -h fs=" | " method=cols      input=lidar_abs1
 tv.list -h fs=" | " method=delta     input=lidar_abs1
 tv.list -h fs=" | " method=deltagaps input=lidar_abs1
 
-tv.register -i input=lidar_abs2 file=$n2 start=file
+tv.register -i input=lidar_abs2 file="${n2}" start=file
 tv.list    fs=" | " method=comma     input=lidar_abs2
 tv.list -h input=lidar_abs2
 tv.list -h fs=" | " method=cols      input=lidar_abs2
 tv.list -h fs=" | " method=delta     input=lidar_abs2
 tv.list -h fs=" | " method=deltagaps input=lidar_abs2
 
-tv.register -i input=lidar_abs3 file=$n3 start=file end=file
+tv.register -i input=lidar_abs3 file="${n3}" start=file end=file
 tv.list    fs=" | " method=comma     input=lidar_abs3
 tv.list -h fs=" | " method=delta     input=lidar_abs3
 tv.list -h fs=" | " method=deltagaps input=lidar_abs3
 
-tv.register -i input=lidar_abs4 file=$n4 start=file end=file
+tv.register -i input=lidar_abs4 file="${n4}" start=file end=file
 tv.list    fs=" | " method=comma     input=lidar_abs4
 tv.list -h fs=" | " method=delta     input=lidar_abs4
 tv.list -h fs=" | " method=deltagaps input=lidar_abs4
 
-tv.register -i input=lidar_abs5 file=$n5 start=file end=file
+tv.register -i input=lidar_abs5 file="${n5}" start=file end=file
 tv.list    fs=" | " method=comma     input=lidar_abs5
 tv.list -h input=lidar_abs5
 tv.list -h fs=" | " method=cols      input=lidar_abs5

+ 13 - 2
temporal/tv.register/tv.register.py

@@ -61,9 +61,19 @@
 #%end
 
 #%option
+#% key: unit
+#% type: string
+#% description: The unit of the relative time
+#% required: no
+#% multiple: no
+#% options: years,months,days,hours,minutes,seconds
+#% answer: days
+#%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), or "file" in case the increment is located in an input file
+#% description: Time increment between maps for valid time interval creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative is integer: 5), or "file" in case the increment is located in an input file
 #% required: no
 #% multiple: no
 #%end
@@ -95,6 +105,7 @@ def main():
     fs = options["fs"]
     start = options["start"]
     end = options["end"]
+    unit = options["unit"]
     increment = options["increment"]
     interval = flags["i"]
 
@@ -102,7 +113,7 @@ def main():
     tgis.create_temporal_database()
     # Register maps
     tgis.register_maps_in_space_time_dataset(type="stvds", name=name, maps=maps, file=file, start=start, end=end, \
-                                             increment=increment, dbif=None, interval=interval, fs=fs)
+                                             unit=unit, increment=increment, dbif=None, interval=interval, fs=fs)
     
 if __name__ == "__main__":
     options, flags = grass.parser()

+ 2 - 2
temporal/tv.what.rast/test.tv.what.rast.sh

@@ -17,14 +17,14 @@ v.random --o -z output=soil_3 n=5 zmin=0 zmax=100 column=height seed=3
 
 n1=`g.tempfile pid=1 -d` 
 
-cat > $n1 << EOF
+cat > "${n1}" << EOF
 soil_1|2001-01-01|2001-04-01
 soil_2|2001-05-01|2001-07-01
 soil_3|2001-08-01|2001-12-01
 EOF
 
 t.create --o type=stvds temporaltype=absolute output=soil_abs1 title="A test" descr="A test"
-tv.register input=soil_abs1 file="$n1" start=file end=file
+tv.register input=soil_abs1 file="${n1}" start=file end=file
 
 t.create --o type=strds temporaltype=absolute output=precip_abs1 title="A test" descr="A test"
 tr.register -i input=precip_abs1 maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 start="2001-03-01 00:00:00" increment="1 months"