temporal_raster_base_algebra.py 70 KB

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