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

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Oct 20 14:47:03 PDT 2013


Author: huhabla
Date: 2013-10-20 14:47:03 -0700 (Sun, 20 Oct 2013)
New Revision: 58078

Modified:
   grass/trunk/lib/python/temporal/abstract_map_dataset.py
   grass/trunk/lib/python/temporal/space_time_datasets.py
Log:
Read support for timestamps set with *.timestamp modules implemented.


Modified: grass/trunk/lib/python/temporal/abstract_map_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_map_dataset.py	2013-10-20 13:08:26 UTC (rev 58077)
+++ grass/trunk/lib/python/temporal/abstract_map_dataset.py	2013-10-20 21:47:03 UTC (rev 58078)
@@ -14,6 +14,9 @@
 """
 from abstract_dataset import *
 from datetime_math import *
+import grass.lib.date as libdate
+import grass.lib.gis as libgis
+import ctypes
 
 
 class AbstractMapDataset(AbstractDataset):
@@ -89,6 +92,7 @@
         raise ImplementationError(
             "This method must be implemented in the subclasses")
 
+
     @abstractmethod
     def has_grass_timestamp(self):
         """!Check if a grass file based time stamp exists for this map.
@@ -103,6 +107,91 @@
         """
 
     @abstractmethod
+    def read_timestamp_from_grass(self):
+        """!Read the timestamp of this map from the map metadata
+           in the grass file system based spatial database and
+           set the internal time stamp that should be insert/updated
+           in the temporal database.
+        """
+
+    def _set_timestamp_from_grass(self, ts):
+        """!Set the timestamp of this map from the map metadata
+           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
+
+        dt1 = libgis.DateTime()
+        dt2 = libgis.DateTime()
+        count = ctypes.c_int()
+
+        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), 
+                                int(dt1.second))
+            if count == 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
+            # TODO: Write time zone support
+            self.set_absolute_time(pdt1, pdt2, None)
+        else:
+            unit = None
+            start = None
+            end = None
+            if count >= 1:
+                if dt1.year > 0:
+                    unit = "years"
+                    start = dt1.year
+                elif dt1.month > 0:
+                    unit = "months"
+                    start = dt1.month
+                elif dt1.day > 0:
+                    unit = "days"
+                    start = dt1.day
+                elif dt1.hour > 0:
+                    unit = "hours"
+                    start = dt1.hour
+                elif dt1.minute > 0:
+                    unit = "minutess"
+                    start = dt1.minutes
+                elif dt1.seconds > 0:
+                    unit = "seconds"
+                    start = dt1.seconds
+            if count == 2:
+                if dt2.year > 0:
+                    end = dt2.year
+                elif dt2.month > 0:
+                    end = dt2.month
+                elif dt2.day > 0:
+                    end = dt2.day
+                elif dt2.hour > 0:
+                    end = dt2.hour
+                elif dt2.minute > 0:
+                    end = dt2.minutes
+                elif dt2.seconds > 0:
+                    end = dt2.seconds
+            self.set_relative_time(start, end, unit)
+ 
+        return True
+
+    @abstractmethod
     def remove_timestamp_from_grass(self):
         """!Remove the timestamp from the grass file
            system based spatial database
@@ -344,42 +433,50 @@
            @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):
             if self.get_layer() is not None:
-                core.fatal(_("Start time must be of type datetime for %(type)s"
+                core.error(_("Start time must be of type datetime for %(type)s"
                              " map <%(id)s> with layer: %(l)s") % {
                              'type': self.get_type(), 'id': self.get_map_id(),
                              'l': self.get_layer()})
+                return False
             else:
-                core.fatal(_("Start time must be of type datetime for "
+                core.error(_("Start time must be of type datetime for "
                              "%(type)s map <%(id)s>") % {
                              'type': self.get_type(), 'id': self.get_map_id()})
+                return False
 
         if end_time and not isinstance(end_time, datetime):
             if self.get_layer():
-                core.fatal(_("End time must be of type datetime for %(type)s "
+                core.error(_("End time must be of type datetime for %(type)s "
                              "map <%(id)s> with layer: %(l)s") % {
                              'type': self.get_type(), 'id': self.get_map_id(),
                              'l': self.get_layer()})
+                return False
             else:
-                core.fatal(_("End time must be of type datetime for "
+                core.error(_("End time must be of type datetime for "
                              "%(type)s map <%(id)s>") % {
                              'type': self.get_type(), 'id': self.get_map_id()})
+                return False
 
         if start_time is not None and end_time is not None:
             if start_time > end_time:
                 if self.get_layer():
-                    core.fatal(_("End time must be greater than start time for"
+                    core.error(_("End time must be greater than start time for"
                                  " %(type)s map <%(id)s> with layer: %(l)s") % {
                                  'type': self.get_type(),
                                  'id': self.get_map_id(),
                                  'l': self.get_layer()})
+                    return False
                 else:
-                    core.fatal(_("End time must be greater than start time "
+                    core.error(_("End time must be greater than start time "
                                  "for %(type)s map <%(id)s>") % {
                                  'type': self.get_type(),
                                  'id': self.get_map_id()})
+                    return False
             else:
                 # Do not create an interval in case start and end time are
                 # equal
@@ -417,17 +514,17 @@
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
             
-        dbif, connected = init_dbif(dbif)
 
-        self.set_absolute_time(start_time, end_time, timezone)
-        self.absolute_time.update_all(dbif)
-        self.base.update(dbif)
+        if self.set_absolute_time(start_time, end_time, timezone):
+            dbif, connected = init_dbif(dbif)
+            self.absolute_time.update_all(dbif)
+            self.base.update(dbif)
 
-        if connected:
-            dbif.close()
+            if connected:
+                dbif.close()
+    
+            self.write_timestamp_to_grass()
 
-        self.write_timestamp_to_grass()
-
     def set_relative_time(self, start_time, end_time, unit):
         """!Set the relative time interval
 
@@ -507,17 +604,16 @@
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
 
-        dbif, connected = init_dbif(dbif)
-
         if self.set_relative_time(start_time, end_time, unit):
+            dbif, connected = init_dbif(dbif)
             self.relative_time.update_all(dbif)
             self.base.update(dbif)
 
-        if connected:
-            dbif.close()
+            if connected:
+                dbif.close()
+    
+            self.write_timestamp_to_grass()
 
-        self.write_timestamp_to_grass()
-
     def set_temporal_extent(self, extent):
         """!Convenient method to set the temporal extent from a temporal extent object
 

Modified: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py	2013-10-20 13:08:26 UTC (rev 58077)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py	2013-10-20 21:47:03 UTC (rev 58078)
@@ -9,15 +9,6 @@
 License (>=v2). Read the file COPYING that comes with GRASS
 for details.
 
-
->>> import grass.script as grass
-
->>> grass.run_command("r3.mapcalc", overwrite=True, expression="str3ds_map_test_case = 1")
-0
->>> grass.run_command("v.random", overwrite=True, output="stvds_map_test_case",
-... n=100, zmin=0, zmax=100, flags="z", column="elevation")
-0
-
 @author Soeren Gebbert
 """
 import getpass
@@ -52,15 +43,19 @@
         >>> grass.run_command("r.mapcalc", overwrite=True,
         ... expression="strds_map_test_case = 1")
         0
+        >>> grass.run_command("r.timestamp", map="strds_map_test_case", 
+        ...                   date="15 jan 1999")
+        0
         >>> mapset = get_current_mapset()
         >>> name = "strds_map_test_case"
         >>> identifier = "%s@%s" % (name, mapset)
         >>> rmap = RasterDataset(identifier)
-        >>> rmap.set_absolute_time(start_time=datetime(2001,1,1),
-        ...                        end_time=datetime(2012,1,1))
-        True
         >>> rmap.map_exists()
         True
+        >>> rmap.read_timestamp_from_grass()
+        True
+        >>> rmap.get_temporal_extent_as_tuple()
+        (datetime.datetime(1999, 1, 15, 0, 0), None)
         >>> rmap.load()
         >>> rmap.spatial_extent.print_info()
          +-------------------- Spatial extent ----------------------------------------+
@@ -72,8 +67,8 @@
          | Bottom:..................... 0.0
         >>> rmap.absolute_time.print_info()
          +-------------------- Absolute time -----------------------------------------+
-         | Start time:................. 2001-01-01 00:00:00
-         | End time:................... 2012-01-01 00:00:00
+         | Start time:................. 1999-01-15 00:00:00
+         | End time:................... None
         >>> rmap.metadata.print_info()
          +-------------------- Metadata information ----------------------------------+
          | Datatype:................... CELL
@@ -95,6 +90,9 @@
         >>> rmap.get_type()
         'raster'
         >>> rmap.get_stds_register()
+        >>> rmap.set_absolute_time(start_time=datetime(2001,1,1),
+        ...                        end_time=datetime(2012,1,1))
+        True
         >>> rmap.get_absolute_time()
         (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0), None)
         >>> rmap.get_temporal_extent_as_tuple()
@@ -211,11 +209,32 @@
     def has_grass_timestamp(self):
         """!Check if a grass file bsased time stamp exists for this map.
         """
-        if G_has_raster_timestamp(self.get_name(), self.get_mapset()):
+        if libgis.G_has_raster_timestamp(self.get_name(), self.get_mapset()):
             return True
         else:
             return False
 
+    def read_timestamp_from_grass(self):
+        """!Read the timestamp of this map from the map metadata
+           in the grass file system based spatial database and
+           set the internal time stamp that should be insert/updated
+           in the temporal database.
+        """
+
+        if not self.has_grass_timestamp():
+            return False
+
+        ts = libgis.TimeStamp()
+        check = libgis.G_read_raster_timestamp(self.get_name(), self.get_mapset(),
+                                               byref(ts))
+
+        if check < 1:
+            core.error(_("Unable to read timestamp file "
+                         "for raster map <%s>" % (self.get_map_id())))
+            return False
+        
+        return self._set_timestamp_from_grass(ts)
+
     def write_timestamp_to_grass(self):
         """!Write the timestamp of this map into the map metadata in
            the grass file system based spatial database.
@@ -376,7 +395,92 @@
     """!Raster3d dataset class
 
        This class provides functions to select, update, insert or delete raster3d
-       map information and valid time stamps into the SQL temporal database.
+       map information and valid time stamps into the SQL temporal database.       
+       
+       Usage:
+
+        @code
+
+        >>> import grass.script as grass
+        >>> init()
+        >>> grass.use_temp_region()
+        >>> grass.run_command("g.region", n=80.0, s=0.0, e=120.0, w=0.0,
+        ... t=100.0, b=0.0, res=10.0)
+        0
+        >>> grass.run_command("r3.mapcalc", overwrite=True, 
+        ...                   expression="str3ds_map_test_case = 1")
+        0
+        >>> grass.run_command("r3.timestamp", map="str3ds_map_test_case", 
+        ...                   date="15 jan 1999")
+        0
+        >>> mapset = get_current_mapset()
+        >>> name = "str3ds_map_test_case"
+        >>> identifier = "%s@%s" % (name, mapset)
+        >>> r3map = Raster3DDataset(identifier)
+        >>> r3map.map_exists()
+        True
+        >>> r3map.read_timestamp_from_grass()
+        True
+        >>> r3map.get_temporal_extent_as_tuple()
+        (datetime.datetime(1999, 1, 15, 0, 0), None)
+        >>> r3map.load()
+        >>> r3map.spatial_extent.print_info()
+         +-------------------- Spatial extent ----------------------------------------+
+         | North:...................... 80.0
+         | South:...................... 0.0
+         | East:.. .................... 120.0
+         | West:....................... 0.0
+         | Top:........................ 100.0
+         | Bottom:..................... 0.0
+        >>> r3map.absolute_time.print_info()
+         +-------------------- Absolute time -----------------------------------------+
+         | Start time:................. 1999-01-15 00:00:00
+         | End time:................... None
+        >>> r3map.metadata.print_info()
+         +-------------------- Metadata information ----------------------------------+
+         | Datatype:................... DCELL
+         | Number of columns:.......... 8
+         | Number of rows:............. 12
+         | Number of cells:............ 960
+         | North-South resolution:..... 10.0
+         | East-west resolution:....... 10.0
+         | Minimum value:.............. 1.0
+         | Maximum value:.............. 1.0
+         | Number of depths:........... 10
+         | Top-Bottom resolution:...... 10.0
+         | STR3DS register table ...... None
+
+        >>> newmap = r3map.get_new_instance("new at PERMANENT")
+        >>> isinstance(newmap, Raster3DDataset)
+        True
+        >>> newstr3ds = r3map.get_new_stds_instance("new at PERMANENT")
+        >>> isinstance(newstr3ds, SpaceTimeRaster3DDataset)
+        True
+        >>> r3map.get_type()
+        'raster3d'
+        >>> r3map.get_stds_register()
+        >>> r3map.set_absolute_time(start_time=datetime(2001,1,1),
+        ...                        end_time=datetime(2012,1,1))
+        True
+        >>> r3map.get_absolute_time()
+        (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0), None)
+        >>> r3map.get_temporal_extent_as_tuple()
+        (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
+        >>> r3map.get_name()
+        'str3ds_map_test_case'
+        >>> r3map.get_mapset() == mapset
+        True
+        >>> r3map.get_temporal_type()
+        'absolute'
+        >>> r3map.get_spatial_extent_as_tuple()
+        (80.0, 0.0, 120.0, 0.0, 100.0, 0.0)
+        >>> r3map.is_time_absolute()
+        True
+        >>> r3map.is_time_relative()
+        False
+        >>> grass.run_command("g.remove", rast3d=name)
+        0
+        >>> grass.del_temp_region()
     """
     def __init__(self, ident):
         AbstractMapDataset.__init__(self)
@@ -486,11 +590,33 @@
     def has_grass_timestamp(self):
         """!Check if a grass file bsased time stamp exists for this map.
         """
-        if G_has_raster3d_timestamp(self.get_name(), self.get_mapset()):
+        if libgis.G_has_raster3d_timestamp(self.get_name(), self.get_mapset()):
             return True
         else:
             return False
 
+
+    def read_timestamp_from_grass(self):
+        """!Read the timestamp of this map from the map metadata
+           in the grass file system based spatial database and
+           set the internal time stamp that should be insert/updated
+           in the temporal database.
+        """
+
+        if not self.has_grass_timestamp():
+            return False
+
+        ts = libgis.TimeStamp()
+        check = libgis.G_read_raster3d_timestamp(self.get_name(), self.get_mapset(),
+                                               byref(ts))
+
+        if check < 1:
+            core.error(_("Unable to read timestamp file "
+                         "for 3D raster map <%s>" % (self.get_map_id())))
+            return False
+        
+        return self._set_timestamp_from_grass(ts)
+        
     def write_timestamp_to_grass(self):
         """!Write the timestamp of this map into the map metadata
         in the grass file system based spatial database.
@@ -654,6 +780,85 @@
 
        This class provides functions to select, update, insert or delete vector
        map information and valid time stamps into the SQL temporal database.
+       
+       Usage:
+
+        @code
+
+        >>> import grass.script as grass
+        >>> init()
+        >>> grass.use_temp_region()
+        >>> grass.run_command("g.region", n=80.0, s=0.0, e=120.0, w=0.0,
+        ... t=1.0, b=0.0, res=10.0)
+        0
+        >>> grass.run_command("v.random", overwrite=True, output="stvds_map_test_case",
+        ... n=100, zmin=0, zmax=100, flags="z", column="elevation")
+        0
+        >>> grass.run_command("v.timestamp", map="stvds_map_test_case", 
+        ...                   date="15 jan 1999")
+        0
+        >>> mapset = get_current_mapset()
+        >>> name = "stvds_map_test_case"
+        >>> identifier = "%s@%s" % (name, mapset)
+        >>> vmap = VectorDataset(identifier)
+        >>> vmap.map_exists()
+        True
+        >>> vmap.read_timestamp_from_grass()
+        True
+        >>> vmap.get_temporal_extent_as_tuple()
+        (datetime.datetime(1999, 1, 15, 0, 0), None)
+        >>> vmap.load()
+        >>> vmap.absolute_time.print_info()
+         +-------------------- Absolute time -----------------------------------------+
+         | Start time:................. 1999-01-15 00:00:00
+         | End time:................... None
+        >>> vmap.metadata.print_info()
+         +-------------------- Metadata information ----------------------------------+
+         | STVDS register table ....... None
+         | Is map 3d .................. True
+         | Number of points ........... 100
+         | Number of lines ............ 0
+         | Number of boundaries ....... 0
+         | Number of centroids ........ 0
+         | Number of faces ............ 0
+         | Number of kernels .......... 0
+         | Number of primitives ....... 100
+         | Number of nodes ............ 0
+         | Number of areas ............ 0
+         | Number of islands .......... 0
+         | Number of holes ............ 0
+         | Number of volumes .......... 0
+        >>> newmap = vmap.get_new_instance("new at PERMANENT")
+        >>> isinstance(newmap, VectorDataset)
+        True
+        >>> newstvds = vmap.get_new_stds_instance("new at PERMANENT")
+        >>> isinstance(newstvds, SpaceTimeVectorDataset)
+        True
+        >>> vmap.get_type()
+        'vector'
+        >>> vmap.get_stds_register()
+        >>> vmap.set_absolute_time(start_time=datetime(2001,1,1),
+        ...                        end_time=datetime(2012,1,1))
+        True
+        >>> vmap.get_absolute_time()
+        (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0), None)
+        >>> vmap.get_temporal_extent_as_tuple()
+        (datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2012, 1, 1, 0, 0))
+        >>> vmap.get_name()
+        'stvds_map_test_case'
+        >>> vmap.get_mapset() == mapset
+        True
+        >>> vmap.get_temporal_type()
+        'absolute'
+        >>> vmap.is_time_absolute()
+        True
+        >>> vmap.is_time_relative()
+        False
+        >>> grass.run_command("g.remove", vect=name)
+        0
+        >>> grass.del_temp_region()
+
+        @endcode
     """
     def __init__(self, ident):
         AbstractMapDataset.__init__(self)
@@ -732,12 +937,36 @@
     def has_grass_timestamp(self):
         """!Check if a grass file bsased time stamp exists for this map.
         """
-        if G_has_vector_timestamp(self.get_name(), self.get_layer(),
+        if libgis.G_has_vector_timestamp(self.get_name(), self.get_layer(),
                                   self.get_mapset()):
             return True
         else:
             return False
 
+
+    def read_timestamp_from_grass(self):
+        """!Read the timestamp of this map from the map metadata
+           in the grass file system based spatial database and
+           set the internal time stamp that should be insert/updated
+           in the temporal database.
+        """
+
+        if not self.has_grass_timestamp():
+            return False
+
+        ts = libgis.TimeStamp()
+        check = libgis.G_read_vector_timestamp(self.get_name(), 
+                                               self.get_layer(),
+                                               self.get_mapset(),
+                                               byref(ts))
+
+        if check < 1:
+            core.error(_("Unable to read timestamp file "
+                         "for vector map <%s>" % (self.get_map_id())))
+            return False
+        
+        return self._set_timestamp_from_grass(ts)
+        
     def write_timestamp_to_grass(self):
         """!Write the timestamp of this map into the map metadata in
            the grass file system based spatial database.



More information about the grass-commit mailing list