t.rast.aggregate.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. ############################################################################
  4. #
  5. # MODULE: t.rast.aggregate
  6. # AUTHOR(S): Soeren Gebbert
  7. #
  8. # PURPOSE: Temporally aggregates the maps of a space time raster dataset by a user defined granularity.
  9. # COPYRIGHT: (C) 2011 by the GRASS Development Team
  10. #
  11. # This program is free software under the GNU General Public
  12. # License (version 2). Read the file COPYING that comes with GRASS
  13. # for details.
  14. #
  15. #############################################################################
  16. #%module
  17. #% description: Temporally aggregates the maps of a space time raster dataset by a user defined granularity.
  18. #% keywords: temporal
  19. #% keywords: aggregation
  20. #%end
  21. #%option G_OPT_STRDS_INPUT
  22. #%end
  23. #%option G_OPT_STRDS_OUTPUT
  24. #%end
  25. #%option
  26. #% key: basename
  27. #% type: string
  28. #% label: Base name of the new generated output maps"
  29. #% description: A numerical suffix separated by an underscore will be attached to create a unique identifier
  30. #% required: yes
  31. #% multiple: no
  32. #% gisprompt:
  33. #%end
  34. #%option
  35. #% key: granularity
  36. #% type: string
  37. #% description: Aggregation granularity, format absolute time "x years, x months, x weeks, x days, x hours, x minutes, x seconds" or an integer value for relative time
  38. #% required: yes
  39. #% multiple: no
  40. #%end
  41. #%option
  42. #% key: method
  43. #% type: string
  44. #% description: Aggregate operation to be performed on the raster maps
  45. #% required: yes
  46. #% multiple: no
  47. #% options: average,count,median,mode,minimum,min_raster,maximum,max_raster,stddev,range,sum,variance,diversity,slope,offset,detcoeff,quart1,quart3,perc90,quantile,skewness,kurtosis
  48. #% answer: average
  49. #%end
  50. #%option
  51. #% key: offset
  52. #% type: integer
  53. #% description: Offset that is used to create the output map ids, output map id is generated as: basename_ (count + offset)
  54. #% required: no
  55. #% multiple: no
  56. #% answer: 0
  57. #%end
  58. #%option G_OPT_T_SAMPLE
  59. #%end
  60. #%option G_OPT_T_WHERE
  61. #%end
  62. #%flag
  63. #% key: n
  64. #% description: Register Null maps
  65. #%end
  66. import grass.script as grass
  67. import grass.temporal as tgis
  68. ############################################################################
  69. def main():
  70. # Get the options
  71. input = options["input"]
  72. output = options["output"]
  73. where = options["where"]
  74. gran = options["granularity"]
  75. base = options["basename"]
  76. register_null = flags["n"]
  77. method = options["method"]
  78. sampling = options["sampling"]
  79. offset = options["offset"]
  80. # Make sure the temporal database exists
  81. tgis.init()
  82. # We need a database interface
  83. dbif = tgis.SQLDatabaseInterfaceConnection()
  84. dbif.connect()
  85. sp = tgis.open_old_space_time_dataset(input, "strds", dbif)
  86. temporal_type, semantic_type, title, description = sp.get_initial_values()
  87. new_sp = tgis.open_new_space_time_dataset(output, "strds", temporal_type,
  88. title, description, semantic_type,
  89. dbif, grass.overwrite())
  90. rows = sp.get_registered_maps("id,start_time,end_time", where, "start_time", dbif)
  91. if not rows:
  92. dbif.close()
  93. grass.fatal(_("Space time raster dataset <%s> is empty") % input)
  94. # Modify the start time to fit the granularity
  95. if sp.is_time_absolute():
  96. first_start_time = tgis.adjust_datetime_to_granularity(
  97. rows[0]["start_time"], gran)
  98. else:
  99. first_start_time = rows[0]["start_time"]
  100. # We use the end time first
  101. last_start_time = rows[len(rows) - 1]["end_time"]
  102. is_end_time = True
  103. # In case no end time is available, then we use the start time
  104. if last_start_time is None:
  105. last_start_time = rows[len(rows) - 1]["start_time"]
  106. is_end_time = False
  107. next_start_time = first_start_time
  108. count = 0
  109. while True:
  110. if is_end_time is True:
  111. if next_start_time >= last_start_time:
  112. break
  113. else:
  114. if next_start_time > last_start_time:
  115. break
  116. start = next_start_time
  117. if sp.is_time_absolute():
  118. end = tgis.increment_datetime_by_string(next_start_time, gran)
  119. else:
  120. end = next_start_time + int(gran)
  121. next_start_time = end
  122. input_map_names = tgis.collect_map_names(
  123. sp, dbif, start, end, sampling)
  124. if input_map_names:
  125. new_map = tgis.aggregate_raster_maps(
  126. input_map_names, base, start, end,
  127. count, method, register_null, dbif, offset)
  128. if new_map:
  129. # Set the time stamp and write it to the raster map
  130. if sp.is_time_absolute():
  131. new_map.set_absolute_time(start, end)
  132. else:
  133. new_map.set_relative_time(start,
  134. end, sp.get_relative_time_unit())
  135. # Insert map in temporal database
  136. new_map.insert(dbif)
  137. new_sp.register_map(new_map, dbif)
  138. count += 1
  139. # Update the spatio-temporal extent and the raster metadata table entries
  140. new_sp.set_aggregation_type(method)
  141. new_sp.metadata.update(dbif)
  142. new_sp.update_from_registered_maps(dbif)
  143. dbif.close()
  144. if __name__ == "__main__":
  145. options, flags = grass.parser()
  146. main()