Jelajahi Sumber

Added (r|r3|v).timestamp read support in t.register.

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@58084 15284696-431f-4ddb-bdfa-cd5b030d7da7
Soeren Gebbert 11 tahun lalu
induk
melakukan
cd02035822

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

@@ -119,10 +119,10 @@ class AbstractMapDataset(AbstractDataset):
            in the grass file system based spatial database and
            set the internal time stamp that should be insert/updated
            in the temporal database.
-           
+
            @param ts The timetsamp to be set, is of type libgis.TimeStamp()
         """
-        
+
         if not self.has_grass_timestamp():
             return False
 
@@ -130,22 +130,22 @@ class AbstractMapDataset(AbstractDataset):
         dt2 = libgis.DateTime()
         count = ctypes.c_int()
 
-        libgis.G_get_timestamps(ctypes.byref(ts), 
-                                ctypes.byref(dt1), 
-                                ctypes.byref(dt2), 
+        libgis.G_get_timestamps(ctypes.byref(ts),
+                                ctypes.byref(dt1),
+                                ctypes.byref(dt2),
                                 ctypes.byref(count))
-                                 
-        
+
+
         if dt1.mode == libdate.DATETIME_ABSOLUTE:
             pdt1 = None
             pdt2 = None
-            if count >= 1:
-                pdt1 = datetime(int(dt1.year), int(dt1.month), int(dt1.day), 
-                                int(dt1.hour), int(dt1.minute), 
+            if count.value >= 1:
+                pdt1 = datetime(int(dt1.year), int(dt1.month), int(dt1.day),
+                                int(dt1.hour), int(dt1.minute),
                                 int(dt1.second))
-            if count == 2:
-                pdt2 = datetime(int(dt2.year), int(dt2.month), int(dt2.day), 
-                                int(dt2.hour), int(dt2.minute), 
+            if count.value == 2:
+                pdt2 = datetime(int(dt2.year), int(dt2.month), int(dt2.day),
+                                int(dt2.hour), int(dt2.minute),
                                 int(dt2.second))
 
             # ATTENTION: We ignore the time zone
@@ -188,7 +188,7 @@ class AbstractMapDataset(AbstractDataset):
                 elif dt2.seconds > 0:
                     end = dt2.seconds
             self.set_relative_time(start, end, unit)
- 
+
         return True
 
     @abstractmethod
@@ -433,7 +433,7 @@ class AbstractMapDataset(AbstractDataset):
            @param end_time a datetime object specifying the end time of the
                            map, None in case or time instance
            @param timezone Thee timezone of the map (not used)
-           
+
            @return True for success and False otherwise
         """
         if start_time and not isinstance(start_time, datetime):
@@ -508,12 +508,12 @@ class AbstractMapDataset(AbstractDataset):
            @param timezone Thee timezone of the map (not used)
            @param dbif The database interface to be used
            """
-           
+
         if self.get_mapset() != get_current_mapset():
             core.fatal(_("Unable to update dataset <%(ds)s> of type %(type)s in the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
-            
+
 
         if self.set_absolute_time(start_time, end_time, timezone):
             dbif, connected = init_dbif(dbif)
@@ -522,7 +522,7 @@ class AbstractMapDataset(AbstractDataset):
 
             if connected:
                 dbif.close()
-    
+
             self.write_timestamp_to_grass()
 
     def set_relative_time(self, start_time, end_time, unit):
@@ -611,7 +611,7 @@ class AbstractMapDataset(AbstractDataset):
 
             if connected:
                 dbif.close()
-    
+
             self.write_timestamp_to_grass()
 
     def set_temporal_extent(self, extent):
@@ -909,7 +909,7 @@ class AbstractMapDataset(AbstractDataset):
             core.fatal(_("Unable to delete dataset <%(ds)s> of type %(type)s from the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
-            
+
         dbif, connected = init_dbif(dbif)
         statement = ""
 
@@ -976,12 +976,12 @@ class AbstractMapDataset(AbstractDataset):
         #    core.verbose(_("Unregister %(type)s map <%(map)s> "
         #                   "from space time datasets"
         #                 % {'type':self.get_type(), 'map':self.get_map_id()}))
-        
+
         if self.get_mapset() != get_current_mapset():
             core.fatal(_("Unable to unregister dataset <%(ds)s> of type %(type)s from the temporal database."
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
-            
+
         statement = ""
         dbif, connected = init_dbif(dbif)
 

+ 13 - 9
lib/python/temporal/register.py

@@ -177,26 +177,25 @@ def register_maps_in_space_time_dataset(
 
         # Put the map into the database
         if not map.is_in_db(dbif):
-            is_in_db = False
             # Break in case no valid time is provided
-            if start == "" or start is None:
+            if (start == "" or start is None) and not map.has_grass_timestamp():
                 dbif.close()
                 if map.get_layer():
                     core.fatal(_("Unable to register %(t)s map <%(id)s> with "
-                                 "layer %(l)s. The map has no valid time and "
+                                 "layer %(l)s. The map has timestamp and "
                                  "the start time is not set.") % {
                                  't': map.get_type(), 'id': map.get_map_id(),
                                  'l': map.get_layer()})
                 else:
                     core.fatal(_("Unable to register %(t)s map <%(id)s>. The"
-                                 " map has no valid time and the start time "
+                                 " map has no timestamp and the start time "
                                  "is not set.") % {'t': map.get_type(),
                                                    'id': map.get_map_id()})
-
-            if unit:
-                map.set_time_to_relative()
-            else:
-                map.set_time_to_absolute()
+            if start != "" and start != None:
+                if unit:
+                    map.set_time_to_relative()
+                else:
+                    map.set_time_to_absolute()
 
         else:
             is_in_db = True
@@ -247,6 +246,11 @@ def register_maps_in_space_time_dataset(
         # Load the data from the grass file database
         map.load()
 
+        # Try to read an existing time stamp from the grass spatial database
+        # in case this map wasn't already registered in the temporal database
+        if not is_in_db:
+            map.read_timestamp_from_grass()
+
         # Set the valid time
         if start:
             # In case the time is in the input file we ignore the increment

+ 60 - 16
temporal/t.register/t.register.html

@@ -1,25 +1,34 @@
 <h2>DESCRIPTION</h2>
 
-The module <em>t.register</em> is designed to register raster, 3D raster and 
+The module <em>t.register</em> is designed to register raster, 3D raster and
 vector maps in the temporal database and in specific space time datasets.
 This module must be used to assign time stamps to raster, 3D raster and vector maps.
 The existing timestamp modules <a href="r.timestamp.html">r.timestamp</a>,
-<a href="r3.timestamp.html">r3.timestamp</a> and <a href="v.timestamp.html">v.timestamp</a> 
-should not be used, since they do not register the maps in the temporal database of GRASS.
+<a href="r3.timestamp.html">r3.timestamp</a> and <a href="v.timestamp.html">v.timestamp</a>
+do not register the maps in the temporal database of GRASS. However, timestamps that have been
+created with these modules can be read and used by <em>t.register</em>. This works only for
+maps that are not already registered in the temporal database.
 <p>
-This module supports absolute and relative time. Maps can be registered by command line argument 
+This module supports absolute and relative time. Maps can be registered by command line argument
 (a list of comma separated map names) or using an input file.
 The start time, the end time and a temporal increment can be provided by command line
 or in the input file.
 End time and increment are mutual exclusive.
-The user can register single maps or a list of maps at once. Maps can be registered in several 
-space time datasets using the same time stamp.
+The user can register single maps or a list of maps at once. Maps can be registered in several
+space time datasets using the same timestamp.
 <p>
 Start time and end time with absolute time must be provided using the format <b>yyyy-mm-dd HH:MM:SS +HHMM</b>.
 It is supported to specify only the date <b>yyyy-mm-dd</b>.
 In case of relative time the temporal unit (years, months, days, hours, minutes or seconds) must be provided.
 The relative start time, end time and the increment are integers.
 
+<h2>Note</h2>
+The timestamps of registred maps will be stored in the temporal
+database and in the metadata of the grass maps in the spatial database. This assures
+that timestamps can always be accessed with <em>(r|r3|v).timestamp</em> and the temporal
+modules. Timestamps should only be modified with <em>t.register</em> because
+the <em>(r|r3|v).timestamp</em> modules have no access to the temporal database.
+
 <p>
 
 
@@ -56,23 +65,58 @@ prec_6|2002-04-01|2002-07-01
 <h2>EXAMPLE</h2>
 
 In this example we create 6 raster maps that will be registered in a single space time
-raster dataset named <em>precip_abs</em> using a monthly temporal granularity. The -i flag generates interval time.
+raster dataset named <em>precip_abs</em> using a monthly temporal granularity.
+The -i flag generates interval time. The generated timestamps will be
+inspected using <em>r.timestamp</em> and t.rast.list.
+We will register an additional map with
+a timetsamp that was set with <em>r.timestamp</em>.
 
 <div class="code"><pre>
-r.mapcalc --o expr="prec_1 = 100"
-r.mapcalc --o expr="prec_2 = 200"
-r.mapcalc --o expr="prec_3 = 300"
-r.mapcalc --o expr="prec_4 = 400"
-r.mapcalc --o expr="prec_5 = 500"
-r.mapcalc --o expr="prec_6 = 600"
-
-t.create --o type=strds temporaltype=absolute \
-    output=precip_abs title="Eexample" \
+r.mapcalc expr="prec_1 = 100"
+r.mapcalc expr="prec_2 = 200"
+r.mapcalc expr="prec_3 = 300"
+r.mapcalc expr="prec_4 = 400"
+r.mapcalc expr="prec_5 = 500"
+r.mapcalc expr="prec_6 = 600"
+
+t.create type=strds temporaltype=absolute \
+    output=precip_abs title="Example" \
     descr="Example"
 
 t.register -i type=rast input=precip_abs \
     maps=prec_1,prec_2,prec_3,prec_4,prec_5,prec_6 \
     start="2001-01-01" increment="1 months"
+
+r.timestamp prec_1
+1 Jan 2001 00:00:00 / 1 Feb 2001 00:00:00
+
+r.timestamp prec_2
+1 Feb 2001 00:00:00 / 1 Mar 2001 00:00:00
+
+t.rast.list input=precip_abs
+
+prec_1	test2	2001-01-01 00:00:00	2001-02-01 00:00:00
+prec_2	test2	2001-02-01 00:00:00	2001-03-01 00:00:00
+prec_3	test2	2001-03-01 00:00:00	2001-04-01 00:00:00
+prec_4	test2	2001-04-01 00:00:00	2001-05-01 00:00:00
+prec_5	test2	2001-05-01 00:00:00	2001-06-01 00:00:00
+prec_6	test2	2001-06-01 00:00:00	2001-07-01 00:00:00
+
+r.mapcalc expr="prec_7 = 700"
+r.timestamp map=prec_7 date="1 jul 2001 / 1 aug 2001"
+
+t.register type=rast input=precip_abs maps=prec_7
+
+t.rast.list input=precip_abs
+
+prec_1	test2	2001-01-01 00:00:00	2001-02-01 00:00:00
+prec_2	test2	2001-02-01 00:00:00	2001-03-01 00:00:00
+prec_3	test2	2001-03-01 00:00:00	2001-04-01 00:00:00
+prec_4	test2	2001-04-01 00:00:00	2001-05-01 00:00:00
+prec_5	test2	2001-05-01 00:00:00	2001-06-01 00:00:00
+prec_6	test2	2001-06-01 00:00:00	2001-07-01 00:00:00
+prec_7	test2	2001-07-01 00:00:00	2001-08-01 00:00:00
+
 </pre></div>
 
 

+ 37 - 0
temporal/t.register/test.t.register.raster.timestamp.sh

@@ -0,0 +1,37 @@
+#!/bin/sh
+# This is a test to register and unregister raster maps in
+# space time raster datasets.
+# The raster maps will be registered in different space time raster
+# datasets.
+
+# We need to set a specific region in the
+# @preprocess step of this test. We generate
+# raster with r.mapcalc and create several space time raster datasets
+# with absolute time
+# The region setting should work for UTM and LL test locations
+g.region s=0 n=80 w=0 e=120 b=0 t=50 res=10 res3=10 -p3
+
+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.timestamp map=prec_1 date="1 jan 1995 / 23 sep 1995"
+r.timestamp map=prec_2 date="14 jul 1996 / 15 jul 1996"
+r.timestamp map=prec_3 date="1 mar 1998"
+r.timestamp map=prec_4 date="17 mar 1950 / 28 apr 1960"
+
+# The first @test
+# 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_abs1 title="A test" descr="A test"
+
+t.register --o -i input=precip_abs1 maps=prec_1,prec_2,prec_3,prec_4
+t.info type=strds input=precip_abs1
+t.info -g type=strds input=precip_abs1
+r.info map=prec_1
+t.rast.list input=precip_abs1
+t.topology input=precip_abs1
+
+# Test the warning message
+t.remove -rf type=strds input=precip_abs1