t.rast.to.rast3.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. ############################################################################
  4. #
  5. # MODULE: t.rast.to.rast3
  6. # AUTHOR(S): Soeren Gebbert
  7. #
  8. # PURPOSE: Convert a space time raster dataset into a 3D raster map
  9. # COPYRIGHT: (C) 2011-2014 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: Converts a space time raster dataset into a 3D raster map.
  18. #% keywords: temporal
  19. #% keywords: conversion
  20. #% keywords: raster3d
  21. #%end
  22. #%option G_OPT_STRDS_INPUT
  23. #%end
  24. #%option G_OPT_R3_OUTPUT
  25. #%end
  26. import os
  27. import grass.script as grass
  28. import grass.temporal as tgis
  29. from datetime import datetime
  30. from grass.exceptions import CalledModuleError
  31. ############################################################################
  32. def main():
  33. # Get the options
  34. input = options["input"]
  35. output = options["output"]
  36. # Make sure the temporal database exists
  37. tgis.init()
  38. mapset = grass.gisenv()["MAPSET"]
  39. sp = tgis.open_old_stds(input, "strds")
  40. grass.use_temp_region()
  41. maps = sp.get_registered_maps_as_objects_by_granularity()
  42. num_maps = len(maps)
  43. # get datatype of the first map
  44. if maps:
  45. maps[0][0].select()
  46. datatype = maps[0][0].metadata.get_datatype()
  47. else:
  48. datatype = None
  49. # Get the granularity and set bottom, top and top-bottom resolution
  50. granularity = sp.get_granularity()
  51. # This is the reference time to scale the z coordinate
  52. reftime = datetime(1900, 1, 1)
  53. # We set top and bottom according to the start time in relation
  54. # to the date 1900-01-01 00:00:00
  55. # In case of days, hours, minutes and seconds, a double number
  56. # is used to represent days and fracs of a day
  57. # Space time voxel cubes with montly or yearly granularity can not be
  58. # mixed with other temporal units
  59. # Compatible temporal units are : days, hours, minutes and seconds
  60. # Incompatible are years and moths
  61. start, end = sp.get_temporal_extent_as_tuple()
  62. if sp.is_time_absolute():
  63. unit = granularity.split(" ")[1]
  64. granularity = float(granularity.split(" ")[0])
  65. print "Gran from stds %0.15f"%(granularity)
  66. if unit == "years" or unit == "year":
  67. bottom = float(start.year - 1900)
  68. top = float(granularity * num_maps)
  69. elif unit == "months" or unit == "month":
  70. bottom = float((start.year - 1900) * 12 + start.month)
  71. top = float(granularity * num_maps)
  72. else:
  73. bottom = float(tgis.time_delta_to_relative_time(start - reftime))
  74. days = 0.0
  75. hours = 0.0
  76. minutes = 0.0
  77. seconds = 0.0
  78. if unit == "days" or unit == "day":
  79. days = float(granularity)
  80. if unit == "hours" or unit == "hour":
  81. hours = float(granularity)
  82. if unit == "minutes" or unit == "minute":
  83. minutes = float(granularity)
  84. if unit == "seconds" or unit == "second":
  85. seconds = float(granularity)
  86. granularity = float(days + hours / 24.0 + minutes / \
  87. 1440.0 + seconds / 86400.0)
  88. else:
  89. unit = sp.get_relative_time_unit()
  90. bottom = start
  91. top = float(bottom + granularity * float(num_maps))
  92. try:
  93. grass.run_command("g.region", t=top, b=bottom, tbres=granularity)
  94. except CalledModuleError:
  95. grass.fatal(_("Unable to set 3D region"))
  96. # Create a NULL map to fill the gaps
  97. null_map = "temporary_null_map_%i" % os.getpid()
  98. if datatype == 'DCELL':
  99. grass.mapcalc("%s = double(null())" % (null_map))
  100. elif datatype == 'FCELL':
  101. grass.mapcalc("%s = float(null())" % (null_map))
  102. else:
  103. grass.mapcalc("%s = null()" % (null_map))
  104. if maps:
  105. count = 0
  106. map_names = ""
  107. for map in maps:
  108. # Use the first map
  109. id = map[0].get_id()
  110. # None ids will be replaced by NULL maps
  111. if id is None:
  112. id = null_map
  113. if count == 0:
  114. map_names = id
  115. else:
  116. map_names += ",%s" % id
  117. count += 1
  118. try:
  119. grass.run_command("r.to.rast3", input=map_names,
  120. output=output, overwrite=grass.overwrite())
  121. except CalledModuleError:
  122. grass.fatal(_("Unable to create 3D raster map <%s>" % output))
  123. grass.run_command("g.remove", type='rast', name=null_map, flags='f')
  124. title = _("Space time voxel cube")
  125. descr = _("This space time voxel cube was created with t.rast.to.rast3")
  126. # Set the unit
  127. try:
  128. grass.run_command("r3.support", map=output, vunit=unit,
  129. title=title, description=descr,
  130. overwrite=grass.overwrite())
  131. except CalledModuleError:
  132. grass.warning(_("%s failed to set units.") % 'r3.support')
  133. # Register the space time voxel cube in the temporal GIS
  134. if output.find("@") >= 0:
  135. id = output
  136. else:
  137. id = output + "@" + mapset
  138. start, end = sp.get_temporal_extent_as_tuple()
  139. r3ds = tgis.Raster3DDataset(id)
  140. if r3ds.is_in_db():
  141. r3ds.select()
  142. r3ds.delete()
  143. r3ds = tgis.Raster3DDataset(id)
  144. r3ds.load()
  145. if sp.is_time_absolute():
  146. r3ds.set_absolute_time(start, end)
  147. else:
  148. r3ds.set_relative_time(start, end, sp.get_relative_time_unit())
  149. r3ds.insert()
  150. if __name__ == "__main__":
  151. options, flags = grass.parser()
  152. main()