temporal_raster_base_algebra.py 80 KB

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