temporal_raster_base_algebra.py 80 KB

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