[GRASS-SVN] r55998 - grass/trunk/lib/python/temporal
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Apr 25 16:07:37 PDT 2013
Author: huhabla
Date: 2013-04-25 16:07:37 -0700 (Thu, 25 Apr 2013)
New Revision: 55998
Added:
grass/trunk/lib/python/temporal/spatial_topology_dataset_connector.py
grass/trunk/lib/python/temporal/spatio_temporal_relationships.py
grass/trunk/lib/python/temporal/temporal_topology_dataset_connector.py
Removed:
grass/trunk/lib/python/temporal/abstract_spatial_dataset.py
grass/trunk/lib/python/temporal/abstract_temporal_dataset.py
grass/trunk/lib/python/temporal/temporal_relationships.py
Modified:
grass/trunk/lib/python/temporal/Makefile
grass/trunk/lib/python/temporal/__init__.py
grass/trunk/lib/python/temporal/abstract_dataset.py
grass/trunk/lib/python/temporal/abstract_map_dataset.py
grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
grass/trunk/lib/python/temporal/space_time_datasets.py
grass/trunk/lib/python/temporal/unit_tests.py
Log:
Better naming scheme. Added spatial topology class.
Modified: grass/trunk/lib/python/temporal/Makefile
===================================================================
--- grass/trunk/lib/python/temporal/Makefile 2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/Makefile 2013-04-25 23:07:37 UTC (rev 55998)
@@ -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 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
+MODULES = base core abstract_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 spatio_temporal_relationships unit_tests aggregation stds_export stds_import extract mapcalc univar_statistics temporal_topology_dataset_connector spatial_topology_dataset_connector
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-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/__init__.py 2013-04-25 23:07:37 UTC (rev 55998)
@@ -3,14 +3,15 @@
from temporal_extent import *
from spatial_extent import *
from metadata import *
+from temporal_topology_dataset_connector import *
+from spatial_topology_dataset_connector import *
from abstract_dataset import *
-from abstract_temporal_dataset import *
from abstract_map_dataset import *
from abstract_space_time_dataset import *
from space_time_datasets import *
from datetime_math import *
from temporal_granularity import *
-from temporal_relationships import *
+from spatio_temporal_relationships import *
from create import *
from factory import *
from gui_support import *
Modified: grass/trunk/lib/python/temporal/abstract_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_dataset.py 2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/abstract_dataset.py 2013-04-25 23:07:37 UTC (rev 55998)
@@ -35,6 +35,8 @@
from temporal_extent import *
from spatial_extent import *
from metadata import *
+from temporal_topology_dataset_connector import *
+from spatial_topology_dataset_connector import *
class ImplementationError(Exception):
@@ -48,12 +50,96 @@
###############################################################################
-class AbstractDataset(object):
+class AbstractDataset(SpatialTopologyDatasetConnector, TemporalTopologyDatasetConnector):
"""!This is the base class for all datasets
(raster, vector, raster3d, strds, stvds, str3ds)"""
def __init__(self):
- pass
+ SpatialTopologyDatasetConnector.__init__(self)
+ TemporalTopologyDatasetConnector.__init__(self)
+
+ def reset_topology(self):
+ """!Reset any information about temporal topology"""
+ self.reset_spatial_topology()
+ self.reset_temporal_topology()
+
+ def get_number_of_relations(self):
+ """! Return a dictionary in which the keys are the relation names and the value
+ are the number of relations.
+
+ The following relations are available:
+
+ Spatial relations
+ - equivalent
+ - overlap
+ - in
+ - contain
+ - meet
+ - cover
+ - covered
+
+ Temporal relations
+ - equal
+ - follows
+ - precedes
+ - overlaps
+ - overlapped
+ - during (including starts, finishes)
+ - contains (including started, finished)
+ - starts
+ - started
+ - finishes
+ - finished
+
+ To access topological information the spatial, temporal or booth topologies must be build first
+ using the SpatialTopologyBuilder, TemporalTopologyBuilder or SpatioTemporalTopologyBuilder.
+
+ @return the dictionary with relations as keys and number as values or None in case the topology wasn't build
+ """
+ if self.is_temporal_topology_build() and not self.is_spatial_topology_build():
+ return self.get_number_of_temporal_relations()
+ elif self.is_spatial_topology_build() and not self.is_temporal_topology_build():
+ self.get_number_of_spatial_relations()
+ else:
+ return self.get_number_of_temporal_relations() + \
+ self.get_number_of_spatial_relations()
+
+ return None
+ def set_topology_build_true(self):
+ """!Use this method when the spatio-temporal topology was build"""
+ self.set_spatial_topology_build_true()
+ self.set_temporal_topology_build_true()
+
+
+ def set_topology_build_false(self):
+ """!Use this method when the spatio-temporal topology was not build"""
+ self.set_spatial_topology_build_false()
+ self.set_temporal_topology_build_false()
+
+ def is_topology_build(self):
+ """!Check if the spatial and temporal topology was build
+
+ @return A dictionary with "spatial" and "temporal" as keys that have boolen values
+ """
+ d = {}
+ d["spatial"] = self.is_spatial_topology_build()
+ d["temporal"] = self.is_temporal_topology_build()
+
+ return d
+
+
+ def print_topology_info(self):
+ if self.is_temporal_topology_build():
+ self.print_temporal_topology_info()
+ if self.is_spatial_topology_build():
+ self.print_spatial_topology_info()
+
+ def print_topology_shell_info(self):
+ if self.is_temporal_topology_build():
+ self.print_temporal_topology_shell_info()
+ if self.is_spatial_topology_build():
+ self.print_spatial_topology_shell_info()
+
def reset(self, ident):
"""!Reset the internal structure and set the identifier
Modified: grass/trunk/lib/python/temporal/abstract_map_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_map_dataset.py 2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/abstract_map_dataset.py 2013-04-25 23:07:37 UTC (rev 55998)
@@ -17,10 +17,10 @@
@author Soeren Gebbert
"""
-from abstract_temporal_dataset import *
+from abstract_dataset import *
from datetime_math import *
-class AbstractMapDataset(AbstractTemporalDataset):
+class AbstractMapDataset(AbstractDataset):
"""!This is the base class for all maps (raster, vector, raster3d).
The temporal extent, the spatial extent and the metadata of maps
@@ -37,7 +37,7 @@
- Abstract methods that must be implemented in the map specific subclasses
"""
def __init__(self):
- AbstractTemporalDataset.__init__(self)
+ AbstractDataset.__init__(self)
def get_new_stds_instance(self, ident):
"""!Return a new space time dataset instance that store maps with the type of this map object (rast, rast3d or vect)
Modified: grass/trunk/lib/python/temporal/abstract_space_time_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_space_time_dataset.py 2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/abstract_space_time_dataset.py 2013-04-25 23:07:37 UTC (rev 55998)
@@ -15,7 +15,7 @@
import sys
from abstract_dataset import *
from temporal_granularity import *
-from temporal_relationships import *
+from spatio_temporal_relationships import *
###############################################################################
@@ -973,7 +973,7 @@
dbif, connected = init_dbif(dbif)
obj_list = self.get_registered_maps_as_objects(where, order, dbif)
- tb = TemporalTopologyBuilder()
+ tb = SpatioTemporalTopologyBuilder()
tb.build(obj_list)
if connected:
Deleted: grass/trunk/lib/python/temporal/abstract_spatial_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_spatial_dataset.py 2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/abstract_spatial_dataset.py 2013-04-25 23:07:37 UTC (rev 55998)
@@ -1,370 +0,0 @@
-# -*- coding: utf-8 -*-
-"""!@package grass.temporal
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related functions to be used in temporal GIS Python library package.
-
-Usage:
-
->>> import grass.temporal as tgis
->>> tmr = tgis.AbstractSpatialDataset()
-
-(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 abstract_dataset import *
-from datetime_math import *
-
-
-class AbstractTemporalDataset(AbstractDataset):
- """!This class implements a spatial topology access structure for an abstract dataset
-
- This object will be set up by spatial topology creation method provided by the
- SpatialTopologyBuilder.
-
- The following spatial relations with access methods are supported:
- - equivalent
- - overlap
- - in
- - contain
- - meet
- - cover
- - covered
-
- Usage:
-
- @code
-
- >>> import grass.temporal as tgis
- >>> tgis.init()
- >>> map = tgis.RasterDataset("a at P")
- >>> tmr = tgis.AbstractTemporalDataset()
- >>> tmr.append_equivalent(map)
- >>> tmr.append_overlap(map)
- >>> tmr.append_in(map)
- >>> tmr.append_contain(map)
- >>> tmr.append_meet(map)
- >>> tmr.append_cover(map)
- >>> tmr.append_covered(map)
- >>> tmr.print_topology_info()
- +-------------------- Spatial Topology --------------------------------------+
- | Equivalent: ................ a at P
- | Cover: ..................... a at P
- | Covered: ................... a at P
- | Overlap: ................... a at P
- | In: ........................ a at P
- | Contain: ................... a at P
- | Meet: ...................... a at P
- >>> tmr.print_topology_shell_info()
- equivalent=a at P
- overlap=a at P
- in=a at P
- contain=a at P
- meet=a at P
- cover=a at P
- covered=a at P
-
- @endcode
- """
-
- def __init__(self):
- AbstractDataset.__init__(self)
- self.reset_topology()
-
- def reset_topology(self):
- """!Reset any information about temporal topology"""
- self._topology = {}
- self._has_topology = False
-
- def get_number_of_relations(self):
- """! Return a dictionary in which the keys are the relation names and the value
- are the number of relations.
-
- The following relations are available:
- - equivalent
- - overlap
- - in
- - contain
- - meet
- - cover
- - covered
-
- To access topological information the spatial topology must be build first
- using the SpatialTopologyBuilder.
-
- @return the dictionary with relations as keys and number as values or None in case the topology wasn't build
- """
- if self._has_topology == False:
- return None
-
- relations = {}
- try:
- relations["equivalent"] = len(self._topology["EQUIVALENT"])
- except:
- relations["equivalent"] = 0
- try:
- relations["overlap"] = len(self._topology["OVERLAP"])
- except:
- relations["overlap"] = 0
- try:
- relations["in"] = len(self._topology["IN"])
- except:
- relations["in"] = 0
- try:
- relations["contain"] = len(self._topology["CONTAIN"])
- except:
- relations["contain"] = 0
- try:
- relations["meet"] = len(self._topology["MEET"])
- except:
- relations["meet"] = 0
- try:
- relations["cover"] = len(self._topology["COVER"])
- except:
- relations["cover"] = 0
- try:
- relations["covered"] = len(self._topology["COVERED"])
- except:
- relations["covered"] = 0
-
- return relations
-
- def set_topology_build_true(self):
- """!Same as name"""
- self._has_topology = True
-
- def set_topology_build_false(self):
- """!Same as name"""
- self._has_topology = False
-
- def is_topology_build(self):
- """!Check if the temporal topology was build"""
- return self._has_topology
-
- def append_equivalent(self, map):
- """!Append a map with equivalent spatial extent as this map
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "EQUIVALENT" not in self._topology:
- self._topology["EQUIVALENT"] = []
- self._topology["EQUIVALENT"].append(map)
-
- def get_equivalent(self):
- """!Return a list of map objects with equivalent spatial extent as this map
-
- @return A list of map objects or None
- """
- if "EQUIVALENT" not in self._topology:
- return None
- return self._topology["EQUIVALENT"]
-
- def append_overlap(self, map):
- """!Append a map that this spatial overlap with this map
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "OVERLAP" not in self._topology:
- self._topology["OVERLAP"] = []
- self._topology["OVERLAP"].append(map)
-
- def get_overlap(self):
- """!Return a list of map objects that this map spatial overlap with
-
- @return A list of map objects or None
- """
- if "OVERLAP" not in self._topology:
- return None
- return self._topology["OVERLAP"]
-
- def append_in(self, map):
- """!Append a map that this is spatial in this map
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "IN" not in self._topology:
- self._topology["IN"] = []
- self._topology["IN"].append(map)
-
- def get_in(self):
- """!Return a list of map objects that are spatial in this map
-
- @return A list of map objects or None
- """
- if "IN" not in self._topology:
- return None
- return self._topology["IN"]
-
- def append_contain(self, map):
- """!Append a map that this map spatially contains
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "CONTAIN" not in self._topology:
- self._topology["CONTAIN"] = []
- self._topology["CONTAIN"].append(map)
-
- def get_contain(self):
- """!Return a list of map objects that this map contains
-
- @return A list of map objects or None
- """
- if "CONTAIN" not in self._topology:
- return None
- return self._topology["CONTAIN"]
-
- def append_meet(self, map):
- """!Append a map that spatially meet with this map
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "MEET" not in self._topology:
- self._topology["MEET"] = []
- self._topology["MEET"].append(map)
-
- def get_meet(self):
- """!Return a list of map objects that spatially meet with this map
-
- @return A list of map objects or None
- """
- if "MEET" not in self._topology:
- return None
- return self._topology["MEET"]
-
- def append_cover(self, map):
- """!Append a map that spatially cover this map
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "COVER" not in self._topology:
- self._topology["COVER"] = []
- self._topology["COVER"].append(map)
-
- def get_cover(self):
- """!Return a list of map objects that spatially cover this map
-
- @return A list of map objects or None
- """
- if "COVER" not in self._topology:
- return None
- return self._topology["COVER"]
-
- def append_covered(self, map):
- """!Append a map that is spatially covered by this map
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "COVERED" not in self._topology:
- self._topology["COVERED"] = []
- self._topology["COVERED"].append(map)
-
- def get_covered(self):
- """!Return a list of map objects that are spatially covered by this map
-
- @return A list of map objects or None
- """
- if "COVERED" not in self._topology:
- return None
- return self._topology["COVERED"]
-
-
- def _generate_map_list_string(self, map_list, line_wrap=True):
- count = 0
- string = ""
- for map_ in map_list:
- if line_wrap and count > 0 and count % 3 == 0:
- string += "\n | ............................ "
- count = 0
- if count == 0:
- string += map_.get_id()
- else:
- string += ",%s" % map_.get_id()
- count += 1
-
- return string
-
- # Set the properties
- equivalent = property(fget=get_equivalent,
- fset=append_equivalent)
- cover = property(fget=get_cover,
- fset=append_cover)
- covered = property(fget=get_covered,
- fset=append_covered)
- overlap = property(fget=get_overlap,
- fset=append_overlap)
- in = property(fget=get_in,
- fset=append_in)
- contain = property(fget=get_contain,
- fset=append_contain)
- meet = property(fget=get_meet,
- fset=append_meet)
-
- def print_topology_info(self):
- """!Print information about this class in human readable style"""
-
- print " +-------------------- Spatial Topology --------------------------------------+"
- # 0123456789012345678901234567890
- if self.equivalent is not None:
- print " | Equivalent: ................ " + \
- self._generate_map_list_string(self.equivalent)
- if self.cover is not None:
- print " | Cover: ..................... " + \
- self._generate_map_list_string(self.cover)
- if self.covered is not None:
- print " | Covered: ................... " + \
- self._generate_map_list_string(self.covered)
- if self.overlap is not None:
- print " | Overlap: ................... " + \
- self._generate_map_list_string(self.overlap)
- if self.in is not None:
- print " | In: ........................ " + \
- self._generate_map_list_string(self.in)
- if self.contain is not None:
- print " | Contain: ................... " + \
- self._generate_map_list_string(self.contain)
- if self.meet is not None:
- print " | Meet: ...................... " + \
- self._generate_map_list_string(self.meet)
-
- def print_topology_shell_info(self):
- """!Print information about this class in shell style"""
-
- if self.next() is not None:
- if self.equivalent is not None:
- print "equivalent=" + self._generate_map_list_string(self.equivalent, False)
- if self.cover is not None:
- print "cover=" + self._generate_map_list_string(
- self.cover, False)
- if self.covered is not None:
- print "covered=" + \
- self._generate_map_list_string(self.covered, False)
- if self.overlap is not None:
- print "overlap=" + \
- self._generate_map_list_string(self.overlap)
- if self.in is not None:
- print "in=" + \
- self._generate_map_list_string(self.in)
- if self.contain is not None:
- print "contain=" + \
- self._generate_map_list_string(self.contain)
- if self.meet is not None:
- print "meet=" + \
- self._generate_map_list_string(self.meet)
-
-###############################################################################
-
-if __name__ == "__main__":
- import doctest
- doctest.testmod()
\ No newline at end of file
Deleted: grass/trunk/lib/python/temporal/abstract_temporal_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_temporal_dataset.py 2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/abstract_temporal_dataset.py 2013-04-25 23:07:37 UTC (rev 55998)
@@ -1,589 +0,0 @@
-# -*- coding: utf-8 -*-
-"""!@package grass.temporal
-
- at brief GRASS Python scripting module (temporal GIS functions)
-
-Temporal GIS related functions to be used in temporal GIS Python library package.
-
-Usage:
-
->>> import grass.temporal as tgis
->>> tmr = tgis.AbstractTemporalDataset()
-
-(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 abstract_dataset import *
-from datetime_math import *
-
-
-class AbstractTemporalDataset(AbstractDataset):
- """!This class implements a temporal topology access structure for an abstract dataset
-
- This object will be set up by temporal topology creation method provided by the
- TemporallyTopologyBuilder.
-
- If correctly initialize the calls next() and prev()
- let the user walk temporally forward and backward in time.
-
- The following temporal relations with access methods are supported:
- - equal
- - follows
- - precedes
- - overlaps
- - overlapped
- - during (including starts, finishes)
- - contains (including started, finished)
- - starts
- - started
- - finishes
- - finished
-
-
- @code:
- # We have build the temporal topology and we know the first map
- start = first
- while start:
-
- # Print all maps this map temporally contains
- dlist = start.get_contains()
- for map in dlist:
- map.print_info()
-
- start = start.next()
- @endcode
-
- Usage:
-
- @code
-
- >>> import grass.temporal as tgis
- >>> tgis.init()
- >>> map = tgis.RasterDataset("a at P")
- >>> tmr = tgis.AbstractTemporalDataset()
- >>> tmr.set_next(map)
- >>> tmr.set_prev(map)
- >>> tmr.append_equal(map)
- >>> tmr.append_follows(map)
- >>> tmr.append_precedes(map)
- >>> tmr.append_overlapped(map)
- >>> tmr.append_overlaps(map)
- >>> tmr.append_during(map)
- >>> tmr.append_contains(map)
- >>> tmr.append_starts(map)
- >>> tmr.append_started(map)
- >>> tmr.append_finishes(map)
- >>> tmr.append_finished(map)
- >>> tmr.print_topology_info()
- +-------------------- Temporal Topology -------------------------------------+
- | Next: ...................... a at P
- | Previous: .................. a at P
- | Equal:...................... a at P
- | Follows: ................... a at P
- | Precedes: .................. a at P
- | Overlaps: .................. a at P
- | Overlapped: ................ a at P
- | During: .................... a at P
- | Contains: .................. a at P
- | Starts:.. .................. a at P
- | Started:. .................. a at P
- | Finishes:................... a at P
- | Finished:................... a at P
- >>> tmr.print_topology_shell_info()
- next=a at P
- prev=a at P
- equal=a at P
- follows=a at P
- precedes=a at P
- overlaps=a at P
- overlapped=a at P
- during=a at P
- contains=a at P
- starts=a at P
- started=a at P
- finishes=a at P
- finished=a at P
-
- @endcode
- """
-
- def __init__(self):
- AbstractDataset.__init__(self)
- self.reset_topology()
-
- def reset_topology(self):
- """!Reset any information about temporal topology"""
- self._topology = {}
- self._has_topology = False
-
- def get_number_of_relations(self):
- """! Return a dictionary in which the keys are the relation names and the value
- are the number of relations.
-
- The following relations are available:
- - equal
- - follows
- - precedes
- - overlaps
- - overlapped
- - during (including starts, finishes)
- - contains (including started, finished)
- - starts
- - started
- - finishes
- - finished
-
- To access topological information the temporal topology must be build first
- using the TemporalTopologyBuilder.
-
- @return the dictionary with relations as keys and number as values or None in case the topology wasn't build
- """
- if self._has_topology == False:
- return None
-
- relations = {}
- try:
- relations["equal"] = len(self._topology["EQUAL"])
- except:
- relations["equal"] = 0
- try:
- relations["follows"] = len(self._topology["FOLLOWS"])
- except:
- relations["follows"] = 0
- try:
- relations["precedes"] = len(self._topology["PRECEDES"])
- except:
- relations["precedes"] = 0
- try:
- relations["overlaps"] = len(self._topology["OVERLAPS"])
- except:
- relations["overlaps"] = 0
- try:
- relations["overlapped"] = len(self._topology["OVERLAPPED"])
- except:
- relations["overlapped"] = 0
- try:
- relations["during"] = len(self._topology["DURING"])
- except:
- relations["during"] = 0
- try:
- relations["contains"] = len(self._topology["CONTAINS"])
- except:
- relations["contains"] = 0
- try:
- relations["starts"] = len(self._topology["STARTS"])
- except:
- relations["starts"] = 0
- try:
- relations["started"] = len(self._topology["STARTED"])
- except:
- relations["started"] = 0
- try:
- relations["finishes"] = len(self._topology["FINISHES"])
- except:
- relations["finishes"] = 0
- try:
- relations["finished"] = len(self._topology["FINISHED"])
- except:
- relations["finished"] = 0
-
- return relations
-
- def set_topology_build_true(self):
- """!Same as name"""
- self._has_topology = True
-
- def set_topology_build_false(self):
- """!Same as name"""
- self._has_topology = False
-
- def is_topology_build(self):
- """!Check if the temporal topology was build"""
- return self._has_topology
-
- def set_next(self, map):
- """!Set the map that is temporally as closest located after this map.
-
- Temporally located means that the start time of the "next" map is
- temporally located AFTER the start time of this map, but temporally
- near than other maps of the same dataset.
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- self._topology["NEXT"] = map
-
- def set_prev(self, map):
- """!Set the map that is temporally as closest located before this map.
-
- Temporally located means that the start time of the "previous" map is
- temporally located BEFORE the start time of this map, but temporally
- near than other maps of the same dataset.
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- self._topology["PREV"] = map
-
- def next(self):
- """!Return the map with a start time temporally located after
- the start time of this map, but temporal closer than other maps
-
- @return A map object or None
- """
- if "NEXT" not in self._topology:
- return None
- return self._topology["NEXT"]
-
- def prev(self):
- """!Return the map with a start time temporally located before
- the start time of this map, but temporal closer than other maps
-
- @return A map object or None
- """
- if "PREV" not in self._topology:
- return None
- return self._topology["PREV"]
-
- def append_equal(self, map):
- """!Append a map with equivalent temporal extent as this map
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "EQUAL" not in self._topology:
- self._topology["EQUAL"] = []
- self._topology["EQUAL"].append(map)
-
- def get_equal(self):
- """!Return a list of map objects with equivalent temporal extent as this map
-
- @return A list of map objects or None
- """
- if "EQUAL" not in self._topology:
- return None
- return self._topology["EQUAL"]
-
- def append_starts(self, map):
- """!Append a map that this map temporally starts with
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "STARTS" not in self._topology:
- self._topology["STARTS"] = []
- self._topology["STARTS"].append(map)
-
- def get_starts(self):
- """!Return a list of map objects that this map temporally starts with
-
- @return A list of map objects or None
- """
- if "STARTS" not in self._topology:
- return None
- return self._topology["STARTS"]
-
- def append_started(self, map):
- """!Append a map that this map temporally started with
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "STARTED" not in self._topology:
- self._topology["STARTED"] = []
- self._topology["STARTED"].append(map)
-
- def get_started(self):
- """!Return a list of map objects that this map temporally started with
-
- @return A list of map objects or None
- """
- if "STARTED" not in self._topology:
- return None
- return self._topology["STARTED"]
-
- def append_finishes(self, map):
- """!Append a map that this map temporally finishes with
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "FINISHES" not in self._topology:
- self._topology["FINISHES"] = []
- self._topology["FINISHES"].append(map)
-
- def get_finishes(self):
- """!Return a list of map objects that this map temporally finishes with
-
- @return A list of map objects or None
- """
- if "FINISHES" not in self._topology:
- return None
- return self._topology["FINISHES"]
-
- def append_finished(self, map):
- """!Append a map that this map temporally finished with
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "FINISHED" not in self._topology:
- self._topology["FINISHED"] = []
- self._topology["FINISHED"].append(map)
-
- def get_finished(self):
- """!Return a list of map objects that this map temporally finished with
-
- @return A list of map objects or None
- """
- if "FINISHED" not in self._topology:
- return None
- return self._topology["FINISHED"]
-
- def append_overlaps(self, map):
- """!Append a map that this map temporally overlaps
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "OVERLAPS" not in self._topology:
- self._topology["OVERLAPS"] = []
- self._topology["OVERLAPS"].append(map)
-
- def get_overlaps(self):
- """!Return a list of map objects that this map temporally overlaps
-
- @return A list of map objects or None
- """
- if "OVERLAPS" not in self._topology:
- return None
- return self._topology["OVERLAPS"]
-
- def append_overlapped(self, map):
- """!Append a map that this map temporally overlapped
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "OVERLAPPED" not in self._topology:
- self._topology["OVERLAPPED"] = []
- self._topology["OVERLAPPED"].append(map)
-
- def get_overlapped(self):
- """!Return a list of map objects that this map temporally overlapped
-
- @return A list of map objects or None
- """
- if "OVERLAPPED" not in self._topology:
- return None
- return self._topology["OVERLAPPED"]
-
- def append_follows(self, map):
- """!Append a map that this map temporally follows
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "FOLLOWS" not in self._topology:
- self._topology["FOLLOWS"] = []
- self._topology["FOLLOWS"].append(map)
-
- def get_follows(self):
- """!Return a list of map objects that this map temporally follows
-
- @return A list of map objects or None
- """
- if "FOLLOWS" not in self._topology:
- return None
- return self._topology["FOLLOWS"]
-
- def append_precedes(self, map):
- """!Append a map that this map temporally precedes
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "PRECEDES" not in self._topology:
- self._topology["PRECEDES"] = []
- self._topology["PRECEDES"].append(map)
-
- def get_precedes(self):
- """!Return a list of map objects that this map temporally precedes
-
- @return A list of map objects or None
- """
- if "PRECEDES" not in self._topology:
- return None
- return self._topology["PRECEDES"]
-
- def append_during(self, map):
- """!Append a map that this map is temporally located during
- This includes temporal relationships starts and finishes
-
- @param map This object should be of type
- AbstractMapDataset or derived classes
- """
- if "DURING" not in self._topology:
- self._topology["DURING"] = []
- self._topology["DURING"].append(map)
-
- def get_during(self):
- """!Return a list of map objects that this map is temporally located during
- This includes temporally relationships starts and finishes
-
- @return A list of map objects or None
- """
- if "DURING" not in self._topology:
- return None
- return self._topology["DURING"]
-
- def append_contains(self, map):
- """!Append a map that this map temporally contains
- This includes temporal relationships started and finished
-
- @param map This object should be of type AbstractMapDataset
- or derived classes
- """
- if "CONTAINS" not in self._topology:
- self._topology["CONTAINS"] = []
- self._topology["CONTAINS"].append(map)
-
- def get_contains(self):
- """!Return a list of map objects that this map temporally contains
- This includes temporal relationships started and finished
-
- @return A list of map objects or None
- """
- if "CONTAINS" not in self._topology:
- return None
- return self._topology["CONTAINS"]
-
- def _generate_map_list_string(self, map_list, line_wrap=True):
- count = 0
- string = ""
- for map_ in map_list:
- if line_wrap and count > 0 and count % 3 == 0:
- string += "\n | ............................ "
- count = 0
- if count == 0:
- string += map_.get_id()
- else:
- string += ",%s" % map_.get_id()
- count += 1
-
- return string
-
- # Set the properties
- equal = property(fget=get_equal,
- fset=append_equal)
- follows = property(fget=get_follows,
- fset=append_follows)
- precedes = property(fget=get_precedes,
- fset=append_precedes)
- overlaps = property(fget=get_overlaps,
- fset=append_overlaps)
- overlapped = property(fget=get_overlapped,
- fset=append_overlapped)
- during = property(fget=get_during,
- fset=append_during)
- contains = property(fget=get_contains,
- fset=append_contains)
- starts = property(fget=get_starts,
- fset=append_starts)
- started = property(fget=get_started,
- fset=append_started)
- finishes = property(fget=get_finishes,
- fset=append_finishes)
- finished = property(fget=get_finished,
- fset=append_finished)
-
- def print_topology_info(self):
- """!Print information about this class in human readable style"""
-
- print " +-------------------- Temporal Topology -------------------------------------+"
- # 0123456789012345678901234567890
- if self.next() is not None:
- print " | Next: ...................... " + str(self.next().get_id())
- if self.prev() is not None:
- print " | Previous: .................. " + str(self.prev().get_id())
- if self.equal is not None:
- print " | Equal:...................... " + \
- self._generate_map_list_string(self.equal)
- if self.follows is not None:
- print " | Follows: ................... " + \
- self._generate_map_list_string(self.follows)
- if self.precedes is not None:
- print " | Precedes: .................. " + \
- self._generate_map_list_string(self.precedes)
- if self.overlaps is not None:
- print " | Overlaps: .................. " + \
- self._generate_map_list_string(self.overlaps)
- if self.overlapped is not None:
- print " | Overlapped: ................ " + \
- self._generate_map_list_string(self.overlapped)
- if self.during is not None:
- print " | During: .................... " + \
- self._generate_map_list_string(self.during)
- if self.contains is not None:
- print " | Contains: .................. " + \
- self._generate_map_list_string(self.contains)
- if self.starts is not None:
- print " | Starts:.. .................. " + \
- self._generate_map_list_string(self.starts)
- if self.started is not None:
- print " | Started:. .................. " + \
- self._generate_map_list_string(self.started)
- if self.finishes is not None:
- print " | Finishes:................... " + \
- self._generate_map_list_string(self.finishes)
- if self.finished is not None:
- print " | Finished:................... " + \
- self._generate_map_list_string(self.finished)
-
- def print_topology_shell_info(self):
- """!Print information about this class in shell style"""
-
- if self.next() is not None:
- print "next=" + self.next().get_id()
- if self.prev() is not None:
- print "prev=" + self.prev().get_id()
- if self.equal is not None:
- print "equal=" + self._generate_map_list_string(self.equal, False)
- if self.follows is not None:
- print "follows=" + self._generate_map_list_string(self.follows, False)
- if self.precedes is not None:
- print "precedes=" + self._generate_map_list_string(
- self.precedes, False)
- if self.overlaps is not None:
- print "overlaps=" + self._generate_map_list_string(
- self.overlaps, False)
- if self.overlapped is not None:
- print "overlapped=" + \
- self._generate_map_list_string(self.overlapped, False)
- if self.during is not None:
- print "during=" + self._generate_map_list_string(self.during, False)
- if self.contains is not None:
- print "contains=" + self._generate_map_list_string(
- self.contains, False)
- if self.starts is not None:
- print "starts=" + \
- self._generate_map_list_string(self.starts)
- if self.started is not None:
- print "started=" + \
- self._generate_map_list_string(self.started)
- if self.finishes is not None:
- print "finishes=" + \
- self._generate_map_list_string(self.finishes)
- if self.finished is not None:
- print "finished=" + \
- self._generate_map_list_string(self.finished)
-
-###############################################################################
-
-if __name__ == "__main__":
- import doctest
- doctest.testmod()
\ No newline at end of file
Modified: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py 2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py 2013-04-25 23:07:37 UTC (rev 55998)
@@ -28,6 +28,7 @@
import grass.lib.raster3d as libraster3d
import grass.script as grass
+from abstract_map_dataset import *
from abstract_space_time_dataset import *
###############################################################################
@@ -57,6 +58,7 @@
>>> rmap = RasterDataset(identifier)
>>> rmap.set_absolute_time(start_time=datetime(2001,1,1),
... end_time=datetime(2012,1,1))
+ True
>>> rmap.map_exists()
True
>>> rmap.load()
Copied: grass/trunk/lib/python/temporal/spatial_topology_dataset_connector.py (from rev 55991, grass/trunk/lib/python/temporal/abstract_spatial_dataset.py)
===================================================================
--- grass/trunk/lib/python/temporal/spatial_topology_dataset_connector.py (rev 0)
+++ grass/trunk/lib/python/temporal/spatial_topology_dataset_connector.py 2013-04-25 23:07:37 UTC (rev 55998)
@@ -0,0 +1,365 @@
+# -*- coding: utf-8 -*-
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in temporal GIS Python library package.
+
+Usage:
+
+>>> import grass.temporal as tgis
+>>> tmr = tgis.SpatialTopologyDatasetConnector()
+
+(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
+"""
+
+class SpatialTopologyDatasetConnector(object):
+ """!This class implements a spatial topology access structure to connect spatial related datasets
+
+ This object will be set up by spatial topology creation method provided by the
+ SpatioTemporalTopologyBuilder.
+
+ The following spatial relations with access methods are supported:
+ - equivalent
+ - overlap
+ - in
+ - contain
+ - meet
+ - cover
+ - covered
+
+ Usage:
+
+ @code
+
+ >>> import grass.temporal as tgis
+ >>> tgis.init()
+ >>> map = tgis.RasterDataset("a at P")
+ >>> tmr = tgis.SpatialTopologyDatasetConnector()
+ >>> tmr.append_equivalent(map)
+ >>> tmr.append_overlap(map)
+ >>> tmr.append_in(map)
+ >>> tmr.append_contain(map)
+ >>> tmr.append_meet(map)
+ >>> tmr.append_cover(map)
+ >>> tmr.append_covered(map)
+ >>> tmr.print_spatial_topology_info()
+ +-------------------- Spatial Topology --------------------------------------+
+ | Equivalent: ................ a at P
+ | Cover: ..................... a at P
+ | Covered: ................... a at P
+ | Overlap: ................... a at P
+ | In: ........................ a at P
+ | Contain: ................... a at P
+ | Meet: ...................... a at P
+ >>> tmr.print_spatial_topology_shell_info()
+ equivalent=a at P
+ cover=a at P
+ covered=a at P
+ overlap=a at P
+ in=a at P
+ contain=a at P
+ meet=a at P
+
+ @endcode
+ """
+
+ def __init__(self):
+ self.reset_spatial_topology()
+
+ def reset_spatial_topology(self):
+ """!Reset any information about temporal topology"""
+ self._spatial_topology = {}
+ self._has_spatial_topology = False
+
+ def get_number_of_spatial_relations(self):
+ """! Return a dictionary in which the keys are the relation names and the value
+ are the number of relations.
+
+ The following relations are available:
+ - equivalent
+ - overlap
+ - in
+ - contain
+ - meet
+ - cover
+ - covered
+
+ To access topological information the spatial topology must be build first
+ using the SpatialTopologyBuilder.
+
+ @return the dictionary with relations as keys and number as values or None in case the topology wasn't build
+ """
+ if self._has_spatial_topology == False:
+ return None
+
+ relations = {}
+ try:
+ relations["equivalent"] = len(self._spatial_topology["EQUIVALENT"])
+ except:
+ relations["equivalent"] = 0
+ try:
+ relations["overlap"] = len(self._spatial_topology["OVERLAP"])
+ except:
+ relations["overlap"] = 0
+ try:
+ relations["in"] = len(self._spatial_topology["IN"])
+ except:
+ relations["in"] = 0
+ try:
+ relations["contain"] = len(self._spatial_topology["CONTAIN"])
+ except:
+ relations["contain"] = 0
+ try:
+ relations["meet"] = len(self._spatial_topology["MEET"])
+ except:
+ relations["meet"] = 0
+ try:
+ relations["cover"] = len(self._spatial_topology["COVER"])
+ except:
+ relations["cover"] = 0
+ try:
+ relations["covered"] = len(self._spatial_topology["COVERED"])
+ except:
+ relations["covered"] = 0
+
+ return relations
+
+ def set_spatial_topology_build_true(self):
+ """!Same as name"""
+ self._has_spatial_topology = True
+
+ def set_spatial_topology_build_false(self):
+ """!Same as name"""
+ self._has_spatial_topology = False
+
+ def is_spatial_topology_build(self):
+ """!Check if the temporal topology was build"""
+ return self._has_spatial_topology
+
+ def append_equivalent(self, map):
+ """!Append a map with equivalent spatial extent as this map
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "EQUIVALENT" not in self._spatial_topology:
+ self._spatial_topology["EQUIVALENT"] = []
+ self._spatial_topology["EQUIVALENT"].append(map)
+
+ def get_equivalent(self):
+ """!Return a list of map objects with equivalent spatial extent as this map
+
+ @return A list of map objects or None
+ """
+ if "EQUIVALENT" not in self._spatial_topology:
+ return None
+ return self._spatial_topology["EQUIVALENT"]
+
+ def append_overlap(self, map):
+ """!Append a map that this spatial overlap with this map
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "OVERLAP" not in self._spatial_topology:
+ self._spatial_topology["OVERLAP"] = []
+ self._spatial_topology["OVERLAP"].append(map)
+
+ def get_overlap(self):
+ """!Return a list of map objects that this map spatial overlap with
+
+ @return A list of map objects or None
+ """
+ if "OVERLAP" not in self._spatial_topology:
+ return None
+ return self._spatial_topology["OVERLAP"]
+
+ def append_in(self, map):
+ """!Append a map that this is spatial in this map
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "IN" not in self._spatial_topology:
+ self._spatial_topology["IN"] = []
+ self._spatial_topology["IN"].append(map)
+
+ def get_in(self):
+ """!Return a list of map objects that are spatial in this map
+
+ @return A list of map objects or None
+ """
+ if "IN" not in self._spatial_topology:
+ return None
+ return self._spatial_topology["IN"]
+
+ def append_contain(self, map):
+ """!Append a map that this map spatially contains
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "CONTAIN" not in self._spatial_topology:
+ self._spatial_topology["CONTAIN"] = []
+ self._spatial_topology["CONTAIN"].append(map)
+
+ def get_contain(self):
+ """!Return a list of map objects that this map contains
+
+ @return A list of map objects or None
+ """
+ if "CONTAIN" not in self._spatial_topology:
+ return None
+ return self._spatial_topology["CONTAIN"]
+
+ def append_meet(self, map):
+ """!Append a map that spatially meet with this map
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "MEET" not in self._spatial_topology:
+ self._spatial_topology["MEET"] = []
+ self._spatial_topology["MEET"].append(map)
+
+ def get_meet(self):
+ """!Return a list of map objects that spatially meet with this map
+
+ @return A list of map objects or None
+ """
+ if "MEET" not in self._spatial_topology:
+ return None
+ return self._spatial_topology["MEET"]
+
+ def append_cover(self, map):
+ """!Append a map that spatially cover this map
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "COVER" not in self._spatial_topology:
+ self._spatial_topology["COVER"] = []
+ self._spatial_topology["COVER"].append(map)
+
+ def get_cover(self):
+ """!Return a list of map objects that spatially cover this map
+
+ @return A list of map objects or None
+ """
+ if "COVER" not in self._spatial_topology:
+ return None
+ return self._spatial_topology["COVER"]
+
+ def append_covered(self, map):
+ """!Append a map that is spatially covered by this map
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "COVERED" not in self._spatial_topology:
+ self._spatial_topology["COVERED"] = []
+ self._spatial_topology["COVERED"].append(map)
+
+ def get_covered(self):
+ """!Return a list of map objects that are spatially covered by this map
+
+ @return A list of map objects or None
+ """
+ if "COVERED" not in self._spatial_topology:
+ return None
+ return self._spatial_topology["COVERED"]
+
+
+ def _generate_map_list_string(self, map_list, line_wrap=True):
+ count = 0
+ string = ""
+ for map_ in map_list:
+ if line_wrap and count > 0 and count % 3 == 0:
+ string += "\n | ............................ "
+ count = 0
+ if count == 0:
+ string += map_.get_id()
+ else:
+ string += ",%s" % map_.get_id()
+ count += 1
+
+ return string
+
+ # Set the properties
+ equivalent = property(fget=get_equivalent,
+ fset=append_equivalent)
+ cover = property(fget=get_cover,
+ fset=append_cover)
+ covered = property(fget=get_covered,
+ fset=append_covered)
+ overlap = property(fget=get_overlap,
+ fset=append_overlap)
+ in_ = property(fget=get_in,
+ fset=append_in)
+ contain = property(fget=get_contain,
+ fset=append_contain)
+ meet = property(fget=get_meet,
+ fset=append_meet)
+
+ def print_spatial_topology_info(self):
+ """!Print information about this class in human readable style"""
+
+ print " +-------------------- Spatial Topology --------------------------------------+"
+ # 0123456789012345678901234567890
+ if self.equivalent is not None:
+ print " | Equivalent: ................ " + \
+ self._generate_map_list_string(self.equivalent)
+ if self.cover is not None:
+ print " | Cover: ..................... " + \
+ self._generate_map_list_string(self.cover)
+ if self.covered is not None:
+ print " | Covered: ................... " + \
+ self._generate_map_list_string(self.covered)
+ if self.overlap is not None:
+ print " | Overlap: ................... " + \
+ self._generate_map_list_string(self.overlap)
+ if self.in_ is not None:
+ print " | In: ........................ " + \
+ self._generate_map_list_string(self.in_)
+ if self.contain is not None:
+ print " | Contain: ................... " + \
+ self._generate_map_list_string(self.contain)
+ if self.meet is not None:
+ print " | Meet: ...................... " + \
+ self._generate_map_list_string(self.meet)
+
+ def print_spatial_topology_shell_info(self):
+ """!Print information about this class in shell style"""
+
+ if self.equivalent is not None:
+ print "equivalent=" + self._generate_map_list_string(self.equivalent, False)
+ if self.cover is not None:
+ print "cover=" + self._generate_map_list_string(
+ self.cover, False)
+ if self.covered is not None:
+ print "covered=" + \
+ self._generate_map_list_string(self.covered, False)
+ if self.overlap is not None:
+ print "overlap=" + \
+ self._generate_map_list_string(self.overlap)
+ if self.in_ is not None:
+ print "in=" + \
+ self._generate_map_list_string(self.in_)
+ if self.contain is not None:
+ print "contain=" + \
+ self._generate_map_list_string(self.contain)
+ if self.meet is not None:
+ print "meet=" + \
+ self._generate_map_list_string(self.meet)
+
+###############################################################################
+
+if __name__ == "__main__":
+ import doctest
+ doctest.testmod()
\ No newline at end of file
Copied: grass/trunk/lib/python/temporal/spatio_temporal_relationships.py (from rev 55991, grass/trunk/lib/python/temporal/temporal_relationships.py)
===================================================================
--- grass/trunk/lib/python/temporal/spatio_temporal_relationships.py (rev 0)
+++ grass/trunk/lib/python/temporal/spatio_temporal_relationships.py 2013-04-25 23:07:37 UTC (rev 55998)
@@ -0,0 +1,760 @@
+"""!@package grass.temporal
+
+ 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
+import grass.temporal as tgis
+
+tgis.print_temporal_relations(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 abstract_dataset import *
+from datetime_math import *
+import grass.lib.vector as vector
+import grass.lib.gis as gis
+from ctypes import *
+
+###############################################################################
+
+class SpatioTemporalTopologyBuilder(object):
+ """!This class is designed to build the spatio-temporal topology
+ of spatio-temporally related abstract dataset objects.
+
+ The abstract dataset objects must be provided as a single list, or in two lists.
+
+ Example:
+ @code
+ # We have a space time raster dataset and build a map list
+ # from all registered maps ordered by start time
+ maps = strds.get_registered_maps_as_objects()
+
+ # Now lets build the temporal topology of the maps in the list
+
+ tb = SpatioTemporalTopologyBuilder()
+
+ tb.build(maps)
+
+ dbif, connected = init_dbif(None)
+
+ for _map in tb:
+ _map.select(dbif)
+ _map.print_info()
+
+ # Using the next and previous methods, we can iterate over the
+ # topological related maps in this way
+
+ _first = tb.get_first()
+
+ while _first:
+ _first.print_topology_info()
+ _first = _first.next()
+
+ # Dictionary like accessed
+ _map = tb["name at mapset"]
+ @endcode
+
+ """
+ def __init__(self):
+ self._reset()
+ # 0001-01-01 00:00:00
+ self._timeref = datetime(1,1,1)
+
+ def _reset(self):
+ self._store = {}
+ self._first = None
+ self._iteratable = False
+
+ def _set_first(self, first):
+ self._first = first
+ self._insert(first)
+
+ def _detect_first(self):
+ if len(self) > 0:
+ prev_ = self._store.values()[0]
+ while prev_ is not None:
+ self._first = prev_
+ prev_ = prev_.prev()
+
+ def _insert(self, t):
+ self._store[t.get_id()] = t
+
+ def get_first(self):
+ """!Return the first map with the earliest start time
+
+ @return The map with the earliest start time
+ """
+ return self._first
+
+ def _build_internal_iteratable(self, maps):
+ """!Build an iteratable temporal topology structure for all maps in
+ the list and store the maps internally
+
+ Basically the "next" and "prev" relations will be set in the
+ temporal topology structure of each map
+ The maps will be added to the object, so they can be
+ accessed using the iterator of this class
+
+ @param maps A sorted (by start_time)list of abstract_dataset
+ objects with initiated temporal extent
+ """
+ self._build_iteratable(maps)
+
+ for _map in maps:
+ self._insert(_map)
+
+ # Detect the first map
+ self._detect_first()
+
+ def _build_iteratable(self, maps):
+ """!Build an iteratable temporal topology structure for
+ all maps in the list
+
+ Basically the "next" and "prev" relations will be set in
+ the temporal topology structure of each map.
+
+ @param maps A sorted (by start_time)list of abstract_dataset
+ objects with initiated temporal extent
+ """
+# for i in xrange(len(maps)):
+# offset = i + 1
+# for j in xrange(offset, len(maps)):
+# # Get the temporal relationship
+# relation = maps[j].temporal_relation(maps[i])
+#
+# # Build the next reference
+# if relation != "equal" and relation != "started":
+# maps[i].set_next(maps[j])
+# break
+
+ # First we need to order the map list chronologically
+ sorted_maps = sorted(
+ maps, key=AbstractDatasetComparisonKeyStartTime)
+
+ for i in xrange(len(sorted_maps) - 1):
+ sorted_maps[i].set_next(sorted_maps[i + 1])
+
+ for map_ in sorted_maps:
+ next_ = map_.next()
+ if next_:
+ next_.set_prev(map_)
+ map_.set_temporal_topology_build_true()
+
+ def _map_to_rect(self, tree, map_, spatial=None):
+ """Use the temporal extent of a map to create and return a RTree rectange
+
+
+ @param spatial This indicates if the spatial topology is created as well:
+ spatial can be None (no spatial topology), "2D" using west, east,
+ #south, north or "3D" using west, east, south, north, bottom, top
+ """
+ rect = vector.RTreeAllocRect(tree)
+
+ start, end = map_.get_valid_time()
+
+ if not end:
+ end = start
+
+ if map_.is_time_absolute():
+ start = time_delta_to_relative_time(start - self._timeref)
+ end = time_delta_to_relative_time(end - self._timeref)
+
+ if spatial is None:
+ vector.RTreeSetRect1D(rect, tree, float(start), float(end))
+ elif spatial == "2D":
+ north, south, east, west, top, bottom = map_.get_spatial_extent()
+ vector.RTreeSetRect3D(rect, tree, west, east, south, north,
+ float(start), float(end))
+ elif spatial == "3D":
+ north, south, east, west, top, bottom = map_.get_spatial_extent()
+ vector.RTreeSetRect4D(rect, tree, west, east, south, north,
+ bottom, top, float(start), float(end))
+
+ return rect
+
+ def _build_rtree(self, maps, spatial=None):
+ """Build and return the 1-4 dimensional R*-Tree
+
+
+ @param spatial This indicates if the spatial topology is created as well:
+ spatial can be None (no spatial topology), "2D" using west, east,
+ south, north or "3D" using west, east, south, north, bottom, top
+ """
+ dim = 1
+ if spatial == "2D":
+ dim = 3
+ if spatial == "3D":
+ dim = 4
+ tree = vector.RTreeCreateTree(-1, 0, dim)
+
+ for i in xrange(len(maps)):
+
+ rect = self._map_to_rect(tree, maps[i], spatial)
+ vector.RTreeInsertRect(rect, i + 1, tree)
+
+ return tree
+
+ def build(self, mapsA, mapsB=None, spatial=None):
+ """!Build the spatio-temporal topology structure between
+ one or two unordered lists of abstract dataset objects
+
+ This method builds the temporal or spatio-temporal topology from mapsA to
+ mapsB and vice verse. The spatio-temporal topology structure of each map
+ will be reseted and rebuild for mapsA and mapsB.
+
+ After building the temporal or spatio-temporal topology the modified
+ map objects of mapsA can be accessed
+ in the same way as a dictionary using there id.
+ The implemented iterator assures
+ the chronological iteration over the mapsA.
+
+ @param mapsA A list of abstract_dataset
+ objects with initiated temporal extent
+ @param mapsB An optional list of abstract_dataset
+ objects with initiated temporal extent
+ @param spatial This indicates if the spatial topology is created as well:
+ spatial can be None (no spatial topology), "2D" using west, east,
+ south, north or "3D" using west, east, south, north, bottom, top
+ """
+
+ if spatial is not None:
+ dbif, connected = init_dbif(None)
+
+ identical = False
+ if mapsA == mapsB:
+ identical = True
+
+ if mapsB == None:
+ mapsB = mapsA
+ idetnical = True
+
+ for map_ in mapsA:
+ map_.reset_topology()
+ # Spatial extent from the database
+ if spatial is not None:
+ map_.select(dbif)
+
+ if not identical:
+ for map_ in mapsB:
+ map_.reset_topology()
+ # Spatial extent from the database
+ if spatial is not None:
+ map_.select(dbif)
+
+ tree = self. _build_rtree(mapsA, spatial)
+
+ for j in xrange(len(mapsB)):
+
+ list_ = gis.ilist()
+ rect = self._map_to_rect(tree, mapsB[j], spatial)
+ num = vector.RTreeSearch2(tree, rect, byref(list_))
+ vector.RTreeFreeRect(rect)
+
+ for k in xrange(list_.n_values):
+ i = list_.value[k] - 1
+
+ # Get the temporal relationship
+ relation = mapsB[j].temporal_relation(mapsA[i])
+
+ A = mapsA[i]
+ B = mapsB[j]
+ set_temoral_relationship(A, B, relation)
+
+ if spatial is not None:
+ relation = mapsB[j].spatial_relation(mapsA[i])
+ set_spatial_relationship(A, B, relation)
+
+ self._build_internal_iteratable(mapsA)
+ if not identical and mapsB != None:
+ self._build_iteratable(mapsB)
+
+ vector.RTreeDestroyTree(tree)
+
+ if spatial is not None:
+ if connected:
+ dbif.close()
+
+ def __iter__(self):
+ start_ = self._first
+ while start_ is not None:
+ yield start_
+ start_ = start_.next()
+
+ def __getitem__(self, index):
+ return self._store[index.get_id()]
+
+ def __len__(self):
+ return len(self._store)
+
+ def __contains__(self, _map):
+ return _map in self._store.values()
+
+###############################################################################
+
+def set_temoral_relationship(A, B, relation):
+ if relation == "equal":
+ if B != A:
+ if not B.get_equal() or \
+ (B.get_equal() and \
+ A not in B.get_equal()):
+ B.append_equal(A)
+ if not A.get_equal() or \
+ (A.get_equal() and \
+ B not in A.get_equal()):
+ A.append_equal(B)
+ elif relation == "follows":
+ if not B.get_follows() or \
+ (B.get_follows() and \
+ A not in B.get_follows()):
+ B.append_follows(A)
+ if not A.get_precedes() or \
+ (A.get_precedes() and
+ B not in A.get_precedes()):
+ A.append_precedes(B)
+ elif relation == "precedes":
+ if not B.get_precedes() or \
+ (B.get_precedes() and \
+ A not in B.get_precedes()):
+ B.append_precedes(A)
+ if not A.get_follows() or \
+ (A.get_follows() and \
+ B not in A.get_follows()):
+ A.append_follows(B)
+ elif relation == "during" or relation == "starts" or \
+ relation == "finishes":
+ if not B.get_during() or \
+ (B.get_during() and \
+ A not in B.get_during()):
+ B.append_during(A)
+ if not A.get_contains() or \
+ (A.get_contains() and \
+ B not in A.get_contains()):
+ A.append_contains(B)
+ if relation == "starts":
+ if not B.get_starts() or \
+ (B.get_starts() and \
+ A not in B.get_starts()):
+ B.append_starts(A)
+ if not A.get_started() or \
+ (A.get_started() and \
+ B not in A.get_started()):
+ A.append_started(B)
+ if relation == "finishes":
+ if not B.get_finishes() or \
+ (B.get_finishes() and \
+ A not in B.get_finishes()):
+ B.append_finishes(A)
+ if not A.get_finished() or \
+ (A.get_finished() and \
+ B not in A.get_finished()):
+ A.append_finished(B)
+ elif relation == "contains" or relation == "started" or \
+ relation == "finished":
+ if not B.get_contains() or \
+ (B.get_contains() and \
+ A not in B.get_contains()):
+ B.append_contains(A)
+ if not A.get_during() or \
+ (A.get_during() and \
+ B not in A.get_during()):
+ A.append_during(B)
+ if relation == "started":
+ if not B.get_started() or \
+ (B.get_started() and \
+ A not in B.get_started()):
+ B.append_started(A)
+ if not A.get_starts() or \
+ (A.get_starts() and \
+ B not in A.get_starts()):
+ A.append_starts(B)
+ if relation == "finished":
+ if not B.get_finished() or \
+ (B.get_finished() and \
+ A not in B.get_finished()):
+ B.append_finished(A)
+ if not A.get_finishes() or \
+ (A.get_finishes() and \
+ B not in A.get_finishes()):
+ A.append_finishes(B)
+ elif relation == "overlaps":
+ if not B.get_overlaps() or \
+ (B.get_overlaps() and \
+ A not in B.get_overlaps()):
+ B.append_overlaps(A)
+ if not A.get_overlapped() or \
+ (A.get_overlapped() and \
+ B not in A.get_overlapped()):
+ A.append_overlapped(B)
+ elif relation == "overlapped":
+ if not B.get_overlapped() or \
+ (B.get_overlapped() and \
+ A not in B.get_overlapped()):
+ B.append_overlapped(A)
+ if not A.get_overlaps() or \
+ (A.get_overlaps() and \
+ B not in A.get_overlaps()):
+ A.append_overlaps(B)
+
+###############################################################################
+
+def set_spatial_relationship(A, B, relation):
+ if relation == "equivalent":
+ if B != A:
+ if not B.get_equivalent() or \
+ (B.get_equivalent() and \
+ A not in B.get_equivalent()):
+ B.append_equivalent(A)
+ if not A.get_equivalent() or \
+ (A.get_equivalent() and \
+ B not in A.get_equivalent()):
+ A.append_equivalent(B)
+ elif relation == "overlap":
+ if not B.get_overlap() or \
+ (B.get_overlap() and \
+ A not in B.get_overlap()):
+ B.append_overlap(A)
+ if not A.get_overlap() or \
+ (A.get_overlap() and
+ B not in A.get_overlap()):
+ A.append_overlap(B)
+ elif relation == "meet":
+ if not B.get_meet() or \
+ (B.get_meet() and \
+ A not in B.get_meet()):
+ B.append_meet(A)
+ if not A.get_meet() or \
+ (A.get_meet() and
+ B not in A.get_meet()):
+ A.append_meet(B)
+ elif relation == "contain":
+ if not B.get_contain() or \
+ (B.get_contain() and \
+ A not in B.get_contain()):
+ B.append_contain(A)
+ if not A.get_in() or \
+ (A.get_in() and \
+ B not in A.get_in()):
+ A.append_in(B)
+ elif relation == "in":
+ if not B.get_in() or \
+ (B.get_in() and \
+ A not in B.get_in()):
+ B.append_in(A)
+ if not A.get_contain() or \
+ (A.get_contain() and \
+ B not in A.get_contain()):
+ A.append_contain(B)
+ elif relation == "cover":
+ if not B.get_cover() or \
+ (B.get_cover() and \
+ A not in B.get_cover()):
+ B.append_cover(A)
+ if not A.get_covered() or \
+ (A.get_covered() and \
+ B not in A.get_covered()):
+ A.append_covered(B)
+ elif relation == "covered":
+ if not B.get_covered() or \
+ (B.get_covered() and \
+ A not in B.get_covered()):
+ B.append_covered(A)
+ if not A.get_cover() or \
+ (A.get_cover() and \
+ B not in A.get_cover()):
+ A.append_cover(B)
+
+###############################################################################
+
+def print_temporal_topology_relationships(maps1, maps2=None, dbif=None):
+ """!Print the temporal relationships of the
+ map lists maps1 and maps2 to stdout.
+
+ @param maps1 A list of abstract_dataset
+ objects with initiated temporal extent
+ @param maps2 An optional list of abstract_dataset
+ objects with initiated temporal extent
+ @param dbif The database interface to be used
+ """
+
+ tb = SpatioTemporalTopologyBuilder()
+
+ tb.build(maps1, maps2)
+
+ dbif, connected = init_dbif(dbif)
+
+ for _map in tb:
+ _map.select(dbif)
+ _map.print_info()
+
+ if connected:
+ dbif.close()
+
+ return
+
+###############################################################################
+
+def count_temporal_topology_relationships(maps1, maps2=None, dbif=None):
+ """!Count the temporal relations of a single list of maps or between two lists of maps
+
+
+ @param maps1 A list of abstract_dataset
+ objects with initiated temporal extent
+ @param maps2 A list of abstract_dataset
+ objects with initiated temporal extent
+ @param dbif The database interface to be used
+ @return A dictionary with counted temporal relationships
+ """
+
+
+ tb = SpatioTemporalTopologyBuilder()
+ tb.build(maps1, maps2)
+
+ dbif, connected = init_dbif(dbif)
+
+ relations = None
+
+ for _map in tb:
+ if relations != None:
+ r = _map.get_number_of_relations()
+ for k in r.keys():
+ relations[k] += r[k]
+ else:
+ relations = _map.get_number_of_relations()
+
+ if connected:
+ dbif.close()
+
+ return relations
+
+###############################################################################
+
+def create_temporal_relation_sql_where_statement(
+ start, end, use_start=True, use_during=False,
+ use_overlap=False, use_contain=False, use_equal=False,
+ use_follows=False, use_precedes=False):
+ """!Create a SQL WHERE statement for temporal relation selection of maps in space time datasets
+
+ @param start The start time
+ @param end The end time
+ @param use_start Select maps of which the start time is located in the selection granule
+ @verbatim
+ map : s
+ granule: s-----------------e
+
+ map : s--------------------e
+ granule: s-----------------e
+
+ map : s--------e
+ granule: s-----------------e
+ @endverbatim
+
+ @param use_during Select maps which are temporal during the selection granule
+ @verbatim
+ map : s-----------e
+ granule: s-----------------e
+ @endverbatim
+
+ @param use_overlap Select maps which temporal overlap the selection granule
+ @verbatim
+ map : s-----------e
+ granule: s-----------------e
+
+ map : s-----------e
+ granule: s----------e
+ @endverbatim
+
+ @param use_contain Select maps which temporally contain the selection granule
+ @verbatim
+ map : s-----------------e
+ granule: s-----------e
+ @endverbatim
+
+ @param use_equal Select maps which temporally equal to the selection granule
+ @verbatim
+ map : s-----------e
+ granule: s-----------e
+ @endverbatim
+
+ @param use_follows Select maps which temporally follow the selection granule
+ @verbatim
+ map : s-----------e
+ granule: s-----------e
+ @endverbatim
+
+ @param use_precedes Select maps which temporally precedes the selection granule
+ @verbatim
+ map : s-----------e
+ granule: s-----------e
+ @endverbatim
+
+ Usage:
+
+ @code
+
+ >>> # Relative time
+ >>> start = 1
+ >>> end = 2
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False)
+ >>> create_temporal_relation_sql_where_statement(start, end)
+ '((start_time >= 1 and start_time < 2) )'
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=True)
+ '((start_time >= 1 and start_time < 2) )'
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False, use_during=True)
+ '(((start_time > 1 and end_time < 2) OR (start_time >= 1 and end_time < 2) OR (start_time > 1 and end_time <= 2)))'
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False, use_overlap=True)
+ '(((start_time < 1 and end_time > 1 and end_time < 2) OR (start_time < 2 and start_time > 1 and end_time > 2)))'
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False, use_contain=True)
+ '(((start_time < 1 and end_time > 2) OR (start_time <= 1 and end_time > 2) OR (start_time < 1 and end_time >= 2)))'
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False, use_equal=True)
+ '((start_time = 1 and end_time = 2))'
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False, use_follows=True)
+ '((start_time = 2))'
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False, use_precedes=True)
+ '((end_time = 1))'
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=True, use_during=True, use_overlap=True, use_contain=True,
+ ... use_equal=True, use_follows=True, use_precedes=True)
+ '((start_time >= 1 and start_time < 2) OR ((start_time > 1 and end_time < 2) OR (start_time >= 1 and end_time < 2) OR (start_time > 1 and end_time <= 2)) OR ((start_time < 1 and end_time > 1 and end_time < 2) OR (start_time < 2 and start_time > 1 and end_time > 2)) OR ((start_time < 1 and end_time > 2) OR (start_time <= 1 and end_time > 2) OR (start_time < 1 and end_time >= 2)) OR (start_time = 1 and end_time = 2) OR (start_time = 2) OR (end_time = 1))'
+
+ >>> # Absolute time
+ >>> start = datetime(2001, 1, 1, 12, 30)
+ >>> end = datetime(2001, 3, 31, 14, 30)
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False)
+ >>> create_temporal_relation_sql_where_statement(start, end)
+ "((start_time >= '2001-01-01 12:30:00' and start_time < '2001-03-31 14:30:00') )"
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=True)
+ "((start_time >= '2001-01-01 12:30:00' and start_time < '2001-03-31 14:30:00') )"
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False, use_during=True)
+ "(((start_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time >= '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time > '2001-01-01 12:30:00' and end_time <= '2001-03-31 14:30:00')))"
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False, use_overlap=True)
+ "(((start_time < '2001-01-01 12:30:00' and end_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time < '2001-03-31 14:30:00' and start_time > '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00')))"
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False, use_contain=True)
+ "(((start_time < '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time <= '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time < '2001-01-01 12:30:00' and end_time >= '2001-03-31 14:30:00')))"
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False, use_equal=True)
+ "((start_time = '2001-01-01 12:30:00' and end_time = '2001-03-31 14:30:00'))"
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False, use_follows=True)
+ "((start_time = '2001-03-31 14:30:00'))"
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=False, use_precedes=True)
+ "((end_time = '2001-01-01 12:30:00'))"
+ >>> create_temporal_relation_sql_where_statement(start, end,
+ ... use_start=True, use_during=True, use_overlap=True, use_contain=True,
+ ... use_equal=True, use_follows=True, use_precedes=True)
+ "((start_time >= '2001-01-01 12:30:00' and start_time < '2001-03-31 14:30:00') OR ((start_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time >= '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time > '2001-01-01 12:30:00' and end_time <= '2001-03-31 14:30:00')) OR ((start_time < '2001-01-01 12:30:00' and end_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time < '2001-03-31 14:30:00' and start_time > '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00')) OR ((start_time < '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time <= '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time < '2001-01-01 12:30:00' and end_time >= '2001-03-31 14:30:00')) OR (start_time = '2001-01-01 12:30:00' and end_time = '2001-03-31 14:30:00') OR (start_time = '2001-03-31 14:30:00') OR (end_time = '2001-01-01 12:30:00'))"
+
+ @endcode
+ """
+
+ where = "("
+
+ if use_start:
+ if isinstance(start, datetime):
+ where += "(start_time >= '%s' and start_time < '%s') " % (start, end)
+ else:
+ where += "(start_time >= %i and start_time < %i) " % (start, end)
+
+ if use_during:
+ if use_start:
+ where += " OR "
+
+ if isinstance(start, datetime):
+ where += "((start_time > '%s' and end_time < '%s') OR " % (start, end)
+ where += "(start_time >= '%s' and end_time < '%s') OR " % (start, end)
+ where += "(start_time > '%s' and end_time <= '%s'))" % (start, end)
+ else:
+ where += "((start_time > %i and end_time < %i) OR " % (start, end)
+ where += "(start_time >= %i and end_time < %i) OR " % (start, end)
+ where += "(start_time > %i and end_time <= %i))" % (start, end)
+
+ if use_overlap:
+ if use_start or use_during:
+ where += " OR "
+
+ if isinstance(start, datetime):
+ where += "((start_time < '%s' and end_time > '%s' and end_time < '%s') OR " % (start, start, end)
+ where += "(start_time < '%s' and start_time > '%s' and end_time > '%s'))" % (end, start, end)
+ else:
+ where += "((start_time < %i and end_time > %i and end_time < %i) OR " % (start, start, end)
+ where += "(start_time < %i and start_time > %i and end_time > %i))" % (end, start, end)
+
+ if use_contain:
+ if use_start or use_during or use_overlap:
+ where += " OR "
+
+ if isinstance(start, datetime):
+ where += "((start_time < '%s' and end_time > '%s') OR " % (start, end)
+ where += "(start_time <= '%s' and end_time > '%s') OR " % (start, end)
+ where += "(start_time < '%s' and end_time >= '%s'))" % (start, end)
+ else:
+ where += "((start_time < %i and end_time > %i) OR " % (start, end)
+ where += "(start_time <= %i and end_time > %i) OR " % (start, end)
+ where += "(start_time < %i and end_time >= %i))" % (start, end)
+
+ if use_equal:
+ if use_start or use_during or use_overlap or use_contain:
+ where += " OR "
+
+ if isinstance(start, datetime):
+ where += "(start_time = '%s' and end_time = '%s')" % (start, end)
+ else:
+ where += "(start_time = %i and end_time = %i)" % (start, end)
+
+ if use_follows:
+ if use_start or use_during or use_overlap or use_contain or use_equal:
+ where += " OR "
+
+ if isinstance(start, datetime):
+ where += "(start_time = '%s')" % (end)
+ else:
+ where += "(start_time = %i)" % (end)
+
+ if use_precedes:
+ if use_start or use_during or use_overlap or use_contain or use_equal \
+ or use_follows:
+ where += " OR "
+
+ if isinstance(start, datetime):
+ where += "(end_time = '%s')" % (start)
+ else:
+ where += "(end_time = %i)" % (start)
+
+ where += ")"
+
+ # Catch empty where statement
+ if where == "()":
+ where = None
+
+ return where
+
+
+###############################################################################
+
+if __name__ == "__main__":
+ import doctest
+ doctest.testmod()
Deleted: grass/trunk/lib/python/temporal/temporal_relationships.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_relationships.py 2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/temporal_relationships.py 2013-04-25 23:07:37 UTC (rev 55998)
@@ -1,649 +0,0 @@
-"""!@package grass.temporal
-
- 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
-import grass.temporal as tgis
-
-tgis.print_temporal_relations(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 abstract_map_dataset import *
-from datetime_math import *
-import grass.lib.vector as vector
-import grass.lib.gis as gis
-from ctypes import *
-
-###############################################################################
-
-class TemporalTopologyBuilder(object):
- """!This class is designed to build the temporal topology
- of temporally related abstract dataset objects.
-
- The abstract dataset objects must be provided as a single list, or in two lists.
-
- Example:
- @code
- # We have a space time raster dataset and build a map list
- # from all registered maps ordered by start time
- maps = strds.get_registered_maps_as_objects()
-
- # Now lets build the temporal topology of the maps in the list
-
- tb = TemporalTopologyBuilder()
-
- tb.build(maps)
-
- dbif, connected = init_dbif(None)
-
- for _map in tb:
- _map.select(dbif)
- _map.print_info()
-
- # Using the next and previous methods, we can iterate over the
- # topological related maps in this way
-
- _first = tb.get_first()
-
- while _first:
- _first.print_topology_info()
- _first = _first.next()
-
- # Dictionary like accessed
- _map = tb["name at mapset"]
- @endcode
-
- """
- def __init__(self):
- self._reset()
- # 0001-01-01 00:00:00
- self._timeref = datetime(1,1,1)
-
- def _reset(self):
- self._store = {}
- self._first = None
- self._iteratable = False
-
- def _set_first(self, first):
- self._first = first
- self._insert(first)
-
- def _detect_first(self):
- if len(self) > 0:
- prev_ = self._store.values()[0]
- while prev_ is not None:
- self._first = prev_
- prev_ = prev_.prev()
-
- def _insert(self, t):
- self._store[t.get_id()] = t
-
- def get_first(self):
- """!Return the first map with the earliest start time
-
- @return The map with the earliest start time
- """
- return self._first
-
- def _build_internal_iteratable(self, maps):
- """!Build an iteratable temporal topology structure for all maps in
- the list and store the maps internally
-
- Basically the "next" and "prev" relations will be set in the
- temporal topology structure of each map
- The maps will be added to the object, so they can be
- accessed using the iterator of this class
-
- @param maps A sorted (by start_time)list of abstract_dataset
- objects with initiated temporal extent
- """
- self._build_iteratable(maps)
-
- for _map in maps:
- self._insert(_map)
-
- # Detect the first map
- self._detect_first()
-
- def _build_iteratable(self, maps):
- """!Build an iteratable temporal topology structure for
- all maps in the list
-
- Basically the "next" and "prev" relations will be set in
- the temporal topology structure of each map.
-
- @param maps A sorted (by start_time)list of abstract_dataset
- objects with initiated temporal extent
- """
-# for i in xrange(len(maps)):
-# offset = i + 1
-# for j in xrange(offset, len(maps)):
-# # Get the temporal relationship
-# relation = maps[j].temporal_relation(maps[i])
-#
-# # Build the next reference
-# if relation != "equal" and relation != "started":
-# maps[i].set_next(maps[j])
-# break
-
- # First we need to order the map list chronologically
- sorted_maps = sorted(
- maps, key=AbstractDatasetComparisonKeyStartTime)
-
- for i in xrange(len(sorted_maps) - 1):
- sorted_maps[i].set_next(sorted_maps[i + 1])
-
- for map_ in sorted_maps:
- next_ = map_.next()
- if next_:
- next_.set_prev(map_)
- map_.set_topology_build_true()
-
- def _map_to_rect(self, tree, map_):
- """Use the temporal extent of a map to create and return a RTree rectange"""
- rect = vector.RTreeAllocRect(tree)
-
- start, end = map_.get_valid_time()
-
- if not end:
- end = start
-
- if map_.is_time_absolute():
- start = time_delta_to_relative_time(start - self._timeref)
- end = time_delta_to_relative_time(end - self._timeref)
-
- vector.RTreeSetRect1D(rect, tree, float(start), float(end))
-
- return rect
-
- def _build_1d_rtree(self, maps):
- """Build and return the one dimensional R*-Tree"""
-
- tree = vector.RTreeCreateTree(-1, 0, 1)
-
- for i in xrange(len(maps)):
-
- rect = self._map_to_rect(tree, maps[i])
- vector.RTreeInsertRect(rect, i + 1, tree)
-
- return tree
-
- def build(self, mapsA, mapsB=None):
- """!Build the temporal topology structure between
- one or two unordered lists of abstract dataset objects
-
- This method builds the temporal topology from mapsA to
- mapsB and vice verse. The temporal topology structure of each map,
- defined in class temporal_map_relations,
- will be reseted and rebuild for mapsA and mapsB.
-
- After building the temporal topology the modified
- map objects of mapsA can be accessed
- in the same way as a dictionary using there id.
- The implemented iterator assures
- the chronological iteration over the mapsA.
-
- @param mapsA A list of abstract_dataset
- objects with initiated temporal extent
- @param mapsB An optional list of abstract_dataset
- objects with initiated temporal extent
- """
-
- identical = False
- if mapsA == mapsB:
- identical = True
-
- if mapsB == None:
- mapsB = mapsA
- idetnical = True
-
- for map_ in mapsA:
- map_.reset_topology()
-
- if not identical:
- for map_ in mapsB:
- map_.reset_topology()
-
- tree = self. _build_1d_rtree(mapsA)
-
- for j in xrange(len(mapsB)):
-
- list_ = gis.ilist()
- rect = self._map_to_rect(tree, mapsB[j])
- num = vector.RTreeSearch2(tree, rect, byref(list_))
- vector.RTreeFreeRect(rect)
-
- for k in xrange(list_.n_values):
- i = list_.value[k] - 1
-
- # Get the temporal relationship
- relation = mapsB[j].temporal_relation(mapsA[i])
-
- A = mapsA[i]
- B = mapsB[j]
- set_temoral_relationship(A, B, relation)
-
- self._build_internal_iteratable(mapsA)
- if not identical and mapsB != None:
- self._build_iteratable(mapsB)
-
- vector.RTreeDestroyTree(tree)
-
- def __iter__(self):
- start_ = self._first
- while start_ is not None:
- yield start_
- start_ = start_.next()
-
- def __getitem__(self, index):
- return self._store[index.get_id()]
-
- def __len__(self):
- return len(self._store)
-
- def __contains__(self, _map):
- return _map in self._store.values()
-
-###############################################################################
-
-
-def set_temoral_relationship(A, B, relation):
- if relation == "equal":
- if B != A:
- if not B.get_equal() or \
- (B.get_equal() and \
- A not in B.get_equal()):
- B.append_equal(A)
- if not A.get_equal() or \
- (A.get_equal() and \
- B not in A.get_equal()):
- A.append_equal(B)
- elif relation == "follows":
- if not B.get_follows() or \
- (B.get_follows() and \
- A not in B.get_follows()):
- B.append_follows(A)
- if not A.get_precedes() or \
- (A.get_precedes() and
- B not in A.get_precedes()):
- A.append_precedes(B)
- elif relation == "precedes":
- if not B.get_precedes() or \
- (B.get_precedes() and \
- A not in B.get_precedes()):
- B.append_precedes(A)
- if not A.get_follows() or \
- (A.get_follows() and \
- B not in A.get_follows()):
- A.append_follows(B)
- elif relation == "during" or relation == "starts" or \
- relation == "finishes":
- if not B.get_during() or \
- (B.get_during() and \
- A not in B.get_during()):
- B.append_during(A)
- if not A.get_contains() or \
- (A.get_contains() and \
- B not in A.get_contains()):
- A.append_contains(B)
- if relation == "starts":
- if not B.get_starts() or \
- (B.get_starts() and \
- A not in B.get_starts()):
- B.append_starts(A)
- if not A.get_started() or \
- (A.get_started() and \
- B not in A.get_started()):
- A.append_started(B)
- if relation == "finishes":
- if not B.get_finishes() or \
- (B.get_finishes() and \
- A not in B.get_finishes()):
- B.append_finishes(A)
- if not A.get_finished() or \
- (A.get_finished() and \
- B not in A.get_finished()):
- A.append_finished(B)
- elif relation == "contains" or relation == "started" or \
- relation == "finished":
- if not B.get_contains() or \
- (B.get_contains() and \
- A not in B.get_contains()):
- B.append_contains(A)
- if not A.get_during() or \
- (A.get_during() and \
- B not in A.get_during()):
- A.append_during(B)
- if relation == "started":
- if not B.get_started() or \
- (B.get_started() and \
- A not in B.get_started()):
- B.append_started(A)
- if not A.get_starts() or \
- (A.get_starts() and \
- B not in A.get_starts()):
- A.append_starts(B)
- if relation == "finished":
- if not B.get_finished() or \
- (B.get_finished() and \
- A not in B.get_finished()):
- B.append_finished(A)
- if not A.get_finishes() or \
- (A.get_finishes() and \
- B not in A.get_finishes()):
- A.append_finishes(B)
- elif relation == "overlaps":
- if not B.get_overlaps() or \
- (B.get_overlaps() and \
- A not in B.get_overlaps()):
- B.append_overlaps(A)
- if not A.get_overlapped() or \
- (A.get_overlapped() and \
- B not in A.get_overlapped()):
- A.append_overlapped(B)
- elif relation == "overlapped":
- if not B.get_overlapped() or \
- (B.get_overlapped() and \
- A not in B.get_overlapped()):
- B.append_overlapped(A)
- if not A.get_overlaps() or \
- (A.get_overlaps() and \
- B not in A.get_overlaps()):
- A.append_overlaps(B)
-
-###############################################################################
-
-def print_temporal_topology_relationships(maps1, maps2=None, dbif=None):
- """!Print the temporal relationships of the
- map lists maps1 and maps2 to stdout.
-
- @param maps1 A list of abstract_dataset
- objects with initiated temporal extent
- @param maps2 An optional list of abstract_dataset
- objects with initiated temporal extent
- @param dbif The database interface to be used
- """
-
- tb = TemporalTopologyBuilder()
-
- tb.build(maps1, maps2)
-
- dbif, connected = init_dbif(dbif)
-
- for _map in tb:
- _map.select(dbif)
- _map.print_info()
-
- if connected:
- dbif.close()
-
- return
-
-###############################################################################
-
-def count_temporal_topology_relationships(maps1, maps2=None, dbif=None):
- """!Count the temporal relations of a single list of maps or between two lists of maps
-
-
- @param maps1 A list of abstract_dataset
- objects with initiated temporal extent
- @param maps2 A list of abstract_dataset
- objects with initiated temporal extent
- @param dbif The database interface to be used
- @return A dictionary with counted temporal relationships
- """
-
-
- tb = TemporalTopologyBuilder()
- tb.build(maps1, maps2)
-
- dbif, connected = init_dbif(dbif)
-
- relations = None
-
- for _map in tb:
- if relations != None:
- r = _map.get_number_of_relations()
- for k in r.keys():
- relations[k] += r[k]
- else:
- relations = _map.get_number_of_relations()
-
- if connected:
- dbif.close()
-
- return relations
-
-###############################################################################
-
-def create_temporal_relation_sql_where_statement(
- start, end, use_start=True, use_during=False,
- use_overlap=False, use_contain=False, use_equal=False,
- use_follows=False, use_precedes=False):
- """!Create a SQL WHERE statement for temporal relation selection of maps in space time datasets
-
- @param start The start time
- @param end The end time
- @param use_start Select maps of which the start time is located in the selection granule
- @verbatim
- map : s
- granule: s-----------------e
-
- map : s--------------------e
- granule: s-----------------e
-
- map : s--------e
- granule: s-----------------e
- @endverbatim
-
- @param use_during Select maps which are temporal during the selection granule
- @verbatim
- map : s-----------e
- granule: s-----------------e
- @endverbatim
-
- @param use_overlap Select maps which temporal overlap the selection granule
- @verbatim
- map : s-----------e
- granule: s-----------------e
-
- map : s-----------e
- granule: s----------e
- @endverbatim
-
- @param use_contain Select maps which temporally contain the selection granule
- @verbatim
- map : s-----------------e
- granule: s-----------e
- @endverbatim
-
- @param use_equal Select maps which temporally equal to the selection granule
- @verbatim
- map : s-----------e
- granule: s-----------e
- @endverbatim
-
- @param use_follows Select maps which temporally follow the selection granule
- @verbatim
- map : s-----------e
- granule: s-----------e
- @endverbatim
-
- @param use_precedes Select maps which temporally precedes the selection granule
- @verbatim
- map : s-----------e
- granule: s-----------e
- @endverbatim
-
- Usage:
-
- @code
-
- >>> # Relative time
- >>> start = 1
- >>> end = 2
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False)
- >>> create_temporal_relation_sql_where_statement(start, end)
- '((start_time >= 1 and start_time < 2) )'
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=True)
- '((start_time >= 1 and start_time < 2) )'
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False, use_during=True)
- '(((start_time > 1 and end_time < 2) OR (start_time >= 1 and end_time < 2) OR (start_time > 1 and end_time <= 2)))'
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False, use_overlap=True)
- '(((start_time < 1 and end_time > 1 and end_time < 2) OR (start_time < 2 and start_time > 1 and end_time > 2)))'
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False, use_contain=True)
- '(((start_time < 1 and end_time > 2) OR (start_time <= 1 and end_time > 2) OR (start_time < 1 and end_time >= 2)))'
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False, use_equal=True)
- '((start_time = 1 and end_time = 2))'
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False, use_follows=True)
- '((start_time = 2))'
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False, use_precedes=True)
- '((end_time = 1))'
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=True, use_during=True, use_overlap=True, use_contain=True,
- ... use_equal=True, use_follows=True, use_precedes=True)
- '((start_time >= 1 and start_time < 2) OR ((start_time > 1 and end_time < 2) OR (start_time >= 1 and end_time < 2) OR (start_time > 1 and end_time <= 2)) OR ((start_time < 1 and end_time > 1 and end_time < 2) OR (start_time < 2 and start_time > 1 and end_time > 2)) OR ((start_time < 1 and end_time > 2) OR (start_time <= 1 and end_time > 2) OR (start_time < 1 and end_time >= 2)) OR (start_time = 1 and end_time = 2) OR (start_time = 2) OR (end_time = 1))'
-
- >>> # Absolute time
- >>> start = datetime(2001, 1, 1, 12, 30)
- >>> end = datetime(2001, 3, 31, 14, 30)
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False)
- >>> create_temporal_relation_sql_where_statement(start, end)
- "((start_time >= '2001-01-01 12:30:00' and start_time < '2001-03-31 14:30:00') )"
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=True)
- "((start_time >= '2001-01-01 12:30:00' and start_time < '2001-03-31 14:30:00') )"
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False, use_during=True)
- "(((start_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time >= '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time > '2001-01-01 12:30:00' and end_time <= '2001-03-31 14:30:00')))"
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False, use_overlap=True)
- "(((start_time < '2001-01-01 12:30:00' and end_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time < '2001-03-31 14:30:00' and start_time > '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00')))"
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False, use_contain=True)
- "(((start_time < '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time <= '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time < '2001-01-01 12:30:00' and end_time >= '2001-03-31 14:30:00')))"
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False, use_equal=True)
- "((start_time = '2001-01-01 12:30:00' and end_time = '2001-03-31 14:30:00'))"
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False, use_follows=True)
- "((start_time = '2001-03-31 14:30:00'))"
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=False, use_precedes=True)
- "((end_time = '2001-01-01 12:30:00'))"
- >>> create_temporal_relation_sql_where_statement(start, end,
- ... use_start=True, use_during=True, use_overlap=True, use_contain=True,
- ... use_equal=True, use_follows=True, use_precedes=True)
- "((start_time >= '2001-01-01 12:30:00' and start_time < '2001-03-31 14:30:00') OR ((start_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time >= '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time > '2001-01-01 12:30:00' and end_time <= '2001-03-31 14:30:00')) OR ((start_time < '2001-01-01 12:30:00' and end_time > '2001-01-01 12:30:00' and end_time < '2001-03-31 14:30:00') OR (start_time < '2001-03-31 14:30:00' and start_time > '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00')) OR ((start_time < '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time <= '2001-01-01 12:30:00' and end_time > '2001-03-31 14:30:00') OR (start_time < '2001-01-01 12:30:00' and end_time >= '2001-03-31 14:30:00')) OR (start_time = '2001-01-01 12:30:00' and end_time = '2001-03-31 14:30:00') OR (start_time = '2001-03-31 14:30:00') OR (end_time = '2001-01-01 12:30:00'))"
-
- @endcode
- """
-
- where = "("
-
- if use_start:
- if isinstance(start, datetime):
- where += "(start_time >= '%s' and start_time < '%s') " % (start, end)
- else:
- where += "(start_time >= %i and start_time < %i) " % (start, end)
-
- if use_during:
- if use_start:
- where += " OR "
-
- if isinstance(start, datetime):
- where += "((start_time > '%s' and end_time < '%s') OR " % (start, end)
- where += "(start_time >= '%s' and end_time < '%s') OR " % (start, end)
- where += "(start_time > '%s' and end_time <= '%s'))" % (start, end)
- else:
- where += "((start_time > %i and end_time < %i) OR " % (start, end)
- where += "(start_time >= %i and end_time < %i) OR " % (start, end)
- where += "(start_time > %i and end_time <= %i))" % (start, end)
-
- if use_overlap:
- if use_start or use_during:
- where += " OR "
-
- if isinstance(start, datetime):
- where += "((start_time < '%s' and end_time > '%s' and end_time < '%s') OR " % (start, start, end)
- where += "(start_time < '%s' and start_time > '%s' and end_time > '%s'))" % (end, start, end)
- else:
- where += "((start_time < %i and end_time > %i and end_time < %i) OR " % (start, start, end)
- where += "(start_time < %i and start_time > %i and end_time > %i))" % (end, start, end)
-
- if use_contain:
- if use_start or use_during or use_overlap:
- where += " OR "
-
- if isinstance(start, datetime):
- where += "((start_time < '%s' and end_time > '%s') OR " % (start, end)
- where += "(start_time <= '%s' and end_time > '%s') OR " % (start, end)
- where += "(start_time < '%s' and end_time >= '%s'))" % (start, end)
- else:
- where += "((start_time < %i and end_time > %i) OR " % (start, end)
- where += "(start_time <= %i and end_time > %i) OR " % (start, end)
- where += "(start_time < %i and end_time >= %i))" % (start, end)
-
- if use_equal:
- if use_start or use_during or use_overlap or use_contain:
- where += " OR "
-
- if isinstance(start, datetime):
- where += "(start_time = '%s' and end_time = '%s')" % (start, end)
- else:
- where += "(start_time = %i and end_time = %i)" % (start, end)
-
- if use_follows:
- if use_start or use_during or use_overlap or use_contain or use_equal:
- where += " OR "
-
- if isinstance(start, datetime):
- where += "(start_time = '%s')" % (end)
- else:
- where += "(start_time = %i)" % (end)
-
- if use_precedes:
- if use_start or use_during or use_overlap or use_contain or use_equal \
- or use_follows:
- where += " OR "
-
- if isinstance(start, datetime):
- where += "(end_time = '%s')" % (start)
- else:
- where += "(end_time = %i)" % (start)
-
- where += ")"
-
- # Catch empty where statement
- if where == "()":
- where = None
-
- return where
-
-
-###############################################################################
-
-if __name__ == "__main__":
- import doctest
- doctest.testmod()
Copied: grass/trunk/lib/python/temporal/temporal_topology_dataset_connector.py (from rev 55991, grass/trunk/lib/python/temporal/abstract_temporal_dataset.py)
===================================================================
--- grass/trunk/lib/python/temporal/temporal_topology_dataset_connector.py (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_topology_dataset_connector.py 2013-04-25 23:07:37 UTC (rev 55998)
@@ -0,0 +1,585 @@
+# -*- coding: utf-8 -*-
+"""!@package grass.temporal
+
+ at brief GRASS Python scripting module (temporal GIS functions)
+
+Temporal GIS related functions to be used in temporal GIS Python library package.
+
+Usage:
+
+>>> import grass.temporal as tgis
+>>> tmr = tgis.TemporalTopologyDatasetConnector()
+
+(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
+"""
+
+class TemporalTopologyDatasetConnector(object):
+ """!This class implements a temporal topology access structure to connect temporal related datasets
+
+ This object will be set up by temporal topology creation method provided by the
+ SpatioTemporalTopologyBuilder.
+
+ If correctly initialize the calls next() and prev()
+ let the user walk temporally forward and backward in time.
+
+ The following temporal relations with access methods are supported:
+ - equal
+ - follows
+ - precedes
+ - overlaps
+ - overlapped
+ - during (including starts, finishes)
+ - contains (including started, finished)
+ - starts
+ - started
+ - finishes
+ - finished
+
+
+ @code:
+ # We have build the temporal topology and we know the first map
+ start = first
+ while start:
+
+ # Print all maps this map temporally contains
+ dlist = start.get_contains()
+ for map in dlist:
+ map.print_info()
+
+ start = start.next()
+ @endcode
+
+ Usage:
+
+ @code
+
+ >>> import grass.temporal as tgis
+ >>> tgis.init()
+ >>> map = tgis.RasterDataset("a at P")
+ >>> tmr = tgis.TemporalTopologyDatasetConnector()
+ >>> tmr.set_next(map)
+ >>> tmr.set_prev(map)
+ >>> tmr.append_equal(map)
+ >>> tmr.append_follows(map)
+ >>> tmr.append_precedes(map)
+ >>> tmr.append_overlapped(map)
+ >>> tmr.append_overlaps(map)
+ >>> tmr.append_during(map)
+ >>> tmr.append_contains(map)
+ >>> tmr.append_starts(map)
+ >>> tmr.append_started(map)
+ >>> tmr.append_finishes(map)
+ >>> tmr.append_finished(map)
+ >>> tmr.print_temporal_topology_info()
+ +-------------------- Temporal Topology -------------------------------------+
+ | Next: ...................... a at P
+ | Previous: .................. a at P
+ | Equal:...................... a at P
+ | Follows: ................... a at P
+ | Precedes: .................. a at P
+ | Overlaps: .................. a at P
+ | Overlapped: ................ a at P
+ | During: .................... a at P
+ | Contains: .................. a at P
+ | Starts:.. .................. a at P
+ | Started:. .................. a at P
+ | Finishes:................... a at P
+ | Finished:................... a at P
+ >>> tmr.print_temporal_topology_shell_info()
+ next=a at P
+ prev=a at P
+ equal=a at P
+ follows=a at P
+ precedes=a at P
+ overlaps=a at P
+ overlapped=a at P
+ during=a at P
+ contains=a at P
+ starts=a at P
+ started=a at P
+ finishes=a at P
+ finished=a at P
+
+ @endcode
+ """
+
+ def __init__(self):
+ self.reset_temporal_topology()
+
+ def reset_temporal_topology(self):
+ """!Reset any information about temporal topology"""
+ self._temporal_topology = {}
+ self._has_temporal_topology = False
+
+ def get_number_of_temporal_relations(self):
+ """! Return a dictionary in which the keys are the relation names and the value
+ are the number of relations.
+
+ The following relations are available:
+ - equal
+ - follows
+ - precedes
+ - overlaps
+ - overlapped
+ - during (including starts, finishes)
+ - contains (including started, finished)
+ - starts
+ - started
+ - finishes
+ - finished
+
+ To access topological information the temporal topology must be build first
+ using the SpatioTemporalTopologyBuilder.
+
+ @return the dictionary with relations as keys and number as values or None in case the topology wasn't build
+ """
+ if self._has_temporal_topology == False:
+ return None
+
+ relations = {}
+ try:
+ relations["equal"] = len(self._temporal_topology["EQUAL"])
+ except:
+ relations["equal"] = 0
+ try:
+ relations["follows"] = len(self._temporal_topology["FOLLOWS"])
+ except:
+ relations["follows"] = 0
+ try:
+ relations["precedes"] = len(self._temporal_topology["PRECEDES"])
+ except:
+ relations["precedes"] = 0
+ try:
+ relations["overlaps"] = len(self._temporal_topology["OVERLAPS"])
+ except:
+ relations["overlaps"] = 0
+ try:
+ relations["overlapped"] = len(self._temporal_topology["OVERLAPPED"])
+ except:
+ relations["overlapped"] = 0
+ try:
+ relations["during"] = len(self._temporal_topology["DURING"])
+ except:
+ relations["during"] = 0
+ try:
+ relations["contains"] = len(self._temporal_topology["CONTAINS"])
+ except:
+ relations["contains"] = 0
+ try:
+ relations["starts"] = len(self._temporal_topology["STARTS"])
+ except:
+ relations["starts"] = 0
+ try:
+ relations["started"] = len(self._temporal_topology["STARTED"])
+ except:
+ relations["started"] = 0
+ try:
+ relations["finishes"] = len(self._temporal_topology["FINISHES"])
+ except:
+ relations["finishes"] = 0
+ try:
+ relations["finished"] = len(self._temporal_topology["FINISHED"])
+ except:
+ relations["finished"] = 0
+
+ return relations
+
+ def set_temporal_topology_build_true(self):
+ """!Same as name"""
+ self._has_temporal_topology = True
+
+ def set_temporal_topology_build_false(self):
+ """!Same as name"""
+ self._has_temporal_topology = False
+
+ def is_temporal_topology_build(self):
+ """!Check if the temporal topology was build"""
+ return self._has_temporal_topology
+
+ def set_next(self, map):
+ """!Set the map that is temporally as closest located after this map.
+
+ Temporally located means that the start time of the "next" map is
+ temporally located AFTER the start time of this map, but temporally
+ near than other maps of the same dataset.
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ self._temporal_topology["NEXT"] = map
+
+ def set_prev(self, map):
+ """!Set the map that is temporally as closest located before this map.
+
+ Temporally located means that the start time of the "previous" map is
+ temporally located BEFORE the start time of this map, but temporally
+ near than other maps of the same dataset.
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ self._temporal_topology["PREV"] = map
+
+ def next(self):
+ """!Return the map with a start time temporally located after
+ the start time of this map, but temporal closer than other maps
+
+ @return A map object or None
+ """
+ if "NEXT" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["NEXT"]
+
+ def prev(self):
+ """!Return the map with a start time temporally located before
+ the start time of this map, but temporal closer than other maps
+
+ @return A map object or None
+ """
+ if "PREV" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["PREV"]
+
+ def append_equal(self, map):
+ """!Append a map with equivalent temporal extent as this map
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "EQUAL" not in self._temporal_topology:
+ self._temporal_topology["EQUAL"] = []
+ self._temporal_topology["EQUAL"].append(map)
+
+ def get_equal(self):
+ """!Return a list of map objects with equivalent temporal extent as this map
+
+ @return A list of map objects or None
+ """
+ if "EQUAL" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["EQUAL"]
+
+ def append_starts(self, map):
+ """!Append a map that this map temporally starts with
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "STARTS" not in self._temporal_topology:
+ self._temporal_topology["STARTS"] = []
+ self._temporal_topology["STARTS"].append(map)
+
+ def get_starts(self):
+ """!Return a list of map objects that this map temporally starts with
+
+ @return A list of map objects or None
+ """
+ if "STARTS" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["STARTS"]
+
+ def append_started(self, map):
+ """!Append a map that this map temporally started with
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "STARTED" not in self._temporal_topology:
+ self._temporal_topology["STARTED"] = []
+ self._temporal_topology["STARTED"].append(map)
+
+ def get_started(self):
+ """!Return a list of map objects that this map temporally started with
+
+ @return A list of map objects or None
+ """
+ if "STARTED" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["STARTED"]
+
+ def append_finishes(self, map):
+ """!Append a map that this map temporally finishes with
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "FINISHES" not in self._temporal_topology:
+ self._temporal_topology["FINISHES"] = []
+ self._temporal_topology["FINISHES"].append(map)
+
+ def get_finishes(self):
+ """!Return a list of map objects that this map temporally finishes with
+
+ @return A list of map objects or None
+ """
+ if "FINISHES" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["FINISHES"]
+
+ def append_finished(self, map):
+ """!Append a map that this map temporally finished with
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "FINISHED" not in self._temporal_topology:
+ self._temporal_topology["FINISHED"] = []
+ self._temporal_topology["FINISHED"].append(map)
+
+ def get_finished(self):
+ """!Return a list of map objects that this map temporally finished with
+
+ @return A list of map objects or None
+ """
+ if "FINISHED" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["FINISHED"]
+
+ def append_overlaps(self, map):
+ """!Append a map that this map temporally overlaps
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "OVERLAPS" not in self._temporal_topology:
+ self._temporal_topology["OVERLAPS"] = []
+ self._temporal_topology["OVERLAPS"].append(map)
+
+ def get_overlaps(self):
+ """!Return a list of map objects that this map temporally overlaps
+
+ @return A list of map objects or None
+ """
+ if "OVERLAPS" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["OVERLAPS"]
+
+ def append_overlapped(self, map):
+ """!Append a map that this map temporally overlapped
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "OVERLAPPED" not in self._temporal_topology:
+ self._temporal_topology["OVERLAPPED"] = []
+ self._temporal_topology["OVERLAPPED"].append(map)
+
+ def get_overlapped(self):
+ """!Return a list of map objects that this map temporally overlapped
+
+ @return A list of map objects or None
+ """
+ if "OVERLAPPED" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["OVERLAPPED"]
+
+ def append_follows(self, map):
+ """!Append a map that this map temporally follows
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "FOLLOWS" not in self._temporal_topology:
+ self._temporal_topology["FOLLOWS"] = []
+ self._temporal_topology["FOLLOWS"].append(map)
+
+ def get_follows(self):
+ """!Return a list of map objects that this map temporally follows
+
+ @return A list of map objects or None
+ """
+ if "FOLLOWS" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["FOLLOWS"]
+
+ def append_precedes(self, map):
+ """!Append a map that this map temporally precedes
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "PRECEDES" not in self._temporal_topology:
+ self._temporal_topology["PRECEDES"] = []
+ self._temporal_topology["PRECEDES"].append(map)
+
+ def get_precedes(self):
+ """!Return a list of map objects that this map temporally precedes
+
+ @return A list of map objects or None
+ """
+ if "PRECEDES" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["PRECEDES"]
+
+ def append_during(self, map):
+ """!Append a map that this map is temporally located during
+ This includes temporal relationships starts and finishes
+
+ @param map This object should be of type
+ AbstractMapDataset or derived classes
+ """
+ if "DURING" not in self._temporal_topology:
+ self._temporal_topology["DURING"] = []
+ self._temporal_topology["DURING"].append(map)
+
+ def get_during(self):
+ """!Return a list of map objects that this map is temporally located during
+ This includes temporally relationships starts and finishes
+
+ @return A list of map objects or None
+ """
+ if "DURING" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["DURING"]
+
+ def append_contains(self, map):
+ """!Append a map that this map temporally contains
+ This includes temporal relationships started and finished
+
+ @param map This object should be of type AbstractMapDataset
+ or derived classes
+ """
+ if "CONTAINS" not in self._temporal_topology:
+ self._temporal_topology["CONTAINS"] = []
+ self._temporal_topology["CONTAINS"].append(map)
+
+ def get_contains(self):
+ """!Return a list of map objects that this map temporally contains
+ This includes temporal relationships started and finished
+
+ @return A list of map objects or None
+ """
+ if "CONTAINS" not in self._temporal_topology:
+ return None
+ return self._temporal_topology["CONTAINS"]
+
+ def _generate_map_list_string(self, map_list, line_wrap=True):
+ count = 0
+ string = ""
+ for map_ in map_list:
+ if line_wrap and count > 0 and count % 3 == 0:
+ string += "\n | ............................ "
+ count = 0
+ if count == 0:
+ string += map_.get_id()
+ else:
+ string += ",%s" % map_.get_id()
+ count += 1
+
+ return string
+
+ # Set the properties
+ equal = property(fget=get_equal,
+ fset=append_equal)
+ follows = property(fget=get_follows,
+ fset=append_follows)
+ precedes = property(fget=get_precedes,
+ fset=append_precedes)
+ overlaps = property(fget=get_overlaps,
+ fset=append_overlaps)
+ overlapped = property(fget=get_overlapped,
+ fset=append_overlapped)
+ during = property(fget=get_during,
+ fset=append_during)
+ contains = property(fget=get_contains,
+ fset=append_contains)
+ starts = property(fget=get_starts,
+ fset=append_starts)
+ started = property(fget=get_started,
+ fset=append_started)
+ finishes = property(fget=get_finishes,
+ fset=append_finishes)
+ finished = property(fget=get_finished,
+ fset=append_finished)
+
+ def print_temporal_topology_info(self):
+ """!Print information about this class in human readable style"""
+
+ print " +-------------------- Temporal Topology -------------------------------------+"
+ # 0123456789012345678901234567890
+ if self.next() is not None:
+ print " | Next: ...................... " + str(self.next().get_id())
+ if self.prev() is not None:
+ print " | Previous: .................. " + str(self.prev().get_id())
+ if self.equal is not None:
+ print " | Equal:...................... " + \
+ self._generate_map_list_string(self.equal)
+ if self.follows is not None:
+ print " | Follows: ................... " + \
+ self._generate_map_list_string(self.follows)
+ if self.precedes is not None:
+ print " | Precedes: .................. " + \
+ self._generate_map_list_string(self.precedes)
+ if self.overlaps is not None:
+ print " | Overlaps: .................. " + \
+ self._generate_map_list_string(self.overlaps)
+ if self.overlapped is not None:
+ print " | Overlapped: ................ " + \
+ self._generate_map_list_string(self.overlapped)
+ if self.during is not None:
+ print " | During: .................... " + \
+ self._generate_map_list_string(self.during)
+ if self.contains is not None:
+ print " | Contains: .................. " + \
+ self._generate_map_list_string(self.contains)
+ if self.starts is not None:
+ print " | Starts:.. .................. " + \
+ self._generate_map_list_string(self.starts)
+ if self.started is not None:
+ print " | Started:. .................. " + \
+ self._generate_map_list_string(self.started)
+ if self.finishes is not None:
+ print " | Finishes:................... " + \
+ self._generate_map_list_string(self.finishes)
+ if self.finished is not None:
+ print " | Finished:................... " + \
+ self._generate_map_list_string(self.finished)
+
+ def print_temporal_topology_shell_info(self):
+ """!Print information about this class in shell style"""
+
+ if self.next() is not None:
+ print "next=" + self.next().get_id()
+ if self.prev() is not None:
+ print "prev=" + self.prev().get_id()
+ if self.equal is not None:
+ print "equal=" + self._generate_map_list_string(self.equal, False)
+ if self.follows is not None:
+ print "follows=" + self._generate_map_list_string(self.follows, False)
+ if self.precedes is not None:
+ print "precedes=" + self._generate_map_list_string(
+ self.precedes, False)
+ if self.overlaps is not None:
+ print "overlaps=" + self._generate_map_list_string(
+ self.overlaps, False)
+ if self.overlapped is not None:
+ print "overlapped=" + \
+ self._generate_map_list_string(self.overlapped, False)
+ if self.during is not None:
+ print "during=" + self._generate_map_list_string(self.during, False)
+ if self.contains is not None:
+ print "contains=" + self._generate_map_list_string(
+ self.contains, False)
+ if self.starts is not None:
+ print "starts=" + \
+ self._generate_map_list_string(self.starts)
+ if self.started is not None:
+ print "started=" + \
+ self._generate_map_list_string(self.started)
+ if self.finishes is not None:
+ print "finishes=" + \
+ self._generate_map_list_string(self.finishes)
+ if self.finished is not None:
+ print "finished=" + \
+ self._generate_map_list_string(self.finished)
+
+###############################################################################
+
+if __name__ == "__main__":
+ import doctest
+ doctest.testmod()
\ No newline at end of file
Modified: grass/trunk/lib/python/temporal/unit_tests.py
===================================================================
--- grass/trunk/lib/python/temporal/unit_tests.py 2013-04-25 22:49:20 UTC (rev 55997)
+++ grass/trunk/lib/python/temporal/unit_tests.py 2013-04-25 23:07:37 UTC (rev 55998)
@@ -1392,7 +1392,7 @@
_map.set_absolute_time(datetime(2001, 05, 01), datetime(2001, 06, 01))
map_listA.append(copy.copy(_map))
- tb = TemporalTopologyBuilder()
+ tb = SpatioTemporalTopologyBuilder()
tb.build(map_listA)
count = 0
@@ -1422,7 +1422,7 @@
_map.set_absolute_time(datetime(2001, 05, 01), datetime(2001, 05, 14))
map_listB.append(copy.copy(_map))
- tb = TemporalTopologyBuilder()
+ tb = SpatioTemporalTopologyBuilder()
tb.build(map_listB)
# Probing some relations
@@ -1445,7 +1445,7 @@
(_map.get_id(), map_listB[count].get_id()))
count += 1
- tb = TemporalTopologyBuilder()
+ tb = SpatioTemporalTopologyBuilder()
tb.build(map_listA, map_listB)
count = 0
More information about the grass-commit
mailing list