temporal_raster_base_algebra.py 70 KB

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