temporal_algebra.py 92 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378
  1. """!@package grass.temporal
  2. Temporal algebra parser class
  3. (C) 2014 by the GRASS Development Team
  4. This program is free software under the GNU General Public
  5. License (>=v2). Read the file COPYING that comes with GRASS
  6. for details.
  7. @authors Thomas Leppelt and Soeren Gebbert
  8. @code
  9. >>> import grass.temporal as tgis
  10. >>> tgis.init(True)
  11. >>> p = tgis.TemporalAlgebraLexer()
  12. >>> p.build()
  13. >>> p.debug = True
  14. >>> expression = "C = A : B"
  15. >>> p.test(expression)
  16. C = A : B
  17. LexToken(NAME,'C',1,0)
  18. LexToken(EQUALS,'=',1,2)
  19. LexToken(NAME,'A',1,4)
  20. LexToken(T_SELECT,':',1,6)
  21. LexToken(NAME,'B',1,8)
  22. >>> expression = "C = test1 !: test2"
  23. >>> p.test(expression)
  24. C = test1 !: test2
  25. LexToken(NAME,'C',1,0)
  26. LexToken(EQUALS,'=',1,2)
  27. LexToken(NAME,'test1',1,4)
  28. LexToken(T_NOT_SELECT,'!:',1,10)
  29. LexToken(NAME,'test2',1,13)
  30. >>> expression = "C = test1 {equal,:} test2"
  31. >>> p.test(expression)
  32. C = test1 {equal,:} test2
  33. LexToken(NAME,'C',1,0)
  34. LexToken(EQUALS,'=',1,2)
  35. LexToken(NAME,'test1',1,4)
  36. LexToken(T_SELECT_OPERATOR,'{equal,:}',1,10)
  37. LexToken(NAME,'test2',1,20)
  38. >>> expression = "C = test1 {equal,!:} test2"
  39. >>> p.test(expression)
  40. C = test1 {equal,!:} test2
  41. LexToken(NAME,'C',1,0)
  42. LexToken(EQUALS,'=',1,2)
  43. LexToken(NAME,'test1',1,4)
  44. LexToken(T_SELECT_OPERATOR,'{equal,!:}',1,10)
  45. LexToken(NAME,'test2',1,21)
  46. >>> expression = "C = test1 # test2"
  47. >>> p.test(expression)
  48. C = test1 # test2
  49. LexToken(NAME,'C',1,0)
  50. LexToken(EQUALS,'=',1,2)
  51. LexToken(NAME,'test1',1,4)
  52. LexToken(HASH,'#',1,10)
  53. LexToken(NAME,'test2',1,12)
  54. >>> expression = "C = test1 {#} test2"
  55. >>> p.test(expression)
  56. C = test1 {#} test2
  57. LexToken(NAME,'C',1,0)
  58. LexToken(EQUALS,'=',1,2)
  59. LexToken(NAME,'test1',1,4)
  60. LexToken(T_HASH_OPERATOR,'{#}',1,10)
  61. LexToken(NAME,'test2',1,14)
  62. >>> expression = "C = test1 {equal,#} test2"
  63. >>> p.test(expression)
  64. C = test1 {equal,#} test2
  65. LexToken(NAME,'C',1,0)
  66. LexToken(EQUALS,'=',1,2)
  67. LexToken(NAME,'test1',1,4)
  68. LexToken(T_HASH_OPERATOR,'{equal,#}',1,10)
  69. LexToken(NAME,'test2',1,20)
  70. >>> expression = "C = test1 {equal|during,#} test2"
  71. >>> p.test(expression)
  72. C = test1 {equal|during,#} test2
  73. LexToken(NAME,'C',1,0)
  74. LexToken(EQUALS,'=',1,2)
  75. LexToken(NAME,'test1',1,4)
  76. LexToken(T_HASH_OPERATOR,'{equal|during,#}',1,10)
  77. LexToken(NAME,'test2',1,27)
  78. >>> expression = "E = test1 : test2 !: test1"
  79. >>> p.test(expression)
  80. E = test1 : test2 !: test1
  81. LexToken(NAME,'E',1,0)
  82. LexToken(EQUALS,'=',1,2)
  83. LexToken(NAME,'test1',1,4)
  84. LexToken(T_SELECT,':',1,10)
  85. LexToken(NAME,'test2',1,12)
  86. LexToken(T_NOT_SELECT,'!:',1,18)
  87. LexToken(NAME,'test1',1,21)
  88. >>> expression = 'D = buff_t(test1,"10 months")'
  89. >>> p.test(expression)
  90. D = buff_t(test1,"10 months")
  91. LexToken(NAME,'D',1,0)
  92. LexToken(EQUALS,'=',1,2)
  93. LexToken(BUFF_T,'buff_t',1,4)
  94. LexToken(LPAREN,'(',1,10)
  95. LexToken(NAME,'test1',1,11)
  96. LexToken(COMMA,',',1,16)
  97. LexToken(QUOTE,'"',1,17)
  98. LexToken(INT,10,1,18)
  99. LexToken(NAME,'months',1,21)
  100. LexToken(QUOTE,'"',1,27)
  101. LexToken(RPAREN,')',1,28)
  102. >>> expression = 'H = tsnap(test1)'
  103. >>> p.test(expression)
  104. H = tsnap(test1)
  105. LexToken(NAME,'H',1,0)
  106. LexToken(EQUALS,'=',1,2)
  107. LexToken(TSNAP,'tsnap',1,4)
  108. LexToken(LPAREN,'(',1,9)
  109. LexToken(NAME,'test1',1,10)
  110. LexToken(RPAREN,')',1,15)
  111. >>> expression = 'H = tsnap(test2 {during,:} buff_t(test1, "1 days"))'
  112. >>> p.test(expression)
  113. H = tsnap(test2 {during,:} buff_t(test1, "1 days"))
  114. LexToken(NAME,'H',1,0)
  115. LexToken(EQUALS,'=',1,2)
  116. LexToken(TSNAP,'tsnap',1,4)
  117. LexToken(LPAREN,'(',1,9)
  118. LexToken(NAME,'test2',1,10)
  119. LexToken(T_SELECT_OPERATOR,'{during,:}',1,16)
  120. LexToken(BUFF_T,'buff_t',1,27)
  121. LexToken(LPAREN,'(',1,33)
  122. LexToken(NAME,'test1',1,34)
  123. LexToken(COMMA,',',1,39)
  124. LexToken(QUOTE,'"',1,41)
  125. LexToken(INT,1,1,42)
  126. LexToken(NAME,'days',1,44)
  127. LexToken(QUOTE,'"',1,48)
  128. LexToken(RPAREN,')',1,49)
  129. LexToken(RPAREN,')',1,50)
  130. >>> expression = 'H = tshift(test2 {during,:} buff_t(test1, "1 days"), "1 months")'
  131. >>> p.test(expression)
  132. H = tshift(test2 {during,:} buff_t(test1, "1 days"), "1 months")
  133. LexToken(NAME,'H',1,0)
  134. LexToken(EQUALS,'=',1,2)
  135. LexToken(TSHIFT,'tshift',1,4)
  136. LexToken(LPAREN,'(',1,10)
  137. LexToken(NAME,'test2',1,11)
  138. LexToken(T_SELECT_OPERATOR,'{during,:}',1,17)
  139. LexToken(BUFF_T,'buff_t',1,28)
  140. LexToken(LPAREN,'(',1,34)
  141. LexToken(NAME,'test1',1,35)
  142. LexToken(COMMA,',',1,40)
  143. LexToken(QUOTE,'"',1,42)
  144. LexToken(INT,1,1,43)
  145. LexToken(NAME,'days',1,45)
  146. LexToken(QUOTE,'"',1,49)
  147. LexToken(RPAREN,')',1,50)
  148. LexToken(COMMA,',',1,51)
  149. LexToken(QUOTE,'"',1,53)
  150. LexToken(INT,1,1,54)
  151. LexToken(NAME,'months',1,56)
  152. LexToken(QUOTE,'"',1,62)
  153. LexToken(RPAREN,')',1,63)
  154. >>> expression = 'H = tshift(A , 10)'
  155. >>> p.test(expression)
  156. H = tshift(A , 10)
  157. LexToken(NAME,'H',1,0)
  158. LexToken(EQUALS,'=',1,2)
  159. LexToken(TSHIFT,'tshift',1,4)
  160. LexToken(LPAREN,'(',1,10)
  161. LexToken(NAME,'A',1,11)
  162. LexToken(COMMA,',',1,13)
  163. LexToken(INT,10,1,15)
  164. LexToken(RPAREN,')',1,17)
  165. >>> expression = 'H = if(td(A) > 10, A)'
  166. >>> p.test(expression)
  167. H = if(td(A) > 10, A)
  168. LexToken(NAME,'H',1,0)
  169. LexToken(EQUALS,'=',1,2)
  170. LexToken(IF,'if',1,4)
  171. LexToken(LPAREN,'(',1,6)
  172. LexToken(TD,'td',1,7)
  173. LexToken(LPAREN,'(',1,9)
  174. LexToken(NAME,'A',1,10)
  175. LexToken(RPAREN,')',1,11)
  176. LexToken(GREATER,'>',1,13)
  177. LexToken(INT,10,1,15)
  178. LexToken(COMMA,',',1,17)
  179. LexToken(NAME,'A',1,19)
  180. LexToken(RPAREN,')',1,20)
  181. >>> expression = 'H = if(td(A) > 10, A, B)'
  182. >>> p.test(expression)
  183. H = if(td(A) > 10, A, B)
  184. LexToken(NAME,'H',1,0)
  185. LexToken(EQUALS,'=',1,2)
  186. LexToken(IF,'if',1,4)
  187. LexToken(LPAREN,'(',1,6)
  188. LexToken(TD,'td',1,7)
  189. LexToken(LPAREN,'(',1,9)
  190. LexToken(NAME,'A',1,10)
  191. LexToken(RPAREN,')',1,11)
  192. LexToken(GREATER,'>',1,13)
  193. LexToken(INT,10,1,15)
  194. LexToken(COMMA,',',1,17)
  195. LexToken(NAME,'A',1,19)
  196. LexToken(COMMA,',',1,20)
  197. LexToken(NAME,'B',1,22)
  198. LexToken(RPAREN,')',1,23)
  199. >>> expression = 'I = if(equals,td(A) > 10 {equals,||} td(B) < 10, A)'
  200. >>> p.test(expression)
  201. I = if(equals,td(A) > 10 {equals,||} td(B) < 10, A)
  202. LexToken(NAME,'I',1,0)
  203. LexToken(EQUALS,'=',1,2)
  204. LexToken(IF,'if',1,4)
  205. LexToken(LPAREN,'(',1,6)
  206. LexToken(NAME,'equals',1,7)
  207. LexToken(COMMA,',',1,13)
  208. LexToken(TD,'td',1,14)
  209. LexToken(LPAREN,'(',1,16)
  210. LexToken(NAME,'A',1,17)
  211. LexToken(RPAREN,')',1,18)
  212. LexToken(GREATER,'>',1,20)
  213. LexToken(INT,10,1,22)
  214. LexToken(T_COMP_OPERATOR,'{equals,||}',1,25)
  215. LexToken(TD,'td',1,37)
  216. LexToken(LPAREN,'(',1,39)
  217. LexToken(NAME,'B',1,40)
  218. LexToken(RPAREN,')',1,41)
  219. LexToken(LOWER,'<',1,43)
  220. LexToken(INT,10,1,45)
  221. LexToken(COMMA,',',1,47)
  222. LexToken(NAME,'A',1,49)
  223. LexToken(RPAREN,')',1,50)
  224. >>> expression = 'I = if(equals,td(A) > 10 || start_day() < 10, A)'
  225. >>> p.test(expression)
  226. I = if(equals,td(A) > 10 || start_day() < 10, A)
  227. LexToken(NAME,'I',1,0)
  228. LexToken(EQUALS,'=',1,2)
  229. LexToken(IF,'if',1,4)
  230. LexToken(LPAREN,'(',1,6)
  231. LexToken(NAME,'equals',1,7)
  232. LexToken(COMMA,',',1,13)
  233. LexToken(TD,'td',1,14)
  234. LexToken(LPAREN,'(',1,16)
  235. LexToken(NAME,'A',1,17)
  236. LexToken(RPAREN,')',1,18)
  237. LexToken(GREATER,'>',1,20)
  238. LexToken(INT,10,1,22)
  239. LexToken(OR,'|',1,25)
  240. LexToken(OR,'|',1,26)
  241. LexToken(START_DAY,'start_day',1,28)
  242. LexToken(LPAREN,'(',1,37)
  243. LexToken(RPAREN,')',1,38)
  244. LexToken(LOWER,'<',1,40)
  245. LexToken(INT,10,1,42)
  246. LexToken(COMMA,',',1,44)
  247. LexToken(NAME,'A',1,46)
  248. LexToken(RPAREN,')',1,47)
  249. >>> expression = 'E = if({equals},td(A) >= 4 {contain,&&} td(B) == 2, C : D)'
  250. >>> p.test(expression)
  251. E = if({equals},td(A) >= 4 {contain,&&} td(B) == 2, C : D)
  252. LexToken(NAME,'E',1,0)
  253. LexToken(EQUALS,'=',1,2)
  254. LexToken(IF,'if',1,4)
  255. LexToken(LPAREN,'(',1,6)
  256. LexToken(T_REL_OPERATOR,'{equals}',1,7)
  257. LexToken(COMMA,',',1,15)
  258. LexToken(TD,'td',1,16)
  259. LexToken(LPAREN,'(',1,18)
  260. LexToken(NAME,'A',1,19)
  261. LexToken(RPAREN,')',1,20)
  262. LexToken(GREATER_EQUALS,'>=',1,22)
  263. LexToken(INT,4,1,25)
  264. LexToken(T_COMP_OPERATOR,'{contain,&&}',1,27)
  265. LexToken(TD,'td',1,40)
  266. LexToken(LPAREN,'(',1,42)
  267. LexToken(NAME,'B',1,43)
  268. LexToken(RPAREN,')',1,44)
  269. LexToken(CEQUALS,'==',1,46)
  270. LexToken(INT,2,1,49)
  271. LexToken(COMMA,',',1,50)
  272. LexToken(NAME,'C',1,52)
  273. LexToken(T_SELECT,':',1,54)
  274. LexToken(NAME,'D',1,56)
  275. LexToken(RPAREN,')',1,57)
  276. >>> expression = 'F = if({equals},A {equal,#}, B, C : D)'
  277. >>> p.test(expression)
  278. F = if({equals},A {equal,#}, B, C : D)
  279. LexToken(NAME,'F',1,0)
  280. LexToken(EQUALS,'=',1,2)
  281. LexToken(IF,'if',1,4)
  282. LexToken(LPAREN,'(',1,6)
  283. LexToken(T_REL_OPERATOR,'{equals}',1,7)
  284. LexToken(COMMA,',',1,15)
  285. LexToken(NAME,'A',1,16)
  286. LexToken(T_HASH_OPERATOR,'{equal,#}',1,18)
  287. LexToken(COMMA,',',1,27)
  288. LexToken(NAME,'B',1,29)
  289. LexToken(COMMA,',',1,30)
  290. LexToken(NAME,'C',1,32)
  291. LexToken(T_SELECT,':',1,34)
  292. LexToken(NAME,'D',1,36)
  293. LexToken(RPAREN,')',1,37)
  294. >>> p = tgis.TemporalAlgebraParser()
  295. >>> p.run = False
  296. >>> p.debug = True
  297. >>> expression = "D = A : (B !: C)"
  298. >>> p.parse(expression)
  299. B* = B !: C
  300. A* = A : B*
  301. D = A*
  302. >>> expression = "D = A {!:} B {during,:} C"
  303. >>> print(expression)
  304. D = A {!:} B {during,:} C
  305. >>> p.parse(expression)
  306. A* = A {!:} B
  307. A** = A* {during,:} C
  308. D = A**
  309. >>> expression = "D = A {:} B {during,!:} C"
  310. >>> print(expression)
  311. D = A {:} B {during,!:} C
  312. >>> p.parse(expression)
  313. A* = A {:} B
  314. A** = A* {during,!:} C
  315. D = A**
  316. >>> expression = "D = A {:} (B {during,!:} (C : E))"
  317. >>> print(expression)
  318. D = A {:} (B {during,!:} (C : E))
  319. >>> p.parse(expression)
  320. C* = C : E
  321. B* = B {during,!:} C*
  322. A* = A {:} B*
  323. D = A*
  324. >>> p.run = False
  325. >>> p.debug = False
  326. >>> expression = "C = test1 : test2"
  327. >>> print(expression)
  328. C = test1 : test2
  329. >>> p.parse(expression, 'stvds')
  330. >>> expression = 'D = buff_t(test1,"10 months")'
  331. >>> print(expression)
  332. D = buff_t(test1,"10 months")
  333. >>> p.parse(expression, 'stvds')
  334. >>> expression = 'E = test2 {during,:} buff_t(test1,"1 days")'
  335. >>> print(expression)
  336. E = test2 {during,:} buff_t(test1,"1 days")
  337. >>> p.parse(expression, 'stvds')
  338. >>> expression = 'F = test2 {equal,:} buff_t(test1,"1 days")'
  339. >>> print(expression)
  340. F = test2 {equal,:} buff_t(test1,"1 days")
  341. >>> p.parse(expression, 'stvds')
  342. >>> p.debug = True
  343. >>> expression = 'H = tsnap(test2 {during,:} buff_t(test1, "1 days"))'
  344. >>> p.parse(expression, 'stvds')
  345. test1* = buff_t( test1 , " 1 days " )
  346. test2* = test2 {during,:} test1*
  347. test2** = tsnap( test2* )
  348. H = test2**
  349. >>> expression = 'H = tshift(test2 {during,:} test1, "1 days")'
  350. >>> p.parse(expression, 'stvds')
  351. test2* = test2 {during,:} test1
  352. test2** = tshift( test2* , " 1 days " )
  353. H = test2**
  354. >>> expression = 'H = tshift(H, 3)'
  355. >>> p.parse(expression, 'stvds')
  356. H* = tshift( H , 3 )
  357. H = H*
  358. >>> expression = 'C = if(td(A) == 2, A)'
  359. >>> p.parse(expression, 'stvds')
  360. td(A)
  361. td(A) == 2
  362. A* = if condition True then A
  363. C = A*
  364. >>> expression = 'C = if(td(A) == 5, A, B)'
  365. >>> p.parse(expression, 'stvds')
  366. td(A)
  367. td(A) == 5
  368. A* = if condition True then A else B
  369. C = A*
  370. >>> expression = 'C = if(td(A) == 5 || start_date() > "2010-01-01", A, B)'
  371. >>> p.parse(expression, 'stvds')
  372. td(A)
  373. td(A) == 5
  374. start_date > "2010-01-01"
  375. True || True
  376. A* = if condition True then A else B
  377. C = A*
  378. @endcode
  379. """
  380. try:
  381. import ply.lex as lex
  382. import ply.yacc as yacc
  383. except:
  384. pass
  385. import os
  386. from space_time_datasets import *
  387. from factory import *
  388. from open_stds import *
  389. import copy
  390. ##############################################################################
  391. class TemporalAlgebraLexer(object):
  392. """!Lexical analyzer for the GRASS GIS temporal algebra"""
  393. # Functions that defines an if condition, temporal buffering and snapping
  394. conditional_functions = {
  395. 'if' : 'IF',
  396. 'buff_t': 'BUFF_T',
  397. 'tsnap' : 'TSNAP',
  398. 'tshift' : 'TSHIFT',
  399. }
  400. # Variables with date and time strings
  401. datetime_functions = {
  402. 'start_time' : 'START_TIME', # start time as HH::MM:SS
  403. 'start_date' : 'START_DATE', # start date as yyyy-mm-DD
  404. 'start_datetime' : 'START_DATETIME', # start datetime as yyyy-mm-DD HH:MM:SS
  405. 'end_time' : 'END_TIME', # end time as HH:MM:SS
  406. 'end_date' : 'END_DATE', # end date as yyyy-mm-DD
  407. 'end_datetime' : 'END_DATETIME', # end datetime as yyyy-mm-DD HH:MM:SS
  408. }
  409. # Time functions
  410. time_functions = {
  411. 'td' : 'TD', # The size of the current
  412. # sample time interval in days and
  413. # fraction of days for absolute time,
  414. # and in relative units in case of relative time.
  415. #'start_td' : 'START_TD', # The time difference between the start
  416. # time of the sample space time raster
  417. # dataset and the start time of the
  418. # current sample interval or instance.
  419. # The time is measured in days and
  420. # fraction of days for absolute time,
  421. # and in relative units in case of relative time.
  422. #'end_td' : 'END_TD', # The time difference between the
  423. # start time of the sample
  424. # space time raster dataset and the
  425. # end time of the current sample interval.
  426. # The time is measured in days and
  427. # fraction of days for absolute time,
  428. # and in relative units in case of relative time.
  429. # The end_time() will be represented by null() in case of a time instance.
  430. 'start_doy' : 'START_DOY', # Day of year (doy) from the start time [1 - 366]
  431. 'start_dow' : 'START_DOW', # Day of week (dow) from the start time [1 - 7], the start of the week is Monday == 1
  432. 'start_year' : 'START_YEAR', # The year of the start time [0 - 9999]
  433. 'start_month' : 'START_MONTH', # The month of the start time [1 - 12]
  434. 'start_week' : 'START_WEEK', # Week of year of the start time [1 - 54]
  435. 'start_day' : 'START_DAY', # Day of month from the start time [1 - 31]
  436. 'start_hour' : 'START_HOUR', # The hour of the start time [0 - 23]
  437. 'start_minute': 'START_MINUTE', # The minute of the start time [0 - 59]
  438. 'start_second': 'START_SECOND', # The second of the start time [0 - 59]
  439. 'end_doy' : 'END_DOY', # Day of year (doy) from the end time [1 - 366]
  440. 'end_dow' : 'END_DOW', # Day of week (dow) from the end time [1 - 7], the start of the week is Monday == 1
  441. 'end_year' : 'END_YEAR', # The year of the end time [0 - 9999]
  442. 'end_month' : 'END_MONTH', # The month of the end time [1 - 12]
  443. 'end_week' : 'END_WEEK', # Week of year of the end time [1 - 54]
  444. 'end_day' : 'END_DAY', # Day of month from the start time [1 - 31]
  445. 'end_hour' : 'END_HOUR', # The hour of the end time [0 - 23]
  446. 'end_minute' : 'END_MINUTE', # The minute of the end time [0 - 59]
  447. 'end_second' : 'END_SECOND', # The second of the end time [0 - 59]
  448. }
  449. # This is the list of token names.
  450. tokens = (
  451. 'DATETIME',
  452. 'TIME',
  453. 'DATE',
  454. 'INT',
  455. 'FLOAT',
  456. 'LPAREN',
  457. 'RPAREN',
  458. 'COMMA',
  459. 'CEQUALS',
  460. 'EQUALS',
  461. 'UNEQUALS',
  462. 'LOWER',
  463. 'LOWER_EQUALS',
  464. 'GREATER',
  465. 'GREATER_EQUALS',
  466. 'HASH',
  467. 'OR',
  468. 'AND',
  469. 'T_SELECT_OPERATOR',
  470. 'T_HASH_OPERATOR',
  471. 'T_COMP_OPERATOR',
  472. 'T_REL_OPERATOR',
  473. 'T_SELECT',
  474. 'T_NOT_SELECT',
  475. 'NAME',
  476. 'QUOTE',
  477. )
  478. # Build the token list
  479. tokens = tokens + tuple(datetime_functions.values()) \
  480. + tuple(time_functions.values()) \
  481. + tuple(conditional_functions.values())
  482. # Regular expression rules for simple tokens
  483. t_T_SELECT_OPERATOR = r'\{([a-zA-Z\| ]+[,])?([\|&+=]?[!]?[:])\}'
  484. t_T_HASH_OPERATOR = r'\{([a-zA-Z\| ]+[,])?[#]\}'
  485. t_T_COMP_OPERATOR = r'\{([a-zA-Z\| ]+[,])?(\|\||&&)\}'
  486. t_T_REL_OPERATOR = r'\{([a-zA-Z\| ])+\}'
  487. t_T_SELECT = r':'
  488. t_T_NOT_SELECT = r'!:'
  489. t_LPAREN = r'\('
  490. t_RPAREN = r'\)'
  491. t_COMMA = r','
  492. t_CEQUALS = r'=='
  493. t_EQUALS = r'='
  494. t_UNEQUALS = r'!='
  495. t_LOWER = r'<'
  496. t_LOWER_EQUALS = r'<='
  497. t_GREATER = r'>'
  498. t_GREATER_EQUALS = r'>='
  499. t_HASH = r'\#'
  500. t_OR = r'[\|]'
  501. t_AND = r'[&]'
  502. t_QUOTE = r'[\"\']'
  503. # These are the things that should be ignored.
  504. t_ignore = ' \t'
  505. # Read time string and convert it into a date object
  506. def t_DATETIME(self, t):
  507. r'"\d\d\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[ T](0[0-9]|1(0-9)|2[0-4]):(0[0-9]|[1-5][0-9]|60):(0[0-9]|[1-5][0-9]|60)"'
  508. # t.value = int(t.value)
  509. return t
  510. # Read date string and convert it into a date object
  511. def t_DATE(self, t):
  512. r'"\d\d\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])"'
  513. # t.value = int(t.value)
  514. return t
  515. # Read time string and convert it into a date object
  516. def t_TIME(self, t):
  517. r'"(0[0-9]|1[0-9]|2[0-4]):(0[0-9]|[1-5][0-9]|60):(0[0-9]|[1-5][0-9]|60)"'
  518. # t.value = int(t.value)
  519. return t
  520. # Read in a float. This rule has to be done before the int rule.
  521. def t_FLOAT(self, t):
  522. r'-?\d+\.\d*(e-?\d+)?'
  523. t.value = float(t.value)
  524. return t
  525. # Read in an int.
  526. def t_INT(self, t):
  527. r'-?\d+'
  528. t.value = int(t.value)
  529. return t
  530. # Read in a list of maps.
  531. def t_LIST(self, t):
  532. r'[\[][.]*[\]]'
  533. t.value = list(t.value)
  534. return t
  535. # Ignore comments.
  536. # def t_comment(self, t):
  537. # r'^[#][^\n]*'
  538. # pass
  539. # Track line numbers.
  540. def t_newline(self, t):
  541. r'\n+'
  542. t.lineno += len(t.value)
  543. def t_NAME(self, t):
  544. r'[a-zA-Z_][a-zA-Z_0-9]*'
  545. self.temporal_symbol(t)
  546. return t
  547. # Parse symbols
  548. def temporal_symbol(self, t):
  549. # Check for reserved words
  550. if t.value in TemporalAlgebraLexer.time_functions.keys():
  551. t.type = TemporalAlgebraLexer.time_functions.get(t.value)
  552. elif t.value in TemporalAlgebraLexer.datetime_functions.keys():
  553. t.type = TemporalAlgebraLexer.datetime_functions.get(t.value)
  554. elif t.value in TemporalAlgebraLexer.conditional_functions.keys():
  555. t.type = TemporalAlgebraLexer.conditional_functions.get(t.value)
  556. else:
  557. t.type = 'NAME'
  558. return t
  559. # Handle errors.
  560. def t_error(self, t):
  561. raise SyntaxError("syntax error on line %d near '%s'" %
  562. (t.lineno, t.value))
  563. # Build the lexer
  564. def build(self,**kwargs):
  565. self.lexer = lex.lex(module=self, optimize=False, debug=False, **kwargs)
  566. # Just for testing
  567. def test(self,data):
  568. self.name_list = {}
  569. print(data)
  570. self.lexer.input(data)
  571. while True:
  572. tok = self.lexer.token()
  573. if not tok: break
  574. print tok
  575. ###############################################################################
  576. class GlobalTemporalVar(object):
  577. """ This class handles global temporal variable conditional expressions,
  578. like start_doy() == 3.
  579. The three parts of the statement are stored separately in
  580. tfunc (START_DOY), compop (==) and value (3).
  581. But also boolean values, time differences and relation operators for comparison in
  582. if-statements can be stored in this class.
  583. """
  584. def __init__(self):
  585. self.tfunc = None
  586. self.compop = None
  587. self.value = None
  588. self.boolean = None
  589. self.relationop = None
  590. self.topology = []
  591. self.td = None
  592. def get_type(self):
  593. if self.tfunc != None and self.compop != None and self.value != None:
  594. return("global")
  595. elif self.boolean != None:
  596. return("boolean")
  597. elif self.relationop != None and self.topology != []:
  598. return("operator")
  599. elif self.td != None:
  600. return("timediff")
  601. def get_type_value(self):
  602. typename = self.get_type()
  603. valuelist = []
  604. if typename == "global":
  605. valuelist = [self.tfunc, self.compop, self.value]
  606. elif typename == "operator":
  607. valuelist.append(self.topology)
  608. valuelist.append(self.relationop)
  609. elif typename == "boolean":
  610. valuelist = self.boolean
  611. elif typename == "timediff":
  612. valuelist.append(self.td)
  613. return(valuelist)
  614. def __str__(self):
  615. return str(self.tfunc) + str(self.compop) + str(self.value)
  616. ###############################################################################
  617. class FatalError(Exception):
  618. def __init__(self, msg):
  619. self.value = msg
  620. def __str__(self):
  621. return self.value
  622. ###############################################################################
  623. class TemporalAlgebraParser(object):
  624. """The temporal algebra class"""
  625. # Get the tokens from the lexer class
  626. tokens = TemporalAlgebraLexer.tokens
  627. # Setting equal precedence level for select and hash operations.
  628. precedence = (
  629. ('left', 'T_SELECT_OPERATOR', 'T_SELECT', 'T_NOT_SELECT'), # 1
  630. ('left', 'AND', 'OR', 'T_COMP_OPERATOR'), #2
  631. )
  632. def __init__(self, pid=None, run = True, debug = False, spatial = False, null = False):
  633. self.run = run
  634. self.debug = debug
  635. self.pid = pid
  636. # Intermediate vector map names
  637. self.names = {}
  638. # Count map names
  639. self.spatial = spatial
  640. self.null = null
  641. self.mapset = get_current_mapset()
  642. self.temporaltype = None
  643. self.msgr = get_tgis_message_interface()
  644. self.dbif = SQLDatabaseInterfaceConnection()
  645. self.dbif.connect()
  646. def __del__(self):
  647. if self.dbif.connected:
  648. self.dbif.close()
  649. def parse(self, expression, stdstype = 'strds', basename = None, overwrite=False):
  650. self.lexer = TemporalAlgebraLexer()
  651. self.lexer.build()
  652. self.parser = yacc.yacc(module=self, debug=self.debug)
  653. self.overwrite = overwrite
  654. self.count = 0
  655. self.stdstype = stdstype
  656. self.basename = basename
  657. self.expression = expression
  658. self.parser.parse(expression)
  659. def generate_map_name(self):
  660. """!Generate an unique intermediate vector map name
  661. and register it in the objects map list for later removement.
  662. The vector map names are unique between processes. Do not use the
  663. same object for map name generation in multiple threads.
  664. """
  665. self.count += 1
  666. if self.pid != None:
  667. pid = self.pid
  668. else:
  669. pid = os.getpid()
  670. name = "tmp_map_name_%i_%i"%(pid, self.count)
  671. self.names[name] = name
  672. return name
  673. def generate_new_map(self, base_map, bool_op = 'and', copy = True):
  674. """!Generate a new map using the spatio-temporal extent of the base map
  675. @param base_map This map is used to create the new map
  676. """
  677. # Generate an intermediate name for the result map list.
  678. name = self.generate_map_name()
  679. # Check for mapset in given stds input.
  680. mapname = name + "@" + self.mapset
  681. # Create new map based on the related map list.
  682. map_new = base_map.get_new_instance(mapname)
  683. # Set initial map extend of new vector map.
  684. self.overlay_map_extent(map_new, base_map, bool_op = bool_op, copy = copy)
  685. return map_new
  686. def overlay_map_extent(self, mapA, mapB, bool_op = None, temp_op = '=',
  687. copy = False):
  688. """!Compute the spatio-temporal extent of two topological related maps
  689. @param mapA The first map
  690. @param mapB The second maps
  691. @param bool_op The boolean operator specifying the spatial extent
  692. operation (intersection, union, disjoint union)
  693. @param temp_op The temporal operator specifying the temporal
  694. extent operation (intersection, union, disjoint union)
  695. @param copy Specifies if the temporal extent of mapB should be
  696. copied to mapA
  697. @return 0 if there is no overlay
  698. """
  699. returncode = 1
  700. if copy:
  701. map_extent_temporal = mapB.get_temporal_extent()
  702. map_extent_spatial = mapB.get_spatial_extent()
  703. # Set initial map extend of new vector map.
  704. mapA.set_spatial_extent(map_extent_spatial)
  705. mapA.set_temporal_extent(map_extent_temporal)
  706. if "cmd_list" in dir(mapB):
  707. mapA.cmd_list = mapB.cmd_list
  708. else:
  709. # Calculate spatial extent for different overlay operations.
  710. if bool_op == 'and':
  711. overlay_ext = mapA.spatial_intersection(mapB)
  712. if overlay_ext != None:
  713. mapA.set_spatial_extent(overlay_ext)
  714. else:
  715. returncode = 0
  716. elif bool_op in ['or', 'xor']:
  717. overlay_ext = mapA.spatial_union(mapB)
  718. if overlay_ext != None:
  719. mapA.set_spatial_extent(overlay_ext)
  720. else:
  721. returncode = 0
  722. elif bool_op == 'disor':
  723. overlay_ext = mapA.spatial_disjoint_union(mapB)
  724. if overlay_ext != None:
  725. mapA.set_spatial_extent(overlay_ext)
  726. else:
  727. returncode = 0
  728. # Calculate temporal extent for different temporal operators.
  729. if temp_op == '&':
  730. temp_ext = mapA.temporal_intersection(mapB)
  731. if temp_ext != None:
  732. mapA.set_temporal_extent(temp_ext)
  733. else:
  734. returncode = 0
  735. elif temp_op == '|':
  736. temp_ext = mapA.temporal_union(mapB)
  737. if temp_ext != None:
  738. mapA.set_temporal_extent(temp_ext)
  739. else:
  740. returncode = 0
  741. elif temp_op == '+':
  742. temp_ext = mapA.temporal_disjoint_union(mapB)
  743. if temp_ext != None:
  744. mapA.set_temporal_extent(temp_ext)
  745. else:
  746. returncode = 0
  747. return(returncode)
  748. ######################### Temporal functions ##############################
  749. def check_stds(self, input, clear = False):
  750. """! Check if input space time dataset exist in database and return its map list.
  751. @param input Name of space time data set as string or list of maps.
  752. @param clear Reset the stored conditional values to empty list.
  753. @return List of maps.
  754. """
  755. if not isinstance(input, list):
  756. # Check for mapset in given stds input.
  757. if input.find("@") >= 0:
  758. id_input = input
  759. else:
  760. id_input = input + "@" + self.mapset
  761. # Create empty spacetime dataset.
  762. stds = dataset_factory(self.stdstype, id_input)
  763. # Check for occurence of space time dataset.
  764. if stds.is_in_db(dbif=self.dbif) == False:
  765. raise FatalError(_("Space time %s dataset <%s> not found") %
  766. (stds.get_new_map_instance(None).get_type(), id_input))
  767. else:
  768. # Select temporal dataset entry from database.
  769. stds.select(dbif=self.dbif)
  770. maplist = stds.get_registered_maps_as_objects(dbif=self.dbif)
  771. # Create map_value as empty list item.
  772. for map_i in maplist:
  773. if "map_value" not in dir(map_i):
  774. map_i.map_value = []
  775. if "condition_value" not in dir(map_i):
  776. map_i.condition_value = []
  777. # Set and check global temporal type variable and map.
  778. if map_i.is_time_absolute() and self.temporaltype == None:
  779. self.temporaltype = 'absolute'
  780. elif map_i.is_time_relative() and self.temporaltype == None:
  781. self.temporaltype = 'relative'
  782. elif map_i.is_time_absolute() and self.temporaltype == 'relative':
  783. self.msgr.fatal(_("Wrong temporal type of space time dataset <%s> \
  784. <%s> time is required") %
  785. (id_input, self.temporaltype))
  786. elif map_i.is_time_relative() and self.temporaltype == 'absolute':
  787. self.msgr.fatal(_("Wrong temporal type of space time dataset <%s> \
  788. <%s> time is required") %
  789. (id_input, self.temporaltype))
  790. else:
  791. maplist = input
  792. # Create map_value as empty list item.
  793. for map_i in maplist:
  794. if "map_value" not in dir(map_i):
  795. map_i.map_value = []
  796. elif clear:
  797. map_i.map_value = []
  798. if "condition_value" not in dir(map_i):
  799. map_i.condition_value = []
  800. elif clear:
  801. map_i.condition_value = []
  802. return(maplist)
  803. def get_temporal_topo_list(self, maplistA, maplistB = None, topolist = ["EQUAL"],
  804. assign_val = False, count_map = False):
  805. """!Build temporal topology for two space time data sets, copy map objects
  806. for given relation into map list.
  807. @param maplistA List of maps.
  808. @param maplistB List of maps.
  809. @param topolist List of strings of temporal relations.
  810. @param assign_val Boolean for assigning a boolean map value based on
  811. the map_values from the compared map list by
  812. topological relationships.
  813. @param count_map Boolean if the number of topological related maps
  814. should be returned.
  815. @return List of maps from maplistA that fulfil the topological relationships
  816. to maplistB specified in topolist.
  817. @code
  818. # Example with two lists of maps
  819. >>> import grass.temporal as tgis
  820. >>> tgis.init(True)
  821. >>> l = tgis.TemporalAlgebraParser()
  822. >>> # Create two list of maps with equal time stamps
  823. >>> mapsA = []
  824. >>> mapsB = []
  825. >>> for i in range(10):
  826. ... idA = "a%i@B"%(i)
  827. ... mapA = tgis.RasterDataset(idA)
  828. ... idB = "b%i@B"%(i)
  829. ... mapB = tgis.RasterDataset(idB)
  830. ... check = mapA.set_relative_time(i, i + 1, "months")
  831. ... check = mapB.set_relative_time(i, i + 1, "months")
  832. ... mapsA.append(mapA)
  833. ... mapsB.append(mapB)
  834. >>> resultlist = l.get_temporal_topo_list(mapsA, mapsB, ['EQUAL'])
  835. >>> for map in resultlist:
  836. ... if map.get_equal():
  837. ... relations = map.get_equal()
  838. ... print "Map %s has equal relation to map %s"%(map.get_name(),
  839. ... relations[0].get_name())
  840. Map a0 has equal relation to map b0
  841. Map a1 has equal relation to map b1
  842. Map a2 has equal relation to map b2
  843. Map a3 has equal relation to map b3
  844. Map a4 has equal relation to map b4
  845. Map a5 has equal relation to map b5
  846. Map a6 has equal relation to map b6
  847. Map a7 has equal relation to map b7
  848. Map a8 has equal relation to map b8
  849. Map a9 has equal relation to map b9
  850. >>> resultlist = l.get_temporal_topo_list(mapsA, mapsB, ['DURING'])
  851. >>> print(resultlist)
  852. []
  853. >>> # Create two list of maps with equal time stamps
  854. >>> mapsA = []
  855. >>> mapsB = []
  856. >>> for i in range(10):
  857. ... idA = "a%i@B"%(i)
  858. ... mapA = tgis.RasterDataset(idA)
  859. ... idB = "b%i@B"%(i)
  860. ... mapB = tgis.RasterDataset(idB)
  861. ... check = mapA.set_relative_time(i, i + 1, "months")
  862. ... check = mapB.set_relative_time(i, i + 2, "months")
  863. ... mapsA.append(mapA)
  864. ... mapsB.append(mapB)
  865. >>> resultlist = l.get_temporal_topo_list(mapsA, mapsB, ['starts','during'])
  866. >>> for map in resultlist:
  867. ... if map.get_starts():
  868. ... relations = map.get_starts()
  869. ... print "Map %s has start relation to map %s"%(map.get_name(),
  870. ... relations[0].get_name())
  871. Map a0 has start relation to map b0
  872. Map a1 has start relation to map b1
  873. Map a2 has start relation to map b2
  874. Map a3 has start relation to map b3
  875. Map a4 has start relation to map b4
  876. Map a5 has start relation to map b5
  877. Map a6 has start relation to map b6
  878. Map a7 has start relation to map b7
  879. Map a8 has start relation to map b8
  880. Map a9 has start relation to map b9
  881. >>> for map in resultlist:
  882. ... if map.get_during():
  883. ... relations = map.get_during()
  884. ... print "Map %s has during relation to map %s"%(map.get_name(),
  885. ... relations[0].get_name())
  886. Map a0 has during relation to map b0
  887. Map a1 has during relation to map b0
  888. Map a2 has during relation to map b1
  889. Map a3 has during relation to map b2
  890. Map a4 has during relation to map b3
  891. Map a5 has during relation to map b4
  892. Map a6 has during relation to map b5
  893. Map a7 has during relation to map b6
  894. Map a8 has during relation to map b7
  895. Map a9 has during relation to map b8
  896. >>> # Create two list of maps with equal time stamps and map_value method.
  897. >>> mapsA = []
  898. >>> mapsB = []
  899. >>> for i in range(10):
  900. ... idA = "a%i@B"%(i)
  901. ... mapA = tgis.RasterDataset(idA)
  902. ... idB = "b%i@B"%(i)
  903. ... mapB = tgis.RasterDataset(idB)
  904. ... check = mapA.set_relative_time(i, i + 1, "months")
  905. ... check = mapB.set_relative_time(i, i + 1, "months")
  906. ... mapB.map_value = True
  907. ... mapsA.append(mapA)
  908. ... mapsB.append(mapB)
  909. >>> # Create two list of maps with equal time stamps
  910. >>> mapsA = []
  911. >>> mapsB = []
  912. >>> for i in range(10):
  913. ... idA = "a%i@B"%(i)
  914. ... mapA = tgis.RasterDataset(idA)
  915. ... mapA.map_value = True
  916. ... idB = "b%i@B"%(i)
  917. ... mapB = tgis.RasterDataset(idB)
  918. ... mapB.map_value = False
  919. ... check = mapA.set_absolute_time(datetime(2000,1,i+1),
  920. ... datetime(2000,1,i + 2))
  921. ... check = mapB.set_absolute_time(datetime(2000,1,i+6),
  922. ... datetime(2000,1,i + 7))
  923. ... mapsA.append(mapA)
  924. ... mapsB.append(mapB)
  925. >>> resultlist = l.get_temporal_topo_list(mapsA, mapsB)
  926. >>> for map in resultlist:
  927. ... print(map.get_id())
  928. a5@B
  929. a6@B
  930. a7@B
  931. a8@B
  932. a9@B
  933. >>> resultlist = l.get_temporal_topo_list(mapsA, mapsB, ['during'])
  934. >>> for map in resultlist:
  935. ... print(map.get_id())
  936. @endcode
  937. """
  938. topologylist = ["EQUAL", "FOLLOWS", "PRECEDES", "OVERLAPS", "OVERLAPPED", \
  939. "DURING", "STARTS", "FINISHES", "CONTAINS", "STARTED", \
  940. "FINISHED"]
  941. complementdict = {"EQUAL": "EQUAL", "FOLLOWS" : "PRECEDES",
  942. "PRECEDES" : "FOLLOWS", "OVERLAPS" : "OVERLAPPED",
  943. "OVERLAPPED" : "OVERLAPS", "DURING" : "CONTAINS",
  944. "CONTAINS" : "DURING", "STARTS" : "STARTED",
  945. "STARTED" : "STARTS", "FINISHES" : "FINISHED",
  946. "FINISHED" : "FINISHES"}
  947. resultdict = {}
  948. # Check if given temporal relation are valid.
  949. for topo in topolist:
  950. if topo.upper() not in topologylist:
  951. raise SyntaxError("Unpermitted temporal relation name '" + topo + "'")
  952. # Create temporal topology for maplistA to maplistB.
  953. tb = SpatioTemporalTopologyBuilder()
  954. # Dictionary with different spatial variables used for topology builder.
  955. spatialdict = {'strds' : '2D', 'stvds' : '2D', 'str3ds' : '3D'}
  956. # Build spatial temporal topology
  957. if self.spatial:
  958. tb.build(maplistA, maplistB, spatial = spatialdict[self.stdstype])
  959. else:
  960. tb.build(maplistA, maplistB)
  961. # Iterate through maps in maplistA and search for relationships given
  962. # in topolist.
  963. # TODO: Better implementation with less nesting
  964. for map_i in maplistA:
  965. tbrelations = map_i.get_temporal_relations()
  966. for topo in topolist:
  967. if topo.upper() in tbrelations.keys():
  968. if assign_val:
  969. mapvaluelist = []
  970. if complementdict[topo.upper()] in tbrelations:
  971. relationmaplist = tbrelations[complementdict[topo.upper()]]
  972. for relationmap in relationmaplist:
  973. if "map_value" in dir(relationmap):
  974. for element in relationmap.map_value:
  975. if isinstance(element, GlobalTemporalVar):
  976. if element.get_type() == "boolean":
  977. mapvaluelist.append(element.boolean)
  978. if all(mapvaluelist):
  979. resultbool = True
  980. else:
  981. resultbool = False
  982. if "condition_value" in dir(map_i):
  983. if isinstance(map_i.condition_value, list):
  984. map_i.condition_value.append(resultbool)
  985. if count_map:
  986. relationmaplist = tbrelations[topo.upper()]
  987. gvar = GlobalTemporalVar()
  988. gvar.td = len(relationmaplist)
  989. if "map_value" in dir(map_i):
  990. map_i.map_value.append(gvar)
  991. else:
  992. map_i.map_value = gvar
  993. resultdict[map_i.get_id()] = map_i
  994. resultlist = resultdict.values()
  995. # Sort list of maps chronological.
  996. resultlist = sorted(resultlist, key = AbstractDatasetComparisonKeyStartTime)
  997. return(resultlist)
  998. def eval_toperator(self, operator):
  999. """!This function evaluates a string containing temporal operations.
  1000. @param operator String of temporal operations, e.g. {equal|during,=!:}.
  1001. @return List of temporal relations (equal, during), the given function
  1002. (!:) and the interval/instances (=).
  1003. @code
  1004. >>> import grass.temporal as tgis
  1005. >>> tgis.init()
  1006. >>> p = tgis.TemporalAlgebraParser()
  1007. >>> operator = "{equal,:}"
  1008. >>> p.eval_toperator(operator)
  1009. (['equal'], '=', ':')
  1010. >>> operator = "{equal|during,:}"
  1011. >>> p.eval_toperator(operator)
  1012. (['equal', 'during'], '=', ':')
  1013. >>> operator = "{equal,!:}"
  1014. >>> p.eval_toperator(operator)
  1015. (['equal'], '=', '!:')
  1016. >>> operator = "{equal|during,!:}"
  1017. >>> p.eval_toperator(operator)
  1018. (['equal', 'during'], '=', '!:')
  1019. >>> operator = "{equal|during,=!:}"
  1020. >>> p.eval_toperator(operator)
  1021. (['equal', 'during'], '=', '!:')
  1022. >>> operator = "{equal|during|starts,#}"
  1023. >>> p.eval_toperator(operator)
  1024. (['equal', 'during', 'starts'], '=', '#')
  1025. >>> operator = "{!:}"
  1026. >>> p.eval_toperator(operator)
  1027. (['equal'], '=', '!:')
  1028. >>> operator = "{=:}"
  1029. >>> p.eval_toperator(operator)
  1030. (['equal'], '=', ':')
  1031. >>> operator = "{#}"
  1032. >>> p.eval_toperator(operator)
  1033. (['equal'], '=', '#')
  1034. >>> operator = "{equal|during}"
  1035. >>> p.eval_toperator(operator)
  1036. (['equal', 'during'], '=', '')
  1037. >>> operator = "{equal}"
  1038. >>> p.eval_toperator(operator)
  1039. (['equal'], '=', '')
  1040. >>> operator = "{equal,||}"
  1041. >>> p.eval_toperator(operator)
  1042. (['equal'], '=', '||')
  1043. >>> operator = "{equal|during,&&}"
  1044. >>> p.eval_toperator(operator)
  1045. (['equal', 'during'], '=', '&&')
  1046. @endcode
  1047. """
  1048. topologylist = ["EQUAL", "FOLLOWS", "PRECEDES", "OVERLAPS", "OVERLAPPED", \
  1049. "DURING", "STARTS", "FINISHES", "CONTAINS", "STARTED", \
  1050. "FINISHED"]
  1051. functionlist = [":", "!:", "#"]
  1052. intervallist = ["=", "|", "&", "+"]
  1053. comparelist = ["||", "&&"]
  1054. relations = []
  1055. interval = '='
  1056. function = ''
  1057. op = operator.strip('{}')
  1058. oplist = op.split(',')
  1059. if len(oplist) > 1:
  1060. relationlist = oplist[0].split('|')
  1061. for relation in relationlist:
  1062. if relation.upper() in topologylist and relation not in relations:
  1063. relations.append(relation)
  1064. else:
  1065. raise SyntaxError("invalid syntax")
  1066. opright = oplist[1]
  1067. if opright in comparelist:
  1068. function = opright
  1069. elif opright[0] in intervallist:
  1070. interval = opright[0]
  1071. if opright[1:] in functionlist:
  1072. function = opright[1:]
  1073. else:
  1074. raise SyntaxError("invalid syntax")
  1075. elif opright in functionlist:
  1076. function = opright
  1077. else:
  1078. raise SyntaxError("invalid syntax")
  1079. elif all([rel.upper() in topologylist for rel in oplist[0].split('|')]):
  1080. relations = oplist[0].split('|')
  1081. else:
  1082. relations = ['equal']
  1083. opstr = str(oplist[0])
  1084. if opstr[0] in intervallist:
  1085. interval = opstr[0]
  1086. if opstr[1:] in functionlist:
  1087. function = opstr[1:]
  1088. else:
  1089. raise SyntaxError("invalid syntax")
  1090. elif opstr in functionlist:
  1091. function = opstr
  1092. #else:
  1093. #raise SyntaxError("invalid syntax")
  1094. return(relations, interval, function)
  1095. def perform_temporal_selection(self, maplistA, maplistB, topolist = ["EQUAL"],
  1096. inverse = False, assign_val = False):
  1097. """!This function performs temporal selection operation.
  1098. @param maplistA List of maps representing the left side of a temporal
  1099. expression.
  1100. @param maplistB List of maps representing the right side of a temporal
  1101. expression.
  1102. @param topolist List of strings of temporal relations.
  1103. @param inverse Boolean value that specifies if the selection should be
  1104. inverted.
  1105. @param assign_val Boolean for assigning a boolean map value based on
  1106. the map_values from the compared map list by
  1107. topological relationships.
  1108. @return List of selected maps from maplistA.
  1109. @code
  1110. >>> import grass.temporal as tgis
  1111. >>> tgis.init()
  1112. >>> l = tgis.TemporalAlgebraParser()
  1113. >>> # Example with two lists of maps
  1114. >>> # Create two list of maps with equal time stamps
  1115. >>> mapsA = []
  1116. >>> mapsB = []
  1117. >>> for i in range(10):
  1118. ... idA = "a%i@B"%(i)
  1119. ... mapA = tgis.RasterDataset(idA)
  1120. ... idB = "b%i@B"%(i)
  1121. ... mapB = tgis.RasterDataset(idB)
  1122. ... check = mapA.set_relative_time(i, i + 1, "months")
  1123. ... check = mapB.set_relative_time(i + 5, i + 6, "months")
  1124. ... mapsA.append(mapA)
  1125. ... mapsB.append(mapB)
  1126. >>> resultlist = l.perform_temporal_selection(mapsA, mapsB, ['EQUAL'],
  1127. ... False)
  1128. >>> for map in resultlist:
  1129. ... if map.get_equal():
  1130. ... relations = map.get_equal()
  1131. ... print "Map %s has equal relation to map %s"%(map.get_name(),
  1132. ... relations[0].get_name())
  1133. Map a5 has equal relation to map b0
  1134. Map a6 has equal relation to map b1
  1135. Map a7 has equal relation to map b2
  1136. Map a8 has equal relation to map b3
  1137. Map a9 has equal relation to map b4
  1138. >>> resultlist = l.perform_temporal_selection(mapsA, mapsB, ['EQUAL'],
  1139. ... True)
  1140. >>> for map in resultlist:
  1141. ... if not map.get_equal():
  1142. ... print "Map %s has no equal relation to mapset mapsB"%(map.get_name())
  1143. Map a0 has no equal relation to mapset mapsB
  1144. Map a1 has no equal relation to mapset mapsB
  1145. Map a2 has no equal relation to mapset mapsB
  1146. Map a3 has no equal relation to mapset mapsB
  1147. Map a4 has no equal relation to mapset mapsB
  1148. @endcode
  1149. """
  1150. if not inverse:
  1151. topolist = self.get_temporal_topo_list(maplistA, maplistB, topolist,
  1152. assign_val = assign_val)
  1153. resultlist = topolist
  1154. else:
  1155. topolist = self.get_temporal_topo_list(maplistA, maplistB, topolist,
  1156. assign_val = False)
  1157. resultlist = []
  1158. for map_i in maplistA:
  1159. if map_i not in topolist:
  1160. resultlist.append(map_i)
  1161. if assign_val:
  1162. if "condition_value" in dir(map_i):
  1163. map_i.condition_value.append(False)
  1164. # Sort list of maps chronological.
  1165. resultlist = sorted(resultlist, key = AbstractDatasetComparisonKeyStartTime)
  1166. return(resultlist)
  1167. def set_granularity(self, maplistA, maplistB, toperator = '=', topolist = ["EQUAL"]):
  1168. """!This function sets the temporal extends of a list of maps based on
  1169. another map list.
  1170. @param maplistB List of maps.
  1171. @param maplistB List of maps.
  1172. @param toperator String containing the temporal operator: =, +, &, |.
  1173. @param topolist List of topological relations.
  1174. @return List of maps with the new temporal extends.
  1175. @code
  1176. >>> import grass.temporal as tgis
  1177. >>> tgis.init()
  1178. >>> p = tgis.TemporalAlgebraParser()
  1179. >>> # Create two list of maps with equal time stamps
  1180. >>> mapsA = []
  1181. >>> mapsB = []
  1182. >>> for i in range(10):
  1183. ... idA = "a%i@B"%(i)
  1184. ... mapA = tgis.RasterDataset(idA)
  1185. ... idB = "b%i@B"%(i)
  1186. ... mapB = tgis.RasterDataset(idB)
  1187. ... check = mapA.set_relative_time(i, i + 1, "months")
  1188. ... check = mapB.set_relative_time(i*2, i*2 + 2, "months")
  1189. ... mapsA.append(mapA)
  1190. ... mapsB.append(mapB)
  1191. >>> resultlist = p.set_granularity(mapsA, mapsB, toperator = "|", topolist = ["during"])
  1192. >>> for map in resultlist:
  1193. ... start,end,unit = map.get_relative_time()
  1194. ... print(map.get_id() + ' - start: ' + str(start) + ' end: ' + str(end))
  1195. a1@B - start: 0 end: 2
  1196. a0@B - start: 0 end: 2
  1197. a3@B - start: 2 end: 4
  1198. a2@B - start: 2 end: 4
  1199. a5@B - start: 4 end: 6
  1200. a4@B - start: 4 end: 6
  1201. a7@B - start: 6 end: 8
  1202. a6@B - start: 6 end: 8
  1203. a9@B - start: 8 end: 10
  1204. a8@B - start: 8 end: 10
  1205. @endcode
  1206. """
  1207. topologylist = ["EQUAL", "FOLLOWS", "PRECEDES", "OVERLAPS", "OVERLAPPED", \
  1208. "DURING", "STARTS", "FINISHES", "CONTAINS", "STARTED", \
  1209. "FINISHED"]
  1210. for topo in topolist:
  1211. if topo.upper() not in topologylist:
  1212. raise SyntaxError("Unpermitted temporal relation name '" + topo + "'")
  1213. # Create temporal topology for maplistA to maplistB.
  1214. tb = SpatioTemporalTopologyBuilder()
  1215. # Dictionary with different spatial variables used for topology builder.
  1216. spatialdict = {'strds' : '2D', 'stvds' : '2D', 'str3ds' : '3D'}
  1217. # Build spatial temporal topology for maplistB to maplistB.
  1218. if self.spatial:
  1219. tb.build(maplistA, maplistB, spatial = spatialdict[self.stdstype])
  1220. else:
  1221. tb.build(maplistA, maplistB)
  1222. resultdict = {}
  1223. # Iterate through maps in maplistA and search for relationships given
  1224. # in topolist.
  1225. for map_i in maplistA:
  1226. tbrelations = map_i.get_temporal_relations()
  1227. for topo in topolist:
  1228. if topo.upper() in tbrelations.keys():
  1229. relationmaplist = tbrelations[topo.upper()]
  1230. for relationmap in relationmaplist:
  1231. newextend = None
  1232. if toperator == "&":
  1233. newextend = map_i.temporal_intersection(relationmap)
  1234. elif toperator == "|":
  1235. newextend = map_i.temporal_union(relationmap)
  1236. elif toperator == "+":
  1237. newextend = map_i.temporal_disjoint_union(relationmap)
  1238. elif toperator == "=":
  1239. resultdict[map_i.get_id()] = map_i
  1240. if newextend != None:
  1241. start = newextend.get_start_time()
  1242. end = newextend.get_end_time()
  1243. #print(map_i.get_id() + ' - start: ' + str(start) + ' end: ' + str(end))
  1244. if map_i.is_time_absolute():
  1245. map_i.set_absolute_time(start, end)
  1246. else:
  1247. relunit = map_i.get_relative_time_unit()
  1248. map_i.set_relative_time(int(start), int(end), relunit)
  1249. resultdict[map_i.get_id()] = map_i
  1250. resultlist = resultdict.values()
  1251. # Sort list of maps chronological.
  1252. resultlist = sorted(resultlist, key = AbstractDatasetComparisonKeyStartTime)
  1253. # Get relations to maplistB per map in A.
  1254. # Loop over all relations from list
  1255. # temporal extent = map.temporal_intersection(map)
  1256. # if temporal extend is None = delete map.
  1257. return(resultlist)
  1258. def get_temporal_func_dict(self, map):
  1259. """! This function creates a dictionary containing temporal functions for a
  1260. map dataset with time stamp.
  1261. @param map Map object with time stamps.
  1262. @return Dictionary with temporal functions for given input map.
  1263. @code
  1264. >>> import grass.temporal as tgis
  1265. >>> import datetime
  1266. >>> tgis.init()
  1267. >>> l = tgis.TemporalAlgebraParser()
  1268. >>> # Example with one list of maps
  1269. >>> # Create one list of maps with equal time stamps
  1270. >>> for i in range(1):
  1271. ... idA = "a%i@B"%(i)
  1272. ... mapA = tgis.RasterDataset(idA)
  1273. ... check = mapA.set_absolute_time(datetime.datetime(2000,1,1),
  1274. ... datetime.datetime(2000,10,1))
  1275. ... tfuncdict = l.get_temporal_func_dict(mapA)
  1276. >>> print(tfuncdict["START_YEAR"])
  1277. 2000
  1278. >>> print(tfuncdict["START_TIME"])
  1279. 00:00:00
  1280. >>> print(tfuncdict["START_DATE"])
  1281. 2000-01-01
  1282. >>> print(tfuncdict["START_DATETIME"])
  1283. 2000-01-01 00:00:00
  1284. @endcode
  1285. """
  1286. tvardict = {"START_DOY" : None, "START_DOW" : None, "START_YEAR" : None,
  1287. "START_MONTH" : None, "START_WEEK" : None, "START_DAY" : None,
  1288. "START_HOUR" : None, "START_MINUTE" : None, "START_SECOND" : None,
  1289. "END_DOY" : None, "END_DOW" : None, "END_YEAR" : None,
  1290. "END_MONTH" : None, "END_WEEK" : None, "END_DAY" : None,
  1291. "END_HOUR" : None, "END_MINUTE" : None, "END_SECOND" : None,
  1292. "START_DATE" : None, "START_DATETIME" : None, "START_TIME" : None,
  1293. "END_DATE" : None, "END_DATETIME" : None, "END_TIME" : None}
  1294. # Compute temporal function only for maps with absolute time reference.
  1295. if map.is_time_absolute:
  1296. # Get datetime of map.
  1297. start, end = map.get_absolute_time()
  1298. # Compute DOY via time deltas.
  1299. yearstart = datetime(start.year, 1, 1)
  1300. yearend = datetime(end.year, 1, 1)
  1301. deltastart = start - yearstart
  1302. deltaend = end - yearend
  1303. # Evaluate datetime objects and fill in into dict.
  1304. tvardict["START_DOY"] = deltastart.days + 1
  1305. tvardict["START_DOW"] = start.isoweekday()
  1306. tvardict["START_YEAR"] = start.year
  1307. tvardict["START_MONTH"] = start.month
  1308. tvardict["START_WEEK"] = start.isocalendar()[1]
  1309. tvardict["START_DAY"] = start.day
  1310. tvardict["START_HOUR"] = start.hour
  1311. tvardict["START_MINUTE"] = start.minute
  1312. tvardict["START_SECOND"] = start.second
  1313. tvardict["END_DOY"] = deltaend.days + 1
  1314. tvardict["END_DOW"] = end.isoweekday()
  1315. tvardict["END_YEAR"] = end.year
  1316. tvardict["END_MONTH"] = end.month
  1317. tvardict["END_WEEK"] = end.isocalendar()[1]
  1318. tvardict["END_DAY"] = end.day
  1319. tvardict["END_HOUR"] = end.hour
  1320. tvardict["END_MINUTE"] = end.minute
  1321. tvardict["END_SECOND"] = end.second
  1322. tvardict["START_DATE"] = start.date()
  1323. tvardict["START_DATETIME"] = start
  1324. tvardict["START_TIME"] = start.time()
  1325. tvardict["END_DATE"] = end.date()
  1326. tvardict["END_DATETIME"] = end
  1327. tvardict["END_TIME"] = end.time()
  1328. if not map.is_time_absolute:
  1329. tvardict["START_DATE"] = start.date()
  1330. tvardict["START_DATETIME"] = start
  1331. tvardict["START_TIME"] = start.time()
  1332. tvardict["END_DATE"] = end.date()
  1333. tvardict["END_DATETIME"] = end
  1334. tvardict["END_TIME"] = end.time()
  1335. #core.fatal(_("The temporal functions for map <%s> only supported for absolute"\
  1336. # "time." % (str(map.get_id()))))
  1337. return(tvardict)
  1338. def eval_datetime_str(self, tfuncval, comp, value):
  1339. # Evaluate date object comparison expression.
  1340. if comp == "<":
  1341. boolname = eval(str(tfuncval < value))
  1342. elif comp == ">":
  1343. boolname = eval(str(tfuncval > value))
  1344. elif comp == "==":
  1345. boolname = eval(str(tfuncval == value))
  1346. elif comp == "<=":
  1347. boolname = eval(str(tfuncval <= value))
  1348. elif comp == ">=":
  1349. boolname = eval(str(tfuncval >= value))
  1350. elif comp == "!=":
  1351. boolname = eval(str(tfuncval != value))
  1352. return(boolname)
  1353. def eval_global_var(self, gvar, maplist):
  1354. """! This function evaluates a global variable expression for a map list.
  1355. For example: start_day() > 5 , end_month() == 2.
  1356. @param gvar Object of type GlobalTemporalVar containing temporal.
  1357. @param maplist List of map objects.
  1358. @return List of maps from maplist with added conditional boolean values.
  1359. """
  1360. boollist = []
  1361. # Loop over maps of input map list.
  1362. for map_i in maplist:
  1363. # Get dictionary with temporal variables for the map.
  1364. tfuncdict = self.get_temporal_func_dict(map_i)
  1365. # Get value from global variable.
  1366. value = gvar.value
  1367. # Get comparison operator from global variable, like <, >, <=, >=, ==, !=
  1368. comp_op = gvar.compop
  1369. # Get temporal function name for global variable.
  1370. tfunc = gvar.tfunc.upper()
  1371. # Get value for function name from dictionary.
  1372. tfuncval = tfuncdict[tfunc]
  1373. # Check if value has to be transfered to datetime object for comparison.
  1374. if tfunc in ["START_DATE", "END_DATE"]:
  1375. timeobj = datetime.strptime(value.replace("\"",""), '%Y-%m-%d')
  1376. value = timeobj.date()
  1377. boolname = self.eval_datetime_str(tfuncval, comp_op, value)
  1378. elif tfunc in ["START_TIME", "END_TIME"]:
  1379. timeobj = datetime.strptime(value.replace("\"",""), '%H:%M:%S')
  1380. value = timeobj.time()
  1381. boolname = self.eval_datetime_str(tfuncval, comp_op, value)
  1382. elif tfunc in ["START_DATETIME", "END_DATETIME"]:
  1383. timeobj = datetime.strptime(value.replace("\"",""), '%Y-%m-%d %H:%M:%S')
  1384. value = timeobj
  1385. boolname = self.eval_datetime_str(tfuncval, comp_op, value)
  1386. else:
  1387. boolname = eval(str(tfuncval) + comp_op + str(value))
  1388. # Add conditional boolean value to the map.
  1389. if "condition_value" in dir(map_i):
  1390. map_i.condition_value.append(boolname)
  1391. else:
  1392. map_i.condition_value = boolname
  1393. return(maplist)
  1394. def eval_map_list(self, maplist ,thenlist, topolist = ["EQUAL"]):
  1395. """! This function transfers boolean values from temporal expression
  1396. from one map list to another by their topology. These boolean
  1397. values are added to the maps as condition_value.
  1398. @param maplist List of map objects containing boolean map values.
  1399. @param thenlist List of map objects where the boolean values
  1400. should be added.
  1401. @return List of maps from thenlist with added conditional boolean values.
  1402. """
  1403. # Get topology of then statement map list in relation to the other maplist
  1404. # and assign boolean values of the maplist to the thenlist.
  1405. containlist = self.perform_temporal_selection(thenlist, maplist,
  1406. assign_val = True,
  1407. topolist = topolist)
  1408. # Inverse selection of maps from thenlist and assigning False values.
  1409. excludelist = self.perform_temporal_selection(thenlist, maplist,
  1410. assign_val = True,
  1411. inverse = True,
  1412. topolist = topolist)
  1413. # Combining the selection and inverse selection list.
  1414. resultlist = containlist + excludelist
  1415. return(resultlist)
  1416. def build_condition_list(self, tvarexpr, thenlist, topolist = ["EQUAL"]):
  1417. """! This function evaluates temporal variable expressions of a conditional
  1418. expression related to the map list of the then statement.
  1419. Global variables or map lists with booleans are compared to the topology
  1420. of the conclusion map list and a conditional list will be appended to
  1421. every map. It contain the boolean expressions from these comparisons
  1422. and optional operators to combine several temporal expressions, like
  1423. "&&" or "||".
  1424. For example: td(A) == 1 && start_day() > 5 --> [True || False]
  1425. (for one map.condition_value in a then map list)
  1426. @param tvarexpr List of GlobalTemporalVar objects and map lists.
  1427. The list is constructed by the TemporalAlgebraParser
  1428. in order of expression evaluation in the parser.
  1429. @param thenlist Map list object of the conclusion statement.
  1430. It will be compared and evaluated by the conditions.
  1431. @return Map list with conditional values for all temporal expressions.
  1432. @code
  1433. >>> import grass.temporal as tgis
  1434. >>> tgis.init()
  1435. >>> p = tgis.TemporalAlgebraParser()
  1436. >>> # Example with two lists of maps
  1437. >>> # Create two list of maps with equal time stamps
  1438. >>> mapsA = []
  1439. >>> mapsB = []
  1440. >>> for i in range(10):
  1441. ... idA = "a%i@B"%(i)
  1442. ... mapA = tgis.RasterDataset(idA)
  1443. ... idB = "b%i@B"%(i)
  1444. ... mapB = tgis.RasterDataset(idB)
  1445. ... check = mapA.set_absolute_time(datetime(2000,1,i + 1),
  1446. ... datetime(2000,1,i + 2))
  1447. ... check = mapB.set_absolute_time(datetime(2000,1,i + 6),
  1448. ... datetime(2000,1,i + 7))
  1449. ... mapsA.append(mapA)
  1450. ... mapsB.append(mapB)
  1451. >>> mapsA = p.check_stds(mapsA)
  1452. >>> mapsB = p.check_stds(mapsB)
  1453. >>> # Create global expression object.
  1454. >>> gvarA = tgis.GlobalTemporalVar()
  1455. >>> gvarA.tfunc = "start_day"
  1456. >>> gvarA.compop = ">"
  1457. >>> gvarA.value = 5
  1458. >>> gvarB = tgis.GlobalTemporalVar()
  1459. >>> gvarB.tfunc = "start_day"
  1460. >>> gvarB.compop = "<="
  1461. >>> gvarB.value = 8
  1462. >>> gvarOP = tgis.GlobalTemporalVar()
  1463. >>> gvarOP.relationop = "&&"
  1464. >>> gvarOP.topology.append("EQUAL")
  1465. >>> tvarexpr = gvarA
  1466. >>> result = p.build_condition_list(tvarexpr, mapsA)
  1467. >>> for map_i in result:
  1468. ... print(map_i.get_map_id() + ' ' + str(map_i.condition_value))
  1469. a0@B [False]
  1470. a1@B [False]
  1471. a2@B [False]
  1472. a3@B [False]
  1473. a4@B [False]
  1474. a5@B [True]
  1475. a6@B [True]
  1476. a7@B [True]
  1477. a8@B [True]
  1478. a9@B [True]
  1479. >>> tvarexpr = [gvarA, gvarOP, gvarB]
  1480. >>> result = p.build_condition_list(tvarexpr, mapsB)
  1481. >>> for map_i in result:
  1482. ... print(map_i.get_map_id() + ' ' + str(map_i.condition_value))
  1483. b0@B [True, ['EQUAL'], '&&', True]
  1484. b1@B [True, ['EQUAL'], '&&', True]
  1485. b2@B [True, ['EQUAL'], '&&', True]
  1486. b3@B [True, ['EQUAL'], '&&', False]
  1487. b4@B [True, ['EQUAL'], '&&', False]
  1488. b5@B [True, ['EQUAL'], '&&', False]
  1489. b6@B [True, ['EQUAL'], '&&', False]
  1490. b7@B [True, ['EQUAL'], '&&', False]
  1491. b8@B [True, ['EQUAL'], '&&', False]
  1492. b9@B [True, ['EQUAL'], '&&', False]
  1493. @endcode
  1494. """
  1495. # Check if the input expression is a valid single global variable.
  1496. if not isinstance(tvarexpr, list):
  1497. if isinstance(tvarexpr, GlobalTemporalVar):
  1498. if tvarexpr.get_type() == "global":
  1499. # Use method eval_global_var to evaluate expression.
  1500. resultlist = self.eval_global_var(tvarexpr, thenlist)
  1501. else:
  1502. # Check if a given list is a list of maps.
  1503. if all([issubclass(type(ele), AbstractMapDataset) for ele in tvarexpr]):
  1504. # Use method eval_map_list to evaluate map_list in comparison to thenlist.
  1505. resultlist = self.eval_map_list(tvarexpr, thenlist, topolist)
  1506. # Loop through the list, search for map lists or global variables.
  1507. for expr in tvarexpr:
  1508. if isinstance(expr, list):
  1509. if all([issubclass(type(ele), AbstractMapDataset) for ele in expr]):
  1510. # Use method eval_map_list to evaluate map_list
  1511. resultlist = self.eval_map_list(expr, thenlist, topolist)
  1512. else:
  1513. # Recursive function call to look into nested list elements.
  1514. self.build_condition_list(expr, thenlist)
  1515. elif isinstance(expr, GlobalTemporalVar):
  1516. # Use according functions for different global variable types.
  1517. if expr.get_type() == "operator":
  1518. if all(["condition_value" in dir(map_i) for map_i in thenlist]):
  1519. # Add operator string to the condition list.
  1520. [map_i.condition_value.extend(expr.get_type_value()) for map_i in thenlist]
  1521. if expr.get_type() == "global":
  1522. # Use method eval_global_var to evaluate expression.
  1523. resultlist = self.eval_global_var(expr, thenlist)
  1524. # Sort resulting list of maps chronological.
  1525. resultlist = sorted(resultlist, key = AbstractDatasetComparisonKeyStartTime)
  1526. return(resultlist)
  1527. def eval_condition_list(self, maplist, inverse = False):
  1528. """! This function evaluates conditional values of a map list.
  1529. A recursive function is used to evaluate comparison statements
  1530. from left to right in the given conditional list.
  1531. For example: [True, '||', False, '&&', True] -> True
  1532. [True, '||', False, '&&', False] -> False
  1533. [True, '&&', False, '&&', True] -> False
  1534. [False, '||', True, '||', False] -> True
  1535. [False, '&&', True, '&&', True] -> False
  1536. [True, '&&', True, '&&', True] -> True
  1537. [True, '&&', True] -> True
  1538. [True, '&&', False] -> False
  1539. [False, '||', True] -> True
  1540. @param tvarexpr List of GlobalTemporalVar objects and map lists.
  1541. The list is constructed by the TemporalAlgebraParser
  1542. in order of expression evaluation in the parser.
  1543. @return Map list with conditional values for all temporal expressions.
  1544. @code
  1545. >>> import grass.temporal as tgis
  1546. >>> tgis.init()
  1547. >>> p = tgis.TemporalAlgebraParser()
  1548. >>> # Example with two lists of maps
  1549. >>> # Create two list of maps with equal time stamps
  1550. >>> mapsA = []
  1551. >>> mapsB = []
  1552. >>> for i in range(10):
  1553. ... idA = "a%i@B"%(i)
  1554. ... mapA = tgis.RasterDataset(idA)
  1555. ... idB = "b%i@B"%(i)
  1556. ... mapB = tgis.RasterDataset(idB)
  1557. ... check = mapA.set_absolute_time(datetime(2000,1,i + 1),
  1558. ... datetime(2000,1,i + 2))
  1559. ... check = mapB.set_absolute_time(datetime(2000,1,i + 6),
  1560. ... datetime(2000,1,i + 7))
  1561. ... mapsA.append(mapA)
  1562. ... mapsB.append(mapB)
  1563. >>> mapsA = p.check_stds(mapsA)
  1564. >>> mapsB = p.check_stds(mapsB)
  1565. >>> # Create global expression object.
  1566. >>> gvarA = tgis.GlobalTemporalVar()
  1567. >>> gvarA.tfunc = "start_day"
  1568. >>> gvarA.compop = ">"
  1569. >>> gvarA.value = 5
  1570. >>> gvarB = tgis.GlobalTemporalVar()
  1571. >>> gvarB.tfunc = "start_day"
  1572. >>> gvarB.compop = "<="
  1573. >>> gvarB.value = 8
  1574. >>> gvarOP = tgis.GlobalTemporalVar()
  1575. >>> gvarOP.relationop = "&&"
  1576. >>> gvarOP.topology.append("EQUAL")
  1577. >>> tvarexpr = [mapsA, gvarOP,gvarA]
  1578. @endcode
  1579. """
  1580. def recurse_compare(conditionlist):
  1581. for ele in conditionlist:
  1582. if ele == '||':
  1583. ele_index = conditionlist.index(ele)
  1584. topolist = conditionlist.pop(ele_index -1)
  1585. right = conditionlist.pop(ele_index)
  1586. left = conditionlist.pop(ele_index - 2)
  1587. if any([left, right]):
  1588. result = True
  1589. else:
  1590. result = False
  1591. conditionlist[ele_index - 2] = result
  1592. recurse_compare(conditionlist)
  1593. if ele == '&&':
  1594. ele_index = conditionlist.index(ele)
  1595. topolist = conditionlist.pop(ele_index -1)
  1596. right = conditionlist.pop(ele_index)
  1597. left = conditionlist.pop(ele_index - 2)
  1598. if all([left, right]):
  1599. result = True
  1600. else:
  1601. result = False
  1602. conditionlist[ele_index - 2] = result
  1603. recurse_compare(conditionlist)
  1604. resultlist = conditionlist
  1605. return(resultlist)
  1606. resultlist = []
  1607. inverselist = []
  1608. for map_i in maplist:
  1609. if "condition_value" in dir(map_i):
  1610. # Get condition values from map object.
  1611. conditionlist = map_i.condition_value
  1612. #print(map_i.get_map_id() + ' ' + str(map_i.condition_value))
  1613. # Evaluate conditions in list with recursive function.
  1614. resultbool = recurse_compare(conditionlist)
  1615. # Set conditional value of map to resulting boolean.
  1616. map_i.condition_value = resultbool
  1617. # Add all maps that fulfill the conditions to result list.
  1618. if resultbool[0]:
  1619. resultlist.append(map_i)
  1620. else:
  1621. inverselist.append(map_i)
  1622. #print(map_i.get_map_id() + ' ' + str(map_i.condition_value))
  1623. if inverse:
  1624. return(inverselist)
  1625. else:
  1626. return(resultlist)
  1627. ###########################################################################
  1628. def p_statement_assign(self, t):
  1629. # The expression should always return a list of maps.
  1630. """
  1631. statement : stds EQUALS expr
  1632. """
  1633. if self.run:
  1634. resultstds = open_new_space_time_dataset(t[1], self.stdstype, \
  1635. self.temporaltype, "", "", \
  1636. 'mean', dbif=self.dbif, \
  1637. overwrite = self.overwrite)
  1638. if isinstance(t[3], list):
  1639. num = len(t[3])
  1640. count = 0
  1641. if num > 0:
  1642. dbif, connected = init_dbif(None)
  1643. for map in t[3]:
  1644. map.select(dbif=dbif)
  1645. #map.update()
  1646. resultstds.register_map(map, dbif=dbif)
  1647. count += 1
  1648. if count % 10 == 0:
  1649. self.msgr.percent(count, num, 1)
  1650. resultstds.update_from_registered_maps(dbif=dbif)
  1651. if connected:
  1652. dbif.close()
  1653. t[0] = t[3]
  1654. else:
  1655. t[0] = t[3]
  1656. if self.debug:
  1657. print t[1], "=", t[3]
  1658. def p_stds_1(self, t):
  1659. # Definition of a space time dataset
  1660. """
  1661. stds : NAME
  1662. """
  1663. t[0] = t[1]
  1664. def p_paren_expr(self, t):
  1665. """ expr : LPAREN expr RPAREN"""
  1666. t[0] = t[2]
  1667. def p_number(self,t):
  1668. """number : INT
  1669. | FLOAT
  1670. """
  1671. t[0] = t[1]
  1672. def p_t_hash(self,t):
  1673. """
  1674. t_hash_var : stds HASH stds
  1675. | stds HASH expr
  1676. | expr HASH stds
  1677. | expr HASH expr
  1678. """
  1679. if self.run:
  1680. maplistA = self.check_stds(t[1])
  1681. maplistB = self.check_stds(t[3])
  1682. resultlist = self.get_temporal_topo_list(maplistA, maplistB,
  1683. count_map = True)
  1684. t[0] = resultlist
  1685. def p_t_hash2(self,t):
  1686. """
  1687. t_hash_var : stds T_HASH_OPERATOR stds
  1688. | stds T_HASH_OPERATOR expr
  1689. | expr T_HASH_OPERATOR stds
  1690. | expr T_HASH_OPERATOR expr
  1691. """
  1692. if self.run:
  1693. maplistA = self.check_stds(t[1])
  1694. maplistB = self.check_stds(t[3])
  1695. topolist = self.eval_toperator(t[2])[0]
  1696. resultlist = self.get_temporal_topo_list(maplistA, maplistB, topolist,
  1697. count_map = True)
  1698. t[0] = resultlist
  1699. def p_t_td_var(self, t):
  1700. """
  1701. t_td_var : TD LPAREN stds RPAREN
  1702. | TD LPAREN expr RPAREN
  1703. """
  1704. if self.run:
  1705. maplist = self.check_stds(t[3])
  1706. for map_i in maplist:
  1707. if map_i.is_time_absolute:
  1708. start, end = map_i.get_absolute_time()
  1709. if end != None:
  1710. td = time_delta_to_relative_time(end - start)
  1711. else:
  1712. start, end, unit = current.get_relative_time()
  1713. if end != None:
  1714. td = end - start
  1715. if "map_value" in dir(map_i):
  1716. gvar = GlobalTemporalVar()
  1717. gvar.td = td
  1718. map_i.map_value.append(gvar)
  1719. else:
  1720. map_i.map_value = gvar
  1721. t[0] = maplist
  1722. else:
  1723. t[0] = "td(" + str(t[3]) + ")"
  1724. if self.debug:
  1725. print "td(" + str(t[3]) + ")"
  1726. def p_t_time_var(self, t):
  1727. # Temporal variables that return a double or integer value
  1728. """
  1729. t_var : START_DOY
  1730. | START_DOW
  1731. | START_YEAR
  1732. | START_MONTH
  1733. | START_WEEK
  1734. | START_DAY
  1735. | START_HOUR
  1736. | START_MINUTE
  1737. | START_SECOND
  1738. | END_DOY
  1739. | END_DOW
  1740. | END_YEAR
  1741. | END_MONTH
  1742. | END_WEEK
  1743. | END_DAY
  1744. | END_HOUR
  1745. | END_MINUTE
  1746. | END_SECOND
  1747. """
  1748. t[0] = t[1]
  1749. def p_compare_op(self, t):
  1750. # Compare operators that are supported for temporal expressions
  1751. """
  1752. comp_op : CEQUALS
  1753. | UNEQUALS
  1754. | LOWER
  1755. | LOWER_EQUALS
  1756. | GREATER
  1757. | GREATER_EQUALS
  1758. """
  1759. t[0] = t[1]
  1760. def p_t_var_expr(self, t):
  1761. # Examples:
  1762. # start_month() > 2
  1763. # start_day() < 14
  1764. # start_day() < start_month()
  1765. # td() < 31
  1766. """
  1767. t_var_expr : t_var LPAREN RPAREN comp_op number
  1768. | t_var LPAREN RPAREN comp_op t_var
  1769. | t_td_var comp_op number
  1770. | t_td_var comp_op t_var
  1771. | t_hash_var comp_op number
  1772. | t_hash_var comp_op t_var
  1773. """
  1774. if self.run:
  1775. if len(t) == 4:
  1776. maplist = self.check_stds(t[1])
  1777. comp_op = t[2]
  1778. for map_i in maplist:
  1779. for obj in map_i.map_value:
  1780. if isinstance(obj, GlobalTemporalVar):
  1781. td = obj.td
  1782. boolnum = eval(str(td) + comp_op + str(t[3]))
  1783. gvar = GlobalTemporalVar()
  1784. gvar.boolean = boolnum
  1785. if obj.get_type() == "timediff":
  1786. index = map_i.map_value.index(obj)
  1787. map_i.map_value[index] = gvar
  1788. t[0] = maplist
  1789. if len(t) == 6:
  1790. if isinstance(t[1], GlobalTemporalVar):
  1791. pass
  1792. gvar = GlobalTemporalVar()
  1793. gvar.tfunc = t[1]
  1794. gvar.compop = t[4]
  1795. gvar.value = t[5]
  1796. t[0] = gvar
  1797. else:
  1798. t[0] = True
  1799. if self.debug:
  1800. if len(t) == 6:
  1801. print t[1], t[4], t[5]
  1802. if len(t) == 4:
  1803. print t[1], t[2], t[3]
  1804. def p_t_var_expr_time1(self, t):
  1805. # Examples:
  1806. # start_time() == "12:30:00"
  1807. # start_date() <= "2001-01-01"
  1808. # start_datetime() > "2001-01-01 12:30:00"
  1809. """
  1810. t_var_expr : START_TIME LPAREN RPAREN comp_op TIME
  1811. | START_DATE LPAREN RPAREN comp_op DATE
  1812. | START_DATETIME LPAREN RPAREN comp_op DATETIME
  1813. | END_TIME LPAREN RPAREN comp_op TIME
  1814. | END_DATE LPAREN RPAREN comp_op DATE
  1815. | END_DATETIME LPAREN RPAREN comp_op DATETIME
  1816. """
  1817. if self.run:
  1818. gvar = GlobalTemporalVar()
  1819. gvar.tfunc = t[1]
  1820. gvar.compop = t[4]
  1821. gvar.value = t[5]
  1822. t[0] = gvar
  1823. else:
  1824. t[0] = True
  1825. if self.debug:
  1826. print t[1], t[4], t[5]
  1827. def p_t_var_expr_time2(self, t):
  1828. """
  1829. t_var_expr : TIME comp_op START_TIME LPAREN RPAREN
  1830. | DATE comp_op START_DATE LPAREN RPAREN
  1831. | DATETIME comp_op START_DATETIME LPAREN RPAREN
  1832. | TIME comp_op END_TIME LPAREN RPAREN
  1833. | DATE comp_op END_DATE LPAREN RPAREN
  1834. | DATETIME comp_op END_DATETIME LPAREN RPAREN
  1835. """
  1836. if self.run:
  1837. reverseop = {"<" : ">", ">" : "<", "<=" : ">=", ">=" : "<=",
  1838. "==" : "==", "!=" : "!="}
  1839. gvar = GlobalTemporalVar()
  1840. gvar.tfunc = t[3]
  1841. gvar.compop = reverseop[t[2]]
  1842. gvar.value = t[1]
  1843. t[0] = gvar
  1844. else:
  1845. t[0] = True
  1846. if self.debug:
  1847. print(t[4])
  1848. print t[1], t[4], t[5]
  1849. def p_t_var_expr_comp(self, t):
  1850. """
  1851. t_var_expr : t_var_expr AND AND t_var_expr
  1852. | t_var_expr OR OR t_var_expr
  1853. """
  1854. if self.run:
  1855. tvarexprA = t[1]
  1856. tvarexprB = t[4]
  1857. operator = GlobalTemporalVar()
  1858. operator.relationop = t[2] + t[3]
  1859. operator.topology.append("EQUAL")
  1860. resultlist = []
  1861. resultlist.append(tvarexprA)
  1862. resultlist.append(operator)
  1863. resultlist.append(tvarexprB)
  1864. t[0] = resultlist
  1865. else:
  1866. t[0] = True
  1867. if self.debug:
  1868. print t[1], t[2] + t[3], t[4]
  1869. def p_t_var_expr_comp_op(self, t):
  1870. """
  1871. t_var_expr : t_var_expr T_COMP_OPERATOR t_var_expr
  1872. """
  1873. if self.run:
  1874. tvarexprA = t[1]
  1875. tvarexprB = t[3]
  1876. operator = GlobalTemporalVar()
  1877. toperator = self.eval_toperator(t[2])[0]
  1878. relationop = toperator[2]
  1879. relations = toperator[0]
  1880. operator.relationop = relationop
  1881. operator.topology.extend(relations)
  1882. resultlist = []
  1883. resultlist.append(tvarexprA)
  1884. resultlist.append(operator)
  1885. resultlist.append(tvarexprB)
  1886. t[0] = resultlist
  1887. else:
  1888. t[0] = True
  1889. if self.debug:
  1890. print t[1], t[2], t[3]
  1891. def p_expr_t_select(self, t):
  1892. # Temporal equal selection
  1893. # The temporal topology relation equals is implicit
  1894. # Examples:
  1895. # A : B # Select the part of A that is temporally equal B
  1896. """
  1897. expr : stds T_SELECT stds
  1898. | expr T_SELECT stds
  1899. | stds T_SELECT expr
  1900. | expr T_SELECT expr
  1901. """
  1902. if self.run:
  1903. # Setup database connection.
  1904. # Check input stds.
  1905. maplistA = self.check_stds(t[1])
  1906. maplistB = self.check_stds(t[3])
  1907. # Perform selection.
  1908. selectlist = self.perform_temporal_selection(maplistA, maplistB)
  1909. # Return map list.
  1910. t[0] = selectlist
  1911. else:
  1912. t[0] = t[1] + "*"
  1913. if self.debug:
  1914. print t[1] + "* = ", t[1], t[2], t[3]
  1915. def p_expr_t_not_select(self, t):
  1916. # Temporal equal selection
  1917. # The temporal topology relation equals is implicit
  1918. # Examples:
  1919. # A !: B # Select the part of A that is temporally unequal to B
  1920. """
  1921. expr : stds T_NOT_SELECT stds
  1922. | expr T_NOT_SELECT stds
  1923. | stds T_NOT_SELECT expr
  1924. | expr T_NOT_SELECT expr
  1925. """
  1926. if self.run:
  1927. # Check input stds.
  1928. maplistA = self.check_stds(t[1])
  1929. maplistB = self.check_stds(t[3])
  1930. # Perform negative selection.
  1931. selectlist = self.perform_temporal_selection(maplistA, maplistB,
  1932. inverse = True)
  1933. # Return map list.
  1934. t[0] = selectlist
  1935. else:
  1936. t[0] = t[1] + "*"
  1937. if self.debug:
  1938. print t[1] + "* = ", t[1], t[2], t[3]
  1939. def p_expr_t_select_operator(self, t):
  1940. # Temporal equal selection
  1941. # The temporal topology relation equals is implicit
  1942. # Examples:
  1943. # A {!:} B # Select the part of A that is temporally unequal to B
  1944. # A {:} B # Select the part of A that is temporally equal B
  1945. # A {equals, !:} B # Select the part of A that is temporally unequal to B
  1946. # A {during, !:} B # Select the part of A that is temporally not during B
  1947. # A {overlaps, :} B # Select the part of A that temporally overlaps B
  1948. # A {overlaps|equals, :} B # Select the part of A that temporally overlaps or equals B
  1949. """
  1950. expr : stds T_SELECT_OPERATOR stds
  1951. | expr T_SELECT_OPERATOR stds
  1952. | stds T_SELECT_OPERATOR expr
  1953. | expr T_SELECT_OPERATOR expr
  1954. """
  1955. if self.run:
  1956. # Check input stds.
  1957. maplistA = self.check_stds(t[1])
  1958. maplistB = self.check_stds(t[3])
  1959. # Evaluate temporal operator.
  1960. operators = self.eval_toperator(t[2])
  1961. # Check for negative selection.
  1962. if operators[2] == "!:":
  1963. negation = True
  1964. else:
  1965. negation = False
  1966. # Perform selection.
  1967. selectlist = self.perform_temporal_selection(maplistA, maplistB,
  1968. topolist = operators[0], inverse = negation)
  1969. selectlist = self.set_granularity(selectlist, maplistB, operators[1],
  1970. operators[0])
  1971. # Return map list.
  1972. t[0] = selectlist
  1973. else:
  1974. t[0] = t[1] + "*"
  1975. if self.debug:
  1976. print t[1] + "* = ", t[1], t[2], t[3]
  1977. def p_expr_condition_if(self, t):
  1978. # Examples
  1979. # if( start_date() < "2005-06-01", A:B)
  1980. """
  1981. expr : IF LPAREN t_var_expr COMMA stds RPAREN
  1982. | IF LPAREN t_var_expr COMMA expr RPAREN
  1983. """
  1984. if self.run:
  1985. # Get stds/map list of then statement.
  1986. thenlist = self.check_stds(t[5])
  1987. # Get temporal conditional statement.
  1988. tvarexpr = t[3]
  1989. thencond = self.build_condition_list(tvarexpr, thenlist)
  1990. thenresult = self.eval_condition_list(thencond)
  1991. # Clear the map and conditional values of the map list.
  1992. resultlist = self.check_stds(thenresult, clear = True)
  1993. # Return resulting map list.
  1994. t[0] = resultlist
  1995. else:
  1996. t[0] = t[5] + "*"
  1997. if self.debug:
  1998. print str(t[5]) + "* = ", "if condition", str(t[3]), ' then ', str(t[5])
  1999. def p_expr_condition_if_relation(self, t):
  2000. # Examples
  2001. # if({equal} start_date() < "2005-06-01", A:B)
  2002. """
  2003. expr : IF LPAREN T_REL_OPERATOR COMMA t_var_expr COMMA stds RPAREN
  2004. | IF LPAREN T_REL_OPERATOR COMMA t_var_expr COMMA expr RPAREN
  2005. """
  2006. if self.run:
  2007. # Get stds/map list of then statement.
  2008. thenlist = self.check_stds(t[7])
  2009. # Get temporal conditional statement.
  2010. tvarexpr = t[5]
  2011. topolist = self.eval_toperator(t[3])[0]
  2012. thencond = self.build_condition_list(tvarexpr, thenlist, topolist)
  2013. thenresult = self.eval_condition_list(thencond)
  2014. # Clear the map and conditional values of the map list.
  2015. resultlist = self.check_stds(thenresult, clear = True)
  2016. # Return resulting map list.
  2017. t[0] = resultlist
  2018. else:
  2019. t[0] = t[7] + "*"
  2020. if self.debug:
  2021. print "result* = ", "if ", str(t[3]), "condition", str(t[5]), " then ", str(t[7])
  2022. def p_expr_condition_elif(self, t):
  2023. # Examples
  2024. # if( start_date() < "2005-06-01", if(start_time() < "12:30:00", A:B), A!:B)
  2025. """
  2026. expr : IF LPAREN t_var_expr COMMA stds COMMA stds RPAREN
  2027. | IF LPAREN t_var_expr COMMA stds COMMA expr RPAREN
  2028. | IF LPAREN t_var_expr COMMA expr COMMA stds RPAREN
  2029. | IF LPAREN t_var_expr COMMA expr COMMA expr RPAREN
  2030. """
  2031. if self.run:
  2032. # Get stds/map list of then statement.
  2033. thenlist = self.check_stds(t[5])
  2034. elselist = self.check_stds(t[7])
  2035. # Get temporal conditional statement for then and else expressions.
  2036. tvarexpr = t[3]
  2037. thencond = self.build_condition_list(tvarexpr, thenlist)
  2038. thenresult = self.eval_condition_list(thencond)
  2039. elsecond = self.build_condition_list(tvarexpr, elselist)
  2040. elseresult = self.eval_condition_list(elsecond, inverse = True)
  2041. # Combine and sort else and then statement to result map list.
  2042. combilist = thenresult + elseresult
  2043. resultlist = sorted(combilist, key = AbstractDatasetComparisonKeyStartTime)
  2044. # Clear the map and conditional values of the map list.
  2045. resultlist = self.check_stds(resultlist, clear = True)
  2046. # Return resulting map list.
  2047. t[0] = resultlist
  2048. else:
  2049. t[0] = t[5] + "*"
  2050. if self.debug:
  2051. print str(t[5]) + "* = ", "if condition", str(t[3]), " then ", str(t[5]), ' else ', str(t[7])
  2052. def p_expr_condition_elif_relation(self, t):
  2053. # Examples
  2054. # if({equal}, start_date() < "2005-06-01", if(start_time() < "12:30:00", A:B), A!:B)
  2055. # The then and else statement using the same topological relationships.
  2056. # Feature request: Independent relationships for then and else to conditions.
  2057. """
  2058. expr : IF LPAREN T_REL_OPERATOR COMMA t_var_expr COMMA stds COMMA stds RPAREN
  2059. | IF LPAREN T_REL_OPERATOR COMMA t_var_expr COMMA stds COMMA expr RPAREN
  2060. | IF LPAREN T_REL_OPERATOR COMMA t_var_expr COMMA expr COMMA stds RPAREN
  2061. | IF LPAREN T_REL_OPERATOR COMMA t_var_expr COMMA expr COMMA expr RPAREN
  2062. """
  2063. if self.run:
  2064. # Get stds/map list of then statement.
  2065. thenlist = self.check_stds(t[7])
  2066. elselist = self.check_stds(t[9])
  2067. # Get temporal conditional statement.
  2068. tvarexpr = t[5]
  2069. topolist = self.eval_toperator(t[3])[0]
  2070. thencond = self.build_condition_list(tvarexpr, thenlist, topolist)
  2071. thenresult = self.eval_condition_list(thencond)
  2072. elsecond = self.build_condition_list(tvarexpr, elselist, topolist)
  2073. elseresult = self.eval_condition_list(elsecond, inverse = True)
  2074. # Combine and sort else and then statement to result map list.
  2075. combilist = thenresult + elseresult
  2076. resultlist = sorted(combilist, key = AbstractDatasetComparisonKeyStartTime)
  2077. # Clear the map and conditional values of the map list.
  2078. resultlist = self.check_stds(resultlist, clear = True)
  2079. # Return resulting map list.
  2080. t[0] = resultlist
  2081. else:
  2082. if t[5]:
  2083. t[0] = str(t[7])
  2084. else:
  2085. t[0] = str(t[9])
  2086. if self.debug:
  2087. if t[5]:
  2088. print str(t[7]), "* = ", "if condition", str(t[5]), " then ", str(t[7]), ' else ', str(t[9])
  2089. else:
  2090. print str(t[9]), "* = ", "if condition", str(t[5]), " then ", str(t[7]), ' else ', str(t[9])
  2091. def p_expr_t_buff(self, t):
  2092. # Examples
  2093. # buff_t(A : B, "10 minutes") # Select the part of A that is temporally
  2094. # equal to B and create a buffer of 10 minutes around
  2095. """
  2096. expr : BUFF_T LPAREN stds COMMA QUOTE number NAME QUOTE RPAREN
  2097. | BUFF_T LPAREN expr COMMA QUOTE number NAME QUOTE RPAREN
  2098. | BUFF_T LPAREN stds COMMA number RPAREN
  2099. | BUFF_T LPAREN expr COMMA number RPAREN
  2100. """
  2101. if self.run:
  2102. # Check input stds.
  2103. bufflist = self.check_stds(t[3])
  2104. for map in bufflist:
  2105. # Get increment format.
  2106. if len(t) == 10:
  2107. increment = str(t[6]) + " " + t[7]
  2108. elif len(t) == 7:
  2109. increment = str(t[5])
  2110. # Perform buffering.
  2111. map.temporal_buffer(increment)
  2112. t[0] = bufflist
  2113. else:
  2114. t[0] = t[3] + "*"
  2115. if self.debug:
  2116. if len(t) == 10:
  2117. print str(t[3]) + "* = buff_t(", str(t[3]), "," , '"', str(t[6]), str(t[7]), '"', ")"
  2118. elif len(t) == 7:
  2119. print str(t[3]) + "* = buff_t(", str(t[3]), ",", str(t[5]), ")"
  2120. def p_expr_t_snap(self, t):
  2121. # Examples
  2122. # tsnap(A : B) # Snap the maps of A temporally.
  2123. """
  2124. expr : TSNAP LPAREN stds RPAREN
  2125. | TSNAP LPAREN expr RPAREN
  2126. """
  2127. if self.run:
  2128. # Check input stds.
  2129. maplist = self.check_stds(t[3])
  2130. # Perform snapping.
  2131. snaplist = AbstractSpaceTimeDataset.snap_map_list(maplist)
  2132. t[0] = snaplist
  2133. else:
  2134. t[0] = t[3] + "*"
  2135. if self.debug:
  2136. print str(t[3]) + "* = tsnap(", str(t[3]), ")"
  2137. def p_expr_t_shift(self, t):
  2138. # Examples
  2139. # tshift(A : B, "10 minutes") # Shift the selection from A temporally
  2140. # by 10 minutes.
  2141. """
  2142. expr : TSHIFT LPAREN stds COMMA QUOTE number NAME QUOTE RPAREN
  2143. | TSHIFT LPAREN expr COMMA QUOTE number NAME QUOTE RPAREN
  2144. | TSHIFT LPAREN stds COMMA number RPAREN
  2145. | TSHIFT LPAREN expr COMMA number RPAREN
  2146. """
  2147. if self.run:
  2148. # Check input stds.
  2149. maplist = self.check_stds(t[3])
  2150. # Get increment format.
  2151. if len(t) == 10:
  2152. increment = str(t[6]) + " " + t[7]
  2153. elif len(t) == 7:
  2154. increment = str(t[5])
  2155. # Perform shifting.
  2156. shiftlist = AbstractSpaceTimeDataset.shift_map_list(maplist, increment)
  2157. t[0] = shiftlist
  2158. else:
  2159. t[0] = t[3] + "*"
  2160. if self.debug:
  2161. if len(t) == 10:
  2162. print str(t[3]) + "* = tshift(", str(t[3]), "," , '"', str(t[6]), str(t[7]), '"', ")"
  2163. elif len(t) == 7:
  2164. print str(t[3]) + "* = tshift(", str(t[3]), ",", str(t[5]), ")"
  2165. # Handle errors.
  2166. def p_error(self, t):
  2167. if t:
  2168. raise SyntaxError("syntax error on line %d, token %s near '%s' expression '%s'" %
  2169. (t.lineno, t.type, t.value, self.expression))
  2170. else:
  2171. raise SyntaxError("Unexpected syntax error")
  2172. ###############################################################################
  2173. if __name__ == "__main__":
  2174. import doctest
  2175. doctest.testmod()