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

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Nov 13 08:20:48 PST 2013


Author: huhabla
Date: 2013-11-13 08:20:48 -0800 (Wed, 13 Nov 2013)
New Revision: 58209

Modified:
   grass/trunk/lib/python/temporal/abstract_dataset.py
   grass/trunk/lib/python/temporal/abstract_map_dataset.py
   grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
   grass/trunk/lib/python/temporal/core.py
   grass/trunk/lib/python/temporal/datetime_math.py
   grass/trunk/lib/python/temporal/register.py
   grass/trunk/lib/python/temporal/space_time_datasets.py
   grass/trunk/lib/python/temporal/spatio_temporal_relationships.py
Log:
Started to use the new PyGRASS message interface in some classes.


Modified: grass/trunk/lib/python/temporal/abstract_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_dataset.py	2013-11-13 16:04:04 UTC (rev 58208)
+++ grass/trunk/lib/python/temporal/abstract_dataset.py	2013-11-13 16:20:48 UTC (rev 58209)
@@ -43,6 +43,7 @@
     def __init__(self):
         SpatialTopologyDatasetConnector.__init__(self)
         TemporalTopologyDatasetConnector.__init__(self)
+        self.msgr = get_tgis_message_interface()
 
     def reset_topology(self):
         """!Reset any information about temporal topology"""

Modified: grass/trunk/lib/python/temporal/abstract_map_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_map_dataset.py	2013-11-13 16:04:04 UTC (rev 58208)
+++ grass/trunk/lib/python/temporal/abstract_map_dataset.py	2013-11-13 16:20:48 UTC (rev 58209)
@@ -438,7 +438,7 @@
         """
         if start_time and not isinstance(start_time, datetime):
             if self.get_layer() is not None:
-                core.error(_("Start time must be of type datetime for %(type)s"
+                self.msgr.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()})
@@ -451,13 +451,13 @@
 
         if end_time and not isinstance(end_time, datetime):
             if self.get_layer():
-                core.error(_("End time must be of type datetime for %(type)s "
+                self.msgr.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.error(_("End time must be of type datetime for "
+                self.msgr.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
@@ -465,14 +465,14 @@
         if start_time is not None and end_time is not None:
             if start_time > end_time:
                 if self.get_layer():
-                    core.error(_("End time must be greater than start time for"
+                    self.msgr.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.error(_("End time must be greater than start time "
+                    self.msgr.error(_("End time must be greater than start time "
                                  "for %(type)s map <%(id)s>") % {
                                  'type': self.get_type(),
                                  'id': self.get_map_id()})
@@ -544,12 +544,12 @@
         """
         if not self.check_relative_time_unit(unit):
             if self.get_layer() is not None:
-                core.error(_("Unsupported relative time unit type for %(type)s"
+                self.msgr.error(_("Unsupported relative time unit type for %(type)s"
                              " map <%(id)s> with layer %(l)s: %(u)s") % {
                              'type': self.get_type(), 'id': self.get_id(),
                              'l': self.get_layer(), 'u': unit})
             else:
-                core.error(_("Unsupported relative time unit type for %(type)s"
+                self.msgr.error(_("Unsupported relative time unit type for %(type)s"
                              " map <%(id)s>: %(u)s") % {
                              'type': self.get_type(), 'id': self.get_id(),
                              'u': unit})
@@ -558,12 +558,12 @@
         if start_time is not None and end_time is not None:
             if int(start_time) > int(end_time):
                 if self.get_layer() is not None:
-                    core.error(_("End time must be greater than start time for"
+                    self.msgr.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_id(),
                                   'l': self.get_layer()})
                 else:
-                    core.error(_("End time must be greater than start time for"
+                    self.msgr.error(_("End time must be greater than start time for"
                                  " %(type)s map <%(id)s>") % {
                                  'type': self.get_type(), 'id': self.get_id()})
                 return False
@@ -867,18 +867,18 @@
             if end is not None:
                 if start >= end:
                     if self.get_layer() is not None:
-                        core.error(_("Map <%(id)s> with layer %(layer)s has "
+                        self.msgr.error(_("Map <%(id)s> with layer %(layer)s has "
                                      "incorrect time interval, start time is "
                                      "greater than end time") % {
                                      'id': self.get_map_id(),
                                      'layer': self.get_layer()})
                     else:
-                        core.error(_("Map <%s> has incorrect time interval, "
+                        self.msgr.error(_("Map <%s> has incorrect time interval, "
                                      "start time is greater than end time") % \
                                    (self.get_map_id()))
                     return False
         else:
-            core.error(_("Map <%s> has incorrect start time") %
+            self.msgr.error(_("Map <%s> has incorrect start time") %
                        (self.get_map_id()))
             return False
 
@@ -926,10 +926,10 @@
             if self.get_stds_register() is not None:
                 statement += "DROP TABLE IF EXISTS " + self.get_stds_register() + ";\n"
 
-            # Commented because of performance issue calling g.message thousend times
-            #core.verbose(_("Delete %s dataset <%s> from temporal database")
-            #             % (self.get_type(), self.get_id()))
 
+            self.msgr.verbose(_("Delete %s dataset <%s> from temporal database")
+                         % (self.get_type(), self.get_id()))
+
             # Delete yourself from the database, trigger functions will
             # take care of dependencies
             statement += self.base.get_delete_statement()
@@ -966,17 +966,17 @@
            @return The SQL statements if execute=False, else an empty string
         """
 
-        # Commented because of performance issue calling g.message thousend times
-        #if self.get_layer() is not None:
-        #    core.verbose(_("Unregister %(type)s map <%(map)s> with "
-        #                   "layer %(layer)s from space time datasets" % \
-        #                 {'type':self.get_type(), 'map':self.get_map_id(),
-        #                  'layer':self.get_layer()}))
-        #else:
-        #    core.verbose(_("Unregister %(type)s map <%(map)s> "
-        #                   "from space time datasets"
-        #                 % {'type':self.get_type(), 'map':self.get_map_id()}))
 
+        if self.get_layer() is not None:
+            self.msgr.verbose(_("Unregister %(type)s map <%(map)s> with "
+                           "layer %(layer)s from space time datasets" % \
+                         {'type':self.get_type(), 'map':self.get_map_id(),
+                          'layer':self.get_layer()}))
+        else:
+            self.msgr.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")%\
@@ -1032,7 +1032,7 @@
                 dbif.cursor.execute(sql)
                 rows = dbif.cursor.fetchall()
         except:
-            core.error(_("Unable to select space time dataset register table "
+            self.msgr.error(_("Unable to select space time dataset register table "
                          "<%s>") % (self.get_stds_register()))
 
         if connected:

Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2013-11-13 16:04:04 UTC (rev 58208)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py	2013-11-13 16:20:48 UTC (rev 58209)
@@ -601,12 +601,12 @@
         """
 
         if self.get_temporal_type() != stds.get_temporal_type():
-            core.error(_("The space time datasets must be of "
+            self.msgr.error(_("The space time datasets must be of "
                          "the same temporal type"))
             return None
 
         if stds.get_map_time() != "interval":
-            core.error(_("The temporal map type of the sample "
+            self.msgr.error(_("The temporal map type of the sample "
                          "dataset must be interval"))
             return None
 
@@ -847,12 +847,12 @@
             use_equal = True
 
         if self.get_temporal_type() != stds.get_temporal_type():
-            core.error(_("The space time datasets must be of "
+            self.msgr.error(_("The space time datasets must be of "
                          "the same temporal type"))
             return None
 
         if stds.get_map_time() != "interval":
-            core.error(_("The temporal map type of the sample "
+            self.msgr.error(_("The temporal map type of the sample "
                          "dataset must be interval"))
             return None
 
@@ -1299,7 +1299,7 @@
         if rows:
             for row in rows:
                 if row["key"] == "tgis_db_version":
-                    db_version = int(row["value"])
+                    db_version = int(float(row["value"]))
 
         if db_version >= 1:
             has_bt_columns = True
@@ -1387,7 +1387,7 @@
             except:
                 if connected:
                     dbif.close()
-                core.error(_("Unable to get map ids from register table <%s>")
+                self.msgr.error(_("Unable to get map ids from register table <%s>")
                            % (self.get_map_register()))
                 raise
 
@@ -1467,7 +1467,7 @@
         """
         if maps is None:
             return None
- 
+
         if not check_granularity_string(gran, maps[-1].get_temporal_type()):
             core.error(_("Wrong granularity format: %s" % (gran)))
             return None
@@ -1502,7 +1502,7 @@
             ({"ds":self.get_id()}, {"type":self.get_type()}))
 
         if not check_granularity_string(gran, self.get_temporal_type()):
-            core.error(_("Wrong granularity format: %s" % (gran)))
+            self.msgr.error(_("Wrong granularity format: %s" % (gran)))
             return False
 
         dbif, connected = init_dbif(dbif)
@@ -1762,12 +1762,12 @@
            @param ident The new identifier "name at mapset"
            @param dbif The database interface to be used
         """
-        
+
         if self.get_mapset() != get_current_mapset():
             core.fatal(_("Unable to rename 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()}))
-            
+
         dbif, connected = init_dbif(dbif)
 
         # SELECT all needed information from the database
@@ -1825,12 +1825,10 @@
         # First we need to check if maps are registered in this dataset and
         # unregister them
 
-        # Commented because of performance issue calling g.message thousend
-        # times
-        # core.verbose(_("Delete space time %s  dataset <%s> from temporal "
-        #               "database") % \
-        #             (self.get_new_map_instance(ident=None).get_type(),
-        #              self.get_id()))
+        self.msgr.verbose(_("Delete space time %s  dataset <%s> from temporal "
+                      "database") % \
+                    (self.get_new_map_instance(ident=None).get_type(),
+                     self.get_id()))
 
         if self.get_mapset() != get_current_mapset():
             core.fatal(_("Unable to delete dataset <%(ds)s> of type %(type)s from the temporal database."
@@ -1844,7 +1842,7 @@
         self.metadata.select(dbif)
 
         if self.get_map_register() is not None:
-            core.verbose(_("Drop map register table: %s") % (
+            self.msgr.verbose(_("Drop map register table: %s") % (
                 self.get_map_register()))
             rows = self.get_registered_maps("id", None, None, dbif)
             # Unregister each registered map in the table
@@ -1901,20 +1899,19 @@
             dbif.close()
             core.fatal(_("Only maps with absolute or relative valid time can "
                          "be registered"))
-        # Commented because of performance issue calling g.message thousend
-        # times
-        #if map.get_layer():
-        #    core.verbose(_("Register %s map <%s> with layer %s in space "
-        #                   "time %s dataset <%s>") % (map.get_type(),
-        #                                              map.get_map_id(),
-        #                                              map.get_layer(),
-        #                                              map.get_type(),
-        #                                              self.get_id()))
-        #else:
-        #    core.verbose(_("Register %s map <%s> in space time %s "
-        #                   "dataset <%s>") % (map.get_type(), map.get_map_id(),
-        #                                      map.get_type(), self.get_id()))
 
+        if map.get_layer():
+            self.msgr.verbose(_("Register %s map <%s> with layer %s in space "
+                           "time %s dataset <%s>") % (map.get_type(),
+                                                      map.get_map_id(),
+                                                      map.get_layer(),
+                                                      map.get_type(),
+                                                      self.get_id()))
+        else:
+            self.msgr.verbose(_("Register %s map <%s> in space time %s "
+                           "dataset <%s>") % (map.get_type(), map.get_map_id(),
+                                              map.get_type(), self.get_id()))
+
         # First select all data from the database
         map.select(dbif)
 
@@ -1964,11 +1961,11 @@
             self.set_relative_time_unit(map_rel_time_unit)
             statement += self.relative_time.get_update_all_statement_mogrified(
                 dbif)
-            # Commented because of performance issue calling g.message thousend times
-            #core.verbose(_("Set temporal unit for space time %s dataset "
-            #               "<%s> to %s") % (map.get_type(), self.get_id(),
-            #                                map_rel_time_unit))
 
+            self.msgr.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
@@ -2000,7 +1997,7 @@
                 dbif.cursor.execute(sql, (map_id,))
                 row = dbif.cursor.fetchone()
             except:
-                core.warning(_("Error in strds_register_table request"))
+                self.msgr.warning(_("Error in strds_register_table request"))
                 raise
 
             if row is not None and row[0] == map_id:
@@ -2008,11 +2005,11 @@
                     dbif.close()
 
                 if map.get_layer() is not None:
-                    core.warning(_("Map <%(map)s> with layer %(l)s is already "
+                    self.msgr.warning(_("Map <%(map)s> with layer %(l)s is already "
                                    "registered.") % {'map': map.get_map_id(),
                                                      'l': map.get_layer()})
                 else:
-                    core.warning(_("Map <%s> is already registered.") % (
+                    self.msgr.warning(_("Map <%s> is already registered.") % (
                                  map.get_map_id()))
                 return False
 
@@ -2045,16 +2042,15 @@
             map.set_stds_register(map_register_table)
             statement += map.metadata.get_update_statement_mogrified(dbif)
 
-            # Commented because of performance issue calling g.message thousend times
-            #if map.get_layer():
-            #    core.verbose(_("Created register table <%s> for "
-            #                   "%s map <%s> with layer %s") %
-            #                    (map_register_table, map.get_type(),
-            #                     map.get_map_id(), map.get_layer()))
-            #else:
-            #    core.verbose(_("Created register table <%s> for %s map <%s>") %
-            #                    (map_register_table, map.get_type(),
-            #                     map.get_map_id()))
+            if map.get_layer():
+                core.verbose(_("Created register table <%s> for "
+                               "%s map <%s> with layer %s") %
+                                (map_register_table, map.get_type(),
+                                 map.get_map_id(), map.get_layer()))
+            else:
+                core.verbose(_("Created register table <%s> for %s map <%s>") %
+                                (map_register_table, map.get_type(),
+                                 map.get_map_id()))
 
         # We need to create the table and register it
         if stds_register_table is None:
@@ -2078,10 +2074,9 @@
             self.set_map_register(stds_register_table)
             statement += self.metadata.get_update_statement_mogrified(dbif)
 
-            # Commented because of performance issue calling g.message thousend times
-            #core.verbose(_("Created register table <%s> for space "
-            #               "time %s  dataset <%s>") %
-            #              (stds_register_table, map.get_type(), self.get_id()))
+            self.msgr.verbose(_("Created register table <%s> for space "
+                           "time %s  dataset <%s>") %
+                          (stds_register_table, map.get_type(), self.get_id()))
 
         # We need to execute the statement at this time
         if statement != "":
@@ -2167,14 +2162,6 @@
         map_register_table = map.get_stds_register()
         stds_register_table = self.get_map_register()
 
-        # Commented because of performance issue calling g.message thousend times
-        #if map.get_layer() is not None:
-        #    core.verbose(_("Unregister %s map <%s> with layer %s") % \
-        #                 (map.get_type(), map.get_map_id(), map.get_layer()))
-        #else:
-        #    core.verbose(_("Unregister %s map <%s>") % (
-        #        map.get_type(), map.get_map_id()))
-
         # Check if the map is registered in the space time raster dataset
         if map_register_table is not None:
             if dbif.dbmi.paramstyle == "qmark":
@@ -2190,13 +2177,13 @@
             # Break if the map is not registered
             if row is None:
                 if map.get_layer() is not None:
-                    core.warning(_("Map <%(map)s> with layer %(l)s is not "
+                    self.msgr.warning(_("Map <%(map)s> with layer %(l)s is not "
                                    "registered in space time dataset "
                                    "<%(base)s>") % {'map': map.get_map_id(),
                                                     'l': map.get_layer(),
                                                     'base': self.base.get_id()})
                 else:
-                    core.warning(_("Map <%(map)s> is not registered in space "
+                    self.msgr.warning(_("Map <%(map)s> is not registered in space "
                                    "time dataset <%(base)s>") % {
                                    'map': map.get_map_id(),
                                    'base': self.base.get_id()})
@@ -2262,7 +2249,7 @@
                          " The mapset of the dataset does not match the current mapset")%\
                          {"ds":self.get_id(), "type":self.get_type()})
 
-        core.verbose(_("Update metadata, spatial and temporal extent from "
+        self.msgr.verbose(_("Update metadata, spatial and temporal extent from "
                        "all registered maps of <%s>") % (self.get_id()))
 
         # Nothing to do if the register is not present

Modified: grass/trunk/lib/python/temporal/core.py
===================================================================
--- grass/trunk/lib/python/temporal/core.py	2013-11-13 16:04:04 UTC (rev 58208)
+++ grass/trunk/lib/python/temporal/core.py	2013-11-13 16:20:48 UTC (rev 58209)
@@ -84,16 +84,47 @@
     global current_mapset
     return current_mapset
 
-def _set_current_mapset():
-    """!This functions set the global current mapset variable to the current mapset
-    by calling g.gisenv. 
+def _set_current_mapset(mapset=None):
+    """!This functions set the global current mapset variable to
+       the current mapset by calling g.gisenv.
+
+       @param mapset The current mapset, g.gisenv will be called
+                     if this variable is set to None
     """
     global current_mapset
-    current_mapset = core.gisenv()["MAPSET"]
 
+    if mapset == None:
+        mapset = core.gisenv()["MAPSET"]
 
+    current_mapset = mapset
+
 ###############################################################################
 
+# The global variable that stores the PyGRASS Messenger object that
+# provides a fast and exit safe interface to the C-library message functions
+message_interface=None
+
+def _set_tgis_message_interface():
+    """!Set the global mesage interface variable
+
+       @param messenger The grass.pyhrass.message.Messenger() object
+    """
+    global message_interface
+    from grass.pygrass import messages
+    message_interface = messages.Messenger()
+
+def get_tgis_message_interface():
+    """!Return the temporal GIS message interface which is of type
+       grass.pyhrass.message.Messenger()
+
+       Use this message interface to print messages to stdout using the
+       GRASS C-library messaging system.
+    """
+    global message_interface
+    return message_interface
+
+###############################################################################
+
 def get_tgis_version():
     """!Get the verion number of the temporal framework
        @return The version number of the temporal framework as string
@@ -128,13 +159,22 @@
 
 ###############################################################################
 
-def get_temporal_dbmi_init_string():
-    kv = core.parse_command("t.connect", flags="pg")
-    grassenv = core.gisenv()
+def get_temporal_dbmi_init_string(kv=None, grassenv=None):
+    """!Return the database initialization string
+
+       @param kv dictionary generated by grass.script.parse_command("t.connect", flags="pg")
+       @param grassenv Grass environemntal variables created by grass.script.gisenv()
+    """
+    if kv == None:
+        kv = core.parse_command("t.connect", flags="pg")
+    if grassenv == None:
+        grassenv = core.gisenv()
+
     global tgis_backend
+
     if tgis_backend == "sqlite":
         # We substitute GRASS variables if they are located in the database string
-        # This behavior is in conjunction with db.connect 
+        # This behavior is in conjunction with db.connect
         if "database" in kv:
             string = kv["database"]
             string = string.replace("$GISDBASE", grassenv["GISDBASE"])
@@ -208,19 +248,24 @@
     # We need to set the correct database backend from the environment variables
     global tgis_backend
 
-    # Set the global variable current_mapset for fast mapset access 
-    _set_current_mapset()
-
     core.run_command("t.connect", flags="c")
     kv = core.parse_command("t.connect", flags="pg")
+    grassenv = core.gisenv()
 
+    # Set the global variable current_mapset for fast mapset access
+    _set_current_mapset(grassenv["MAPSET"])
+    # Start the GRASS message interface server
+    _set_tgis_message_interface()
+
+    msgr = get_tgis_message_interface()
+
     if "driver" in kv:
         if kv["driver"] == "sqlite":
             tgis_backend = kv["driver"]
             try:
                 import sqlite3
             except ImportError:
-                core.error("Unable to locate the sqlite SQL Python interface module sqlite3.")
+                msgr.error("Unable to locate the sqlite SQL Python interface module sqlite3.")
                 raise
             dbmi = sqlite3
         elif kv["driver"] == "pg":
@@ -228,7 +273,7 @@
             try:
                 import psycopg2
             except ImportError:
-                core.error("Unable to locate the Postgresql SQL Python interface module psycopg2.")
+                msgr.error("Unable to locate the Postgresql SQL Python interface module psycopg2.")
                 raise
             dbmi = psycopg2
         else:
@@ -240,7 +285,7 @@
         core.run_command("t.connect", flags="d")
 
     db_exists = False
-    database = get_temporal_dbmi_init_string()
+    database = get_temporal_dbmi_init_string(kv=kv, grassenv=grassenv)
     dbif = SQLDatabaseInterfaceConnection()
 
     # Check if the database already exists
@@ -576,7 +621,7 @@
 
     def check_table(self, table_name):
         """!Check if a table exists in the temporal database
-        
+
            @param table_name The name of the table to be checked for existance
            @return True if the table exists, False otherwise
         """
@@ -604,7 +649,7 @@
             self.close()
 
         return table_exists
-        
+
     def execute_transaction(self, statement):
         """!Execute a transactional SQL statement
 

Modified: grass/trunk/lib/python/temporal/datetime_math.py
===================================================================
--- grass/trunk/lib/python/temporal/datetime_math.py	2013-11-13 16:04:04 UTC (rev 58208)
+++ grass/trunk/lib/python/temporal/datetime_math.py	2013-11-13 16:20:48 UTC (rev 58209)
@@ -693,8 +693,8 @@
 ###############################################################################
 
 
-def string_to_datetime(time_string):
-    """!Convert a string into a datetime object
+def check_datetime_string(time_string):
+    """!Check if  a string can be converted into a datetime object
 
         Supported ISO string formats are:
         - YYYY-mm-dd
@@ -702,21 +702,17 @@
 
         Time zones are not supported
 
-        @param time_string The time string to convert
-        @return datetime object or None in case of an error
+        @param time_string The time string to be checked for conversion
+        @return datetime object or an error message string in case of an error
     """
 
     # BC is not supported
     if time_string.find("bc") > 0:
-        core.error("Dates Before Christ are not supported "
-                   "in the temporal database")
-        return None
+        return _("Dates Before Christ are not supported")
 
     # BC is not supported
     if time_string.find("+") > 0:
-        core.error("Time zones are not supported "
-                   "in the temporal database")
-        return None
+        return _("Time zones are not supported")
 
     if time_string.find(":") > 0:
         time_format = "%Y-%m-%d %H:%M:%S"
@@ -726,10 +722,32 @@
     try:
         return  datetime.strptime(time_string, time_format)
     except:
-        core.error("Unable to parse time string: %s"%time_string)
+        return _("Unable to parse time string: %s"%time_string)
+
+###############################################################################
+
+
+def string_to_datetime(time_string):
+    """!Convert a string into a datetime object
+
+        Supported ISO string formats are:
+        - YYYY-mm-dd
+        - YYYY-mm-dd HH:MM:SS
+
+        Time zones are not supported
+
+        @param time_string The time string to convert
+        @return datetime object or None in case of an error
+    """
+    time_object = check_datetime_string(time_string)
+    if not isinstance(time_object, datetime):
+        core.error(time_object)
         return None
 
+    return time_object
 
+
+
 ###############################################################################
 
 

Modified: grass/trunk/lib/python/temporal/register.py
===================================================================
--- grass/trunk/lib/python/temporal/register.py	2013-11-13 16:04:04 UTC (rev 58208)
+++ grass/trunk/lib/python/temporal/register.py	2013-11-13 16:20:48 UTC (rev 58209)
@@ -192,6 +192,13 @@
                                  "is not set.") % {'t': map.get_type(),
                                                    'id': map.get_map_id()})
             if start != "" and start != None:
+                # We need to check if the time is absolute and the unit was specified
+                time_object = check_datetime_string(start)
+                if isinstance(time_object, datetime) and unit:
+                    core.fatal(_("%(u)s= can only be set for relative time") % {'u': "maps"})
+                if not isinstance(time_object, datetime) and not unit:
+                    core.fatal(_("%(u)s= must be set in case of relative time stamps") % {'u': "maps"})
+
                 if unit:
                     map.set_time_to_relative()
                 else:

Modified: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py	2013-11-13 16:04:04 UTC (rev 58208)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py	2013-11-13 16:20:48 UTC (rev 58209)
@@ -43,7 +43,7 @@
         >>> grass.run_command("r.mapcalc", overwrite=True,
         ... expression="strds_map_test_case = 1")
         0
-        >>> grass.run_command("r.timestamp", map="strds_map_test_case", 
+        >>> grass.run_command("r.timestamp", map="strds_map_test_case",
         ...                   date="15 jan 1999")
         0
         >>> mapset = get_current_mapset()
@@ -229,10 +229,10 @@
                                                byref(ts))
 
         if check < 1:
-            core.error(_("Unable to read timestamp file "
+            self.msgr.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):
@@ -248,11 +248,11 @@
         check = libgis.G_write_raster_timestamp(self.get_name(), byref(ts))
 
         if check == -1:
-            core.error(_("Unable to create timestamp file "
+            self.msgr.error(_("Unable to create timestamp file "
                          "for raster map <%s>" % (self.get_map_id())))
 
         if check == -2:
-            core.error(_("Invalid datetime in timestamp for raster map <%s>" %
+            self.msgr.error(_("Invalid datetime in timestamp for raster map <%s>" %
                          (self.get_map_id())))
 
     def remove_timestamp_from_grass(self):
@@ -395,8 +395,8 @@
     """!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
@@ -407,10 +407,10 @@
         >>> 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, 
+        >>> grass.run_command("r3.mapcalc", overwrite=True,
         ...                   expression="str3ds_map_test_case = 1")
         0
-        >>> grass.run_command("r3.timestamp", map="str3ds_map_test_case", 
+        >>> grass.run_command("r3.timestamp", map="str3ds_map_test_case",
         ...                   date="15 jan 1999")
         0
         >>> mapset = get_current_mapset()
@@ -611,12 +611,12 @@
                                                byref(ts))
 
         if check < 1:
-            core.error(_("Unable to read timestamp file "
+            self.msgr.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.
@@ -630,11 +630,11 @@
         check = libgis.G_write_raster3d_timestamp(self.get_name(), byref(ts))
 
         if check == -1:
-            core.error(_("Unable to create timestamp file "
+            self.msgr.error(_("Unable to create timestamp file "
                          "for raster3d map <%s>" % (self.get_map_id())))
 
         if check == -2:
-            core.error(_("Invalid datetime in timestamp "
+            self.msgr.error(_("Invalid datetime in timestamp "
                          "for raster3d map <%s>" % (self.get_map_id())))
 
     def remove_timestamp_from_grass(self):
@@ -645,7 +645,7 @@
         check = libgis.G_remove_raster3d_timestamp(self.get_name())
 
         if check == -1:
-            core.error(_("Unable to remove timestamp for raster3d map <%s>" %
+            self.msgr.error(_("Unable to remove timestamp for raster3d map <%s>" %
                          (self.get_name())))
 
     def map_exists(self):
@@ -780,7 +780,7 @@
 
        This class provides functions to select, update, insert or delete vector
        map information and valid time stamps into the SQL temporal database.
-       
+
        Usage:
 
         @code
@@ -794,7 +794,7 @@
         >>> 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", 
+        >>> grass.run_command("v.timestamp", map="stvds_map_test_case",
         ...                   date="15 jan 1999")
         0
         >>> mapset = get_current_mapset()
@@ -955,18 +955,18 @@
             return False
 
         ts = libgis.TimeStamp()
-        check = libgis.G_read_vector_timestamp(self.get_name(), 
+        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 "
+            self.msgr.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.
@@ -981,11 +981,11 @@
             self.get_name(), self.get_layer(), byref(ts))
 
         if check == -1:
-            core.error(_("Unable to create timestamp file "
+            self.msgr.error(_("Unable to create timestamp file "
                          "for vector map <%s>" % (self.get_map_id())))
 
         if check == -2:
-            core.error(_("Invalid datetime in timestamp for vector map <%s>" %
+            self.msgr.error(_("Invalid datetime in timestamp for vector map <%s>" %
                          (self.get_map_id())))
 
     def remove_timestamp_from_grass(self):
@@ -998,7 +998,7 @@
             self.get_name(), self.get_layer())
 
         if check == -1:
-            core.error(_("Unable to remove timestamp for vector map <%s>" %
+            self.msgr.error(_("Unable to remove timestamp for vector map <%s>" %
                          (self.get_name())))
 
     def map_exists(self):
@@ -1043,7 +1043,7 @@
             # faces, kernels is still available
             libvector.Vect_set_open_level(1)  # no topology
             with_topo = False
-            core.message(_("Open map without topology support"))
+            self.msgr.message(_("Open map without topology support"))
             if libvector.Vect_open_old2(byref(Map), name, mapset, "1") < 1:
                 core.fatal(_("Unable to open vector map <%s>" %
                              (libvector.Vect_get_full_name(byref(Map)))))

Modified: grass/trunk/lib/python/temporal/spatio_temporal_relationships.py
===================================================================
--- grass/trunk/lib/python/temporal/spatio_temporal_relationships.py	2013-11-13 16:04:04 UTC (rev 58208)
+++ grass/trunk/lib/python/temporal/spatio_temporal_relationships.py	2013-11-13 16:20:48 UTC (rev 58209)
@@ -36,7 +36,9 @@
        The abstract dataset objects must be provided as a single list, or in two lists.
 
         Example:
+
         @code
+
         # We have a space time raster dataset and build a map list
         # from all registered maps ordered by start time
         maps = strds.get_registered_maps_as_objects()
@@ -587,7 +589,7 @@
 
 def set_temoral_relationship(A, B, relation):
     if relation == "equal" or relation == "equals":
-	if A != B:
+        if A != B:
             if not B.get_equal() or \
             (B.get_equal() and \
             A not in B.get_equal()):
@@ -694,7 +696,7 @@
 def set_spatial_relationship(A, B, relation):
 
     if relation == "equivalent":
-	if A != B:
+        if A != B:
             if not B.get_equivalent() or \
             (B.get_equivalent() and \
             A not in B.get_equivalent()):
@@ -788,7 +790,8 @@
 
 ###############################################################################
 
-def print_spatio_temporal_topology_relationships(maps1, maps2=None, spatial="2D", dbif=None):
+def print_spatio_temporal_topology_relationships(maps1, maps2=None,
+                                                 spatial="2D", dbif=None):
     """!Print the temporal relationships of the
        map lists maps1 and maps2 to stdout.
 
@@ -839,7 +842,7 @@
     relations = None
 
     for _map in tb:
-        if relations != None:
+        if relations is not None:
             r = _map.get_number_of_relations()
             for k in r.keys():
                 relations[k] += r[k]



More information about the grass-commit mailing list