[GRASS-SVN] r55988 - grass/trunk/lib/python/temporal
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Apr 24 23:17:50 PDT 2013
Author: huhabla
Date: 2013-04-24 23:17:41 -0700 (Wed, 24 Apr 2013)
New Revision: 55988
Added:
grass/trunk/lib/python/temporal/abstract_spatial_dataset.py
Modified:
grass/trunk/lib/python/temporal/core.py
grass/trunk/lib/python/temporal/pythontemporallib.dox
grass/trunk/lib/python/temporal/space_time_datasets.py
grass/trunk/lib/python/temporal/temporal_relationships.py
Log:
New abstract dataset class to access spatial topology. Added Vect_set_release_support() to redduce memory consumption for vector datasets.
Added: grass/trunk/lib/python/temporal/abstract_spatial_dataset.py
===================================================================
--- grass/trunk/lib/python/temporal/abstract_spatial_dataset.py (rev 0)
+++ grass/trunk/lib/python/temporal/abstract_spatial_dataset.py 2013-04-25 06:17:41 UTC (rev 55988)
@@ -0,0 +1,370 @@
+# -*- 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
Modified: grass/trunk/lib/python/temporal/core.py
===================================================================
--- grass/trunk/lib/python/temporal/core.py 2013-04-24 19:19:45 UTC (rev 55987)
+++ grass/trunk/lib/python/temporal/core.py 2013-04-25 06:17:41 UTC (rev 55988)
@@ -106,7 +106,7 @@
@param use_ctype True use ctypes interface, False use grass.script interface
"""
global use_ctypes_map_access
- use_ctypes_map_access = use_ctypes
+ use_ctypes_map_access = use_ctype
###############################################################################
Modified: grass/trunk/lib/python/temporal/pythontemporallib.dox
===================================================================
--- grass/trunk/lib/python/temporal/pythontemporallib.dox 2013-04-24 19:19:45 UTC (rev 55987)
+++ grass/trunk/lib/python/temporal/pythontemporallib.dox 2013-04-25 06:17:41 UTC (rev 55988)
@@ -204,7 +204,7 @@
\endcode
-\subsevtion PythonTGISExamplesShifting Temporal shifting
+\subsection PythonTGISExamplesShifting Temporal shifting
\code
Modified: grass/trunk/lib/python/temporal/space_time_datasets.py
===================================================================
--- grass/trunk/lib/python/temporal/space_time_datasets.py 2013-04-24 19:19:45 UTC (rev 55987)
+++ grass/trunk/lib/python/temporal/space_time_datasets.py 2013-04-25 06:17:41 UTC (rev 55988)
@@ -26,10 +26,7 @@
import grass.lib.raster as libraster
import grass.lib.vector as libvector
import grass.lib.raster3d as libraster3d
-import grass.script.array as garray
-import grass.script.raster as raster
-import grass.script.vector as vector
-import grass.script.raster3d as raster3d
+import grass.script as grass
from abstract_space_time_dataset import *
@@ -319,12 +316,11 @@
self.base.set_creator(str(getpass.getuser()))
# Get the data from an existing raster map
- global use_ctypes_map_access
- if use_ctypes_map_access:
+ if get_use_ctypes_map_access() == True:
kvp = self.read_info()
else:
- kvp = raster.raster_info(self.get_id())
+ kvp = grass.raster_info(self.get_id())
# Fill spatial extent
@@ -563,12 +559,11 @@
# Fill spatial extent
# Get the data from an existing 3D raster map
- global use_ctypes_map_access
- if use_ctypes_map_access:
+ if get_use_ctypes_map_access() == True:
kvp = self.read_info()
else:
- kvp = raster3d.raster3d_info(self.get_id())
+ kvp = grass.raster3d_info(self.get_id())
self.set_spatial_extent(north=kvp["north"], south=kvp["south"],
east=kvp["east"], west=kvp["west"],
@@ -741,6 +736,9 @@
core.fatal(_("Unable to open vector map <%s>" %
(libvector.Vect_get_full_name(byref(Map)))))
+ # Release the vector spatial index memory when closed
+ libvector.Vect_set_release_support(byref(Map))
+
# Read the extent information
bbox = libvector.bound_box()
libvector.Vect_get_map_box(byref(Map), byref(bbox))
@@ -808,12 +806,11 @@
self.base.set_creator(str(getpass.getuser()))
# Get the data from an existing vector map
- global use_ctypes_map_access
- if use_ctypes_map_access:
+ if get_use_ctypes_map_access() == True:
kvp = self.read_info()
else:
- kvp = vector.vector_info(self.get_map_id())
+ kvp = grass.vector_info(self.get_map_id())
# Fill spatial extent
self.set_spatial_extent(north=kvp["north"], south=kvp["south"],
Modified: grass/trunk/lib/python/temporal/temporal_relationships.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_relationships.py 2013-04-24 19:19:45 UTC (rev 55987)
+++ grass/trunk/lib/python/temporal/temporal_relationships.py 2013-04-25 06:17:41 UTC (rev 55988)
@@ -171,7 +171,7 @@
def _build_1d_rtree(self, maps):
"""Build and return the one dimensional R*-Tree"""
- tree = vector.RTreeCreateTree(-1, 0, 4)
+ tree = vector.RTreeCreateTree(-1, 0, 1)
for i in xrange(len(maps)):
@@ -231,108 +231,9 @@
# Get the temporal relationship
relation = mapsB[j].temporal_relation(mapsA[i])
- if relation == "equal":
- if mapsB[j] != mapsA[i]:
- if not mapsB[j].get_equal() or \
- (mapsB[j].get_equal() and \
- mapsA[i] not in mapsB[j].get_equal()):
- mapsB[j].append_equal(mapsA[i])
- if not mapsA[i].get_equal() or \
- (mapsA[i].get_equal() and \
- mapsB[j] not in mapsA[i].get_equal()):
- mapsA[i].append_equal(mapsB[j])
- elif relation == "follows":
- if not mapsB[j].get_follows() or \
- (mapsB[j].get_follows() and \
- mapsA[i] not in mapsB[j].get_follows()):
- mapsB[j].append_follows(mapsA[i])
- if not mapsA[i].get_precedes() or \
- (mapsA[i].get_precedes() and
- mapsB[j] not in mapsA[i].get_precedes()):
- mapsA[i].append_precedes(mapsB[j])
- elif relation == "precedes":
- if not mapsB[j].get_precedes() or \
- (mapsB[j].get_precedes() and \
- mapsA[i] not in mapsB[j].get_precedes()):
- mapsB[j].append_precedes(mapsA[i])
- if not mapsA[i].get_follows() or \
- (mapsA[i].get_follows() and \
- mapsB[j] not in mapsA[i].get_follows()):
- mapsA[i].append_follows(mapsB[j])
- elif relation == "during" or relation == "starts" or \
- relation == "finishes":
- if not mapsB[j].get_during() or \
- (mapsB[j].get_during() and \
- mapsA[i] not in mapsB[j].get_during()):
- mapsB[j].append_during(mapsA[i])
- if not mapsA[i].get_contains() or \
- (mapsA[i].get_contains() and \
- mapsB[j] not in mapsA[i].get_contains()):
- mapsA[i].append_contains(mapsB[j])
- if relation == "starts":
- if not mapsB[j].get_starts() or \
- (mapsB[j].get_starts() and \
- mapsA[i] not in mapsB[j].get_starts()):
- mapsB[j].append_starts(mapsA[i])
- if not mapsA[i].get_started() or \
- (mapsA[i].get_started() and \
- mapsB[j] not in mapsA[i].get_started()):
- mapsA[i].append_started(mapsB[j])
- if relation == "finishes":
- if not mapsB[j].get_finishes() or \
- (mapsB[j].get_finishes() and \
- mapsA[i] not in mapsB[j].get_finishes()):
- mapsB[j].append_finishes(mapsA[i])
- if not mapsA[i].get_finished() or \
- (mapsA[i].get_finished() and \
- mapsB[j] not in mapsA[i].get_finished()):
- mapsA[i].append_finished(mapsB[j])
- elif relation == "contains" or relation == "started" or \
- relation == "finished":
- if not mapsB[j].get_contains() or \
- (mapsB[j].get_contains() and \
- mapsA[i] not in mapsB[j].get_contains()):
- mapsB[j].append_contains(mapsA[i])
- if not mapsA[i].get_during() or \
- (mapsA[i].get_during() and \
- mapsB[j] not in mapsA[i].get_during()):
- mapsA[i].append_during(mapsB[j])
- if relation == "started":
- if not mapsB[j].get_started() or \
- (mapsB[j].get_started() and \
- mapsA[i] not in mapsB[j].get_started()):
- mapsB[j].append_started(mapsA[i])
- if not mapsA[i].get_starts() or \
- (mapsA[i].get_starts() and \
- mapsB[j] not in mapsA[i].get_starts()):
- mapsA[i].append_starts(mapsB[j])
- if relation == "finished":
- if not mapsB[j].get_finished() or \
- (mapsB[j].get_finished() and \
- mapsA[i] not in mapsB[j].get_finished()):
- mapsB[j].append_finished(mapsA[i])
- if not mapsA[i].get_finishes() or \
- (mapsA[i].get_finishes() and \
- mapsB[j] not in mapsA[i].get_finishes()):
- mapsA[i].append_finishes(mapsB[j])
- elif relation == "overlaps":
- if not mapsB[j].get_overlaps() or \
- (mapsB[j].get_overlaps() and \
- mapsA[i] not in mapsB[j].get_overlaps()):
- mapsB[j].append_overlaps(mapsA[i])
- if not mapsA[i].get_overlapped() or \
- (mapsA[i].get_overlapped() and \
- mapsB[j] not in mapsA[i].get_overlapped()):
- mapsA[i].append_overlapped(mapsB[j])
- elif relation == "overlapped":
- if not mapsB[j].get_overlapped() or \
- (mapsB[j].get_overlapped() and \
- mapsA[i] not in mapsB[j].get_overlapped()):
- mapsB[j].append_overlapped(mapsA[i])
- if not mapsA[i].get_overlaps() or \
- (mapsA[i].get_overlaps() and \
- mapsB[j] not in mapsA[i].get_overlaps()):
- mapsA[i].append_overlaps(mapsB[j])
+ A = mapsA[i]
+ B = mapsB[j]
+ set_temoral_relationship(A, B, relation)
self._build_internal_iteratable(mapsA)
if not identical and mapsB != None:
@@ -357,6 +258,113 @@
###############################################################################
+
+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.
More information about the grass-commit
mailing list