[GRASS-SVN] r58807 - in grass/trunk: lib/python/temporal temporal temporal/t.vect.mapcalc temporal/t.vect.mapcalc/test_suite
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jan 30 09:00:32 PST 2014
Author: huhabla
Date: 2014-01-30 09:00:32 -0800 (Thu, 30 Jan 2014)
New Revision: 58807
Added:
grass/trunk/lib/python/temporal/temporal_vector_algebra.py
grass/trunk/lib/python/temporal/temporal_vector_operator.py
grass/trunk/temporal/t.vect.mapcalc/
grass/trunk/temporal/t.vect.mapcalc/Makefile
grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.html
grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.py
grass/trunk/temporal/t.vect.mapcalc/test_suite/
grass/trunk/temporal/t.vect.mapcalc/test_suite/test.t.vect.mapcalc.sh
Modified:
grass/trunk/lib/python/temporal/Makefile
grass/trunk/lib/python/temporal/__init__.py
grass/trunk/lib/python/temporal/register.py
grass/trunk/lib/python/temporal/temporal_algebra.py
Log:
Added modified temporal vector algebra code from GSoC 2013 student Thomas Leppelt.
Modified: grass/trunk/lib/python/temporal/Makefile
===================================================================
--- grass/trunk/lib/python/temporal/Makefile 2014-01-29 19:29:26 UTC (rev 58806)
+++ grass/trunk/lib/python/temporal/Makefile 2014-01-30 17:00:32 UTC (rev 58807)
@@ -8,7 +8,7 @@
GDIR = $(PYDIR)/grass
DSTDIR = $(GDIR)/temporal
-MODULES = base core abstract_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets open_stds factory gui_support list_stds 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 c_libraries_interface temporal_algebra
+MODULES = base core abstract_dataset abstract_map_dataset abstract_space_time_dataset space_time_datasets open_stds factory gui_support list_stds 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 c_libraries_interface temporal_algebra temporal_vector_algebra temporal_vector_operator
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 2014-01-29 19:29:26 UTC (rev 58806)
+++ grass/trunk/lib/python/temporal/__init__.py 2014-01-30 17:00:32 UTC (rev 58807)
@@ -26,3 +26,5 @@
from univar_statistics import *
from c_libraries_interface import *
from temporal_algebra import *
+from temporal_vector_algebra import *
+from temporal_vector_operator import *
Modified: grass/trunk/lib/python/temporal/register.py
===================================================================
--- grass/trunk/lib/python/temporal/register.py 2014-01-29 19:29:26 UTC (rev 58806)
+++ grass/trunk/lib/python/temporal/register.py 2014-01-30 17:00:32 UTC (rev 58807)
@@ -172,6 +172,12 @@
# Get a new instance of the map type
map = dataset_factory(type, maplist[count]["id"])
+
+ if map.map_exists() is not True:
+ msgr.fatal(_("Unable to update %(t)s map <%(id)s>. "
+ "The map does not exists.") %
+ {'t': map.get_type(),
+ 'id': map.get_map_id()})
# Use the time data from file
if "start" in maplist[count]:
Modified: grass/trunk/lib/python/temporal/temporal_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_algebra.py 2014-01-29 19:29:26 UTC (rev 58806)
+++ grass/trunk/lib/python/temporal/temporal_algebra.py 2014-01-30 17:00:32 UTC (rev 58807)
@@ -2,12 +2,12 @@
Temporal algebra parser class
-(C) 2013 by the GRASS Development Team
+(C) 2014 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 Thomas Leppelt and Soeren Gebbert
+ at authors Thomas Leppelt and Soeren Gebbert
@code
@@ -659,13 +659,9 @@
self.run = run
self.debug = debug
self.pid = pid
- self.lexer = TemporalAlgebraLexer()
- self.lexer.build()
# Intermediate vector map names
self.names = {}
# Count map names
- self.count = 0
- self.parser = yacc.yacc(module=self, debug=False)
self.spatial = spatial
self.null = null
self.mapset = get_current_mapset()
@@ -679,6 +675,10 @@
self.dbif.close()
def parse(self, expression, stdstype = 'strds', basename = None):
+ self.lexer = TemporalAlgebraLexer()
+ self.lexer.build()
+ self.parser = yacc.yacc(module=self, debug=self.debug)
+
self.count = 0
self.stdstype = stdstype
self.basename = basename
@@ -1685,19 +1685,21 @@
'mean', None, \
overwrite = grass.overwrite())
if isinstance(t[3], list):
- dbif, connect = init_dbif(None)
num = len(t[3])
count = 0
- for map in t[3]:
- map.select()
- #map.update()
- resultstds.register_map(map, dbif)
- count += 1
- if count % 10 == 0:
- self.msgr.percent(count, num, 1)
+ if num > 0:
+ dbif, connected = init_dbif(None)
+ for map in t[3]:
+ map.select(dbif=dbif)
+ #map.update()
+ resultstds.register_map(map, dbif=dbif)
+ count += 1
+ if count % 10 == 0:
+ self.msgr.percent(count, num, 1)
- resultstds.update_from_registered_maps(dbif)
- dbif.close()
+ resultstds.update_from_registered_maps(dbif=dbif)
+ if connected:
+ dbif.close()
t[0] = t[3]
if self.debug:
@@ -2249,7 +2251,6 @@
print t[3] + "* = tshift(", t[3], ",", t[5], ")"
t[0] = t[3] + "*"
-
# Handle errors.
def p_error(self, t):
raise SyntaxError("syntax error on line %d near '%s' expression '%s'" %
Added: grass/trunk/lib/python/temporal/temporal_vector_algebra.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_vector_algebra.py (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_vector_algebra.py 2014-01-30 17:00:32 UTC (rev 58807)
@@ -0,0 +1,1013 @@
+"""!@package grass.temporal
+
+Temporal vector algebra
+
+(C) 2014 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 authors Thomas Leppelt and Soeren Gebbert
+
+ at code
+
+ >>> import grass.temporal as tgis
+ >>> tgis.init(True)
+ >>> p = tgis.TemporalVectorAlgebraLexer()
+ >>> p.build()
+ >>> p.debug = True
+ >>> expression = "C = A : B"
+ >>> p.test(expression)
+ C = A : B
+ LexToken(NAME,'C',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(NAME,'A',1,4)
+ LexToken(T_SELECT,':',1,6)
+ LexToken(NAME,'B',1,8)
+ >>> expression = "C = test1 !: test2"
+ >>> p.test(expression)
+ C = test1 !: test2
+ LexToken(NAME,'C',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(NAME,'test1',1,4)
+ LexToken(T_NOT_SELECT,'!:',1,10)
+ LexToken(NAME,'test2',1,13)
+ >>> expression = "C = test1 {equal,:} test2"
+ >>> p.test(expression)
+ C = test1 {equal,:} test2
+ LexToken(NAME,'C',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(NAME,'test1',1,4)
+ LexToken(T_SELECT_OPERATOR,'{equal,:}',1,10)
+ LexToken(NAME,'test2',1,20)
+ >>> expression = "C = test1 {equal,!:} test2"
+ >>> p.test(expression)
+ C = test1 {equal,!:} test2
+ LexToken(NAME,'C',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(NAME,'test1',1,4)
+ LexToken(T_SELECT_OPERATOR,'{equal,!:}',1,10)
+ LexToken(NAME,'test2',1,21)
+ >>> expression = "C = test1 # test2"
+ >>> p.test(expression)
+ C = test1 # test2
+ LexToken(NAME,'C',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(NAME,'test1',1,4)
+ LexToken(HASH,'#',1,10)
+ LexToken(NAME,'test2',1,12)
+ >>> expression = "C = test1 {#} test2"
+ >>> p.test(expression)
+ C = test1 {#} test2
+ LexToken(NAME,'C',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(NAME,'test1',1,4)
+ LexToken(T_HASH_OPERATOR,'{#}',1,10)
+ LexToken(NAME,'test2',1,14)
+ >>> expression = "C = test1 {equal,#} test2"
+ >>> p.test(expression)
+ C = test1 {equal,#} test2
+ LexToken(NAME,'C',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(NAME,'test1',1,4)
+ LexToken(T_HASH_OPERATOR,'{equal,#}',1,10)
+ LexToken(NAME,'test2',1,20)
+ >>> expression = "C = test1 {equal|during,#} test2"
+ >>> p.test(expression)
+ C = test1 {equal|during,#} test2
+ LexToken(NAME,'C',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(NAME,'test1',1,4)
+ LexToken(T_HASH_OPERATOR,'{equal|during,#}',1,10)
+ LexToken(NAME,'test2',1,27)
+ >>> expression = "E = test1 : test2 !: test1"
+ >>> p.test(expression)
+ E = test1 : test2 !: test1
+ LexToken(NAME,'E',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(NAME,'test1',1,4)
+ LexToken(T_SELECT,':',1,10)
+ LexToken(NAME,'test2',1,12)
+ LexToken(T_NOT_SELECT,'!:',1,18)
+ LexToken(NAME,'test1',1,21)
+ >>> expression = 'D = buff_t(test1,"10 months")'
+ >>> p.test(expression)
+ D = buff_t(test1,"10 months")
+ LexToken(NAME,'D',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(BUFF_T,'buff_t',1,4)
+ LexToken(LPAREN,'(',1,10)
+ LexToken(NAME,'test1',1,11)
+ LexToken(COMMA,',',1,16)
+ LexToken(QUOTE,'"',1,17)
+ LexToken(INT,10,1,18)
+ LexToken(NAME,'months',1,21)
+ LexToken(QUOTE,'"',1,27)
+ LexToken(RPAREN,')',1,28)
+ >>> expression = 'H = tsnap(test1)'
+ >>> p.test(expression)
+ H = tsnap(test1)
+ LexToken(NAME,'H',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(TSNAP,'tsnap',1,4)
+ LexToken(LPAREN,'(',1,9)
+ LexToken(NAME,'test1',1,10)
+ LexToken(RPAREN,')',1,15)
+ >>> expression = 'H = tsnap(test2 {during,:} buff_t(test1, "1 days"))'
+ >>> p.test(expression)
+ H = tsnap(test2 {during,:} buff_t(test1, "1 days"))
+ LexToken(NAME,'H',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(TSNAP,'tsnap',1,4)
+ LexToken(LPAREN,'(',1,9)
+ LexToken(NAME,'test2',1,10)
+ LexToken(T_SELECT_OPERATOR,'{during,:}',1,16)
+ LexToken(BUFF_T,'buff_t',1,27)
+ LexToken(LPAREN,'(',1,33)
+ LexToken(NAME,'test1',1,34)
+ LexToken(COMMA,',',1,39)
+ LexToken(QUOTE,'"',1,41)
+ LexToken(INT,1,1,42)
+ LexToken(NAME,'days',1,44)
+ LexToken(QUOTE,'"',1,48)
+ LexToken(RPAREN,')',1,49)
+ LexToken(RPAREN,')',1,50)
+ >>> expression = 'H = tshift(test2 {during,:} buff_t(test1, "1 days"), "1 months")'
+ >>> p.test(expression)
+ H = tshift(test2 {during,:} buff_t(test1, "1 days"), "1 months")
+ LexToken(NAME,'H',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(TSHIFT,'tshift',1,4)
+ LexToken(LPAREN,'(',1,10)
+ LexToken(NAME,'test2',1,11)
+ LexToken(T_SELECT_OPERATOR,'{during,:}',1,17)
+ LexToken(BUFF_T,'buff_t',1,28)
+ LexToken(LPAREN,'(',1,34)
+ LexToken(NAME,'test1',1,35)
+ LexToken(COMMA,',',1,40)
+ LexToken(QUOTE,'"',1,42)
+ LexToken(INT,1,1,43)
+ LexToken(NAME,'days',1,45)
+ LexToken(QUOTE,'"',1,49)
+ LexToken(RPAREN,')',1,50)
+ LexToken(COMMA,',',1,51)
+ LexToken(QUOTE,'"',1,53)
+ LexToken(INT,1,1,54)
+ LexToken(NAME,'months',1,56)
+ LexToken(QUOTE,'"',1,62)
+ LexToken(RPAREN,')',1,63)
+ >>> expression = 'H = tshift(A , 10)'
+ >>> p.test(expression)
+ H = tshift(A , 10)
+ LexToken(NAME,'H',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(TSHIFT,'tshift',1,4)
+ LexToken(LPAREN,'(',1,10)
+ LexToken(NAME,'A',1,11)
+ LexToken(COMMA,',',1,13)
+ LexToken(INT,10,1,15)
+ LexToken(RPAREN,')',1,17)
+ >>> expression = 'H = if(td(A) > 10, A)'
+ >>> p.test(expression)
+ H = if(td(A) > 10, A)
+ LexToken(NAME,'H',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(IF,'if',1,4)
+ LexToken(LPAREN,'(',1,6)
+ LexToken(TD,'td',1,7)
+ LexToken(LPAREN,'(',1,9)
+ LexToken(NAME,'A',1,10)
+ LexToken(RPAREN,')',1,11)
+ LexToken(GREATER,'>',1,13)
+ LexToken(INT,10,1,15)
+ LexToken(COMMA,',',1,17)
+ LexToken(NAME,'A',1,19)
+ LexToken(RPAREN,')',1,20)
+ >>> expression = 'H = if(td(A) > 10, A, B)'
+ >>> p.test(expression)
+ H = if(td(A) > 10, A, B)
+ LexToken(NAME,'H',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(IF,'if',1,4)
+ LexToken(LPAREN,'(',1,6)
+ LexToken(TD,'td',1,7)
+ LexToken(LPAREN,'(',1,9)
+ LexToken(NAME,'A',1,10)
+ LexToken(RPAREN,')',1,11)
+ LexToken(GREATER,'>',1,13)
+ LexToken(INT,10,1,15)
+ LexToken(COMMA,',',1,17)
+ LexToken(NAME,'A',1,19)
+ LexToken(COMMA,',',1,20)
+ LexToken(NAME,'B',1,22)
+ LexToken(RPAREN,')',1,23)
+ >>> expression = 'I = if(equals,td(A) > 10 {equals,||} td(B) < 10, A)'
+ >>> p.test(expression)
+ I = if(equals,td(A) > 10 {equals,||} td(B) < 10, A)
+ LexToken(NAME,'I',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(IF,'if',1,4)
+ LexToken(LPAREN,'(',1,6)
+ LexToken(NAME,'equals',1,7)
+ LexToken(COMMA,',',1,13)
+ LexToken(TD,'td',1,14)
+ LexToken(LPAREN,'(',1,16)
+ LexToken(NAME,'A',1,17)
+ LexToken(RPAREN,')',1,18)
+ LexToken(GREATER,'>',1,20)
+ LexToken(INT,10,1,22)
+ LexToken(T_OVERLAY_OPERATOR,'{equals,||}',1,25)
+ LexToken(TD,'td',1,37)
+ LexToken(LPAREN,'(',1,39)
+ LexToken(NAME,'B',1,40)
+ LexToken(RPAREN,')',1,41)
+ LexToken(LOWER,'<',1,43)
+ LexToken(INT,10,1,45)
+ LexToken(COMMA,',',1,47)
+ LexToken(NAME,'A',1,49)
+ LexToken(RPAREN,')',1,50)
+ >>> expression = 'I = if(equals,td(A) > 10 || start_day() < 10, A)'
+ >>> p.test(expression)
+ I = if(equals,td(A) > 10 || start_day() < 10, A)
+ LexToken(NAME,'I',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(IF,'if',1,4)
+ LexToken(LPAREN,'(',1,6)
+ LexToken(NAME,'equals',1,7)
+ LexToken(COMMA,',',1,13)
+ LexToken(TD,'td',1,14)
+ LexToken(LPAREN,'(',1,16)
+ LexToken(NAME,'A',1,17)
+ LexToken(RPAREN,')',1,18)
+ LexToken(GREATER,'>',1,20)
+ LexToken(INT,10,1,22)
+ LexToken(OR,'|',1,25)
+ LexToken(OR,'|',1,26)
+ LexToken(START_DAY,'start_day',1,28)
+ LexToken(LPAREN,'(',1,37)
+ LexToken(RPAREN,')',1,38)
+ LexToken(LOWER,'<',1,40)
+ LexToken(INT,10,1,42)
+ LexToken(COMMA,',',1,44)
+ LexToken(NAME,'A',1,46)
+ LexToken(RPAREN,')',1,47)
+ >>> expression = 'E = if({equals},td(A) >= 4 {contain,&&} td(B) == 2, C : D)'
+ >>> p.test(expression)
+ E = if({equals},td(A) >= 4 {contain,&&} td(B) == 2, C : D)
+ LexToken(NAME,'E',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(IF,'if',1,4)
+ LexToken(LPAREN,'(',1,6)
+ LexToken(T_REL_OPERATOR,'{equals}',1,7)
+ LexToken(COMMA,',',1,15)
+ LexToken(TD,'td',1,16)
+ LexToken(LPAREN,'(',1,18)
+ LexToken(NAME,'A',1,19)
+ LexToken(RPAREN,')',1,20)
+ LexToken(GREATER_EQUALS,'>=',1,22)
+ LexToken(INT,4,1,25)
+ LexToken(T_OVERLAY_OPERATOR,'{contain,&&}',1,27)
+ LexToken(TD,'td',1,40)
+ LexToken(LPAREN,'(',1,42)
+ LexToken(NAME,'B',1,43)
+ LexToken(RPAREN,')',1,44)
+ LexToken(CEQUALS,'==',1,46)
+ LexToken(INT,2,1,49)
+ LexToken(COMMA,',',1,50)
+ LexToken(NAME,'C',1,52)
+ LexToken(T_SELECT,':',1,54)
+ LexToken(NAME,'D',1,56)
+ LexToken(RPAREN,')',1,57)
+ >>> expression = 'F = if({equals},A {equal,#}, B, C : D)'
+ >>> p.test(expression)
+ F = if({equals},A {equal,#}, B, C : D)
+ LexToken(NAME,'F',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(IF,'if',1,4)
+ LexToken(LPAREN,'(',1,6)
+ LexToken(T_REL_OPERATOR,'{equals}',1,7)
+ LexToken(COMMA,',',1,15)
+ LexToken(NAME,'A',1,16)
+ LexToken(T_HASH_OPERATOR,'{equal,#}',1,18)
+ LexToken(COMMA,',',1,27)
+ LexToken(NAME,'B',1,29)
+ LexToken(COMMA,',',1,30)
+ LexToken(NAME,'C',1,32)
+ LexToken(T_SELECT,':',1,34)
+ LexToken(NAME,'D',1,36)
+ LexToken(RPAREN,')',1,37)
+ >>> expression = 'E = A : B ^ C : D'
+ >>> p.test(expression)
+ E = A : B ^ C : D
+ LexToken(NAME,'E',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(NAME,'A',1,4)
+ LexToken(T_SELECT,':',1,6)
+ LexToken(NAME,'B',1,8)
+ LexToken(XOR,'^',1,10)
+ LexToken(NAME,'C',1,12)
+ LexToken(T_SELECT,':',1,14)
+ LexToken(NAME,'D',1,16)
+ >>> expression = 'E = A : B {|^} C : D'
+ >>> p.test(expression)
+ E = A : B {|^} C : D
+ LexToken(NAME,'E',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(NAME,'A',1,4)
+ LexToken(T_SELECT,':',1,6)
+ LexToken(NAME,'B',1,8)
+ LexToken(T_OVERLAY_OPERATOR,'{|^}',1,10)
+ LexToken(NAME,'C',1,15)
+ LexToken(T_SELECT,':',1,17)
+ LexToken(NAME,'D',1,19)
+ >>> expression = 'E = buff_a(A, 10)'
+ >>> p.test(expression)
+ E = buff_a(A, 10)
+ LexToken(NAME,'E',1,0)
+ LexToken(EQUALS,'=',1,2)
+ LexToken(BUFF_AREA,'buff_a',1,4)
+ LexToken(LPAREN,'(',1,10)
+ LexToken(NAME,'A',1,11)
+ LexToken(COMMA,',',1,12)
+ LexToken(INT,10,1,14)
+ LexToken(RPAREN,')',1,16)
+ >>> p = tgis.TemporalVectorAlgebraParser()
+ >>> p.run = False
+ >>> p.debug = True
+ >>> expression = "D = A : (B !: C)"
+ >>> p.parse(expression)
+ B* = B !: C
+ A* = A : B*
+ D = A*
+ >>> expression = "D = A {!:} B {during,:} C"
+ >>> print(expression)
+ D = A {!:} B {during,:} C
+ >>> p.parse(expression)
+ A* = A {!:} B
+ A** = A* {during,:} C
+ D = A**
+ >>> expression = "D = A {:} B {during,!:} C"
+ >>> print(expression)
+ D = A {:} B {during,!:} C
+ >>> p.parse(expression)
+ A* = A {:} B
+ A** = A* {during,!:} C
+ D = A**
+ >>> expression = "D = A {:} (B {during,!:} (C : E))"
+ >>> print(expression)
+ D = A {:} (B {during,!:} (C : E))
+ >>> p.parse(expression)
+ C* = C : E
+ B* = B {during,!:} C*
+ A* = A {:} B*
+ D = A*
+ >>> p.run = False
+ >>> p.debug = False
+ >>> expression = "C = test1 : test2"
+ >>> print(expression)
+ C = test1 : test2
+ >>> p.parse(expression, 'stvds')
+ >>> expression = 'D = buff_t(test1,"10 months")'
+ >>> print(expression)
+ D = buff_t(test1,"10 months")
+ >>> p.parse(expression, 'stvds')
+ >>> expression = 'E = test2 {during,:} buff_t(test1,"1 days")'
+ >>> print(expression)
+ E = test2 {during,:} buff_t(test1,"1 days")
+ >>> p.parse(expression, 'stvds')
+ >>> expression = 'F = test2 {equal,:} buff_t(test1,"1 days")'
+ >>> print(expression)
+ F = test2 {equal,:} buff_t(test1,"1 days")
+ >>> p.parse(expression, 'stvds')
+ >>> p.debug = True
+ >>> expression = 'H = tsnap(test2 {during,:} buff_t(test1, "1 days"))'
+ >>> p.parse(expression, 'stvds')
+ test1* = buff_t( test1 , " 1 days " )
+ test2* = test2 {during,:} test1*
+ test2** = tsnap( test2* )
+ H = test2**
+ >>> expression = 'H = tshift(test2 {during,:} test1, "1 days")'
+ >>> p.parse(expression, 'stvds')
+ test2* = test2 {during,:} test1
+ test2** = tshift( test2* , " 1 days " )
+ H = test2**
+ >>> expression = 'H = tshift(H, 3)'
+ >>> p.parse(expression, 'stvds')
+ H* = tshift( H , 3 )
+ H = H*
+ >>> expression = 'C = if(td(A) == 2, A)'
+ >>> p.parse(expression, 'stvds')
+ td(A)
+ td(A) == 2
+ A* = if condition True then A
+ C = A*
+ >>> expression = 'C = if(td(A) == 5 || start_date() >= "2010-01-01", A, B)'
+ >>> p.parse(expression, 'stvds')
+ td(A)
+ td(A) == 5
+ start_date >= "2010-01-01"
+ True || True
+ A* = if condition True then A else B
+ C = A*
+ >>> expression = 'C = if(td(A) == 5, A, B)'
+ >>> p.parse(expression, 'stvds')
+ td(A)
+ td(A) == 5
+ A* = if condition True then A else B
+ C = A*
+
+ at endcode
+"""
+
+try:
+ import ply.yacc as yacc
+except:
+ pass
+
+import grass.pygrass.modules as pygrass
+import grass.script as grass
+from space_time_datasets import *
+from factory import *
+from open_stds import *
+import copy
+from temporal_vector_operator import *
+from temporal_algebra import *
+
+m_overlay = pygrass.Module('v.overlay', quiet=True, run_=False)
+m_rename = pygrass.Module('g.rename', quiet=True, run_=False)
+m_patch = pygrass.Module('v.patch', quiet=True, run_=False)
+m_mremove = pygrass.Module('g.mremove', quiet=True, run_=False)
+m_buffer = pygrass.Module('v.buffer', quiet=True, run_=False)
+
+##############################################################################
+
+class TemporalVectorAlgebraLexer(TemporalAlgebraLexer):
+ """!Lexical analyzer for the GRASS GIS temporal vector algebra"""
+
+ def __init__(self):
+ TemporalAlgebraLexer.__init__(self)
+
+ # Buffer functions from v.buffer
+ vector_buff_functions = {
+ 'buff_p' : 'BUFF_POINT',
+ 'buff_l' : 'BUFF_LINE',
+ 'buff_a' : 'BUFF_AREA',
+ }
+
+ # This is the list of token names.
+ vector_tokens = (
+ 'DISOR',
+ 'XOR',
+ 'NOT',
+ 'T_OVERLAY_OPERATOR',
+ )
+
+ # Build the token list
+ tokens = TemporalAlgebraLexer.tokens \
+ + vector_tokens \
+ + tuple(vector_buff_functions.values())
+
+ # Regular expression rules for simple tokens
+ t_DISOR = r'\+'
+ t_XOR = r'\^'
+ t_NOT = r'\~'
+ t_T_OVERLAY_OPERATOR = r'\{([a-zA-Z\|]+[,])?([\|&+=]?[\|&+=\^\~])\}'
+
+ # Parse symbols
+ def temporal_symbol(self, t):
+ # Check for reserved words
+ if t.value in TemporalVectorAlgebraLexer.time_functions.keys():
+ t.type = TemporalVectorAlgebraLexer.time_functions.get(t.value)
+ elif t.value in TemporalVectorAlgebraLexer.datetime_functions.keys():
+ t.type = TemporalVectorAlgebraLexer.datetime_functions.get(t.value)
+ elif t.value in TemporalVectorAlgebraLexer.conditional_functions.keys():
+ t.type = TemporalVectorAlgebraLexer.conditional_functions.get(t.value)
+ elif t.value in TemporalVectorAlgebraLexer.vector_buff_functions.keys():
+ t.type = TemporalVectorAlgebraLexer.vector_buff_functions.get(t.value)
+ else:
+ t.type = 'NAME'
+ return t
+
+class TemporalVectorAlgebraParser(TemporalAlgebraParser):
+ """The temporal algebra class"""
+
+ # Get the tokens from the lexer class
+ tokens = TemporalVectorAlgebraLexer.tokens
+
+ def remove_intermediate_vector_maps(self):
+ """! Removes the intermediate vector maps.
+ """
+ if self.names != {}:
+ namelist = self.names.values()
+ max = 100
+ chunklist = [namelist[i:i + max] for i in range(0, len(namelist), max)]
+ for chunk in chunklist:
+ stringlist = ",".join(chunk)
+ if self.debug:
+ print "g.mremove vect=%s"%(stringlist)
+
+ if self.run:
+ m = copy.deepcopy(m_mremove)
+ m.inputs["vect"].value = stringlist
+ m.flags["f"].value = True
+ m.run()
+
+ # Setting equal precedence level for select and hash operations.
+ precedence = (
+ ('left', 'T_SELECT_OPERATOR', 'T_SELECT', 'T_NOT_SELECT'), # 1
+ ('left', 'AND', 'OR', 'T_COMP_OPERATOR', 'T_OVERLAY_OPERATOR', 'DISOR', \
+ 'NOT', 'XOR'), #2
+ )
+
+ def __init__(self, pid=None, run=False, debug=True, spatial = False):
+ TemporalAlgebraParser.__init__(self, pid, run, debug, spatial)
+
+ def parse(self, expression, stdstype = 'strds', basename = None):
+ self.lexer = TemporalVectorAlgebraLexer()
+ self.lexer.build()
+ self.parser = yacc.yacc(module=self, debug=self.debug)
+
+ self.count = 0
+ self.stdstype = stdstype
+ self.basename = basename
+ self.expression = expression
+ self.parser.parse(expression)
+
+
+ ######################### Temporal functions ##############################
+
+ def eval_toperator(self, operator, comparison = False):
+ """!This function evaluates a string containing temporal operations.
+
+ @param operator String of temporal operations, e.g. {equal|during,=!:}.
+
+ @return List of temporal relations (equal, during), the given function
+ (!:) and the interval/instances (=).
+
+ @code
+ >>> import grass.temporal as tgis
+ >>> tgis.init(True)
+ >>> p = tgis.TemporalVectorAlgebraParser()
+ >>> operator = "{equal,:}"
+ >>> p.eval_toperator(operator)
+ (['EQUAL'], '=', ':')
+ >>> operator = "{equal|during,:}"
+ >>> p.eval_toperator(operator)
+ (['EQUAL', 'DURING'], '=', ':')
+ >>> operator = "{equal,!:}"
+ >>> p.eval_toperator(operator)
+ (['EQUAL'], '=', '!:')
+ >>> operator = "{equal|during,!:}"
+ >>> p.eval_toperator(operator)
+ (['EQUAL', 'DURING'], '=', '!:')
+ >>> operator = "{equal|during,=!:}"
+ >>> p.eval_toperator(operator)
+ (['EQUAL', 'DURING'], '=', '!:')
+ >>> operator = "{equal|during|starts,#}"
+ >>> p.eval_toperator(operator)
+ (['EQUAL', 'DURING', 'STARTS'], '=', '#')
+ >>> operator = "{!:}"
+ >>> p.eval_toperator(operator)
+ (['EQUAL'], '=', '!:')
+ >>> operator = "{=:}"
+ >>> p.eval_toperator(operator)
+ (['EQUAL'], '=', ':')
+ >>> operator = "{#}"
+ >>> p.eval_toperator(operator)
+ (['EQUAL'], '=', '#')
+ >>> operator = "{equal|during}"
+ >>> p.eval_toperator(operator)
+ (['EQUAL', 'DURING'], None, None)
+ >>> operator = "{equal}"
+ >>> p.eval_toperator(operator)
+ (['EQUAL'], None, None)
+ >>> operator = "{equal,||}"
+ >>> p.eval_toperator(operator, True)
+ (['EQUAL'], '=', '||')
+ >>> operator = "{equal|during,&&}"
+ >>> p.eval_toperator(operator, True)
+ (['EQUAL', 'DURING'], '=', '&&')
+ >>> operator = "{&}"
+ >>> p.eval_toperator(operator)
+ (['EQUAL'], '=', '&')
+
+ @endcode
+
+ """
+
+ p = TemporalVectorOperatorParser()
+ p.parse(operator, comparison)
+ p.relations = [rel.upper() for rel in p.relations]
+
+ return(p.relations, p.temporal, p.function)
+
+ def overlay_map_extent(self, mapA, mapB, bool_op = None, temp_op = '=',
+ copy = False):
+ """!Compute the spatio-temporal extent of two topological related maps
+
+ @param mapA The first map
+ @param mapB The second maps
+ @param bool_op The boolean operator specifying the spatial extent
+ operation (intersection, union, disjoint union)
+ @param temp_op The temporal operator specifying the temporal
+ exntent operation (intersection, union, disjoint union)
+ @param copy Specifies if the temporal extent of mapB should be
+ copied to mapA
+ """
+ returncode = 1
+ if copy:
+ map_extent_temporal = mapB.get_temporal_extent()
+ map_extent_spatial = mapB.get_spatial_extent()
+ # Set initial map extend of new vector map.
+ mapA.set_spatial_extent(map_extent_spatial)
+ mapA.set_temporal_extent(map_extent_temporal)
+ if "cmd_list" in dir(mapB):
+ mapA.cmd_list = mapB.cmd_list
+ else:
+ # Calculate spatial extent for different overlay operations.
+ if bool_op == 'and':
+ overlay_ext = mapA.spatial_intersection(mapB)
+ if overlay_ext != None:
+ mapA.set_spatial_extent(overlay_ext)
+ else:
+ returncode = 0
+ elif bool_op in ['or', 'xor']:
+ overlay_ext = mapA.spatial_union(mapB)
+ if overlay_ext != None:
+ mapA.set_spatial_extent(overlay_ext)
+ else:
+ returncode = 0
+ elif bool_op == 'disor':
+ overlay_ext = mapA.spatial_disjoint_union(mapB)
+ if overlay_ext != None:
+ mapA.set_spatial_extent(overlay_ext)
+ else:
+ returncode = 0
+ # Conditional append of command list.
+ if "cmd_list" in dir(mapA) and "cmd_list" in dir(mapB):
+ mapA.cmd_list = mapA.cmd_list + mapB.cmd_list
+ elif "cmd_list" not in dir(mapA) and "cmd_list" in dir(mapB):
+ mapA.cmd_list = mapB.cmd_list
+ # Calculate temporal extent for different temporal operators.
+ if temp_op == '&':
+ temp_ext = mapA.temporal_intersection(mapB)
+ if temp_ext != None:
+ mapA.set_temporal_extent(temp_ext)
+ else:
+ returncode = 0
+ elif temp_op == '|':
+ temp_ext = mapA.temporal_union(mapB)
+ if temp_ext != None:
+ mapA.set_temporal_extent(temp_ext)
+ else:
+ returncode = 0
+ elif temp_op == '+':
+ temp_ext = mapA.temporal_disjoint_union(mapB)
+ if temp_ext != None:
+ mapA.set_temporal_extent(temp_ext)
+ else:
+ returncode = 0
+
+ return(returncode)
+
+ ###########################################################################
+
+ def p_statement_assign(self, t):
+ # The expression should always return a list of maps.
+ """
+ statement : stds EQUALS expr
+
+ """
+ # Execute the command lists
+ if self.run:
+ if isinstance(t[3], list):
+ num = len(t[3])
+ count = 0
+ returncode = 0
+ register_list = []
+ for i in range(num):
+ # Check if resultmap names exist in GRASS database.
+ vectorname = self.basename + "_" + str(i)
+ vectormap = VectorDataset(vectorname + "@" + get_current_mapset())
+ if vectormap.map_exists() and grass.overwrite() == False:
+ self.msgr.fatal(_("Error vector maps with basename %s exist. "
+ "Use --o flag to overwrite existing file") \
+ %(vectorname))
+ for map_i in t[3]:
+ if "cmd_list" in dir(map_i):
+ # Execute command list.
+ for cmd in map_i.cmd_list:
+ try:
+ # We need to check if the input maps have areas in case of v.overlay
+ # otherwise v.overlay will break
+ if cmd.name == "v.overlay":
+ for name in (cmd.inputs["ainput"].value,
+ cmd.inputs["binput"].value):
+ #self.msgr.message("Check if map <" + name + "> exists")
+ if name.find("@") < 0:
+ name = name + "@" + get_current_mapset()
+ tmp_map = map_i.get_new_instance(name)
+ if not tmp_map.map_exists():
+ raise Exception
+ #self.msgr.message("Check if map <" + name + "> has areas")
+ tmp_map.load()
+ if tmp_map.metadata.get_number_of_areas() == 0:
+ raise Exception
+ except Exception:
+ returncode = 1
+ break
+
+ # run the command
+ # print the command that will be executed
+ self.msgr.message("Run command:\n" + cmd.get_bash())
+ cmd.run()
+ if cmd.popen.returncode != 0:
+ self.msgr.fatal(_("Error starting %s : \n%s") \
+ %(cmd.get_bash(), \
+ cmd.popen.stderr))
+ mapname = cmd.outputs['output'].value
+ if mapname.find("@") >= 0:
+ map_test = map_i.get_new_instance(mapname)
+ else:
+ map_test = map_i.get_new_instance(mapname + "@" + self.mapset)
+ if not map_test.map_exists():
+ returncode = 1
+ break
+ if returncode == 0:
+ # We remove the invalid vector name from the remove list.
+ if self.names.has_key(map_i.get_name()):
+ self.names.pop(map_i.get_name())
+ mapset = map_i.get_mapset()
+ # Change map name to given basename.
+ newident = self.basename + "_" + str(count)
+ m = copy.deepcopy(m_rename)
+ m.inputs["vect"].value = (map_i.get_name(),newident)
+ m.flags["overwrite"].value = grass.overwrite()
+ m.run()
+ #m(vect = (map_i.get_name(),newident), \
+ # overwrite = grass.overwrite)
+ map_i.set_id(newident + "@" + mapset)
+ count += 1
+ register_list.append(map_i)
+ else:
+ register_list.append(map_i)
+
+ if len(register_list) > 0:
+ # Open connection to temporal database.
+ dbif, connected = init_dbif(dbif=self.dbif)
+ # Create result space time dataset.
+ resultstds = open_new_space_time_dataset(t[1], self.stdstype, \
+ 'absolute', t[1], t[1], \
+ 'mean', None, \
+ overwrite = grass.overwrite())
+ for map_i in register_list:
+ # Check if modules should be executed from command list.
+ if "cmd_list" in dir(map_i):
+ # Get meta data from grass database.
+ map_i.load()
+ if map_i.is_in_db(dbif=dbif) and grass.overwrite():
+ # Update map in temporal database.
+ map_i.update_all(dbif=dbif)
+ elif map_i.is_in_db(dbif=dbif) and grass.overwrite() == False:
+ # Raise error if map exists and no overwrite flag is given.
+ self.msgr.fatal(_("Error vector map %s exist in temporal database. "
+ "Use overwrite flag. : \n%s") \
+ %(map_i.get_map_id(), cmd.popen.stderr))
+ else:
+ # Insert map into temporal database.
+ map_i.insert(dbif=dbif)
+ else:
+ #Get metadata from temporal database.
+ map_i.select(dbif=dbif)
+ # Register map in result space time dataset.
+ resultstds.register_map(map_i, dbif=dbif)
+ #count += 1
+ #if count % 10 == 0:
+ # grass.percent(count, num, 1)
+ resultstds.update_from_registered_maps(dbif=dbif)
+ if connected:
+ dbif.close()
+ self.remove_intermediate_vector_maps()
+ t[0] = register_list
+
+ if self.debug:
+ if isinstance(t[3], list):
+ for map_i in t[3]:
+ print(map_i.get_id())
+ else:
+ print(t[1] + " = " + str(t[3]))
+ t[0] = t[3]
+
+ def p_overlay_operation(self, t):
+ """
+ expr : stds AND stds
+ | expr AND stds
+ | stds AND expr
+ | expr AND expr
+ | stds OR stds
+ | expr OR stds
+ | stds OR expr
+ | expr OR expr
+ | stds XOR stds
+ | expr XOR stds
+ | stds XOR expr
+ | expr XOR expr
+ | stds NOT stds
+ | expr NOT stds
+ | stds NOT expr
+ | expr NOT expr
+ | stds DISOR stds
+ | expr DISOR stds
+ | stds DISOR expr
+ | expr DISOR expr
+ """
+ # Check input stds.
+ maplistA = self.check_stds(t[1])
+ maplistB = self.check_stds(t[3])
+
+ if self.run:
+ t[0] = self.create_overlay_operations(maplistA, maplistB, ("EQUAL",), "=", t[2])
+ if self.debug:
+ t[0] = t[1]
+
+ def p_overlay_operation_relation(self, t):
+ """
+ expr : stds T_OVERLAY_OPERATOR stds
+ | expr T_OVERLAY_OPERATOR stds
+ | stds T_OVERLAY_OPERATOR expr
+ | expr T_OVERLAY_OPERATOR expr
+ """
+ # Check input stds.
+ maplistA = self.check_stds(t[1])
+ maplistB = self.check_stds(t[3])
+ relations, temporal, function= self.eval_toperator(t[2])
+
+ if self.run:
+ t[0] = self.create_overlay_operations(maplistA, maplistB, relations, temporal, function)
+ if self.debug:
+ t[0] = t[1]
+
+ def create_overlay_operations(self, maplistA, maplistB, relations, temporal, function):
+ """!Create the spatial overlay operation commad list
+
+ @param maplistA A list of map objects
+ @param maplistB A list of map objects
+ @param relations The temporal relationships that must be fullfilled as list of strings
+ ("EQUAL", "DURING", ...)
+ @param temporal The temporal operator as string "=" or "&", ...
+ @param function The spatial overlay operations as string "&", "|", ...
+ @return Return the list of maps with overlay commands
+ """
+ topolist = self.get_temporal_topo_list(maplistA, maplistB, topolist = relations)
+
+ # Select operation name.
+ if function == "&":
+ opname = "and"
+ elif function == "|":
+ opname = "or"
+ elif function == "^":
+ opname = "xor"
+ elif function == "~":
+ opname = "not"
+ elif function == "+":
+ opname = "disor"
+
+ if self.run:
+ resultlist = []
+ for map_i in topolist:
+ # Generate an intermediate name for the result map list.
+ name = self.generate_map_name()
+ # Get mapset input.
+ mapset = get_current_mapset()
+ # Check for mapset in given stds input.
+ mapname = name + "@" + mapset
+ # Create new map based on the related map list.
+ map_new = map_i.get_new_instance(mapname)
+ # Set initial map extend of new vector map.
+ self.overlay_map_extent(map_new, map_i, bool_op = opname, copy = True)
+ # Set first input for overlay module.
+ mapainput = map_i.get_id()
+ # Loop over temporal related maps and create overlay modules.
+ tbrelations = map_i.get_temporal_relations()
+ count = 0
+ for topo in relations:
+ if topo in tbrelations.keys():
+ for map_j in (tbrelations[topo]):
+ # Create overlayed map extent.
+ returncode = self.overlay_map_extent(map_new, map_j, opname, \
+ temp_op = temporal)
+ # Stop the loop if no temporal or spatial relationship exist.
+ if returncode == 0:
+ break
+ if count == 0:
+ # Set map name.
+ name = map_new.get_id()
+ else:
+ # Generate an intermediate name
+ name = self.generate_map_name()
+ map_new.set_id(name + "@" + mapset)
+ # Set second input for overlay module.
+ mapbinput = map_j.get_id()
+ # Create module command in PyGRASS for v.overlay and v.patch.
+ if opname != "disor":
+ m = copy.deepcopy(m_overlay)
+ m.run_ = False
+ m.inputs["operator"].value = opname
+ m.inputs["ainput"].value = str(mapainput)
+ m.inputs["binput"].value = str(mapbinput)
+ m.outputs["output"].value = name
+ m.flags["overwrite"].value = grass.overwrite()
+ else:
+ patchinput = str(mapainput) + ',' + str(mapbinput)
+ m = copy.deepcopy(m_patch)
+ m.run_ = False
+ m.inputs["input"].value = patchinput
+ m.outputs["output"].value = name
+ m.flags["overwrite"].value = grass.overwrite()
+ # Conditional append of module command.
+ if "cmd_list" in dir(map_new):
+ map_new.cmd_list.append(m)
+ else:
+ map_new.cmd_list = [m]
+ # Set new map name to temporary map name.
+ mapainput = name
+ count += 1
+ if returncode == 0:
+ break
+ # Append map to result map list.
+ if returncode == 1:
+ resultlist.append(map_new)
+
+ return resultlist
+
+ def p_buffer_operation(self,t):
+ """
+ expr : buff_function LPAREN stds COMMA number RPAREN
+ | buff_function LPAREN expr COMMA number RPAREN
+ """
+
+ if self.run:
+ # Check input stds.
+ bufflist = self.check_stds(t[3])
+ # Create empty result list.
+ resultlist = []
+
+ for map_i in bufflist:
+ # Generate an intermediate name
+ name = self.generate_map_name()
+ # Get mapset input.
+ mapset = get_current_mapset()
+ # Check for mapset in given stds input.
+ mapname = name + "@" + mapset
+ # Create new map based on the related map list.
+ map_new = map_i.get_new_instance(mapname)
+ # Set initial map extend of new vector map.
+ self.overlay_map_extent(map_new, map_i, copy = True)
+ # Change spatial extent based on buffer size.
+ map_new.spatial_buffer(float(t[5]))
+ # Check buff type.
+ if t[1] == "buff_p":
+ buff_type = "point"
+ elif t[1] == "buff_l":
+ buff_type = "line"
+ elif t[1] == "buff_a":
+ buff_type = "area"
+ m = copy.deepcopy(m_buffer)
+ m.run_ = False
+ m.inputs["type"].value = buff_type
+ m.inputs["input"].value = str(map_i.get_id())
+ m.inputs["distance"].value = float(t[5])
+ m.outputs["output"].value = name
+ m.flags["overwrite"].value = grass.overwrite()
+
+ # Conditional append of module command.
+ if "cmd_list" in dir(map_new):
+ map_new.cmd_list.append(m)
+ else:
+ map_new.cmd_list = [m]
+ resultlist.append(map_new)
+
+ t[0] = resultlist
+
+ if self.debug:
+ pass
+
+ def p_buff_function(self, t):
+ """buff_function : BUFF_POINT
+ | BUFF_LINE
+ | BUFF_AREA
+ """
+ t[0] = t[1]
+
+ # Handle errors.
+ def p_error(self, t):
+ raise SyntaxError("syntax error on line %d near '%s' expression '%s'" %
+ (t.lineno, t.value, self.expression))
+
+###############################################################################
+
+if __name__ == "__main__":
+ import doctest
+ doctest.testmod()
+
+
Added: grass/trunk/lib/python/temporal/temporal_vector_operator.py
===================================================================
--- grass/trunk/lib/python/temporal/temporal_vector_operator.py (rev 0)
+++ grass/trunk/lib/python/temporal/temporal_vector_operator.py 2014-01-30 17:00:32 UTC (rev 58807)
@@ -0,0 +1,349 @@
+"""!@package grass.temporal
+
+Temporal vector operator evaluation with PLY
+
+(C) 2014 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 authors Thomas Leppelt and Soeren Gebbert
+
+ at code
+ >>> import grass.temporal as tgis
+ >>> tgis.init(True)
+ >>> p = tgis.TemporalVectorOperatorParser()
+ >>> expression = "{equal| during,&&}"
+ >>> p.parse(expression, True)
+ >>> print(p.relations, p.temporal, p.function)
+ (['equal', 'during'], '=', '&&')
+ >>> expression = "{equal| during | follows,&&}"
+ >>> p.parse(expression)
+ >>> print(p.relations, p.temporal, p.function)
+ (['equal', 'during', 'follows'], '&', '&')
+ >>> expression = "{equal| during | follows,+!:}"
+ >>> p.parse(expression)
+ >>> print(p.relations, p.temporal, p.function)
+ (['equal', 'during', 'follows'], '+', '!:')
+ >>> expression = "{equal| during,!:}"
+ >>> p.parse(expression)
+ >>> print(p.relations, p.temporal, p.function)
+ (['equal', 'during'], '=', '!:')
+ >>> expression = "{!:}"
+ >>> p.parse(expression)
+ >>> print(p.relations, p.temporal, p.function)
+ (['equal'], '=', '!:')
+ >>> expression = "{&&}"
+ >>> p.parse(expression, True)
+ >>> print(p.relations, p.temporal, p.function)
+ (['equal'], '=', '&&')
+ >>> expression = "{&&}"
+ >>> p.parse(expression)
+ >>> print(p.relations, p.temporal, p.function)
+ (['equal'], '&', '&')
+ >>> expression = "{|#}"
+ >>> p.parse(expression)
+ >>> print(p.relations, p.temporal, p.function)
+ (['equal'], '|', '#')
+ >>> expression = "{equal,||}"
+ >>> p.parse(expression)
+ >>> print(p.relations, p.temporal, p.function)
+ (['equal'], '|', '|')
+ >>> expression = "{equal|during,=!:}"
+ >>> p.parse(expression)
+ >>> print(p.relations, p.temporal, p.function)
+ (['equal', 'during'], '=', '!:')
+ >>> expression = "{equal|during|starts}"
+ >>> p.parse(expression)
+ >>> print(p.relations, p.temporal, p.function)
+ (['equal', 'during', 'starts'], None, None)
+ >>> expression = "{over| equal,||}"
+ >>> p.parse(expression)
+ >>> print(p.relations, p.temporal, p.function)
+ ([['overlaps', 'overlapped'], 'equal'], '|', '|')
+
+ at endcode
+"""
+try:
+ import ply.lex as lex
+ import ply.yacc as yacc
+except:
+ pass
+
+class TemporalVectorOperatorLexer(object):
+ """!Lexical analyzer for the GRASS GIS temporal vector operators"""
+
+ # Functions that defines topological relations.
+ relations = {
+ 'equal' : "EQUAL",
+ 'follows' : "FOLLOWS",
+ 'precedes' : "PRECEDES",
+ 'overlaps' : "OVERLAPS",
+ 'overlapped' : "OVERLAPPED",
+ 'during' : "DURING",
+ 'starts' : "STARTS",
+ 'finishes' : "FINISHES",
+ 'contains' : "CONTAINS",
+ 'started' : "STARTED",
+ 'finished' : "FINISHED",
+ 'over' : "OVER"
+ }
+
+ # This is the list of token names.
+ tokens = (
+ 'COMMA',
+ 'LEFTREF',
+ 'HASH',
+ 'OR',
+ 'AND',
+ 'DISOR',
+ 'XOR',
+ 'NOT',
+ 'T_SELECT',
+ 'T_NOT_SELECT',
+ 'CLPAREN',
+ 'CRPAREN',
+ )
+
+ # Build the token list
+ tokens = tokens + tuple(relations.values())
+
+ # Regular expression rules for simple tokens
+ t_T_SELECT = r':'
+ t_T_NOT_SELECT = r'!:'
+ t_COMMA = r','
+ t_LEFTREF = r'='
+ t_HASH = r'\#'
+ t_OR = r'[\|]'
+ t_AND = r'[&]'
+ t_DISOR = r'\+'
+ t_XOR = r'\^'
+ t_NOT = r'\~'
+ t_CLPAREN = r'\{'
+ t_CRPAREN = r'\}'
+
+ # These are the things that should be ignored.
+ t_ignore = ' \t'
+
+ # Track line numbers.
+ def t_newline(self, t):
+ r'\n+'
+ t.lineno += len(t.value)
+
+ def t_NAME(self, t):
+ r'[a-zA-Z_][a-zA-Z_0-9]*'
+ self.temporal_symbol(t)
+ return t
+
+ # Parse symbols
+ def temporal_symbol(self, t):
+ # Check for reserved words
+ if t.value in TemporalVectorOperatorLexer.relations.keys():
+ t.type = TemporalVectorOperatorLexer.relations.get(t.value)
+ #else:
+ # t.type = 'NAME'
+ return(t)
+
+ # Handle errors.
+ def t_error(self, t):
+ raise SyntaxError("syntax error on line %d near '%s'" %
+ (t.lineno, t.value))
+
+ # Build the lexer
+ def build(self,**kwargs):
+ self.lexer = lex.lex(module=self, **kwargs)
+
+ # Just for testing
+ def test(self,data):
+ self.name_list = {}
+ print(data)
+ self.lexer.input(data)
+ while True:
+ tok = self.lexer.token()
+ if not tok: break
+ print tok
+
+class TemporalVectorOperatorParser(object):
+ """!The parser for the GRASS GIS temporal vector operators"""
+
+ def __init__(self):
+ self.lexer = TemporalVectorOperatorLexer()
+ self.lexer.build()
+ self.parser = yacc.yacc(module=self)
+
+ def parse(self, expression, comparison = False):
+ self.comparison = comparison
+ self.parser.parse(expression)
+
+ # Error rule for syntax errors.
+ def p_error(self, t):
+ raise SyntaxError("invalid syntax")
+
+ # Get the tokens from the lexer class
+ tokens = TemporalVectorOperatorLexer.tokens
+
+ def p_relation_only(self, t):
+ # The expression should always return a list of maps.
+ """
+ operator : CLPAREN relation CRPAREN
+ | CLPAREN relationlist CRPAREN
+ """
+ # Set three operator components.
+ if isinstance(t[2], list):
+ self.relations = t[2]
+ else:
+ self.relations = [t[2]]
+ self.temporal = None
+ self.function = None
+
+ t[0] = t[2]
+
+
+ def p_operator(self, t):
+ # The expression should always return a list of maps.
+ """
+ operator : CLPAREN select CRPAREN
+ | CLPAREN HASH CRPAREN
+ | CLPAREN overlay CRPAREN
+ """
+ # Set three operator components.
+ self.relations = ['equal']
+ self.temporal = "="
+ self.function = t[2]
+
+ t[0] = t[2]
+
+ def p_operator_temporal(self, t):
+ # The expression should always return a list of maps.
+ """
+ operator : CLPAREN temporal select CRPAREN
+ | CLPAREN temporal HASH CRPAREN
+ | CLPAREN temporal overlay CRPAREN
+ """
+ # Set three operator components.
+ self.relations = ['equal']
+ if self.comparison:
+ self.temporal = "="
+ self.function = t[2] + t[3]
+ else:
+ self.temporal = t[2]
+ self.function = t[3]
+
+ t[0] = t[3]
+
+ def p_operator_relation(self, t):
+ # The expression should always return a list of maps.
+ """
+ operator : CLPAREN relation COMMA select CRPAREN
+ | CLPAREN relationlist COMMA select CRPAREN
+ | CLPAREN relation COMMA HASH CRPAREN
+ | CLPAREN relationlist COMMA HASH CRPAREN
+ | CLPAREN relation COMMA overlay CRPAREN
+ | CLPAREN relationlist COMMA overlay CRPAREN
+ """
+ # Set three operator components.
+ if isinstance(t[2], list):
+ self.relations = t[2]
+ else:
+ self.relations = [t[2]]
+ self.temporal = "="
+ self.function = t[4]
+
+ t[0] = t[4]
+
+ def p_operator_relation_temporal(self, t):
+ # The expression should always return a list of maps.
+ """
+ operator : CLPAREN relation COMMA temporal select CRPAREN
+ | CLPAREN relationlist COMMA temporal select CRPAREN
+ | CLPAREN relation COMMA temporal HASH CRPAREN
+ | CLPAREN relationlist COMMA temporal HASH CRPAREN
+ | CLPAREN relation COMMA temporal overlay CRPAREN
+ | CLPAREN relationlist COMMA temporal overlay CRPAREN
+ """
+ # Set three operator components.
+ if isinstance(t[2], list):
+ self.relations = t[2]
+ else:
+ self.relations = [t[2]]
+ if self.comparison:
+ self.temporal = "="
+ self.function = t[4] + t[5]
+ else:
+ self.temporal = t[4]
+ self.function = t[5]
+ t[0] = t[5]
+
+ def p_relation(self, t):
+ # The list of relations.
+ """
+ relation : EQUAL
+ | FOLLOWS
+ | PRECEDES
+ | OVERLAPS
+ | OVERLAPPED
+ | DURING
+ | STARTS
+ | FINISHES
+ | CONTAINS
+ | STARTED
+ | FINISHED
+ """
+ t[0] = t[1]
+
+ def p_over(self, t):
+ # The list of relations.
+ """
+ relation : OVER
+ """
+ over_list = ["overlaps", "overlapped"]
+ t[0] = over_list
+
+ def p_relationlist(self, t):
+ # The list of relations.
+ """
+ relationlist : relation OR relation
+ | relation OR relationlist
+ """
+ rel_list = []
+ rel_list.append(t[1])
+ if isinstance(t[3], list):
+ rel_list = rel_list + t[3]
+ else:
+ rel_list.append(t[3])
+ t[0] = rel_list
+
+ def p_temporal_operator(self, t):
+ # The list of relations.
+ """
+ temporal : LEFTREF
+ | OR
+ | AND
+ | DISOR
+ """
+ t[0] = t[1]
+
+ def p_select_operator(self, t):
+ # The list of relations.
+ """
+ select : T_SELECT
+ | T_NOT_SELECT
+ """
+ t[0] = t[1]
+
+ def p_overlay_operator(self, t):
+ # The list of relations.
+ """
+ overlay : OR
+ | AND
+ | DISOR
+ | XOR
+ | NOT
+ """
+ t[0] = t[1]
+###############################################################################
+
+if __name__ == "__main__":
+ import doctest
+ doctest.testmod()
+
\ No newline at end of file
Added: grass/trunk/temporal/t.vect.mapcalc/Makefile
===================================================================
--- grass/trunk/temporal/t.vect.mapcalc/Makefile (rev 0)
+++ grass/trunk/temporal/t.vect.mapcalc/Makefile 2014-01-30 17:00:32 UTC (rev 58807)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../../
+
+PGM = t.vect.mapcalc
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script
Added: grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.html
===================================================================
--- grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.html (rev 0)
+++ grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.html 2014-01-30 17:00:32 UTC (rev 58807)
@@ -0,0 +1,340 @@
+<h2>DESCRIPTION</h2>
+
+t.vect.mapcalc performs temporal and spatial overlay and buffer functions on space time vector datasets (STVDS)
+by using the temporal vector algebra. New STVDS can be created, which are expressions of existing STVDS.
+
+<h3>PROGRAM USE</h3>
+The module expects an <b>expression</b> as input parameter in the following form: <br>
+<br>
+<b> "result = expression" </b>
+<br>
+<br>
+
+The statement structure is similar to r.mapcalc, see <a href="r.mapcalc.html">r.mapcalc</a>.
+Where <b>result</b> represents the name of a space time vector dataset (STVDS)that will
+contain the result of the calculation that is given as <b>expression</b>
+on the right side of the equality sign.
+These expression can be any valid or nested combination of temporal
+operations and spatial overlay or buffer functions that are provided by the temporal algebra. <br>
+The temporal vector algebra works with space time vector datasets only (STVDS).
+The algebra provides methods for map selection from STVDS based on their temporal relations.
+It is also possible to temporally shift maps, to create temporal buffer and to snap time
+instances to create a valid temporal topology. Furthermore expressions can be nested and
+evaluated in conditional statements (if, else statements). Within if-statements the algebra
+provides temporal variables like start time, end time, day of year, time differences or
+number of maps per time interval to build up conditions. In addition the algebra provides
+the spatial operations for vector overlay and buffering. All these operations can be assigned
+to STVDS or to the resulting map lists of operations between STVDS.
+<br>
+<br>
+As default, topological relationships between space time datasets will be
+evaluated only temporal. Use the <b>s</b> flag to activate the
+additionally evaluate the spatial topology based on the spatial extents of maps.
+<br>
+<br>
+The expression option must be passed as <b>quoted</b>
+expression, for example: <br>
+<div class="code"><pre>t.vect.mapcalc expression="C = A & B" basename=result</pre></div>
+Where <b>C</b> is the new space time vector dataset that will contain maps
+with the basename "result" that represent the intersection of maps from STVDS <b>A</b> and
+equally temporal related maps from STVDS <b>B</b>.
+<br>
+<br>
+The map basename for the result STVDS must always be specified.
+
+<h2>Temporal vector algebra</h2>
+
+The temporal vector algebra provides a wide range of temporal and spatial operators and
+functions that will be presented in the following section. <br>
+<br>
+
+<h3>Temporal relations</h3>
+
+Several temporal topology relations between space
+time datasets are supported: <br>
+<div class="code"><pre>
+equals A ------
+ B ------
+
+during A ----
+ B ------
+
+contains A ------
+ B ----
+
+starts A ----
+ B ------
+
+started A ------
+ B ----
+
+finishs A ----
+ B ------
+
+finished A ------
+ B ----
+
+precedes A ----
+ B ----
+
+follows A ----
+ B ----
+
+overlapped A ------
+ B ------
+
+overlaps A ------
+ B ------
+
+over booth overlaps and overlapped
+
+</pre></div>
+The relations must be read as: A is related to B, like - A equals B - A is
+during B - A contains B <br>
+<br>
+Topological relations must be specified in {} parentheses. <br>
+
+<h3>Temporal Selection</h3>
+
+The temporal selection simply selects parts of a space time dataset without
+processing raster or vector data.
+
+The algebra provides a selection operator <b>:</b> that selects parts
+of a space time dataset that are temporally equal to parts of a second one
+by default. The following expression
+<div class="code"><pre>
+C = A : B
+</pre></div>
+means: Select all parts of space time dataset A that are equal to B and store
+it in space time dataset C. The parts are time stamped maps. <br>
+<br>
+In addition the inverse selection operator <b>!:</b> is defined as the complement of
+the selection operator, hence the following expression
+<div class="code"><pre>
+C = A !: B
+</pre></div>
+means: select all parts of space time time dataset A that are not equal to B
+and store it in space time dataset (STDS) C. <br>
+<br>
+To select parts of a STDS by different topological relations to other STDS,
+the temporal topology selection operator can be used. The operator consists of
+topological relations, that must be separated by the logical OR operator
+<b>|</b> and the temporal selection operator. Both parts are separated by
+comma and surrounded by curly braces:
+{"topological relations", "temporal selection operator"} <br>
+<br>
+Examples:
+<div class="code"><pre>
+C = A {equals,:} B
+C = A {equals,!:} B
+</pre></div>
+We can now define arbitrary topological relations using logical OR operator
+to connect them:
+<div class="code"><pre>
+C = A {equals|during|overlaps,:} B
+</pre></div>
+Select all parts of A that are equal to B, during B or overlaps B. <br>
+<br>
+The selection operator is implicitly contained in the temporal topology
+selection operator, so that the following statements are exactly the same:
+<div class="code"><pre>
+C = A : B
+C = A {:} B
+C = A {equal,:} B
+</pre></div>
+
+Same for the complementary selection:
+<div class="code"><pre>
+C = A !: B
+C = A {!:} B
+C = A {equal,!:} B
+</pre></div>
+
+<h3>Conditional statements</h3>
+
+Selection operations can be evaluated within conditional statements.
+<br>
+<div class="code"><pre>
+Note A and B can either be space time datasets or expressions.
+
+if statement decision option temporal relations
+ if(if, then, else)
+ if(conditions, A) A if conditions are True; temporal topological relation between if and then is equal.
+ if(conditions, A, B) A if conditions are True, B otherwise; temporal topological relation between if, then and else is equal.
+ if(topologies, conditions, A) A if conditions are True; temporal topological relation between if and then is explicit specified by topologies.
+ if(topologies, conditions, A, B) A if conditions are True, B otherwise; temporal topological relation between if, then and else is explicit specified by topologies.
+</pre></div>
+The conditions are comparison expressions that are used to evaluate
+space time datasets. Specific values of temporal variables are
+compared by logical operators and evaluated for each map of the STDS.
+<br>
+<br>
+The supported logical operators:
+<div class="code"><pre>
+Symbol description
+
+ == equal
+ != not equal
+ > greater than
+ >= greater than or equal
+ < less than
+ <= less than or equal
+ && and
+ || or
+</pre></div>
+
+Temporal functions: <br>
+<div class="code"><pre>
+
+td(A) Returns a list of time intervals of STDS A
+
+start_time() Start time as HH::MM:SS
+start_date() Start date as yyyy-mm-DD
+start_datetime() Start datetime as yyyy-mm-DD HH:MM:SS
+end_time() End time as HH:MM:SS
+end_date() End date as yyyy-mm-DD
+end_datetime() End datetime as yyyy-mm-DD HH:MM
+
+start_doy() Day of year (doy) from the start time [1 - 366]
+start_dow() Day of week (dow) from the start time [1 - 7], the start of the week is Monday == 1
+start_year() The year of the start time [0 - 9999]
+start_month() The month of the start time [1 - 12]
+start_week() Week of year of the start time [1 - 54]
+start_day() Day of month from the start time [1 - 31]
+start_hour() The hour of the start time [0 - 23]
+start_minute() The minute of the start time [0 - 59]
+start_second() The second of the start time [0 - 59]
+end_doy() Day of year (doy) from the end time [1 - 366]
+end_dow() Day of week (dow) from the end time [1 - 7], the start of the week is Monday == 1
+end_year() The year of the end time [0 - 9999]
+end_month() The month of the end time [1 - 12]
+end_week() Week of year of the end time [1 - 54]
+end_day() Day of month from the start time [1 - 31]
+end_hour() The hour of the end time [0 - 23]
+end_minute() The minute of the end time [0 - 59]
+end_second() The second of the end time [0 - 59]
+</pre></div>
+
+Additionally the number of maps in intervals can be computed and
+used in conditional statements. <br>
+The operator to count the number of maps
+is the hash <b>#</b>.
+<div class="code"><pre>
+A{contains,#}B
+</pre></div>
+This expression computes the number of maps from space
+time dataset B which are during the time intervals of maps from
+space time dataset A.<br>
+A list of integers (scalars) corresponding to the maps of A
+that contain maps from B will be returned. <br>
+<br>
+
+Furthermore the temporal algebra allows temporal buffering, shifting
+and snapping with the functions buff_t(), tshift() and tsnap()
+respectively.
+<div class="code"><pre>
+buff_t(A, size) Buffer STDS A with granule ("1 month" or 5)
+tshift(A, size) Shift STDS A with granule ("1 month" or 5)
+tsnap(A) Snap time instances and intervals of STDS A
+</pre></div>
+
+<h3>Temporal Operators</h3>
+<p>
+The temporal algebra defines temporal operators that can be combined
+later with spatial operators to perform spatio-temporal operations.
+The temporal operators process the time instances and intervals of temporal related maps.
+</p>
+<div class="code"><pre>
+AND & Intersection
+OR | Union
+DISJOINT OR + Disjoint union
+LEFT REFERENCE = Use the time stamp of the left space time dataset
+</pre></div><p>
+For example we can compute the intersection, union or disjoint union from time stamps of maps
+that temporally overlap, or we can just keep the time stamp of the left STDS.
+</p>
+
+<h3>Spatial vector operators</h3>
+
+The module supports the following boolean vector operations: <br>
+<div class="code"><pre>
+ Boolean Name Operator Meaning Precedence Correspondent function
+----------------------------------------------------------------------------------
+ AND & Intersection 1 (v.overlay operator=and)
+ OR | Union 1 (v.overlay operator=or)
+ DISJOINT OR + Disjoint union 1 (v.patch)
+ XOR ^ Symmetric difference 1 (v.overlay operator=xor)
+ NOT ~ Complement 1 (v.overlay operator=not)
+
+</pre></div>
+
+And vector functions:
+<div class="code"><pre>
+ buff_p(A, size) Buffer the points of vector map layer A with size
+ buff_l(A, size) Buffer the lines of vector map layer A with size
+ buff_a(A, size) Buffer the areas of vector map layer A with size
+</pre></div>
+<br>
+
+<p>
+<h3>Combinations of temporal, vector and select operators</h3>
+
+We combine the temporal topology relations, the temporal operators and the spatial/select operators to create spatio-temporal operators:
+
+<pre class="code">
+{"list of temporal relations", "temporal operator" "spatial or select operator"}
+</pre><p>
+The spatial and the select operators can be used stand-alone. In this case the temporal topology relation "equal" and the temporal operator "left reference =" is assumed and used as default. This allows the convenient use of the spatial and select
+operators in case of space time vector datasets with equal time stamps.
+</p>
+<div class="code"> <pre>
+ ---------------------------------------
+| | & | | | ^ | ~ | + | : | !: |
+|---|----|----|----|----|----|----|-----|
+| & | && | &| | &^ | &~ | &+ | &: | &!: |
+| | | |& | || | |^ | |~ | |+ | |: | |!: |
+| + | +& | +| | +^ | +~ | ++ | +: | +!: |
+| = | =& | =| | =^ | =~ | =+ | =: | =!: |
+ ---------------------------------------
+</pre></div>
+
+<h3>Examples: </h3>
+
+Spatio-temporal intersect all maps from space time dataset A with all maps from space time dataset
+B which have equal time stamps and are temporary before Jan. 1. 2005 and
+store them in space time dataset D.
+<div class="code"><pre>
+D = if(start_date() < "2005-01-01", A & B)
+</pre></div>
+
+Buffer all vector points from space time vector dataset A and B with a distance of one and
+intersect the results with overlapping, containing, during and equal temporal relations
+to store the result in space time vector dataset D with intersected time stamps.
+<div class="code"><pre>
+D = buff_p(A, 1) {overlaps|overlapped|equal|during|contains,&&} buff_p(B, 1)
+</pre></div>
+
+Select all maps from space time dataset B which are during the temporal
+buffered space time dataset A with a map interval of three days, else
+select maps from C and store them in space time dataset D.
+<div class="code"><pre>
+D = if(contain, td(buff_t(A, "1 days")) == 3, B, C)
+</pre></div>
+
+<h2>REFERENCES</h2>
+
+<tt><a href="http://www.dabeaz.com/ply/">PLY(Python-Lex-Yacc)</a></tt>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="t.select.html">t.select</a>
+</em>
+
+
+<h2>AUTHOR</h2>
+
+Thomas Leppelt, Soeren Gebbert, Thuenen Institut, Germany <br>
+
+<p><i>Last changed: $Date: 2013-07-24 17:35:20 +0100 (Thu, 24 Jul 2013) $</i>
+
Added: grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.py
===================================================================
--- grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.py (rev 0)
+++ grass/trunk/temporal/t.vect.mapcalc/t.vect.mapcalc.py 2014-01-30 17:00:32 UTC (rev 58807)
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+############################################################################
+#
+# MODULE: t.vect.mapcalc
+# AUTHOR(S): Thomas Leppelt, Soeren Gebbert
+#
+# PURPOSE: Provide temporal vector algebra to perform spatial an temporal operations
+# for space time datasets by topological relationships to other space time
+# datasets.
+# COPYRIGHT: (C) 2014 by the GRASS Development Team
+#
+# This program is free software under the GNU General Public
+# License (version 2). Read the file COPYING that comes with GRASS
+# for details.
+#
+#############################################################################
+
+#%module
+#% description: Apply temporal and spatial oeprations on space time vector datasets using temporal vector algebra.
+#% keywords: temporal
+#% keywords: mapalgebra
+#%end
+
+#%option
+#% key: expression
+#% type: string
+#% description: The mapcalc expression for temporal and spatial analysis of space time vector datasets.
+#% key_desc: expression
+#% required : yes
+#%end
+
+#%option
+#% key: basename
+#% type: string
+#% description: The basename of vector maps that are stored within the result space time vector dataset.
+#% key_desc: basename
+#% required : yes
+#%end
+
+#%flag
+#% key: s
+#% description: Activate spatial topology.
+#%end
+
+import grass.script as grass
+import grass.temporal as tgis
+import sys
+
+def main():
+ expression = options['expression']
+ basename = options['basename']
+ spatial = flags["s"]
+ stdstype = "stvds"
+
+ # Check for PLY istallation
+ try:
+ import ply.lex as lex
+ import ply.yacc as yacc
+ except:
+ grass.fatal(_("Please install PLY (Lex and Yacc Python implementation) to use the temporal algebra modules."))
+
+ tgis.init(True)
+ p = tgis.TemporalVectorAlgebraParser(run = True, debug=False, spatial = spatial)
+ p.parse(expression, stdstype, basename)
+
+if __name__ == "__main__":
+ options, flags = grass.parser()
+ sys.exit(main())
+
Added: grass/trunk/temporal/t.vect.mapcalc/test_suite/test.t.vect.mapcalc.sh
===================================================================
--- grass/trunk/temporal/t.vect.mapcalc/test_suite/test.t.vect.mapcalc.sh (rev 0)
+++ grass/trunk/temporal/t.vect.mapcalc/test_suite/test.t.vect.mapcalc.sh 2014-01-30 17:00:32 UTC (rev 58807)
@@ -0,0 +1,77 @@
+#!/usr/bin/sh
+
+g.region s=0 n=80 w=0 e=120 b=0 t=50 res=10 -p
+
+export GRASS_OVERWRITE=1
+
+# Test for temporal algebra in LatLon location.
+rm /tmp/vinput1_point_test.txt
+rm /tmp/vinput2_point_test.txt
+rm /tmp/vinput3_point_test.txt
+rm /tmp/vinput4_point_test.txt
+rm /tmp/vinput1_area_test.txt
+rm /tmp/vinput2_area_test.txt
+rm /tmp/vinput3_area_test.txt
+rm /tmp/vinput4_area_test.txt
+
+# Create random area test maps.
+for i in {1..60}
+ do
+ if [[ "$i" -le 20 ]]; then
+ echo vtestpoint1_$i >> /tmp/vinput1_point_test.txt
+ echo vtestarea1_$i >> /tmp/vinput1_area_test.txt
+ v.random --o -z output=vtestpoint1_$i n=3 seed=$i+1
+ v.voronoi --o input=vtestpoint1_$i output=vtestarea1_$i
+ elif [ "$i" -gt 20 ] && [ "$i" -le 40 ]; then
+ echo vtestpoint2_$i >> /tmp/vinput2_point_test.txt
+ echo vtestarea2_$i >> /tmp/vinput2_area_test.txt
+ v.random --o -z output=vtestpoint2_$i n=3 seed=$i+1
+ v.voronoi --o input=vtestpoint2_$i output=vtestarea2_$i
+ else
+ echo vtestpoint3_$i >> /tmp/vinput3_point_test.txt
+ echo vtestpoint4_$i >> /tmp/vinput4_point_test.txt
+ echo vtestarea3_$i >> /tmp/vinput3_area_test.txt
+ echo vtestarea4_$i >> /tmp/vinput4_area_test.txt
+ v.random --o -z output=vtestpoint3_$i n=3 seed=$i+1
+ v.voronoi --o input=vtestpoint3_$i output=vtestarea3_$i
+ v.random --o -z output=vtestpoint4_$i n=3 seed=$i+1
+ v.voronoi --o input=vtestpoint4_$i output=vtestarea4_$i
+ fi
+ done
+
+# Create STVDS and register test maps.
+t.create output=A1 type=stvds title="Area test dataset" descr="Area test dataset"
+t.create output=A2 type=stvds title="Area test dataset" descr="Area test dataset"
+t.create output=A3 type=stvds title="Area test dataset" descr="Area test dataset"
+t.create output=A4 type=stvds title="Area test dataset" descr="Area test dataset"
+t.create output=P1 type=stvds title="Point test dataset" descr="Point test dataset"
+t.create output=P2 type=stvds title="Point test dataset" descr="Point test dataset"
+t.create output=P3 type=stvds title="Point test dataset" descr="Point test dataset"
+t.create output=P4 type=stvds title="Point test dataset" descr="Point test dataset"
+
+t.register -i type=vect input=A1 file=/tmp/vinput1_area_test.txt increment="1 days" start="2013-01-01"
+t.register -i type=vect input=A2 file=/tmp/vinput2_area_test.txt increment="1 days" start="2013-01-10"
+t.register -i type=vect input=A3 file=/tmp/vinput3_area_test.txt increment="3 days" start="2013-01-01"
+t.register -i type=vect input=A4 file=/tmp/vinput4_area_test.txt increment="3 days" start="2013-01-10"
+t.register -i type=vect input=P1 file=/tmp/vinput1_point_test.txt increment="1 days" start="2013-01-01"
+t.register -i type=vect input=P2 file=/tmp/vinput2_point_test.txt increment="1 days" start="2013-01-10"
+t.register -i type=vect input=P3 file=/tmp/vinput3_point_test.txt increment="3 days" start="2013-01-01"
+t.register -i type=vect input=P4 file=/tmp/vinput4_point_test.txt increment="3 days" start="2013-01-10"
+
+# Test different options.
+t.vect.mapcalc expression='B1 = A1 & A2' basename="bmap1"
+t.vect.list input=B1 column=name,start_time,end_time
+t.vect.mapcalc expression='B2 = A1 {equal|during,+&} A3' basename="bmap2"
+t.vect.list input=B2 column=name,start_time,end_time
+t.vect.mapcalc expression='B3 = buff_p(P1,10)' basename="bmap3"
+t.vect.list input=B3 column=name,start_time,end_time
+t.vect.mapcalc expression='B4 = buff_p(P2,30) {equal|during,|^} A4' basename="bmap4"
+t.vect.list input=B4 column=name,start_time,end_time
+t.vect.mapcalc expression='B5 = if(td(A1) == 1 || start_date() >= "2010-01-10", A2)' basename="bmap5"
+t.vect.list input=B5 column=name,start_time,end_time
+t.vect.mapcalc expression='B6 = buff_p(P2,30) {equal|during|started,&^} buff_p(P3,30)' basename="bmap6"
+t.vect.list input=B6 column=name,start_time,end_time
+t.vect.mapcalc expression='B7 = buff_p(P2,30) {starts,&^} buff_p(P3,30)' basename="bmap7"
+t.vect.list input=B8 column=name,start_time,end_time
+t.vect.mapcalc expression='B8 = buff_p(P2,30) {starts,|^} buff_p(P3,30)' basename="bmap8"
+t.vect.list input=B8 column=name,start_time,end_time
More information about the grass-commit
mailing list