[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