t.rast.to.rast3.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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 rast3d map
  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: Converts a space time raster dataset into a raster3d 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. ############################################################################
  31. def main():
  32. # Get the options
  33. input = options["input"]
  34. output = options["output"]
  35. # Make sure the temporal database exists
  36. tgis.init()
  37. mapset = grass.gisenv()["MAPSET"]
  38. if input.find("@") >= 0:
  39. id = input
  40. else:
  41. id = input + "@" + mapset
  42. sp = tgis.SpaceTimeRasterDataset(id)
  43. if sp.is_in_db() == False:
  44. grass.fatal(_("Space time %s dataset <%s> not found") % (
  45. sp.get_new_map_instance(None).get_type(), id))
  46. sp.select()
  47. grass.use_temp_region()
  48. maps = sp.get_registered_maps_as_objects_by_granularity()
  49. num_maps = len(maps)
  50. # Get the granularity and set bottom, top and top-bottom resolution
  51. granularity = sp.get_granularity()
  52. # This is the reference time to scale the z coordinate
  53. reftime = datetime(1900, 1, 1)
  54. # We set top and bottom according to the start time in relation
  55. # to the date 1900-01-01 00:00:00
  56. # In case of days, hours, minutes and seconds, a double number
  57. # is used to represent days and fracs of a day
  58. # Space time voxel cubes with montly or yearly granularity can not be
  59. # mixed with other temporal units
  60. # Compatible temporal units are : days, hours, minutes and seconds
  61. # Incompatible are years and moths
  62. start, end = sp.get_valid_time()
  63. if sp.is_time_absolute():
  64. unit = granularity.split(" ")[1]
  65. granularity = int(granularity.split(" ")[0])
  66. if unit == "years":
  67. bottom = start.year - 1900
  68. top = granularity * num_maps
  69. elif unit == "months":
  70. bottom = (start.year - 1900) * 12 + start.month
  71. top = granularity * num_maps
  72. else:
  73. bottom = tgis.time_delta_to_relative_time(start - reftime)
  74. days = 0
  75. hours = 0
  76. minutes = 0
  77. seconds = 0
  78. if unit == "days":
  79. days = granularity
  80. if unit == "hours":
  81. hours = granularity
  82. if unit == "minutes":
  83. minutes = granularity
  84. if unit == "seconds":
  85. seconds = granularity
  86. granularity = 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 = bottom + granularity * num_maps
  92. ret = grass.run_command("g.region", t=top, b=bottom, tbres=granularity)
  93. if ret != 0:
  94. grass.fatal(_("Unable to set 3d region"))
  95. # Create a NULL map to fill the gaps
  96. null_map = "temporary_null_map_%i" % os.getpid()
  97. grass.mapcalc("%s = null()" % (null_map))
  98. if maps:
  99. count = 0
  100. map_names = ""
  101. for map in maps:
  102. # Use the first map
  103. id = map[0].get_id()
  104. # None ids will be replaced by NULL maps
  105. if id is None:
  106. id = null_map
  107. if count == 0:
  108. map_names = id
  109. else:
  110. map_names += ",%s" % id
  111. count += 1
  112. ret = grass.run_command("r.to.rast3", input=map_names,
  113. output=output, overwrite=grass.overwrite())
  114. if ret != 0:
  115. grass.fatal(_("Unable to create raster3d map <%s>" % output))
  116. grass.run_command("g.remove", rast=null_map)
  117. title = _("Space time voxel cube")
  118. descr = _("This space time voxel cube was created with t.rast.to.rast3")
  119. # Set the unit
  120. ret = grass.run_command("r3.support", map=output, vunit=unit,
  121. title=title, description=descr,
  122. overwrite=grass.overwrite())
  123. # Register the space time voxel cube in the temporal GIS
  124. if output.find("@") >= 0:
  125. id = output
  126. else:
  127. id = output + "@" + mapset
  128. start, end = sp.get_valid_time()
  129. r3ds = tgis.Raster3DDataset(id)
  130. if r3ds.is_in_db():
  131. r3ds.select()
  132. r3ds.delete()
  133. r3ds = tgis.Raster3DDataset(id)
  134. r3ds.load()
  135. if sp.is_time_absolute():
  136. r3ds.set_absolute_time(start, end)
  137. else:
  138. r3ds.set_relative_time(start, end, sp.get_relative_time_unit())
  139. r3ds.insert()
  140. if __name__ == "__main__":
  141. options, flags = grass.parser()
  142. main()