[GRASS-SVN] r55914 - grass/trunk/lib/python/temporal
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Apr 19 05:20:23 PDT 2013
Author: huhabla
Date: 2013-04-19 05:20:22 -0700 (Fri, 19 Apr 2013)
New Revision: 55914
Added:
grass/trunk/lib/python/temporal/create.py
grass/trunk/lib/python/temporal/factory.py
grass/trunk/lib/python/temporal/gui_support.py
grass/trunk/lib/python/temporal/list.py
grass/trunk/lib/python/temporal/register.py
grass/trunk/lib/python/temporal/sampling.py
Removed:
grass/trunk/lib/python/temporal/space_time_datasets_tools.py
Modified:
grass/trunk/lib/python/temporal/Makefile
grass/trunk/lib/python/temporal/__init__.py
grass/trunk/lib/python/temporal/abstract_map_dataset.py
grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
grass/trunk/lib/python/temporal/base.py
grass/trunk/lib/python/temporal/mapcalc.py
grass/trunk/lib/python/temporal/pythontemporallib.dox
grass/trunk/lib/python/temporal/stds_import.py
Log:
Better code and file structure. Fixed several doxygen errors and warnings.
More API documentation.
Modified: grass/trunk/lib/python/temporal/Makefile
===================================================================
--- grass/trunk/lib/python/temporal/Makefile 2013-04-19 08:52:02 UTC (rev 55913)
+++ grass/trunk/lib/python/temporal/Makefile 2013-04-19 12:20:22 UTC (rev 55914)
@@ -8,7 +8,7 @@
GDIR = $(PYDIR)/grass
DSTDIR = $(GDIR)/temporal
-MODULES = base core abstract_dataset abstract_temporal_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets space_time_datasets_tools metadata spatial_extent temporal_extent datetime_math temporal_granularity temporal_relationships unit_tests aggregation stds_export stds_import extract mapcalc univar_statistics
+MODULES = base core abstract_dataset abstract_temporal_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets create factory gui_support list register sampling metadata spatial_extent temporal_extent datetime_math temporal_granularity temporal_relationships unit_tests aggregation stds_export stds_import extract mapcalc univar_statistics
PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)
Modified: grass/trunk/lib/python/temporal/__init__.py
===================================================================
--- grass/trunk/lib/python/temporal/__init__.py 2013-04-19 08:52:02 UTC (rev 55913)
+++ grass/trunk/lib/python/temporal/__init__.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -8,10 +8,15 @@
from abstract_map_dataset import *
from abstract_space_time_dataset import *
from space_time_datasets import *
-from space_time_datasets_tools import *
from datetime_math import *
from temporal_granularity import *
from temporal_relationships import *
+from create import *
+from factory import *
+from gui_support import *
+from list import *
+from register import *
+from sampling import *
from aggregation import *
from extract import *
from stds_export import *
Modified: grass/trunk/lib/python/temporal/abstract_map_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_map_dataset.py 2013-04-19 08:52:02 UTC (rev 55913)
+++ grass/trunk/lib/python/temporal/abstract_map_dataset.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -66,7 +66,7 @@
This table stores all space time datasets in
which this map is registered.
- @param ident The name of the register table
+ @param name The name of the register table
"""
raise ImplementationError(
"This method must be implemented in the subclasses")
@@ -165,7 +165,7 @@
in the file system but not to identify
map information in the temporal database.
- @return The map id name at mapset
+ @return The map id "name at mapset"
"""
return self.base.get_map_id()
@@ -176,10 +176,10 @@
string will be reused
@param name The name of the map
- @param The mapset in which the map is located
- @layer The layer of the vector map, use None in case no layer exists
+ @param mapset The mapset in which the map is located
+ @param layer The layer of the vector map, use None in case no layer exists
- @return the id of the map as name(:layer)@mapset
+ @return the id of the map as "name(:layer)@mapset"
while layer is optional
"""
@@ -383,6 +383,7 @@
@param start_time a datetime object specifying the start time of the map
@param end_time a datetime object specifying the end time of the map, None in case or time instance
@param timezone Thee timezone of the map (not used)
+ @param dbif The database interface to be used
"""
dbif, connected = init_dbif(dbif)
@@ -463,6 +464,7 @@
@param start_time An integer value
@param end_time An integer value, None in case or time instance
+ @param unit The relative time unit
@param dbif The database interface to be used
"""
dbif, connected = init_dbif(dbif)
Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py 2013-04-19 08:52:02 UTC (rev 55913)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -1086,7 +1086,7 @@
This method renames the space time dataset, the map register table
and updates the entries in registered maps stds register.
- @param ident The new identifier name at mapset
+ @param ident The new identifier "name at mapset"
@param dbif The database interface to be used
"""
Modified: grass/trunk/lib/python/temporal/base.py
===================================================================
--- grass/trunk/lib/python/temporal/base.py 2013-04-19 08:52:02 UTC (rev 55913)
+++ grass/trunk/lib/python/temporal/base.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -68,9 +68,9 @@
>>> t.serialize(type="UPDATE ALL", table="raster_base")
('UPDATE raster_base SET name = ? ,creator = ? ,creation_time = ? ,modification_time = ? ,mapset = ? ,id = ? ;\\n', ('soil', 'soeren', datetime.datetime(2001, 1, 1, 0, 0), datetime.datetime(2001, 1, 1, 0, 0), 'PERMANENT', 'soil at PERMANENT'))
- @type must be SELECT. INSERT, UPDATE
- @table The name of the table to select, insert or update
- @where The optional where statement
+ @param type must be SELECT. INSERT, UPDATE
+ @param table The name of the table to select, insert or update
+ @param where The optional where statement
@return a tuple containing the SQL string and the arguments
\endcode
@@ -571,7 +571,7 @@
that should be used to store the values
@param ident The unique identifier must be a combination of
the dataset name, layer name and the mapset
- name at mapset or name:1 at mapset
+ "name at mapset" or "name:layer at mapset"
used as as primary key in the temporal database
@param name The name of the map or dataset
@param mapset The name of the mapset
@@ -604,7 +604,7 @@
@param ident The unique identifier must be a combination
of the dataset name, layer name and the mapset
- name at mapset or name:1 at mapset
+ "name at mapset" or "name:layer at mapset"
"""
self.ident = ident
self.D["id"] = ident
@@ -632,7 +632,7 @@
def set_mapset(self, mapset):
"""!Set the mapset of the dataset
- @param mapsets The name of the mapset in which this dataset is stored
+ @param mapset The name of the mapset in which this dataset is stored
"""
self.D["mapset"] = mapset
@@ -699,7 +699,7 @@
"""!Convenient method to get the unique map identifier
without layer information
- @return the name of the vector map as name at mapset
+ @return the name of the vector map as "name at mapset"
or None in case the id was not set
"""
if self.id:
Added: grass/trunk/lib/python/temporal/create.py
===================================================================
--- grass/trunk/lib/python/temporal/create.py (rev 0)
+++ grass/trunk/lib/python/temporal/create.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -0,0 +1,84 @@
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in Python scripts.
+
+Usage:
+
+ at code
+import grass.temporal as tgis
+
+tgis.register_maps_in_space_time_dataset(type, name, maps)
+
+...
+ 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 space_time_datasets import *
+
+###############################################################################
+
+def create_space_time_dataset(name, type, temporaltype, title, descr, semantic,
+ dbif=None, overwrite=False):
+ """!Create a new space time dataset
+
+ This function is sensitive to the settings in grass.core.overwrite to
+ overwrute existing space time datasets.
+
+ @param name The name of the new space time dataset
+ @param type The type (strds, stvds, str3ds) of the new space time dataset
+ @param temporaltype The temporal type (relative or absolute)
+ @param title The title
+ @param descr The dataset description
+ @param semantic Semantical information
+ @param dbif The temporal database interface to be used
+ @param overwrite Flag to allow overwriting
+
+ @return The new created space time dataset
+
+ This function will raise a ScriptError in case of an error.
+ """
+
+ #Get the current mapset to create the id of the space time dataset
+
+ mapset = core.gisenv()["MAPSET"]
+ id = name + "@" + mapset
+
+ sp = dataset_factory(type, id)
+
+ dbif, connected = init_dbif(dbif)
+
+ if sp.is_in_db(dbif) and overwrite == False:
+ if connected:
+ dbif.close()
+ core.fatal(_("Space time %s dataset <%s> is already in the database. "
+ "Use the overwrite flag.") %
+ (sp.get_new_map_instance(None).get_type(), name))
+ return None
+
+ if sp.is_in_db(dbif) and overwrite == True:
+ core.warning(_("Overwrite space time %s dataset <%s> "
+ "and unregister all maps.") %
+ (sp.get_new_map_instance(None).get_type(), name))
+ sp.delete(dbif)
+ sp = sp.get_new_instance(id)
+
+ core.verbose(_("Create new space time %s dataset.") %
+ sp.get_new_map_instance(None).get_type())
+
+ sp.set_initial_values(temporal_type=temporaltype, semantic_type=semantic,
+ title=title, description=descr)
+ sp.insert(dbif)
+
+ if connected:
+ dbif.close()
+
+ return sp
Added: grass/trunk/lib/python/temporal/factory.py
===================================================================
--- grass/trunk/lib/python/temporal/factory.py (rev 0)
+++ grass/trunk/lib/python/temporal/factory.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -0,0 +1,54 @@
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in Python scripts.
+
+Usage:
+
+ at code
+import grass.temporal as tgis
+
+tgis.register_maps_in_space_time_dataset(type, name, maps)
+
+...
+ 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 space_time_datasets import *
+
+###############################################################################
+
+
+def dataset_factory(type, id):
+ """!A factory functions to create space time or map datasets
+
+ @param type the dataset type: rast or raster, rast3d,
+ vect or vector, strds, str3ds, stvds
+ @param id The id of the dataset ("name at mapset")
+ """
+ if type == "strds":
+ sp = SpaceTimeRasterDataset(id)
+ elif type == "str3ds":
+ sp = SpaceTimeRaster3DDataset(id)
+ elif type == "stvds":
+ sp = SpaceTimeVectorDataset(id)
+ elif type == "rast" or type == "raster":
+ sp = RasterDataset(id)
+ elif type == "rast3d":
+ sp = Raster3DDataset(id)
+ elif type == "vect" or type == "vector":
+ sp = VectorDataset(id)
+ else:
+ core.error(_("Unknown dataset type: %s") % type)
+ return None
+
+ return sp
+
Added: grass/trunk/lib/python/temporal/gui_support.py
===================================================================
--- grass/trunk/lib/python/temporal/gui_support.py (rev 0)
+++ grass/trunk/lib/python/temporal/gui_support.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -0,0 +1,111 @@
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in Python scripts.
+
+
+(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 space_time_datasets import *
+
+###############################################################################
+
+def tlist_grouped(type, group_type = False):
+ """!List of temporal elements grouped by mapsets.
+
+ Returns a dictionary where the keys are mapset
+ names and the values are lists of space time datasets in that
+ mapset. Example:
+
+ @code
+ >>> tgis.tlist_grouped('strds')['PERMANENT']
+ ['precipitation', 'temperature']
+ @endcode
+
+ @param type element type (strds, str3ds, stvds)
+ @param group_type TBD
+
+ @return directory of mapsets/elements
+ """
+ result = {}
+
+ mapset = None
+ if type == 'stds':
+ types = ['strds', 'str3ds', 'stvds']
+ else:
+ types = [type]
+ for type in types:
+ try:
+ tlist_result = tlist(type)
+ except core.ScriptError, e:
+ warning(e)
+ continue
+
+ for line in tlist_result:
+ try:
+ name, mapset = line.split('@')
+ except ValueError:
+ warning(_("Invalid element '%s'") % line)
+ continue
+
+ if mapset not in result:
+ if group_type:
+ result[mapset] = {}
+ else:
+ result[mapset] = []
+
+ if group_type:
+ if type in result[mapset]:
+ result[mapset][type].append(name)
+ else:
+ result[mapset][type] = [name, ]
+ else:
+ result[mapset].append(name)
+
+ return result
+
+###############################################################################
+
+def tlist(type):
+ """!Return a list of space time datasets of absolute and relative time
+
+ @param type element type (strds, str3ds, stvds)
+
+ @return a list of space time dataset ids
+ """
+ id = None
+ sp = dataset_factory(type, id)
+
+ dbif = SQLDatabaseInterfaceConnection()
+ dbif.connect()
+
+ output = []
+ temporal_type = ["absolute", 'relative']
+ for type in temporal_type:
+ # Table name
+ if type == "absolute":
+ table = sp.get_type() + "_view_abs_time"
+ else:
+ table = sp.get_type() + "_view_rel_time"
+
+ # Create the sql selection statement
+ sql = "SELECT id FROM " + table
+ sql += " ORDER BY id"
+
+ dbif.cursor.execute(sql)
+ rows = dbif.cursor.fetchall()
+
+ # Append the ids of the space time datasets
+ for row in rows:
+ for col in row:
+ output.append(str(col))
+ dbif.close()
+
+ return output
Added: grass/trunk/lib/python/temporal/list.py
===================================================================
--- grass/trunk/lib/python/temporal/list.py (rev 0)
+++ grass/trunk/lib/python/temporal/list.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -0,0 +1,195 @@
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in Python scripts.
+
+Usage:
+
+ at code
+import grass.temporal as tgis
+
+tgis.register_maps_in_space_time_dataset(type, name, maps)
+
+...
+ 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 space_time_datasets import *
+
+###############################################################################
+
+def list_maps_of_stds(type, input, columns, order, where, separator, method, header, gran=None):
+ """! List the maps of a space time dataset using diffetent methods
+
+ @param type The type of the maps raster, raster3d or vector
+ @param input Name of a space time raster dataset
+ @param columns A comma separated list of columns to be printed to stdout
+ @param order A comma separated list of columns to order the
+ space time dataset by category
+ @param where A where statement for selected listing without "WHERE"
+ e.g: start_time < "2001-01-01" and end_time > "2001-01-01"
+ @param separator The field separator character between the columns
+ @param method String identifier to select a method out of cols,
+ comma,delta or deltagaps
+ - "cols" Print preselected columns specified by columns
+ - "comma" Print the map ids ("name at mapset") as comma separated string
+ - "delta" Print the map ids ("name at mapset") with start time,
+ end time, relative length of intervals and the relative
+ distance to the begin
+ - "deltagaps" Same as "delta" with additional listing of gaps.
+ Gaps can be simply identified as the id is "None"
+ - "gran" List map using the granularity of the space time dataset,
+ columns are identical to deltagaps
+ @param header Set True to print column names
+ @param gran The user defined granule to be used if method=gran is set, in case gran=None the
+ granule of the space time dataset is used
+ """
+ mapset = core.gisenv()["MAPSET"]
+
+ if input.find("@") >= 0:
+ id = input
+ else:
+ id = input + "@" + mapset
+
+ dbif, connected = init_dbif(None)
+
+ sp = dataset_factory(type, id)
+
+ if not sp.is_in_db(dbif=dbif):
+ core.fatal(_("Dataset <%s> not found in temporal database") % (id))
+
+ sp.select(dbif=dbif)
+
+ if separator is None or separator == "":
+ separator = "\t"
+
+ # This method expects a list of objects for gap detection
+ if method == "delta" or method == "deltagaps" or method == "gran":
+ if type == "stvds":
+ columns = "id,name,layer,mapset,start_time,end_time"
+ else:
+ columns = "id,name,mapset,start_time,end_time"
+ if method == "deltagaps":
+ maps = sp.get_registered_maps_as_objects_with_gaps(where=where, dbif=dbif)
+ elif method == "delta":
+ maps = sp.get_registered_maps_as_objects(where=where, order="start_time", dbif=dbif)
+ elif method == "gran":
+ if gran is not None and gran != "":
+ maps = sp.get_registered_maps_as_objects_by_granularity(gran=gran, dbif=dbif)
+ else:
+ maps = sp.get_registered_maps_as_objects_by_granularity(dbif=dbif)
+
+ if header:
+ string = ""
+ string += "%s%s" % ("id", separator)
+ string += "%s%s" % ("name", separator)
+ if type == "stvds":
+ string += "%s%s" % ("layer", separator)
+ string += "%s%s" % ("mapset", separator)
+ string += "%s%s" % ("start_time", separator)
+ string += "%s%s" % ("end_time", separator)
+ string += "%s%s" % ("interval_length", separator)
+ string += "%s" % ("distance_from_begin")
+ print string
+
+ if maps and len(maps) > 0:
+
+ if isinstance(maps[0], list):
+ if len(maps[0]) > 0:
+ first_time, dummy = maps[0][0].get_valid_time()
+ else:
+ core.warning(_("Empty map list."))
+ return
+ else:
+ first_time, dummy = maps[0].get_valid_time()
+
+ for mymap in maps:
+
+ if isinstance(mymap, list):
+ if len(mymap) > 0:
+ map = mymap[0]
+ else:
+ core.fatal(_("Empty entry in map list, this should not happen."))
+ else:
+ map = mymap
+
+ start, end = map.get_valid_time()
+ if end:
+ delta = end - start
+ else:
+ delta = None
+ delta_first = start - first_time
+
+ if map.is_time_absolute():
+ if end:
+ delta = time_delta_to_relative_time(delta)
+ delta_first = time_delta_to_relative_time(delta_first)
+
+ string = ""
+ string += "%s%s" % (map.get_id(), separator)
+ string += "%s%s" % (map.get_name(), separator)
+ if type == "stvds":
+ string += "%s%s" % (map.get_layer(), separator)
+ string += "%s%s" % (map.get_mapset(), separator)
+ string += "%s%s" % (start, separator)
+ string += "%s%s" % (end, separator)
+ string += "%s%s" % (delta, separator)
+ string += "%s" % (delta_first)
+ print string
+
+ else:
+ # In comma separated mode only map ids are needed
+ if method == "comma":
+ columns = "id"
+
+ rows = sp.get_registered_maps(columns, where, order, dbif)
+
+ if rows:
+ if method == "comma":
+ string = ""
+ count = 0
+ for row in rows:
+ if count == 0:
+ string += row["id"]
+ else:
+ string += ",%s" % row["id"]
+ count += 1
+ print string
+
+ elif method == "cols":
+ # Print the column names if requested
+ if header:
+ output = ""
+ count = 0
+
+ collist = columns.split(",")
+
+ for key in collist:
+ if count > 0:
+ output += separator + str(key)
+ else:
+ output += str(key)
+ count += 1
+ print output
+
+ for row in rows:
+ output = ""
+ count = 0
+ for col in row:
+ if count > 0:
+ output += separator + str(col)
+ else:
+ output += str(col)
+ count += 1
+
+ print output
+ if connected:
+ dbif.close()
Modified: grass/trunk/lib/python/temporal/mapcalc.py
===================================================================
--- grass/trunk/lib/python/temporal/mapcalc.py 2013-04-19 08:52:02 UTC (rev 55913)
+++ grass/trunk/lib/python/temporal/mapcalc.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -60,13 +60,13 @@
- end_second() - The minute of the end time [0 - 59]
- @param input The name of the input space time raster/raster3d dataset
+ @param inputs The names of the input space time raster/raster3d datasets
@param output The name of the extracted new space time raster(3d) dataset
@param type The type of the dataset: "raster" or "raster3d"
- @param method The method to be used for temporal sampling
@param expression The r(3).mapcalc expression
@param base The base name of the new created maps in case a
mapclac expression is provided
+ @param method The method to be used for temporal sampling
@param nprocs The number of parallel processes to be used for
mapcalc processing
@param register_null Set this number True to register empty maps
Modified: grass/trunk/lib/python/temporal/pythontemporallib.dox
===================================================================
--- grass/trunk/lib/python/temporal/pythontemporallib.dox 2013-04-19 08:52:02 UTC (rev 55913)
+++ grass/trunk/lib/python/temporal/pythontemporallib.dox 2013-04-19 12:20:22 UTC (rev 55914)
@@ -1,13 +1,30 @@
-/*! \page pythontemporallib GRASS Python Temporal Library
+/*! \page pythontemporallib GRASS GIS Temporal Framework
by GRASS Development Team (http://grass.osgeo.org)
-Python Temporal GIS package
+The GRASS GIS Temporal Framework
-TODO: add more detailed documentation
+\section PythonTGISIntro Introduction
-List of modules:
+The GRASS GIS Temporal Framework implements the temporal GIS functionality of GRASS GIS
+and provides an API to implement spatio-temporal processing modules. The framework
+introduces space time datasets that represent time series of raster, 3D raster or vector maps.
+This framework provides the following functionalities:
+- Assign time stamp to maps and register maps in the temporal database
+- Modification of time stamps
+- Creation, renaming and deletion of space time datasets
+- Registration and un-registration of maps in space time datasets
+- Query of maps that are registered in space time datasets using SQL where statements
+- Analysis of the spatio-temporal topology of space time datasets
+- Sampling of space time datasets
+- Computation of temporal and spatial relationships between registered maps
+- Higher level functions that are shared between modules
+Most of the functions described above are member functions of the maps and space time dataset classes.
+Maps and space time datasets are represented as objects in the temporal framework.
+
+\section PythonTGISPackages Library
+
Core functionality such as the database interface connection to sqlite3
and postgresql as well as the creation of the temporal database are defined here:
@@ -15,18 +32,17 @@
In these modules are the temporal database interfaces for raster maps,
3D raster maps, vector maps and space time datasets defined.
+In addition the temporal and spatial extent modules implement the topological
+relationship computation that is needed for spatio-temporal topology computation:
-Additionally the temporal and spatial extent modules implement the topological
-relationship computation that is needed for spatio-temporal topology computation.
-
- python::temporal::base
- python::temporal::spatial_extent
- python::temporal::temporal_extent
- python::temporal::metadata
-Several "abstract" modules are defined that implement the shared functionality
+Several "abstract" classes are defined that implement the shared functionality
of time stamped maps and space time datasets, such as temporal and spatial
-handling and representation.
+handling and representation:
- python::temporal::abstract_dataset
- python::temporal::abstract_temporal_dataset
@@ -42,27 +58,155 @@
and their conversion as well as topology computation are defined in these modules:
- python::temporal::datetime_math
+- python::temporal::temporal_granularity
- python::temporal::temporal_relationships
-- python::temporal::temporal_granularity
Functionality that is shared between different temporal GRASS modules, such as
-map listing, map registration and unregistration, aggregation, extraction,
-map calculation, statistics as well as import and export of
+map listing, space time dataset creation, map registration and unregistration,
+aggregation, extraction, map calculation, statistics as well as import and export of
space time datasets are defined here:
-- python::temporal::space_time_datasets_tools
- python::temporal::aggregation
+- python::temporal::create
- python::temporal::extract
+- python::temporal::factory
+- python::temporal::list
- python::temporal::mapcalc
+- python::temporal::register
+- python::temporal::sampling
- python::temporal::stds_export
- python::temporal::stds_import
- python::temporal::univar_statistics
+Two helper functions to support the listing of space time datasets in the automatically generated GUI:
+
+- python::temporal::gui_support
+
Lots of unit tests:
- python::temporal::unit_tests
-\section pythonTempAuthors Authors
+\section PythonTGISExamples Examples
+\subsection PythonTGISExamplesSimple Simple example
+
+This simple example shows how to open a space time raster dataset
+to access its registered maps.
+
+\code
+# Lets import the temporal framework and
+# the script framework
+import grass.temporal as tgis
+import grass.script as grass
+
+# Make sure the temporal database exists
+# and set the temporal GIS environment
+tgis.init()
+
+# We create the temporal database interface for fast processing
+dbif = tgis.SQLDatabaseInterfaceConnection()
+dbif.connect()
+
+# The id of a space time raster dataset is build from its name and its mapset
+id = "test at PERMANENT"
+
+# We create a space time raster dataset object
+strds = tgis.SpaceTimeRasterDataset(id)
+
+# Check if the space time raster dataset is in the temporal database
+if strds.is_in_db(dbif=dbif) == False:
+ dbif.close()
+ grass.fatal(_("Space time %s dataset <%s> not found") % (
+ strds.get_new_map_instance(None).get_type(), id))
+
+# Fill the object with the content from the temporal database
+strds.select(dbif=dbif)
+
+# Print informations about the space time raster dataset to stdout
+strds.print_info()
+
+# Get all maps that are registered in the strds and print
+# informations about the maps to stdout
+maps = strds.get_registered_maps_as_objects(dbif=dbif)
+
+# We iterate over the temporal sorted map list
+for map in maps:
+ # We fill the map object with the content
+ # from the temporal database. We use the existing
+ # database connection, otherwise a new connection
+ # will be established for each map object
+ # which slows the processing down
+ map.select(dbif=dbif)
+ map.print_info()
+
+# Close the database connection
+dbif.close()
+\endcode
+
+
+\subsection PythonTGISExamplesSTDSCreation Creation of a space time dataset
+
+This example shows howto create a space time dataset. The code is generic and works
+for different space time datasets (raster, 3D raster and vector):
+
+\code
+# Lets import the temporal framework and
+# the script framework
+import grass.temporal as tgis
+import grass.script as grass
+
+# The id of the new space time dataset
+id="test at PERMANENT"
+# The title of the new space time dataset
+title="This is a test dataset"
+# The description of the space time dataset
+description="The description"
+# The type of the space time dataset (strds, str3ds or stvds)
+type="strds"
+# The temporal type of the space time dataset (absolute or relative)
+temporal_type="absolute"
+
+# Make sure the temporal database exists
+# and set the temporal GIS environment
+tgis.init()
+
+# We use the dataset factory to create an new space time dataset instance of a specific type
+stds = tgis.dataset_factory(type, id)
+
+# We need a dtabase connection to insert the content of the space time dataset
+dbif = tgis.SQLDatabaseInterfaceConnection()
+dbif.connect()
+
+# First we check if the dataset is already in the database
+if stds.is_in_db(dbif=dbif) and overwrite == False:
+ dbif.close()
+ grass.fatal(_("Space time %s dataset <%s> is already in the database. "
+ "Use the overwrite flag.") %
+ (stds.get_new_map_instance(None).get_type(), name))
+
+# We delete the exiting dataset and create a new one in case we are allowed to overwrite it
+if stds.is_in_db(dbif=dbif) and overwrite == True:
+ grass.warning(_("Overwrite space time %s dataset <%s> "
+ "and unregister all maps.") %
+ (stds.get_new_map_instance(None).get_type(), name))
+ stds.delete(dbif=dbif)
+ stds = stds.get_new_instance(id)
+
+# We set the initial values. This function also created the command history.
+stds.set_initial_values(temporal_type=temporaltype, semantic_type="mean",
+ title=title, description=description)
+
+# Now we can insert the new space time dataset in the database
+stds.insert(dbif=dbif)
+
+# Close the database connection
+dbif.close()
+
+\endcode
+
+\section PythonTGISAuthors Authors
+
Soeren Gebbert
+
+TODO: add more documentation
*/
Added: grass/trunk/lib/python/temporal/register.py
===================================================================
--- grass/trunk/lib/python/temporal/register.py (rev 0)
+++ grass/trunk/lib/python/temporal/register.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -0,0 +1,419 @@
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in Python scripts.
+
+Usage:
+
+ at code
+import grass.temporal as tgis
+
+tgis.register_maps_in_space_time_dataset(type, name, maps)
+
+...
+ 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 space_time_datasets import *
+
+###############################################################################
+
+
+def register_maps_in_space_time_dataset(
+ type, name, maps=None, file=None, start=None,
+ end=None, unit=None, increment=None, dbif=None,
+ interval=False, fs="|"):
+ """!Use this method to register maps in 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.
+
+ @param type The type of the maps rast, rast3d or vect
+ @param name The name of the space time dataset
+ @param maps A comma separated list of map names
+ @param file Input file one map with start and optional end time,
+ one per line
+ @param 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 is integer 5)
+ @param 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 is integer 5)
+ @param unit The unit of the relative time: years, months, days,
+ hours, minutes, seconds
+ @param increment Time increment between maps for time stamp creation
+ (format absolute: NNN seconds, minutes, hours, days,
+ weeks, months, years; format relative: 1.0)
+ @param dbif The database interface to be used
+ @param interval If True, time intervals are created in case the start
+ time and an increment is provided
+ @param fs Field separator used in input file
+ """
+
+ start_time_in_file = False
+ end_time_in_file = False
+
+ if maps and file:
+ core.fatal(_("%s= and %s= are mutually exclusive") % ("maps", "file"))
+
+ if end and increment:
+ core.fatal(_("%s= and %s= are mutually exclusive") % (
+ "end", "increment"))
+
+ if end and not start:
+ core.fatal(_("Please specify %s= and %s=") % ("start_time",
+ "end_time"))
+
+ if not maps and not file:
+ core.fatal(_("Please specify %s= or %s=") % ("maps", "file"))
+
+ # We may need the mapset
+ mapset = core.gisenv()["MAPSET"]
+
+ # The name of the space time dataset is optional
+ if name:
+ # Check if the dataset name contains the mapset as well
+ if name.find("@") < 0:
+ id = name + "@" + mapset
+ else:
+ id = name
+
+ if type == "rast" or type == "raster":
+ sp = dataset_factory("strds", id)
+ elif type == "rast3d":
+ sp = dataset_factory("str3ds", id)
+ elif type == "vect" or type == "vector":
+ sp = dataset_factory("stvds", id)
+ else:
+ core.fatal(_("Unkown map type: %s") % (type))
+
+ dbif, connected = init_dbif(None)
+
+ if name:
+ # Read content from temporal database
+ sp.select(dbif)
+
+ if not sp.is_in_db(dbif):
+ dbif.close()
+ core.fatal(_("Space time %s dataset <%s> no found") %
+ (sp.get_new_map_instance(None).get_type(), name))
+
+ if sp.is_time_relative() and not unit:
+ dbif.close()
+ core.fatal(_("Space time %s dataset <%s> with relative time found, "
+ "but no relative unit set for %s maps") %
+ (sp.get_new_map_instance(None).get_type(),
+ name, sp.get_new_map_instance(None).get_type()))
+
+ # We need a dummy map object to build the map ids
+ dummy = dataset_factory(type, None)
+
+ maplist = []
+
+ # Map names as comma separated string
+ if maps:
+ if maps.find(",") < 0:
+ maplist = [maps, ]
+ else:
+ maplist = maps.split(",")
+
+ # Build the map list again with the ids
+ for count in range(len(maplist)):
+ row = {}
+ mapid = dummy.build_id(maplist[count], mapset, None)
+
+ row["id"] = mapid
+ maplist[count] = row
+
+ # Read the map list from file
+ if file:
+ fd = open(file, "r")
+
+ line = True
+ while True:
+ line = fd.readline()
+ if not line:
+ break
+
+ line_list = line.split(fs)
+
+ # Detect start and end time
+ if len(line_list) == 2:
+ start_time_in_file = True
+ end_time_in_file = False
+ elif len(line_list) == 3:
+ start_time_in_file = True
+ end_time_in_file = True
+ else:
+ start_time_in_file = False
+ end_time_in_file = False
+
+ mapname = line_list[0].strip()
+ row = {}
+
+ if start_time_in_file and end_time_in_file:
+ row["start"] = line_list[1].strip()
+ row["end"] = line_list[2].strip()
+
+ if start_time_in_file and not end_time_in_file:
+ row["start"] = line_list[1].strip()
+
+ row["id"] = dummy.build_id(mapname, mapset)
+
+ maplist.append(row)
+
+ num_maps = len(maplist)
+ map_object_list = []
+ statement = ""
+ # Store the ids of datasets that must be updated
+ datatsets_to_modify = {}
+
+ core.message(_("Gathering map informations"))
+
+ for count in range(len(maplist)):
+ if count%50 == 0:
+ core.percent(count, num_maps, 1)
+
+ # Get a new instance of the map type
+ map = dataset_factory(type, maplist[count]["id"])
+
+ # Use the time data from file
+ if "start" in maplist[count]:
+ start = maplist[count]["start"]
+ if "end" in maplist[count]:
+ end = maplist[count]["end"]
+
+ is_in_db = False
+
+ # Put the map into the database
+ if not map.is_in_db(dbif):
+ is_in_db = False
+ # Break in case no valid time is provided
+ if start == "" or start is None:
+ dbif.close()
+ if map.get_layer():
+ core.fatal(_("Unable to register %s map <%s> with layer %s. "
+ "The map has no valid time and the start time is not set.") %
+ (map.get_type(), map.get_map_id(), map.get_layer()))
+ else:
+ core.fatal(_("Unable to register %s map <%s>. The map has no valid"
+ " time and the start time is not set.") %
+ (map.get_type(), map.get_map_id()))
+
+ if unit:
+ map.set_time_to_relative()
+ else:
+ map.set_time_to_absolute()
+
+ else:
+ is_in_db = True
+
+ # Check the overwrite flag
+ if not core.overwrite():
+ if map.get_layer():
+ core.warning(_("Map is already registered in temporal database. "
+ "Unable to update %s map <%s> with layer %s. "
+ "Overwrite flag is not set.") %
+ (map.get_type(), map.get_map_id(), str(map.get_layer())))
+ else:
+ core.warning(_("Map is already registered in temporal database. "
+ "Unable to update %s map <%s>. "
+ "Overwrite flag is not set.") %
+ (map.get_type(), map.get_map_id()))
+
+ # Simple registration is allowed
+ if name:
+ map_object_list.append(map)
+ # Jump to next map
+ continue
+
+ # Select information from temporal database
+ map.select(dbif)
+
+ # Save the datasets that must be updated
+ datasets = map.get_registered_datasets(dbif)
+ if datasets:
+ for dataset in datasets:
+ datatsets_to_modify[dataset["id"]] = dataset["id"]
+
+ if name and map.get_temporal_type() != sp.get_temporal_type():
+ dbif.close()
+ if map.get_layer():
+ core.fatal(_("Unable to update %s map <%s> with layer. "
+ "The temporal types are different.") %
+ (map.get_type(), map.get_map_id(), map.get_layer()))
+ else:
+ core.fatal(_("Unable to update %s map <%s>. "
+ "The temporal types are different.") %
+ (map.get_type(), map.get_map_id()))
+
+ # Load the data from the grass file database
+ map.load()
+
+ # Set the valid time
+ if start:
+ # In case the time is in the input file we ignore the increment counter
+ if start_time_in_file:
+ count = 1
+ assign_valid_time_to_map(ttype=map.get_temporal_type(),
+ map=map, start=start, end=end, unit=unit,
+ increment=increment, mult=count,
+ interval=interval)
+
+ if is_in_db:
+ # Gather the SQL update statement
+ statement += map.update_all(dbif=dbif, execute=False)
+ else:
+ # Gather the SQL insert statement
+ statement += map.insert(dbif=dbif, execute=False)
+
+ # Sqlite3 performace better for huge datasets when committing in small chunks
+ if dbif.dbmi.__name__ == "sqlite3":
+ if count % 100 == 0:
+ if statement is not None and statement != "":
+ core.message(_("Registering maps in the temporal database")
+ )
+ dbif.execute_transaction(statement)
+ statement = ""
+
+ # Store the maps in a list to register in a space time dataset
+ if name:
+ map_object_list.append(map)
+
+ core.percent(num_maps, num_maps, 1)
+
+ if statement is not None and statement != "":
+ core.message(_("Register maps in the temporal database"))
+ dbif.execute_transaction(statement)
+
+ # Finally Register the maps in the space time dataset
+ if name and map_object_list:
+ statement = ""
+ count = 0
+ num_maps = len(map_object_list)
+ core.message(_("Register maps in the space time raster dataset"))
+ for map in map_object_list:
+ if count%50 == 0:
+ core.percent(count, num_maps, 1)
+ sp.register_map(map=map, dbif=dbif)
+ count += 1
+
+ # Update the space time tables
+ if name and map_object_list:
+ core.message(_("Update space time raster dataset"))
+ sp.update_from_registered_maps(dbif)
+ sp.update_command_string(dbif=dbif)
+
+ # Update affected datasets
+ if datatsets_to_modify:
+ for dataset in datatsets_to_modify:
+ if type == "rast" or type == "raster":
+ ds = dataset_factory("strds", dataset)
+ elif type == "rast3d":
+ ds = dataset_factory("str3ds", dataset)
+ elif type == "vect" or type == "vector":
+ ds = dataset_factory("stvds", dataset)
+ ds.select(dbif)
+ ds.update_from_registered_maps(dbif)
+
+ if connected == True:
+ dbif.close()
+
+ core.percent(num_maps, num_maps, 1)
+
+
+###############################################################################
+
+def assign_valid_time_to_map(ttype, map, start, end, unit, increment=None, mult=1, interval=False):
+ """!Assign the valid time to a map dataset
+
+ @param ttype The temporal type which should be assigned
+ and which the time format is of
+ @param map A map dataset object derived from abstract_map_dataset
+ @param 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 is integer 5)
+ @param 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 is integer 5)
+ @param unit The unit of the relative time: years, months,
+ days, hours, minutes, seconds
+ @param increment Time increment between maps for time stamp creation
+ (format absolute: NNN seconds, minutes, hours, days,
+ weeks, months, years; format relative is integer 1)
+ @param mult A multiplier for the increment
+ @param interval If True, time intervals are created in case the start
+ time and an increment is provided
+ """
+
+ if ttype == "absolute":
+ start_time = string_to_datetime(start)
+ if start_time is None:
+ core.fatal(_("Unable to convert string \"%s\"into a "
+ "datetime object") % (start))
+ end_time = None
+
+ if end:
+ end_time = string_to_datetime(end)
+ if end_time is None:
+ dbif.close()
+ core.fatal(_("Unable to convert string \"%s\"into a "
+ "datetime object") % (end))
+
+ # Add the increment
+ if increment:
+ start_time = increment_datetime_by_string(
+ start_time, increment, mult)
+ if start_time is None:
+ core.fatal(_("Error in increment computation"))
+ if interval:
+ end_time = increment_datetime_by_string(
+ start_time, increment, 1)
+ if end_time is None:
+ core.fatal(_("Error in increment computation"))
+ # Commented because of performance issue calling g.message thousend times
+ #if map.get_layer():
+ # core.verbose(_("Set absolute valid time for map <%(id)s> with "
+ # "layer %(layer)s to %(start)s - %(end)s") %
+ # {'id': map.get_map_id(), 'layer': map.get_layer(),
+ # 'start': str(start_time), 'end': str(end_time)})
+ #else:
+ # core.verbose(_("Set absolute valid time for map <%s> to %s - %s") %
+ # (map.get_map_id(), str(start_time), str(end_time)))
+
+ map.set_absolute_time(start_time, end_time, None)
+ else:
+ start_time = int(start)
+ end_time = None
+
+ if end:
+ end_time = int(end)
+
+ if increment:
+ start_time = start_time + mult * int(increment)
+ if interval:
+ end_time = start_time + int(increment)
+
+ # Commented because of performance issue calling g.message thousend times
+ #if map.get_layer():
+ # core.verbose(_("Set relative valid time for map <%s> with layer %s "
+ # "to %i - %s with unit %s") %
+ # (map.get_map_id(), map.get_layer(), start_time,
+ # str(end_time), unit))
+ #else:
+ # core.verbose(_("Set relative valid time for map <%s> to %i - %s "
+ # "with unit %s") % (map.get_map_id(), start_time,
+ # str(end_time), unit))
+
+ map.set_relative_time(start_time, end_time, unit)
Added: grass/trunk/lib/python/temporal/sampling.py
===================================================================
--- grass/trunk/lib/python/temporal/sampling.py (rev 0)
+++ grass/trunk/lib/python/temporal/sampling.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -0,0 +1,169 @@
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in Python scripts.
+
+Usage:
+
+ at code
+import grass.temporal as tgis
+
+tgis.register_maps_in_space_time_dataset(type, name, maps)
+
+...
+ 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 space_time_datasets import *
+
+###############################################################################
+
+def sample_stds_by_stds_topology(intype, sampletype, inputs, sampler, header,
+ separator, method, spatial=False,
+ print_only=True):
+ """!Sample the input space time datasets with a sample
+ space time dataset, return the created map matrix and optionally
+ print the result to stdout
+
+ In case multiple maps are located in the current granule,
+ the map names are separated by comma.
+
+ In case a layer is present, the names map ids are extended
+ in this form: "name:layer at mapset"
+
+ Attention: Do not use the comma as separator for printing
+
+ @param intype Type of the input space time dataset (strds, stvds or str3ds)
+ @param sampletype Type of the sample space time dataset (strds, stvds or str3ds)
+ @param inputs Name or comma separated names of space time datasets
+ @param sampler Name of a space time dataset used for temporal sampling
+ @param header Set True to print column names
+ @param separator The field separator character between the columns
+ @param method The method to be used for temporal sampling
+ (start,during,contain,overlap,equal)
+ @param spatial Perform spatial overlapping check
+ @param print_only If set True (default) then the result of the sampling will be
+ printed to stdout, if set to False the resulting map matrix
+ will be returned.
+
+ @return The map matrix or None if nothing found
+ """
+ mapset = core.gisenv()["MAPSET"]
+
+ # Make a method list
+ method = method.split(",")
+
+ # Split the inputs
+ input_list = inputs.split(",")
+ sts = []
+
+ for input in input_list:
+ if input.find("@") >= 0:
+ id = input
+ else:
+ id = input + "@" + mapset
+
+ st = dataset_factory(intype, id)
+ sts.append(st)
+
+ if sampler.find("@") >= 0:
+ sid = sampler
+ else:
+ sid = sampler + "@" + mapset
+
+ sst = dataset_factory(sampletype, sid)
+
+ dbif = SQLDatabaseInterfaceConnection()
+ dbif.connect()
+
+ for st in sts:
+ if st.is_in_db(dbif) == False:
+ core.fatal(_("Dataset <%s> not found in temporal database") % (st.get_id()))
+ st.select(dbif)
+
+ if sst.is_in_db(dbif) == False:
+ core.fatal(_("Dataset <%s> not found in temporal database") % (sid))
+
+ sst.select(dbif)
+
+ if separator is None or separator == "" or separator.find(",") >= 0:
+ separator = " | "
+
+ mapmatrizes = []
+ for st in sts:
+ mapmatrix = st.sample_by_dataset(sst, method, spatial, dbif)
+ if mapmatrix and len(mapmatrix) > 0:
+ mapmatrizes.append(mapmatrix)
+
+ if len(mapmatrizes) > 0:
+
+ # Simply return the map matrix
+ if not print_only:
+ dbif.close()
+ return mapmatrizes
+
+ if header:
+ string = ""
+ string += "%s%s" % (sst.get_id(), separator)
+ for st in sts:
+ string += "%s%s" % (st.get_id(), separator)
+ string += "%s%s" % ("start_time", separator)
+ string += "%s%s" % ("end_time", separator)
+ string += "%s%s" % ("interval_length", separator)
+ string += "%s" % ("distance_from_begin")
+ print string
+
+ first_time, dummy = mapmatrizes[0][0]["granule"].get_valid_time()
+
+ for i in range(len(mapmatrizes[0])):
+ mapname_list = []
+ for mapmatrix in mapmatrizes:
+ mapnames = ""
+ count = 0
+ entry = mapmatrix[i]
+ for sample in entry["samples"]:
+ if count == 0:
+ mapnames += str(sample.get_id())
+ else:
+ mapnames += ",%s" % str(sample.get_id())
+ count += 1
+ mapname_list.append(mapnames)
+
+ entry = mapmatrizes[0][i]
+ map = entry["granule"]
+
+ start, end = map.get_valid_time()
+ if end:
+ delta = end - start
+ else:
+ delta = None
+ delta_first = start - first_time
+
+ if map.is_time_absolute():
+ if end:
+ delta = time_delta_to_relative_time(delta)
+ delta_first = time_delta_to_relative_time(delta_first)
+
+ string = ""
+ string += "%s%s" % (map.get_id(), separator)
+ for mapnames in mapname_list:
+ string += "%s%s" % (mapnames, separator)
+ string += "%s%s" % (start, separator)
+ string += "%s%s" % (end, separator)
+ string += "%s%s" % (delta, separator)
+ string += "%s" % (delta_first)
+ print string
+
+ dbif.close()
+ if len(mapmatrizes) > 0:
+ return mapmatrizes
+
+ return None
Deleted: grass/trunk/lib/python/temporal/space_time_datasets_tools.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets_tools.py 2013-04-19 08:52:02 UTC (rev 55913)
+++ grass/trunk/lib/python/temporal/space_time_datasets_tools.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -1,917 +0,0 @@
-"""!@package grass.temporal
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related functions to be used in Python scripts.
-
-Usage:
-
- at code
-import grass.temporal as tgis
-
-tgis.register_maps_in_space_time_dataset(type, name, maps)
-
-...
- 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 space_time_datasets import *
-
-###############################################################################
-
-
-def register_maps_in_space_time_dataset(
- type, name, maps=None, file=None, start=None,
- end=None, unit=None, increment=None, dbif=None,
- interval=False, fs="|"):
- """!Use this method to register maps in 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.
-
- @param type The type of the maps rast, rast3d or vect
- @param name The name of the space time dataset
- @param maps A comma separated list of map names
- @param file Input file one map with start and optional end time,
- one per line
- @param 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 is integer 5)
- @param 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 is integer 5)
- @param unit The unit of the relative time: years, months, days,
- hours, minutes, seconds
- @param increment Time increment between maps for time stamp creation
- (format absolute: NNN seconds, minutes, hours, days,
- weeks, months, years; format relative: 1.0)
- @param dbif The database interface to be used
- @param interval If True, time intervals are created in case the start
- time and an increment is provided
- @param fs Field separator used in input file
- """
-
- start_time_in_file = False
- end_time_in_file = False
-
- if maps and file:
- core.fatal(_("%s= and %s= are mutually exclusive") % ("maps", "file"))
-
- if end and increment:
- core.fatal(_("%s= and %s= are mutually exclusive") % (
- "end", "increment"))
-
- if end and not start:
- core.fatal(_("Please specify %s= and %s=") % ("start_time",
- "end_time"))
-
- if not maps and not file:
- core.fatal(_("Please specify %s= or %s=") % ("maps", "file"))
-
- # We may need the mapset
- mapset = core.gisenv()["MAPSET"]
-
- # The name of the space time dataset is optional
- if name:
- # Check if the dataset name contains the mapset as well
- if name.find("@") < 0:
- id = name + "@" + mapset
- else:
- id = name
-
- if type == "rast" or type == "raster":
- sp = dataset_factory("strds", id)
- elif type == "rast3d":
- sp = dataset_factory("str3ds", id)
- elif type == "vect" or type == "vector":
- sp = dataset_factory("stvds", id)
- else:
- core.fatal(_("Unkown map type: %s") % (type))
-
- dbif, connected = init_dbif(None)
-
- if name:
- # Read content from temporal database
- sp.select(dbif)
-
- if not sp.is_in_db(dbif):
- dbif.close()
- core.fatal(_("Space time %s dataset <%s> no found") %
- (sp.get_new_map_instance(None).get_type(), name))
-
- if sp.is_time_relative() and not unit:
- dbif.close()
- core.fatal(_("Space time %s dataset <%s> with relative time found, "
- "but no relative unit set for %s maps") %
- (sp.get_new_map_instance(None).get_type(),
- name, sp.get_new_map_instance(None).get_type()))
-
- # We need a dummy map object to build the map ids
- dummy = dataset_factory(type, None)
-
- maplist = []
-
- # Map names as comma separated string
- if maps:
- if maps.find(",") < 0:
- maplist = [maps, ]
- else:
- maplist = maps.split(",")
-
- # Build the map list again with the ids
- for count in range(len(maplist)):
- row = {}
- mapid = dummy.build_id(maplist[count], mapset, None)
-
- row["id"] = mapid
- maplist[count] = row
-
- # Read the map list from file
- if file:
- fd = open(file, "r")
-
- line = True
- while True:
- line = fd.readline()
- if not line:
- break
-
- line_list = line.split(fs)
-
- # Detect start and end time
- if len(line_list) == 2:
- start_time_in_file = True
- end_time_in_file = False
- elif len(line_list) == 3:
- start_time_in_file = True
- end_time_in_file = True
- else:
- start_time_in_file = False
- end_time_in_file = False
-
- mapname = line_list[0].strip()
- row = {}
-
- if start_time_in_file and end_time_in_file:
- row["start"] = line_list[1].strip()
- row["end"] = line_list[2].strip()
-
- if start_time_in_file and not end_time_in_file:
- row["start"] = line_list[1].strip()
-
- row["id"] = dummy.build_id(mapname, mapset)
-
- maplist.append(row)
-
- num_maps = len(maplist)
- map_object_list = []
- statement = ""
- # Store the ids of datasets that must be updated
- datatsets_to_modify = {}
-
- core.message(_("Gathering map informations"))
-
- for count in range(len(maplist)):
- if count%50 == 0:
- core.percent(count, num_maps, 1)
-
- # Get a new instance of the map type
- map = dataset_factory(type, maplist[count]["id"])
-
- # Use the time data from file
- if "start" in maplist[count]:
- start = maplist[count]["start"]
- if "end" in maplist[count]:
- end = maplist[count]["end"]
-
- is_in_db = False
-
- # Put the map into the database
- if not map.is_in_db(dbif):
- is_in_db = False
- # Break in case no valid time is provided
- if start == "" or start is None:
- dbif.close()
- if map.get_layer():
- core.fatal(_("Unable to register %s map <%s> with layer %s. "
- "The map has no valid time and the start time is not set.") %
- (map.get_type(), map.get_map_id(), map.get_layer()))
- else:
- core.fatal(_("Unable to register %s map <%s>. The map has no valid"
- " time and the start time is not set.") %
- (map.get_type(), map.get_map_id()))
-
- if unit:
- map.set_time_to_relative()
- else:
- map.set_time_to_absolute()
-
- else:
- is_in_db = True
-
- # Check the overwrite flag
- if not core.overwrite():
- if map.get_layer():
- core.warning(_("Map is already registered in temporal database. "
- "Unable to update %s map <%s> with layer %s. "
- "Overwrite flag is not set.") %
- (map.get_type(), map.get_map_id(), str(map.get_layer())))
- else:
- core.warning(_("Map is already registered in temporal database. "
- "Unable to update %s map <%s>. "
- "Overwrite flag is not set.") %
- (map.get_type(), map.get_map_id()))
-
- # Simple registration is allowed
- if name:
- map_object_list.append(map)
- # Jump to next map
- continue
-
- # Select information from temporal database
- map.select(dbif)
-
- # Save the datasets that must be updated
- datasets = map.get_registered_datasets(dbif)
- if datasets:
- for dataset in datasets:
- datatsets_to_modify[dataset["id"]] = dataset["id"]
-
- if name and map.get_temporal_type() != sp.get_temporal_type():
- dbif.close()
- if map.get_layer():
- core.fatal(_("Unable to update %s map <%s> with layer. "
- "The temporal types are different.") %
- (map.get_type(), map.get_map_id(), map.get_layer()))
- else:
- core.fatal(_("Unable to update %s map <%s>. "
- "The temporal types are different.") %
- (map.get_type(), map.get_map_id()))
-
- # Load the data from the grass file database
- map.load()
-
- # Set the valid time
- if start:
- # In case the time is in the input file we ignore the increment counter
- if start_time_in_file:
- count = 1
- assign_valid_time_to_map(ttype=map.get_temporal_type(),
- map=map, start=start, end=end, unit=unit,
- increment=increment, mult=count,
- interval=interval)
-
- if is_in_db:
- # Gather the SQL update statement
- statement += map.update_all(dbif=dbif, execute=False)
- else:
- # Gather the SQL insert statement
- statement += map.insert(dbif=dbif, execute=False)
-
- # Sqlite3 performace better for huge datasets when committing in small chunks
- if dbif.dbmi.__name__ == "sqlite3":
- if count % 100 == 0:
- if statement is not None and statement != "":
- core.message(_("Registering maps in the temporal database")
- )
- dbif.execute_transaction(statement)
- statement = ""
-
- # Store the maps in a list to register in a space time dataset
- if name:
- map_object_list.append(map)
-
- core.percent(num_maps, num_maps, 1)
-
- if statement is not None and statement != "":
- core.message(_("Register maps in the temporal database"))
- dbif.execute_transaction(statement)
-
- # Finally Register the maps in the space time dataset
- if name and map_object_list:
- statement = ""
- count = 0
- num_maps = len(map_object_list)
- core.message(_("Register maps in the space time raster dataset"))
- for map in map_object_list:
- if count%50 == 0:
- core.percent(count, num_maps, 1)
- sp.register_map(map=map, dbif=dbif)
- count += 1
-
- # Update the space time tables
- if name and map_object_list:
- core.message(_("Update space time raster dataset"))
- sp.update_from_registered_maps(dbif)
- sp.update_command_string(dbif=dbif)
-
- # Update affected datasets
- if datatsets_to_modify:
- for dataset in datatsets_to_modify:
- if type == "rast" or type == "raster":
- ds = dataset_factory("strds", dataset)
- elif type == "rast3d":
- ds = dataset_factory("str3ds", dataset)
- elif type == "vect" or type == "vector":
- ds = dataset_factory("stvds", dataset)
- ds.select(dbif)
- ds.update_from_registered_maps(dbif)
-
- if connected == True:
- dbif.close()
-
- core.percent(num_maps, num_maps, 1)
-
-
-###############################################################################
-
-def assign_valid_time_to_map(ttype, map, start, end, unit, increment=None, mult=1, interval=False):
- """!Assign the valid time to a map dataset
-
- @param ttype The temporal type which should be assigned
- and which the time format is of
- @param map A map dataset object derived from abstract_map_dataset
- @param 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 is integer 5)
- @param 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 is integer 5)
- @param unit The unit of the relative time: years, months,
- days, hours, minutes, seconds
- @param increment Time increment between maps for time stamp creation
- (format absolute: NNN seconds, minutes, hours, days,
- weeks, months, years; format relative is integer 1)
- @param multi A multiplier for the increment
- @param interval If True, time intervals are created in case the start
- time and an increment is provided
- """
-
- if ttype == "absolute":
- start_time = string_to_datetime(start)
- if start_time is None:
- core.fatal(_("Unable to convert string \"%s\"into a "
- "datetime object") % (start))
- end_time = None
-
- if end:
- end_time = string_to_datetime(end)
- if end_time is None:
- dbif.close()
- core.fatal(_("Unable to convert string \"%s\"into a "
- "datetime object") % (end))
-
- # Add the increment
- if increment:
- start_time = increment_datetime_by_string(
- start_time, increment, mult)
- if start_time is None:
- core.fatal(_("Error in increment computation"))
- if interval:
- end_time = increment_datetime_by_string(
- start_time, increment, 1)
- if end_time is None:
- core.fatal(_("Error in increment computation"))
- # Commented because of performance issue calling g.message thousend times
- #if map.get_layer():
- # core.verbose(_("Set absolute valid time for map <%(id)s> with "
- # "layer %(layer)s to %(start)s - %(end)s") %
- # {'id': map.get_map_id(), 'layer': map.get_layer(),
- # 'start': str(start_time), 'end': str(end_time)})
- #else:
- # core.verbose(_("Set absolute valid time for map <%s> to %s - %s") %
- # (map.get_map_id(), str(start_time), str(end_time)))
-
- map.set_absolute_time(start_time, end_time, None)
- else:
- start_time = int(start)
- end_time = None
-
- if end:
- end_time = int(end)
-
- if increment:
- start_time = start_time + mult * int(increment)
- if interval:
- end_time = start_time + int(increment)
-
- # Commented because of performance issue calling g.message thousend times
- #if map.get_layer():
- # core.verbose(_("Set relative valid time for map <%s> with layer %s "
- # "to %i - %s with unit %s") %
- # (map.get_map_id(), map.get_layer(), start_time,
- # str(end_time), unit))
- #else:
- # core.verbose(_("Set relative valid time for map <%s> to %i - %s "
- # "with unit %s") % (map.get_map_id(), start_time,
- # str(end_time), unit))
-
- map.set_relative_time(start_time, end_time, unit)
-
-###############################################################################
-
-
-def dataset_factory(type, id):
- """!A factory functions to create space time or map datasets
-
- @param type the dataset type: rast or raster, rast3d,
- vect or vector, strds, str3ds, stvds
- @param id The id of the dataset ("name at mapset")
- """
- if type == "strds":
- sp = SpaceTimeRasterDataset(id)
- elif type == "str3ds":
- sp = SpaceTimeRaster3DDataset(id)
- elif type == "stvds":
- sp = SpaceTimeVectorDataset(id)
- elif type == "rast" or type == "raster":
- sp = RasterDataset(id)
- elif type == "rast3d":
- sp = Raster3DDataset(id)
- elif type == "vect" or type == "vector":
- sp = VectorDataset(id)
- else:
- core.error(_("Unknown dataset type: %s") % type)
- return None
-
- return sp
-
-###############################################################################
-
-
-def list_maps_of_stds(type, input, columns, order, where, separator, method, header, gran=None):
- """! List the maps of a space time dataset using diffetent methods
-
- @param type The type of the maps raster, raster3d or vector
- @param input Name of a space time raster dataset
- @param columns A comma separated list of columns to be printed to stdout
- @param order A comma separated list of columns to order the
- space time dataset by category
- @param where A where statement for selected listing without "WHERE"
- e.g: start_time < "2001-01-01" and end_time > "2001-01-01"
- @param separator The field separator character between the columns
- @param method String identifier to select a method out of cols,
- comma,delta or deltagaps
- - "cols" Print preselected columns specified by columns
- - "comma" Print the map ids (name at mapset) as comma separated string
- - "delta" Print the map ids (name at mapset) with start time,
- end time, relative length of intervals and the relative
- distance to the begin
- - "deltagaps" Same as "delta" with additional listing of gaps.
- Gaps can be simply identified as the id is "None"
- - "gran" List map using the granularity of the space time dataset,
- columns are identical to deltagaps
- @param header Set True to print column names
- @param gran The user defined granule to be used if method=gran is set, in case gran=None the
- granule of the space time dataset is used
- """
- mapset = core.gisenv()["MAPSET"]
-
- if input.find("@") >= 0:
- id = input
- else:
- id = input + "@" + mapset
-
- dbif, connected = init_dbif(None)
-
- sp = dataset_factory(type, id)
-
- if not sp.is_in_db(dbif=dbif):
- core.fatal(_("Dataset <%s> not found in temporal database") % (id))
-
- sp.select(dbif=dbif)
-
- if separator is None or separator == "":
- separator = "\t"
-
- # This method expects a list of objects for gap detection
- if method == "delta" or method == "deltagaps" or method == "gran":
- if type == "stvds":
- columns = "id,name,layer,mapset,start_time,end_time"
- else:
- columns = "id,name,mapset,start_time,end_time"
- if method == "deltagaps":
- maps = sp.get_registered_maps_as_objects_with_gaps(where=where, dbif=dbif)
- elif method == "delta":
- maps = sp.get_registered_maps_as_objects(where=where, order="start_time", dbif=dbif)
- elif method == "gran":
- if gran is not None and gran != "":
- maps = sp.get_registered_maps_as_objects_by_granularity(gran=gran, dbif=dbif)
- else:
- maps = sp.get_registered_maps_as_objects_by_granularity(dbif=dbif)
-
- if header:
- string = ""
- string += "%s%s" % ("id", separator)
- string += "%s%s" % ("name", separator)
- if type == "stvds":
- string += "%s%s" % ("layer", separator)
- string += "%s%s" % ("mapset", separator)
- string += "%s%s" % ("start_time", separator)
- string += "%s%s" % ("end_time", separator)
- string += "%s%s" % ("interval_length", separator)
- string += "%s" % ("distance_from_begin")
- print string
-
- if maps and len(maps) > 0:
-
- if isinstance(maps[0], list):
- if len(maps[0]) > 0:
- first_time, dummy = maps[0][0].get_valid_time()
- else:
- core.warning(_("Empty map list."))
- return
- else:
- first_time, dummy = maps[0].get_valid_time()
-
- for mymap in maps:
-
- if isinstance(mymap, list):
- if len(mymap) > 0:
- map = mymap[0]
- else:
- core.fatal(_("Empty entry in map list, this should not happen."))
- else:
- map = mymap
-
- start, end = map.get_valid_time()
- if end:
- delta = end - start
- else:
- delta = None
- delta_first = start - first_time
-
- if map.is_time_absolute():
- if end:
- delta = time_delta_to_relative_time(delta)
- delta_first = time_delta_to_relative_time(delta_first)
-
- string = ""
- string += "%s%s" % (map.get_id(), separator)
- string += "%s%s" % (map.get_name(), separator)
- if type == "stvds":
- string += "%s%s" % (map.get_layer(), separator)
- string += "%s%s" % (map.get_mapset(), separator)
- string += "%s%s" % (start, separator)
- string += "%s%s" % (end, separator)
- string += "%s%s" % (delta, separator)
- string += "%s" % (delta_first)
- print string
-
- else:
- # In comma separated mode only map ids are needed
- if method == "comma":
- columns = "id"
-
- rows = sp.get_registered_maps(columns, where, order, dbif)
-
- if rows:
- if method == "comma":
- string = ""
- count = 0
- for row in rows:
- if count == 0:
- string += row["id"]
- else:
- string += ",%s" % row["id"]
- count += 1
- print string
-
- elif method == "cols":
- # Print the column names if requested
- if header:
- output = ""
- count = 0
-
- collist = columns.split(",")
-
- for key in collist:
- if count > 0:
- output += separator + str(key)
- else:
- output += str(key)
- count += 1
- print output
-
- for row in rows:
- output = ""
- count = 0
- for col in row:
- if count > 0:
- output += separator + str(col)
- else:
- output += str(col)
- count += 1
-
- print output
- if connected:
- dbif.close()
-###############################################################################
-
-
-def sample_stds_by_stds_topology(intype, sampletype, inputs, sampler, header,
- separator, method, spatial=False,
- print_only=True):
- """!Sample the input space time datasets with a sample
- space time dataset, return the created map matrix and optionally
- print the result to stdout
-
- In case multiple maps are located in the current granule,
- the map names are separated by comma.
-
- In case a layer is present, the names map ids are extended
- in this form: name:layer at mapset
-
- Attention: Do not use the comma as separator for printing
-
- @param intype Type of the input space time dataset (strds, stvds or str3ds)
- @param samtype Type of the sample space time dataset (strds, stvds or str3ds)
- @param inputs Name or comma separated names of space time datasets
- @param sampler Name of a space time dataset used for temporal sampling
- @param header Set True to print column names
- @param separator The field separator character between the columns
- @param method The method to be used for temporal sampling
- (start,during,contain,overlap,equal)
- @param spatial Perform spatial overlapping check
- @param print_only If set True (default) then the result of the sampling will be
- printed to stdout, if set to False the resulting map matrix
- will be returned.
-
- @return The map matrix or None if nothing found
- """
- mapset = core.gisenv()["MAPSET"]
-
- # Make a method list
- method = method.split(",")
-
- # Split the inputs
- input_list = inputs.split(",")
- sts = []
-
- for input in input_list:
- if input.find("@") >= 0:
- id = input
- else:
- id = input + "@" + mapset
-
- st = dataset_factory(intype, id)
- sts.append(st)
-
- if sampler.find("@") >= 0:
- sid = sampler
- else:
- sid = sampler + "@" + mapset
-
- sst = dataset_factory(sampletype, sid)
-
- dbif = SQLDatabaseInterfaceConnection()
- dbif.connect()
-
- for st in sts:
- if st.is_in_db(dbif) == False:
- core.fatal(_("Dataset <%s> not found in temporal database") % (st.get_id()))
- st.select(dbif)
-
- if sst.is_in_db(dbif) == False:
- core.fatal(_("Dataset <%s> not found in temporal database") % (sid))
-
- sst.select(dbif)
-
- if separator is None or separator == "" or separator.find(",") >= 0:
- separator = " | "
-
- mapmatrizes = []
- for st in sts:
- mapmatrix = st.sample_by_dataset(sst, method, spatial, dbif)
- if mapmatrix and len(mapmatrix) > 0:
- mapmatrizes.append(mapmatrix)
-
- if len(mapmatrizes) > 0:
-
- # Simply return the map matrix
- if not print_only:
- dbif.close()
- return mapmatrizes
-
- if header:
- string = ""
- string += "%s%s" % (sst.get_id(), separator)
- for st in sts:
- string += "%s%s" % (st.get_id(), separator)
- string += "%s%s" % ("start_time", separator)
- string += "%s%s" % ("end_time", separator)
- string += "%s%s" % ("interval_length", separator)
- string += "%s" % ("distance_from_begin")
- print string
-
- first_time, dummy = mapmatrizes[0][0]["granule"].get_valid_time()
-
- for i in range(len(mapmatrizes[0])):
- mapname_list = []
- for mapmatrix in mapmatrizes:
- mapnames = ""
- count = 0
- entry = mapmatrix[i]
- for sample in entry["samples"]:
- if count == 0:
- mapnames += str(sample.get_id())
- else:
- mapnames += ",%s" % str(sample.get_id())
- count += 1
- mapname_list.append(mapnames)
-
- entry = mapmatrizes[0][i]
- map = entry["granule"]
-
- start, end = map.get_valid_time()
- if end:
- delta = end - start
- else:
- delta = None
- delta_first = start - first_time
-
- if map.is_time_absolute():
- if end:
- delta = time_delta_to_relative_time(delta)
- delta_first = time_delta_to_relative_time(delta_first)
-
- string = ""
- string += "%s%s" % (map.get_id(), separator)
- for mapnames in mapname_list:
- string += "%s%s" % (mapnames, separator)
- string += "%s%s" % (start, separator)
- string += "%s%s" % (end, separator)
- string += "%s%s" % (delta, separator)
- string += "%s" % (delta_first)
- print string
-
- dbif.close()
- if len(mapmatrizes) > 0:
- return mapmatrizes
-
- return None
-
-###############################################################################
-
-def tlist_grouped(type, group_type = False):
- """!List of temporal elements grouped by mapsets.
-
- Returns a dictionary where the keys are mapset
- names and the values are lists of space time datasets in that
- mapset. Example:
-
- @code
- >>> tgis.tlist_grouped('strds')['PERMANENT']
- ['precipitation', 'temperature']
- @endcode
-
- @param type element type (strds, str3ds, stvds)
-
- @return directory of mapsets/elements
- """
- result = {}
-
- mapset = None
- if type == 'stds':
- types = ['strds', 'str3ds', 'stvds']
- else:
- types = [type]
- for type in types:
- try:
- tlist_result = tlist(type)
- except core.ScriptError, e:
- warning(e)
- continue
-
- for line in tlist_result:
- try:
- name, mapset = line.split('@')
- except ValueError:
- warning(_("Invalid element '%s'") % line)
- continue
-
- if mapset not in result:
- if group_type:
- result[mapset] = {}
- else:
- result[mapset] = []
-
- if group_type:
- if type in result[mapset]:
- result[mapset][type].append(name)
- else:
- result[mapset][type] = [name, ]
- else:
- result[mapset].append(name)
-
- return result
-
-###############################################################################
-
-def tlist(type):
- """!Return a list of space time datasets of absolute and relative time
-
- @param type element type (strds, str3ds, stvds)
-
- @return a list of space time dataset ids
- """
- id = None
- sp = dataset_factory(type, id)
-
- dbif = SQLDatabaseInterfaceConnection()
- dbif.connect()
-
- output = []
- temporal_type = ["absolute", 'relative']
- for type in temporal_type:
- # Table name
- if type == "absolute":
- table = sp.get_type() + "_view_abs_time"
- else:
- table = sp.get_type() + "_view_rel_time"
-
- # Create the sql selection statement
- sql = "SELECT id FROM " + table
- sql += " ORDER BY id"
-
- dbif.cursor.execute(sql)
- rows = dbif.cursor.fetchall()
-
- # Append the ids of the space time datasets
- for row in rows:
- for col in row:
- output.append(str(col))
- dbif.close()
-
- return output
-
-###############################################################################
-
-def create_space_time_dataset(name, type, temporaltype, title, descr, semantic,
- dbif=None, overwrite=False):
- """!Create a new space time dataset
-
- This function is sensitive to the settings in grass.core.overwrite to
- overwrute existing space time datasets.
-
- @param name The name of the new space time dataset
- @param type The type (strds, stvds, str3ds) of the new space time dataset
- @param temporaltype The temporal type (relative or absolute)
- @param title The title
- @param descr The dataset description
- @param semantic Semantical information
- @param dbif The temporal database interface to be used
-
- @return The new created space time dataset
-
- This function will raise a ScriptError in case of an error.
- """
-
- #Get the current mapset to create the id of the space time dataset
-
- mapset = core.gisenv()["MAPSET"]
- id = name + "@" + mapset
-
- print id
- print overwrite
-
- sp = dataset_factory(type, id)
-
- dbif, connected = init_dbif(dbif)
-
- if sp.is_in_db(dbif) and overwrite == False:
- if connected:
- dbif.close()
- core.fatal(_("Space time %s dataset <%s> is already in the database. "
- "Use the overwrite flag.") %
- (sp.get_new_map_instance(None).get_type(), name))
- return None
-
- if sp.is_in_db(dbif) and overwrite == True:
- core.warning(_("Overwrite space time %s dataset <%s> "
- "and unregister all maps.") %
- (sp.get_new_map_instance(None).get_type(), name))
- sp.delete(dbif)
- sp = sp.get_new_instance(id)
-
- core.verbose(_("Create new space time %s dataset.") %
- sp.get_new_map_instance(None).get_type())
-
- sp.set_initial_values(temporal_type=temporaltype, semantic_type=semantic,
- title=title, description=descr)
- sp.insert(dbif)
-
- if connected:
- dbif.close()
-
- return sp
Modified: grass/trunk/lib/python/temporal/stds_import.py
===================================================================
--- grass/trunk/lib/python/temporal/stds_import.py 2013-04-19 08:52:02 UTC (rev 55913)
+++ grass/trunk/lib/python/temporal/stds_import.py 2013-04-19 12:20:22 UTC (rev 55914)
@@ -157,7 +157,7 @@
@param output The name of the output space time dataset
@param extrdir The extraction directory
@param title The title of the new created space time dataset
- @param description The description of the new created
+ @param descr The description of the new created
space time dataset
@param location The name of the location that should be created,
maps are imported into this location
More information about the grass-commit
mailing list