[GRASS-SVN] r50467 - grass/trunk/lib/python/temporal
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jan 26 07:23:10 EST 2012
Author: huhabla
Date: 2012-01-26 04:23:09 -0800 (Thu, 26 Jan 2012)
New Revision: 50467
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/aggregation.py
grass/trunk/lib/python/temporal/base.py
grass/trunk/lib/python/temporal/core.py
grass/trunk/lib/python/temporal/datetime_math.py
grass/trunk/lib/python/temporal/space_time_datasets.py
grass/trunk/lib/python/temporal/space_time_datasets_tools.py
grass/trunk/lib/python/temporal/spatial_extent.py
grass/trunk/lib/python/temporal/temporal_extent.py
grass/trunk/lib/python/temporal/temporal_granularity.py
Log:
Implemented handling of time-stamped vector layers
Modified: grass/trunk/lib/python/temporal/abstract_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_dataset.py 2012-01-26 12:22:41 UTC (rev 50466)
+++ grass/trunk/lib/python/temporal/abstract_dataset.py 2012-01-26 12:23:09 UTC (rev 50467)
@@ -66,8 +66,41 @@
self.metadata.print_self()
def get_id(self):
+ """Return the unique identifier of the dataset"""
return self.base.get_id()
+ def get_name(self):
+ """Return the name"""
+ return self.base.get_name()
+
+ def get_mapset(self):
+ """Return the mapset"""
+ return self.base.get_mapset()
+
+ def build_id(name, mapset, layer=None):
+ """Build and return the id (primary key) based on name, mapset and layer of a dataset.
+
+ @param name: The name of the map
+ @param mapset: The name of the mapset
+ @param layer: The name of the layer (optional)
+
+ Return None in case the name can not be build (name or mapset are None)
+ """
+
+ if not name or not mapset:
+ return None
+
+ # Make sure to extract the pure mapname
+ pure_name = name.split("@")[0].split(":")[0]
+
+ if layer:
+ return "%s:%s@%s"%(name, layer, mapset)
+ else:
+ return "%s@%s"%(name, mapset)
+
+ return None
+
+
def get_valid_time(self):
"""Returns a tuple of the start, the end valid time, this can be either datetime or double values
@return A tuple of (start_time, end_time)
Modified: grass/trunk/lib/python/temporal/abstract_map_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_map_dataset.py 2012-01-26 12:22:41 UTC (rev 50466)
+++ grass/trunk/lib/python/temporal/abstract_map_dataset.py 2012-01-26 12:23:09 UTC (rev 50467)
@@ -58,6 +58,41 @@
"""Load the content of this object from map files"""
raise IOError("This method must be implemented in the subclasses")
+ def get_map_id(self):
+ """Return the map id. The map id is the unique map identifier in grass and must not be equal to the
+ primary key identifier (id) of the map in the database. Since vector maps may have layer information,
+ the unique id is a combination of name, layer and mapset.
+
+ Use get_map_id() every time your need to access the grass map in the file system but not to identify
+ map information in the temporal database.
+
+ """
+ return self.base.get_map_id()
+
+ def build_id(self, name, mapset, layer=None):
+ """Convenient method to build the unique identifier
+
+ Existing layer and mapset definitions in the name string will be reused
+
+ @param return the id of the vector map as name(:layer)@mapset while layer is optional
+ """
+
+ # Check if the name includes any mapset
+ if name.find("@") >= 0:
+ name, mapset = name.split("@")[0]
+
+ if name.find(":") >= 0:
+ name, layer = name.split(":")[0]
+
+ if layer:
+ return "%s:%s@%s"%(name, layer, mapset)
+ else:
+ return "%s@%s"%(name, mapset)
+
+ def get_layer(self):
+ """Return the layer of the map or None in case no layer is defined"""
+ return self.base.get_layer()
+
def print_info(self):
"""Print information about this class in human readable style"""
@@ -128,14 +163,23 @@
"""
if start_time and not isinstance(start_time, datetime) :
- core.fatal(_("Start time must be of type datetime for %s map <%s>") % (self.get_type(), self.get_id()))
+ if self.get_layer():
+ core.fatal(_("Start time must be of type datetime for %s map <%s> with layer: %s") % (self.get_type(), self.get_map_id(), self.get_layer()))
+ else:
+ core.fatal(_("Start time must be of type datetime for %s map <%s>") % (self.get_type(), self.get_map_id()))
if end_time and not isinstance(end_time, datetime) :
- core.fatal(_("End time must be of type datetime for %s map <%s>") % (self.get_type(), self.get_id()))
+ if self.get_layer():
+ core.fatal(_("End time must be of type datetime for %s map <%s> with layer: %s") % (self.get_type(), self.get_map_id(), self.get_layer()))
+ else:
+ core.fatal(_("End time must be of type datetime for %s map <%s>") % (self.get_type(), self.get_map_id()))
if start_time and end_time:
if start_time > end_time:
- core.fatal(_("End time must be greater than start time for %s map <%s>") % (self.get_type(), self.get_id()))
+ if self.get_layer():
+ core.fatal(_("End time must be greater than start time for %s map <%s> with layer: %s") % (self.get_type(), self.get_map_id(), self.get_layer()))
+ else:
+ core.fatal(_("End time must be greater than start time for %s map <%s>") % (self.get_type(), self.get_map_id()))
else:
# Do not create an interval in case start and end time are equal
if start_time == end_time:
@@ -182,27 +226,33 @@
end = datetime_to_grass_datetime_string(end_time)
start += " / %s"%(end)
- core.run_command(self.get_timestamp_module_name(), map=self.get_id(), date=start)
+ core.run_command(self.get_timestamp_module_name(), map=self.get_map_id(), date=start)
def set_relative_time(self, start_time, end_time, unit):
"""Set the relative time interval
@param start_time: A double value
@param end_time: A double value
- @param unit: The unit of the relative time. Supported uits: years, months, days, hours, minutes, seconds
+ @param unit: The unit of the relative time. Supported units: years, months, days, hours, minutes, seconds
Return True for success and False otherwise
"""
if not self.check_relative_time_unit(unit):
- core.error(_("Unsupported relative time unit type for %s map <%s>: %s") % (self.get_type(), self.get_id(), unit))
+ if self.get_layer():
+ core.error(_("Unsupported relative time unit type for %s map <%s> with layer %s: %s") % (self.get_type(), self.get_id(), self.get_layer(), unit))
+ else:
+ core.error(_("Unsupported relative time unit type for %s map <%s>: %s") % (self.get_type(), self.get_id(), unit))
return False
if start_time != None and end_time != None:
if int(start_time) > int(end_time):
- core.error(_("End time must be greater than start time for %s map <%s>") % (self.get_type(), self.get_id()))
+ if self.get_layer():
+ core.error(_("End time must be greater than start time for %s map <%s> with layer %s") % (self.get_type(), self.get_id(), self.get_layer()))
+ else:
+ core.error(_("End time must be greater than start time for %s map <%s>") % (self.get_type(), self.get_id()))
return False
else:
# Do not create an interval in case start and end time are equal
@@ -255,7 +305,7 @@
if end_time:
end = "%i %s"%(int(end_time), unit)
start += " / %s"%(end)
- core.run_command(self.get_timestamp_module_name(), map=self.get_id(), date=start)
+ core.run_command(self.get_timestamp_module_name(), map=self.get_map_id(), date=start)
def set_spatial_extent(self, north, south, east, west, top=0, bottom=0):
"""Set the spatial extent of the map
@@ -265,7 +315,7 @@
@param east: The eastern edge
@param west: The western edge
@param top: The top edge
- @param bottom: The bottom ege
+ @param bottom: The bottom edge
"""
self.spatial_extent.set_spatial_extent(north, south, east, west, top, bottom)
@@ -279,10 +329,13 @@
if start != None:
if end != None:
if start >= end:
- core.error(_("Map <%s> has incorrect time interval, start time is greater than end time") % (self.get_id()))
+ if self.get_layer():
+ core.error(_("Map <%s> with layer %s has incorrect time interval, start time is greater than end time") % (self.get_map_id(), self.get_layer()))
+ else:
+ core.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.get_id()))
+ core.error(_("Map <%s> has incorrect start time") % (self.get_map_id()))
return False
return True
@@ -327,7 +380,7 @@
self.base.delete(dbif)
# Remove the timestamp from the file system
- core.run_command(self.get_timestamp_module_name(), map=self.get_id(), date="none")
+ core.run_command(self.get_timestamp_module_name(), map=self.get_map_id(), date="none")
self.reset(None)
dbif.connection.commit()
@@ -339,11 +392,15 @@
""" Remove the map entry in each space time dataset in which this map is registered
@param dbif: The database interface to be used
- @param update: Call for each unregister statement the update_from_registered_maps
- of the space time dataset. This can slow down the unregistration process significantly.
+ @param update: Call for each unregister statement the update from registered maps
+ of the space time dataset. This can slow down the un-registration process significantly.
"""
- core.verbose(_("Unregister %s dataset <%s> from space time datasets") % (self.get_type(), self.get_id()))
+ if self.get_layer():
+ core.verbose(_("Unregister %s map <%s> with layer %s from space time datasets") % \
+ (self.get_type(), self.get_map_id(), self.get_layer()))
+ else:
+ core.verbose(_("Unregister %s map <%s> from space time datasets") % (self.get_type(), self.get_map_id()))
connect = False
@@ -368,7 +425,7 @@
stds.select(dbif)
stds.unregister_map(self, dbif)
# Take care to update the space time dataset after
- # the map has been unregistred
+ # the map has been unregistered
if update == True:
stds.update_from_registered_maps(dbif)
Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py 2012-01-26 12:22:41 UTC (rev 50466)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py 2012-01-26 12:23:09 UTC (rev 50467)
@@ -183,7 +183,7 @@
self.relative_time.set_unit(unit)
def get_map_time(self):
- """Return the type of the map time, interval, point, maixed or invalid"""
+ """Return the type of the map time, interval, point, mixed or invalid"""
temporal_type = self.get_temporal_type()
@@ -197,7 +197,7 @@
def print_temporal_relation_matrix(self, maps):
"""Print the temporal relation matrix of all registered maps to stdout
- The temproal relation matrix includes the temporal relations between
+ The temporal relation matrix includes the temporal relations between
all registered maps. The relations are strings stored in a list of lists.
@param dbif: The database interface to be used
@@ -227,11 +227,11 @@
print maps[i].base.get_name()
def get_temporal_relation_matrix(self, maps):
- """Return the temporal relation matrix of all registered maps as listof lists
+ """Return the temporal relation matrix of all registered maps as list of lists
The map list must be ordered by start time
- The temproal relation matrix includes the temporal relations between
+ The temporal relation matrix includes the temporal relations between
all registered maps. The relations are strings stored in a list of lists.
@param maps: a ordered by start_time list of map objects
@@ -293,10 +293,10 @@
return tcount
def count_gaps(self, maps):
- """Count the number of gaps between temporal neighbours
+ """Count the number of gaps between temporal neighbors
@param maps: A sorted (start_time) list of abstract_dataset objects
- @return The numbers of gaps between temporal neighbours
+ @return The numbers of gaps between temporal neighbors
"""
gaps = 0
@@ -473,7 +473,7 @@
use_contain = False
use_equal = False
- # Inititalize the methods
+ # Initialize the methods
if method:
for name in method:
if name == "start":
@@ -731,7 +731,7 @@
def get_registered_maps(self, columns=None, where = None, order = None, dbif=None):
"""Return sqlite rows of all registered maps.
- In case columsn are not specified, each row includes all columns specified in the datatype specific view
+ In case columns are not specified, each row includes all columns specified in the datatype specific view
@param columns: Columns to be selected as SQL compliant string
@param where: The SQL where statement to select a subset of the registered maps without "WHERE"
@@ -856,14 +856,19 @@
if map.is_in_db(dbif) == False:
dbif.close()
core.fatal(_("Only maps with absolute or relative valid time can be registered"))
+ 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()))
- core.verbose(_("Register %s map <%s> in space time %s dataset <%s>") % (map.get_type(), map.get_id(), map.get_type(), self.get_id()))
-
# First select all data from the database
map.select(dbif)
if not map.check_valid_time():
- core.fatal(_("Map <%s> has invalid time") % map.get_id())
+ if map.get_layer():
+ core.fatal(_("Map <%s> with layer %s has invalid time") % map.get_map_id(), map.get_layer())
+ else:
+ core.fatal(_("Map <%s> has invalid time") % map.get_map_id())
map_id = map.base.get_id()
map_name = map.base.get_name()
@@ -882,7 +887,10 @@
# Check temporal types
if stds_ttype != map_ttype:
- core.fatal(_("Temporal type of space time dataset <%s> and map <%s> are different") % (self.get_id(), map.get_id()))
+ if map.get_layer():
+ core.fatal(_("Temporal type of space time dataset <%s> and map <%s> with layer %s are different") % (self.get_id(), map.get_map_id(), map.get_layer()))
+ else:
+ core.fatal(_("Temporal type of space time dataset <%s> and map <%s> are different") % (self.get_id(), map.get_map_id()))
# In case no map has been registered yet, set the relative time unit from the first map
if self.metadata.get_number_of_maps() == None and self.map_counter == 0 and self.is_time_relative():
@@ -894,7 +902,10 @@
# Check the relative time unit
if self.is_time_relative() and (stds_rel_time_unit != map_rel_time_unit):
- core.fatal(_("Relative time units of space time dataset <%s> and map <%s> are different") % (self.get_id(), map.get_id()))
+ if map.get_layer():
+ core.fatal(_("Relative time units of space time dataset <%s> and map <%s> with layer %s are different") % (self.get_id(), map.get_map_id(), map.get_layer()))
+ else:
+ core.fatal(_("Relative time units of space time dataset <%s> and map <%s> are different") % (self.get_id(), map.get_map_id()))
#print "STDS register table", stds_register_table
@@ -902,7 +913,7 @@
dbif.close()
core.fatal(_("Only maps from the same mapset can be registered"))
- # Check if map is already registred
+ # Check if map is already registered
if stds_register_table:
if dbmi.paramstyle == "qmark":
sql = "SELECT id FROM " + stds_register_table + " WHERE id = (?)"
@@ -914,13 +925,17 @@
if row and row[0] == map_id:
if connect == True:
dbif.close()
- core.warning(_("Map <%s> is already registered.") % (map_id))
+
+ if map.get_layer():
+ core.warning(_("Map <%s> with layer %s is already registered.") % (map.get_map_id(), map.get_layer()))
+ else:
+ core.warning(_("Map <%s> is already registered.") % (map.get_map_id()))
return False
# Create tables
sql_path = get_sql_template_path()
- # We need to create the map raster register table bevor we can register the map
+ # We need to create the map raster register table before we can register the map
if map_register_table == None:
# Create a unique id
uuid_rand = "map_" + str(uuid.uuid4()).replace("-", "")
@@ -943,16 +958,24 @@
except:
if connect == True:
dbif.close()
- core.error(_("Unable to create the space time %s dataset register table for <%s>") % \
- (map.get_type(), map.get_id()))
+ if map.get_layer():
+ core.error(_("Unable to create the space time %s dataset register table for map <%s> with layer %s") % \
+ (map.get_type(), map.get_map_id(), map.get_layer()))
+ else:
+ core.error(_("Unable to create the space time %s dataset register table for <%s>") % \
+ (map.get_type(), map.get_map_id()))
raise
# Set the stds register table name and put it into the DB
map.set_stds_register(map_register_table)
map.metadata.update(dbif)
- core.verbose(_("Created register table <%s> for %s map <%s>") % \
- (map_register_table, map.get_type(), map.get_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 == None:
@@ -980,8 +1003,12 @@
except:
if connect == True:
dbif.close()
- core.error(_("Unable to create the space time %s dataset register table for <%s>") % \
- (map.get_type(), map.get_id()))
+ if map.get_layer():
+ core.error(_("Unable to create the space time %s dataset register table for map <%s> with layer %s") % \
+ (map.get_type(), map.get_map_id(), map.get_layer()))
+ else:
+ core.error(_("Unable to create the space time %s dataset register table for <%s>") % \
+ (map.get_type(), map.get_map_id()))
raise
# Set the map register table name and put it into the DB
@@ -1028,7 +1055,7 @@
def unregister_map(self, map, dbif = None):
"""Unregister a map from the space time dataset.
- This method takes care of the unregistration of a map
+ This method takes care of the un-registration of a map
from a space time dataset.
@param map: The map object to unregister
@@ -1043,13 +1070,20 @@
if map.is_in_db(dbif) == False:
dbif.close()
- core.fatal(_("Unable to find map <%s> in temporal database") % (map.get_id()))
+
+ if map.get_layer():
+ core.fatal(_("Unable to find map <%s> with layer %s in temporal database") % (map.get_map_id(), map.get_layer()))
+ else:
+ core.fatal(_("Unable to find map <%s> in temporal database") % (map.get_map_id()))
- core.verbose(_("Unregister %s map <%s>") % (map.get_type(), map.get_id()))
+ if map.get_layer():
+ 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()))
# First select all data from the database
map.select(dbif)
- map_id = map.base.get_id()
+ map_id = map.get_id()
map_register_table = map.get_stds_register()
stds_register_table = self.get_map_register()
@@ -1063,7 +1097,10 @@
# Break if the map is not registered
if row == None:
- core.warning(_("Map <%s> is not registered in space time dataset") %(map_id, self.base.get_id()))
+ if map.get_layer():
+ core.warning(_("Map <%s> with layer %s is not registered in space time dataset <%s>") %(map.get_map_id(), map.get_layer(), self.base.get_id()))
+ else:
+ core.warning(_("Map <%s> is not registered in space time dataset <%s>") %(map.get_map_id(), self.base.get_id()))
if connect == True:
dbif.close()
return False
@@ -1100,9 +1137,9 @@
will be used. If the end time is earlier than the maximum start time, it will
be replaced by the maximum start time.
- An other solution to automate this is to use the diactivated trigger
+ An other solution to automate this is to use the deactivated trigger
in the SQL files. But this will result in a huge performance issue
- in case many maps are registred (>1000).
+ in case many maps are registered (>1000).
@param dbif: The database interface to be used
"""
@@ -1286,7 +1323,7 @@
def create_temporal_relation_sql_where_statement(start, end, use_start=True, use_during=False,
use_overlap=False, use_contain=False, use_equal=False):
- """ Create a SQL WHERE statement for temporal relation selection of maps in space time datastes
+ """ Create a SQL WHERE statement for temporal relation selection of maps in space time datasets
@param start: The start time
@param end: The end time
Modified: grass/trunk/lib/python/temporal/aggregation.py
===================================================================
--- grass/trunk/lib/python/temporal/aggregation.py 2012-01-26 12:22:41 UTC (rev 50466)
+++ grass/trunk/lib/python/temporal/aggregation.py 2012-01-26 12:23:09 UTC (rev 50467)
@@ -42,7 +42,7 @@
use_contain = False
use_equal = False
- # Inititalize the methods
+ # Initialize the methods
if sampling:
for name in sampling.split(","):
if name == "start":
Modified: grass/trunk/lib/python/temporal/base.py
===================================================================
--- grass/trunk/lib/python/temporal/base.py 2012-01-26 12:22:41 UTC (rev 50466)
+++ grass/trunk/lib/python/temporal/base.py 2012-01-26 12:23:09 UTC (rev 50467)
@@ -5,8 +5,8 @@
Temporal GIS base classes to be used in other
Python temporal gis packages.
-This packages includes all base classes to stor basic information like id, name,
-mapset creation and modification time as well as sql serialization and deserialization
+This packages includes all base classes to store basic information like id, name,
+mapset creation and modification time as well as sql serialization and de-serialization
and the sql database interface.
Usage:
@@ -35,11 +35,11 @@
self.D = {}
def serialize(self, type, table, where=None):
"""Convert the internal dictionary into a string of semicolon separated SQL statements
- The keys are the colum names and the values are the row entries
+ The keys are the column names and the values are the row entries
@type must be SELECT. INSERT, UPDATE
@table The name of the table to select, insert or update
- @where The optinal where statment
+ @where The optional where statement
@return the sql string
"""
@@ -142,14 +142,14 @@
def deserialize(self, row):
"""Convert the content of the dbmi dictionary like row into the internal dictionary
- @param row: The dixtionary like row to stoe in the internal dict
+ @param row: The dictionary like row to store in the internal dict
"""
self.D = {}
for key in row.keys():
self.D[key] = row[key]
def clear(self):
- """Inititalize the internal storage"""
+ """Initialize the internal storage"""
self.D = {}
def print_self(self):
@@ -390,6 +390,8 @@
if ident != None and name == None and mapset == None:
if ident.find("@") >= 0:
name, mapset = ident.split("@")
+ if name.find(":") >= 0:
+ name, layer = ident.split(":")
self.set_name(name)
self.set_mapset(mapset)
self.set_creator(creator)
@@ -401,7 +403,7 @@
def set_id(self, ident):
"""Convenient method to set the unique identifier (primary key)
- @param ident: The unique identififer should be a combination of the dataset name and the mapset name at mapset
+ @param ident: The unique identifier should be a combination of the dataset name, layer name and the mapset name at mapset
"""
self.ident = ident
self.D["id"] = ident
@@ -416,10 +418,19 @@
def set_mapset(self, mapset):
"""Set the mapset of the dataset
- @param mapsets: The name of the mapset in whoch this dataset is stored
+ @param mapsets: The name of the mapset in which this dataset is stored
"""
self.D["mapset"] = mapset
+ def set_layer(self, layer):
+ """Convenient method to set the layer of the map (part of primary key)
+
+ Layer are currently supported for vector maps
+
+ @param layer: The layer of the map
+ """
+ self.D["layer"] = layer
+
def set_creator(self, creator):
"""Set the creator of the dataset
@@ -468,6 +479,30 @@
else:
return None
+ def get_map_id(self):
+ """Convenient method to get the unique map identifier without layer information
+
+ @param return the name of the vector map as name at mapset
+ """
+ id = self.get_id()
+ if id.find(":") >= 0:
+ # Remove the layer identifier from the id
+ return id.split("@")[0].split(":")[0] + "@" + id.split("@")[1]
+ else:
+ return id
+
+ def get_layer(self):
+ """Convenient method to get the layer of the map (part of primary key)
+
+ Layer are currently supported for vector maps
+
+ @return None if not found
+ """
+ if self.D.has_key("layer"):
+ return self.D["layer"]
+ else:
+ return None
+
def get_name(self):
"""Get the name of the dataset
@return None if not found"""
@@ -531,6 +566,8 @@
print " | Id: ........................ " + str(self.get_id())
print " | Name: ...................... " + str(self.get_name())
print " | Mapset: .................... " + str(self.get_mapset())
+ if self.get_layer():
+ print " | Layer:...................... " + str(self.get_layer())
print " | Creator: ................... " + str(self.get_creator())
print " | Creation time: ............. " + str(self.get_ctime())
# print " | Modification time: ......... " + str(self.get_mtime())
@@ -542,6 +579,8 @@
print "id=" + str(self.get_id())
print "name=" + str(self.get_name())
print "mapset=" + str(self.get_mapset())
+ if self.get_layer():
+ print "layer=" + str(self.get_layer())
print "creator=" + str(self.get_creator())
print "creation_time=" + str(self.get_ctime())
# print "modification_time=" + str(self.get_mtime())
@@ -563,11 +602,23 @@
modification_time, temporal_type, revision)
class vector_base(dataset_base):
- def __init__(self, ident=None, name=None, mapset=None, creator=None, creation_time=None,\
+ def __init__(self, ident=None, name=None, mapset=None, layer=None, creator=None, creation_time=None,\
modification_time=None, temporal_type=None, revision=1):
dataset_base.__init__(self, "vector_base", ident, name, mapset, creator, creation_time,\
modification_time, temporal_type, revision)
+ self.set_id(ident)
+ if ident != None and name == None and mapset == None:
+ if ident.find("@") >= 0:
+ name, mapset = ident.split("@")
+ if layer == None:
+ if name.find(":") >= 0:
+ name, layer = name.split(":")
+ self.set_name(name)
+ self.set_mapset(mapset)
+ # Layer currently only in use by vector maps
+ self.set_layer(layer)
+
###############################################################################
class stds_base(dataset_base):
Modified: grass/trunk/lib/python/temporal/core.py
===================================================================
--- grass/trunk/lib/python/temporal/core.py 2012-01-26 12:22:41 UTC (rev 50466)
+++ grass/trunk/lib/python/temporal/core.py 2012-01-26 12:23:09 UTC (rev 50467)
@@ -2,7 +2,7 @@
@brief GRASS Python scripting module (temporal GIS functions)
-Temporal GIS core functions to be used in Python sripts.
+Temporal GIS core functions to be used in Python scripts.
Usage:
@@ -27,7 +27,7 @@
###############################################################################
-# The chosen DBMI backend can be defined on runtime
+# The chosen DBMI back-end can be defined on runtime
# Check the grass environment before import
core.run_command("t.connect", flags="c")
kv = core.parse_command("t.connect", flags="pg")
@@ -79,7 +79,7 @@
"""This function creates the grass location database structure for raster, vector and raster3d maps
as well as for the space-time datasets strds, str3ds and stvds
- This functions must be called befor any spatio-temporal processing is started
+ This functions must be called before any spatio-temporal processing is started
"""
database = get_temporal_dbmi_init_string()
Modified: grass/trunk/lib/python/temporal/datetime_math.py
===================================================================
--- grass/trunk/lib/python/temporal/datetime_math.py 2012-01-26 12:22:41 UTC (rev 50466)
+++ grass/trunk/lib/python/temporal/datetime_math.py 2012-01-26 12:23:09 UTC (rev 50467)
@@ -2,7 +2,7 @@
@brief GRASS Python scripting module (temporal GIS functions)
-Temporal GIS datetime math functions to be used in Python sripts.
+Temporal GIS datetime math functions to be used in Python scripts.
Usage:
@@ -51,7 +51,7 @@
def increment_datetime_by_string(mydate, increment, mult = 1):
"""Return a new datetime object incremented with the provided relative dates specified as string.
- Additional a multiplier can be specified to multiply the increment bevor adding to the provided datetime object.
+ Additional a multiplier can be specified to multiply the increment before adding to the provided datetime object.
@param mydate A datetime object to incremented
@param increment A string providing increment information:
@@ -126,7 +126,7 @@
# Make a deep copy of the datetime object
dt1 = copy.copy(mydate)
- # Make sure the montha starts with a 1
+ # Make sure the month starts with a 1
if residual_months == 0:
residual_months = 1
@@ -321,7 +321,7 @@
def string_to_datetime(time_string):
"""Convert a string into a datetime object using the dateutil parser. Return None in case of failure"""
- # BC is not suported
+ # BC is not supported
if time_string.find("bc") > 0:
core.error("Dates Before Christ are not supported in the temporal database")
return None
@@ -340,7 +340,7 @@
# GRASS datetime month names
month_names = ["", "jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]
- # Check for time zone infor in the datetime object
+ # Check for time zone info in the datetime object
if dt.tzinfo != None:
string = "%.2i %s %.2i %.2i:%.2i:%.2i %+.4i"%(dt.day, month_names[dt.month], dt.year, \
dt.hour, dt.minute, dt.second, dt.tzinfo._offset.seconds/60)
Modified: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py 2012-01-26 12:22:41 UTC (rev 50466)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py 2012-01-26 12:23:09 UTC (rev 50467)
@@ -78,7 +78,7 @@
"""Load all info from an existing raster map into the internal structure"""
# Get the data from an existing raster map
- kvp = raster.raster_info(self.ident)
+ kvp = raster.raster_info(self.get_map_id())
# Fill base information
@@ -156,7 +156,7 @@
"""Load all info from an existing raster3d map into the internal structure"""
# Get the data from an existing raster map
- kvp = raster3d.raster3d_info(self.ident)
+ kvp = raster3d.raster3d_info(self.get_map_id())
# Fill base information
@@ -224,6 +224,10 @@
"""Return the name of the C-module to set the time stamp in the file system"""
return "v.timestamp"
+ def get_layer(self):
+ """Return the layer"""
+ return self.base.get_layer()
+
def reset(self, ident):
"""Reset the internal structure and set the identifier"""
self.ident = ident
@@ -238,11 +242,14 @@
"""Load all info from an existing vector map into the internal structure"""
# Get the data from an existing raster map
- kvp = vector.vector_info(self.ident)
+ kvp = vector.vector_info(self.get_map_id())
# Fill base information
-
- self.base.set_name(self.ident.split("@")[0])
+ if self.ident.find(":") >= 0:
+ self.base.set_name(self.ident.split("@")[0].split(":")[0])
+ self.base.set_layer(self.ident.split("@")[0].split(":")[1])
+ else:
+ self.base.set_name(self.ident.split("@")[0])
self.base.set_mapset(self.ident.split("@")[1])
self.base.set_creator(str(getpass.getuser()))
Modified: grass/trunk/lib/python/temporal/space_time_datasets_tools.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets_tools.py 2012-01-26 12:22:41 UTC (rev 50466)
+++ grass/trunk/lib/python/temporal/space_time_datasets_tools.py 2012-01-26 12:23:09 UTC (rev 50467)
@@ -26,7 +26,9 @@
###############################################################################
-def register_maps_in_space_time_dataset(type, name, maps=None, file=None, start=None, end=None, unit=None, increment=None, dbif = None, interval=False, fs="|"):
+def register_maps_in_space_time_dataset(type, name, maps=None, layer=None, file=None, start=None, \
+ end=None, unit=None, increment=None, dbif = None, \
+ interval=False, fs="|"):
"""Use this method to register maps in space time datasets. This function is generic and
Additionally a start time string and an increment string can be specified
@@ -50,6 +52,7 @@
start_time_in_file = False
end_time_in_file = False
+ layer_in_file = False
if maps and file:
core.fatal(_("%s= and %s= are mutually exclusive") % ("input","file"))
@@ -63,6 +66,9 @@
if not maps and not file:
core.fatal(_("Please specify %s= or %s=") % ("input","file"))
+ if layer and layer == "file":
+ layer_in_file = True
+
if start and start == "file":
start_time_in_file = True
@@ -94,15 +100,39 @@
dbif.close()
core.fatal(_("Space time %s dataset <%s> no found") % (sp.get_new_map_instance(None).get_type(), name))
+ dummy = sp.get_new_map_instance(None)
+
maplist = []
-
+ layerlist = []
+
# Map names as comma separated string
if maps:
- if maps.find(",") == -1:
- maplist = (maps,)
+ if maps.find(",") < 0:
+ maplist = [maps,]
else:
- maplist = tuple(maps.split(","))
+ maplist = maps.split(",")
+ # Layer as comma separated string
+ if layer:
+ if layer.find(",") < 0:
+ layerlist = (layer,)
+ else:
+ layerlist = layer.split(",")
+
+ if len(maplist) != len(layerlist):
+ core.fatal(_("Number of %s= and %s= must be equal") % ("maps","layer"))
+
+ # Build the maplist again with the ids
+ for count in range(len(maplist)):
+ row = {}
+ if layer:
+ mapid = dummy.build_id(maplist[count], mapset, layerlist[count])
+ else:
+ mapid = dummy.build_id(maplist[count], mapset, None)
+
+ row["id"] = mapid
+ maplist[count] = row
+
# Read the map list from file
if file:
fd = open(file, "r")
@@ -117,66 +147,73 @@
mapname = line_list[0].strip()
- if mapname.find("@") < 0:
- mapid = mapname + "@" + mapset
- else:
- mapid = mapname
-
row = {}
- row["id"] = mapid
+
+ if layer_in_file:
+ row["layer"] = line_list[1].strip()
+ if start_time_in_file and end_time_in_file:
+ row["start"] = line_list[2].strip()
+ row["end"] = line_list[3].strip()
- if start_time_in_file and end_time_in_file:
- row["start"] = line_list[1].strip()
- row["end"] = line_list[2].strip()
+ if start_time_in_file and not end_time_in_file:
+ row["start"] = line_list[2].strip()
+
+ row["id"] = dummy.build_id(mapname, mapset, row["layer"])
+ else:
+ if start_time_in_file and end_time_in_file:
+ row["start"] = line_list[1].strip()
+ row["end"] = line_list[2].strip()
- if start_time_in_file and not end_time_in_file:
- row["start"] = line_list[1].strip()
+ if start_time_in_file and not end_time_in_file:
+ row["start"] = line_list[1].strip()
+
+ row["id"] = dummy.build_id(mapname, mapset)
maplist.append(row)
num_maps = len(maplist)
- count = 0
- for entry in maplist:
+ for count in range(len(maplist)):
core.percent(count, num_maps, 1)
# Get a new instance of the space time dataset map type
- if file:
- map = sp.get_new_map_instance(entry["id"])
- else:
- if entry.find("@") < 0:
- mapid = entry + "@" + mapset
- else:
- mapid = entry
+ map = sp.get_new_map_instance(maplist[count]["id"])
- map = sp.get_new_map_instance(mapid)
-
# Use the time data from file
if start_time_in_file:
- start = entry["start"]
+ start = maplist[count]["start"]
if end_time_in_file:
- end = entry["end"]
+ end = maplist[count]["end"]
# Put the map into the database
if map.is_in_db(dbif) == False:
# Break in case no valid time is provided
if start == "" or start == None:
dbif.close()
- core.fatal(_("Unable to register %s map <%s>. The map has no valid time and the start time is not set.") % \
- (map.get_type(), map.get_id() ))
+ if map.get_layer():
+ core.fatal(_("Unable to register %s map <%s> with layer %s. The map has no valid time and the start time is not set.") % \
+ (map.get_type(), map.get_map_id(), map.get_layer() ))
+ else:
+ core.fatal(_("Unable to register %s map <%s>. The map has no valid time and the start time is not set.") % \
+ (map.get_type(), map.get_map_id() ))
# Load the data from the grass file database
map.load()
-
+
if sp.get_temporal_type() == "absolute":
map.set_time_to_absolute()
else:
map.set_time_to_relative()
+
# Put it into the temporal database
map.insert(dbif)
else:
map.select(dbif)
if map.get_temporal_type() != sp.get_temporal_type():
dbif.close()
- core.fatal(_("Unable to register %s map <%s>. The temporal types are different.") % (map.get_type(), map.get_id()))
+ if map.get_layer():
+ core.fatal(_("Unable to register %s map <%s> with layer. The temporal types are different.") % \
+ (map.get_type(), map.get_map_id(), map.get_layer()))
+ core.fatal(_("Unable to register %s map <%s>. The temporal types are different.") % \
+ (map.get_type(), map.get_map_id()))
# In case the time is in the input file we ignore the increment counter
if start_time_in_file:
@@ -188,7 +225,6 @@
# Finally Register map in the space time dataset
sp.register_map(map, dbif)
- count += 1
# Update the space time tables
sp.update_from_registered_maps(dbif)
@@ -200,7 +236,7 @@
###############################################################################
-def unregister_maps_from_space_time_datasets(type, name, maps, file=None, dbif = None):
+def unregister_maps_from_space_time_datasets(type, name, maps, layer=None, file=None, dbif=None):
"""Unregister maps from a single space time dataset or, in case no dataset name is provided,
unregister from all datasets within the maps are registered.
@@ -220,6 +256,11 @@
dbif.connect()
connect = True
+ layer_in_file = False
+
+ if layer and layer == "file":
+ layer_in_file = True
+
# In case a space time dataset is specified
if name:
# Check if the dataset name contains the mapset as well
@@ -240,14 +281,38 @@
core.fatal("Space time " + sp.get_new_map_instance(None).get_type() + " dataset <" + name + "> not found")
maplist = []
+ layerlist = []
+ dummy = raster_dataset(None)
+
# Map names as comma separated string
- if maps:
- if maps.find(",") == -1:
- maplist = (maps,)
- else:
- maplist = tuple(maps.split(","))
-
+ if maps != None:
+ if maps.find(",") == -1:
+ maplist = [maps,]
+ else:
+ maplist = maps.split(",")
+
+ if layer:
+ if layer.find(",") < 0:
+ layerlist = (layer,)
+ else:
+ layerlist = layer.split(",")
+
+ if len(maplist) != len(layerlist):
+ core.fatal(_("Number of %s= and %s= must be equal") % ("maps","layer"))
+
+ # Build the maplist
+ for count in range(len(maplist)):
+ mapname = maplist[count]
+
+ if layer:
+ mylayer = layerlist[count]
+ mapid = dummy.build_id(mapname, mapset, mylayer)
+ else:
+ mapid = dummy.build_id(mapname, mapset)
+
+ maplist[count] = mapid
+
# Read the map list from file
if file:
fd = open(file, "r")
@@ -260,19 +325,21 @@
line_list = line.split(fs)
mapname = line_list[0].strip()
- maplist.append(mapname)
+ if layer_in_file:
+ mylayer = line_list[1].strip()
+ mapid = dummy.build_id(mapname, mapset, mylayer)
+ else:
+ mapid = dummy.build_id(mapname, mapset)
+
+ maplist.append(mapid)
+
num_maps = len(maplist)
count = 0
- for mapname in maplist:
+ for mapid in maplist:
core.percent(count, num_maps, 1)
- mapname = mapname.strip()
- # Check if the map name contains the mapset as well
- if mapname.find("@") < 0:
- mapid = mapname + "@" + mapset
- else:
- mapid = mapname
+ print mapid
map = dataset_factory(type, mapid)
# Unregister map if in database
@@ -497,8 +564,11 @@
start_time = increment_datetime_by_string(start_time, increment, mult)
if interval:
end_time = increment_datetime_by_string(start_time, increment, 1)
-
- core.verbose(_("Set absolute valid time for map <%s> to %s - %s") % (map.get_id(), str(start_time), str(end_time)))
+ if map.get_layer():
+ core.verbose(_("Set absolute valid time for map <%s> with layer %s to %s - %s") % (map.get_map_id(), map.get_layer(), str(start_time), str(end_time)))
+ else:
+ core.verbose(_("Set absolute valid time for map <%s> to %s - %s") % (map.get_map_id(), str(start_time), str(end_time)))
+
map.update_absolute_time(start_time, end_time, None, dbif)
else:
start_time = int(start)
@@ -512,7 +582,11 @@
if interval:
end_time = start_time + int(increment)
- core.verbose(_("Set relative valid time for map <%s> to %i - %s with unit %s") % (map.get_id(), start_time, str(end_time), unit))
+ if map.get_layer():
+ core.verbose(_("Set relative valid time for map <%s> with layer %s to %i - %s with unit %s") % (map.get_map_id(), map.get_layer(), start_time, str(end_time), unit))
+ else:
+ core.verbose(_("Set relative valid time for map <%s> to %i - %s with unit %s") % (map.get_map_id(), start_time, str(end_time), unit))
+
map.update_relative_time(start_time, end_time, unit, dbif)
if connect == True:
@@ -552,14 +626,14 @@
@param type: The type of the maps raster, raster3d or vector
@param input: Name of a space time raster dataset
@param columns: A comma separated list of columns to be printed to stdout
- @param order: A comma seoarated list of columns to order the space time dataset by category
+ @param order: A comma separated list of columns to order the space time dataset by category
@param where: A where statement for selected listing without "WHERE" e.g: start_time < "2001-01-01" and end_time > "2001-01-01"
@param separator: The field separator character between the columns
@param method: String identifier to select a method out of cols,comma,delta or deltagaps
* "cols": Print preselected columns specified by columns
* "comma": Print the map ids (name at mapset) as comma separated string
* "delta": Print the map ids (name at mapset) with start time, end time, relative length of intervals and the relative distance to the begin
- * "deltagaps": Same as "delta" with addtitionakl listing of gaps. Gaps can be simply identified as the id is "None"
+ * "deltagaps": Same as "delta" with additional listing of gaps. Gaps can be simply identified as the id is "None"
* "gran": List map using the granularity of the space time dataset, columns are identical to deltagaps
@param header: Set True to print column names
"""
@@ -582,7 +656,10 @@
# This method expects a list of objects for gap detection
if method == "delta" or method == "deltagaps" or method == "gran":
- columns = "id,start_time,end_time"
+ if type == "stvds":
+ columns = "id,name,layer,mapset,start_time,end_time"
+ else:
+ columns = "id,name,mapset,start_time,end_time"
if method == "deltagaps":
maps = sp.get_registered_maps_as_objects_with_gaps(where, None)
elif method == "delta":
@@ -592,7 +669,11 @@
if header:
string = ""
- string += "%s%s" % ("id", separator)
+ string += "%s%s" % ("id", separator)
+ string += "%s%s" % ("name", separator)
+ if type == "stvds":
+ string += "%s%s" % ("layer", separator)
+ string += "%s%s" % ("mapset", separator)
string += "%s%s" % ("start_time", separator)
string += "%s%s" % ("end_time", separator)
string += "%s%s" % ("interval_length", separator)
@@ -627,6 +708,10 @@
string = ""
string += "%s%s" % (map.get_id(), separator)
+ string += "%s%s" % (map.get_name(), separator)
+ if type == "stvds":
+ string += "%s%s" % (map.get_layer(), separator)
+ string += "%s%s" % (map.get_mapset(), separator)
string += "%s%s" % (start, separator)
string += "%s%s" % (end, separator)
string += "%s%s" % (delta, separator)
@@ -686,6 +771,8 @@
""" Sample the input space time dataset with a sample space time dataset and print the result to stdout
In case multiple maps are located in the current granule, the map names are separated by comma.
+
+ In case a layer is present, the names map ids are extended in this form: name:layer at mapset
Attention: Do not use the comma as separator
Modified: grass/trunk/lib/python/temporal/spatial_extent.py
===================================================================
--- grass/trunk/lib/python/temporal/spatial_extent.py 2012-01-26 12:22:41 UTC (rev 50466)
+++ grass/trunk/lib/python/temporal/spatial_extent.py 2012-01-26 12:23:09 UTC (rev 50467)
@@ -122,7 +122,7 @@
self.D["north"] = north
def set_south(self, sourth):
- """Set the sourthern edge of the map"""
+ """Set the southern edge of the map"""
self.D["south"] = sourth
def set_west(self, west):
Modified: grass/trunk/lib/python/temporal/temporal_extent.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_extent.py 2012-01-26 12:22:41 UTC (rev 50466)
+++ grass/trunk/lib/python/temporal/temporal_extent.py 2012-01-26 12:23:09 UTC (rev 50467)
@@ -103,7 +103,7 @@
return False
def before(self, map):
- """Return True if this time object is temporal located bevor the provided time object
+ """Return True if this time object is temporal located before the provided time object
A |---------|
B |---------|
"""
@@ -235,7 +235,7 @@
return False
def overlapped(self, map):
- """Return True if this time object is temporal overlaped by the provided time object
+ """Return True if this time object is temporal overlapped by the provided time object
A |---------|
B |---------|
"""
@@ -250,7 +250,7 @@
def temporal_relation(self, map):
"""Returns the temporal relation between temporal objects
- Temporal relationsships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
+ Temporal relationships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
"""
# First check for correct time
@@ -505,7 +505,7 @@
def temporal_relation(self, map):
"""Returns the temporal relation between temporal objects
- Temporal relationsships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
+ Temporal relationships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
"""
# Check units for relative time
Modified: grass/trunk/lib/python/temporal/temporal_granularity.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_granularity.py 2012-01-26 12:22:41 UTC (rev 50466)
+++ grass/trunk/lib/python/temporal/temporal_granularity.py 2012-01-26 12:23:09 UTC (rev 50467)
@@ -28,7 +28,7 @@
def compute_relative_time_granularity(maps):
""" Compute the relative granularity"""
- # The intervaltime must be scaled to days resoltuion
+ # The interval time must be scaled to days resolution
granularity = None
delta = []
More information about the grass-commit
mailing list