stds_export.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. """!@package grass.temporal
  2. @brief GRASS Python scripting module (temporal GIS functions)
  3. Temporal GIS export functions to be used in temporal modules
  4. Usage:
  5. @code
  6. import grass.temporal as tgis
  7. input="temp_1950_2012@PERMANENT"
  8. output="/tmp/temp_1950_2012.tar.gz"
  9. compression="gzip"
  10. workdir="/tmp"
  11. where=None
  12. _format="GTiff"
  13. _type="strds"
  14. tgis.export_stds(input, output, compression, workdir, where, _format, _type)
  15. ...
  16. @endcode
  17. (C) 2008-2011 by the GRASS Development Team
  18. This program is free software under the GNU General Public
  19. License (>=v2). Read the file COPYING that comes with GRASS
  20. for details.
  21. @author Soeren Gebbert
  22. """
  23. import shutil
  24. import os
  25. import tarfile
  26. import tempfile
  27. from space_time_datasets_tools import *
  28. proj_file_name = "proj.txt"
  29. init_file_name = "init.txt"
  30. metadata_file_name = "metadata.txt"
  31. read_file_name = "readme.txt"
  32. list_file_name = "list.txt"
  33. tmp_tar_file_name = "archive"
  34. # This global variable is for unique vector map export,
  35. # since single vector maps may have several layer
  36. # and therefore several attribute tables
  37. exported_maps = {}
  38. ############################################################################
  39. def _export_raster_maps_as_geotiff(rows, tar, list_file, new_cwd, fs):
  40. for row in rows:
  41. name = row["name"]
  42. start = row["start_time"]
  43. end = row["end_time"]
  44. max_val = row["max"]
  45. min_val = row["min"]
  46. datatype = row["datatype"]
  47. if not end:
  48. end = start
  49. string = "%s%s%s%s%s\n" % (name, fs, start, fs, end)
  50. # Write the filename, the start_time and the end_time
  51. list_file.write(string)
  52. # Export the raster map with r.out.gdal as tif
  53. out_name = name + ".tif"
  54. if datatype == "CELL":
  55. nodata = max_val + 1
  56. if nodata < 256 and min_val >= 0:
  57. gdal_type = "Byte"
  58. elif nodata < 65536 and min_val >= 0:
  59. gdal_type = "UInt16"
  60. elif min_val >= 0:
  61. gdal_type = "UInt32"
  62. else:
  63. gdal_type = "Int32"
  64. ret = core.run_command("r.out.gdal", flags="c", input=name, output=out_name, nodata=nodata, type=gdal_type, format="GTiff")
  65. else:
  66. ret = core.run_command("r.out.gdal", flags="c", input=name, output=out_name, format="GTiff")
  67. if ret != 0:
  68. shutil.rmtree(new_cwd)
  69. tar.close()
  70. core.fatal(_("Unable to export raster map <%s>" % name))
  71. tar.add(out_name)
  72. # Export the color rules
  73. out_name = name + ".color"
  74. ret = core.run_command("r.colors.out", map=name, rules=out_name)
  75. if ret != 0:
  76. shutil.rmtree(new_cwd)
  77. tar.close()
  78. core.fatal(_("Unable to export color rules for raster map <%s> r.out.gdal" % name))
  79. tar.add(out_name)
  80. ############################################################################
  81. def _export_raster_maps(rows, tar, list_file, new_cwd, fs):
  82. for row in rows:
  83. name = row["name"]
  84. start = row["start_time"]
  85. end = row["end_time"]
  86. if not end:
  87. end = start
  88. string = "%s%s%s%s%s\n" % (name, fs, start, fs, end)
  89. # Write the filename, the start_time and the end_time
  90. list_file.write(string)
  91. # Export the raster map with r.pack
  92. ret = core.run_command("r.pack", input=name, flags="c")
  93. if ret != 0:
  94. shutil.rmtree(new_cwd)
  95. tar.close()
  96. core.fatal(_("Unable to export raster map <%s> with r.pack" % name))
  97. tar.add(name + ".pack")
  98. ############################################################################
  99. def _export_vector_maps_as_gml(rows, tar, list_file, new_cwd, fs):
  100. for row in rows:
  101. name = row["name"]
  102. start = row["start_time"]
  103. end = row["end_time"]
  104. layer = row["layer"]
  105. if not layer:
  106. layer = 1
  107. if not end:
  108. end = start
  109. string = "%s%s%s%s%s\n" % (name, fs, start, fs, end)
  110. # Write the filename, the start_time and the end_time
  111. list_file.write(string)
  112. # Export the vector map with v.out.ogr
  113. ret = core.run_command("v.out.ogr", input=name, dsn=(name + ".xml"), layer=layer, format="GML")
  114. if ret != 0:
  115. shutil.rmtree(new_cwd)
  116. tar.close()
  117. core.fatal(_("Unable to export vector map <%s> as GML with v.out.ogr" % name))
  118. tar.add(name + ".xml")
  119. tar.add(name + ".xsd")
  120. ############################################################################
  121. def _export_vector_maps(rows, tar, list_file, new_cwd, fs):
  122. for row in rows:
  123. name = row["name"]
  124. start = row["start_time"]
  125. end = row["end_time"]
  126. layer = row["layer"]
  127. # Export unique maps only
  128. if name in exported_maps:
  129. continue
  130. if not layer:
  131. layer = 1
  132. if not end:
  133. end = start
  134. string = "%s:%s%s%s%s%s\n" % (name, layer, fs, start, fs, end)
  135. # Write the filename, the start_time and the end_time
  136. list_file.write(string)
  137. # Export the vector map with v.pack
  138. ret = core.run_command("v.pack", input=name, flags="c")
  139. if ret != 0:
  140. shutil.rmtree(new_cwd)
  141. tar.close()
  142. core.fatal(_("Unable to export vector map <%s> with v.pack" % name))
  143. tar.add(name + ".pack")
  144. exported_maps[name] = name
  145. ############################################################################
  146. def _export_raster3d_maps(rows, tar, list_file, new_cwd, fs):
  147. for row in rows:
  148. name = row["name"]
  149. start = row["start_time"]
  150. end = row["end_time"]
  151. if not end:
  152. end = start
  153. string = "%s%s%s%s%s\n" % (name, fs, start, fs, end)
  154. # Write the filename, the start_time and the end_time
  155. list_file.write(string)
  156. # Export the raster map with r3.pack
  157. ret = core.run_command("r3.pack", input=name, flags="c")
  158. if ret != 0:
  159. shutil.rmtree(new_cwd)
  160. tar.close()
  161. core.fatal(_("Unable to export raster map <%s> with r3.pack" % name))
  162. tar.add(name + ".pack")
  163. ############################################################################
  164. def export_stds(input, output, compression, workdir, where, _format="pack", _type="strds"):
  165. """
  166. !Export space time datasets as tar archive with optional compression
  167. This method should be used to export space time datasets of type raster and vector
  168. as tar archive that can be reimported with the method import_stds().
  169. @param input The name of the space time dataset to export
  170. @param output The name of the archive file
  171. @param compression The compression of the archive file:
  172. * "no" no compression
  173. * "gzip" GNU zip compression
  174. * "bzip2" Bzip compression
  175. @param workdir The working directory used for extraction and packing
  176. @param where The temporal WHERE SQL statement to select a subset of maps from the space time dataset
  177. @param _format The export format:
  178. * "GTiff" Geotiff format, only for raster maps
  179. * "pack" The GRASS raster, 3D raster or vector Pack format, this is the default setting
  180. * "GML" GML file export format, only for vector maps, v.out.ogr export option
  181. @param type The space time dataset type
  182. * "strds" Space time raster dataset
  183. * "str3ds" Space time 3D raster dataset
  184. * "stvds" Space time vector dataset
  185. """
  186. mapset = core.gisenv()["MAPSET"]
  187. if input.find("@") >= 0:
  188. id = input
  189. else:
  190. id = input + "@" + mapset
  191. sp = dataset_factory(_type, id)
  192. if sp.is_in_db() == False:
  193. core.fatal(_("Space time %s dataset <%s> not found") % (sp.get_new_map_instance(None).get_type(), id))
  194. # Save current working directory path
  195. old_cwd = os.getcwd()
  196. # Create the temporary directory and jump into it
  197. new_cwd = tempfile.mkdtemp(dir=workdir)
  198. os.chdir(new_cwd)
  199. sp.select()
  200. if _type == "strds":
  201. columns = "name,start_time,end_time,min,max,datatype"
  202. elif _type == "stvds":
  203. columns = "name,start_time,end_time,layer"
  204. else:
  205. columns = "name,start_time,end_time"
  206. rows = sp.get_registered_maps(columns, where, "start_time", None)
  207. if compression == "gzip":
  208. flag = "w:gz"
  209. elif compression == "bzip2":
  210. flag = "w:bz2"
  211. else:
  212. flag = "w:"
  213. # Open the tar archive to add the files
  214. tar = tarfile.open(tmp_tar_file_name, flag)
  215. list_file = open(list_file_name, "w")
  216. fs = "|"
  217. if rows:
  218. if _type == "strds":
  219. if _format == "GTiff":
  220. _export_raster_maps_as_geotiff(rows, tar, list_file, new_cwd, fs)
  221. else:
  222. _export_raster_maps(rows, tar, list_file, new_cwd, fs)
  223. elif _type == "stvds":
  224. if _format == "GML":
  225. _export_vector_maps_as_gml(rows, tar, list_file, new_cwd, fs)
  226. else:
  227. _export_vector_maps(rows, tar, list_file, new_cwd, fs)
  228. elif _type == "str3ds":
  229. _export_raster3d_maps(rows, tar, list_file, new_cwd, fs)
  230. list_file.close()
  231. # Write projection and metadata
  232. proj = core.read_command("g.proj", flags="j")
  233. proj_file = open(proj_file_name, "w")
  234. proj_file.write(proj)
  235. proj_file.close()
  236. init_file = open(init_file_name, "w")
  237. # Create the init string
  238. string = ""
  239. string += "%s=%s\n" % ("stds_type", sp.get_type()) # This is optional, if not present strds will be assumed for backward compatibility
  240. string += "%s=%s\n" % ("format", _format) # This is optional, if not present gtiff will be assumed for backward compatibility
  241. string += "%s=%s\n" % ("temporal_type", sp.get_temporal_type())
  242. string += "%s=%s\n" % ("semantic_type", sp.get_semantic_type())
  243. string += "%s=%s\n" % ("number_of_maps", sp.metadata.get_number_of_maps())
  244. north, south, east, west, top, bottom = sp.get_spatial_extent()
  245. string += "%s=%s\n" % ("north", north)
  246. string += "%s=%s\n" % ("south", south)
  247. string += "%s=%s\n" % ("east", east)
  248. string += "%s=%s\n" % ("west", west)
  249. init_file.write(string)
  250. init_file.close()
  251. metadata = core.read_command("t.info", type=_type, input=id)
  252. metadata_file = open(metadata_file_name, "w")
  253. metadata_file.write(metadata)
  254. metadata_file.close()
  255. read_file = open(read_file_name, "w")
  256. if _type == "strds":
  257. read_file.write("This space time raster dataset was exported with t.rast.export of GRASS GIS 7\n")
  258. elif _type == "stvds":
  259. read_file.write("This space time vector dataset was exported with t.vect.export of GRASS GIS 7\n")
  260. elif _type == "str3ds":
  261. read_file.write("This space time 3D raster dataset was exported with t.rast3d.export of GRASS GIS 7\n")
  262. read_file.write("\n")
  263. read_file.write("Files:\n")
  264. if _type == "strds":
  265. if _format == "GTiff":
  266. #123456789012345678901234567890
  267. read_file.write(" *.tif -- GeoTIFF raster files\n")
  268. read_file.write(" *.color -- GRASS GIS raster color rules\n")
  269. elif _format == "pack":
  270. read_file.write(" *.pack -- GRASS raster files packed with r.pack\n")
  271. elif _type == "stvds":
  272. #123456789012345678901234567890
  273. if _format == "GML":
  274. read_file.write(" *.xml -- Vector GML files\n")
  275. else:
  276. read_file.write(" *.pack -- GRASS vector files packed with v.pack\n")
  277. elif _type == "str3ds":
  278. read_file.write(" *.pack -- GRASS 3D raster files packed with r3.pack\n")
  279. read_file.write("%13s -- Projection information in PROJ.4 format\n" % (proj_file_name))
  280. read_file.write("%13s -- GRASS GIS space time %s dataset information\n" % (init_file_name, sp.get_new_map_instance(None).get_type()))
  281. read_file.write("%13s -- Time series file, lists all maps by name with interval\n" % (list_file_name))
  282. read_file.write(" time stamps in ISO-Format. Field separator is |\n")
  283. read_file.write("%13s -- Projection information in PROJ.4 format\n" % (metadata_file_name))
  284. read_file.write("%13s -- This file\n" % (read_file_name))
  285. read_file.close()
  286. # Append the file list
  287. tar.add(list_file_name)
  288. tar.add(proj_file_name)
  289. tar.add(init_file_name)
  290. tar.add(read_file_name)
  291. tar.add(metadata_file_name)
  292. tar.close()
  293. os.chdir(old_cwd)
  294. # Move the archive to its destination
  295. shutil.move(os.path.join(new_cwd, tmp_tar_file_name), output)
  296. # Remove the temporary created working directory
  297. shutil.rmtree(new_cwd)