temporal_raster3d_algebra.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. """
  9. from __future__ import print_function
  10. try:
  11. import ply.yacc as yacc
  12. except:
  13. pass
  14. from .temporal_raster_base_algebra import TemporalRasterBaseAlgebraParser,\
  15. TemporalRasterAlgebraLexer
  16. import grass.pygrass.modules as pymod
  17. from .space_time_datasets import Raster3DDataset
  18. ###############################################################################
  19. class TemporalRaster3DAlgebraParser(TemporalRasterBaseAlgebraParser):
  20. """The temporal raster algebra class"""
  21. def __init__(self, pid=None, run=False, debug=True, spatial=False,
  22. register_null=False, dry_run=False, nprocs=1):
  23. TemporalRasterBaseAlgebraParser.__init__(self, pid=pid, run=run, debug=debug,
  24. spatial=spatial, register_null=register_null,
  25. dry_run=dry_run, nprocs=nprocs)
  26. self.m_mapcalc = pymod.Module('r3.mapcalc')
  27. self.m_mremove = pymod.Module('g.remove')
  28. def parse(self, expression, basename = None, overwrite=False):
  29. # Check for space time dataset type definitions from temporal algebra
  30. l = TemporalRasterAlgebraLexer()
  31. l.build()
  32. l.lexer.input(expression)
  33. while True:
  34. tok = l.lexer.token()
  35. if not tok:
  36. break
  37. if tok.type == "STVDS" or tok.type == "STRDS" or tok.type == "STR3DS":
  38. raise SyntaxError("Syntax error near '%s'" % (tok.type))
  39. self.lexer = TemporalRasterAlgebraLexer()
  40. self.lexer.build()
  41. self.parser = yacc.yacc(module=self, debug=self.debug, write_tables=False)
  42. self.overwrite = overwrite
  43. self.count = 0
  44. self.stdstype = "str3ds"
  45. self.maptype = "raster_3d"
  46. self.mapclass = Raster3DDataset
  47. self.basename = basename
  48. self.expression = expression
  49. self.parser.parse(expression)
  50. return self.process_chain_dict
  51. ######################### Temporal functions ##############################
  52. def p_statement_assign(self, t):
  53. # The expression should always return a list of maps.
  54. """
  55. statement : stds EQUALS expr
  56. """
  57. TemporalRasterBaseAlgebraParser.p_statement_assign(self, t)
  58. def p_ts_neighbor_operation(self, t):
  59. # Examples:
  60. # A[1,0,-1]
  61. # B[-2]
  62. # C[1,-2,1,3]
  63. """
  64. expr : stds L_SPAREN number COMMA number COMMA number R_SPAREN
  65. | stds L_SPAREN number R_SPAREN
  66. | stds L_SPAREN number COMMA number COMMA number COMMA number R_SPAREN
  67. """
  68. # Check input stds.
  69. maplist = self.check_stds(t[1])
  70. t_neighbor = 0
  71. row_neighbor = None
  72. col_neighbor = None
  73. depth_neighbor = None
  74. if len(t) == 5:
  75. t_neighbor = t[3]
  76. elif len(t) == 9:
  77. row_neighbor = t[3]
  78. col_neighbor = t[5]
  79. depth_neighbor = t[7]
  80. elif len(t) == 11:
  81. t_neighbor = t[9]
  82. row_neighbor = t[3]
  83. col_neighbor = t[5]
  84. depth_neighbor = t[7]
  85. if self.run:
  86. resultlist = []
  87. max_index = len(maplist)
  88. for map_i in maplist:
  89. # Get map index and temporal extent.
  90. map_index = maplist.index(map_i)
  91. new_index = map_index + t_neighbor
  92. if new_index < max_index and new_index >= 0:
  93. map_i_t_extent = map_i.get_temporal_extent()
  94. # Get neighboring map and set temporal extent.
  95. map_n = maplist[new_index]
  96. # Generate an intermediate map for the result map list.
  97. map_new = self.generate_new_map(map_n, bool_op = 'and', copy = True)
  98. map_new.set_temporal_extent(map_i_t_extent)
  99. # Create r.mapcalc expression string for the operation.
  100. if "cmd_list" in dir(map_new) and len(t) == 5:
  101. cmdstring = "%s" % (map_new.cmd_list)
  102. elif "cmd_list" not in dir(map_new) and len(t) == 5:
  103. cmdstring = "%s" % (map_n.get_id())
  104. elif "cmd_list" in dir(map_new) and len(t) in (9,11):
  105. cmdstring = "%s[%s,%s,%s]" % (map_new.cmd_list, row_neighbor, col_neighbor, depth_neighbor)
  106. elif "cmd_list" not in dir(map_new) and len(t) in (9,11):
  107. cmdstring = "%s[%s,%s,%s]" % (map_n.get_id(), row_neighbor, col_neighbor, depth_neighbor)
  108. # Set new command list for map.
  109. map_new.cmd_list = cmdstring
  110. # Append map with updated command list to result list.
  111. resultlist.append(map_new)
  112. t[0] = resultlist
  113. ###############################################################################
  114. if __name__ == "__main__":
  115. import doctest
  116. doctest.testmod()