temporal_raster_base_algebra.py 74 KB

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