temporal_raster_algebra.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. @author Thomas Leppelt and Soeren Gebbert
  8. @code
  9. >>> p = TemporalRasterAlgebraLexer()
  10. >>> p.build()
  11. >>> p.debug = True
  12. >>> expression = 'R = A[0,1,0] / B[0,0,1] * 20 + C[0,1,1] - 2.45'
  13. >>> p.test(expression)
  14. R = A[0,1,0] / B[0,0,1] * 20 + C[0,1,1] - 2.45
  15. LexToken(NAME,'R',1,0)
  16. LexToken(EQUALS,'=',1,2)
  17. LexToken(NAME,'A',1,4)
  18. LexToken(L_SPAREN,'[',1,5)
  19. LexToken(INT,0,1,6)
  20. LexToken(COMMA,',',1,7)
  21. LexToken(INT,1,1,8)
  22. LexToken(COMMA,',',1,9)
  23. LexToken(INT,0,1,10)
  24. LexToken(R_SPAREN,']',1,11)
  25. LexToken(DIV,'/',1,13)
  26. LexToken(NAME,'B',1,15)
  27. LexToken(L_SPAREN,'[',1,16)
  28. LexToken(INT,0,1,17)
  29. LexToken(COMMA,',',1,18)
  30. LexToken(INT,0,1,19)
  31. LexToken(COMMA,',',1,20)
  32. LexToken(INT,1,1,21)
  33. LexToken(R_SPAREN,']',1,22)
  34. LexToken(MULT,'*',1,24)
  35. LexToken(INT,20,1,26)
  36. LexToken(ADD,'+',1,29)
  37. LexToken(NAME,'C',1,31)
  38. LexToken(L_SPAREN,'[',1,32)
  39. LexToken(INT,0,1,33)
  40. LexToken(COMMA,',',1,34)
  41. LexToken(INT,1,1,35)
  42. LexToken(COMMA,',',1,36)
  43. LexToken(INT,1,1,37)
  44. LexToken(R_SPAREN,']',1,38)
  45. LexToken(SUB,'-',1,40)
  46. LexToken(FLOAT,2.45,1,42)
  47. @endcode
  48. """
  49. from temporal_raster_base_algebra import *
  50. ###############################################################################
  51. class TemporalRasterAlgebraParser(TemporalRasterBaseAlgebraParser):
  52. """The temporal raster algebra class"""
  53. def __init__(self, pid=None, run=False, debug=True, spatial = False, nprocs = 1, register_null = False):
  54. TemporalRasterBaseAlgebraParser.__init__(self, pid, run, debug, spatial, nprocs, register_null)
  55. self.m_mapcalc = pymod.Module('r.mapcalc')
  56. self.m_mremove = pymod.Module('g.mremove')
  57. def parse(self, expression, basename = None, overwrite=False):
  58. self.lexer = TemporalRasterAlgebraLexer()
  59. self.lexer.build()
  60. self.parser = yacc.yacc(module=self, debug=self.debug)
  61. self.overwrite = overwrite
  62. self.count = 0
  63. self.stdstype = "strds"
  64. self.basename = basename
  65. self.expression = expression
  66. self.parser.parse(expression)
  67. def remove_empty_maps(self):
  68. """! Removes the intermediate vector maps.
  69. """
  70. if self.empty_maps:
  71. self.msgr.message(_("Removing empty raster maps"))
  72. namelist = self.empty_maps.values()
  73. max = 100
  74. chunklist = [namelist[i:i + max] for i in range(0, len(namelist), max)]
  75. for chunk in chunklist:
  76. stringlist = ",".join(chunk)
  77. if self.run:
  78. m = copy.deepcopy(self.m_mremove)
  79. m.inputs["type"].value = "rast"
  80. m.inputs["pattern"].value = stringlist
  81. m.flags["f"].value = True
  82. m.run()
  83. ######################### Temporal functions ##############################
  84. def p_statement_assign(self, t):
  85. # The expression should always return a list of maps.
  86. """
  87. statement : stds EQUALS expr
  88. """
  89. TemporalRasterBaseAlgebraParser.p_statement_assign(self, t)
  90. def p_ts_neighbour_operation(self, t):
  91. # Examples:
  92. # A[1,0]
  93. # B[-2]
  94. # C[-2,1,3]
  95. """
  96. expr : stds L_SPAREN number COMMA number R_SPAREN
  97. | stds L_SPAREN number R_SPAREN
  98. | stds L_SPAREN number COMMA number COMMA number R_SPAREN
  99. """
  100. # Check input stds.
  101. maplist = self.check_stds(t[1])
  102. row_neigbour = None
  103. col_neigbour = None
  104. if len(t) == 5:
  105. t_neighbour = t[3]
  106. elif len(t) == 7:
  107. t_neighbour = 0
  108. row_neigbour = t[3]
  109. col_neigbour = t[5]
  110. elif len(t) == 9:
  111. t_neighbour = t[7]
  112. row_neigbour = t[3]
  113. col_neigbour = t[5]
  114. if self.run:
  115. resultlist = []
  116. max_index = len(maplist)
  117. for map_i in maplist:
  118. # Get map index and temporal extent.
  119. map_index = maplist.index(map_i)
  120. new_index = map_index + t_neighbour
  121. if new_index < max_index and new_index >= 0:
  122. map_i_t_extent = map_i.get_temporal_extent()
  123. # Get neighbouring map and set temporal extent.
  124. map_n = maplist[new_index]
  125. # Generate an intermediate map for the result map list.
  126. map_new = self.generate_new_map(map_n, bool_op = 'and', copy = True)
  127. map_new.set_temporal_extent(map_i_t_extent)
  128. # Create r.mapcalc expression string for the operation.
  129. if "cmd_list" in dir(map_new) and len(t) == 5:
  130. cmdstring = "%s" %(map_new.cmd_list)
  131. elif "cmd_list" not in dir(map_new) and len(t) == 5:
  132. cmdstring = "%s" %(map_n.get_id())
  133. elif "cmd_list" in dir(map_new) and len(t) in (7, 9):
  134. cmdstring = "%s[%s,%s]" %(map_new.cmd_list, row_neigbour, col_neigbour)
  135. elif "cmd_list" not in dir(map_new) and len(t) in (7, 9):
  136. cmdstring = "%s[%s,%s]" %(map_n.get_id(), row_neigbour, col_neigbour)
  137. # Set new command list for map.
  138. map_new.cmd_list = cmdstring
  139. # Append map with updated command list to result list.
  140. resultlist.append(map_new)
  141. t[0] = resultlist
  142. ###############################################################################
  143. if __name__ == "__main__":
  144. import doctest
  145. doctest.testmod()