temporal_raster_base_algebra.py 77 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834
  1. """@package grass.temporal
  2. Temporal raster algebra
  3. (C) 2013 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-block:: python
  9. >>> p = TemporalRasterAlgebraLexer()
  10. >>> p.build()
  11. >>> p.debug = True
  12. >>> expression = 'R = A {+,equal,l} B'
  13. >>> p.test(expression)
  14. R = A {+,equal,l} B
  15. LexToken(NAME,'R',1,0)
  16. LexToken(EQUALS,'=',1,2)
  17. LexToken(NAME,'A',1,4)
  18. LexToken(T_ARITH2_OPERATOR,'{+,equal,l}',1,6)
  19. LexToken(NAME,'B',1,18)
  20. >>> expression = 'R = A {*,equal|during,r} B'
  21. >>> p.test(expression)
  22. R = A {*,equal|during,r} B
  23. LexToken(NAME,'R',1,0)
  24. LexToken(EQUALS,'=',1,2)
  25. LexToken(NAME,'A',1,4)
  26. LexToken(T_ARITH1_OPERATOR,'{*,equal|during,r}',1,6)
  27. LexToken(NAME,'B',1,25)
  28. >>> expression = 'R = A {+,equal|during} B'
  29. >>> p.test(expression)
  30. R = A {+,equal|during} B
  31. LexToken(NAME,'R',1,0)
  32. LexToken(EQUALS,'=',1,2)
  33. LexToken(NAME,'A',1,4)
  34. LexToken(T_ARITH2_OPERATOR,'{+,equal|during}',1,6)
  35. LexToken(NAME,'B',1,23)
  36. """
  37. from __future__ import print_function
  38. try:
  39. import ply.lex as lex
  40. import ply.yacc as yacc
  41. except:
  42. pass
  43. import copy
  44. import grass.pygrass.modules as pymod
  45. from grass.exceptions import FatalError
  46. from .temporal_algebra import TemporalAlgebraLexer, TemporalAlgebraParser, GlobalTemporalVar
  47. from .core import init_dbif
  48. from .abstract_dataset import AbstractDatasetComparisonKeyStartTime
  49. from .factory import dataset_factory
  50. from .open_stds import open_new_stds
  51. from spatio_temporal_relationships import SpatioTemporalTopologyBuilder
  52. from .space_time_datasets import Raster3DDataset, RasterDataset
  53. ##############################################################################
  54. class TemporalRasterAlgebraLexer(TemporalAlgebraLexer):
  55. """Lexical analyzer for the GRASS GIS temporal algebra"""
  56. def __init__(self):
  57. TemporalAlgebraLexer.__init__(self)
  58. # Supported r.mapcalc functions.
  59. mapcalc_functions = {
  60. 'exp' : 'EXP',
  61. 'log' : 'LOG',
  62. 'sqrt' : 'SQRT',
  63. 'abs' : 'ABS',
  64. 'cos' : 'COS',
  65. 'acos' : 'ACOS',
  66. 'sin' : 'SIN',
  67. 'asin' : 'ASIN',
  68. 'tan' : 'TAN',
  69. 'double' : 'DOUBLE',
  70. 'float' : 'FLOATEXP',
  71. 'int' : 'INTEXP',
  72. 'isnull' : 'ISNULL',
  73. 'isntnull': 'ISNTNULL',
  74. 'null' : 'NULL',
  75. 'exist' : 'EXIST',
  76. }
  77. # Functions that defines single maps with time stamp and without temporal extent.
  78. map_functions = {'map' : 'MAP'}
  79. # This is the list of token names.
  80. raster_tokens = (
  81. 'MOD',
  82. 'DIV',
  83. 'MULT',
  84. 'ADD',
  85. 'SUB',
  86. 'T_ARITH1_OPERATOR',
  87. 'T_ARITH2_OPERATOR',
  88. 'L_SPAREN',
  89. 'R_SPAREN',
  90. )
  91. # Build the token list
  92. tokens = TemporalAlgebraLexer.tokens \
  93. + raster_tokens \
  94. + tuple(mapcalc_functions.values()) \
  95. + tuple(map_functions.values())
  96. # Regular expression rules for simple tokens
  97. t_MOD = r'[\%]'
  98. t_DIV = r'[\/]'
  99. t_MULT = r'[\*]'
  100. t_ADD = r'[\+]'
  101. t_SUB = r'[-]'
  102. t_T_ARITH1_OPERATOR = r'\{[\%\*\/][,]?[a-zA-Z\| ]*([,])?([lrudi]|left|right|union|disjoint|intersect)?\}'
  103. t_T_ARITH2_OPERATOR = r'\{[+-][,]?[a-zA-Z\| ]*([,])?([lrudi]|left|right|union|disjoint|intersect)?\}'
  104. t_L_SPAREN = r'\['
  105. t_R_SPAREN = r'\]'
  106. # Parse symbols
  107. def temporal_symbol(self, t):
  108. # Check for reserved words
  109. if t.value in TemporalRasterAlgebraLexer.time_functions.keys():
  110. t.type = TemporalRasterAlgebraLexer.time_functions.get(t.value)
  111. elif t.value in TemporalRasterAlgebraLexer.datetime_functions.keys():
  112. t.type = TemporalRasterAlgebraLexer.datetime_functions.get(t.value)
  113. elif t.value in TemporalRasterAlgebraLexer.conditional_functions.keys():
  114. t.type = TemporalRasterAlgebraLexer.conditional_functions.get(t.value)
  115. elif t.value in TemporalRasterAlgebraLexer.mapcalc_functions.keys():
  116. t.type = TemporalRasterAlgebraLexer.mapcalc_functions.get(t.value)
  117. elif t.value in TemporalRasterAlgebraLexer.map_functions.keys():
  118. t.type = TemporalRasterAlgebraLexer.map_functions.get(t.value)
  119. else:
  120. t.type = 'NAME'
  121. return t
  122. ##############################################################################
  123. class TemporalRasterBaseAlgebraParser(TemporalAlgebraParser):
  124. """The temporal algebra class"""
  125. # Get the tokens from the lexer class
  126. tokens = TemporalRasterAlgebraLexer.tokens
  127. # Setting equal precedence level for select and hash operations.
  128. precedence = (
  129. ('left', 'T_SELECT_OPERATOR', 'T_SELECT', 'T_NOT_SELECT'), # 1
  130. ('left', 'ADD', 'SUB', 'T_ARITH2_OPERATOR', 'T_HASH_OPERATOR', 'HASH'), #2
  131. ('left', 'AND', 'OR', 'T_COMP_OPERATOR', 'MOD', 'DIV', 'MULT',
  132. 'T_ARITH1_OPERATOR'))
  133. def __init__(self, pid=None, run=True,
  134. debug=False, spatial=False,
  135. register_null=False,
  136. dry_run=False, nprocs=1):
  137. TemporalAlgebraParser.__init__(self,
  138. pid=pid,
  139. run=run,
  140. debug=debug,
  141. spatial=spatial,
  142. register_null=register_null,
  143. dry_run=dry_run,
  144. nprocs=nprocs)
  145. def check_null(self, t):
  146. try:
  147. int(t)
  148. return t
  149. except ValueError:
  150. return "null()"
  151. ######################### Temporal functions ##############################
  152. def build_spatio_temporal_topology_list(self, maplistA, maplistB=None, topolist=["EQUAL"],
  153. assign_val=False, count_map=False, compare_bool=False,
  154. compare_cmd=False, compop=None, aggregate=None,
  155. new=False, convert=False, operator_cmd=False):
  156. """Build temporal topology for two space time data sets, copy map objects
  157. for given relation into map list.
  158. :param maplistA: List of maps.
  159. :param maplistB: List of maps.
  160. :param topolist: List of strings of temporal relations.
  161. :param assign_val: Boolean for assigning a boolean map value based on
  162. the map_values from the compared map list by
  163. topological relationships.
  164. :param count_map: Boolean if the number of topological related maps
  165. should be returned.
  166. :param compare_bool: Boolean for comparing boolean map values based on
  167. related map list and compariosn operator.
  168. :param compare_cmd: Boolean for comparing command list values based on
  169. related map list and compariosn operator.
  170. :param compop: Comparison operator, && or ||.
  171. :param aggregate: Aggregation operator for relation map list, & or |.
  172. :param new: Boolean if new temporary maps should be created.
  173. :param convert: Boolean if conditional values should be converted to
  174. r.mapcalc command strings.
  175. :param operator_cmd: Boolean for aggregate arithmetic operators implicitly
  176. in command list values based on related map lists.
  177. :return: List of maps from maplistA that fulfil the topological relationships
  178. to maplistB specified in topolist.
  179. >>> # Create two list of maps with equal time stamps
  180. >>> from datetime import datetime
  181. >>> import grass.temporal as tgis
  182. >>> tgis.init(True)
  183. >>> l = tgis.TemporalAlgebraParser()
  184. >>> mapsA = []
  185. >>> mapsB = []
  186. >>> for i in range(10):
  187. ... idA = "a%i@B"%(i)
  188. ... mapA = tgis.RasterDataset(idA)
  189. ... mapA.uid = idA
  190. ... mapA.map_value = True
  191. ... idB = "b%i@B"%(i)
  192. ... mapB = tgis.RasterDataset(idB)
  193. ... mapB.uid = idB
  194. ... mapB.map_value = False
  195. ... check = mapA.set_absolute_time(datetime(2000,1,i+1),
  196. ... datetime(2000,1,i + 2))
  197. ... check = mapB.set_absolute_time(datetime(2000,1,i+6),
  198. ... datetime(2000,1,i + 7))
  199. ... mapsA.append(mapA)
  200. ... mapsB.append(mapB)
  201. >>> resultlist = l.build_spatio_temporal_topology_list(mapsA, mapsB)
  202. >>> for map in resultlist:
  203. ... print(map.get_id())
  204. a5@B
  205. a6@B
  206. a7@B
  207. a8@B
  208. a9@B
  209. """
  210. print(topolist, assign_val, count_map, compare_bool, compare_cmd,
  211. compop, aggregate, new, convert, operator_cmd)
  212. # Check the topology definitions and return the list of temporal and spatial
  213. # topological relations that must be fulfilled
  214. temporal_topo_list, spatial_topo_list = self._check_topology(topolist=topolist)
  215. resultdict = {}
  216. # Create temporal topology for maplistA to maplistB.
  217. tb = SpatioTemporalTopologyBuilder()
  218. # Build spatio-temporal topology
  219. if len(spatial_topo_list) > 0:
  220. # Dictionary with different spatial variables used for topology builder.
  221. spatialdict = {'strds' : '2D', 'stvds' : '2D', 'str3ds' : '3D'}
  222. tb.build(maplistA, maplistB, spatial=spatialdict[self.stdstype])
  223. else:
  224. tb.build(maplistA, maplistB)
  225. # Iterate through maps in maplistA and search for relationships given
  226. # in topolist.
  227. for map_i in maplistA:
  228. if assign_val:
  229. self.assign_bool_value(map_i, temporal_topo_list, spatial_topo_list)
  230. elif compare_bool:
  231. self.compare_bool_value(map_i, compop, aggregate, temporal_topo_list, spatial_topo_list)
  232. elif compare_cmd:
  233. self.compare_cmd_value(map_i, compop, aggregate, temporal_topo_list, spatial_topo_list, convert)
  234. elif operator_cmd:
  235. self.operator_cmd_value(map_i, compop, temporal_topo_list, spatial_topo_list)
  236. temporal_relations = map_i.get_temporal_relations()
  237. spatial_relations = map_i.get_spatial_relations()
  238. for temporal_topology in temporal_topo_list:
  239. if temporal_topology.upper() in temporal_relations.keys():
  240. if self._check_spatial_topology_entries(spatial_topo_list, spatial_relations) is True:
  241. if count_map:
  242. relationmaplist = temporal_relations[temporal_topology.upper()]
  243. gvar = GlobalTemporalVar()
  244. gvar.td = len(relationmaplist)
  245. if "map_value" in dir(map_i):
  246. map_i.map_value.append(gvar)
  247. else:
  248. map_i.map_value = gvar
  249. # Use unique identifier, since map names may be equal
  250. resultdict[map_i.uid] = map_i
  251. # map_i.print_info()
  252. resultlist = resultdict.values()
  253. # Sort list of maps chronological.
  254. resultlist = sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime)
  255. return(resultlist)
  256. def build_command_string(self, map_i, relmap, operator = None, cmd_type = None):
  257. """This function build the r.mapcalc command string for conditionals,
  258. spatial variable combinations and boolean comparisons.
  259. For Example: 'if(a1 == 1, b1, c2)' or 'exist(a1) && sin(b1)'
  260. :param map_i: map object with temporal extent and built relations.
  261. :param relmap: map object with defined temporal relation to map_i.
  262. :param operator: String representing operator between two spatial variables
  263. (&&,||,+,-,*,/).
  264. :param cmd_type: map object with defined temporal relation to map_i:
  265. condition, conclusion or operator.
  266. :return: the resulting command string for conditionals or spatial variable
  267. combinations
  268. """
  269. def sub_cmdstring(map_i):
  270. """This function search for command string in a map object and
  271. return substitute string (contained commandstring or map name)"""
  272. if "cmd_list" in dir(map_i):
  273. map_sub = map_i.cmd_list
  274. elif "map_value" in dir(map_i) and len(map_i.map_value) > 0 and map_i.map_value[0].get_type() == "timediff":
  275. map_sub = map_i.map_value[0].get_type_value()[0]
  276. else:
  277. try:
  278. map_sub = map_i.get_id()
  279. except:
  280. map_sub = map_i
  281. return(map_sub)
  282. # Check for type of operation, conditional or spatial variable combination
  283. # and Create r.mapcalc expression string for the operation.
  284. cmdstring = ""
  285. if cmd_type == 'condition':
  286. conditionsub = sub_cmdstring(map_i)
  287. conclusionsub = sub_cmdstring(relmap)
  288. cmdstring = "if(%s, %s)" %(conditionsub, conclusionsub)
  289. elif cmd_type == 'conclusion':
  290. thensub = sub_cmdstring(map_i)
  291. elsesub = sub_cmdstring(relmap)
  292. cmdstring = "%s, %s" %(thensub, elsesub)
  293. elif cmd_type == 'operator':
  294. leftsub = sub_cmdstring(map_i)
  295. rightsub = sub_cmdstring(relmap)
  296. if operator == None:
  297. self.msgr.fatal("Error: Can't build command string for map %s, operator is missing"
  298. %(map_i.get_map_id()))
  299. cmdstring = "(%s %s %s)" %(leftsub, operator, rightsub)
  300. return(cmdstring)
  301. def compare_cmd_value(self, map_i, compop, aggregate,
  302. temporal_topo_list = ["EQUAL"],
  303. spatial_topo_list = [], convert = False):
  304. """ Function to evaluate two map lists with boolean values by boolean
  305. comparison operator.
  306. R = A && B
  307. R = if(A < 1 && B > 1, A, B)
  308. R = if(A < 1 {&&,equal|equivalent} B > 1, A, B)
  309. Extended temporal algebra version with command
  310. list builder for temporal raster algebra.
  311. :param map_i: Map object with temporal extent.
  312. :param temporal_relations: List of temporal relation to map_i.
  313. :param temporal_topo_list: List of strings for given temporal relations.
  314. :param compop: Comparison operator, && or ||.
  315. :param aggregate: Aggregation operator for relation map list, & or |.
  316. :param convert: Boolean if conditional values should be converted to
  317. r.mapcalc command strings.
  318. :return: Map object with conditional value that has been evaluated by
  319. comparison operators.
  320. """
  321. # Build command list list with elements from related maps and given relation operator.
  322. if convert and "condition_value" in dir(map_i):
  323. if map_i.condition_value != []:
  324. cmdstring = str(int(map_i.condition_value[0]))
  325. map_i.cmd_list = cmdstring
  326. if "cmd_list" in dir(map_i):
  327. leftcmd = map_i.cmd_list
  328. cmd_value_list = [leftcmd]
  329. count = 0
  330. temporal_relations = map_i.get_temporal_relations()
  331. for topo in temporal_topo_list:
  332. if topo.upper() in temporal_relations.keys():
  333. relationmaplist = temporal_relations[topo.upper()]
  334. if count == 0 and "cmd_list" in dir(map_i):
  335. cmd_value_list.append(compop)
  336. cmd_value_list.append('(')
  337. for relationmap in relationmaplist:
  338. if self._check_spatial_topology_relation(spatial_topo_list, map_i, relationmap) is True:
  339. if convert and "condition_value" in dir(relationmap):
  340. if relationmap.condition_value != []:
  341. cmdstring = str(int(relationmap.condition_value[0]))
  342. relationmap.cmd_list = cmdstring
  343. if "cmd_list" in dir(relationmap):
  344. if count > 0:
  345. cmd_value_list.append(aggregate + aggregate)
  346. cmd_value_list.append(relationmap.cmd_list)
  347. count = count + 1
  348. if self.debug:
  349. print("compare_cmd_value", map_i.get_id(),
  350. relationmap.get_id(), relationmap.cmd_list)
  351. if count > 0:
  352. cmd_value_list.append(')')
  353. cmd_value_str = ''.join(map(str, cmd_value_list))
  354. # Add command list to result map.
  355. map_i.cmd_list = cmd_value_str
  356. print(cmd_value_str)
  357. return(cmd_value_str)
  358. def operator_cmd_value(self, map_i, operator,
  359. temporal_topo_list = ["EQUAL"],
  360. spatial_topo_list = []):
  361. """ Function to evaluate two map lists by given arithmetic operator.
  362. :param map_i: Map object with temporal extent.
  363. :param operator: Arithmetic operator, +-*/%.
  364. :param temporal_topo_list: List of strings for given temporal relations.
  365. :param spatial_topo_list: List of strings for given spatial relations.
  366. :return: Map object with command list with operators that has been
  367. evaluated by implicit aggregation.
  368. """
  369. temporal_relations = map_i.get_temporal_relations()
  370. spatial_relations = map_i.get_spatial_relations()
  371. # Build comandlist list with elements from related maps and given relation operator.
  372. leftcmd = map_i
  373. cmdstring = ""
  374. for topo in temporal_topo_list:
  375. if topo.upper() in temporal_relations.keys():
  376. relationmaplist = temporal_relations[topo.upper()]
  377. for relationmap in relationmaplist:
  378. if self._check_spatial_topology_relation(spatial_topo_list, map_i, relationmap) is True:
  379. # Create r.mapcalc expression string for the operation.
  380. cmdstring = self.build_command_string(leftcmd,
  381. relationmap,
  382. operator=operator,
  383. cmd_type="operator")
  384. leftcmd = cmdstring
  385. if self.debug:
  386. print("operator_cmd_value", map_i.get_id(), operator, relationmap.get_id())
  387. # Add command list to result map.
  388. map_i.cmd_list = cmdstring
  389. print("map command string", cmdstring)
  390. return(cmdstring)
  391. def set_temporal_extent_list(self, maplist, topolist=["EQUAL"], temporal='l' ,
  392. cmd_bool=False, cmd_type=None, operator=None):
  393. """ Change temporal extent of map list based on temporal relations to
  394. other map list and given temporal operator.
  395. :param maplist: List of map objects for which relations has been build
  396. correctly.
  397. :param topolist: List of strings of temporal relations.
  398. :param temporal: The temporal operator specifying the temporal
  399. extent operation (intersection, union, disjoint
  400. union, right reference, left reference).
  401. :param cmd_bool: Boolean if command string should be merged for related maps.
  402. :param cmd_type: map object with defined temporal relation to map_i:
  403. condition, conclusion or operator.
  404. :param operator: String defining the type of operator.
  405. :return: Map list with specified temporal extent and optional command string.
  406. """
  407. resultdict = {}
  408. temporal_topo_list, spatial_topo_list = self._check_topology(topolist=topolist)
  409. for map_i in maplist:
  410. # Loop over temporal related maps and create overlay modules.
  411. tbrelations = map_i.get_temporal_relations()
  412. # Generate an intermediate map for the result map list.
  413. map_new = self.generate_new_map(base_map=map_i,
  414. bool_op='and',
  415. copy=True,
  416. rename=True)
  417. # Combine temporal and spatial extents of intermediate map with related maps.
  418. for topo in topolist:
  419. if topo in tbrelations.keys():
  420. for map_j in (tbrelations[topo]):
  421. if self._check_spatial_topology_relation(spatial_topo_list, map_i, map_j) is True:
  422. if temporal == 'r':
  423. # Generate an intermediate map for the result map list.
  424. map_new = self.generate_new_map(base_map=map_i,
  425. bool_op='and',
  426. copy=True,
  427. rename=True)
  428. # Create overlaid map extent.
  429. returncode = self.overlay_map_extent(map_new, map_j,
  430. 'and',
  431. temp_op=temporal)
  432. # Stop the loop if no temporal or spatial relationship exist.
  433. if returncode == 0:
  434. break
  435. # Append map to result map list.
  436. elif returncode == 1:
  437. # print(map_new.cmd_list)
  438. # resultlist.append(map_new)
  439. if cmd_bool:
  440. # Create r.mapcalc expression string for the operation.
  441. cmdstring = self.build_command_string(map_i,
  442. map_j,
  443. operator=operator,
  444. cmd_type=cmd_type)
  445. # Conditional append of module command.
  446. map_new.cmd_list = cmdstring
  447. # Write map object to result dictionary.
  448. resultdict[map_new.uid] = map_new
  449. if returncode == 0:
  450. break
  451. # Append map to result map list.
  452. #if returncode == 1:
  453. # resultlist.append(map_new)
  454. # Get sorted map objects as values from result dictionoary.
  455. resultlist = resultdict.values()
  456. resultlist = sorted(resultlist, key = AbstractDatasetComparisonKeyStartTime)
  457. return(resultlist)
  458. def build_condition_cmd_list(self, iflist, thenlist, elselist=None,
  459. condition_topolist=["EQUAL"],
  460. conclusion_topolist=["EQUAL"],
  461. temporal='l', null=False):
  462. """This function build the r.mapcalc command strings for spatial conditionals.
  463. For Example: 'if(a1 == 1, b1, c2)'
  464. :param iflist: Map list with temporal extents and command list.
  465. :param thenlist: Map list with temporal extents and command list or numeric string.
  466. :param elselist: Map list with temporal extents and command list or numeric string.
  467. :param condition_topolist: List of strings for given temporal relations between
  468. conditions and conclusions.
  469. :param conclusion_topolist: List of strings for given temporal relations between
  470. conditions (then and else).
  471. :param temporal: The temporal operator specifying the temporal
  472. extent operation (intersection, union, disjoint
  473. union, right reference, left reference).
  474. :param null: Boolean if null map support should be activated.
  475. :return: map list with resulting command string for given condition type.
  476. """
  477. resultlist = []
  478. # First merge conclusion command maplists or strings.
  479. # Check if alternative conclusion map list is given.
  480. if all([isinstance(thenlist, list), isinstance(elselist, list)]):
  481. # Build conclusion command map list.
  482. conclusiontopolist = self.build_spatio_temporal_topology_list(thenlist, elselist,
  483. conclusion_topolist)
  484. conclusionlist = self.set_temporal_extent_list(conclusiontopolist,
  485. topolist=conclusion_topolist,
  486. temporal=temporal ,
  487. cmd_bool=True,
  488. cmd_type="conclusion")
  489. # Check if any conclusion is a numeric statements.
  490. elif any([isinstance(thenlist, str), isinstance(elselist, str)]):
  491. conclusionlist = []
  492. # Check if only alternative conclusion is a numeric statements.
  493. if all([isinstance(thenlist, list), isinstance(elselist, str)]):
  494. listinput = thenlist
  495. numinput = elselist
  496. for map_i in listinput:
  497. # Create r.mapcalc expression string for the operation.
  498. cmdstring = self.build_command_string(map_i,
  499. numinput,
  500. cmd_type='conclusion')
  501. # Conditional append of module command.
  502. map_i.cmd_list = cmdstring
  503. # Append map to result map list.
  504. conclusionlist.append(map_i)
  505. # Check if only direct conclusion is a numeric statements.
  506. elif all([isinstance(thenlist, str), isinstance(elselist, list)]):
  507. listinput = elselist
  508. numinput = thenlist
  509. for map_i in listinput:
  510. # Create r.mapcalc expression string for the operation.
  511. cmdstring = self.build_command_string(numinput,
  512. map_i,
  513. cmd_type='conclusion')
  514. # Conditional append of module command.
  515. map_i.cmd_list = cmdstring
  516. # Append map to result map list.
  517. conclusionlist.append(map_i)
  518. elif all([isinstance(thenlist, str), isinstance(elselist, str)]):
  519. conclusionlist = thenlist + ',' + elselist
  520. else:
  521. # The direct conclusion is used.
  522. conclusionlist = thenlist
  523. # Use the conclusion map or string to merge it with the condition and
  524. # return maplist.
  525. if isinstance(conclusionlist, str):
  526. resultlist = []
  527. for map_i in iflist:
  528. # Create r.mapcalc expression string for the operation.
  529. cmdstring = self.build_command_string(map_i,
  530. conclusionlist,
  531. cmd_type='condition')
  532. # Conditional append of module command.
  533. map_i.cmd_list = cmdstring
  534. # Append map to result map list.
  535. resultlist.append(map_i)
  536. return(resultlist)
  537. elif isinstance(conclusionlist, list):
  538. # Build result command map list between conditions and conclusions.
  539. print("build_condition_cmd_list", condition_topolist)
  540. conditiontopolist = self.build_spatio_temporal_topology_list(iflist,
  541. conclusionlist,
  542. topolist=condition_topolist)
  543. resultlist = self.set_temporal_extent_list(conditiontopolist,
  544. topolist=condition_topolist,
  545. temporal='r',
  546. cmd_bool=True,
  547. cmd_type="condition")
  548. return(resultlist)
  549. ###########################################################################
  550. def p_statement_assign(self, t):
  551. # This function executes the processing of raster/raster3d algebra
  552. # that was build based on the expression
  553. """
  554. statement : stds EQUALS expr
  555. """
  556. if self.run:
  557. # Create the process queue for parallel mapcalc processing
  558. if self.dry_run is False:
  559. process_queue = pymod.ParallelModuleQueue(int(self.nprocs))
  560. if isinstance(t[3], list):
  561. num = len(t[3])
  562. count = 0
  563. register_list = []
  564. leadzero = len(str(num))
  565. for i in range(num):
  566. # Check if resultmap names exist in GRASS database.
  567. map_name = self.basename + "_" + str(i).zfill(leadzero) + "@" + self.mapset
  568. if self.stdstype == "strds":
  569. new_map = RasterDataset(map_name)
  570. else:
  571. new_map = Raster3DDataset(map_name)
  572. if new_map.map_exists() and self.overwrite is False:
  573. self.msgr.fatal("Error maps with basename %s exist. "
  574. "Use --o flag to overwrite existing file"%map_name)
  575. map_test_list = []
  576. for map_i in t[3]:
  577. newident = self.basename + "_" + str(count).zfill(leadzero)
  578. if "cmd_list" in dir(map_i):
  579. # Build r.mapcalc module and execute expression.
  580. # Change map name to given basename.
  581. # Create deepcopy of r.mapcalc module.
  582. new_map = map_i.get_new_instance(newident + "@" + self.mapset)
  583. new_map.set_temporal_extent(map_i.get_temporal_extent())
  584. new_map.set_spatial_extent(map_i.get_spatial_extent())
  585. map_test_list.append(new_map)
  586. m = copy.deepcopy(self.m_mapcalc)
  587. m_expression = newident + "=" + map_i.cmd_list
  588. m.inputs["expression"].value = str(m_expression)
  589. m.flags["overwrite"].value = self.overwrite
  590. if self.debug:
  591. print(m.get_bash())
  592. self.process_chain_dict["processes"].append(m.get_dict())
  593. if self.dry_run is False:
  594. process_queue.put(m)
  595. elif map_i.map_exists():
  596. # Copy map if it exists b = a
  597. new_map = map_i.get_new_instance(newident + "@" + self.mapset)
  598. new_map.set_temporal_extent(map_i.get_temporal_extent())
  599. new_map.set_spatial_extent(map_i.get_spatial_extent())
  600. map_test_list.append(new_map)
  601. m = copy.deepcopy(self.m_mapcalc)
  602. m_expression = newident + "=" + map_i.get_map_id()
  603. m.inputs["expression"].value = str(m_expression)
  604. m.flags["overwrite"].value = self.overwrite
  605. if self.debug:
  606. print(m.get_bash())
  607. self.process_chain_dict["processes"].append(m.get_dict())
  608. if self.dry_run is False:
  609. process_queue.put(m)
  610. else:
  611. self.msgr.error(_("Error computing map <%s>"%map_i.get_id()))
  612. count += 1
  613. if self.dry_run is False:
  614. process_queue.wait()
  615. for map_i in map_test_list:
  616. register_list.append(map_i)
  617. # Open connection to temporal database.
  618. dbif, connect = init_dbif(self.dbif)
  619. # Create result space time dataset.
  620. if self.dry_run is False:
  621. resultstds = open_new_stds(t[1], self.stdstype,
  622. 'absolute', t[1], t[1],
  623. 'mean', self.dbif,
  624. overwrite = self.overwrite)
  625. for map_i in register_list:
  626. # Put the map into the process dictionary
  627. start, end = map_i.get_temporal_extent_as_tuple()
  628. self.process_chain_dict["register"].append((map_i.get_name(),
  629. str(start),
  630. str(end)))
  631. if self.dry_run is False:
  632. # Get meta data from grass database.
  633. map_i.load()
  634. # Do not register empty maps if not required
  635. # In case of a null map continue, do not register null maps
  636. if map_i.metadata.get_min() is None and \
  637. map_i.metadata.get_max() is None:
  638. if not self.register_null:
  639. self.removable_maps[map_i.get_name()] = map_i
  640. continue
  641. if map_i.is_in_db(dbif) and self.overwrite:
  642. # Update map in temporal database.
  643. if self.dry_run is False:
  644. map_i.update_all(dbif)
  645. elif map_i.is_in_db(dbif) and self.overwrite is False:
  646. # Raise error if map exists and no overwrite flag is given.
  647. self.msgr.fatal("Error raster map %s exist in temporal database. "
  648. "Use overwrite flag."%map_i.get_map_id())
  649. else:
  650. # Insert map into temporal database.
  651. if self.dry_run is False:
  652. map_i.insert(dbif)
  653. # Register map in result space time dataset.
  654. if self.dry_run is False:
  655. success = resultstds.register_map(map_i, dbif)
  656. if self.dry_run is False:
  657. resultstds.update_from_registered_maps(dbif)
  658. self.process_chain_dict["STDS"]["name"] = t[1]
  659. self.process_chain_dict["STDS"]["stdstype"] = self.stdstype
  660. self.process_chain_dict["STDS"]["temporal_type"] = 'absolute'
  661. dbif.close()
  662. t[0] = register_list
  663. # Remove intermediate maps
  664. self.remove_maps()
  665. def p_expr_spmap_function(self, t):
  666. # Add a single map.
  667. # Only the spatial extent of the map is evaluated.
  668. # Temporal extent is not existing.
  669. # Examples:
  670. # R = map(A)
  671. """
  672. mapexpr : MAP LPAREN stds RPAREN
  673. """
  674. if self.run:
  675. # Check input map.
  676. input = t[3]
  677. if not isinstance(input, list):
  678. # Check for mapset in given stds input.
  679. if input.find("@") >= 0:
  680. id_input = input
  681. else:
  682. id_input = input + "@" + self.mapset
  683. # Create empty map dataset.
  684. map_i = dataset_factory(self.maptype, id_input)
  685. # Check for occurrence of space time dataset.
  686. if map_i.map_exists() == False:
  687. raise FatalError(_("%s map <%s> not found in GRASS spatial database") %
  688. (map_i.get_type(), id_input))
  689. else:
  690. # Select dataset entry from database.
  691. map_i.select(dbif=self.dbif)
  692. # Create command list for map object.
  693. cmdstring = "(%s)" %(map_i.get_map_id())
  694. map_i.cmd_list = cmdstring
  695. # Return map object.
  696. t[0] = cmdstring
  697. else:
  698. t[0] = "map(" + t[3] + ")"
  699. if self.debug:
  700. print("map(" + t[3] + ")")
  701. def p_arith1_operation(self, t):
  702. # A % B
  703. # A / B
  704. # A * B
  705. # A % td(B)
  706. # A * td(B)
  707. # A / td(B)
  708. """
  709. expr : stds MOD stds
  710. | expr MOD stds
  711. | stds MOD expr
  712. | expr MOD expr
  713. | stds DIV stds
  714. | expr DIV stds
  715. | stds DIV expr
  716. | expr DIV expr
  717. | stds MULT stds
  718. | expr MULT stds
  719. | stds MULT expr
  720. | expr MULT expr
  721. | stds MOD t_td_var
  722. | expr MOD t_td_var
  723. | stds DIV t_td_var
  724. | expr DIV t_td_var
  725. | stds MULT t_td_var
  726. | expr MULT t_td_var
  727. """
  728. # Check input stds.
  729. maplistA = self.check_stds(t[1])
  730. maplistB = self.check_stds(t[3])
  731. topolist = self.build_spatio_temporal_topology_list(maplistA, maplistB)
  732. if self.run:
  733. resultlist = []
  734. for map_i in topolist:
  735. # Generate an intermediate map for the result map list.
  736. map_new = self.generate_new_map(base_map=map_i,
  737. bool_op='and',
  738. copy=True)
  739. # Loop over temporal related maps and create overlay modules.
  740. tbrelations = map_i.get_temporal_relations()
  741. count = 0
  742. for map_j in (tbrelations['EQUAL']):
  743. # Create overlaid map extent.
  744. returncode = self.overlay_map_extent(map_new, map_j,
  745. 'and',
  746. temp_op='l')
  747. # Stop the loop if no temporal or spatial relationship exist.
  748. if returncode == 0:
  749. break
  750. if count == 0:
  751. # Set map name.
  752. name = map_new.get_id()
  753. else:
  754. # Generate an intermediate map
  755. name = self.generate_map_name()
  756. # Create r.mapcalc expression string for the operation.
  757. cmdstring = self.build_command_string(map_i, map_j,
  758. operator=t[2],
  759. cmd_type="operator")
  760. # Conditional append of module command.
  761. map_new.cmd_list = cmdstring
  762. count += 1
  763. # Append map to result map list.
  764. if returncode == 1:
  765. resultlist.append(map_new)
  766. t[0] = resultlist
  767. if self.debug:
  768. for map in resultlist:
  769. print(map.cmd_list)
  770. def p_arith1_operation_numeric1(self, t):
  771. # A % 1
  772. # A / 4
  773. # A * 5
  774. # A % map(b1)
  775. # A * map(b2)
  776. # A / map(b3)
  777. """
  778. expr : stds MOD number
  779. | expr MOD number
  780. | stds DIV number
  781. | expr DIV number
  782. | stds MULT number
  783. | expr MULT number
  784. | stds MOD numberstr
  785. | expr MOD numberstr
  786. | stds DIV numberstr
  787. | expr DIV numberstr
  788. | stds MULT numberstr
  789. | expr MULT numberstr
  790. | stds MOD mapexpr
  791. | expr MOD mapexpr
  792. | stds DIV mapexpr
  793. | expr DIV mapexpr
  794. | stds MULT mapexpr
  795. | expr MULT mapexpr
  796. """
  797. # Check input stds.
  798. maplist = self.check_stds(t[1])
  799. if self.run:
  800. resultlist = []
  801. for map_i in maplist:
  802. mapinput = map_i.get_id()
  803. # Create r.mapcalc expression string for the operation.
  804. if "cmd_list" in dir(map_i):
  805. cmdstring = "(%s %s %s)" %(map_i.cmd_list, t[2], t[3])
  806. else:
  807. cmdstring = "(%s %s %s)" %(mapinput, t[2], t[3])
  808. # Conditional append of module command.
  809. map_i.cmd_list = cmdstring
  810. # Append map to result map list.
  811. resultlist.append(map_i)
  812. t[0] = resultlist
  813. if self.debug:
  814. for map in resultlist:
  815. print(map.cmd_list)
  816. def p_arith1_operation_numeric2(self, t):
  817. # 1 % A
  818. # 4 / A
  819. # 5 * A
  820. # map(b1) % A
  821. # map(b4) / A
  822. # map(b5) * A
  823. """
  824. expr : number MOD stds
  825. | number MOD expr
  826. | number DIV stds
  827. | number DIV expr
  828. | number MULT stds
  829. | number MULT expr
  830. | numberstr MOD stds
  831. | numberstr MOD expr
  832. | numberstr DIV stds
  833. | numberstr DIV expr
  834. | numberstr MULT stds
  835. | numberstr MULT expr
  836. | mapexpr MOD stds
  837. | mapexpr MOD expr
  838. | mapexpr DIV stds
  839. | mapexpr DIV expr
  840. | mapexpr MULT stds
  841. | mapexpr MULT expr
  842. """
  843. # Check input stds.
  844. maplist = self.check_stds(t[3])
  845. if self.run:
  846. resultlist = []
  847. for map_i in maplist:
  848. mapinput = map_i.get_id()
  849. # Create r.mapcalc expression string for the operation.
  850. if "cmd_list" in dir(map_i):
  851. cmdstring = "(%s %s %s)" %(t[1], t[2], map_i.cmd_list)
  852. else:
  853. cmdstring = "(%s %s %s)" %(t[1], t[2], mapinput)
  854. # Conditional append of module command.
  855. map_i.cmd_list = cmdstring
  856. # Append map to result map list.
  857. resultlist.append(map_i)
  858. t[0] = resultlist
  859. if self.debug:
  860. for map in resultlist:
  861. print(map.cmd_list)
  862. def p_arith2_operation(self, t):
  863. # A + B
  864. # A - B
  865. # A + td(B)
  866. # A - td(B)
  867. """
  868. expr : stds ADD stds
  869. | expr ADD stds
  870. | stds ADD expr
  871. | expr ADD expr
  872. | stds SUB stds
  873. | expr SUB stds
  874. | stds SUB expr
  875. | expr SUB expr
  876. | stds ADD t_td_var
  877. | expr ADD t_td_var
  878. | expr SUB t_td_var
  879. | stds SUB t_td_var
  880. """
  881. # Check input stds.
  882. maplistA = self.check_stds(t[1])
  883. maplistB = self.check_stds(t[3])
  884. topolist = self.build_spatio_temporal_topology_list(maplistA, maplistB)
  885. if self.run:
  886. resultlist = []
  887. for map_i in topolist:
  888. # Generate an intermediate map for the result map list.
  889. map_new = self.generate_new_map(base_map=map_i,
  890. bool_op='and',
  891. copy=True)
  892. # Loop over temporal related maps and create overlay modules.
  893. tbrelations = map_i.get_temporal_relations()
  894. count = 0
  895. for map_j in (tbrelations['EQUAL']):
  896. # Create overlaid map extent.
  897. returncode = self.overlay_map_extent(map_new,
  898. map_j,
  899. 'and',
  900. temp_op='l')
  901. # Stop the loop if no temporal or spatial relationship exist.
  902. if returncode == 0:
  903. break
  904. if count == 0:
  905. # Set map name.
  906. name = map_new.get_id()
  907. else:
  908. # Generate an intermediate map
  909. name = self.generate_map_name()
  910. # Create r.mapcalc expression string for the operation.
  911. cmdstring = self.build_command_string(map_i,
  912. map_j,
  913. operator=t[2],
  914. cmd_type="operator")
  915. # Conditional append of module command.
  916. map_new.cmd_list = cmdstring
  917. count += 1
  918. # Append map to result map list.
  919. if returncode == 1:
  920. resultlist.append(map_new)
  921. t[0] = resultlist
  922. if self.debug:
  923. for map in resultlist:
  924. print(map.cmd_list)
  925. def p_arith2_operation_numeric1(self, t):
  926. # A + 2
  927. # A - 3
  928. # A + map(b4)
  929. # A - map(b5)
  930. """
  931. expr : stds ADD number
  932. | expr ADD number
  933. | stds SUB number
  934. | expr SUB number
  935. | stds ADD numberstr
  936. | expr ADD numberstr
  937. | stds SUB numberstr
  938. | expr SUB numberstr
  939. | stds ADD mapexpr
  940. | expr ADD mapexpr
  941. | stds SUB mapexpr
  942. | expr SUB mapexpr
  943. """
  944. # Check input stds.
  945. maplist = self.check_stds(t[1])
  946. if self.run:
  947. resultlist = []
  948. for map_i in maplist:
  949. mapinput = map_i.get_id()
  950. # Create r.mapcalc expression string for the operation.
  951. if "cmd_list" in dir(map_i):
  952. cmdstring = "(%s %s %s)" %(map_i.cmd_list, t[2], t[3])
  953. else:
  954. cmdstring = "(%s %s %s)" %(mapinput, t[2], t[3])
  955. # Conditional append of module command.
  956. map_i.cmd_list = cmdstring
  957. # Append map to result map list.
  958. resultlist.append(map_i)
  959. t[0] = resultlist
  960. if self.debug:
  961. for map in resultlist:
  962. print(map.cmd_list)
  963. def p_arith2_operation_numeric2(self, t):
  964. # 2 + A
  965. # 3 - A
  966. # map(b2) + A
  967. # map(b3) - A
  968. """
  969. expr : number ADD stds
  970. | number ADD expr
  971. | number SUB stds
  972. | number SUB expr
  973. | numberstr ADD stds
  974. | numberstr ADD expr
  975. | numberstr SUB stds
  976. | numberstr SUB expr
  977. | mapexpr ADD stds
  978. | mapexpr ADD expr
  979. | mapexpr SUB stds
  980. | mapexpr SUB expr
  981. """
  982. # Check input stds.
  983. maplist = self.check_stds(t[3])
  984. if self.run:
  985. resultlist = []
  986. for map_i in maplist:
  987. mapinput = map_i.get_id()
  988. # Create r.mapcalc expression string for the operation.
  989. if "cmd_list" in dir(map_i):
  990. cmdstring = "(%s %s %s)" %(t[1], t[2], map_i.cmd_list)
  991. else:
  992. cmdstring = "(%s %s %s)" %(t[1], t[2], mapinput)
  993. # Conditional append of module command.
  994. map_i.cmd_list = cmdstring
  995. # Append map to result map list.
  996. resultlist.append(map_i)
  997. t[0] = resultlist
  998. if self.debug:
  999. for map in resultlist:
  1000. print(map.cmd_list)
  1001. def p_arith1_operation_relation(self, t):
  1002. # A {*, equal, l} B
  1003. # A {*, equal, l} td(B)
  1004. # A {*, equal, l} B {/, during, r} C
  1005. # A {*, equal, l} B {/, equal, l} C {/, during, r} D
  1006. """
  1007. expr : stds T_ARITH1_OPERATOR stds
  1008. | expr T_ARITH1_OPERATOR stds
  1009. | stds T_ARITH1_OPERATOR expr
  1010. | expr T_ARITH1_OPERATOR expr
  1011. | stds T_ARITH1_OPERATOR t_td_var
  1012. | expr T_ARITH1_OPERATOR t_td_var
  1013. """
  1014. if self.run:
  1015. # Check input stds.
  1016. maplistA = self.check_stds(t[1])
  1017. maplistB = self.check_stds(t[3])
  1018. relations, temporal, function, aggregate = self.eval_toperator(t[2], optype='raster')
  1019. # Build conditional values based on topological relationships.
  1020. complist = self.build_spatio_temporal_topology_list(maplistA,
  1021. maplistB,
  1022. topolist=relations,
  1023. operator_cmd=True,
  1024. compop=function)
  1025. # Set temporal extent based on topological relationships.
  1026. resultlist = self.set_temporal_extent_list(complist,
  1027. topolist=relations,
  1028. temporal=temporal)
  1029. t[0] = resultlist
  1030. if self.debug:
  1031. for map in resultlist:
  1032. print(map.cmd_list)
  1033. def p_arith2_operation_relation(self, t):
  1034. # A {+, equal, l} B
  1035. # A {+, equal, l} td(b)
  1036. # A {+, equal, l} B {-, during, r} C
  1037. # A {+, equal, l} B {+, equal, l} C {-, during, r} D
  1038. """
  1039. expr : stds T_ARITH2_OPERATOR stds
  1040. | expr T_ARITH2_OPERATOR stds
  1041. | stds T_ARITH2_OPERATOR expr
  1042. | expr T_ARITH2_OPERATOR expr
  1043. | stds T_ARITH2_OPERATOR t_td_var
  1044. | expr T_ARITH2_OPERATOR t_td_var
  1045. """
  1046. if self.run:
  1047. # Check input stds.
  1048. maplistA = self.check_stds(t[1])
  1049. maplistB = self.check_stds(t[3])
  1050. relations, temporal, function, aggregate = self.eval_toperator(t[2], optype='raster')
  1051. # Build conditional values based on topological relationships.
  1052. complist = self.build_spatio_temporal_topology_list(maplistA,
  1053. maplistB,
  1054. topolist=relations,
  1055. operator_cmd=True,
  1056. compop=function)
  1057. # Set temporal extent based on topological relationships.
  1058. resultlist = self.set_temporal_extent_list(complist,
  1059. topolist=relations,
  1060. temporal=temporal)
  1061. t[0] = resultlist
  1062. if self.debug:
  1063. for map in resultlist:
  1064. print(map.cmd_list)
  1065. def p_arith_operation_numeric_string(self, t):
  1066. # 1 + 1
  1067. # 1 - 1
  1068. # 1 * 1
  1069. # 1 / 1
  1070. # 1 % 1
  1071. """
  1072. numberstr : number ADD number
  1073. | number SUB number
  1074. | number DIV number
  1075. | number MULT number
  1076. | number MOD number
  1077. """
  1078. numstring = "(%s %s %s)" %(t[1], t[2], t[3])
  1079. t[0] = numstring
  1080. if self.debug:
  1081. print(numstring)
  1082. def p_mapcalc_function(self, t):
  1083. # Supported mapcalc functions.
  1084. """
  1085. mapcalc_arith : ABS
  1086. | LOG
  1087. | SQRT
  1088. | EXP
  1089. | COS
  1090. | ACOS
  1091. | SIN
  1092. | ASIN
  1093. | TAN
  1094. | DOUBLE
  1095. | FLOATEXP
  1096. | INTEXP
  1097. """
  1098. t[0] = t[1]
  1099. if self.debug:
  1100. print(t[1])
  1101. def p_mapcalc_operation1(self, t):
  1102. # sin(A)
  1103. # log(B)
  1104. """
  1105. expr : mapcalc_arith LPAREN stds RPAREN
  1106. | mapcalc_arith LPAREN expr RPAREN
  1107. """
  1108. # Check input stds.
  1109. maplist = self.check_stds(t[3])
  1110. if self.run:
  1111. resultlist = []
  1112. for map_i in maplist:
  1113. # Create r.mapcalc expression string for the operation.
  1114. if "cmd_list" in dir(map_i):
  1115. cmdstring = "%s(%s)" %(t[1].lower(), map_i.cmd_list)
  1116. else:
  1117. cmdstring = "%s(%s)" %(t[1].lower(), map_i.get_id())
  1118. # Set new command list for map.
  1119. map_i.cmd_list = cmdstring
  1120. # Append map with updated command list to result list.
  1121. resultlist.append(map_i)
  1122. t[0] = resultlist
  1123. if self.debug:
  1124. for map in resultlist:
  1125. print(map.cmd_list)
  1126. def p_mapexpr_operation(self, t):
  1127. # sin(map(a))
  1128. """
  1129. mapexpr : mapcalc_arith LPAREN mapexpr RPAREN
  1130. """
  1131. # Check input stds.
  1132. mapstring = t[3]
  1133. if self.run:
  1134. cmdstring = "%s(%s)" %(t[1].lower(), mapstring)
  1135. t[0] = cmdstring
  1136. if self.debug:
  1137. print(mapstring)
  1138. def p_s_var_expr_1(self, t):
  1139. # isnull(A)
  1140. """
  1141. s_var_expr : ISNULL LPAREN stds RPAREN
  1142. | ISNULL LPAREN expr RPAREN
  1143. """
  1144. # Check input stds.
  1145. maplist = self.check_stds(t[3])
  1146. if self.run:
  1147. resultlist = []
  1148. for map_i in maplist:
  1149. # Create r.mapcalc expression string for the operation.
  1150. if "cmd_list" in dir(map_i):
  1151. cmdstring = "%s(%s)" %(t[1].lower(), map_i.cmd_list)
  1152. else:
  1153. cmdstring = "%s(%s)" %(t[1].lower(), map_i.get_id())
  1154. # Set new command list for map.
  1155. map_i.cmd_list = cmdstring
  1156. # Append map with updated command list to result list.
  1157. resultlist.append(map_i)
  1158. t[0] = resultlist
  1159. if self.debug:
  1160. for map in resultlist:
  1161. print(map.cmd_list)
  1162. def p_s_var_expr_2(self, t):
  1163. # isntnull(A)
  1164. """
  1165. s_var_expr : ISNTNULL LPAREN stds RPAREN
  1166. | ISNTNULL LPAREN expr RPAREN
  1167. """
  1168. # Check input stds.
  1169. maplist = self.check_stds(t[3])
  1170. if self.run:
  1171. resultlist = []
  1172. for map_i in maplist:
  1173. # Create r.mapcalc expression string for the operation.
  1174. if "cmd_list" in dir(map_i):
  1175. cmdstring = "!isnull(%s)" %(map_i.cmd_list)
  1176. else:
  1177. cmdstring = "!isnull(%s)" %(map_i.get_id())
  1178. # Set new command list for map.
  1179. map_i.cmd_list = cmdstring
  1180. # Append map with updated command list to result list.
  1181. resultlist.append(map_i)
  1182. t[0] = resultlist
  1183. if self.debug:
  1184. for map in resultlist:
  1185. print(map.cmd_list)
  1186. def p_s_var_expr_3(self, t):
  1187. # A <= 2
  1188. """
  1189. s_var_expr : stds comp_op number
  1190. | expr comp_op number
  1191. """
  1192. # Check input stds.
  1193. maplist = self.check_stds(t[1])
  1194. if self.run:
  1195. resultlist = []
  1196. for map_i in maplist:
  1197. # Create r.mapcalc expression string for the operation.
  1198. if "cmd_list" in dir(map_i):
  1199. cmdstring = "%s %s %s" %(map_i.cmd_list, t[2], t[3])
  1200. else:
  1201. cmdstring = "%s %s %s" %(map_i.get_id(), t[2], t[3])
  1202. # Set new command list for map.
  1203. map_i.cmd_list = cmdstring
  1204. # Append map with updated command list to result list.
  1205. resultlist.append(map_i)
  1206. t[0] = resultlist
  1207. if self.debug:
  1208. for map in resultlist:
  1209. print(map.cmd_list)
  1210. def p_s_var_expr_4(self, t):
  1211. # exist(B)
  1212. """
  1213. s_var_expr : EXIST LPAREN stds RPAREN
  1214. | EXIST LPAREN expr RPAREN
  1215. """
  1216. # Check input stds.
  1217. maplist = self.check_stds(t[3])
  1218. if self.run:
  1219. resultlist = []
  1220. for map_i in maplist:
  1221. # Create r.mapcalc expression string for the operation.
  1222. if "cmd_list" in dir(map_i):
  1223. cmdstring = "%s" %(map_i.cmd_list)
  1224. else:
  1225. cmdstring = "%s" %(map_i.get_id())
  1226. # Set new command list for map.
  1227. map_i.cmd_list = cmdstring
  1228. # Append map with updated command list to result list.
  1229. resultlist.append(map_i)
  1230. t[0] = resultlist
  1231. if self.debug:
  1232. for map in resultlist:
  1233. print(map.cmd_list)
  1234. def p_s_var_expr_comp(self, t):
  1235. # A <= 2 || B == 10
  1236. # A < 3 && A > 1
  1237. """
  1238. s_var_expr : s_var_expr AND AND s_var_expr
  1239. | s_var_expr OR OR s_var_expr
  1240. """
  1241. if self.run:
  1242. # Check input stds.
  1243. s_var_exprA = self.check_stds(t[1])
  1244. s_var_exprB = self.check_stds(t[4])
  1245. relations = ["EQUAL"]
  1246. temporal = "l"
  1247. function = t[2] + t[3]
  1248. aggregate = t[2]
  1249. # Build conditional values based on topological relationships.
  1250. complist = self.build_spatio_temporal_topology_list(s_var_exprA,
  1251. s_var_exprB,
  1252. topolist=relations,
  1253. compare_cmd=True,
  1254. compop=function,
  1255. aggregate=aggregate)
  1256. # Set temporal extent based on topological relationships.
  1257. resultlist = self.set_temporal_extent_list(complist,
  1258. topolist=relations,
  1259. temporal=temporal)
  1260. t[0] = resultlist
  1261. if self.debug:
  1262. for map in resultlist:
  1263. print(map.cmd_list)
  1264. def p_s_var_expr_comp_op(self, t):
  1265. # A <= 2 {||} B == 10
  1266. # A < 3 {&&, equal} A > 1
  1267. """
  1268. s_var_expr : s_var_expr T_COMP_OPERATOR s_var_expr
  1269. """
  1270. if self.run:
  1271. # Check input stds.
  1272. s_var_exprA = self.check_stds(t[1])
  1273. s_var_exprB = self.check_stds(t[3])
  1274. # Evaluate temporal comparison operator.
  1275. relations, temporal, function, aggregate = self.eval_toperator(t[2], optype='boolean')
  1276. # Build conditional values based on topological relationships.
  1277. complist = self.build_spatio_temporal_topology_list(s_var_exprA,
  1278. s_var_exprB,
  1279. topolist=relations,
  1280. compare_cmd=True,
  1281. compop=function,
  1282. aggregate=aggregate)
  1283. # Set temporal extent based on topological relationships.
  1284. resultlist = self.set_temporal_extent_list(complist,
  1285. topolist=relations,
  1286. temporal=temporal)
  1287. t[0] = resultlist
  1288. if self.debug:
  1289. for map in resultlist:
  1290. print(map.cmd_list)
  1291. def p_s_expr_condition_if(self, t):
  1292. # if(s_var_expr, B)
  1293. # if(A == 1, B)
  1294. """
  1295. expr : IF LPAREN s_var_expr COMMA stds RPAREN
  1296. | IF LPAREN s_var_expr COMMA expr RPAREN
  1297. | IF LPAREN ts_var_expr COMMA stds RPAREN
  1298. | IF LPAREN ts_var_expr COMMA expr RPAREN
  1299. """
  1300. ifmaplist = self.check_stds(t[3])
  1301. thenmaplist = self.check_stds(t[5])
  1302. resultlist = self.build_condition_cmd_list(ifmaplist,
  1303. thenmaplist,
  1304. elselist=None,
  1305. condition_topolist=["EQUAL"],
  1306. conclusion_topolist=["EQUAL"],
  1307. temporal='r',
  1308. null=False)
  1309. t[0] = resultlist
  1310. if self.debug:
  1311. for map in resultlist:
  1312. print(map.cmd_list)
  1313. def p_s_numeric_condition_if(self, t):
  1314. # if(s_var_expr, 1)
  1315. # if(A == 5, 10)
  1316. """
  1317. expr : IF LPAREN s_var_expr COMMA number RPAREN
  1318. | IF LPAREN s_var_expr COMMA NULL LPAREN RPAREN RPAREN
  1319. | IF LPAREN ts_var_expr COMMA number RPAREN
  1320. | IF LPAREN ts_var_expr COMMA NULL LPAREN RPAREN RPAREN
  1321. """
  1322. ifmaplist = self.check_stds(t[3])
  1323. resultlist = []
  1324. # Select input for r.mapcalc expression based on length of PLY object.
  1325. if len(t) == 7:
  1326. numinput = str(t[5])
  1327. elif len(t) == 9:
  1328. numinput = str(t[5] + t[6] + t[7])
  1329. # Iterate over condition map list.
  1330. for map_i in ifmaplist:
  1331. # Create r.mapcalc expression string for the operation.
  1332. cmdstring = self.build_command_string(map_i, numinput,
  1333. cmd_type='condition')
  1334. # Conditional append of module command.
  1335. map_i.cmd_list = cmdstring
  1336. # Append map to result map list.
  1337. resultlist.append(map_i)
  1338. t[0] = resultlist
  1339. if self.debug:
  1340. for map in resultlist:
  1341. print(map.cmd_list)
  1342. def p_s_expr_condition_if_relation(self, t):
  1343. # if({equal||during}, s_var_expr, A)
  1344. """
  1345. expr : IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA stds RPAREN
  1346. | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA expr RPAREN
  1347. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA stds RPAREN
  1348. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA expr RPAREN
  1349. """
  1350. relations, temporal, function, aggregation = self.eval_toperator(t[3],
  1351. optype='relation')
  1352. ifmaplist = self.check_stds(t[5])
  1353. thenmaplist = self.check_stds(t[7])
  1354. resultlist = self.build_condition_cmd_list(ifmaplist,
  1355. thenmaplist,
  1356. elselist=None,
  1357. condition_topolist=relations,
  1358. conclusion_topolist=["EQUAL"],
  1359. temporal='r',
  1360. null=False)
  1361. t[0] = resultlist
  1362. if self.debug:
  1363. for map in resultlist:
  1364. print(map.cmd_list)
  1365. def p_s_expr_condition_elif(self, t):
  1366. # if(s_var_expr, A, B)
  1367. """
  1368. expr : IF LPAREN s_var_expr COMMA stds COMMA stds RPAREN
  1369. | IF LPAREN s_var_expr COMMA stds COMMA expr RPAREN
  1370. | IF LPAREN s_var_expr COMMA expr COMMA stds RPAREN
  1371. | IF LPAREN s_var_expr COMMA expr COMMA expr RPAREN
  1372. | IF LPAREN ts_var_expr COMMA stds COMMA stds RPAREN
  1373. | IF LPAREN ts_var_expr COMMA stds COMMA expr RPAREN
  1374. | IF LPAREN ts_var_expr COMMA expr COMMA stds RPAREN
  1375. | IF LPAREN ts_var_expr COMMA expr COMMA expr RPAREN
  1376. """
  1377. # Check map list inputs.
  1378. ifmaplist = self.check_stds(t[3])
  1379. thenmaplist = self.check_stds(t[5])
  1380. elsemaplist = self.check_stds(t[7])
  1381. # Create conditional command map list.
  1382. resultlist = self.build_condition_cmd_list(ifmaplist,
  1383. thenmaplist,
  1384. elselist=elsemaplist,
  1385. condition_topolist=["EQUAL"],
  1386. conclusion_topolist=["EQUAL"],
  1387. temporal='r',
  1388. null=False)
  1389. t[0] = resultlist
  1390. if self.debug:
  1391. for map in resultlist:
  1392. print(map.cmd_list)
  1393. def p_s_numeric_condition_elif(self, t):
  1394. # if(s_var_expr, 1, 2)
  1395. # if(A == 5, 10, 0)
  1396. """
  1397. expr : IF LPAREN s_var_expr COMMA number COMMA number RPAREN
  1398. | IF LPAREN s_var_expr COMMA NULL LPAREN RPAREN COMMA number RPAREN
  1399. | IF LPAREN s_var_expr COMMA number COMMA NULL LPAREN RPAREN RPAREN
  1400. | IF LPAREN s_var_expr COMMA NULL LPAREN RPAREN COMMA NULL LPAREN RPAREN RPAREN
  1401. | IF LPAREN ts_var_expr COMMA number COMMA number RPAREN
  1402. | IF LPAREN ts_var_expr COMMA NULL LPAREN RPAREN COMMA number RPAREN
  1403. | IF LPAREN ts_var_expr COMMA number COMMA NULL LPAREN RPAREN RPAREN
  1404. | IF LPAREN ts_var_expr COMMA NULL LPAREN RPAREN COMMA NULL LPAREN RPAREN RPAREN
  1405. """
  1406. ifmaplist = self.check_stds(t[3])
  1407. # Select input for r.mapcalc expression based on length of PLY object.
  1408. if len(t) == 9:
  1409. numthen = t[5]
  1410. numelse = t[7]
  1411. elif len(t) == 11 and t[6] == '(':
  1412. numthen = t[5] + t[6] + t[7]
  1413. numelse = t[9]
  1414. elif len(t) == 11 and t[6] == ',':
  1415. numthen = t[5]
  1416. numelse = t[7] + t[8] + t[9]
  1417. elif len(t) == 13:
  1418. numthen = t[5] + t[6] + t[7]
  1419. numelse = t[9] + t[10] + t[11]
  1420. numthen = str(numthen)
  1421. numelse = str(numelse)
  1422. print(numthen + " " +numelse )
  1423. # Create conditional command map list.
  1424. resultlist = self.build_condition_cmd_list(ifmaplist,
  1425. numthen,
  1426. numelse,
  1427. condition_topolist=["EQUAL"],
  1428. conclusion_topolist=["EQUAL"],
  1429. temporal='r',
  1430. null=False)
  1431. t[0] = resultlist
  1432. if self.debug:
  1433. for map in resultlist:
  1434. print(map.cmd_list)
  1435. def p_s_numeric_expr_condition_elif(self, t):
  1436. # if(s_var_expr, 1, A)
  1437. # if(A == 5 && C > 5, A, null())
  1438. """
  1439. expr : IF LPAREN s_var_expr COMMA number COMMA stds RPAREN
  1440. | IF LPAREN s_var_expr COMMA NULL LPAREN RPAREN COMMA stds RPAREN
  1441. | IF LPAREN s_var_expr COMMA number COMMA expr RPAREN
  1442. | IF LPAREN s_var_expr COMMA NULL LPAREN RPAREN COMMA expr RPAREN
  1443. | IF LPAREN s_var_expr COMMA stds COMMA number RPAREN
  1444. | IF LPAREN s_var_expr COMMA stds COMMA NULL LPAREN RPAREN RPAREN
  1445. | IF LPAREN s_var_expr COMMA expr COMMA number RPAREN
  1446. | IF LPAREN s_var_expr COMMA expr COMMA NULL LPAREN RPAREN RPAREN
  1447. | IF LPAREN ts_var_expr COMMA number COMMA stds RPAREN
  1448. | IF LPAREN ts_var_expr COMMA NULL LPAREN RPAREN COMMA stds RPAREN
  1449. | IF LPAREN ts_var_expr COMMA number COMMA expr RPAREN
  1450. | IF LPAREN ts_var_expr COMMA NULL LPAREN RPAREN COMMA expr RPAREN
  1451. | IF LPAREN ts_var_expr COMMA stds COMMA number RPAREN
  1452. | IF LPAREN ts_var_expr COMMA stds COMMA NULL LPAREN RPAREN RPAREN
  1453. | IF LPAREN ts_var_expr COMMA expr COMMA number RPAREN
  1454. | IF LPAREN ts_var_expr COMMA expr COMMA NULL LPAREN RPAREN RPAREN
  1455. """
  1456. ifmaplist = self.check_stds(t[3])
  1457. # Select input for r.mapcalc expression based on length of PLY object.
  1458. if len(t) == 9:
  1459. if isinstance(t[5], int):
  1460. theninput = str(t[5])
  1461. elseinput = self.check_stds(t[7])
  1462. elif isinstance(t[7], int):
  1463. theninput = self.check_stds(t[5])
  1464. elseinput = str(t[7])
  1465. elif len(t) == 11:
  1466. if t[5] == 'null':
  1467. theninput = str(t[5] + t[6] + t[7])
  1468. elseinput = self.check_stds(t[9])
  1469. elif t[7] == 'null':
  1470. theninput = self.check_stds(t[5])
  1471. elseinput = str(t[7] + t[8] + t[9])
  1472. # Create conditional command map list.
  1473. resultlist = self.build_condition_cmd_list(ifmaplist,
  1474. theninput,
  1475. elseinput,
  1476. condition_topolist=["EQUAL"],
  1477. conclusion_topolist=["EQUAL"],
  1478. temporal='r',
  1479. null=False)
  1480. t[0] = resultlist
  1481. if self.debug:
  1482. for map in resultlist:
  1483. print(map.cmd_list)
  1484. def p_s_numeric_expr_condition_elif_relation(self, t):
  1485. # if({during},s_var_expr, 1, A)
  1486. # if({during}, A == 5, A, null())
  1487. """
  1488. expr : IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA number COMMA stds RPAREN
  1489. | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA NULL LPAREN RPAREN COMMA stds RPAREN
  1490. | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA number COMMA expr RPAREN
  1491. | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA NULL LPAREN RPAREN COMMA expr RPAREN
  1492. | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA stds COMMA number RPAREN
  1493. | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA stds COMMA NULL LPAREN RPAREN RPAREN
  1494. | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA expr COMMA number RPAREN
  1495. | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA expr COMMA NULL LPAREN RPAREN RPAREN
  1496. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA number COMMA stds RPAREN
  1497. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA NULL LPAREN RPAREN COMMA stds RPAREN
  1498. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA number COMMA expr RPAREN
  1499. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA NULL LPAREN RPAREN COMMA expr RPAREN
  1500. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA stds COMMA number RPAREN
  1501. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA stds COMMA NULL LPAREN RPAREN RPAREN
  1502. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA expr COMMA number RPAREN
  1503. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA expr COMMA NULL LPAREN RPAREN RPAREN
  1504. """
  1505. relations, temporal, function, aggregation = self.eval_toperator(t[3], optype='relation')
  1506. ifmaplist = self.check_stds(t[5])
  1507. # Select input for r.mapcalc expression based on length of PLY object.
  1508. if len(t) == 11:
  1509. if isinstance(t[7], int):
  1510. theninput = str(t[7])
  1511. elseinput = self.check_stds(t[9])
  1512. elif isinstance(t[9], int):
  1513. theninput = self.check_stds(t[7])
  1514. elseinput = str(t[9])
  1515. elif len(t) == 13:
  1516. if t[7] == 'null':
  1517. theninput = str(t[7] + t[8] + t[9])
  1518. elseinput = self.check_stds(t[11])
  1519. elif t[9] == 'null':
  1520. theninput = self.check_stds(t[7])
  1521. elseinput = str(t[9] + t[10] + t[11])
  1522. # Create conditional command map list.
  1523. resultlist = self.build_condition_cmd_list(ifmaplist,
  1524. theninput,
  1525. elseinput,
  1526. condition_topolist=relations,
  1527. conclusion_topolist=["EQUAL"],
  1528. temporal='r',
  1529. null=False)
  1530. t[0] = resultlist
  1531. if self.debug:
  1532. for map in resultlist:
  1533. print(map.cmd_list)
  1534. def p_s_expr_condition_elif_relation(self, t):
  1535. # if({equal||during}, s_var_expr, A, B)
  1536. """
  1537. expr : IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA stds COMMA stds RPAREN
  1538. | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA stds COMMA expr RPAREN
  1539. | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA expr COMMA stds RPAREN
  1540. | IF LPAREN T_REL_OPERATOR COMMA s_var_expr COMMA expr COMMA expr RPAREN
  1541. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA stds COMMA stds RPAREN
  1542. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA stds COMMA expr RPAREN
  1543. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA expr COMMA stds RPAREN
  1544. | IF LPAREN T_REL_OPERATOR COMMA ts_var_expr COMMA expr COMMA expr RPAREN
  1545. """
  1546. relations, temporal, function, aggregation = self.eval_toperator(t[3], optype='relation')
  1547. ifmaplist = self.check_stds(t[5])
  1548. thenmaplist = self.check_stds(t[7])
  1549. elsemaplist = self.check_stds(t[9])
  1550. # Create conditional command map list.
  1551. resultlist = self.build_condition_cmd_list(ifmaplist,
  1552. thenmaplist,
  1553. elsemaplist,
  1554. condition_topolist=relations,
  1555. conclusion_topolist=["EQUAL"],
  1556. temporal='r',
  1557. null=False)
  1558. t[0] = resultlist
  1559. if self.debug:
  1560. for map in resultlist:
  1561. print(map.cmd_list)
  1562. def p_ts_var_expr1(self, t):
  1563. # Combination of spatial and temporal conditional expressions.
  1564. # Examples:
  1565. # A <= 2 || start_date <= 2013-01-01
  1566. # end_date > 2013-01-15 && A > 10
  1567. # IMPORTANT: Only the intersection of map lists in conditionals are
  1568. # exported.
  1569. """
  1570. ts_var_expr : s_var_expr AND AND t_var_expr
  1571. | t_var_expr AND AND s_var_expr
  1572. | t_var_expr OR OR s_var_expr
  1573. | s_var_expr OR OR t_var_expr
  1574. | ts_var_expr AND AND s_var_expr
  1575. | ts_var_expr AND AND t_var_expr
  1576. | ts_var_expr OR OR s_var_expr
  1577. | ts_var_expr OR OR t_var_expr
  1578. | s_var_expr AND AND ts_var_expr
  1579. | t_var_expr AND AND ts_var_expr
  1580. | s_var_expr OR OR ts_var_expr
  1581. | t_var_expr OR OR ts_var_expr
  1582. """
  1583. if self.run:
  1584. # Check input stds.
  1585. s_var_exprA = self.check_stds(t[1])
  1586. s_var_exprB = self.check_stds(t[4])
  1587. relations = ["EQUAL"]
  1588. temporal = "l"
  1589. function = t[2] + t[3]
  1590. aggregate = t[2]
  1591. # Build conditional values based on topological relationships.
  1592. complist = self.build_spatio_temporal_topology_list(s_var_exprA,
  1593. s_var_exprB,
  1594. topolist=relations,
  1595. compare_cmd=True,
  1596. compop=function,
  1597. aggregate=aggregate,
  1598. convert=True)
  1599. # Set temporal extent based on topological relationships.
  1600. resultlist = self.set_temporal_extent_list(complist,
  1601. topolist=relations,
  1602. temporal=temporal)
  1603. t[0] = resultlist
  1604. def p_hash_operation(self, t):
  1605. # Calculate the number of maps within an interval of another map from a
  1606. # second space time dataset.
  1607. # A # B
  1608. # A {equal,r#} B
  1609. """
  1610. expr : t_hash_var
  1611. """
  1612. # Check input stds.
  1613. maplist = self.check_stds(t[1])
  1614. if self.run:
  1615. resultlist = []
  1616. for map_i in maplist:
  1617. for obj in map_i.map_value:
  1618. if isinstance(obj, GlobalTemporalVar):
  1619. n_maps = obj.td
  1620. mapinput = map_i.get_id()
  1621. # Create r.mapcalc expression string for the operation.
  1622. cmdstring = "(%s)" %(n_maps)
  1623. # Append module command.
  1624. map_i.cmd_list = cmdstring
  1625. # Append map to result map list.
  1626. resultlist.append(map_i)
  1627. t[0] = resultlist
  1628. if self.debug:
  1629. for map in resultlist:
  1630. print(map.cmd_list)
  1631. ###############################################################################
  1632. if __name__ == "__main__":
  1633. import doctest
  1634. doctest.testmod()