[GRASS-SVN] r48399 - in grass/trunk: lib/python lib/python/temporal
lib/temporal temporal/t.create temporal/t.info
temporal/t.list temporal/t.remove temporal/t.time.abs
temporal/t.time.rel temporal/tr.register
temporal/tr.unregister temporal/tr3.register
temporal/tr3.unregister temporal/tv.register temporal/tv.unregister
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Sep 21 17:06:55 EDT 2011
Author: huhabla
Date: 2011-09-21 14:06:55 -0700 (Wed, 21 Sep 2011)
New Revision: 48399
Added:
grass/trunk/lib/python/temporal/
grass/trunk/lib/python/temporal/abstract_datasets.py
grass/trunk/lib/python/temporal/base.py
grass/trunk/lib/python/temporal/core.py
grass/trunk/lib/python/temporal/metadata.py
grass/trunk/lib/python/temporal/space_time_datasets.py
grass/trunk/lib/python/temporal/spatial_extent.py
grass/trunk/lib/python/temporal/temporal_extent.py
Removed:
grass/trunk/lib/python/tgis_abstract_datasets.py
grass/trunk/lib/python/tgis_base.py
grass/trunk/lib/python/tgis_core.py
grass/trunk/lib/python/tgis_metadata.py
grass/trunk/lib/python/tgis_space_time_datasets.py
grass/trunk/lib/python/tgis_spatial_extent.py
grass/trunk/lib/python/tgis_temporal_extent.py
Modified:
grass/trunk/lib/python/Makefile
grass/trunk/lib/temporal/Makefile
grass/trunk/temporal/t.create/t.create.py
grass/trunk/temporal/t.info/t.info.py
grass/trunk/temporal/t.list/t.list.py
grass/trunk/temporal/t.remove/t.remove.py
grass/trunk/temporal/t.time.abs/t.time.abs.py
grass/trunk/temporal/t.time.rel/t.time.rel.py
grass/trunk/temporal/tr.register/tr.register.py
grass/trunk/temporal/tr.unregister/tr.unregister.py
grass/trunk/temporal/tr3.register/tr3.register.py
grass/trunk/temporal/tr3.unregister/tr3.unregister.py
grass/trunk/temporal/tv.register/tv.register.py
grass/trunk/temporal/tv.unregister/tv.unregister.py
Log:
Moved the temporal GIS code from grass.script into a separate library structure named grass.temporal.
Modified: grass/trunk/lib/python/Makefile
===================================================================
--- grass/trunk/lib/python/Makefile 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/Makefile 2011-09-21 21:06:55 UTC (rev 48399)
@@ -8,16 +8,17 @@
GDIR = $(PYDIR)/grass
DSTDIR = $(GDIR)/script
-MODULES = core db raster raster3d vector array setup task tgis_base tgis_core tgis_abstract_datasets tgis_space_time_datasets tgis_metadata tgis_spatial_extent tgis_temporal_extent
+MODULES = core db raster raster3d vector array setup task
PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)
-CLEAN_SUBDIRS = ctypes
+CLEAN_SUBDIRS = ctypes temporal
EXTRA_CLEAN_FILES = setup.py
default: $(PYFILES) $(PYCFILES) $(GDIR)/__init__.py $(GDIR)/__init__.pyc
-$(MAKE) -C ctypes || echo $(CURDIR)/ctypes >> $(ERRORLOG)
+ -$(MAKE) -C temporal || echo $(CURDIR)/temporal >> $(ERRORLOG)
$(PYDIR):
$(MKDIR) $@
Added: grass/trunk/lib/python/temporal/abstract_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_datasets.py (rev 0)
+++ grass/trunk/lib/python/temporal/abstract_datasets.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,758 @@
+"""!@package grass.script.tgis_abstract_datasets
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in temporal GIS Python library package.
+
+Usage:
+
+ at code
+from grass.script import tgis_abstract_datasets as grass
+
+...
+ at endcode
+
+(C) 2008-2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+import uuid
+from temporal_extent import *
+from spatial_extent import *
+from metadata import *
+
+class abstract_dataset(object):
+ """This is the base class for all datasets (raster, vector, raster3d, strds, stvds, str3ds)"""
+
+ def reset(self, ident):
+ """Reset the internal structure and set the identifier"""
+ raise IOError("This method must be implemented in the subclasses")
+
+ def get_type(self):
+ """Return the type of this class"""
+ raise IOError("This method must be implemented in the subclasses")
+
+ def get_new_instance(self, ident):
+ """Return a new instance with the type of this class"""
+ raise IOError("This method must be implemented in the subclasses")
+
+ def get_id(self):
+ return self.base.get_id()
+
+ def get_absolute_time(self):
+ """Returns a tuple of the start, the end valid time and the timezone of the map
+ @return A tuple of (start_time, end_time, timezone)
+ """
+
+ start = self.absolute_time.get_start_time()
+ end = self.absolute_time.get_end_time()
+ tz = self.absolute_time.get_timezone()
+
+ return (start, end, tz)
+
+ def get_relative_time(self):
+ """Returns the relative time interval (start_time, end_time) or None if not present"""
+
+ start = self.relative_time.get_start_time()
+ end = self.relative_time.get_end_time()
+
+ return (start, end)
+
+ def get_temporal_type(self):
+ """Return the temporal type of this dataset"""
+ return self.base.get_ttype()
+
+ def get_spatial_extent(self):
+ """Return a tuple of spatial extent (north, south, east, west, top, bottom) """
+
+ north = self.spatial_extent.get_north()
+ south = self.spatial_extent.get_south()
+ east = self.spatial_extent.get_east()
+ west = self.spatial_extent.get_west()
+ top = self.spatial_extent.get_top()
+ bottom = self.spatial_extent.get_bottom()
+
+ return (north, south, east, west, top, bottom)
+
+ def select(self, dbif=None):
+ """Select temporal dataset entry from database and fill up the internal structure"""
+ self.base.select(dbif)
+ if self.is_time_absolute():
+ self.absolute_time.select(dbif)
+ if self.is_time_relative():
+ self.relative_time.select(dbif)
+ self.spatial_extent.select(dbif)
+ self.metadata.select(dbif)
+
+ def is_in_db(self, dbif=None):
+ """Check if the temporal dataset entry is in the database"""
+ return self.base.is_in_db(dbif)
+
+ def delete(self):
+ """Delete temporal dataset entry from database if it exists"""
+ raise IOError("This method must be implemented in the subclasses")
+
+ def insert(self, dbif=None):
+ """Insert temporal dataset entry into database from the internal structure"""
+ self.base.insert(dbif)
+ if self.is_time_absolute():
+ self.absolute_time.insert(dbif)
+ if self.is_time_relative():
+ self.relative_time.insert(dbif)
+ self.spatial_extent.insert(dbif)
+ self.metadata.insert(dbif)
+
+ def update(self, dbif=None):
+ """Update temporal dataset entry of database from the internal structure"""
+ self.base.update(dbif)
+ if self.is_time_absolute():
+ self.absolute_time.update(dbif)
+ if self.is_time_relative():
+ self.relative_time.update(dbif)
+ self.spatial_extent.update(dbif)
+ self.metadata.update(dbif)
+
+ def print_self(self):
+ """Print the content of the internal structure to stdout"""
+ self.base.print_self()
+ if self.is_time_absolute():
+ self.absolute_time.print_self()
+ if self.is_time_relative():
+ self.relative_time.print_self()
+ self.spatial_extent.print_self()
+ self.metadata.print_self()
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+
+ if self.get_type() == "raster":
+ # 1 2 3 4 5 6 7
+ # 0123456789012345678901234567890123456789012345678901234567890123456789012345678
+ print ""
+ print " +-------------------- Raster Dataset ----------------------------------------+"
+ if self.get_type() == "raster3d":
+ # 1 2 3 4 5 6 7
+ # 0123456789012345678901234567890123456789012345678901234567890123456789012345678
+ print ""
+ print " +-------------------- Raster3d Dataset --------------------------------------+"
+ if self.get_type() == "vector":
+ # 1 2 3 4 5 6 7
+ # 0123456789012345678901234567890123456789012345678901234567890123456789012345678
+ print ""
+ print " +-------------------- Vector Dataset ----------------------------------------+"
+ if self.get_type() == "strds":
+ # 1 2 3 4 5 6 7
+ # 0123456789012345678901234567890123456789012345678901234567890123456789012345678
+ print ""
+ print " +-------------------- Space Time Raster Dataset -----------------------------+"
+ if self.get_type() == "str3ds":
+ # 1 2 3 4 5 6 7
+ # 0123456789012345678901234567890123456789012345678901234567890123456789012345678
+ print ""
+ print " +-------------------- Space Time Raster3d Dataset ---------------------------+"
+ if self.get_type() == "stvds":
+ # 1 2 3 4 5 6 7
+ # 0123456789012345678901234567890123456789012345678901234567890123456789012345678
+ print ""
+ print " +-------------------- Space Time Vector Dataset -----------------------------+"
+ print " | |"
+ self.base.print_info()
+ if self.is_time_absolute():
+ self.absolute_time.print_info()
+ if self.is_time_relative():
+ self.relative_time.print_info()
+ self.spatial_extent.print_info()
+ self.metadata.print_info()
+ print " +----------------------------------------------------------------------------+"
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ self.base.print_shell_info()
+ if self.is_time_absolute():
+ self.absolute_time.print_shell_info()
+ if self.is_time_relative():
+ self.relative_time.print_shell_info()
+ self.spatial_extent.print_shell_info()
+ self.metadata.print_shell_info()
+
+ def set_time_to_absolute(self):
+ self.base.set_ttype("absolute")
+
+ def set_time_to_relative(self):
+ self.base.set_ttype("relative")
+
+ def is_time_absolute(self):
+ if self.base.D.has_key("temporal_type"):
+ return self.base.get_ttype() == "absolute"
+ else:
+ return None
+
+ def is_time_relative(self):
+ if self.base.D.has_key("temporal_type"):
+ return self.base.get_ttype() == "relative"
+ else:
+ return None
+
+ def temporal_relation(self, map):
+ """Return the temporal relation of this and the provided temporal map"""
+ if self.is_time_absolute() and map.is_time_absolute():
+ return self.absolute_time.temporal_relation(map.absolute_time)
+ if self.is_time_relative() and map.is_time_relative():
+ return self.relative_time.temporal_relation(map.relative_time)
+ return None
+
+###############################################################################
+
+class abstract_map_dataset(abstract_dataset):
+ """This is the base class for all maps (raster, vector, raster3d)
+ providing additional function to set the valid time and the spatial extent.
+ """
+
+ def get_new_stds_instance(self, ident):
+ """Return a new space time dataset instance in which maps are stored with the type of this class"""
+ raise IOError("This method must be implemented in the subclasses")
+
+ def get_stds_register(self):
+ """Return the space time dataset register table name in which stds are listed in which this map is registered"""
+ raise IOError("This method must be implemented in the subclasses")
+
+ def set_stds_register(self, name):
+ """Set the space time dataset register table name in which stds are listed in which this map is registered"""
+ raise IOError("This method must be implemented in the subclasses")
+
+ def set_absolute_time(self, start_time, end_time=None, timezone=None):
+ """Set the absolute time interval with start time and end time
+
+ @start_time a datetime object specifying the start time of the map
+ @end_time a datetime object specifying the end time of the map
+ @timezone Thee timezone of the map
+
+ """
+ if start_time != None and not isinstance(start_time, datetime) :
+ core.fatal(_("Start time must be of type datetime"))
+
+ if end_time != None and not isinstance(end_time, datetime) :
+ core.fatal(_("End time must be of type datetime"))
+
+ if start_time != None and end_time != None:
+ if start_time >= end_time:
+ core.error(_("End time must be later than start time"))
+ return False
+
+ self.base.set_ttype("absolute")
+
+ self.absolute_time.set_start_time(start_time)
+ self.absolute_time.set_end_time(end_time)
+ self.absolute_time.set_timezone(timezone)
+
+ return True
+
+ def update_absolute_time(self, start_time, end_time=None, timezone=None, dbif = None):
+ """Update the absolute time
+
+ @start_time a datetime object specifying the start time of the map
+ @end_time a datetime object specifying the end time of the map
+ @timezone Thee timezone of the map
+ """
+ connect = False
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ self.set_absolute_time(start_time, end_time, timezone)
+ self.absolute_time.update(dbif)
+ self.base.update(dbif)
+
+ if connect == True:
+ dbif.close()
+
+ def set_relative_time(self, start_time, end_time=None):
+ """Set the relative time interval
+
+ @start_time A double value in days
+ @end_time A double value in days
+
+ """
+ if start_time != None and end_time != None:
+ if abs(float(start_time)) >= abs(float(end_time)):
+ core.error(_("End time must be greater than start time"))
+ return False
+
+ self.base.set_ttype("relative")
+
+ self.relative_time.set_start_time(float(start_time))
+ if end_time != None:
+ self.relative_time.set_end_time(float(end_time))
+ else:
+ self.relative_time.set_end_time(None)
+
+ return True
+
+ def update_relative_time(self, start_time, end_time=None, dbif = None):
+ """Set the relative time interval
+
+ @interval A double value in days
+
+ """
+ connect = False
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ self.set_relative_time(start_time, end_time)
+ self.relative_time.update(dbif)
+ self.base.update(dbif)
+
+ if connect == True:
+ dbif.close()
+
+ def set_spatial_extent(self, north, south, east, west, top=0, bottom=0):
+ """Set the spatial extent of the map"""
+ self.spatial_extent.set_spatial_extent(north, south, east, west, top, bottom)
+
+ def delete(self, dbif=None):
+ """Delete a map entry from database if it exists
+
+ Remove dependent entries:
+ * Remove the map entry in each space time dataset in which this map is registered
+ * Remove the space time dataset register table
+ """
+
+ connect = False
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ if self.is_in_db(dbif):
+
+ # First we unregister from all dependent space time datasets
+ self.unregister(dbif)
+
+ # Remove the strds register table
+ if self.get_stds_register():
+ sql = "DROP TABLE " + self.get_stds_register()
+ #print sql
+ try:
+ dbif.cursor.execute(sql)
+ except:
+ core.error("Unable to remove space time dataset register table " + self.get_stds_register())
+
+ core.verbose("Delete " + self.get_type() + " dataset <" + self.get_id() + "> from temporal database")
+
+ # Delete yourself from the database, trigger functions will take care of dependencies
+ self.base.delete(dbif)
+
+ self.reset(None)
+
+ if connect == True:
+ dbif.close()
+
+ def unregister(self, dbif=None):
+ """ Remove the map entry in each space time dataset in which this map is registered
+ """
+
+ core.verbose("Unregister " + self.get_type() + " dataset <" + self.get_id() + "> from space time datasets")
+
+ connect = False
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ # Get all datasets in which this map is registered
+ rows = self.get_registered_datasets(dbif)
+
+ # For each stds in which the map is registered
+ if rows:
+ for row in rows:
+ # Create a space time dataset object to remove the map
+ # from its register
+ stds = self.get_new_stds_instance(row["id"])
+ stds.select(dbif)
+ stds.unregister_map(self, dbif)
+ # Take care to update the space time dataset after
+ # the map has been unregistred
+ stds.update_from_registered_maps(dbif)
+
+ if connect == True:
+ dbif.close()
+
+ def get_registered_datasets(self, dbif=None):
+ """Return all space time dataset ids in which this map is registered as
+ sqlite3 rows with column "id" or None if this map is not registered in any
+ space time dataset.
+ """
+ connect = False
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ rows = None
+
+ try:
+ if self.get_stds_register() != None:
+ # Select all stds tables in which this map is registered
+ sql = "SELECT id FROM " + self.get_stds_register()
+ dbif.cursor.execute(sql)
+ rows = dbif.cursor.fetchall()
+ except:
+ core.error("Unable to select space time dataset register table " + self.get_stds_register())
+
+ if connect == True:
+ dbif.close()
+
+ return rows
+
+###############################################################################
+
+class abstract_space_time_dataset(abstract_dataset):
+ """Abstract space time dataset class
+
+ This class represents a space time dataset. Convenient functions
+ to select, update, insert or delete objects of this type int the SQL
+ temporal database exists as well as functions to register or unregister
+ raster maps.
+
+ Parts of the temporal logic are implemented in the SQL temporal database,
+ like the computation of the temporal and spatial extent as well as the
+ collecting of metadata.
+ """
+ def __init__(self, ident):
+ self.reset(ident)
+
+ def get_new_instance(self, ident):
+ """Return a new instance with the type of this class"""
+ raise IOError("This method must be implemented in the subclasses")
+
+ def get_new_map_instance(self, ident):
+ """Return a new instance of a map dataset which is associated with the type of this class"""
+ raise IOError("This method must be implemented in the subclasses")
+
+ def get_map_register(self):
+ """Return the name of the map register table"""
+ raise IOError("This method must be implemented in the subclasses")
+
+ def set_map_register(self, name):
+ """Set the name of the map register table"""
+ raise IOError("This method must be implemented in the subclasses")
+
+ def set_initial_values(self, granularity, temporal_type, semantic_type, \
+ title=None, description=None):
+
+ if temporal_type == "absolute":
+ self.set_time_to_absolute()
+ self.absolute_time.set_granularity(granularity)
+ elif temporal_type == "relative":
+ self.set_time_to_relative()
+ self.relative_time.set_granularity(granularity)
+ else:
+ core.fatal("Unknown temporal type \"" + temporal_type + "\"")
+
+ self.base.set_semantic_type(semantic_type)
+ self.metadata.set_title(title)
+ self.metadata.set_description(description)
+
+ def delete(self, dbif=None):
+ """Delete a space time dataset from the database"""
+ # First we need to check if maps are registered in this dataset and
+ # unregister them
+
+ core.verbose("Delete space time " + self.get_new_map_instance(ident=None).get_type() + " dataset <" + self.get_id() + "> from temporal database")
+
+ connect = False
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ if self.get_map_register():
+ sql = "SELECT id FROM " + self.get_map_register()
+ try:
+ dbif.cursor.execute(sql)
+ rows = dbif.cursor.fetchall()
+ # Unregister each registered map in the table
+ if rows:
+ for row in rows:
+ # Unregister map
+ map = self.get_new_map_instance(row["id"])
+ self.unregister_map(map, dbif)
+
+ # Drop remove the map register table
+ sql = "DROP TABLE " + self.get_map_register()
+ dbif.cursor.execute(sql)
+ except:
+ core.error("Unable to unregister maps from register table <" + self.get_map_register() + ">")
+ raise
+
+ # Remove the primary key, the foreign keys will be removed by trigger
+ self.base.delete(dbif)
+ self.reset(None)
+
+ if connect == True:
+ dbif.close()
+
+ def register_map(self, map, dbif=None):
+ """Register a map in the space time dataset.
+
+ This method takes care of the registration of a map
+ in a space time dataset.
+
+ In case the map is already registered this function will break with a warning
+ and return False
+ """
+
+ connect = False
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ if map.is_in_db(dbif) == False:
+ core.fatal("Only maps with absolute or relative valid time can be registered")
+
+ core.verbose("Register " + map.get_type() + " map: " + map.get_id() + " in space time " + map.get_type() + " dataset <" + self.get_id() + ">")
+
+ # First select all data from the database
+ map.select(dbif)
+ map_id = map.base.get_id()
+ map_name = map.base.get_name()
+ map_mapset = map.base.get_mapset()
+ map_register_table = map.get_stds_register()
+
+ #print "Map register table", map_register_table
+
+ # Get basic info
+ stds_name = self.base.get_name()
+ stds_mapset = self.base.get_mapset()
+ stds_register_table = self.get_map_register()
+
+ #print "STDS register table", stds_register_table
+
+ if stds_mapset != map_mapset:
+ core.fatal("Only maps from the same mapset can be registered")
+
+ # Check if map is already registred
+ if stds_register_table:
+ sql = "SELECT id FROM " + stds_register_table + " WHERE id = (?)"
+ dbif.cursor.execute(sql, (map_id,))
+ row = dbif.cursor.fetchone()
+ # In case of no entry make a new one
+ if row and row[0] == map_id:
+ core.warning("Map " + map_id + "is already registered.")
+ return False
+
+ # Create tables
+ sql_path = get_sql_template_path()
+
+ # We need to create the stmap raster register table bevor we can register the map
+ if map_register_table == None:
+ # Create a unique id
+ uuid_rand = "map_" + str(uuid.uuid4()).replace("-", "")
+
+ # Read the SQL template
+ sql = open(os.path.join(sql_path, "map_stds_register_table_template.sql"), 'r').read()
+ # Create the raster, raster3d and vector tables
+ sql = sql.replace("GRASS_MAP", map.get_type())
+ sql = sql.replace("MAP_NAME", map_name + "_" + map_mapset )
+ sql = sql.replace("TABLE_NAME", uuid_rand )
+ sql = sql.replace("MAP_ID", map_id)
+ sql = sql.replace("STDS", self.get_type())
+ try:
+ dbif.cursor.executescript(sql)
+ except:
+ core.error("Unable to create the space time " + map.get_type() +\
+ " dataset register table for " + map.get_type() + " map <" + map.get_id())
+ raise
+
+ map_register_table = uuid_rand + "_" + self.get_type() + "_register"
+ # 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 <" + map_register_table + "> for " + map.get_type() + " map <" + map.get_id() + ">")
+
+ # We need to create the table and register it
+ if stds_register_table == None:
+ # Read the SQL template
+ sql = open(os.path.join(sql_path, "stds_map_register_table_template.sql"), 'r').read()
+ # Create the raster, raster3d and vector tables
+ sql = sql.replace("GRASS_MAP", map.get_type())
+ sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
+ sql = sql.replace("SPACETIME_ID", self.base.get_id())
+ sql = sql.replace("STDS", self.get_type())
+
+ sql_script = ""
+ #sql_script += "BEGIN TRANSACTION;\n"
+ sql_script += sql
+ #sql_script += "\n"
+ #sql_script += "END TRANSACTION;"
+ try:
+ dbif.cursor.executescript(sql_script)
+ except:
+ core.error("Unable to create the " + map.get_type() +\
+ " map register table for space time " + map.get_type() + " dataset <" + map.get_id())
+ raise
+
+ # Trigger have been disabled due to peformance issues while registration
+ ## We need raster specific trigger
+ #sql = open(os.path.join(sql_path, "stds_" + map.get_type() + "_register_trigger_template.sql"), 'r').read()
+ #sql = sql.replace("GRASS_MAP", map.get_type())
+ #sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
+ #sql = sql.replace("SPACETIME_ID", self.base.get_id())
+ #sql = sql.replace("STDS", self.get_type())
+
+ #sql_script = ""
+ #sql_script += "BEGIN TRANSACTION;\n"
+ #sql_script += sql
+ #sql_script += "\n"
+ #sql_script += "END TRANSACTION;"
+
+ #dbif.cursor.executescript(sql_script)
+
+ stds_register_table = stds_name + "_" + stds_mapset + "_" + map.get_type() + "_register"
+
+ # Set the map register table name and put it into the DB
+ self.set_map_register(stds_register_table)
+ self.metadata.update(dbif)
+
+ core.verbose("Created register table <" + stds_register_table + "> for space time " + map.get_type() + " dataset <" + self.get_id() + ">")
+
+ # Register the stds in the map stds register table
+ # Check if the entry is already there
+ sql = "SELECT id FROM " + map_register_table + " WHERE id = ?"
+ dbif.cursor.execute(sql, (self.base.get_id(),))
+ row = dbif.cursor.fetchone()
+
+ # In case of no entry make a new one
+ if row == None:
+ sql = "INSERT INTO " + map_register_table + " (id) " + "VALUES (?)"
+ #print sql
+ dbif.cursor.execute(sql, (self.base.get_id(),))
+
+ # Now put the raster name in the stds map register table
+ sql = "INSERT INTO " + stds_register_table + " (id) " + "VALUES (?)"
+ #print sql
+ dbif.cursor.execute(sql, (map_id,))
+
+ if connect == True:
+ dbif.close()
+
+ return True
+
+ 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
+ from a space time dataset.
+ """
+ connect = False
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ if map.is_in_db(dbif) == False:
+ core.fatal("Unable to find map <" + map.get_id() + "> in temporal database")
+
+ core.info("Unregister " + map.get_type() + " map: " + map.get_id())
+
+ # First select all data from the database
+ map.select(dbif)
+ map_id = map.base.get_id()
+ map_register_table = map.get_stds_register()
+
+ # Get basic info
+ stds_register_table = self.get_map_register()
+
+ # Check if the map is registered in the space time raster dataset
+ sql = "SELECT id FROM " + map_register_table + " WHERE id = ?"
+ dbif.cursor.execute(sql, (self.base.get_id(),))
+ row = dbif.cursor.fetchone()
+
+ # Break if the map is not registered
+ if row == None:
+ core.warning("Map " + map_id + " is not registered in space time dataset " + self.base.get_id())
+ return False
+
+ # Remove the space time raster dataset from the raster dataset register
+ if map_register_table != None:
+ sql = "DELETE FROM " + map_register_table + " WHERE id = ?"
+ dbif.cursor.execute(sql, (self.base.get_id(),))
+
+ # Remove the raster map from the space time raster dataset register
+ if stds_register_table != None:
+ sql = "DELETE FROM " + stds_register_table + " WHERE id = ?"
+ dbif.cursor.execute(sql, (map_id,))
+
+ if connect == True:
+ dbif.close()
+
+ def update_from_registered_maps(self, dbif = None):
+ """This methods updates the spatial and temporal extent as well as
+ type specific metadata. It should always been called after maps are registered
+ or unregistered/deleted from the space time dataset.
+
+ An other solution to automate this is to use the diactivated trigger
+ in the SQL files. But this will result in a huge performance issue
+ in case many maps are registred (>1000).
+ """
+ core.info("Update metadata, spatial and temporal extent from all registered maps of <" + self.get_id() + ">")
+
+ connect = False
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ # Get basic info
+ stds_name = self.base.get_name()
+ stds_mapset = self.base.get_mapset()
+ sql_path = get_sql_template_path()
+
+ #We create a transaction
+ sql_script = ""
+ sql_script += "BEGIN TRANSACTION;\n"
+
+ # Update the spatial and temporal extent from registered maps
+ # Read the SQL template
+ sql = open(os.path.join(sql_path, "update_stds_spatial_temporal_extent_template.sql"), 'r').read()
+ sql = sql.replace("GRASS_MAP", self.get_new_map_instance(None).get_type())
+ sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
+ sql = sql.replace("SPACETIME_ID", self.base.get_id())
+ sql = sql.replace("STDS", self.get_type())
+
+ sql_script += sql
+ sql_script += "\n"
+
+ # Update type specific metadata
+ sql = open(os.path.join(sql_path, "update_" + self.get_type() + "_metadata_template.sql"), 'r').read()
+ sql = sql.replace("GRASS_MAP", self.get_new_map_instance(None).get_type())
+ sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
+ sql = sql.replace("SPACETIME_ID", self.base.get_id())
+ sql = sql.replace("STDS", self.get_type())
+
+ sql_script += sql
+ sql_script += "\n"
+
+ sql_script += "END TRANSACTION;"
+
+ dbif.cursor.executescript(sql_script)
+
+ if connect == True:
+ dbif.close()
Added: grass/trunk/lib/python/temporal/base.py
===================================================================
--- grass/trunk/lib/python/temporal/base.py (rev 0)
+++ grass/trunk/lib/python/temporal/base.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,477 @@
+"""!@package grass.script.tgis_base
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+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
+and the sqlite3 database interface.
+
+Usage:
+
+ at code
+from grass.script import tgis_core as grass
+
+rbase = grass.raster_base(ident="soil")
+...
+ at endcode
+
+(C) 2008-2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+
+from core import *
+
+###############################################################################
+
+class dict_sql_serializer(object):
+ def __init__(self):
+ 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
+
+ @type must be SELECT. INSERT, UPDATE
+ @table The name of the table to select, insert or update
+ @where The optinal where statment
+ @return the sql string
+ """
+
+ sql = ""
+ args = []
+
+ # Create ordered select statement
+ if type == "SELECT":
+ sql += 'SELECT '
+ count = 0
+ for key in self.D.keys():
+ if count == 0:
+ sql += ' %s ' % key
+ else:
+ sql += ' , %s ' % key
+ count += 1
+ sql += ' FROM ' + table + ' '
+ if where:
+ sql += where
+
+ # Create insert statement
+ if type =="INSERT":
+ count = 0
+ sql += 'INSERT INTO ' + table + ' ('
+ for key in self.D.keys():
+ if count == 0:
+ sql += ' %s ' % key
+ else:
+ sql += ' ,%s ' % key
+ count += 1
+
+ count = 0
+ sql += ') VALUES ('
+ for key in self.D.keys():
+ if count == 0:
+ sql += '?'
+ else:
+ sql += ',?'
+ count += 1
+ args.append(self.D[key])
+ sql += ') '
+
+ if where:
+ sql += where
+
+ # Create update statement
+ if type =="UPDATE":
+ count = 0
+ sql += 'UPDATE ' + table + ' SET '
+ for key in self.D.keys():
+ # Update only entries which are not None
+ if self.D[key] != None:
+ if count == 0:
+ sql += ' %s = ? ' % key
+ else:
+ sql += ' ,%s = ? ' % key
+ count += 1
+ args.append(self.D[key])
+ if where:
+ sql += where
+
+ return sql, tuple(args)
+
+ def deserialize(self, row):
+ """Convert the content of the sqlite row into the internal dictionary"""
+ self.D = {}
+ for key in row.keys():
+ self.D[key] = row[key]
+
+ def clear(self):
+ """Remove all the content of this class"""
+ self.D = {}
+
+ def print_self(self):
+ print self.D
+
+ def test(self):
+ t = dict_sql_serializer()
+ t.D["id"] = "soil at PERMANENT"
+ t.D["name"] = "soil"
+ t.D["mapset"] = "PERMANENT"
+ t.D["creator"] = "soeren"
+ t.D["creation_time"] = datetime.now()
+ t.D["modification_time"] = datetime.now()
+ t.D["revision"] = 1
+ sql, values = t.serialize(type="SELECT", table="raster_base")
+ print sql, '\n', values
+ sql, values = t.serialize(type="INSERT", table="raster_base")
+ print sql, '\n', values
+ sql, values = t.serialize(type="UPDATE", table="raster_base")
+ print sql, '\n', values
+
+###############################################################################
+
+class sql_database_interface(dict_sql_serializer):
+ """This is the sql database interface to sqlite3"""
+ def __init__(self, table=None, ident=None, database=None):
+ dict_sql_serializer.__init__(self)
+
+ self.table = table # Name of the table, set in the subclass
+ if database == None:
+ self.database = get_grass_location_db_path()
+ else:
+ self.database = database
+ self.ident = ident
+
+ def get_table_name(self):
+ return self.table
+
+ def connect(self):
+ #print "Connect to", self.database
+ self.connection = sqlite3.connect(self.database, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
+ self.connection.row_factory = sqlite3.Row
+ self.cursor = self.connection.cursor()
+
+ def close(self):
+ #print "Close connection to", self.database
+ self.connection.commit()
+ self.cursor.close()
+
+ def get_delete_statement(self):
+ return "DELETE FROM " + self.get_table_name() + " WHERE id = \"" + str(self.ident) + "\""
+
+ def delete(self, dbif=None):
+ sql = self.get_delete_statement()
+ #print sql
+
+ if dbif:
+ dbif.cursor.execute(sql)
+ else:
+ self.connect()
+ self.cursor.execute(sql)
+ self.close()
+
+ def get_is_in_db_statement(self):
+ return "SELECT id FROM " + self.get_table_name() + " WHERE id = \"" + str(self.ident) + "\""
+
+ def is_in_db(self, dbif=None):
+
+ sql = self.get_is_in_db_statement()
+ #print sql
+
+ if dbif:
+ dbif.cursor.execute(sql)
+ row = dbif.cursor.fetchone()
+ else:
+ self.connect()
+ self.cursor.execute(sql)
+ row = self.cursor.fetchone()
+ self.close()
+
+ # Nothing found
+ if row == None:
+ return False
+
+ return True
+
+ def get_select_statement(self):
+ return self.serialize("SELECT", self.get_table_name(), "WHERE id = \"" + str(self.ident) + "\"")
+
+ def select(self, dbif=None):
+ sql, args = self.get_select_statement()
+ #print sql
+ #print args
+
+ if dbif:
+ if len(args) == 0:
+ dbif.cursor.execute(sql)
+ else:
+ dbif.cursor.execute(sql, args)
+ row = dbif.cursor.fetchone()
+ else:
+ self.connect()
+ if len(args) == 0:
+ self.cursor.execute(sql)
+ else:
+ self.cursor.execute(sql, args)
+ row = self.cursor.fetchone()
+ self.close()
+
+ # Nothing found
+ if row == None:
+ return False
+
+ if len(row) > 0:
+ self.deserialize(row)
+ else:
+ raise IOError
+
+ return True
+
+ def get_insert_statement(self):
+ return self.serialize("INSERT", self.get_table_name())
+
+ def insert(self, dbif=None):
+ sql, args = self.get_insert_statement()
+ #print sql
+ #print args
+
+ if dbif:
+ dbif.cursor.execute(sql, args)
+ else:
+ self.connect()
+ self.cursor.execute(sql, args)
+ self.close()
+
+ def get_update_statement(self):
+ return self.serialize("UPDATE", self.get_table_name(), "WHERE id = \"" + str(self.ident) + "\"")
+
+ def update(self, dbif=None):
+ if self.ident == None:
+ raise IOError("Missing identifer");
+
+ sql, args = self.get_update_statement()
+ #print sql
+ #print args
+
+ if dbif:
+ dbif.cursor.execute(sql, args)
+ else:
+ self.connect()
+ self.cursor.execute(sql, args)
+ self.close()
+
+###############################################################################
+
+class dataset_base(sql_database_interface):
+ """This is the base class for all maps and spacetime datasets storing basic information"""
+ def __init__(self, table=None, ident=None, name=None, mapset=None, creator=None, ctime=None,\
+ mtime=None, ttype=None, revision=1):
+
+ sql_database_interface.__init__(self, table, ident)
+
+ self.set_id(ident)
+ self.set_name(name)
+ self.set_mapset(mapset)
+ self.set_creator(creator)
+ self.set_ctime(ctime)
+ self.set_mtime(mtime)
+ self.set_ttype(ttype)
+ self.set_revision(revision)
+
+ def set_id(self, ident):
+ """Convenient method to set the unique identifier (primary key)"""
+ self.ident = ident
+ self.D["id"] = ident
+
+ def set_name(self, name):
+ """Set the name of the map"""
+ self.D["name"] = name
+
+ def set_mapset(self, mapset):
+ """Set the mapset of the map"""
+ self.D["mapset"] = mapset
+
+ def set_creator(self, creator):
+ """Set the creator of the map"""
+ self.D["creator"] = creator
+
+ def set_ctime(self, ctime=None):
+ """Set the creation time of the map, if nothing set the current time is used"""
+ if ctime == None:
+ self.D["creation_time"] = datetime.now()
+ else:
+ self.D["creation_time"] = ctime
+
+ def set_mtime(self, mtime=None):
+ """Set the modification time of the map, if nothing set the current time is used"""
+ if mtime == None:
+ self.D["modification_time"] = datetime.now()
+ else:
+ self.D["modification_time"] = mtime
+
+ def set_ttype(self, ttype):
+ """Set the temporal type of the map: absolute or relative, if nothing set absolute time will assumed"""
+ if ttype == None or (ttype != "absolute" and ttype != "relative"):
+ self.D["temporal_type"] = "absolute"
+ else:
+ self.D["temporal_type"] = ttype
+
+ def set_revision(self, revision=1):
+ """Set the revision of the map: if nothing set revision 1 will assumed"""
+ self.D["revision"] = revision
+
+ def get_id(self):
+ """Convenient method to get the unique identifier (primary key)
+ @return None if not found
+ """
+ if self.D.has_key("id"):
+ return self.D["id"]
+ else:
+ return None
+
+ def get_name(self):
+ """Get the name of the map
+ @return None if not found"""
+ if self.D.has_key("name"):
+ return self.D["name"]
+ else:
+ return None
+
+ def get_mapset(self):
+ """Get the mapset of the map
+ @return None if not found"""
+ if self.D.has_key("mapset"):
+ return self.D["mapset"]
+ else:
+ return None
+
+ def get_creator(self):
+ """Get the creator of the map
+ @return None if not found"""
+ if self.D.has_key("creator"):
+ return self.D["creator"]
+ else:
+ return None
+
+ def get_ctime(self):
+ """Get the creation time of the map, datatype is datetime
+ @return None if not found"""
+ if self.D.has_key("creation_time"):
+ return self.D["creation_time"]
+ else:
+ return None
+
+ def get_mtime(self):
+ """Get the modification time of the map, datatype is datetime
+ @return None if not found"""
+ if self.D.has_key("modification_time"):
+ return self.D["modification_time"]
+ else:
+ return None
+
+ def get_ttype(self):
+ """Get the temporal type of the map
+ @return None if not found"""
+ if self.D.has_key("temporal_type"):
+ return self.D["temporal_type"]
+ else:
+ return None
+
+ def get_revision(self):
+ """Get the revision of the map
+ @return None if not found"""
+ if self.D.has_key("revision"):
+ return self.D["revision"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ # 0123456789012345678901234567890
+ print " +-------------------- Basic information -------------------------------------+"
+ print " | Id: ........................ " + str(self.get_id())
+ print " | Name: ...................... " + str(self.get_name())
+ print " | Mapset: .................... " + str(self.get_mapset())
+ print " | Creator: ................... " + str(self.get_creator())
+ print " | Creation time: ............. " + str(self.get_ctime())
+ print " | Modification time: ......... " + str(self.get_mtime())
+ print " | Temporal type: ............. " + str(self.get_ttype())
+ print " | Revision in database: ...... " + str(self.get_revision())
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ print "id=" + str(self.get_id())
+ print "name=" + str(self.get_name())
+ print "mapset=" + str(self.get_mapset())
+ print "creator=" + str(self.get_creator())
+ print "creation_time=" + str(self.get_ctime())
+ print "modification_time=" + str(self.get_mtime())
+ print "temporal_type=" + str(self.get_ttype())
+ print "revision=" + str(self.get_revision())
+
+###############################################################################
+
+class raster_base(dataset_base):
+ def __init__(self, ident=None, name=None, mapset=None, creator=None, creation_time=None,\
+ modification_time=None, temporal_type=None, revision=1):
+ dataset_base.__init__(self, "raster_base", ident, name, mapset, creator, creation_time,\
+ modification_time, temporal_type, revision)
+
+class raster3d_base(dataset_base):
+ def __init__(self, ident=None, name=None, mapset=None, creator=None, creation_time=None,\
+ modification_time=None, temporal_type=None, revision=1):
+ dataset_base.__init__(self, "raster3d_base", ident, name, mapset, creator, creation_time,\
+ modification_time, temporal_type, revision)
+
+class vector_base(dataset_base):
+ def __init__(self, ident=None, name=None, mapset=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)
+
+###############################################################################
+
+class stds_base(dataset_base):
+ def __init__(self, table=None, ident=None, name=None, mapset=None, semantic_type=None, creator=None, creation_time=None,\
+ modification_time=None, temporal_type=None, revision=1):
+ dataset_base.__init__(self, table, ident, name, mapset, creator, creation_time,\
+ modification_time, temporal_type, revision)
+
+ self.set_semantic_type(semantic_type)
+
+ def set_semantic_type(self, semantic_type):
+ """Set the semantic type of the space time dataset"""
+ self.D["semantic_type"] = semantic_type
+
+ def get_semantic_type(self):
+ """Get the semantic type of the space time dataset
+ @return None if not found"""
+ if self.D.has_key("semantic_type"):
+ return self.D["semantic_type"]
+ else:
+ return None
+
+###############################################################################
+
+class strds_base(stds_base):
+ def __init__(self, ident=None, name=None, mapset=None, semantic_type=None, creator=None, creation_time=None,\
+ modification_time=None, temporal_type=None, revision=1):
+ stds_base.__init__(self, "strds_base", ident, name, mapset, semantic_type, creator, creation_time,\
+ modification_time, temporal_type, revision)
+
+class str3ds_base(stds_base):
+ def __init__(self, ident=None, name=None, mapset=None, semantic_type=None, creator=None, creation_time=None,\
+ modification_time=None, temporal_type=None, revision=1):
+ stds_base.__init__(self, "str3ds_base", ident, name, mapset, semantic_type, creator, creation_time,\
+ modification_time, temporal_type, revision)
+
+class stvds_base(stds_base):
+ def __init__(self, ident=None, name=None, mapset=None, semantic_type=None, creator=None, creation_time=None,\
+ modification_time=None, temporal_type=None, revision=1):
+ stds_base.__init__(self, "stvds_base", ident, name, mapset, semantic_type, creator, creation_time,\
+ modification_time, temporal_type, revision)
+
Added: grass/trunk/lib/python/temporal/core.py
===================================================================
--- grass/trunk/lib/python/temporal/core.py (rev 0)
+++ grass/trunk/lib/python/temporal/core.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,216 @@
+"""!@package grass.script.tgis_core
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS core functions to be used in Python sripts.
+
+Usage:
+
+ at code
+from grass.script import tgis_core as grass
+
+grass.create_temporal_database()
+...
+ at endcode
+
+(C) 2008-2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+import os
+import sqlite3
+import grass.script.core as core
+import copy
+from datetime import datetime, date, time, timedelta
+
+###############################################################################
+
+def get_grass_location_db_path():
+ grassenv = core.gisenv()
+ dbpath = os.path.join(grassenv["GISDBASE"], grassenv["LOCATION_NAME"])
+ return os.path.join(dbpath, "grass.db")
+
+###############################################################################
+
+def get_sql_template_path():
+ base = os.getenv("GISBASE")
+ base_etc = os.path.join(base, "etc")
+ return os.path.join(base_etc, "sql")
+
+def test_increment_datetime_by_string():
+
+ dt = datetime(2001, 9, 1, 0, 0, 0)
+ string = "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
+
+ dt1 = datetime(2003,2,18,12,5,0)
+ dt2 = increment_datetime_by_string(dt, string)
+
+ delta = dt1 -dt2
+
+ if delta.days != 0 or delta.seconds != 0:
+ core.fatal("increment computation is wrong")
+
+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.
+
+ @mydate A datetime object to incremented
+ @increment A string providing increment information:
+ The string may include comma separated values of type seconds, minutes, hours, days, weeks, months and years
+ Example: Increment the datetime 2001-01-01 00:00:00 with "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
+ will result in the datetime 2003-02-18 12:05:00
+ @mult A multiplier, default is 1
+ """
+
+ if increment:
+
+ seconds = 0
+ minutes = 0
+ hours = 0
+ days = 0
+ weeks = 0
+ months = 0
+ years = 0
+
+ inclist = []
+ # Split the increment string
+ incparts = increment.split(",")
+ for incpart in incparts:
+ inclist.append(incpart.strip().split(" "))
+
+ for inc in inclist:
+ if inc[1].find("seconds") >= 0:
+ seconds = mult * int(inc[0])
+ elif inc[1].find("minutes") >= 0:
+ minutes = mult * int(inc[0])
+ elif inc[1].find("hours") >= 0:
+ hours = mult * int(inc[0])
+ elif inc[1].find("days") >= 0:
+ days = mult * int(inc[0])
+ elif inc[1].find("weeks") >= 0:
+ weeks = mult * int(inc[0])
+ elif inc[1].find("months") >= 0:
+ months = mult * int(inc[0])
+ elif inc[1].find("years") >= 0:
+ years = mult * int(inc[0])
+ else:
+ core.fatal("Wrong increment format: " + increment)
+
+ return increment_datetime(mydate, years, months, weeks, days, hours, minutes, seconds)
+
+ return mydate
+
+###############################################################################
+
+def increment_datetime(mydate, years=0, months=0, weeks=0, days=0, hours=0, minutes=0, seconds=0):
+ """Return a new datetime object incremented with the provided relative dates and times"""
+
+ tdelta_seconds = timedelta(seconds=seconds)
+ tdelta_minutes = timedelta(minutes=minutes)
+ tdelta_hours = timedelta(hours=hours)
+ tdelta_days = timedelta(days=days)
+ tdelta_weeks = timedelta(weeks=weeks)
+ tdelta_months = timedelta(0)
+ tdelta_years = timedelta(0)
+
+ if months > 0:
+ # Compute the actual number of days in the month to add as timedelta
+ year = mydate.year
+ month = mydate.month
+
+ all_months = int(months + month)
+
+ years_to_add = int(all_months/12)
+ residual_months = all_months%12
+
+ # Make a deep copy of the datetime object
+ dt1 = copy.copy(mydate)
+
+ # Make sure the montha starts with a 1
+ if residual_months == 0:
+ residual_months = 1
+
+ dt1 = dt1.replace(year = year + years_to_add, month = residual_months)
+ tdelta_months = dt1 - mydate
+
+ if years > 0:
+ # Make a deep copy of the datetime object
+ dt1 = copy.copy(mydate)
+ # Compute the number of days
+ dt1 = dt1.replace(year=mydate.year + int(years))
+ tdelta_years = dt1 - mydate
+
+ return mydate + tdelta_seconds + tdelta_minutes + tdelta_hours + \
+ tdelta_days + tdelta_weeks + tdelta_months + tdelta_years
+
+###############################################################################
+
+def create_temporal_database():
+ """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"""
+
+ database = get_grass_location_db_path()
+
+ # Check if it already exists
+ if os.path.exists(database):
+ return False
+
+ # Read all SQL scripts and templates
+ map_tables_template_sql = open(os.path.join(get_sql_template_path(), "map_tables_template.sql"), 'r').read()
+ raster_metadata_sql = open(os.path.join(get_sql_template_path(), "raster_metadata_table.sql"), 'r').read()
+ raster3d_metadata_sql = open(os.path.join(get_sql_template_path(), "raster3d_metadata_table.sql"), 'r').read()
+ vector_metadata_sql = open(os.path.join(get_sql_template_path(), "vector_metadata_table.sql"), 'r').read()
+ stds_tables_template_sql = open(os.path.join(get_sql_template_path(), "stds_tables_template.sql"), 'r').read()
+ strds_metadata_sql = open(os.path.join(get_sql_template_path(), "strds_metadata_table.sql"), 'r').read()
+ str3ds_metadata_sql = open(os.path.join(get_sql_template_path(), "str3ds_metadata_table.sql"), 'r').read()
+ stvds_metadata_sql = open(os.path.join(get_sql_template_path(), "stvds_metadata_table.sql"), 'r').read()
+
+ # Create the raster, raster3d and vector tables
+ raster_tables_sql = map_tables_template_sql.replace("GRASS_MAP", "raster")
+ vector_tables_sql = map_tables_template_sql.replace("GRASS_MAP", "vector")
+ raster3d_tables_sql = map_tables_template_sql.replace("GRASS_MAP", "raster3d")
+
+ # Create the space-time raster, raster3d and vector dataset tables
+ strds_tables_sql = stds_tables_template_sql.replace("STDS", "strds")
+ stvds_tables_sql = stds_tables_template_sql.replace("STDS", "stvds")
+ str3ds_tables_sql = stds_tables_template_sql.replace("STDS", "str3ds")
+
+ # Check for completion
+ sqlite3.complete_statement(raster_tables_sql)
+ sqlite3.complete_statement(vector_tables_sql)
+ sqlite3.complete_statement(raster3d_tables_sql)
+ sqlite3.complete_statement(raster_metadata_sql)
+ sqlite3.complete_statement(vector_metadata_sql)
+ sqlite3.complete_statement(raster3d_metadata_sql)
+ sqlite3.complete_statement(strds_tables_sql)
+ sqlite3.complete_statement(stvds_tables_sql)
+ sqlite3.complete_statement(str3ds_tables_sql)
+ sqlite3.complete_statement(strds_metadata_sql)
+ sqlite3.complete_statement(stvds_metadata_sql)
+ sqlite3.complete_statement(str3ds_metadata_sql)
+
+ # Connect to database
+ connection = sqlite3.connect(database)
+ cursor = connection.cursor()
+
+ # Execute the SQL statements
+ # Create the global tables for the native grass datatypes
+ cursor.executescript(raster_tables_sql)
+ cursor.executescript(raster_metadata_sql)
+ cursor.executescript(vector_tables_sql)
+ cursor.executescript(vector_metadata_sql)
+ cursor.executescript(raster3d_tables_sql)
+ cursor.executescript(raster3d_metadata_sql)
+ # Create the tables for the new space-time datatypes
+ cursor.executescript(strds_tables_sql)
+ cursor.executescript(strds_metadata_sql)
+ cursor.executescript(stvds_tables_sql)
+ cursor.executescript(stvds_metadata_sql)
+ cursor.executescript(str3ds_tables_sql)
+ cursor.executescript(str3ds_metadata_sql)
+
+ connection.commit()
+ cursor.close()
Added: grass/trunk/lib/python/temporal/metadata.py
===================================================================
--- grass/trunk/lib/python/temporal/metadata.py (rev 0)
+++ grass/trunk/lib/python/temporal/metadata.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,640 @@
+"""!@package grass.script.tgis_metadata
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related metadata functions to be used in Python scripts and tgis packages.
+
+Usage:
+
+ at code
+from grass.script import tgis_metadata as grass
+
+meta = grass.raster_metadata()
+...
+ at endcode
+
+(C) 2008-2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+from base import *
+
+###############################################################################
+
+class raster_metadata_base(sql_database_interface):
+ """This is the raster metadata base class for raster and raster3d maps"""
+ def __init__(self, table=None, ident=None, datatype=None, cols=None, rows=None, number_of_cells=None, nsres=None, ewres=None, min=None, max=None):
+
+ sql_database_interface.__init__(self, table, ident)
+
+ self.set_id(ident)
+ self.set_datatype(datatype)
+ self.set_cols(cols)
+ self.set_rows(rows)
+ self.set_number_of_cells(number_of_cells)
+ self.set_nsres(nsres)
+ self.set_ewres(ewres)
+ self.set_min(min)
+ self.set_max(max)
+
+ def set_id(self, ident):
+ """Convenient method to set the unique identifier (primary key)"""
+ self.ident = ident
+ self.D["id"] = ident
+
+ def set_datatype(self, datatype):
+ """Set the datatype"""
+ self.D["datatype"] = datatype
+
+ def set_cols(self, cols):
+ """Set the number of cols"""
+ self.D["cols"] = cols
+
+ def set_rows(self, rows):
+ """Set the number of rows"""
+ self.D["rows"] = rows
+
+ def set_number_of_cells(self, number_of_cells):
+ """Set the number of cells"""
+ self.D["number_of_cells"] = number_of_cells
+
+ def set_nsres(self, nsres):
+ """Set the north-south resolution"""
+ self.D["nsres"] = nsres
+
+ def set_ewres(self, ewres):
+ """Set the east-west resolution"""
+ self.D["ewres"] = ewres
+
+ def set_min(self, min):
+ """Set the minimum raster value"""
+ self.D["min"] = min
+
+ def set_max(self, max):
+ """Set the maximum raster value"""
+ self.D["max"] = max
+
+ def get_id(self):
+ """Convenient method to get the unique identifier (primary key)
+ @return None if not found
+ """
+ if self.D.has_key("id"):
+ return self.D["id"]
+ else:
+ return None
+
+ def get_datatype(self):
+ """Get the map type
+ @return None if not found"""
+ if self.D.has_key("datatype"):
+ return self.D["datatype"]
+ else:
+ return None
+
+ def get_cols(self):
+ """Get number of cols
+ @return None if not found"""
+ if self.D.has_key("cols"):
+ return self.D["cols"]
+ else:
+ return None
+
+ def get_rows(self):
+ """Get number of rows
+ @return None if not found"""
+ if self.D.has_key("rows"):
+ return self.D["rows"]
+ else:
+ return None
+
+ def get_number_of_cells(self):
+ """Get number of cells
+ @return None if not found"""
+ if self.D.has_key("number_of_cells"):
+ return self.D["number_of_cells"]
+ else:
+ return None
+
+ def get_nsres(self):
+ """Get the north-south resolution
+ @return None if not found"""
+ if self.D.has_key("nsres"):
+ return self.D["nsres"]
+ else:
+ return None
+
+ def get_ewres(self):
+ """Get east-west resolution
+ @return None if not found"""
+ if self.D.has_key("ewres"):
+ return self.D["ewres"]
+ else:
+ return None
+
+ def get_min(self):
+ """Get the minimum cell value
+ @return None if not found"""
+ if self.D.has_key("min"):
+ return self.D["min"]
+ else:
+ return None
+
+ def get_max(self):
+ """Get the maximum cell value
+ @return None if not found"""
+ if self.D.has_key("max"):
+ return self.D["max"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ # 0123456789012345678901234567890
+ print " | Datatype:................... " + str(self.get_datatype())
+ print " | Number of columns:.......... " + str(self.get_cols())
+ print " | Number of rows:............. " + str(self.get_rows())
+ print " | Number of cells:............ " + str(self.get_number_of_cells())
+ print " | North-South resolution:..... " + str(self.get_nsres())
+ print " | East-west resolution:....... " + str(self.get_ewres())
+ print " | Minimum value:.............. " + str(self.get_min())
+ print " | Maximum value:.............. " + str(self.get_max())
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ print "datatype=" + str(self.get_datatype())
+ print "cols=" + str(self.get_cols())
+ print "rows=" + str(self.get_rows())
+ print "number_of_cells=" + str(self.get_number_of_cells())
+ print "nsres=" + str(self.get_nsres())
+ print "ewres=" + str(self.get_ewres())
+ print "min=" + str(self.get_min())
+ print "max=" + str(self.get_max())
+
+###############################################################################
+
+class raster_metadata(raster_metadata_base):
+ """This is the raster metadata class"""
+ def __init__(self, ident=None, strds_register=None, datatype=None, cols=None, rows=None, number_of_cells=None, nsres=None, ewres=None, min=None, max=None):
+
+ raster_metadata_base.__init__(self, "raster_metadata", ident, datatype, cols, rows, number_of_cells, nsres, ewres, min, max)
+
+ self.set_strds_register(strds_register)
+
+ def set_strds_register(self, strds_register):
+ """Set the space time raster dataset register table name"""
+ self.D["strds_register"] = strds_register
+
+ def get_strds_register(self):
+ """Get the space time raster dataset register table name
+ @return None if not found"""
+ if self.D.has_key("strds_register"):
+ return self.D["strds_register"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ print " +-------------------- Metadata information ----------------------------------+"
+ # 0123456789012345678901234567890
+ print " | STRDS register table ....... " + str(self.get_strds_register())
+ raster_metadata_base.print_info(self)
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ raster_metadata_base.print_shell_info(self)
+
+###############################################################################
+
+class raster3d_metadata(raster_metadata_base):
+ """This is the raster3d metadata class"""
+ def __init__(self, ident=None, str3ds_register=None, datatype=None, cols=None, rows=None, depths=None, number_of_cells=None, nsres=None, ewres=None, tbres=None, min=None, max=None):
+
+ raster_metadata_base.__init__(self, "raster3d_metadata", ident, datatype, cols, rows, number_of_cells, nsres, ewres, min, max)
+
+ self.set_str3ds_register(str3ds_register)
+ self.set_tbres(tbres)
+ self.set_depths(depths)
+
+ def set_str3ds_register(self, str3ds_register):
+ """Set the space time raster3d dataset register table name"""
+ self.D["str3ds_register"] = str3ds_register
+
+ def set_depths(self, depths):
+ """Set the number of depths"""
+ self.D["depths"] = depths
+
+ def set_tbres(self, tbres):
+ """Set the top-bottom resolution"""
+ self.D["tbres"] = tbres
+
+ def get_str3ds_register(self):
+ """Get the space time raster3d dataset register table name
+ @return None if not found"""
+ if self.D.has_key("str3ds_register"):
+ return self.D["str3ds_register"]
+ else:
+ return None
+
+ def get_depths(self):
+ """Get number of depths
+ @return None if not found"""
+ if self.D.has_key("depths"):
+ return self.D["depths"]
+ else:
+ return None
+
+ def get_tbres(self):
+ """Get top-bottom resolution
+ @return None if not found"""
+ if self.D.has_key("tbres"):
+ return self.D["tbres"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ print " +-------------------- Metadata information ----------------------------------+"
+ # 0123456789012345678901234567890
+ print " | STR3DS register table ...... " + str(self.get_str3ds_register())
+ raster_metadata_base.print_info(self)
+ # 0123456789012345678901234567890
+ print " | Number of depths:........... " + str(self.get_depths())
+ print " | Top-Bottom resolution:...... " + str(self.get_tbres())
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ raster_metadata_base.print_shell_info(self)
+ print "depths=" + str(self.get_depths())
+ print "tbres=" + str(self.get_tbres())
+
+###############################################################################
+
+class vector_metadata(sql_database_interface):
+ """This is the vector metadata class"""
+ def __init__(self, ident=None, stvds_register=None):
+
+ sql_database_interface.__init__(self, "vector_metadata", ident)
+
+ self.set_id(ident)
+ self.set_stvds_register(stvds_register)
+
+ def set_id(self, ident):
+ """Convenient method to set the unique identifier (primary key)"""
+ self.ident = ident
+ self.D["id"] = ident
+
+ def set_stvds_register(self, stvds_register):
+ """Set the space time vector dataset register table name"""
+ self.D["stvds_register"] = stvds_register
+
+ def get_id(self):
+ """Convenient method to get the unique identifier (primary key)
+ @return None if not found
+ """
+ if self.D.has_key("id"):
+ return self.D["id"]
+ else:
+ return None
+
+ def get_stvds_register(self):
+ """Get the space time vector dataset register table name
+ @return None if not found"""
+ if self.D.has_key("stvds_register"):
+ return self.D["stvds_register"]
+ else:
+ return None
+
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ # 0123456789012345678901234567890
+ print " +-------------------- Metadata information ----------------------------------+"
+ print " | STVDS register table ....... " + str(self.get_stvds_register())
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ print "stvds_register=" + str(self.get_stvds_register())
+
+###############################################################################
+
+class stds_metadata_base(sql_database_interface):
+ """This is the space time dataset metadata base class for strds, stvds and str3ds datasets
+ setting/getting the id, the title and the description
+ """
+ def __init__(self, table=None, ident=None, title=None, description=None):
+
+ sql_database_interface.__init__(self, table, ident)
+
+ self.set_id(ident)
+ self.set_title(title)
+ self.set_description(description)
+ # No setter for this
+ self.D["number_of_maps"] = None
+
+ def set_id(self, ident):
+ """Convenient method to set the unique identifier (primary key)"""
+ self.ident = ident
+ self.D["id"] = ident
+
+ def set_title(self, title):
+ """Set the title"""
+ self.D["title"] = title
+
+ def set_description(self, description):
+ """Set the number of cols"""
+ self.D["description"] = description
+
+ def get_id(self):
+ """Convenient method to get the unique identifier (primary key)
+ @return None if not found
+ """
+ if self.D.has_key("id"):
+ return self.D["id"]
+ else:
+ return None
+
+ def get_title(self):
+ """Get the title
+ @return None if not found"""
+ if self.D.has_key("title"):
+ return self.D["title"]
+ else:
+ return None
+
+ def get_description(self):
+ """Get description
+ @return None if not found"""
+ if self.D.has_key("description"):
+ return self.D["description"]
+ else:
+ return None
+
+ def get_number_of_maps(self):
+ """Get the number of registered maps, this value is set in the database
+ automatically via SQL trigger, so no setter exists
+ @return None if not found"""
+ if self.D.has_key("number_of_maps"):
+ return self.D["number_of_maps"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ # 0123456789012345678901234567890
+ print " | Number of registered maps:.. " + str(self.get_number_of_maps())
+ print " | Title:"
+ print " | " + str(self.get_title())
+ print " | Description:"
+ print " | " + str(self.get_description())
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ print "number_of_maps=" + str(self.get_number_of_maps())
+
+###############################################################################
+
+class stds_raster_metadata_base(stds_metadata_base):
+ """This is the space time dataset metadata base class for strds and str3ds datasets
+
+ Most of the metadata values are set by triggers in the database when
+ new raster of voxel maps are added. Therefor only some set- an many get-functions
+ are available.
+ """
+ def __init__(self, table=None, ident=None, title=None, description=None):
+
+ stds_metadata_base.__init__(self, table, ident, title, description)
+
+ # Initialize the dict to select all values from the db
+ self.D["min_max"] = None
+ self.D["max_max"] = None
+ self.D["min_min"] = None
+ self.D["max_min"] = None
+ self.D["nsres_min"] = None
+ self.D["nsres_max"] = None
+ self.D["ewres_min"] = None
+ self.D["ewres_max"] = None
+
+ def get_max_min(self):
+ """Get the minimal maximum of all registered maps, this value is set in the database
+ automatically via SQL trigger, so no setter exists
+ @return None if not found"""
+ if self.D.has_key("max_min"):
+ return self.D["max_min"]
+ else:
+ return None
+
+ def get_min_min(self):
+ """Get the minimal minimum of all registered maps, this value is set in the database
+ automatically via SQL trigger, so no setter exists
+ @return None if not found"""
+ if self.D.has_key("min_min"):
+ return self.D["min_min"]
+ else:
+ return None
+
+ def get_max_max(self):
+ """Get the maximal maximum of all registered maps, this value is set in the database
+ automatically via SQL trigger, so no setter exists
+ @return None if not found"""
+ if self.D.has_key("max_max"):
+ return self.D["max_max"]
+ else:
+ return None
+
+ def get_min_max(self):
+ """Get the maximal minimum of all registered maps, this value is set in the database
+ automatically via SQL trigger, so no setter exists
+ @return None if not found"""
+ if self.D.has_key("min_max"):
+ return self.D["min_max"]
+ else:
+ return None
+
+ def get_nsres_min(self):
+ """Get the minimal north-south resolution of all registered maps, this value is set in the database
+ automatically via SQL trigger, so no setter exists
+ @return None if not found"""
+ if self.D.has_key("nsres_min"):
+ return self.D["nsres_min"]
+ else:
+ return None
+
+ def get_nsres_max(self):
+ """Get the maximal north-south resolution of all registered maps, this value is set in the database
+ automatically via SQL trigger, so no setter exists
+ @return None if not found"""
+ if self.D.has_key("nsres_max"):
+ return self.D["nsres_max"]
+ else:
+ return None
+
+ def get_ewres_min(self):
+ """Get the minimal east-west resolution of all registered maps, this value is set in the database
+ automatically via SQL trigger, so no setter exists
+ @return None if not found"""
+ if self.D.has_key("ewres_min"):
+ return self.D["ewres_min"]
+ else:
+ return None
+
+ def get_ewres_max(self):
+ """Get the maximal east-west resolution of all registered maps, this value is set in the database
+ automatically via SQL trigger, so no setter exists
+ @return None if not found"""
+ if self.D.has_key("ewres_max"):
+ return self.D["ewres_max"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ stds_metadata_base.print_info(self)
+ # 0123456789012345678901234567890
+ print " | North-South resolution min:. " + str(self.get_nsres_min())
+ print " | North-South resolution max:. " + str(self.get_nsres_max())
+ print " | East-west resolution min:... " + str(self.get_ewres_min())
+ print " | East-west resolution max:... " + str(self.get_ewres_max())
+ print " | Minimum value min:.......... " + str(self.get_min_min())
+ print " | Minimum value max:.......... " + str(self.get_min_max())
+ print " | Maximum value min:.......... " + str(self.get_max_min())
+ print " | Maximum value max:.......... " + str(self.get_max_max())
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ stds_metadata_base.print_shell_info(self)
+ print "nsres_min=" + str(self.get_nsres_min())
+ print "nsres_max=" + str(self.get_nsres_max())
+ print "ewres_min=" + str(self.get_ewres_min())
+ print "ewres_max=" + str(self.get_ewres_max())
+ print "min_min=" + str(self.get_min_min())
+ print "min_max=" + str(self.get_min_max())
+ print "max_min=" + str(self.get_max_min())
+ print "max_max=" + str(self.get_max_max())
+
+
+###############################################################################
+
+class strds_metadata(stds_raster_metadata_base):
+ """This is the raster metadata class"""
+ def __init__(self, ident=None, raster_register=None, title=None, description=None):
+
+ stds_raster_metadata_base.__init__(self, "strds_metadata", ident, title, description)
+
+ self.set_raster_register(raster_register)
+
+ def set_raster_register(self, raster_register):
+ """Set the raster map register table name"""
+ self.D["raster_register"] = raster_register
+
+ def get_raster_register(self):
+ """Get the raster map register table name
+ @return None if not found"""
+ if self.D.has_key("raster_register"):
+ return self.D["raster_register"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ print " +-------------------- Metadata information ----------------------------------+"
+ # 0123456789012345678901234567890
+ print " | Raster register table:...... " + str(self.get_raster_register())
+ stds_raster_metadata_base.print_info(self)
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ stds_raster_metadata_base.print_shell_info(self)
+
+###############################################################################
+
+class str3ds_metadata(stds_raster_metadata_base):
+ """This is the space time raster3d metadata class"""
+ def __init__(self, ident=None, raster3d_register=None, title=None, description=None):
+
+ stds_raster_metadata_base.__init__(self, "str3ds_metadata", ident, title, description)
+
+ self.set_raster3d_register(raster3d_register)
+ self.D["tbres_min"] = None
+ self.D["tbres_max"] = None
+
+ def set_raster3d_register(self, raster3d_register):
+ """Set the raster map register table name"""
+ self.D["raster3d_register"] = raster3d_register
+
+ def get_raster3d_register(self):
+ """Get the raster3d map register table name
+ @return None if not found"""
+ if self.D.has_key("raster3d_register"):
+ return self.D["raster3d_register"]
+ else:
+ return None
+
+ def get_tbres_min(self):
+ """Get the minimal top-bottom resolution of all registered maps, this value is set in the database
+ automatically via SQL trigger, so no setter exists
+ @return None if not found"""
+ if self.D.has_key("tbres_min"):
+ return self.D["tbres_min"]
+ else:
+ return None
+
+ def get_tbres_max(self):
+ """Get the maximal top-bottom resolution of all registered maps, this value is set in the database
+ automatically via SQL trigger, so no setter exists
+ @return None if not found"""
+ if self.D.has_key("tbres_max"):
+ return self.D["tbres_max"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ print " +-------------------- Metadata information ----------------------------------+"
+ # 0123456789012345678901234567890
+ print " | Raster3d register table:.... " + str(self.get_raster3d_register())
+ stds_raster_metadata_base.print_info(self)
+ # 0123456789012345678901234567890
+ print " | Top-bottom resolution min:.. " + str(self.get_ewres_min())
+ print " | Top-bottom resolution max:.. " + str(self.get_ewres_max())
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ stds_raster_metadata_base.print_shell_info(self)
+ print "tbres_min=" + str(self.get_tbres_min())
+ print "tbres_max=" + str(self.get_tbres_max())
+
+###############################################################################
+
+class stvds_metadata(stds_metadata_base):
+ """This is the raster metadata class"""
+ def __init__(self, ident=None, vector_register=None, title=None, description=None):
+
+ stds_metadata_base.__init__(self, "stvds_metadata", ident, title, description)
+
+ self.set_vector_register(vector_register)
+
+ def set_vector_register(self, vector_register):
+ """Set the vector map register table name"""
+ self.D["vector_register"] = vector_register
+
+ def get_vector_register(self):
+ """Get the vector map register table name
+ @return None if not found"""
+ if self.D.has_key("vector_register"):
+ return self.D["vector_register"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ print " +-------------------- Metadata information ----------------------------------+"
+ # 0123456789012345678901234567890
+ print " | Vector register table:...... " + str(self.get_vector_register())
+ stds_metadata_base.print_info(self)
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ stds_metadata_base.print_shell_info(self)
Added: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py (rev 0)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,687 @@
+"""!@package grass.script.tgis_space_time_dataset
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in Python scripts.
+
+Usage:
+
+ at code
+from grass.script import tgis_space_time_dataset as grass
+
+strds = grass.space_time_raster_dataset("soils_1950_2010")
+
+...
+ at endcode
+
+(C) 2008-2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+import getpass
+import grass.script.raster as raster
+import grass.script.vector as vector
+import grass.script.raster3d as raster3d
+from abstract_datasets import *
+
+
+###############################################################################
+
+class raster_dataset(abstract_map_dataset):
+ """Raster dataset class
+
+ This class provides functions to select, update, insert or delete raster
+ map informations and valid time stamps into the SQL temporal database.
+ """
+ def __init__(self, ident):
+ self.reset(ident)
+
+ def get_type(self):
+ return "raster"
+
+ def get_new_instance(self, ident):
+ """Return a new instance with the type of this class"""
+ return raster_dataset(ident)
+
+ def get_new_stds_instance(self, ident):
+ """Return a new space time dataset instance in which maps are stored with the type of this class"""
+ return space_time_raster_dataset(ident)
+
+ def get_stds_register(self):
+ """Return the space time dataset register table name in which stds are listed in which this map is registered"""
+ return self.metadata.get_strds_register()
+
+ def set_stds_register(self, name):
+ """Set the space time dataset register table name in which stds are listed in which this map is registered"""
+ self.metadata.set_strds_register(name)
+
+ def reset(self, ident):
+ """Reset the internal structure and set the identifier"""
+ self.ident = ident
+
+ self.base = raster_base(ident=ident)
+ self.absolute_time = raster_absolute_time(ident=ident)
+ self.relative_time = raster_relative_time(ident=ident)
+ self.spatial_extent = raster_spatial_extent(ident=ident)
+ self.metadata = raster_metadata(ident=ident)
+
+ def load(self):
+ """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)
+
+ # Fill base information
+
+ self.base.set_name(self.ident.split("@")[0])
+ self.base.set_mapset(self.ident.split("@")[1])
+ self.base.set_creator(str(getpass.getuser()))
+
+ # Fill spatial extent
+
+ self.set_spatial_extent(north=kvp["north"], south=kvp["south"], \
+ east=kvp["east"], west=kvp["west"])
+
+ # Fill metadata
+
+ self.metadata.set_nsres(kvp["nsres"])
+ self.metadata.set_ewres(kvp["ewres"])
+ self.metadata.set_datatype(kvp["datatype"])
+ self.metadata.set_min(kvp["min"])
+ self.metadata.set_max(kvp["max"])
+
+ rows = int((kvp["north"] - kvp["south"])/kvp["nsres"] + 0.5)
+ cols = int((kvp["east"] - kvp["west"])/kvp["ewres"] + 0.5)
+
+ ncells = cols * rows
+
+ self.metadata.set_cols(cols)
+ self.metadata.set_rows(rows)
+ self.metadata.set_number_of_cells(ncells)
+
+###############################################################################
+
+class raster3d_dataset(abstract_map_dataset):
+ """Raster3d dataset class
+
+ This class provides functions to select, update, insert or delete raster3d
+ map informations and valid time stamps into the SQL temporal database.
+ """
+ def __init__(self, ident):
+ self.reset(ident)
+
+ def get_type(self):
+ return "raster3d"
+
+ def get_new_instance(self, ident):
+ """Return a new instance with the type of this class"""
+ return raster3d_dataset(ident)
+
+ def get_new_stds_instance(self, ident):
+ """Return a new space time dataset instance in which maps are stored with the type of this class"""
+ return space_time_raster3d_dataset(ident)
+
+ def get_stds_register(self):
+ """Return the space time dataset register table name in which stds are listed in which this map is registered"""
+ return self.metadata.get_str3ds_register()
+
+ def set_stds_register(self, name):
+ """Set the space time dataset register table name in which stds are listed in which this map is registered"""
+ self.metadata.set_str3ds_register(name)
+
+ def reset(self, ident):
+ """Reset the internal structure and set the identifier"""
+ self.ident = ident
+
+ self.base = raster3d_base(ident=ident)
+ self.absolute_time = raster3d_absolute_time(ident=ident)
+ self.relative_time = raster3d_relative_time(ident=ident)
+ self.spatial_extent = raster3d_spatial_extent(ident=ident)
+ self.metadata = raster3d_metadata(ident=ident)
+
+ def load(self):
+ """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)
+
+ # Fill base information
+
+ self.base.set_name(self.ident.split("@")[0])
+ self.base.set_mapset(self.ident.split("@")[1])
+ self.base.set_creator(str(getpass.getuser()))
+
+ # Fill spatial extent
+
+ self.set_spatial_extent(north=kvp["north"], south=kvp["south"], \
+ east=kvp["east"], west=kvp["west"],\
+ top=kvp["top"], bottom=kvp["bottom"])
+
+ # Fill metadata
+
+ self.metadata.set_nsres(kvp["nsres"])
+ self.metadata.set_ewres(kvp["ewres"])
+ self.metadata.set_tbres(kvp["tbres"])
+ self.metadata.set_datatype(kvp["datatype"])
+ self.metadata.set_min(kvp["min"])
+ self.metadata.set_max(kvp["max"])
+
+ rows = int((kvp["north"] - kvp["south"])/kvp["nsres"] + 0.5)
+ cols = int((kvp["east"] - kvp["west"])/kvp["ewres"] + 0.5)
+ depths = int((kvp["top"] - kvp["bottom"])/kvp["tbres"] + 0.5)
+
+ ncells = cols * rows * depths
+
+ self.metadata.set_cols(cols)
+ self.metadata.set_rows(rows)
+ self.metadata.set_depths(depths)
+ self.metadata.set_number_of_cells(ncells)
+
+###############################################################################
+
+class vector_dataset(abstract_map_dataset):
+ """Vector dataset class
+
+ This class provides functions to select, update, insert or delete vector
+ map informations and valid time stamps into the SQL temporal database.
+ """
+ def __init__(self, ident):
+ self.reset(ident)
+
+ def get_type(self):
+ return "vector"
+
+ def get_new_instance(self, ident):
+ """Return a new instance with the type of this class"""
+ return vector_dataset(ident)
+
+ def get_new_stds_instance(self, ident):
+ """Return a new space time dataset instance in which maps are stored with the type of this class"""
+ return space_time_vector_dataset(ident)
+
+ def get_stds_register(self):
+ """Return the space time dataset register table name in which stds are listed in which this map is registered"""
+ return self.metadata.get_stvds_register()
+
+ def set_stds_register(self, name):
+ """Set the space time dataset register table name in which stds are listed in which this map is registered"""
+ self.metadata.set_stvds_register(name)
+
+ def reset(self, ident):
+ """Reset the internal structure and set the identifier"""
+ self.ident = ident
+
+ self.base = vector_base(ident=ident)
+ self.absolute_time = vector_absolute_time(ident=ident)
+ self.relative_time = vector_relative_time(ident=ident)
+ self.spatial_extent = vector_spatial_extent(ident=ident)
+ self.metadata = vector_metadata(ident=ident)
+
+ def load(self):
+ """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)
+
+ # Fill base information
+
+ self.base.set_name(self.ident.split("@")[0])
+ self.base.set_mapset(self.ident.split("@")[1])
+ self.base.set_creator(str(getpass.getuser()))
+
+ # Fill spatial extent
+
+ self.set_spatial_extent(north=kvp["north"], south=kvp["south"], \
+ east=kvp["east"], west=kvp["west"],\
+ top=kvp["top"], bottom=kvp["bottom"])
+
+ # Fill metadata .. no metadata yet
+
+###############################################################################
+
+class space_time_raster_dataset(abstract_space_time_dataset):
+ """Space time raster dataset class
+ """
+ def __init__(self, ident):
+ abstract_space_time_dataset.__init__(self, ident)
+
+ def get_type(self):
+ return "strds"
+
+ def get_new_instance(self, ident):
+ """Return a new instance with the type of this class"""
+ return space_time_raster_dataset(ident)
+
+ def get_new_map_instance(self, ident):
+ """Return a new instance of a map dataset which is associated with the type of this class"""
+ return raster_dataset(ident)
+
+ def get_map_register(self):
+ """Return the name of the map register table"""
+ return self.metadata.get_raster_register()
+
+ def set_map_register(self, name):
+ """Set the name of the map register table"""
+ self.metadata.set_raster_register(name)
+
+ def reset(self, ident):
+
+ """Reset the internal structure and set the identifier"""
+ self.ident = ident
+
+ self.base = strds_base(ident=ident)
+
+ if ident != None:
+ self.base.set_name(self.ident.split("@")[0])
+ self.base.set_mapset(self.ident.split("@")[1])
+ self.base.set_creator(str(getpass.getuser()))
+ self.absolute_time = strds_absolute_time(ident=ident)
+ self.relative_time = strds_relative_time(ident=ident)
+ self.spatial_extent = strds_spatial_extent(ident=ident)
+ self.metadata = strds_metadata(ident=ident)
+
+###############################################################################
+
+class space_time_raster3d_dataset(abstract_space_time_dataset):
+ """Space time raster3d dataset class
+ """
+
+ def __init__(self, ident):
+ abstract_space_time_dataset.__init__(self, ident)
+
+ def get_type(self):
+ return "str3ds"
+
+ def get_new_instance(self, ident):
+ """Return a new instance with the type of this class"""
+ return space_time_raster3d_dataset(ident)
+
+ def get_new_map_instance(self, ident):
+ """Return a new instance of a map dataset which is associated with the type of this class"""
+ return raster3d_dataset(ident)
+
+ def get_map_register(self):
+ """Return the name of the map register table"""
+ return self.metadata.get_raster3d_register()
+
+ def set_map_register(self, name):
+ """Set the name of the map register table"""
+ self.metadata.set_raster3d_register(name)
+
+ def reset(self, ident):
+
+ """Reset the internal structure and set the identifier"""
+ self.ident = ident
+
+ self.base = str3ds_base(ident=ident)
+
+ if ident != None:
+ self.base.set_name(self.ident.split("@")[0])
+ self.base.set_mapset(self.ident.split("@")[1])
+ self.base.set_creator(str(getpass.getuser()))
+ self.absolute_time = str3ds_absolute_time(ident=ident)
+ self.relative_time = str3ds_relative_time(ident=ident)
+ self.spatial_extent = str3ds_spatial_extent(ident=ident)
+ self.metadata = str3ds_metadata(ident=ident)
+
+###############################################################################
+
+class space_time_vector_dataset(abstract_space_time_dataset):
+ """Space time vector dataset class
+ """
+
+ def __init__(self, ident):
+ abstract_space_time_dataset.__init__(self, ident)
+
+ def get_type(self):
+ return "stvds"
+
+ def get_new_instance(self, ident):
+ """Return a new instance with the type of this class"""
+ return space_time_vector_dataset(ident)
+
+ def get_new_map_instance(self, ident):
+ """Return a new instance of a map dataset which is associated with the type of this class"""
+ return vector_dataset(ident)
+
+ def get_map_register(self):
+ """Return the name of the map register table"""
+ return self.metadata.get_vector_register()
+
+ def set_map_register(self, name):
+ """Set the name of the map register table"""
+ self.metadata.set_vector_register(name)
+
+ def reset(self, ident):
+
+ """Reset the internal structure and set the identifier"""
+ self.ident = ident
+
+ self.base = stvds_base(ident=ident)
+
+ if ident != None:
+ self.base.set_name(self.ident.split("@")[0])
+ self.base.set_mapset(self.ident.split("@")[1])
+ self.base.set_creator(str(getpass.getuser()))
+ self.absolute_time = stvds_absolute_time(ident=ident)
+ self.relative_time = stvds_relative_time(ident=ident)
+ self.spatial_extent = stvds_spatial_extent(ident=ident)
+ self.metadata = stvds_metadata(ident=ident)
+
+###############################################################################
+
+def register_maps_in_space_time_dataset(type, name, maps, start=None, increment=None, dbif = None):
+ """Use this method to register maps in space time datasets. This function is generic and
+ can handle raster, vector and raster3d maps as well as there space time datasets.
+
+ Additionally a start time string and an increment string can be specified
+ to assign a time interval automatically to the maps.
+
+ It takes care of the correct update of the space time datasets from all
+ registered maps.
+
+ @type The type of the maps raster, raster3d or vector
+ @name The name of the space time dataset
+ @maps A comma separated list of map names
+ @start The start date and time of the first raster map, in case the map has no date (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
+ @increment Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
+ """
+
+ # We may need the mapset
+ mapset = core.gisenv()["MAPSET"]
+
+ # Check if the dataset name contains the mapset as well
+ if name.find("@") < 0:
+ id = name + "@" + mapset
+ else:
+ id = name
+
+ if type == "raster":
+ sp = space_time_raster_dataset(id)
+ if type == "raster3d":
+ sp = space_time_raster3d_dataset(id)
+ if type == "vector":
+ sp = space_time_vector_dataset(id)
+
+ connect = False
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ # Read content from temporal database
+ sp.select(dbif)
+
+ if sp.is_in_db(dbif) == False:
+ core.fatal("Space time " + sp.get_new_map_instance(None).get_type() + " dataset <" + name + "> not found")
+
+ if maps.find(",") == -1:
+ maplist = (maps,)
+ else:
+ maplist = tuple(maps.split(","))
+
+ count = 0
+ for mapname in maplist:
+ mapname = mapname.strip()
+ # Check if the map name contains the mapset as well
+ if mapname.find("@") < 0:
+ mapid = mapname + "@" + mapset
+ else:
+ mapid = mapname
+ # Get a new instance of the space time dataset map type
+ map = sp.get_new_map_instance(mapid)
+
+ # In case the map is already registered print a message and continue to the next map
+
+ # 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:
+ core.fatal("Unable to register " + map.get_type() + " map <" + map.get_id() + ">. The map has no valid time and the start time is not set.")
+ # 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():
+ core.fatal("Unable to register " + map.get_type() + " map <" + map.get_id() + ">. The temporal types are different.")
+
+ # Set the valid time
+ if start:
+ assign_valid_time_to_map(ttype=sp.get_temporal_type(), map=map, start=start, end=None, increment=increment, mult=count, dbif=dbif)
+
+ # 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)
+
+ if connect == True:
+ dbif.close()
+
+###############################################################################
+
+def unregister_maps_from_space_time_datasets(type, name, maps, 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.
+
+ @type The type of the maps raster, vector or raster3d
+ @name Name of an existing space time raster dataset. If no name is provided the raster map(s) are unregistered from all space time datasets in which they are registered.
+ @maps Name(s) of existing map(s) to unregister
+ """
+ mapset = core.gisenv()["MAPSET"]
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ # In case a space time dataset is specified
+ if name:
+ # Check if the dataset name contains the mapset as well
+ if name.find("@") < 0:
+ id = name + "@" + mapset
+ else:
+ id = name
+
+ if type == "raster":
+ sp = space_time_raster_dataset(id)
+ if type == "raster3d":
+ sp = space_time_raster3d_dataset(id)
+ if type == "vector":
+ sp = space_time_vector_dataset(id)
+
+ if sp.is_in_db(dbif) == False:
+ core.fatal("Space time " + sp.get_new_map_instance(None).get_type() + " dataset <" + name + "> not found")
+
+ # Build the list of maps
+ if maps.find(",") == -1:
+ maplist = (maps,)
+ else:
+ maplist = tuple(maps.split(","))
+
+ for mapname in maplist:
+ mapname = mapname.strip()
+ # Check if the map name contains the mapset as well
+ if mapname.find("@") < 0:
+ mapid = mapname + "@" + mapset
+ else:
+ mapid = mapname
+
+ # Create a new instance with the map type
+ if type == "raster":
+ map = raster_dataset(mapid)
+ if type == "raster3d":
+ map = raster3d_dataset(mapid)
+ if type == "vector":
+ map = vector_dataset(mapid)
+
+ # Unregister map if in database
+ if map.is_in_db(dbif) == True:
+ if name:
+ sp.select(dbif)
+ sp.unregister_map(map, dbif)
+ else:
+ map.select(dbif)
+ map.unregister(dbif)
+
+ if name:
+ sp.update_from_registered_maps(dbif)
+
+ if connect == True:
+ dbif.close()
+
+###############################################################################
+
+def assign_valid_time_to_maps(type, maps, ttype, start, end=None, increment=None, dbif = None):
+ """Use this method to assign valid time (absolute or relative) to raster,
+ raster3d and vector datasets.
+
+ It takes care of the correct update of the space time datasets from all
+ registered maps.
+
+ Valid end time and increment are mutual exclusive.
+
+ @type The type of the maps raster, raster3d or vector
+ @maps A comma separated list of map names
+ @start The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
+ @end The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
+ @increment Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
+ """
+
+ if end and increment:
+ core.fatal("Valid end time and increment are mutual exclusive")
+
+ # List of space time datasets to be updated
+ splist = {}
+
+ # We may need the mapset
+ mapset = core.gisenv()["MAPSET"]
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ if maps.find(",") == -1:
+ maplist = (maps,)
+ else:
+ maplist = tuple(maps.split(","))
+
+ count = 0
+ for mapname in maplist:
+ mapname = mapname.strip()
+ # Check if the map name contains the mapset as well
+ if mapname.find("@") < 0:
+ mapid = mapname + "@" + mapset
+ else:
+ mapid = mapname
+
+ if type == "raster":
+ map = raster_dataset(mapid)
+ if type == "raster3d":
+ map = raster3d_dataset(mapid)
+ if type == "vector":
+ map = vector_dataset(mapid)
+
+ if map.is_in_db(dbif) == False:
+ # Load the data from the grass file database
+ map.load()
+ if ttype == "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)
+ sprows = map.get_registered_datasets(dbif)
+ # Make an entry in the dataset list, using a dict make sure that
+ # each dataset is listed only once
+ if sprows != None:
+ for dataset in sprows:
+ splist[dataset["id"]] = True
+
+ # Set the valid time
+ assign_valid_time_to_map(ttype=ttype, map=map, start=start, end=end, increment=increment, mult=count, dbif=dbif)
+
+ count += 1
+
+ # Update all the space time datasets in which registered maps are changed there valid time
+ for name in splist.keys():
+ sp = map.get_new_stds_instance(name)
+ sp.select(dbif)
+ sp.update_from_registered_maps(dbif)
+
+ if connect == True:
+ dbif.close()
+
+
+###############################################################################
+
+def assign_valid_time_to_map(ttype, map, start, end, increment=None, mult=1, dbif = None):
+ """Assign the valid time to a map dataset
+
+ @ttype The temporal type which should be assigned and which the time format is of
+ @map A map dataset object derived from abstract_map_dataset
+ @start The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
+ @end The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
+ @increment Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
+ @multi A multiplier for the increment
+ """
+
+ connect = False
+
+ if dbif == None:
+ dbif = sql_database_interface()
+ dbif.connect()
+ connect = True
+
+ if ttype == "absolute":
+ # Create the start time object
+ if start.find(":") > 0:
+ time_format = "%Y-%m-%d %H:%M:%S"
+ else:
+ time_format = "%Y-%m-%d"
+
+ start_time = datetime.strptime(start, time_format)
+ if end:
+ end_time = datetime.strptime(end, time_format)
+ else:
+ end_time = None
+
+ # Add the increment
+ if increment:
+ start_time = increment_datetime_by_string(start_time, increment, mult)
+ 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)))
+ map.update_absolute_time(start_time, end_time, None, dbif)
+ else:
+ start_time = float(start)
+
+ if end:
+ end_time = float(end)
+ else:
+ end_time = None
+
+ if increment:
+ start_time = start_time + mult * float(increment)
+ end_time = start_time + float(increment)
+
+ core.verbose(_("Set relative valid time for map <%s> to %f - %s") % (map.get_id(), start_time, str(end_time)))
+ map.update_relative_time(start_time, end_time, dbif)
+
+ if connect == True:
+ dbif.close()
Added: grass/trunk/lib/python/temporal/spatial_extent.py
===================================================================
--- grass/trunk/lib/python/temporal/spatial_extent.py (rev 0)
+++ grass/trunk/lib/python/temporal/spatial_extent.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,290 @@
+"""!@package grass.script.tgis_spatial_extent
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related spatial extent functions to be used in Python scripts and tgis packages.
+
+Usage:
+
+ at code
+from grass.script import tgis_spatial_extent as grass
+
+extent = grass.raster_spatial_extent()
+...
+ at endcode
+
+(C) 2008-2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+from base import *
+
+class spatial_extent(sql_database_interface):
+ """This is the spatial extent base class for all maps and spacetime datasets"""
+ def __init__(self, table=None, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None, proj="XY"):
+
+ sql_database_interface.__init__(self, table, ident)
+ self.set_id(ident)
+ self.set_spatial_extent(north, south, east, west, top, bottom)
+ self.set_projection(proj)
+
+ def overlap_2d(self, extent):
+ """Return True if the 2d extents overlap. Code is lend from wind_overlap.c in lib/gis"""
+
+ if self.get_projection() != extent.get_projection():
+ core.error("Projections are different. Unable to compute overlap_2d for spatial extents")
+
+ N = extent.get_north()
+ S = extent.get_south()
+ E = extent.get_east()
+ W = extent.get_west()
+
+ if(self.get_north() <= S):
+ return False
+
+ if(self.get_south() >= N):
+ return False
+
+ # Adjust the east and west in case of LL projection
+ if self.get_proj() == "LL":
+ while E < self.get_west():
+ E += 360.0
+ W += 360.0
+
+ while W > self.get_east():
+ E -= 360.0
+ W -= 360.0
+
+ if self.get_east() <= W:
+ return False
+
+ if self.get_west() >= E:
+ return False
+
+ return True
+
+ def overlap(self, extent):
+ """Return True if the extents overlap."""
+
+ if self.overlap_2d(extent) == False:
+ return False
+
+ T = extent.get_top()
+ B = extent.get_bottom()
+
+ if self.get_top() <= B:
+ return False
+
+ if self.get_bottom() >= T:
+ return False
+
+ return True
+
+ def set_spatial_extent(self, north, south, east, west, top, bottom):
+ """Set the spatial extent"""
+
+ self.set_north(north)
+ self.set_south(south)
+ self.set_east(east)
+ self.set_west(west)
+ self.set_top(top)
+ self.set_bottom(bottom)
+
+ def set_projection(self, proj):
+ """Set the projection of the spatial extent it should be XY or LL.
+ As default the projection is XY
+ """
+ if proj == None or (proj != "XY" and proj != "LL"):
+ self.D["proj"] = "XY"
+ else:
+ self.D["proj"] = proj
+
+ def set_spatial_extent_2d(self, north, south, east, west):
+
+ self.set_id(ident)
+ self.set_north(north)
+ self.set_south(south)
+ self.set_east(east)
+ self.set_west(west)
+ self.set_top(0)
+ self.set_bottom(0)
+
+ def set_id(self, ident):
+ """Convenient method to set the unique identifier (primary key)"""
+ self.ident = ident
+ self.D["id"] = ident
+
+ def set_north(self, north):
+ """Set the northern edge of the map"""
+ self.D["north"] = north
+
+ def set_south(self, sourth):
+ """Set the sourthern edge of the map"""
+ self.D["south"] = sourth
+
+ def set_west(self, west):
+ """Set the western edge of the map"""
+ self.D["west"] = west
+
+ def set_east(self, east):
+ """Set the eastern edge of the map"""
+ self.D["east"] = east
+
+ def set_top(self, top):
+ """Set the top edge of the map"""
+ self.D["top"] = top
+
+ def set_bottom(self, bottom):
+ """Set the bottom edge of the map"""
+ self.D["bottom"] = bottom
+
+ def get_id(self):
+ """Convenient method to get the unique identifier (primary key)
+ @return None if not found
+ """
+ if self.D.has_key("id"):
+ return self.D["id"]
+ else:
+ return None
+
+ def get_projection(self):
+ """Get the projection of the spatial extent"""
+ return self.D["proj"]
+
+ def get_volume(self):
+ """Compute the volume of the extent, in case z is zero (top == bottom or top - bottom = 1) the area is returned"""
+
+ if self.get_projection() == "LL":
+ core.error("Volume computation is not supported for LL projections")
+
+ area = self.get_area()
+
+ bbox = self.get_spatial_extent()
+
+ z = abs(bbox[4] - bbox[5])
+
+ if z == 0:
+ z = 1.0
+
+ return area*z
+
+ def get_area(self):
+ """Compute the area of the extent, extent in z direction is ignored"""
+
+ if self.get_projection() == "LL":
+ core.error("Area computation is not supported for LL projections")
+
+ bbox = self.get_spatial_extent()
+
+ y = abs(bbox[0] - bbox[1])
+ x = abs(bbox[2] - bbox[3])
+
+ return x*y
+
+ def get_spatial_extent(self):
+ """Return a tuple (north, south, east, west, top, bottom) of the spatial extent"""
+
+ return (self.get_north(), self.get_south, self.get_east(), self.get_west(), \
+ self.get_top(), self.get_bottom())
+
+ def get_spatial_extent_2d(self):
+ """Return a tuple (north, south, east, west,) of the 2d spatial extent"""
+ return (self.get_north(), self.get_south, self.get_east(), self.get_west())
+
+ def get_north(self):
+ """Get the northern edge of the map
+ @return None if not found"""
+ if self.D.has_key("north"):
+ return self.D["north"]
+ else:
+ return None
+
+ def get_south(self):
+ """Get the southern edge of the map
+ @return None if not found"""
+ if self.D.has_key("south"):
+ return self.D["south"]
+ else:
+ return None
+
+ def get_east(self):
+ """Get the eastern edge of the map
+ @return None if not found"""
+ if self.D.has_key("east"):
+ return self.D["east"]
+ else:
+ return None
+
+ def get_west(self):
+ """Get the western edge of the map
+ @return None if not found"""
+ if self.D.has_key("west"):
+ return self.D["west"]
+ else:
+ return None
+
+ def get_top(self):
+ """Get the top edge of the map
+ @return None if not found"""
+ if self.D.has_key("top"):
+ return self.D["top"]
+ else:
+ return None
+
+ def get_bottom(self):
+ """Get the bottom edge of the map
+ @return None if not found"""
+ if self.D.has_key("bottom"):
+ return self.D["bottom"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ # 0123456789012345678901234567890
+ print " +-------------------- Spatial extent ----------------------------------------+"
+ print " | North:...................... " + str(self.get_north())
+ print " | South:...................... " + str(self.get_south())
+ print " | East:.. .................... " + str(self.get_east())
+ print " | West:....................... " + str(self.get_west())
+ print " | Top:........................ " + str(self.get_top())
+ print " | Bottom:..................... " + str(self.get_bottom())
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ print "north=" + str(self.get_north())
+ print "south=" + str(self.get_south())
+ print "east=" + str(self.get_east())
+ print "west=" + str(self.get_west())
+ print "top=" + str(self.get_top())
+ print "bottom=" + str(self.get_bottom())
+
+
+###############################################################################
+
+class raster_spatial_extent(spatial_extent):
+ def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
+ spatial_extent.__init__(self, "raster_spatial_extent", ident, north, south, east, west, top, bottom)
+
+class raster3d_spatial_extent(spatial_extent):
+ def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
+ spatial_extent.__init__(self, "raster3d_spatial_extent", ident, north, south, east, west, top, bottom)
+
+class vector_spatial_extent(spatial_extent):
+ def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
+ spatial_extent.__init__(self, "vector_spatial_extent", ident, north, south, east, west, top, bottom)
+
+class strds_spatial_extent(spatial_extent):
+ def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
+ spatial_extent.__init__(self, "strds_spatial_extent", ident, north, south, east, west, top, bottom)
+
+class str3ds_spatial_extent(spatial_extent):
+ def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
+ spatial_extent.__init__(self, "str3ds_spatial_extent", ident, north, south, east, west, top, bottom)
+
+class stvds_spatial_extent(spatial_extent):
+ def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
+ spatial_extent.__init__(self, "stvds_spatial_extent", ident, north, south, east, west, top, bottom)
Added: grass/trunk/lib/python/temporal/temporal_extent.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_extent.py (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_extent.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -0,0 +1,438 @@
+"""!@package grass.script.tgis_temporal_extent
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related temporal extent functions to be used in Python scripts and tgis packages.
+
+Usage:
+
+ at code
+from grass.script import tgis_temporal_extent as grass
+
+grass.raster_temporal_extent()
+...
+ at endcode
+
+(C) 2008-2011 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Soeren Gebbert
+"""
+from base import *
+
+###############################################################################
+
+class abstract_temporal_extent(sql_database_interface):
+ """This is the abstract time base class for relative and absolute time objects"""
+ def __init__(self, table=None, ident=None, start_time=None, end_time=None):
+
+ sql_database_interface.__init__(self, table, ident)
+
+ self.set_id(ident)
+ self.set_start_time(start_time)
+ self.set_end_time(end_time)
+
+ def starts(self, map):
+ """Return True if this absolute time object starts at the start of the provided absolute time object and finishes within it
+ A |-----|
+ B |---------|
+ """
+ if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] < map.D["end_time"]:
+ return True
+ else:
+ return False
+
+ def started(self, map):
+ """Return True if this absolute time object is started at the start of the provided absolute time object
+ A |---------|
+ B |-----|
+ """
+ if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] > map.D["end_time"]:
+ return True
+ else:
+ return False
+
+ def finishes(self, map):
+ """Return True if this absolute time object finishes at the end and within of the provided absolute time object
+ A |-----|
+ B |---------|
+ """
+ if self.D["end_time"] == map.D["end_time"] and self.D["start_time"] > map.D["start_time"] :
+ return True
+ else:
+ return False
+
+ def finished(self, map):
+ """Return True if this absolute time object finished at the end of the provided absolute time object
+ A |---------|
+ B |-----|
+ """
+ if self.D["end_time"] == map.D["end_time"] and self.D["start_time"] < map.D["start_time"] :
+ return True
+ else:
+ return False
+
+ def after(self, map):
+ """Return True if this absolute time object is temporal located after the provided absolute time object
+ A |---------|
+ B |---------|
+ """
+ if self.D["start_time"] > map.D["end_time"]:
+ return True
+ else:
+ return False
+
+ def before(self, map):
+ """Return True if this absolute time object is temporal located bevor the provided absolute time object
+ A |---------|
+ B |---------|
+ """
+ if self.D["end_time"] < map.D["start_time"]:
+ return True
+ else:
+ return False
+
+ def adjacent(self, map):
+ """Return True if this absolute time object is a meeting neighbour the provided absolute time object
+ A |---------|
+ B |---------|
+ A |---------|
+ B |---------|
+ """
+ if (self.D["start_time"] == map.D["end_time"]) or (self.D["end_time"] == map.D["start_time"]):
+ return True
+ else:
+ return False
+
+ def follows(self, map):
+ """Return True if this absolute time object is temporal follows the provided absolute time object
+ A |---------|
+ B |---------|
+ """
+ if self.D["start_time"] == map.D["end_time"]:
+ return True
+ else:
+ return False
+
+ def precedes(self, map):
+ """Return True if this absolute time object is temporal precedes the provided absolute time object
+ A |---------|
+ B |---------|
+ """
+ if self.D["end_time"] == map.D["start_time"]:
+ return True
+ else:
+ return False
+
+ def during(self, map):
+ """Return True if this absolute time object is temporal located during the provided absolute time object
+ A |-------|
+ B |---------|
+ """
+ if self.D["start_time"] > map.D["start_time"] and self.D["end_time"] < map.D["end_time"]:
+ return True
+ else:
+ return False
+
+ def contains(self, map):
+ """Return True if this absolute time object is temporal located during the provided absolute time object
+ A |---------|
+ B |-------|
+ """
+ if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] > map.D["end_time"]:
+ return True
+ else:
+ return False
+
+ def equivalent(self, map):
+ """Return True if this absolute time object is temporal located equivalent the provided absolute time object
+ A |---------|
+ B |---------|
+ """
+ if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] == map.D["end_time"]:
+ return True
+ else:
+ return False
+
+ def overlaps(self, map):
+ """Return True if this absolute time object is temporal overlaps the provided absolute time object
+ A |---------|
+ B |---------|
+ """
+ if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] < map.D["end_time"] and\
+ self.D["end_time"] > map.D["start_time"]:
+ return True
+ else:
+ return False
+
+ def overlapped(self, map):
+ """Return True if this absolute time object is temporal overlaped by the provided absolute time object
+ A |---------|
+ B |---------|
+ """
+ if self.D["start_time"] > map.D["start_time"] and self.D["end_time"] > map.D["end_time"] and\
+ self.D["start_time"] < map.D["end_time"]:
+ return True
+ else:
+ return False
+
+ def temporal_relation(self, map):
+ """Returns the temporal relation between absolute time temporal objects
+ Temporal relationsships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
+ """
+ if self.equivalent(map):
+ return "equivalent"
+ if self.during(map):
+ return "during"
+ if self.contains(map):
+ return "contains"
+ if self.overlaps(map):
+ return "overlaps"
+ if self.overlapped(map):
+ return "overlapped"
+ if self.after(map):
+ return "after"
+ if self.before(map):
+ return "before"
+ if self.starts(map):
+ return "starts"
+ if self.finishes(map):
+ return "finishes"
+ if self.started(map):
+ return "started"
+ if self.finished(map):
+ return "finished"
+ if self.equivalent(map):
+ return "equivalent"
+ if self.follows(map):
+ return "follows"
+ if self.precedes(map):
+ return "precedes"
+ return None
+
+ def set_id(self, ident):
+ """Convenient method to set the unique identifier (primary key)"""
+ self.ident = ident
+ self.D["id"] = ident
+
+ def set_start_time(self, start_time):
+ """Set the valid start time of the map"""
+ self.D["start_time"] = start_time
+
+ def set_end_time(self, end_time):
+ """Set the valid end time of the map"""
+ self.D["end_time"] = end_time
+
+ def get_id(self):
+ """Convenient method to get the unique identifier (primary key)
+ @return None if not found
+ """
+ if self.D.has_key("id"):
+ return self.D["id"]
+ else:
+ return None
+
+ def get_start_time(self):
+ """Get the valid start time of the map
+ @return None if not found"""
+ if self.D.has_key("start_time"):
+ return self.D["start_time"]
+ else:
+ return None
+
+ def get_end_time(self):
+ """Get the valid end time of the map
+ @return None if not found"""
+ if self.D.has_key("end_time"):
+ return self.D["end_time"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ # 0123456789012345678901234567890
+ print " | Start time:................. " + str(self.get_start_time())
+ print " | End time:................... " + str(self.get_end_time())
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ print "start_time=" + str(self.get_start_time())
+ print "end_time=" + str(self.get_end_time())
+
+###############################################################################
+
+class absolute_temporal_extent(abstract_temporal_extent):
+ """This is the absolute time class for all maps and spacetime datasets
+
+ start_time and end_time must be of type datetime
+ """
+ def __init__(self, table=None, ident=None, start_time=None, end_time=None, timezone=None):
+
+ abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
+
+ self.set_timezone(timezone)
+
+ def set_timezone(self, timezone):
+ """Set the timezone of the map, integer from 1 - 24"""
+ self.D["timezone"] = timezone
+
+ def get_timezone(self):
+ """Get the timezone of the map
+ @return None if not found"""
+ if self.D.has_key("timezone"):
+ return self.D["timezone"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ # 0123456789012345678901234567890
+ print " +-------------------- Absolute time -----------------------------------------+"
+ abstract_temporal_extent.print_info(self)
+ print " | Timezone:................... " + str(self.get_timezone())
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ abstract_temporal_extent.print_shell_info(self)
+ print "timezone=" + str(self.get_timezone())
+
+###############################################################################
+
+class raster_absolute_time(absolute_temporal_extent):
+ def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
+ absolute_temporal_extent.__init__(self, "raster_absolute_time", ident, start_time, end_time, timezone)
+
+class raster3d_absolute_time(absolute_temporal_extent):
+ def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
+ absolute_temporal_extent.__init__(self, "raster3d_absolute_time", ident, start_time, end_time, timezone)
+
+class vector_absolute_time(absolute_temporal_extent):
+ def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
+ absolute_temporal_extent.__init__(self, "vector_absolute_time", ident, start_time, end_time, timezone)
+
+###############################################################################
+
+class stds_absolute_time(absolute_temporal_extent):
+ def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
+ absolute_temporal_extent.__init__(self, table, ident, start_time, end_time, timezone)
+
+ self.set_granularity(granularity)
+
+ def set_granularity(self, granularity):
+ """Set the granularity of the space time dataset"""
+ self.D["granularity"] = granularity
+
+ def get_granularity(self):
+ """Get the granularity of the space time dataset
+ @return None if not found"""
+ if self.D.has_key("granularity"):
+ return self.D["granularity"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ absolute_temporal_extent.print_info(self)
+ # 0123456789012345678901234567890
+ print " | Granularity:................ " + str(self.get_granularity())
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ absolute_temporal_extent.print_shell_info(self)
+ print "granularity=" + str(self.get_granularity())
+
+###############################################################################
+
+class strds_absolute_time(stds_absolute_time):
+ def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
+ stds_absolute_time.__init__(self, "strds_absolute_time", ident, start_time, end_time, granularity, timezone)
+
+class str3ds_absolute_time(stds_absolute_time):
+ def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
+ stds_absolute_time.__init__(self, "str3ds_absolute_time", ident, start_time, end_time, granularity, timezone)
+
+class stvds_absolute_time(stds_absolute_time):
+ def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
+ stds_absolute_time.__init__(self, "stvds_absolute_time", ident, start_time, end_time, granularity, timezone)
+
+###############################################################################
+
+
+class relative_temporal_extent(abstract_temporal_extent):
+ """This is the relative time class for all maps and spacetime datasets
+
+ start_time and end_time must be of type datetime
+ """
+ def __init__(self, table=None, ident=None, start_time=None, end_time=None):
+
+ abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
+
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ # 0123456789012345678901234567890
+ print " +-------------------- Reltive time ------------------------------------------+"
+ abstract_temporal_extent.print_info(self)
+
+
+###############################################################################
+
+class raster_relative_time(relative_temporal_extent):
+ def __init__(self, ident=None, start_time=None, end_time=None):
+ relative_temporal_extent.__init__(self, "raster_relative_time", ident, start_time, end_time)
+
+class raster3d_relative_time(relative_temporal_extent):
+ def __init__(self, ident=None, start_time=None, end_time=None):
+ relative_temporal_extent.__init__(self, "raster3d_relative_time", ident, start_time, end_time)
+
+class vector_relative_time(relative_temporal_extent):
+ def __init__(self, ident=None, start_time=None, end_time=None):
+ relative_temporal_extent.__init__(self, "vector_relative_time", ident, start_time, end_time)
+
+###############################################################################
+
+class stds_relative_time(relative_temporal_extent):
+ def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None):
+ relative_temporal_extent.__init__(self, table, ident, start_time, end_time)
+
+ self.set_granularity(granularity)
+
+ def set_granularity(self, granularity):
+ """Set the granularity of the space time dataset"""
+ self.D["granularity"] = granularity
+
+ def get_granularity(self):
+ """Get the granularity of the space time dataset
+ @return None if not found"""
+ if self.D.has_key("granularity"):
+ return self.D["granularity"]
+ else:
+ return None
+
+ def print_info(self):
+ """Print information about this class in human readable style"""
+ relative_temporal_extent.print_info(self)
+ # 0123456789012345678901234567890
+ print " | Granularity:................ " + str(self.get_granularity())
+
+ def print_shell_info(self):
+ """Print information about this class in shell style"""
+ relative_temporal_extent.print_shell_info(self)
+ print "granularity=" + str(self.get_granularity())
+
+###############################################################################
+
+class strds_relative_time(stds_relative_time):
+ def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
+ stds_relative_time.__init__(self, "strds_relative_time", ident, start_time, end_time, granularity)
+
+class str3ds_relative_time(stds_relative_time):
+ def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
+ stds_relative_time.__init__(self, "str3ds_relative_time", ident, start_time, end_time, granularity)
+
+class stvds_relative_time(stds_relative_time):
+ def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
+ stds_relative_time.__init__(self, "stvds_relative_time", ident, start_time, end_time, granularity)
+
Deleted: grass/trunk/lib/python/tgis_abstract_datasets.py
===================================================================
--- grass/trunk/lib/python/tgis_abstract_datasets.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_abstract_datasets.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,758 +0,0 @@
-"""!@package grass.script.tgis_abstract_datasets
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related functions to be used in temporal GIS Python library package.
-
-Usage:
-
- at code
-from grass.script import tgis_abstract_datasets as grass
-
-...
- at endcode
-
-(C) 2008-2011 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Soeren Gebbert
-"""
-import uuid
-from tgis_temporal_extent import *
-from tgis_spatial_extent import *
-from tgis_metadata import *
-
-class abstract_dataset(object):
- """This is the base class for all datasets (raster, vector, raster3d, strds, stvds, str3ds)"""
-
- def reset(self, ident):
- """Reset the internal structure and set the identifier"""
- raise IOError("This method must be implemented in the subclasses")
-
- def get_type(self):
- """Return the type of this class"""
- raise IOError("This method must be implemented in the subclasses")
-
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- raise IOError("This method must be implemented in the subclasses")
-
- def get_id(self):
- return self.base.get_id()
-
- def get_absolute_time(self):
- """Returns a tuple of the start, the end valid time and the timezone of the map
- @return A tuple of (start_time, end_time, timezone)
- """
-
- start = self.absolute_time.get_start_time()
- end = self.absolute_time.get_end_time()
- tz = self.absolute_time.get_timezone()
-
- return (start, end, tz)
-
- def get_relative_time(self):
- """Returns the relative time interval (start_time, end_time) or None if not present"""
-
- start = self.relative_time.get_start_time()
- end = self.relative_time.get_end_time()
-
- return (start, end)
-
- def get_temporal_type(self):
- """Return the temporal type of this dataset"""
- return self.base.get_ttype()
-
- def get_spatial_extent(self):
- """Return a tuple of spatial extent (north, south, east, west, top, bottom) """
-
- north = self.spatial_extent.get_north()
- south = self.spatial_extent.get_south()
- east = self.spatial_extent.get_east()
- west = self.spatial_extent.get_west()
- top = self.spatial_extent.get_top()
- bottom = self.spatial_extent.get_bottom()
-
- return (north, south, east, west, top, bottom)
-
- def select(self, dbif=None):
- """Select temporal dataset entry from database and fill up the internal structure"""
- self.base.select(dbif)
- if self.is_time_absolute():
- self.absolute_time.select(dbif)
- if self.is_time_relative():
- self.relative_time.select(dbif)
- self.spatial_extent.select(dbif)
- self.metadata.select(dbif)
-
- def is_in_db(self, dbif=None):
- """Check if the temporal dataset entry is in the database"""
- return self.base.is_in_db(dbif)
-
- def delete(self):
- """Delete temporal dataset entry from database if it exists"""
- raise IOError("This method must be implemented in the subclasses")
-
- def insert(self, dbif=None):
- """Insert temporal dataset entry into database from the internal structure"""
- self.base.insert(dbif)
- if self.is_time_absolute():
- self.absolute_time.insert(dbif)
- if self.is_time_relative():
- self.relative_time.insert(dbif)
- self.spatial_extent.insert(dbif)
- self.metadata.insert(dbif)
-
- def update(self, dbif=None):
- """Update temporal dataset entry of database from the internal structure"""
- self.base.update(dbif)
- if self.is_time_absolute():
- self.absolute_time.update(dbif)
- if self.is_time_relative():
- self.relative_time.update(dbif)
- self.spatial_extent.update(dbif)
- self.metadata.update(dbif)
-
- def print_self(self):
- """Print the content of the internal structure to stdout"""
- self.base.print_self()
- if self.is_time_absolute():
- self.absolute_time.print_self()
- if self.is_time_relative():
- self.relative_time.print_self()
- self.spatial_extent.print_self()
- self.metadata.print_self()
-
- def print_info(self):
- """Print information about this class in human readable style"""
-
- if self.get_type() == "raster":
- # 1 2 3 4 5 6 7
- # 0123456789012345678901234567890123456789012345678901234567890123456789012345678
- print ""
- print " +-------------------- Raster Dataset ----------------------------------------+"
- if self.get_type() == "raster3d":
- # 1 2 3 4 5 6 7
- # 0123456789012345678901234567890123456789012345678901234567890123456789012345678
- print ""
- print " +-------------------- Raster3d Dataset --------------------------------------+"
- if self.get_type() == "vector":
- # 1 2 3 4 5 6 7
- # 0123456789012345678901234567890123456789012345678901234567890123456789012345678
- print ""
- print " +-------------------- Vector Dataset ----------------------------------------+"
- if self.get_type() == "strds":
- # 1 2 3 4 5 6 7
- # 0123456789012345678901234567890123456789012345678901234567890123456789012345678
- print ""
- print " +-------------------- Space Time Raster Dataset -----------------------------+"
- if self.get_type() == "str3ds":
- # 1 2 3 4 5 6 7
- # 0123456789012345678901234567890123456789012345678901234567890123456789012345678
- print ""
- print " +-------------------- Space Time Raster3d Dataset ---------------------------+"
- if self.get_type() == "stvds":
- # 1 2 3 4 5 6 7
- # 0123456789012345678901234567890123456789012345678901234567890123456789012345678
- print ""
- print " +-------------------- Space Time Vector Dataset -----------------------------+"
- print " | |"
- self.base.print_info()
- if self.is_time_absolute():
- self.absolute_time.print_info()
- if self.is_time_relative():
- self.relative_time.print_info()
- self.spatial_extent.print_info()
- self.metadata.print_info()
- print " +----------------------------------------------------------------------------+"
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- self.base.print_shell_info()
- if self.is_time_absolute():
- self.absolute_time.print_shell_info()
- if self.is_time_relative():
- self.relative_time.print_shell_info()
- self.spatial_extent.print_shell_info()
- self.metadata.print_shell_info()
-
- def set_time_to_absolute(self):
- self.base.set_ttype("absolute")
-
- def set_time_to_relative(self):
- self.base.set_ttype("relative")
-
- def is_time_absolute(self):
- if self.base.D.has_key("temporal_type"):
- return self.base.get_ttype() == "absolute"
- else:
- return None
-
- def is_time_relative(self):
- if self.base.D.has_key("temporal_type"):
- return self.base.get_ttype() == "relative"
- else:
- return None
-
- def temporal_relation(self, map):
- """Return the temporal relation of this and the provided temporal map"""
- if self.is_time_absolute() and map.is_time_absolute():
- return self.absolute_time.temporal_relation(map.absolute_time)
- if self.is_time_relative() and map.is_time_relative():
- return self.relative_time.temporal_relation(map.relative_time)
- return None
-
-###############################################################################
-
-class abstract_map_dataset(abstract_dataset):
- """This is the base class for all maps (raster, vector, raster3d)
- providing additional function to set the valid time and the spatial extent.
- """
-
- def get_new_stds_instance(self, ident):
- """Return a new space time dataset instance in which maps are stored with the type of this class"""
- raise IOError("This method must be implemented in the subclasses")
-
- def get_stds_register(self):
- """Return the space time dataset register table name in which stds are listed in which this map is registered"""
- raise IOError("This method must be implemented in the subclasses")
-
- def set_stds_register(self, name):
- """Set the space time dataset register table name in which stds are listed in which this map is registered"""
- raise IOError("This method must be implemented in the subclasses")
-
- def set_absolute_time(self, start_time, end_time=None, timezone=None):
- """Set the absolute time interval with start time and end time
-
- @start_time a datetime object specifying the start time of the map
- @end_time a datetime object specifying the end time of the map
- @timezone Thee timezone of the map
-
- """
- if start_time != None and not isinstance(start_time, datetime) :
- core.fatal(_("Start time must be of type datetime"))
-
- if end_time != None and not isinstance(end_time, datetime) :
- core.fatal(_("End time must be of type datetime"))
-
- if start_time != None and end_time != None:
- if start_time >= end_time:
- core.error(_("End time must be later than start time"))
- return False
-
- self.base.set_ttype("absolute")
-
- self.absolute_time.set_start_time(start_time)
- self.absolute_time.set_end_time(end_time)
- self.absolute_time.set_timezone(timezone)
-
- return True
-
- def update_absolute_time(self, start_time, end_time=None, timezone=None, dbif = None):
- """Update the absolute time
-
- @start_time a datetime object specifying the start time of the map
- @end_time a datetime object specifying the end time of the map
- @timezone Thee timezone of the map
- """
- connect = False
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- self.set_absolute_time(start_time, end_time, timezone)
- self.absolute_time.update(dbif)
- self.base.update(dbif)
-
- if connect == True:
- dbif.close()
-
- def set_relative_time(self, start_time, end_time=None):
- """Set the relative time interval
-
- @start_time A double value in days
- @end_time A double value in days
-
- """
- if start_time != None and end_time != None:
- if abs(float(start_time)) >= abs(float(end_time)):
- core.error(_("End time must be greater than start time"))
- return False
-
- self.base.set_ttype("relative")
-
- self.relative_time.set_start_time(float(start_time))
- if end_time != None:
- self.relative_time.set_end_time(float(end_time))
- else:
- self.relative_time.set_end_time(None)
-
- return True
-
- def update_relative_time(self, start_time, end_time=None, dbif = None):
- """Set the relative time interval
-
- @interval A double value in days
-
- """
- connect = False
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- self.set_relative_time(start_time, end_time)
- self.relative_time.update(dbif)
- self.base.update(dbif)
-
- if connect == True:
- dbif.close()
-
- def set_spatial_extent(self, north, south, east, west, top=0, bottom=0):
- """Set the spatial extent of the map"""
- self.spatial_extent.set_spatial_extent(north, south, east, west, top, bottom)
-
- def delete(self, dbif=None):
- """Delete a map entry from database if it exists
-
- Remove dependent entries:
- * Remove the map entry in each space time dataset in which this map is registered
- * Remove the space time dataset register table
- """
-
- connect = False
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- if self.is_in_db(dbif):
-
- # First we unregister from all dependent space time datasets
- self.unregister(dbif)
-
- # Remove the strds register table
- if self.get_stds_register():
- sql = "DROP TABLE " + self.get_stds_register()
- #print sql
- try:
- dbif.cursor.execute(sql)
- except:
- core.error("Unable to remove space time dataset register table " + self.get_stds_register())
-
- core.verbose("Delete " + self.get_type() + " dataset <" + self.get_id() + "> from temporal database")
-
- # Delete yourself from the database, trigger functions will take care of dependencies
- self.base.delete(dbif)
-
- self.reset(None)
-
- if connect == True:
- dbif.close()
-
- def unregister(self, dbif=None):
- """ Remove the map entry in each space time dataset in which this map is registered
- """
-
- core.verbose("Unregister " + self.get_type() + " dataset <" + self.get_id() + "> from space time datasets")
-
- connect = False
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- # Get all datasets in which this map is registered
- rows = self.get_registered_datasets(dbif)
-
- # For each stds in which the map is registered
- if rows:
- for row in rows:
- # Create a space time dataset object to remove the map
- # from its register
- stds = self.get_new_stds_instance(row["id"])
- stds.select(dbif)
- stds.unregister_map(self, dbif)
- # Take care to update the space time dataset after
- # the map has been unregistred
- stds.update_from_registered_maps(dbif)
-
- if connect == True:
- dbif.close()
-
- def get_registered_datasets(self, dbif=None):
- """Return all space time dataset ids in which this map is registered as
- sqlite3 rows with column "id" or None if this map is not registered in any
- space time dataset.
- """
- connect = False
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- rows = None
-
- try:
- if self.get_stds_register() != None:
- # Select all stds tables in which this map is registered
- sql = "SELECT id FROM " + self.get_stds_register()
- dbif.cursor.execute(sql)
- rows = dbif.cursor.fetchall()
- except:
- core.error("Unable to select space time dataset register table " + self.get_stds_register())
-
- if connect == True:
- dbif.close()
-
- return rows
-
-###############################################################################
-
-class abstract_space_time_dataset(abstract_dataset):
- """Abstract space time dataset class
-
- This class represents a space time dataset. Convenient functions
- to select, update, insert or delete objects of this type int the SQL
- temporal database exists as well as functions to register or unregister
- raster maps.
-
- Parts of the temporal logic are implemented in the SQL temporal database,
- like the computation of the temporal and spatial extent as well as the
- collecting of metadata.
- """
- def __init__(self, ident):
- self.reset(ident)
-
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- raise IOError("This method must be implemented in the subclasses")
-
- def get_new_map_instance(self, ident):
- """Return a new instance of a map dataset which is associated with the type of this class"""
- raise IOError("This method must be implemented in the subclasses")
-
- def get_map_register(self):
- """Return the name of the map register table"""
- raise IOError("This method must be implemented in the subclasses")
-
- def set_map_register(self, name):
- """Set the name of the map register table"""
- raise IOError("This method must be implemented in the subclasses")
-
- def set_initial_values(self, granularity, temporal_type, semantic_type, \
- title=None, description=None):
-
- if temporal_type == "absolute":
- self.set_time_to_absolute()
- self.absolute_time.set_granularity(granularity)
- elif temporal_type == "relative":
- self.set_time_to_relative()
- self.relative_time.set_granularity(granularity)
- else:
- core.fatal("Unknown temporal type \"" + temporal_type + "\"")
-
- self.base.set_semantic_type(semantic_type)
- self.metadata.set_title(title)
- self.metadata.set_description(description)
-
- def delete(self, dbif=None):
- """Delete a space time dataset from the database"""
- # First we need to check if maps are registered in this dataset and
- # unregister them
-
- core.verbose("Delete space time " + self.get_new_map_instance(ident=None).get_type() + " dataset <" + self.get_id() + "> from temporal database")
-
- connect = False
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- if self.get_map_register():
- sql = "SELECT id FROM " + self.get_map_register()
- try:
- dbif.cursor.execute(sql)
- rows = dbif.cursor.fetchall()
- # Unregister each registered map in the table
- if rows:
- for row in rows:
- # Unregister map
- map = self.get_new_map_instance(row["id"])
- self.unregister_map(map, dbif)
-
- # Drop remove the map register table
- sql = "DROP TABLE " + self.get_map_register()
- dbif.cursor.execute(sql)
- except:
- core.error("Unable to unregister maps from register table <" + self.get_map_register() + ">")
- raise
-
- # Remove the primary key, the foreign keys will be removed by trigger
- self.base.delete(dbif)
- self.reset(None)
-
- if connect == True:
- dbif.close()
-
- def register_map(self, map, dbif=None):
- """Register a map in the space time dataset.
-
- This method takes care of the registration of a map
- in a space time dataset.
-
- In case the map is already registered this function will break with a warning
- and return False
- """
-
- connect = False
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- if map.is_in_db(dbif) == False:
- core.fatal("Only maps with absolute or relative valid time can be registered")
-
- core.verbose("Register " + map.get_type() + " map: " + map.get_id() + " in space time " + map.get_type() + " dataset <" + self.get_id() + ">")
-
- # First select all data from the database
- map.select(dbif)
- map_id = map.base.get_id()
- map_name = map.base.get_name()
- map_mapset = map.base.get_mapset()
- map_register_table = map.get_stds_register()
-
- #print "Map register table", map_register_table
-
- # Get basic info
- stds_name = self.base.get_name()
- stds_mapset = self.base.get_mapset()
- stds_register_table = self.get_map_register()
-
- #print "STDS register table", stds_register_table
-
- if stds_mapset != map_mapset:
- core.fatal("Only maps from the same mapset can be registered")
-
- # Check if map is already registred
- if stds_register_table:
- sql = "SELECT id FROM " + stds_register_table + " WHERE id = (?)"
- dbif.cursor.execute(sql, (map_id,))
- row = dbif.cursor.fetchone()
- # In case of no entry make a new one
- if row and row[0] == map_id:
- core.warning("Map " + map_id + "is already registered.")
- return False
-
- # Create tables
- sql_path = get_sql_template_path()
-
- # We need to create the stmap raster register table bevor we can register the map
- if map_register_table == None:
- # Create a unique id
- uuid_rand = "map_" + str(uuid.uuid4()).replace("-", "")
-
- # Read the SQL template
- sql = open(os.path.join(sql_path, "map_stds_register_table_template.sql"), 'r').read()
- # Create the raster, raster3d and vector tables
- sql = sql.replace("GRASS_MAP", map.get_type())
- sql = sql.replace("MAP_NAME", map_name + "_" + map_mapset )
- sql = sql.replace("TABLE_NAME", uuid_rand )
- sql = sql.replace("MAP_ID", map_id)
- sql = sql.replace("STDS", self.get_type())
- try:
- dbif.cursor.executescript(sql)
- except:
- core.error("Unable to create the space time " + map.get_type() +\
- " dataset register table for " + map.get_type() + " map <" + map.get_id())
- raise
-
- map_register_table = uuid_rand + "_" + self.get_type() + "_register"
- # 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 <" + map_register_table + "> for " + map.get_type() + " map <" + map.get_id() + ">")
-
- # We need to create the table and register it
- if stds_register_table == None:
- # Read the SQL template
- sql = open(os.path.join(sql_path, "stds_map_register_table_template.sql"), 'r').read()
- # Create the raster, raster3d and vector tables
- sql = sql.replace("GRASS_MAP", map.get_type())
- sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
- sql = sql.replace("SPACETIME_ID", self.base.get_id())
- sql = sql.replace("STDS", self.get_type())
-
- sql_script = ""
- #sql_script += "BEGIN TRANSACTION;\n"
- sql_script += sql
- #sql_script += "\n"
- #sql_script += "END TRANSACTION;"
- try:
- dbif.cursor.executescript(sql_script)
- except:
- core.error("Unable to create the " + map.get_type() +\
- " map register table for space time " + map.get_type() + " dataset <" + map.get_id())
- raise
-
- # Trigger have been disabled due to peformance issues while registration
- ## We need raster specific trigger
- #sql = open(os.path.join(sql_path, "stds_" + map.get_type() + "_register_trigger_template.sql"), 'r').read()
- #sql = sql.replace("GRASS_MAP", map.get_type())
- #sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
- #sql = sql.replace("SPACETIME_ID", self.base.get_id())
- #sql = sql.replace("STDS", self.get_type())
-
- #sql_script = ""
- #sql_script += "BEGIN TRANSACTION;\n"
- #sql_script += sql
- #sql_script += "\n"
- #sql_script += "END TRANSACTION;"
-
- #dbif.cursor.executescript(sql_script)
-
- stds_register_table = stds_name + "_" + stds_mapset + "_" + map.get_type() + "_register"
-
- # Set the map register table name and put it into the DB
- self.set_map_register(stds_register_table)
- self.metadata.update(dbif)
-
- core.verbose("Created register table <" + stds_register_table + "> for space time " + map.get_type() + " dataset <" + self.get_id() + ">")
-
- # Register the stds in the map stds register table
- # Check if the entry is already there
- sql = "SELECT id FROM " + map_register_table + " WHERE id = ?"
- dbif.cursor.execute(sql, (self.base.get_id(),))
- row = dbif.cursor.fetchone()
-
- # In case of no entry make a new one
- if row == None:
- sql = "INSERT INTO " + map_register_table + " (id) " + "VALUES (?)"
- #print sql
- dbif.cursor.execute(sql, (self.base.get_id(),))
-
- # Now put the raster name in the stds map register table
- sql = "INSERT INTO " + stds_register_table + " (id) " + "VALUES (?)"
- #print sql
- dbif.cursor.execute(sql, (map_id,))
-
- if connect == True:
- dbif.close()
-
- return True
-
- 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
- from a space time dataset.
- """
- connect = False
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- if map.is_in_db(dbif) == False:
- core.fatal("Unable to find map <" + map.get_id() + "> in temporal database")
-
- core.info("Unregister " + map.get_type() + " map: " + map.get_id())
-
- # First select all data from the database
- map.select(dbif)
- map_id = map.base.get_id()
- map_register_table = map.get_stds_register()
-
- # Get basic info
- stds_register_table = self.get_map_register()
-
- # Check if the map is registered in the space time raster dataset
- sql = "SELECT id FROM " + map_register_table + " WHERE id = ?"
- dbif.cursor.execute(sql, (self.base.get_id(),))
- row = dbif.cursor.fetchone()
-
- # Break if the map is not registered
- if row == None:
- core.warning("Map " + map_id + " is not registered in space time dataset " + self.base.get_id())
- return False
-
- # Remove the space time raster dataset from the raster dataset register
- if map_register_table != None:
- sql = "DELETE FROM " + map_register_table + " WHERE id = ?"
- dbif.cursor.execute(sql, (self.base.get_id(),))
-
- # Remove the raster map from the space time raster dataset register
- if stds_register_table != None:
- sql = "DELETE FROM " + stds_register_table + " WHERE id = ?"
- dbif.cursor.execute(sql, (map_id,))
-
- if connect == True:
- dbif.close()
-
- def update_from_registered_maps(self, dbif = None):
- """This methods updates the spatial and temporal extent as well as
- type specific metadata. It should always been called after maps are registered
- or unregistered/deleted from the space time dataset.
-
- An other solution to automate this is to use the diactivated trigger
- in the SQL files. But this will result in a huge performance issue
- in case many maps are registred (>1000).
- """
- core.info("Update metadata, spatial and temporal extent from all registered maps of <" + self.get_id() + ">")
-
- connect = False
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- # Get basic info
- stds_name = self.base.get_name()
- stds_mapset = self.base.get_mapset()
- sql_path = get_sql_template_path()
-
- #We create a transaction
- sql_script = ""
- sql_script += "BEGIN TRANSACTION;\n"
-
- # Update the spatial and temporal extent from registered maps
- # Read the SQL template
- sql = open(os.path.join(sql_path, "update_stds_spatial_temporal_extent_template.sql"), 'r').read()
- sql = sql.replace("GRASS_MAP", self.get_new_map_instance(None).get_type())
- sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
- sql = sql.replace("SPACETIME_ID", self.base.get_id())
- sql = sql.replace("STDS", self.get_type())
-
- sql_script += sql
- sql_script += "\n"
-
- # Update type specific metadata
- sql = open(os.path.join(sql_path, "update_" + self.get_type() + "_metadata_template.sql"), 'r').read()
- sql = sql.replace("GRASS_MAP", self.get_new_map_instance(None).get_type())
- sql = sql.replace("SPACETIME_NAME", stds_name + "_" + stds_mapset )
- sql = sql.replace("SPACETIME_ID", self.base.get_id())
- sql = sql.replace("STDS", self.get_type())
-
- sql_script += sql
- sql_script += "\n"
-
- sql_script += "END TRANSACTION;"
-
- dbif.cursor.executescript(sql_script)
-
- if connect == True:
- dbif.close()
Deleted: grass/trunk/lib/python/tgis_base.py
===================================================================
--- grass/trunk/lib/python/tgis_base.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_base.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,477 +0,0 @@
-"""!@package grass.script.tgis_base
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-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
-and the sqlite3 database interface.
-
-Usage:
-
- at code
-from grass.script import tgis_core as grass
-
-rbase = grass.raster_base(ident="soil")
-...
- at endcode
-
-(C) 2008-2011 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Soeren Gebbert
-"""
-
-from tgis_core import *
-
-###############################################################################
-
-class dict_sql_serializer(object):
- def __init__(self):
- 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
-
- @type must be SELECT. INSERT, UPDATE
- @table The name of the table to select, insert or update
- @where The optinal where statment
- @return the sql string
- """
-
- sql = ""
- args = []
-
- # Create ordered select statement
- if type == "SELECT":
- sql += 'SELECT '
- count = 0
- for key in self.D.keys():
- if count == 0:
- sql += ' %s ' % key
- else:
- sql += ' , %s ' % key
- count += 1
- sql += ' FROM ' + table + ' '
- if where:
- sql += where
-
- # Create insert statement
- if type =="INSERT":
- count = 0
- sql += 'INSERT INTO ' + table + ' ('
- for key in self.D.keys():
- if count == 0:
- sql += ' %s ' % key
- else:
- sql += ' ,%s ' % key
- count += 1
-
- count = 0
- sql += ') VALUES ('
- for key in self.D.keys():
- if count == 0:
- sql += '?'
- else:
- sql += ',?'
- count += 1
- args.append(self.D[key])
- sql += ') '
-
- if where:
- sql += where
-
- # Create update statement
- if type =="UPDATE":
- count = 0
- sql += 'UPDATE ' + table + ' SET '
- for key in self.D.keys():
- # Update only entries which are not None
- if self.D[key] != None:
- if count == 0:
- sql += ' %s = ? ' % key
- else:
- sql += ' ,%s = ? ' % key
- count += 1
- args.append(self.D[key])
- if where:
- sql += where
-
- return sql, tuple(args)
-
- def deserialize(self, row):
- """Convert the content of the sqlite row into the internal dictionary"""
- self.D = {}
- for key in row.keys():
- self.D[key] = row[key]
-
- def clear(self):
- """Remove all the content of this class"""
- self.D = {}
-
- def print_self(self):
- print self.D
-
- def test(self):
- t = dict_sql_serializer()
- t.D["id"] = "soil at PERMANENT"
- t.D["name"] = "soil"
- t.D["mapset"] = "PERMANENT"
- t.D["creator"] = "soeren"
- t.D["creation_time"] = datetime.now()
- t.D["modification_time"] = datetime.now()
- t.D["revision"] = 1
- sql, values = t.serialize(type="SELECT", table="raster_base")
- print sql, '\n', values
- sql, values = t.serialize(type="INSERT", table="raster_base")
- print sql, '\n', values
- sql, values = t.serialize(type="UPDATE", table="raster_base")
- print sql, '\n', values
-
-###############################################################################
-
-class sql_database_interface(dict_sql_serializer):
- """This is the sql database interface to sqlite3"""
- def __init__(self, table=None, ident=None, database=None):
- dict_sql_serializer.__init__(self)
-
- self.table = table # Name of the table, set in the subclass
- if database == None:
- self.database = get_grass_location_db_path()
- else:
- self.database = database
- self.ident = ident
-
- def get_table_name(self):
- return self.table
-
- def connect(self):
- #print "Connect to", self.database
- self.connection = sqlite3.connect(self.database, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
- self.connection.row_factory = sqlite3.Row
- self.cursor = self.connection.cursor()
-
- def close(self):
- #print "Close connection to", self.database
- self.connection.commit()
- self.cursor.close()
-
- def get_delete_statement(self):
- return "DELETE FROM " + self.get_table_name() + " WHERE id = \"" + str(self.ident) + "\""
-
- def delete(self, dbif=None):
- sql = self.get_delete_statement()
- #print sql
-
- if dbif:
- dbif.cursor.execute(sql)
- else:
- self.connect()
- self.cursor.execute(sql)
- self.close()
-
- def get_is_in_db_statement(self):
- return "SELECT id FROM " + self.get_table_name() + " WHERE id = \"" + str(self.ident) + "\""
-
- def is_in_db(self, dbif=None):
-
- sql = self.get_is_in_db_statement()
- #print sql
-
- if dbif:
- dbif.cursor.execute(sql)
- row = dbif.cursor.fetchone()
- else:
- self.connect()
- self.cursor.execute(sql)
- row = self.cursor.fetchone()
- self.close()
-
- # Nothing found
- if row == None:
- return False
-
- return True
-
- def get_select_statement(self):
- return self.serialize("SELECT", self.get_table_name(), "WHERE id = \"" + str(self.ident) + "\"")
-
- def select(self, dbif=None):
- sql, args = self.get_select_statement()
- #print sql
- #print args
-
- if dbif:
- if len(args) == 0:
- dbif.cursor.execute(sql)
- else:
- dbif.cursor.execute(sql, args)
- row = dbif.cursor.fetchone()
- else:
- self.connect()
- if len(args) == 0:
- self.cursor.execute(sql)
- else:
- self.cursor.execute(sql, args)
- row = self.cursor.fetchone()
- self.close()
-
- # Nothing found
- if row == None:
- return False
-
- if len(row) > 0:
- self.deserialize(row)
- else:
- raise IOError
-
- return True
-
- def get_insert_statement(self):
- return self.serialize("INSERT", self.get_table_name())
-
- def insert(self, dbif=None):
- sql, args = self.get_insert_statement()
- #print sql
- #print args
-
- if dbif:
- dbif.cursor.execute(sql, args)
- else:
- self.connect()
- self.cursor.execute(sql, args)
- self.close()
-
- def get_update_statement(self):
- return self.serialize("UPDATE", self.get_table_name(), "WHERE id = \"" + str(self.ident) + "\"")
-
- def update(self, dbif=None):
- if self.ident == None:
- raise IOError("Missing identifer");
-
- sql, args = self.get_update_statement()
- #print sql
- #print args
-
- if dbif:
- dbif.cursor.execute(sql, args)
- else:
- self.connect()
- self.cursor.execute(sql, args)
- self.close()
-
-###############################################################################
-
-class dataset_base(sql_database_interface):
- """This is the base class for all maps and spacetime datasets storing basic information"""
- def __init__(self, table=None, ident=None, name=None, mapset=None, creator=None, ctime=None,\
- mtime=None, ttype=None, revision=1):
-
- sql_database_interface.__init__(self, table, ident)
-
- self.set_id(ident)
- self.set_name(name)
- self.set_mapset(mapset)
- self.set_creator(creator)
- self.set_ctime(ctime)
- self.set_mtime(mtime)
- self.set_ttype(ttype)
- self.set_revision(revision)
-
- def set_id(self, ident):
- """Convenient method to set the unique identifier (primary key)"""
- self.ident = ident
- self.D["id"] = ident
-
- def set_name(self, name):
- """Set the name of the map"""
- self.D["name"] = name
-
- def set_mapset(self, mapset):
- """Set the mapset of the map"""
- self.D["mapset"] = mapset
-
- def set_creator(self, creator):
- """Set the creator of the map"""
- self.D["creator"] = creator
-
- def set_ctime(self, ctime=None):
- """Set the creation time of the map, if nothing set the current time is used"""
- if ctime == None:
- self.D["creation_time"] = datetime.now()
- else:
- self.D["creation_time"] = ctime
-
- def set_mtime(self, mtime=None):
- """Set the modification time of the map, if nothing set the current time is used"""
- if mtime == None:
- self.D["modification_time"] = datetime.now()
- else:
- self.D["modification_time"] = mtime
-
- def set_ttype(self, ttype):
- """Set the temporal type of the map: absolute or relative, if nothing set absolute time will assumed"""
- if ttype == None or (ttype != "absolute" and ttype != "relative"):
- self.D["temporal_type"] = "absolute"
- else:
- self.D["temporal_type"] = ttype
-
- def set_revision(self, revision=1):
- """Set the revision of the map: if nothing set revision 1 will assumed"""
- self.D["revision"] = revision
-
- def get_id(self):
- """Convenient method to get the unique identifier (primary key)
- @return None if not found
- """
- if self.D.has_key("id"):
- return self.D["id"]
- else:
- return None
-
- def get_name(self):
- """Get the name of the map
- @return None if not found"""
- if self.D.has_key("name"):
- return self.D["name"]
- else:
- return None
-
- def get_mapset(self):
- """Get the mapset of the map
- @return None if not found"""
- if self.D.has_key("mapset"):
- return self.D["mapset"]
- else:
- return None
-
- def get_creator(self):
- """Get the creator of the map
- @return None if not found"""
- if self.D.has_key("creator"):
- return self.D["creator"]
- else:
- return None
-
- def get_ctime(self):
- """Get the creation time of the map, datatype is datetime
- @return None if not found"""
- if self.D.has_key("creation_time"):
- return self.D["creation_time"]
- else:
- return None
-
- def get_mtime(self):
- """Get the modification time of the map, datatype is datetime
- @return None if not found"""
- if self.D.has_key("modification_time"):
- return self.D["modification_time"]
- else:
- return None
-
- def get_ttype(self):
- """Get the temporal type of the map
- @return None if not found"""
- if self.D.has_key("temporal_type"):
- return self.D["temporal_type"]
- else:
- return None
-
- def get_revision(self):
- """Get the revision of the map
- @return None if not found"""
- if self.D.has_key("revision"):
- return self.D["revision"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- # 0123456789012345678901234567890
- print " +-------------------- Basic information -------------------------------------+"
- print " | Id: ........................ " + str(self.get_id())
- print " | Name: ...................... " + str(self.get_name())
- print " | Mapset: .................... " + str(self.get_mapset())
- print " | Creator: ................... " + str(self.get_creator())
- print " | Creation time: ............. " + str(self.get_ctime())
- print " | Modification time: ......... " + str(self.get_mtime())
- print " | Temporal type: ............. " + str(self.get_ttype())
- print " | Revision in database: ...... " + str(self.get_revision())
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- print "id=" + str(self.get_id())
- print "name=" + str(self.get_name())
- print "mapset=" + str(self.get_mapset())
- print "creator=" + str(self.get_creator())
- print "creation_time=" + str(self.get_ctime())
- print "modification_time=" + str(self.get_mtime())
- print "temporal_type=" + str(self.get_ttype())
- print "revision=" + str(self.get_revision())
-
-###############################################################################
-
-class raster_base(dataset_base):
- def __init__(self, ident=None, name=None, mapset=None, creator=None, creation_time=None,\
- modification_time=None, temporal_type=None, revision=1):
- dataset_base.__init__(self, "raster_base", ident, name, mapset, creator, creation_time,\
- modification_time, temporal_type, revision)
-
-class raster3d_base(dataset_base):
- def __init__(self, ident=None, name=None, mapset=None, creator=None, creation_time=None,\
- modification_time=None, temporal_type=None, revision=1):
- dataset_base.__init__(self, "raster3d_base", ident, name, mapset, creator, creation_time,\
- modification_time, temporal_type, revision)
-
-class vector_base(dataset_base):
- def __init__(self, ident=None, name=None, mapset=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)
-
-###############################################################################
-
-class stds_base(dataset_base):
- def __init__(self, table=None, ident=None, name=None, mapset=None, semantic_type=None, creator=None, creation_time=None,\
- modification_time=None, temporal_type=None, revision=1):
- dataset_base.__init__(self, table, ident, name, mapset, creator, creation_time,\
- modification_time, temporal_type, revision)
-
- self.set_semantic_type(semantic_type)
-
- def set_semantic_type(self, semantic_type):
- """Set the semantic type of the space time dataset"""
- self.D["semantic_type"] = semantic_type
-
- def get_semantic_type(self):
- """Get the semantic type of the space time dataset
- @return None if not found"""
- if self.D.has_key("semantic_type"):
- return self.D["semantic_type"]
- else:
- return None
-
-###############################################################################
-
-class strds_base(stds_base):
- def __init__(self, ident=None, name=None, mapset=None, semantic_type=None, creator=None, creation_time=None,\
- modification_time=None, temporal_type=None, revision=1):
- stds_base.__init__(self, "strds_base", ident, name, mapset, semantic_type, creator, creation_time,\
- modification_time, temporal_type, revision)
-
-class str3ds_base(stds_base):
- def __init__(self, ident=None, name=None, mapset=None, semantic_type=None, creator=None, creation_time=None,\
- modification_time=None, temporal_type=None, revision=1):
- stds_base.__init__(self, "str3ds_base", ident, name, mapset, semantic_type, creator, creation_time,\
- modification_time, temporal_type, revision)
-
-class stvds_base(stds_base):
- def __init__(self, ident=None, name=None, mapset=None, semantic_type=None, creator=None, creation_time=None,\
- modification_time=None, temporal_type=None, revision=1):
- stds_base.__init__(self, "stvds_base", ident, name, mapset, semantic_type, creator, creation_time,\
- modification_time, temporal_type, revision)
-
Deleted: grass/trunk/lib/python/tgis_core.py
===================================================================
--- grass/trunk/lib/python/tgis_core.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_core.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,216 +0,0 @@
-"""!@package grass.script.tgis_core
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS core functions to be used in Python sripts.
-
-Usage:
-
- at code
-from grass.script import tgis_core as grass
-
-grass.create_temporal_database()
-...
- at endcode
-
-(C) 2008-2011 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Soeren Gebbert
-"""
-import os
-import sqlite3
-import core
-import copy
-from datetime import datetime, date, time, timedelta
-
-###############################################################################
-
-def get_grass_location_db_path():
- grassenv = core.gisenv()
- dbpath = os.path.join(grassenv["GISDBASE"], grassenv["LOCATION_NAME"])
- return os.path.join(dbpath, "grass.db")
-
-###############################################################################
-
-def get_sql_template_path():
- base = os.getenv("GISBASE")
- base_etc = os.path.join(base, "etc")
- return os.path.join(base_etc, "sql")
-
-def test_increment_datetime_by_string():
-
- dt = datetime(2001, 9, 1, 0, 0, 0)
- string = "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
-
- dt1 = datetime(2003,2,18,12,5,0)
- dt2 = increment_datetime_by_string(dt, string)
-
- delta = dt1 -dt2
-
- if delta.days != 0 or delta.seconds != 0:
- core.fatal("increment computation is wrong")
-
-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.
-
- @mydate A datetime object to incremented
- @increment A string providing increment information:
- The string may include comma separated values of type seconds, minutes, hours, days, weeks, months and years
- Example: Increment the datetime 2001-01-01 00:00:00 with "60 seconds, 4 minutes, 12 hours, 10 days, 1 weeks, 5 months, 1 years"
- will result in the datetime 2003-02-18 12:05:00
- @mult A multiplier, default is 1
- """
-
- if increment:
-
- seconds = 0
- minutes = 0
- hours = 0
- days = 0
- weeks = 0
- months = 0
- years = 0
-
- inclist = []
- # Split the increment string
- incparts = increment.split(",")
- for incpart in incparts:
- inclist.append(incpart.strip().split(" "))
-
- for inc in inclist:
- if inc[1].find("seconds") >= 0:
- seconds = mult * int(inc[0])
- elif inc[1].find("minutes") >= 0:
- minutes = mult * int(inc[0])
- elif inc[1].find("hours") >= 0:
- hours = mult * int(inc[0])
- elif inc[1].find("days") >= 0:
- days = mult * int(inc[0])
- elif inc[1].find("weeks") >= 0:
- weeks = mult * int(inc[0])
- elif inc[1].find("months") >= 0:
- months = mult * int(inc[0])
- elif inc[1].find("years") >= 0:
- years = mult * int(inc[0])
- else:
- core.fatal("Wrong increment format: " + increment)
-
- return increment_datetime(mydate, years, months, weeks, days, hours, minutes, seconds)
-
- return mydate
-
-###############################################################################
-
-def increment_datetime(mydate, years=0, months=0, weeks=0, days=0, hours=0, minutes=0, seconds=0):
- """Return a new datetime object incremented with the provided relative dates and times"""
-
- tdelta_seconds = timedelta(seconds=seconds)
- tdelta_minutes = timedelta(minutes=minutes)
- tdelta_hours = timedelta(hours=hours)
- tdelta_days = timedelta(days=days)
- tdelta_weeks = timedelta(weeks=weeks)
- tdelta_months = timedelta(0)
- tdelta_years = timedelta(0)
-
- if months > 0:
- # Compute the actual number of days in the month to add as timedelta
- year = mydate.year
- month = mydate.month
-
- all_months = int(months + month)
-
- years_to_add = int(all_months/12)
- residual_months = all_months%12
-
- # Make a deep copy of the datetime object
- dt1 = copy.copy(mydate)
-
- # Make sure the montha starts with a 1
- if residual_months == 0:
- residual_months = 1
-
- dt1 = dt1.replace(year = year + years_to_add, month = residual_months)
- tdelta_months = dt1 - mydate
-
- if years > 0:
- # Make a deep copy of the datetime object
- dt1 = copy.copy(mydate)
- # Compute the number of days
- dt1 = dt1.replace(year=mydate.year + int(years))
- tdelta_years = dt1 - mydate
-
- return mydate + tdelta_seconds + tdelta_minutes + tdelta_hours + \
- tdelta_days + tdelta_weeks + tdelta_months + tdelta_years
-
-###############################################################################
-
-def create_temporal_database():
- """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"""
-
- database = get_grass_location_db_path()
-
- # Check if it already exists
- if os.path.exists(database):
- return False
-
- # Read all SQL scripts and templates
- map_tables_template_sql = open(os.path.join(get_sql_template_path(), "map_tables_template.sql"), 'r').read()
- raster_metadata_sql = open(os.path.join(get_sql_template_path(), "raster_metadata_table.sql"), 'r').read()
- raster3d_metadata_sql = open(os.path.join(get_sql_template_path(), "raster3d_metadata_table.sql"), 'r').read()
- vector_metadata_sql = open(os.path.join(get_sql_template_path(), "vector_metadata_table.sql"), 'r').read()
- stds_tables_template_sql = open(os.path.join(get_sql_template_path(), "stds_tables_template.sql"), 'r').read()
- strds_metadata_sql = open(os.path.join(get_sql_template_path(), "strds_metadata_table.sql"), 'r').read()
- str3ds_metadata_sql = open(os.path.join(get_sql_template_path(), "str3ds_metadata_table.sql"), 'r').read()
- stvds_metadata_sql = open(os.path.join(get_sql_template_path(), "stvds_metadata_table.sql"), 'r').read()
-
- # Create the raster, raster3d and vector tables
- raster_tables_sql = map_tables_template_sql.replace("GRASS_MAP", "raster")
- vector_tables_sql = map_tables_template_sql.replace("GRASS_MAP", "vector")
- raster3d_tables_sql = map_tables_template_sql.replace("GRASS_MAP", "raster3d")
-
- # Create the space-time raster, raster3d and vector dataset tables
- strds_tables_sql = stds_tables_template_sql.replace("STDS", "strds")
- stvds_tables_sql = stds_tables_template_sql.replace("STDS", "stvds")
- str3ds_tables_sql = stds_tables_template_sql.replace("STDS", "str3ds")
-
- # Check for completion
- sqlite3.complete_statement(raster_tables_sql)
- sqlite3.complete_statement(vector_tables_sql)
- sqlite3.complete_statement(raster3d_tables_sql)
- sqlite3.complete_statement(raster_metadata_sql)
- sqlite3.complete_statement(vector_metadata_sql)
- sqlite3.complete_statement(raster3d_metadata_sql)
- sqlite3.complete_statement(strds_tables_sql)
- sqlite3.complete_statement(stvds_tables_sql)
- sqlite3.complete_statement(str3ds_tables_sql)
- sqlite3.complete_statement(strds_metadata_sql)
- sqlite3.complete_statement(stvds_metadata_sql)
- sqlite3.complete_statement(str3ds_metadata_sql)
-
- # Connect to database
- connection = sqlite3.connect(database)
- cursor = connection.cursor()
-
- # Execute the SQL statements
- # Create the global tables for the native grass datatypes
- cursor.executescript(raster_tables_sql)
- cursor.executescript(raster_metadata_sql)
- cursor.executescript(vector_tables_sql)
- cursor.executescript(vector_metadata_sql)
- cursor.executescript(raster3d_tables_sql)
- cursor.executescript(raster3d_metadata_sql)
- # Create the tables for the new space-time datatypes
- cursor.executescript(strds_tables_sql)
- cursor.executescript(strds_metadata_sql)
- cursor.executescript(stvds_tables_sql)
- cursor.executescript(stvds_metadata_sql)
- cursor.executescript(str3ds_tables_sql)
- cursor.executescript(str3ds_metadata_sql)
-
- connection.commit()
- cursor.close()
Deleted: grass/trunk/lib/python/tgis_metadata.py
===================================================================
--- grass/trunk/lib/python/tgis_metadata.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_metadata.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,640 +0,0 @@
-"""!@package grass.script.tgis_metadata
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related metadata functions to be used in Python scripts and tgis packages.
-
-Usage:
-
- at code
-from grass.script import tgis_metadata as grass
-
-meta = grass.raster_metadata()
-...
- at endcode
-
-(C) 2008-2011 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Soeren Gebbert
-"""
-from tgis_base import *
-
-###############################################################################
-
-class raster_metadata_base(sql_database_interface):
- """This is the raster metadata base class for raster and raster3d maps"""
- def __init__(self, table=None, ident=None, datatype=None, cols=None, rows=None, number_of_cells=None, nsres=None, ewres=None, min=None, max=None):
-
- sql_database_interface.__init__(self, table, ident)
-
- self.set_id(ident)
- self.set_datatype(datatype)
- self.set_cols(cols)
- self.set_rows(rows)
- self.set_number_of_cells(number_of_cells)
- self.set_nsres(nsres)
- self.set_ewres(ewres)
- self.set_min(min)
- self.set_max(max)
-
- def set_id(self, ident):
- """Convenient method to set the unique identifier (primary key)"""
- self.ident = ident
- self.D["id"] = ident
-
- def set_datatype(self, datatype):
- """Set the datatype"""
- self.D["datatype"] = datatype
-
- def set_cols(self, cols):
- """Set the number of cols"""
- self.D["cols"] = cols
-
- def set_rows(self, rows):
- """Set the number of rows"""
- self.D["rows"] = rows
-
- def set_number_of_cells(self, number_of_cells):
- """Set the number of cells"""
- self.D["number_of_cells"] = number_of_cells
-
- def set_nsres(self, nsres):
- """Set the north-south resolution"""
- self.D["nsres"] = nsres
-
- def set_ewres(self, ewres):
- """Set the east-west resolution"""
- self.D["ewres"] = ewres
-
- def set_min(self, min):
- """Set the minimum raster value"""
- self.D["min"] = min
-
- def set_max(self, max):
- """Set the maximum raster value"""
- self.D["max"] = max
-
- def get_id(self):
- """Convenient method to get the unique identifier (primary key)
- @return None if not found
- """
- if self.D.has_key("id"):
- return self.D["id"]
- else:
- return None
-
- def get_datatype(self):
- """Get the map type
- @return None if not found"""
- if self.D.has_key("datatype"):
- return self.D["datatype"]
- else:
- return None
-
- def get_cols(self):
- """Get number of cols
- @return None if not found"""
- if self.D.has_key("cols"):
- return self.D["cols"]
- else:
- return None
-
- def get_rows(self):
- """Get number of rows
- @return None if not found"""
- if self.D.has_key("rows"):
- return self.D["rows"]
- else:
- return None
-
- def get_number_of_cells(self):
- """Get number of cells
- @return None if not found"""
- if self.D.has_key("number_of_cells"):
- return self.D["number_of_cells"]
- else:
- return None
-
- def get_nsres(self):
- """Get the north-south resolution
- @return None if not found"""
- if self.D.has_key("nsres"):
- return self.D["nsres"]
- else:
- return None
-
- def get_ewres(self):
- """Get east-west resolution
- @return None if not found"""
- if self.D.has_key("ewres"):
- return self.D["ewres"]
- else:
- return None
-
- def get_min(self):
- """Get the minimum cell value
- @return None if not found"""
- if self.D.has_key("min"):
- return self.D["min"]
- else:
- return None
-
- def get_max(self):
- """Get the maximum cell value
- @return None if not found"""
- if self.D.has_key("max"):
- return self.D["max"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- # 0123456789012345678901234567890
- print " | Datatype:................... " + str(self.get_datatype())
- print " | Number of columns:.......... " + str(self.get_cols())
- print " | Number of rows:............. " + str(self.get_rows())
- print " | Number of cells:............ " + str(self.get_number_of_cells())
- print " | North-South resolution:..... " + str(self.get_nsres())
- print " | East-west resolution:....... " + str(self.get_ewres())
- print " | Minimum value:.............. " + str(self.get_min())
- print " | Maximum value:.............. " + str(self.get_max())
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- print "datatype=" + str(self.get_datatype())
- print "cols=" + str(self.get_cols())
- print "rows=" + str(self.get_rows())
- print "number_of_cells=" + str(self.get_number_of_cells())
- print "nsres=" + str(self.get_nsres())
- print "ewres=" + str(self.get_ewres())
- print "min=" + str(self.get_min())
- print "max=" + str(self.get_max())
-
-###############################################################################
-
-class raster_metadata(raster_metadata_base):
- """This is the raster metadata class"""
- def __init__(self, ident=None, strds_register=None, datatype=None, cols=None, rows=None, number_of_cells=None, nsres=None, ewres=None, min=None, max=None):
-
- raster_metadata_base.__init__(self, "raster_metadata", ident, datatype, cols, rows, number_of_cells, nsres, ewres, min, max)
-
- self.set_strds_register(strds_register)
-
- def set_strds_register(self, strds_register):
- """Set the space time raster dataset register table name"""
- self.D["strds_register"] = strds_register
-
- def get_strds_register(self):
- """Get the space time raster dataset register table name
- @return None if not found"""
- if self.D.has_key("strds_register"):
- return self.D["strds_register"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- print " +-------------------- Metadata information ----------------------------------+"
- # 0123456789012345678901234567890
- print " | STRDS register table ....... " + str(self.get_strds_register())
- raster_metadata_base.print_info(self)
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- raster_metadata_base.print_shell_info(self)
-
-###############################################################################
-
-class raster3d_metadata(raster_metadata_base):
- """This is the raster3d metadata class"""
- def __init__(self, ident=None, str3ds_register=None, datatype=None, cols=None, rows=None, depths=None, number_of_cells=None, nsres=None, ewres=None, tbres=None, min=None, max=None):
-
- raster_metadata_base.__init__(self, "raster3d_metadata", ident, datatype, cols, rows, number_of_cells, nsres, ewres, min, max)
-
- self.set_str3ds_register(str3ds_register)
- self.set_tbres(tbres)
- self.set_depths(depths)
-
- def set_str3ds_register(self, str3ds_register):
- """Set the space time raster3d dataset register table name"""
- self.D["str3ds_register"] = str3ds_register
-
- def set_depths(self, depths):
- """Set the number of depths"""
- self.D["depths"] = depths
-
- def set_tbres(self, tbres):
- """Set the top-bottom resolution"""
- self.D["tbres"] = tbres
-
- def get_str3ds_register(self):
- """Get the space time raster3d dataset register table name
- @return None if not found"""
- if self.D.has_key("str3ds_register"):
- return self.D["str3ds_register"]
- else:
- return None
-
- def get_depths(self):
- """Get number of depths
- @return None if not found"""
- if self.D.has_key("depths"):
- return self.D["depths"]
- else:
- return None
-
- def get_tbres(self):
- """Get top-bottom resolution
- @return None if not found"""
- if self.D.has_key("tbres"):
- return self.D["tbres"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- print " +-------------------- Metadata information ----------------------------------+"
- # 0123456789012345678901234567890
- print " | STR3DS register table ...... " + str(self.get_str3ds_register())
- raster_metadata_base.print_info(self)
- # 0123456789012345678901234567890
- print " | Number of depths:........... " + str(self.get_depths())
- print " | Top-Bottom resolution:...... " + str(self.get_tbres())
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- raster_metadata_base.print_shell_info(self)
- print "depths=" + str(self.get_depths())
- print "tbres=" + str(self.get_tbres())
-
-###############################################################################
-
-class vector_metadata(sql_database_interface):
- """This is the vector metadata class"""
- def __init__(self, ident=None, stvds_register=None):
-
- sql_database_interface.__init__(self, "vector_metadata", ident)
-
- self.set_id(ident)
- self.set_stvds_register(stvds_register)
-
- def set_id(self, ident):
- """Convenient method to set the unique identifier (primary key)"""
- self.ident = ident
- self.D["id"] = ident
-
- def set_stvds_register(self, stvds_register):
- """Set the space time vector dataset register table name"""
- self.D["stvds_register"] = stvds_register
-
- def get_id(self):
- """Convenient method to get the unique identifier (primary key)
- @return None if not found
- """
- if self.D.has_key("id"):
- return self.D["id"]
- else:
- return None
-
- def get_stvds_register(self):
- """Get the space time vector dataset register table name
- @return None if not found"""
- if self.D.has_key("stvds_register"):
- return self.D["stvds_register"]
- else:
- return None
-
-
- def print_info(self):
- """Print information about this class in human readable style"""
- # 0123456789012345678901234567890
- print " +-------------------- Metadata information ----------------------------------+"
- print " | STVDS register table ....... " + str(self.get_stvds_register())
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- print "stvds_register=" + str(self.get_stvds_register())
-
-###############################################################################
-
-class stds_metadata_base(sql_database_interface):
- """This is the space time dataset metadata base class for strds, stvds and str3ds datasets
- setting/getting the id, the title and the description
- """
- def __init__(self, table=None, ident=None, title=None, description=None):
-
- sql_database_interface.__init__(self, table, ident)
-
- self.set_id(ident)
- self.set_title(title)
- self.set_description(description)
- # No setter for this
- self.D["number_of_maps"] = None
-
- def set_id(self, ident):
- """Convenient method to set the unique identifier (primary key)"""
- self.ident = ident
- self.D["id"] = ident
-
- def set_title(self, title):
- """Set the title"""
- self.D["title"] = title
-
- def set_description(self, description):
- """Set the number of cols"""
- self.D["description"] = description
-
- def get_id(self):
- """Convenient method to get the unique identifier (primary key)
- @return None if not found
- """
- if self.D.has_key("id"):
- return self.D["id"]
- else:
- return None
-
- def get_title(self):
- """Get the title
- @return None if not found"""
- if self.D.has_key("title"):
- return self.D["title"]
- else:
- return None
-
- def get_description(self):
- """Get description
- @return None if not found"""
- if self.D.has_key("description"):
- return self.D["description"]
- else:
- return None
-
- def get_number_of_maps(self):
- """Get the number of registered maps, this value is set in the database
- automatically via SQL trigger, so no setter exists
- @return None if not found"""
- if self.D.has_key("number_of_maps"):
- return self.D["number_of_maps"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- # 0123456789012345678901234567890
- print " | Number of registered maps:.. " + str(self.get_number_of_maps())
- print " | Title:"
- print " | " + str(self.get_title())
- print " | Description:"
- print " | " + str(self.get_description())
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- print "number_of_maps=" + str(self.get_number_of_maps())
-
-###############################################################################
-
-class stds_raster_metadata_base(stds_metadata_base):
- """This is the space time dataset metadata base class for strds and str3ds datasets
-
- Most of the metadata values are set by triggers in the database when
- new raster of voxel maps are added. Therefor only some set- an many get-functions
- are available.
- """
- def __init__(self, table=None, ident=None, title=None, description=None):
-
- stds_metadata_base.__init__(self, table, ident, title, description)
-
- # Initialize the dict to select all values from the db
- self.D["min_max"] = None
- self.D["max_max"] = None
- self.D["min_min"] = None
- self.D["max_min"] = None
- self.D["nsres_min"] = None
- self.D["nsres_max"] = None
- self.D["ewres_min"] = None
- self.D["ewres_max"] = None
-
- def get_max_min(self):
- """Get the minimal maximum of all registered maps, this value is set in the database
- automatically via SQL trigger, so no setter exists
- @return None if not found"""
- if self.D.has_key("max_min"):
- return self.D["max_min"]
- else:
- return None
-
- def get_min_min(self):
- """Get the minimal minimum of all registered maps, this value is set in the database
- automatically via SQL trigger, so no setter exists
- @return None if not found"""
- if self.D.has_key("min_min"):
- return self.D["min_min"]
- else:
- return None
-
- def get_max_max(self):
- """Get the maximal maximum of all registered maps, this value is set in the database
- automatically via SQL trigger, so no setter exists
- @return None if not found"""
- if self.D.has_key("max_max"):
- return self.D["max_max"]
- else:
- return None
-
- def get_min_max(self):
- """Get the maximal minimum of all registered maps, this value is set in the database
- automatically via SQL trigger, so no setter exists
- @return None if not found"""
- if self.D.has_key("min_max"):
- return self.D["min_max"]
- else:
- return None
-
- def get_nsres_min(self):
- """Get the minimal north-south resolution of all registered maps, this value is set in the database
- automatically via SQL trigger, so no setter exists
- @return None if not found"""
- if self.D.has_key("nsres_min"):
- return self.D["nsres_min"]
- else:
- return None
-
- def get_nsres_max(self):
- """Get the maximal north-south resolution of all registered maps, this value is set in the database
- automatically via SQL trigger, so no setter exists
- @return None if not found"""
- if self.D.has_key("nsres_max"):
- return self.D["nsres_max"]
- else:
- return None
-
- def get_ewres_min(self):
- """Get the minimal east-west resolution of all registered maps, this value is set in the database
- automatically via SQL trigger, so no setter exists
- @return None if not found"""
- if self.D.has_key("ewres_min"):
- return self.D["ewres_min"]
- else:
- return None
-
- def get_ewres_max(self):
- """Get the maximal east-west resolution of all registered maps, this value is set in the database
- automatically via SQL trigger, so no setter exists
- @return None if not found"""
- if self.D.has_key("ewres_max"):
- return self.D["ewres_max"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- stds_metadata_base.print_info(self)
- # 0123456789012345678901234567890
- print " | North-South resolution min:. " + str(self.get_nsres_min())
- print " | North-South resolution max:. " + str(self.get_nsres_max())
- print " | East-west resolution min:... " + str(self.get_ewres_min())
- print " | East-west resolution max:... " + str(self.get_ewres_max())
- print " | Minimum value min:.......... " + str(self.get_min_min())
- print " | Minimum value max:.......... " + str(self.get_min_max())
- print " | Maximum value min:.......... " + str(self.get_max_min())
- print " | Maximum value max:.......... " + str(self.get_max_max())
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- stds_metadata_base.print_shell_info(self)
- print "nsres_min=" + str(self.get_nsres_min())
- print "nsres_max=" + str(self.get_nsres_max())
- print "ewres_min=" + str(self.get_ewres_min())
- print "ewres_max=" + str(self.get_ewres_max())
- print "min_min=" + str(self.get_min_min())
- print "min_max=" + str(self.get_min_max())
- print "max_min=" + str(self.get_max_min())
- print "max_max=" + str(self.get_max_max())
-
-
-###############################################################################
-
-class strds_metadata(stds_raster_metadata_base):
- """This is the raster metadata class"""
- def __init__(self, ident=None, raster_register=None, title=None, description=None):
-
- stds_raster_metadata_base.__init__(self, "strds_metadata", ident, title, description)
-
- self.set_raster_register(raster_register)
-
- def set_raster_register(self, raster_register):
- """Set the raster map register table name"""
- self.D["raster_register"] = raster_register
-
- def get_raster_register(self):
- """Get the raster map register table name
- @return None if not found"""
- if self.D.has_key("raster_register"):
- return self.D["raster_register"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- print " +-------------------- Metadata information ----------------------------------+"
- # 0123456789012345678901234567890
- print " | Raster register table:...... " + str(self.get_raster_register())
- stds_raster_metadata_base.print_info(self)
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- stds_raster_metadata_base.print_shell_info(self)
-
-###############################################################################
-
-class str3ds_metadata(stds_raster_metadata_base):
- """This is the space time raster3d metadata class"""
- def __init__(self, ident=None, raster3d_register=None, title=None, description=None):
-
- stds_raster_metadata_base.__init__(self, "str3ds_metadata", ident, title, description)
-
- self.set_raster3d_register(raster3d_register)
- self.D["tbres_min"] = None
- self.D["tbres_max"] = None
-
- def set_raster3d_register(self, raster3d_register):
- """Set the raster map register table name"""
- self.D["raster3d_register"] = raster3d_register
-
- def get_raster3d_register(self):
- """Get the raster3d map register table name
- @return None if not found"""
- if self.D.has_key("raster3d_register"):
- return self.D["raster3d_register"]
- else:
- return None
-
- def get_tbres_min(self):
- """Get the minimal top-bottom resolution of all registered maps, this value is set in the database
- automatically via SQL trigger, so no setter exists
- @return None if not found"""
- if self.D.has_key("tbres_min"):
- return self.D["tbres_min"]
- else:
- return None
-
- def get_tbres_max(self):
- """Get the maximal top-bottom resolution of all registered maps, this value is set in the database
- automatically via SQL trigger, so no setter exists
- @return None if not found"""
- if self.D.has_key("tbres_max"):
- return self.D["tbres_max"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- print " +-------------------- Metadata information ----------------------------------+"
- # 0123456789012345678901234567890
- print " | Raster3d register table:.... " + str(self.get_raster3d_register())
- stds_raster_metadata_base.print_info(self)
- # 0123456789012345678901234567890
- print " | Top-bottom resolution min:.. " + str(self.get_ewres_min())
- print " | Top-bottom resolution max:.. " + str(self.get_ewres_max())
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- stds_raster_metadata_base.print_shell_info(self)
- print "tbres_min=" + str(self.get_tbres_min())
- print "tbres_max=" + str(self.get_tbres_max())
-
-###############################################################################
-
-class stvds_metadata(stds_metadata_base):
- """This is the raster metadata class"""
- def __init__(self, ident=None, vector_register=None, title=None, description=None):
-
- stds_metadata_base.__init__(self, "stvds_metadata", ident, title, description)
-
- self.set_vector_register(vector_register)
-
- def set_vector_register(self, vector_register):
- """Set the vector map register table name"""
- self.D["vector_register"] = vector_register
-
- def get_vector_register(self):
- """Get the vector map register table name
- @return None if not found"""
- if self.D.has_key("vector_register"):
- return self.D["vector_register"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- print " +-------------------- Metadata information ----------------------------------+"
- # 0123456789012345678901234567890
- print " | Vector register table:...... " + str(self.get_vector_register())
- stds_metadata_base.print_info(self)
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- stds_metadata_base.print_shell_info(self)
Deleted: grass/trunk/lib/python/tgis_space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/tgis_space_time_datasets.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_space_time_datasets.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,687 +0,0 @@
-"""!@package grass.script.tgis_space_time_dataset
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related functions to be used in Python scripts.
-
-Usage:
-
- at code
-from grass.script import tgis_space_time_dataset as grass
-
-strds = grass.space_time_raster_dataset("soils_1950_2010")
-
-...
- at endcode
-
-(C) 2008-2011 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Soeren Gebbert
-"""
-import getpass
-import raster
-import vector
-import raster3d
-from tgis_abstract_datasets import *
-
-
-###############################################################################
-
-class raster_dataset(abstract_map_dataset):
- """Raster dataset class
-
- This class provides functions to select, update, insert or delete raster
- map informations and valid time stamps into the SQL temporal database.
- """
- def __init__(self, ident):
- self.reset(ident)
-
- def get_type(self):
- return "raster"
-
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- return raster_dataset(ident)
-
- def get_new_stds_instance(self, ident):
- """Return a new space time dataset instance in which maps are stored with the type of this class"""
- return space_time_raster_dataset(ident)
-
- def get_stds_register(self):
- """Return the space time dataset register table name in which stds are listed in which this map is registered"""
- return self.metadata.get_strds_register()
-
- def set_stds_register(self, name):
- """Set the space time dataset register table name in which stds are listed in which this map is registered"""
- self.metadata.set_strds_register(name)
-
- def reset(self, ident):
- """Reset the internal structure and set the identifier"""
- self.ident = ident
-
- self.base = raster_base(ident=ident)
- self.absolute_time = raster_absolute_time(ident=ident)
- self.relative_time = raster_relative_time(ident=ident)
- self.spatial_extent = raster_spatial_extent(ident=ident)
- self.metadata = raster_metadata(ident=ident)
-
- def load(self):
- """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)
-
- # Fill base information
-
- self.base.set_name(self.ident.split("@")[0])
- self.base.set_mapset(self.ident.split("@")[1])
- self.base.set_creator(str(getpass.getuser()))
-
- # Fill spatial extent
-
- self.set_spatial_extent(north=kvp["north"], south=kvp["south"], \
- east=kvp["east"], west=kvp["west"])
-
- # Fill metadata
-
- self.metadata.set_nsres(kvp["nsres"])
- self.metadata.set_ewres(kvp["ewres"])
- self.metadata.set_datatype(kvp["datatype"])
- self.metadata.set_min(kvp["min"])
- self.metadata.set_max(kvp["max"])
-
- rows = int((kvp["north"] - kvp["south"])/kvp["nsres"] + 0.5)
- cols = int((kvp["east"] - kvp["west"])/kvp["ewres"] + 0.5)
-
- ncells = cols * rows
-
- self.metadata.set_cols(cols)
- self.metadata.set_rows(rows)
- self.metadata.set_number_of_cells(ncells)
-
-###############################################################################
-
-class raster3d_dataset(abstract_map_dataset):
- """Raster3d dataset class
-
- This class provides functions to select, update, insert or delete raster3d
- map informations and valid time stamps into the SQL temporal database.
- """
- def __init__(self, ident):
- self.reset(ident)
-
- def get_type(self):
- return "raster3d"
-
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- return raster3d_dataset(ident)
-
- def get_new_stds_instance(self, ident):
- """Return a new space time dataset instance in which maps are stored with the type of this class"""
- return space_time_raster3d_dataset(ident)
-
- def get_stds_register(self):
- """Return the space time dataset register table name in which stds are listed in which this map is registered"""
- return self.metadata.get_str3ds_register()
-
- def set_stds_register(self, name):
- """Set the space time dataset register table name in which stds are listed in which this map is registered"""
- self.metadata.set_str3ds_register(name)
-
- def reset(self, ident):
- """Reset the internal structure and set the identifier"""
- self.ident = ident
-
- self.base = raster3d_base(ident=ident)
- self.absolute_time = raster3d_absolute_time(ident=ident)
- self.relative_time = raster3d_relative_time(ident=ident)
- self.spatial_extent = raster3d_spatial_extent(ident=ident)
- self.metadata = raster3d_metadata(ident=ident)
-
- def load(self):
- """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)
-
- # Fill base information
-
- self.base.set_name(self.ident.split("@")[0])
- self.base.set_mapset(self.ident.split("@")[1])
- self.base.set_creator(str(getpass.getuser()))
-
- # Fill spatial extent
-
- self.set_spatial_extent(north=kvp["north"], south=kvp["south"], \
- east=kvp["east"], west=kvp["west"],\
- top=kvp["top"], bottom=kvp["bottom"])
-
- # Fill metadata
-
- self.metadata.set_nsres(kvp["nsres"])
- self.metadata.set_ewres(kvp["ewres"])
- self.metadata.set_tbres(kvp["tbres"])
- self.metadata.set_datatype(kvp["datatype"])
- self.metadata.set_min(kvp["min"])
- self.metadata.set_max(kvp["max"])
-
- rows = int((kvp["north"] - kvp["south"])/kvp["nsres"] + 0.5)
- cols = int((kvp["east"] - kvp["west"])/kvp["ewres"] + 0.5)
- depths = int((kvp["top"] - kvp["bottom"])/kvp["tbres"] + 0.5)
-
- ncells = cols * rows * depths
-
- self.metadata.set_cols(cols)
- self.metadata.set_rows(rows)
- self.metadata.set_depths(depths)
- self.metadata.set_number_of_cells(ncells)
-
-###############################################################################
-
-class vector_dataset(abstract_map_dataset):
- """Vector dataset class
-
- This class provides functions to select, update, insert or delete vector
- map informations and valid time stamps into the SQL temporal database.
- """
- def __init__(self, ident):
- self.reset(ident)
-
- def get_type(self):
- return "vector"
-
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- return vector_dataset(ident)
-
- def get_new_stds_instance(self, ident):
- """Return a new space time dataset instance in which maps are stored with the type of this class"""
- return space_time_vector_dataset(ident)
-
- def get_stds_register(self):
- """Return the space time dataset register table name in which stds are listed in which this map is registered"""
- return self.metadata.get_stvds_register()
-
- def set_stds_register(self, name):
- """Set the space time dataset register table name in which stds are listed in which this map is registered"""
- self.metadata.set_stvds_register(name)
-
- def reset(self, ident):
- """Reset the internal structure and set the identifier"""
- self.ident = ident
-
- self.base = vector_base(ident=ident)
- self.absolute_time = vector_absolute_time(ident=ident)
- self.relative_time = vector_relative_time(ident=ident)
- self.spatial_extent = vector_spatial_extent(ident=ident)
- self.metadata = vector_metadata(ident=ident)
-
- def load(self):
- """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)
-
- # Fill base information
-
- self.base.set_name(self.ident.split("@")[0])
- self.base.set_mapset(self.ident.split("@")[1])
- self.base.set_creator(str(getpass.getuser()))
-
- # Fill spatial extent
-
- self.set_spatial_extent(north=kvp["north"], south=kvp["south"], \
- east=kvp["east"], west=kvp["west"],\
- top=kvp["top"], bottom=kvp["bottom"])
-
- # Fill metadata .. no metadata yet
-
-###############################################################################
-
-class space_time_raster_dataset(abstract_space_time_dataset):
- """Space time raster dataset class
- """
- def __init__(self, ident):
- abstract_space_time_dataset.__init__(self, ident)
-
- def get_type(self):
- return "strds"
-
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- return space_time_raster_dataset(ident)
-
- def get_new_map_instance(self, ident):
- """Return a new instance of a map dataset which is associated with the type of this class"""
- return raster_dataset(ident)
-
- def get_map_register(self):
- """Return the name of the map register table"""
- return self.metadata.get_raster_register()
-
- def set_map_register(self, name):
- """Set the name of the map register table"""
- self.metadata.set_raster_register(name)
-
- def reset(self, ident):
-
- """Reset the internal structure and set the identifier"""
- self.ident = ident
-
- self.base = strds_base(ident=ident)
-
- if ident != None:
- self.base.set_name(self.ident.split("@")[0])
- self.base.set_mapset(self.ident.split("@")[1])
- self.base.set_creator(str(getpass.getuser()))
- self.absolute_time = strds_absolute_time(ident=ident)
- self.relative_time = strds_relative_time(ident=ident)
- self.spatial_extent = strds_spatial_extent(ident=ident)
- self.metadata = strds_metadata(ident=ident)
-
-###############################################################################
-
-class space_time_raster3d_dataset(abstract_space_time_dataset):
- """Space time raster3d dataset class
- """
-
- def __init__(self, ident):
- abstract_space_time_dataset.__init__(self, ident)
-
- def get_type(self):
- return "str3ds"
-
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- return space_time_raster3d_dataset(ident)
-
- def get_new_map_instance(self, ident):
- """Return a new instance of a map dataset which is associated with the type of this class"""
- return raster3d_dataset(ident)
-
- def get_map_register(self):
- """Return the name of the map register table"""
- return self.metadata.get_raster3d_register()
-
- def set_map_register(self, name):
- """Set the name of the map register table"""
- self.metadata.set_raster3d_register(name)
-
- def reset(self, ident):
-
- """Reset the internal structure and set the identifier"""
- self.ident = ident
-
- self.base = str3ds_base(ident=ident)
-
- if ident != None:
- self.base.set_name(self.ident.split("@")[0])
- self.base.set_mapset(self.ident.split("@")[1])
- self.base.set_creator(str(getpass.getuser()))
- self.absolute_time = str3ds_absolute_time(ident=ident)
- self.relative_time = str3ds_relative_time(ident=ident)
- self.spatial_extent = str3ds_spatial_extent(ident=ident)
- self.metadata = str3ds_metadata(ident=ident)
-
-###############################################################################
-
-class space_time_vector_dataset(abstract_space_time_dataset):
- """Space time vector dataset class
- """
-
- def __init__(self, ident):
- abstract_space_time_dataset.__init__(self, ident)
-
- def get_type(self):
- return "stvds"
-
- def get_new_instance(self, ident):
- """Return a new instance with the type of this class"""
- return space_time_vector_dataset(ident)
-
- def get_new_map_instance(self, ident):
- """Return a new instance of a map dataset which is associated with the type of this class"""
- return vector_dataset(ident)
-
- def get_map_register(self):
- """Return the name of the map register table"""
- return self.metadata.get_vector_register()
-
- def set_map_register(self, name):
- """Set the name of the map register table"""
- self.metadata.set_vector_register(name)
-
- def reset(self, ident):
-
- """Reset the internal structure and set the identifier"""
- self.ident = ident
-
- self.base = stvds_base(ident=ident)
-
- if ident != None:
- self.base.set_name(self.ident.split("@")[0])
- self.base.set_mapset(self.ident.split("@")[1])
- self.base.set_creator(str(getpass.getuser()))
- self.absolute_time = stvds_absolute_time(ident=ident)
- self.relative_time = stvds_relative_time(ident=ident)
- self.spatial_extent = stvds_spatial_extent(ident=ident)
- self.metadata = stvds_metadata(ident=ident)
-
-###############################################################################
-
-def register_maps_in_space_time_dataset(type, name, maps, start=None, increment=None, dbif = None):
- """Use this method to register maps in space time datasets. This function is generic and
- can handle raster, vector and raster3d maps as well as there space time datasets.
-
- Additionally a start time string and an increment string can be specified
- to assign a time interval automatically to the maps.
-
- It takes care of the correct update of the space time datasets from all
- registered maps.
-
- @type The type of the maps raster, raster3d or vector
- @name The name of the space time dataset
- @maps A comma separated list of map names
- @start The start date and time of the first raster map, in case the map has no date (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
- @increment Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
- """
-
- # We may need the mapset
- mapset = core.gisenv()["MAPSET"]
-
- # Check if the dataset name contains the mapset as well
- if name.find("@") < 0:
- id = name + "@" + mapset
- else:
- id = name
-
- if type == "raster":
- sp = space_time_raster_dataset(id)
- if type == "raster3d":
- sp = space_time_raster3d_dataset(id)
- if type == "vector":
- sp = space_time_vector_dataset(id)
-
- connect = False
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- # Read content from temporal database
- sp.select(dbif)
-
- if sp.is_in_db(dbif) == False:
- core.fatal("Space time " + sp.get_new_map_instance(None).get_type() + " dataset <" + name + "> not found")
-
- if maps.find(",") == -1:
- maplist = (maps,)
- else:
- maplist = tuple(maps.split(","))
-
- count = 0
- for mapname in maplist:
- mapname = mapname.strip()
- # Check if the map name contains the mapset as well
- if mapname.find("@") < 0:
- mapid = mapname + "@" + mapset
- else:
- mapid = mapname
- # Get a new instance of the space time dataset map type
- map = sp.get_new_map_instance(mapid)
-
- # In case the map is already registered print a message and continue to the next map
-
- # 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:
- core.fatal("Unable to register " + map.get_type() + " map <" + map.get_id() + ">. The map has no valid time and the start time is not set.")
- # 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():
- core.fatal("Unable to register " + map.get_type() + " map <" + map.get_id() + ">. The temporal types are different.")
-
- # Set the valid time
- if start:
- assign_valid_time_to_map(ttype=sp.get_temporal_type(), map=map, start=start, end=None, increment=increment, mult=count, dbif=dbif)
-
- # 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)
-
- if connect == True:
- dbif.close()
-
-###############################################################################
-
-def unregister_maps_from_space_time_datasets(type, name, maps, 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.
-
- @type The type of the maps raster, vector or raster3d
- @name Name of an existing space time raster dataset. If no name is provided the raster map(s) are unregistered from all space time datasets in which they are registered.
- @maps Name(s) of existing map(s) to unregister
- """
- mapset = core.gisenv()["MAPSET"]
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- # In case a space time dataset is specified
- if name:
- # Check if the dataset name contains the mapset as well
- if name.find("@") < 0:
- id = name + "@" + mapset
- else:
- id = name
-
- if type == "raster":
- sp = space_time_raster_dataset(id)
- if type == "raster3d":
- sp = space_time_raster3d_dataset(id)
- if type == "vector":
- sp = space_time_vector_dataset(id)
-
- if sp.is_in_db(dbif) == False:
- core.fatal("Space time " + sp.get_new_map_instance(None).get_type() + " dataset <" + name + "> not found")
-
- # Build the list of maps
- if maps.find(",") == -1:
- maplist = (maps,)
- else:
- maplist = tuple(maps.split(","))
-
- for mapname in maplist:
- mapname = mapname.strip()
- # Check if the map name contains the mapset as well
- if mapname.find("@") < 0:
- mapid = mapname + "@" + mapset
- else:
- mapid = mapname
-
- # Create a new instance with the map type
- if type == "raster":
- map = raster_dataset(mapid)
- if type == "raster3d":
- map = raster3d_dataset(mapid)
- if type == "vector":
- map = vector_dataset(mapid)
-
- # Unregister map if in database
- if map.is_in_db(dbif) == True:
- if name:
- sp.select(dbif)
- sp.unregister_map(map, dbif)
- else:
- map.select(dbif)
- map.unregister(dbif)
-
- if name:
- sp.update_from_registered_maps(dbif)
-
- if connect == True:
- dbif.close()
-
-###############################################################################
-
-def assign_valid_time_to_maps(type, maps, ttype, start, end=None, increment=None, dbif = None):
- """Use this method to assign valid time (absolute or relative) to raster,
- raster3d and vector datasets.
-
- It takes care of the correct update of the space time datasets from all
- registered maps.
-
- Valid end time and increment are mutual exclusive.
-
- @type The type of the maps raster, raster3d or vector
- @maps A comma separated list of map names
- @start The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
- @end The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
- @increment Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
- """
-
- if end and increment:
- core.fatal("Valid end time and increment are mutual exclusive")
-
- # List of space time datasets to be updated
- splist = {}
-
- # We may need the mapset
- mapset = core.gisenv()["MAPSET"]
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- if maps.find(",") == -1:
- maplist = (maps,)
- else:
- maplist = tuple(maps.split(","))
-
- count = 0
- for mapname in maplist:
- mapname = mapname.strip()
- # Check if the map name contains the mapset as well
- if mapname.find("@") < 0:
- mapid = mapname + "@" + mapset
- else:
- mapid = mapname
-
- if type == "raster":
- map = raster_dataset(mapid)
- if type == "raster3d":
- map = raster3d_dataset(mapid)
- if type == "vector":
- map = vector_dataset(mapid)
-
- if map.is_in_db(dbif) == False:
- # Load the data from the grass file database
- map.load()
- if ttype == "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)
- sprows = map.get_registered_datasets(dbif)
- # Make an entry in the dataset list, using a dict make sure that
- # each dataset is listed only once
- if sprows != None:
- for dataset in sprows:
- splist[dataset["id"]] = True
-
- # Set the valid time
- assign_valid_time_to_map(ttype=ttype, map=map, start=start, end=end, increment=increment, mult=count, dbif=dbif)
-
- count += 1
-
- # Update all the space time datasets in which registered maps are changed there valid time
- for name in splist.keys():
- sp = map.get_new_stds_instance(name)
- sp.select(dbif)
- sp.update_from_registered_maps(dbif)
-
- if connect == True:
- dbif.close()
-
-
-###############################################################################
-
-def assign_valid_time_to_map(ttype, map, start, end, increment=None, mult=1, dbif = None):
- """Assign the valid time to a map dataset
-
- @ttype The temporal type which should be assigned and which the time format is of
- @map A map dataset object derived from abstract_map_dataset
- @start The start date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
- @end The end date and time of the first raster map (format absolute: "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd", format relative 5.0)
- @increment Time increment between maps for time stamp creation (format absolute: NNN seconds, minutes, hours, days, weeks, months, years; format relative: 1.0)
- @multi A multiplier for the increment
- """
-
- connect = False
-
- if dbif == None:
- dbif = sql_database_interface()
- dbif.connect()
- connect = True
-
- if ttype == "absolute":
- # Create the start time object
- if start.find(":") > 0:
- time_format = "%Y-%m-%d %H:%M:%S"
- else:
- time_format = "%Y-%m-%d"
-
- start_time = datetime.strptime(start, time_format)
- if end:
- end_time = datetime.strptime(end, time_format)
- else:
- end_time = None
-
- # Add the increment
- if increment:
- start_time = increment_datetime_by_string(start_time, increment, mult)
- 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)))
- map.update_absolute_time(start_time, end_time, None, dbif)
- else:
- start_time = float(start)
-
- if end:
- end_time = float(end)
- else:
- end_time = None
-
- if increment:
- start_time = start_time + mult * float(increment)
- end_time = start_time + float(increment)
-
- core.verbose(_("Set relative valid time for map <%s> to %f - %s") % (map.get_id(), start_time, str(end_time)))
- map.update_relative_time(start_time, end_time, dbif)
-
- if connect == True:
- dbif.close()
Deleted: grass/trunk/lib/python/tgis_spatial_extent.py
===================================================================
--- grass/trunk/lib/python/tgis_spatial_extent.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_spatial_extent.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,290 +0,0 @@
-"""!@package grass.script.tgis_spatial_extent
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related spatial extent functions to be used in Python scripts and tgis packages.
-
-Usage:
-
- at code
-from grass.script import tgis_spatial_extent as grass
-
-extent = grass.raster_spatial_extent()
-...
- at endcode
-
-(C) 2008-2011 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Soeren Gebbert
-"""
-from tgis_base import *
-
-class spatial_extent(sql_database_interface):
- """This is the spatial extent base class for all maps and spacetime datasets"""
- def __init__(self, table=None, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None, proj="XY"):
-
- sql_database_interface.__init__(self, table, ident)
- self.set_id(ident)
- self.set_spatial_extent(north, south, east, west, top, bottom)
- self.set_projection(proj)
-
- def overlap_2d(self, extent):
- """Return True if the 2d extents overlap. Code is lend from wind_overlap.c in lib/gis"""
-
- if self.get_projection() != extent.get_projection():
- core.error("Projections are different. Unable to compute overlap_2d for spatial extents")
-
- N = extent.get_north()
- S = extent.get_south()
- E = extent.get_east()
- W = extent.get_west()
-
- if(self.get_north() <= S):
- return False
-
- if(self.get_south() >= N):
- return False
-
- # Adjust the east and west in case of LL projection
- if self.get_proj() == "LL":
- while E < self.get_west():
- E += 360.0
- W += 360.0
-
- while W > self.get_east():
- E -= 360.0
- W -= 360.0
-
- if self.get_east() <= W:
- return False
-
- if self.get_west() >= E:
- return False
-
- return True
-
- def overlap(self, extent):
- """Return True if the extents overlap."""
-
- if self.overlap_2d(extent) == False:
- return False
-
- T = extent.get_top()
- B = extent.get_bottom()
-
- if self.get_top() <= B:
- return False
-
- if self.get_bottom() >= T:
- return False
-
- return True
-
- def set_spatial_extent(self, north, south, east, west, top, bottom):
- """Set the spatial extent"""
-
- self.set_north(north)
- self.set_south(south)
- self.set_east(east)
- self.set_west(west)
- self.set_top(top)
- self.set_bottom(bottom)
-
- def set_projection(self, proj):
- """Set the projection of the spatial extent it should be XY or LL.
- As default the projection is XY
- """
- if proj == None or (proj != "XY" and proj != "LL"):
- self.D["proj"] = "XY"
- else:
- self.D["proj"] = proj
-
- def set_spatial_extent_2d(self, north, south, east, west):
-
- self.set_id(ident)
- self.set_north(north)
- self.set_south(south)
- self.set_east(east)
- self.set_west(west)
- self.set_top(0)
- self.set_bottom(0)
-
- def set_id(self, ident):
- """Convenient method to set the unique identifier (primary key)"""
- self.ident = ident
- self.D["id"] = ident
-
- def set_north(self, north):
- """Set the northern edge of the map"""
- self.D["north"] = north
-
- def set_south(self, sourth):
- """Set the sourthern edge of the map"""
- self.D["south"] = sourth
-
- def set_west(self, west):
- """Set the western edge of the map"""
- self.D["west"] = west
-
- def set_east(self, east):
- """Set the eastern edge of the map"""
- self.D["east"] = east
-
- def set_top(self, top):
- """Set the top edge of the map"""
- self.D["top"] = top
-
- def set_bottom(self, bottom):
- """Set the bottom edge of the map"""
- self.D["bottom"] = bottom
-
- def get_id(self):
- """Convenient method to get the unique identifier (primary key)
- @return None if not found
- """
- if self.D.has_key("id"):
- return self.D["id"]
- else:
- return None
-
- def get_projection(self):
- """Get the projection of the spatial extent"""
- return self.D["proj"]
-
- def get_volume(self):
- """Compute the volume of the extent, in case z is zero (top == bottom or top - bottom = 1) the area is returned"""
-
- if self.get_projection() == "LL":
- core.error("Volume computation is not supported for LL projections")
-
- area = self.get_area()
-
- bbox = self.get_spatial_extent()
-
- z = abs(bbox[4] - bbox[5])
-
- if z == 0:
- z = 1.0
-
- return area*z
-
- def get_area(self):
- """Compute the area of the extent, extent in z direction is ignored"""
-
- if self.get_projection() == "LL":
- core.error("Area computation is not supported for LL projections")
-
- bbox = self.get_spatial_extent()
-
- y = abs(bbox[0] - bbox[1])
- x = abs(bbox[2] - bbox[3])
-
- return x*y
-
- def get_spatial_extent(self):
- """Return a tuple (north, south, east, west, top, bottom) of the spatial extent"""
-
- return (self.get_north(), self.get_south, self.get_east(), self.get_west(), \
- self.get_top(), self.get_bottom())
-
- def get_spatial_extent_2d(self):
- """Return a tuple (north, south, east, west,) of the 2d spatial extent"""
- return (self.get_north(), self.get_south, self.get_east(), self.get_west())
-
- def get_north(self):
- """Get the northern edge of the map
- @return None if not found"""
- if self.D.has_key("north"):
- return self.D["north"]
- else:
- return None
-
- def get_south(self):
- """Get the southern edge of the map
- @return None if not found"""
- if self.D.has_key("south"):
- return self.D["south"]
- else:
- return None
-
- def get_east(self):
- """Get the eastern edge of the map
- @return None if not found"""
- if self.D.has_key("east"):
- return self.D["east"]
- else:
- return None
-
- def get_west(self):
- """Get the western edge of the map
- @return None if not found"""
- if self.D.has_key("west"):
- return self.D["west"]
- else:
- return None
-
- def get_top(self):
- """Get the top edge of the map
- @return None if not found"""
- if self.D.has_key("top"):
- return self.D["top"]
- else:
- return None
-
- def get_bottom(self):
- """Get the bottom edge of the map
- @return None if not found"""
- if self.D.has_key("bottom"):
- return self.D["bottom"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- # 0123456789012345678901234567890
- print " +-------------------- Spatial extent ----------------------------------------+"
- print " | North:...................... " + str(self.get_north())
- print " | South:...................... " + str(self.get_south())
- print " | East:.. .................... " + str(self.get_east())
- print " | West:....................... " + str(self.get_west())
- print " | Top:........................ " + str(self.get_top())
- print " | Bottom:..................... " + str(self.get_bottom())
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- print "north=" + str(self.get_north())
- print "south=" + str(self.get_south())
- print "east=" + str(self.get_east())
- print "west=" + str(self.get_west())
- print "top=" + str(self.get_top())
- print "bottom=" + str(self.get_bottom())
-
-
-###############################################################################
-
-class raster_spatial_extent(spatial_extent):
- def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
- spatial_extent.__init__(self, "raster_spatial_extent", ident, north, south, east, west, top, bottom)
-
-class raster3d_spatial_extent(spatial_extent):
- def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
- spatial_extent.__init__(self, "raster3d_spatial_extent", ident, north, south, east, west, top, bottom)
-
-class vector_spatial_extent(spatial_extent):
- def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
- spatial_extent.__init__(self, "vector_spatial_extent", ident, north, south, east, west, top, bottom)
-
-class strds_spatial_extent(spatial_extent):
- def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
- spatial_extent.__init__(self, "strds_spatial_extent", ident, north, south, east, west, top, bottom)
-
-class str3ds_spatial_extent(spatial_extent):
- def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
- spatial_extent.__init__(self, "str3ds_spatial_extent", ident, north, south, east, west, top, bottom)
-
-class stvds_spatial_extent(spatial_extent):
- def __init__(self, ident=None, north=None, south=None, east=None, west=None, top=None, bottom=None):
- spatial_extent.__init__(self, "stvds_spatial_extent", ident, north, south, east, west, top, bottom)
Deleted: grass/trunk/lib/python/tgis_temporal_extent.py
===================================================================
--- grass/trunk/lib/python/tgis_temporal_extent.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/python/tgis_temporal_extent.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -1,438 +0,0 @@
-"""!@package grass.script.tgis_temporal_extent
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related temporal extent functions to be used in Python scripts and tgis packages.
-
-Usage:
-
- at code
-from grass.script import tgis_temporal_extent as grass
-
-grass.raster_temporal_extent()
-...
- at endcode
-
-(C) 2008-2011 by the GRASS Development Team
-This program is free software under the GNU General Public
-License (>=v2). Read the file COPYING that comes with GRASS
-for details.
-
- at author Soeren Gebbert
-"""
-from tgis_base import *
-
-###############################################################################
-
-class abstract_temporal_extent(sql_database_interface):
- """This is the abstract time base class for relative and absolute time objects"""
- def __init__(self, table=None, ident=None, start_time=None, end_time=None):
-
- sql_database_interface.__init__(self, table, ident)
-
- self.set_id(ident)
- self.set_start_time(start_time)
- self.set_end_time(end_time)
-
- def starts(self, map):
- """Return True if this absolute time object starts at the start of the provided absolute time object and finishes within it
- A |-----|
- B |---------|
- """
- if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] < map.D["end_time"]:
- return True
- else:
- return False
-
- def started(self, map):
- """Return True if this absolute time object is started at the start of the provided absolute time object
- A |---------|
- B |-----|
- """
- if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] > map.D["end_time"]:
- return True
- else:
- return False
-
- def finishes(self, map):
- """Return True if this absolute time object finishes at the end and within of the provided absolute time object
- A |-----|
- B |---------|
- """
- if self.D["end_time"] == map.D["end_time"] and self.D["start_time"] > map.D["start_time"] :
- return True
- else:
- return False
-
- def finished(self, map):
- """Return True if this absolute time object finished at the end of the provided absolute time object
- A |---------|
- B |-----|
- """
- if self.D["end_time"] == map.D["end_time"] and self.D["start_time"] < map.D["start_time"] :
- return True
- else:
- return False
-
- def after(self, map):
- """Return True if this absolute time object is temporal located after the provided absolute time object
- A |---------|
- B |---------|
- """
- if self.D["start_time"] > map.D["end_time"]:
- return True
- else:
- return False
-
- def before(self, map):
- """Return True if this absolute time object is temporal located bevor the provided absolute time object
- A |---------|
- B |---------|
- """
- if self.D["end_time"] < map.D["start_time"]:
- return True
- else:
- return False
-
- def adjacent(self, map):
- """Return True if this absolute time object is a meeting neighbour the provided absolute time object
- A |---------|
- B |---------|
- A |---------|
- B |---------|
- """
- if (self.D["start_time"] == map.D["end_time"]) or (self.D["end_time"] == map.D["start_time"]):
- return True
- else:
- return False
-
- def follows(self, map):
- """Return True if this absolute time object is temporal follows the provided absolute time object
- A |---------|
- B |---------|
- """
- if self.D["start_time"] == map.D["end_time"]:
- return True
- else:
- return False
-
- def precedes(self, map):
- """Return True if this absolute time object is temporal precedes the provided absolute time object
- A |---------|
- B |---------|
- """
- if self.D["end_time"] == map.D["start_time"]:
- return True
- else:
- return False
-
- def during(self, map):
- """Return True if this absolute time object is temporal located during the provided absolute time object
- A |-------|
- B |---------|
- """
- if self.D["start_time"] > map.D["start_time"] and self.D["end_time"] < map.D["end_time"]:
- return True
- else:
- return False
-
- def contains(self, map):
- """Return True if this absolute time object is temporal located during the provided absolute time object
- A |---------|
- B |-------|
- """
- if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] > map.D["end_time"]:
- return True
- else:
- return False
-
- def equivalent(self, map):
- """Return True if this absolute time object is temporal located equivalent the provided absolute time object
- A |---------|
- B |---------|
- """
- if self.D["start_time"] == map.D["start_time"] and self.D["end_time"] == map.D["end_time"]:
- return True
- else:
- return False
-
- def overlaps(self, map):
- """Return True if this absolute time object is temporal overlaps the provided absolute time object
- A |---------|
- B |---------|
- """
- if self.D["start_time"] < map.D["start_time"] and self.D["end_time"] < map.D["end_time"] and\
- self.D["end_time"] > map.D["start_time"]:
- return True
- else:
- return False
-
- def overlapped(self, map):
- """Return True if this absolute time object is temporal overlaped by the provided absolute time object
- A |---------|
- B |---------|
- """
- if self.D["start_time"] > map.D["start_time"] and self.D["end_time"] > map.D["end_time"] and\
- self.D["start_time"] < map.D["end_time"]:
- return True
- else:
- return False
-
- def temporal_relation(self, map):
- """Returns the temporal relation between absolute time temporal objects
- Temporal relationsships are implemented after [Allen and Ferguson 1994 Actions and Events in Interval Temporal Logic]
- """
- if self.equivalent(map):
- return "equivalent"
- if self.during(map):
- return "during"
- if self.contains(map):
- return "contains"
- if self.overlaps(map):
- return "overlaps"
- if self.overlapped(map):
- return "overlapped"
- if self.after(map):
- return "after"
- if self.before(map):
- return "before"
- if self.starts(map):
- return "starts"
- if self.finishes(map):
- return "finishes"
- if self.started(map):
- return "started"
- if self.finished(map):
- return "finished"
- if self.equivalent(map):
- return "equivalent"
- if self.follows(map):
- return "follows"
- if self.precedes(map):
- return "precedes"
- return None
-
- def set_id(self, ident):
- """Convenient method to set the unique identifier (primary key)"""
- self.ident = ident
- self.D["id"] = ident
-
- def set_start_time(self, start_time):
- """Set the valid start time of the map"""
- self.D["start_time"] = start_time
-
- def set_end_time(self, end_time):
- """Set the valid end time of the map"""
- self.D["end_time"] = end_time
-
- def get_id(self):
- """Convenient method to get the unique identifier (primary key)
- @return None if not found
- """
- if self.D.has_key("id"):
- return self.D["id"]
- else:
- return None
-
- def get_start_time(self):
- """Get the valid start time of the map
- @return None if not found"""
- if self.D.has_key("start_time"):
- return self.D["start_time"]
- else:
- return None
-
- def get_end_time(self):
- """Get the valid end time of the map
- @return None if not found"""
- if self.D.has_key("end_time"):
- return self.D["end_time"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- # 0123456789012345678901234567890
- print " | Start time:................. " + str(self.get_start_time())
- print " | End time:................... " + str(self.get_end_time())
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- print "start_time=" + str(self.get_start_time())
- print "end_time=" + str(self.get_end_time())
-
-###############################################################################
-
-class absolute_temporal_extent(abstract_temporal_extent):
- """This is the absolute time class for all maps and spacetime datasets
-
- start_time and end_time must be of type datetime
- """
- def __init__(self, table=None, ident=None, start_time=None, end_time=None, timezone=None):
-
- abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
-
- self.set_timezone(timezone)
-
- def set_timezone(self, timezone):
- """Set the timezone of the map, integer from 1 - 24"""
- self.D["timezone"] = timezone
-
- def get_timezone(self):
- """Get the timezone of the map
- @return None if not found"""
- if self.D.has_key("timezone"):
- return self.D["timezone"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- # 0123456789012345678901234567890
- print " +-------------------- Absolute time -----------------------------------------+"
- abstract_temporal_extent.print_info(self)
- print " | Timezone:................... " + str(self.get_timezone())
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- abstract_temporal_extent.print_shell_info(self)
- print "timezone=" + str(self.get_timezone())
-
-###############################################################################
-
-class raster_absolute_time(absolute_temporal_extent):
- def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
- absolute_temporal_extent.__init__(self, "raster_absolute_time", ident, start_time, end_time, timezone)
-
-class raster3d_absolute_time(absolute_temporal_extent):
- def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
- absolute_temporal_extent.__init__(self, "raster3d_absolute_time", ident, start_time, end_time, timezone)
-
-class vector_absolute_time(absolute_temporal_extent):
- def __init__(self, ident=None, start_time=None, end_time=None, timezone=None):
- absolute_temporal_extent.__init__(self, "vector_absolute_time", ident, start_time, end_time, timezone)
-
-###############################################################################
-
-class stds_absolute_time(absolute_temporal_extent):
- def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
- absolute_temporal_extent.__init__(self, table, ident, start_time, end_time, timezone)
-
- self.set_granularity(granularity)
-
- def set_granularity(self, granularity):
- """Set the granularity of the space time dataset"""
- self.D["granularity"] = granularity
-
- def get_granularity(self):
- """Get the granularity of the space time dataset
- @return None if not found"""
- if self.D.has_key("granularity"):
- return self.D["granularity"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- absolute_temporal_extent.print_info(self)
- # 0123456789012345678901234567890
- print " | Granularity:................ " + str(self.get_granularity())
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- absolute_temporal_extent.print_shell_info(self)
- print "granularity=" + str(self.get_granularity())
-
-###############################################################################
-
-class strds_absolute_time(stds_absolute_time):
- def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
- stds_absolute_time.__init__(self, "strds_absolute_time", ident, start_time, end_time, granularity, timezone)
-
-class str3ds_absolute_time(stds_absolute_time):
- def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
- stds_absolute_time.__init__(self, "str3ds_absolute_time", ident, start_time, end_time, granularity, timezone)
-
-class stvds_absolute_time(stds_absolute_time):
- def __init__(self, ident=None, start_time=None, end_time=None, granularity=None, timezone=None):
- stds_absolute_time.__init__(self, "stvds_absolute_time", ident, start_time, end_time, granularity, timezone)
-
-###############################################################################
-
-
-class relative_temporal_extent(abstract_temporal_extent):
- """This is the relative time class for all maps and spacetime datasets
-
- start_time and end_time must be of type datetime
- """
- def __init__(self, table=None, ident=None, start_time=None, end_time=None):
-
- abstract_temporal_extent.__init__(self, table, ident, start_time, end_time)
-
-
- def print_info(self):
- """Print information about this class in human readable style"""
- # 0123456789012345678901234567890
- print " +-------------------- Reltive time ------------------------------------------+"
- abstract_temporal_extent.print_info(self)
-
-
-###############################################################################
-
-class raster_relative_time(relative_temporal_extent):
- def __init__(self, ident=None, start_time=None, end_time=None):
- relative_temporal_extent.__init__(self, "raster_relative_time", ident, start_time, end_time)
-
-class raster3d_relative_time(relative_temporal_extent):
- def __init__(self, ident=None, start_time=None, end_time=None):
- relative_temporal_extent.__init__(self, "raster3d_relative_time", ident, start_time, end_time)
-
-class vector_relative_time(relative_temporal_extent):
- def __init__(self, ident=None, start_time=None, end_time=None):
- relative_temporal_extent.__init__(self, "vector_relative_time", ident, start_time, end_time)
-
-###############################################################################
-
-class stds_relative_time(relative_temporal_extent):
- def __init__(self, table=None, ident=None, start_time=None, end_time=None, granularity=None):
- relative_temporal_extent.__init__(self, table, ident, start_time, end_time)
-
- self.set_granularity(granularity)
-
- def set_granularity(self, granularity):
- """Set the granularity of the space time dataset"""
- self.D["granularity"] = granularity
-
- def get_granularity(self):
- """Get the granularity of the space time dataset
- @return None if not found"""
- if self.D.has_key("granularity"):
- return self.D["granularity"]
- else:
- return None
-
- def print_info(self):
- """Print information about this class in human readable style"""
- relative_temporal_extent.print_info(self)
- # 0123456789012345678901234567890
- print " | Granularity:................ " + str(self.get_granularity())
-
- def print_shell_info(self):
- """Print information about this class in shell style"""
- relative_temporal_extent.print_shell_info(self)
- print "granularity=" + str(self.get_granularity())
-
-###############################################################################
-
-class strds_relative_time(stds_relative_time):
- def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
- stds_relative_time.__init__(self, "strds_relative_time", ident, start_time, end_time, granularity)
-
-class str3ds_relative_time(stds_relative_time):
- def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
- stds_relative_time.__init__(self, "str3ds_relative_time", ident, start_time, end_time, granularity)
-
-class stvds_relative_time(stds_relative_time):
- def __init__(self, ident=None, start_time=None, end_time=None, granularity=None):
- stds_relative_time.__init__(self, "stvds_relative_time", ident, start_time, end_time, granularity)
-
Modified: grass/trunk/lib/temporal/Makefile
===================================================================
--- grass/trunk/lib/temporal/Makefile 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/lib/temporal/Makefile 2011-09-21 21:06:55 UTC (rev 48399)
@@ -6,10 +6,9 @@
SQLFILES:= $(wildcard *.sql)
-default: copy_sql_files
+DSTFILES := $(patsubst %.sql,$(SQLDIR)/%.sql,$(SQLFILES))
-copy_sql_files: $(SQLDIR)
- for i in $(SQLFILES); do $(INSTALL_DATA) $$i $(SQLDIR)/; done
+default: $(DSTFILES)
-$(SQLDIR):
- $(MKDIR) $@
\ No newline at end of file
+$(SQLDIR)/%.sql: %.sql | $(SQLDIR)
+ $(INSTALL_DATA) $< $@
Modified: grass/trunk/temporal/t.create/t.create.py
===================================================================
--- grass/trunk/temporal/t.create/t.create.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/t.create/t.create.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -81,6 +81,7 @@
#% multiple: no
#%end
+import grass.temporal as tgis
import grass.script as grass
############################################################################
@@ -97,7 +98,7 @@
gran = options["granularity"]
# Make sure the temporal database exists
- grass.create_temporal_database()
+ tgis.create_temporal_database()
#Get the current mapset to create the id of the space time dataset
@@ -105,13 +106,13 @@
id = name + "@" + mapset
if type == "strds":
- sp = grass.space_time_raster_dataset(id)
+ sp = tgis.space_time_raster_dataset(id)
if type == "str3ds":
- sp = grass.space_time_raster3d_dataset(id)
+ sp = tgis.space_time_raster3d_dataset(id)
if type == "stvds":
- sp = grass.space_time_vector_dataset(id)
+ sp = tgis.space_time_vector_dataset(id)
- dbif = grass.sql_database_interface()
+ dbif = tgis.sql_database_interface()
dbif.connect()
if sp.is_in_db(dbif) and grass.overwrite() == False:
@@ -130,6 +131,6 @@
dbif.close()
if __name__ == "__main__":
- options, flags = grass.core.parser()
+ options, flags = grass.parser()
main()
Modified: grass/trunk/temporal/t.info/t.info.py
===================================================================
--- grass/trunk/temporal/t.info/t.info.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/t.info/t.info.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -43,6 +43,7 @@
#%end
import grass.script as grass
+import grass.temporal as tgis
############################################################################
@@ -54,7 +55,7 @@
shellstyle = flags['g']
# Make sure the temporal database exists
- grass.create_temporal_database()
+ tgis.create_temporal_database()
#Get the current mapset to create the id of the space time dataset
@@ -65,17 +66,17 @@
id = name + "@" + mapset
if type == "strds":
- sp = grass.space_time_raster_dataset(id)
+ sp = tgis.space_time_raster_dataset(id)
if type == "str3ds":
- sp = grass.space_time_raster3d_dataset(id)
+ sp = tgis.space_time_raster3d_dataset(id)
if type == "stvds":
- sp = grass.space_time_vector_dataset(id)
+ sp = tgis.space_time_vector_dataset(id)
if type == "raster":
- sp = grass.raster_dataset(id)
+ sp = tgis.raster_dataset(id)
if type == "raster3d":
- sp = grass.raster3d_dataset(id)
+ sp = tgis.raster3d_dataset(id)
if type == "vector":
- sp = grass.vector_dataset(id)
+ sp = tgis.vector_dataset(id)
if sp.is_in_db() == False:
grass.fatal("Dataset <" + name + "> not found in temporal database")
@@ -89,6 +90,6 @@
sp.print_info()
if __name__ == "__main__":
- options, flags = grass.core.parser()
+ options, flags = grass.parser()
main()
Modified: grass/trunk/temporal/t.list/t.list.py
===================================================================
--- grass/trunk/temporal/t.list/t.list.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/t.list/t.list.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -80,6 +80,7 @@
#%end
import grass.script as grass
+import grass.temporal as tgis
############################################################################
@@ -95,24 +96,24 @@
colhead = flags['c']
# Make sure the temporal database exists
- grass.create_temporal_database()
+ tgis.create_temporal_database()
id = None
if type == "strds":
- sp = grass.space_time_raster_dataset(id)
+ sp = tgis.space_time_raster_dataset(id)
if type == "str3ds":
- sp = grass.space_time_raster3d_dataset(id)
+ sp = tgis.space_time_raster3d_dataset(id)
if type == "stvds":
- sp = grass.space_time_vector_dataset(id)
+ sp = tgis.space_time_vector_dataset(id)
if type == "raster":
- sp = grass.raster_dataset(id)
+ sp = tgis.raster_dataset(id)
if type == "raster3d":
- sp = grass.raster3d_dataset(id)
+ sp = tgis.raster3d_dataset(id)
if type == "vector":
- sp = grass.vector_dataset(id)
+ sp = tgis.vector_dataset(id)
- dbif = grass.sql_database_interface()
+ dbif = tgis.sql_database_interface()
dbif.connect()
# Insert content from db
@@ -170,5 +171,5 @@
print output
if __name__ == "__main__":
- options, flags = grass.core.parser()
+ options, flags = grass.parser()
main()
Modified: grass/trunk/temporal/t.remove/t.remove.py
===================================================================
--- grass/trunk/temporal/t.remove/t.remove.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/t.remove/t.remove.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -39,6 +39,7 @@
#%end
import grass.script as grass
+import grass.temporal as tgis
############################################################################
@@ -49,11 +50,11 @@
type = options["type"]
# Make sure the temporal database exists
- grass.create_temporal_database()
+ tgis.create_temporal_database()
mapset = grass.gisenv()["MAPSET"]
- dbif = grass.sql_database_interface()
+ dbif = tgis.sql_database_interface()
dbif.connect()
for name in names.split(","):
@@ -65,17 +66,17 @@
id = name
if type == "strds":
- ds = grass.space_time_raster_dataset(id)
+ ds = tgis.space_time_raster_dataset(id)
if type == "str3ds":
- ds = grass.space_time_raster3d_dataset(id)
+ ds = tgis.space_time_raster3d_dataset(id)
if type == "stvds":
- ds = grass.space_time_vector_dataset(id)
+ ds = tgis.space_time_vector_dataset(id)
if type == "raster":
- ds = grass.raster_dataset(id)
+ ds = tgis.raster_dataset(id)
if type == "raster3d":
- ds = grass.raster3d_dataset(id)
+ ds = tgis.raster3d_dataset(id)
if type == "vector":
- ds = grass.vector_dataset(id)
+ ds = tgis.vector_dataset(id)
if ds.is_in_db(dbif) == False:
grass.fatal(ds.get_type() + " dataset <" + name + "> not found in temporal database")
@@ -87,6 +88,6 @@
dbif.close()
if __name__ == "__main__":
- options, flags = grass.core.parser()
+ options, flags = grass.parser()
main()
Modified: grass/trunk/temporal/t.time.abs/t.time.abs.py
===================================================================
--- grass/trunk/temporal/t.time.abs/t.time.abs.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/t.time.abs/t.time.abs.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -56,6 +56,7 @@
#%end
import grass.script as grass
+import grass.temporal as tgis
############################################################################
@@ -68,12 +69,12 @@
increment = options["increment"]
# Make sure the temporal database exists
- grass.create_temporal_database()
+ tgis.create_temporal_database()
# Set valid absolute time to maps
- grass.assign_valid_time_to_maps(type="raster", maps=maps, ttype="absolute", \
- start=start, end=end, increment=increment, dbif=None)
+ tgis.assign_valid_time_to_maps(type="raster", maps=maps, ttype="absolute", \
+ start=start, end=end, increment=increment, dbif=None)
if __name__ == "__main__":
- options, flags = grass.core.parser()
+ options, flags = grass.parser()
main()
Modified: grass/trunk/temporal/t.time.rel/t.time.rel.py
===================================================================
--- grass/trunk/temporal/t.time.rel/t.time.rel.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/t.time.rel/t.time.rel.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -56,6 +56,7 @@
#%end
import grass.script as grass
+import grass.temporal as tgis
############################################################################
@@ -68,12 +69,12 @@
increment = options["increment"]
# Make sure the temporal database exists
- grass.create_temporal_database()
+ tgis.create_temporal_database()
# Set valid relative time to maps
- grass.assign_valid_time_to_maps(type="raster", maps=maps, ttype="relative", \
+ tgis.assign_valid_time_to_maps(type="raster", maps=maps, ttype="relative", \
start=start, end=end, increment=increment, dbif=None)
if __name__ == "__main__":
- options, flags = grass.core.parser()
+ options, flags = grass.parser()
main()
Modified: grass/trunk/temporal/tr.register/tr.register.py
===================================================================
--- grass/trunk/temporal/tr.register/tr.register.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/tr.register/tr.register.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -53,6 +53,7 @@
#%end
import grass.script as grass
+import grass.temporal as tgis
############################################################################
@@ -65,11 +66,11 @@
increment = options["increment"]
# Make sure the temporal database exists
- grass.create_temporal_database()
+ tgis.create_temporal_database()
# Register maps
- grass.register_maps_in_space_time_dataset("raster", name, maps, start, increment)
+ tgis.register_maps_in_space_time_dataset("raster", name, maps, start, increment)
if __name__ == "__main__":
- options, flags = grass.core.parser()
+ options, flags = grass.parser()
main()
Modified: grass/trunk/temporal/tr.unregister/tr.unregister.py
===================================================================
--- grass/trunk/temporal/tr.unregister/tr.unregister.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/tr.unregister/tr.unregister.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -37,6 +37,8 @@
#%end
import grass.script as grass
+import grass.temporal as tgis
+
############################################################################
def main():
@@ -46,11 +48,11 @@
maps = options["maps"]
# Make sure the temporal database exists
- grass.create_temporal_database()
+ tgis.create_temporal_database()
# Unregister maps
- grass.unregister_maps_from_space_time_datasets("raster", name, maps)
+ tgis.unregister_maps_from_space_time_datasets("raster", name, maps)
if __name__ == "__main__":
- options, flags = grass.core.parser()
+ options, flags = grass.parser()
main()
Modified: grass/trunk/temporal/tr3.register/tr3.register.py
===================================================================
--- grass/trunk/temporal/tr3.register/tr3.register.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/tr3.register/tr3.register.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -53,6 +53,7 @@
#%end
import grass.script as grass
+import grass.temporal as tgis
############################################################################
@@ -65,11 +66,11 @@
increment = options["increment"]
# Make sure the temporal database exists
- grass.create_temporal_database()
+ tgis.create_temporal_database()
# Register maps
- grass.register_maps_in_space_time_dataset("raster3d", name, maps, start, increment)
+ tgis.register_maps_in_space_time_dataset("raster3d", name, maps, start, increment)
if __name__ == "__main__":
- options, flags = grass.core.parser()
+ options, flags = grass.parser()
main()
Modified: grass/trunk/temporal/tr3.unregister/tr3.unregister.py
===================================================================
--- grass/trunk/temporal/tr3.unregister/tr3.unregister.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/tr3.unregister/tr3.unregister.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -37,6 +37,8 @@
#%end
import grass.script as grass
+import grass.temporal as tgis
+
############################################################################
def main():
@@ -46,11 +48,11 @@
maps = options["maps"]
# Make sure the temporal database exists
- grass.create_temporal_database()
+ tgis.create_temporal_database()
# Unregister maps
- grass.unregister_maps_from_space_time_datasets("raster3d", name, maps)
+ tgis.unregister_maps_from_space_time_datasets("raster3d", name, maps)
if __name__ == "__main__":
- options, flags = grass.core.parser()
+ options, flags = grass.parser()
main()
Modified: grass/trunk/temporal/tv.register/tv.register.py
===================================================================
--- grass/trunk/temporal/tv.register/tv.register.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/tv.register/tv.register.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -53,6 +53,7 @@
#%end
import grass.script as grass
+import grass.temporal as tgis
############################################################################
@@ -65,11 +66,11 @@
increment = options["increment"]
# Make sure the temporal database exists
- grass.create_temporal_database()
+ tgis.create_temporal_database()
# Register maps
- grass.register_maps_in_space_time_dataset("vector", name, maps, start, increment)
+ tgis.register_maps_in_space_time_dataset("vector", name, maps, start, increment)
if __name__ == "__main__":
- options, flags = grass.core.parser()
+ options, flags = grass.parser()
main()
Modified: grass/trunk/temporal/tv.unregister/tv.unregister.py
===================================================================
--- grass/trunk/temporal/tv.unregister/tv.unregister.py 2011-09-21 19:57:28 UTC (rev 48398)
+++ grass/trunk/temporal/tv.unregister/tv.unregister.py 2011-09-21 21:06:55 UTC (rev 48399)
@@ -37,6 +37,8 @@
#%end
import grass.script as grass
+import grass.temporal as tgis
+
############################################################################
def main():
@@ -46,11 +48,11 @@
maps = options["maps"]
# Make sure the temporal database exists
- grass.create_temporal_database()
+ tgis.create_temporal_database()
# Unregister maps
- grass.unregister_maps_from_space_time_datasets("vector", name, maps)
+ tgis.unregister_maps_from_space_time_datasets("vector", name, maps)
if __name__ == "__main__":
- options, flags = grass.core.parser()
+ options, flags = grass.parser()
main()
More information about the grass-commit
mailing list