stds_export.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  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) 2012-2013 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 import *
  28. from factory import *
  29. from open_stds import *
  30. from grass.exceptions import CalledModuleError
  31. proj_file_name = "proj.txt"
  32. init_file_name = "init.txt"
  33. metadata_file_name = "metadata.txt"
  34. read_file_name = "readme.txt"
  35. list_file_name = "list.txt"
  36. tmp_tar_file_name = "archive"
  37. # This global variable is for unique vector map export,
  38. # since single vector maps may have several layer
  39. # and therefore several attribute tables
  40. exported_maps = {}
  41. ############################################################################
  42. def _export_raster_maps_as_gdal(rows, tar, list_file, new_cwd, fs, format_):
  43. for row in rows:
  44. name = row["name"]
  45. start = row["start_time"]
  46. end = row["end_time"]
  47. max_val = row["max"]
  48. min_val = row["min"]
  49. datatype = row["datatype"]
  50. if not end:
  51. end = start
  52. string = "%s%s%s%s%s\n" % (name, fs, start, fs, end)
  53. # Write the filename, the start_time and the end_time
  54. list_file.write(string)
  55. try:
  56. if format_ == "GTiff":
  57. # Export the raster map with r.out.gdal as tif
  58. out_name = name + ".tif"
  59. if datatype == "CELL":
  60. nodata = max_val + 1
  61. if nodata < 256 and min_val >= 0:
  62. gdal_type = "Byte"
  63. elif nodata < 65536 and min_val >= 0:
  64. gdal_type = "UInt16"
  65. elif min_val >= 0:
  66. gdal_type = "UInt32"
  67. else:
  68. gdal_type = "Int32"
  69. gscript.run_command("r.out.gdal", flags="c", input=name,
  70. output=out_name, nodata=nodata,
  71. type=gdal_type, format="GTiff")
  72. else:
  73. gscript.run_command("r.out.gdal", flags="c",
  74. input=name, output=out_name,
  75. format="GTiff")
  76. elif format_ == "AAIGrid":
  77. # Export the raster map with r.out.gdal as Arc/Info ASCII Grid
  78. out_name = name + ".asc"
  79. gscript.run_command("r.out.gdal", flags="c", input=name,
  80. output=out_name, format="AAIGrid")
  81. except CalledModuleError:
  82. shutil.rmtree(new_cwd)
  83. tar.close()
  84. core.fatal(_("Unable to export raster map <%s>" % name))
  85. tar.add(out_name)
  86. # Export the color rules
  87. out_name = name + ".color"
  88. try:
  89. gscript.run_command("r.colors.out", map=name, rules=out_name)
  90. except CalledModuleError:
  91. shutil.rmtree(new_cwd)
  92. tar.close()
  93. core.fatal(_("Unable to export color rules for raster "
  94. "map <%s> r.out.gdal" % name))
  95. tar.add(out_name)
  96. ############################################################################
  97. def _export_raster_maps(rows, tar, list_file, new_cwd, fs):
  98. for row in rows:
  99. name = row["name"]
  100. start = row["start_time"]
  101. end = row["end_time"]
  102. if not end:
  103. end = start
  104. string = "%s%s%s%s%s\n" % (name, fs, start, fs, end)
  105. # Write the filename, the start_time and the end_time
  106. list_file.write(string)
  107. # Export the raster map with r.pack
  108. try:
  109. gscript.run_command("r.pack", input=name, flags="c")
  110. except CalledModuleError:
  111. shutil.rmtree(new_cwd)
  112. tar.close()
  113. core.fatal(_("Unable to export raster map <%s> with r.pack" %
  114. name))
  115. tar.add(name + ".pack")
  116. ############################################################################
  117. def _export_vector_maps_as_gml(rows, tar, list_file, new_cwd, fs):
  118. for row in rows:
  119. name = row["name"]
  120. start = row["start_time"]
  121. end = row["end_time"]
  122. layer = row["layer"]
  123. if not layer:
  124. layer = 1
  125. if not end:
  126. end = start
  127. string = "%s%s%s%s%s\n" % (name, fs, start, fs, end)
  128. # Write the filename, the start_time and the end_time
  129. list_file.write(string)
  130. # Export the vector map with v.out.ogr
  131. try:
  132. gscript.run_command("v.out.ogr", input=name, dsn=(name + ".xml"),
  133. layer=layer, format="GML")
  134. except CalledModuleError:
  135. shutil.rmtree(new_cwd)
  136. tar.close()
  137. core.fatal(_("Unable to export vector map <%s> as "
  138. "GML with v.out.ogr" % name))
  139. tar.add(name + ".xml")
  140. tar.add(name + ".xsd")
  141. ############################################################################
  142. def _export_vector_maps(rows, tar, list_file, new_cwd, fs):
  143. for row in rows:
  144. name = row["name"]
  145. start = row["start_time"]
  146. end = row["end_time"]
  147. layer = row["layer"]
  148. # Export unique maps only
  149. if name in exported_maps:
  150. continue
  151. if not layer:
  152. layer = 1
  153. if not end:
  154. end = start
  155. string = "%s:%s%s%s%s%s\n" % (name, layer, fs, start, fs, end)
  156. # Write the filename, the start_time and the end_time
  157. list_file.write(string)
  158. # Export the vector map with v.pack
  159. try:
  160. gscript.run_command("v.pack", input=name, flags="c")
  161. except CalledModuleError:
  162. shutil.rmtree(new_cwd)
  163. tar.close()
  164. core.fatal(_("Unable to export vector map <%s> with v.pack" %
  165. name))
  166. tar.add(name + ".pack")
  167. exported_maps[name] = name
  168. ############################################################################
  169. def _export_raster3d_maps(rows, tar, list_file, new_cwd, fs):
  170. for row in rows:
  171. name = row["name"]
  172. start = row["start_time"]
  173. end = row["end_time"]
  174. if not end:
  175. end = start
  176. string = "%s%s%s%s%s\n" % (name, fs, start, fs, end)
  177. # Write the filename, the start_time and the end_time
  178. list_file.write(string)
  179. # Export the raster 3d map with r3.pack
  180. try:
  181. gscript.run_command("r3.pack", input=name, flags="c")
  182. except CalledModuleError:
  183. shutil.rmtree(new_cwd)
  184. tar.close()
  185. core.fatal(_("Unable to export raster map <%s> with r3.pack" %
  186. name))
  187. tar.add(name + ".pack")
  188. ############################################################################
  189. def export_stds(input, output, compression, workdir, where, format_="pack",
  190. type_="strds"):
  191. """
  192. !Export space time datasets as tar archive with optional compression
  193. This method should be used to export space time datasets
  194. of type raster and vector as tar archive that can be reimported
  195. with the method import_stds().
  196. @param input The name of the space time dataset to export
  197. @param output The name of the archive file
  198. @param compression The compression of the archive file:
  199. - "no" no compression
  200. - "gzip" GNU zip compression
  201. - "bzip2" Bzip compression
  202. @param workdir The working directory used for extraction and packing
  203. @param where The temporal WHERE SQL statement to select a subset
  204. of maps from the space time dataset
  205. @param format_ The export format:
  206. - "GTiff" Geotiff format, only for raster maps
  207. - "AAIGrid" Arc/Info ASCII Grid format, only for raster maps
  208. - "pack" The GRASS raster, 3D raster or vector Pack format,
  209. this is the default setting
  210. - "GML" GML file export format, only for vector maps,
  211. v.out.ogr export option
  212. @param type_ The space time dataset type
  213. - "strds" Space time raster dataset
  214. - "str3ds" Space time 3D raster dataset
  215. - "stvds" Space time vector dataset
  216. """
  217. # Save current working directory path
  218. old_cwd = os.getcwd()
  219. # Create the temporary directory and jump into it
  220. new_cwd = tempfile.mkdtemp(dir=workdir)
  221. os.chdir(new_cwd)
  222. if type_ == "strds":
  223. columns = "name,start_time,end_time,min,max,datatype"
  224. elif type_ == "stvds":
  225. columns = "name,start_time,end_time,layer"
  226. else:
  227. columns = "name,start_time,end_time"
  228. sp = open_old_space_time_dataset(input, type_)
  229. rows = sp.get_registered_maps(columns, where, "start_time", None)
  230. if compression == "gzip":
  231. flag = "w:gz"
  232. elif compression == "bzip2":
  233. flag = "w:bz2"
  234. else:
  235. flag = "w:"
  236. # Open the tar archive to add the files
  237. tar = tarfile.open(tmp_tar_file_name, flag)
  238. list_file = open(list_file_name, "w")
  239. fs = "|"
  240. if rows:
  241. if type_ == "strds":
  242. if format_ == "GTiff" or format_ == "AAIGrid":
  243. _export_raster_maps_as_gdal(
  244. rows, tar, list_file, new_cwd, fs, format_)
  245. else:
  246. _export_raster_maps(rows, tar, list_file, new_cwd, fs)
  247. elif type_ == "stvds":
  248. if format_ == "GML":
  249. _export_vector_maps_as_gml(rows, tar, list_file, new_cwd, fs)
  250. else:
  251. _export_vector_maps(rows, tar, list_file, new_cwd, fs)
  252. elif type_ == "str3ds":
  253. _export_raster3d_maps(rows, tar, list_file, new_cwd, fs)
  254. list_file.close()
  255. # Write projection and metadata
  256. proj = core.read_command("g.proj", flags="j")
  257. proj_file = open(proj_file_name, "w")
  258. proj_file.write(proj)
  259. proj_file.close()
  260. init_file = open(init_file_name, "w")
  261. # Create the init string
  262. string = ""
  263. # This is optional, if not present strds will be assumed for backward
  264. # compatibility
  265. string += "%s=%s\n" % ("stds_type", sp.get_type())
  266. # This is optional, if not present gtiff will be assumed for
  267. # backward compatibility
  268. string += "%s=%s\n" % ("format", format_)
  269. string += "%s=%s\n" % ("temporal_type", sp.get_temporal_type())
  270. string += "%s=%s\n" % ("semantic_type", sp.get_semantic_type())
  271. if sp.is_time_relative():
  272. string += "%s=%s\n" % ("relative_time_unit",
  273. sp.get_relative_time_unit())
  274. string += "%s=%s\n" % ("number_of_maps", sp.metadata.get_number_of_maps())
  275. north, south, east, west, top, bottom = sp.get_spatial_extent_as_tuple()
  276. string += "%s=%s\n" % ("north", north)
  277. string += "%s=%s\n" % ("south", south)
  278. string += "%s=%s\n" % ("east", east)
  279. string += "%s=%s\n" % ("west", west)
  280. init_file.write(string)
  281. init_file.close()
  282. metadata = core.read_command("t.info", type=type_, input=sp.get_id())
  283. metadata_file = open(metadata_file_name, "w")
  284. metadata_file.write(metadata)
  285. metadata_file.close()
  286. read_file = open(read_file_name, "w")
  287. if type_ == "strds":
  288. read_file.write("This space time raster dataset was exported with "
  289. "t.rast.export of GRASS GIS 7\n")
  290. elif type_ == "stvds":
  291. read_file.write("This space time vector dataset was exported with "
  292. "t.vect.export of GRASS GIS 7\n")
  293. elif type_ == "str3ds":
  294. read_file.write("This space time 3D raster dataset was exported "
  295. "with t.rast3d.export of GRASS GIS 7\n")
  296. read_file.write("\n")
  297. read_file.write("Files:\n")
  298. if type_ == "strds":
  299. if format_ == "GTiff":
  300. #123456789012345678901234567890
  301. read_file.write(" *.tif -- GeoTIFF raster files\n")
  302. read_file.write(" *.color -- GRASS GIS raster color rules\n")
  303. elif format_ == "pack":
  304. read_file.write(" *.pack -- GRASS raster files packed with r.pack\n")
  305. elif type_ == "stvds":
  306. #123456789012345678901234567890
  307. if format_ == "GML":
  308. read_file.write(" *.xml -- Vector GML files\n")
  309. else:
  310. read_file.write(" *.pack -- GRASS vector files packed with v.pack\n")
  311. elif type_ == "str3ds":
  312. read_file.write(" *.pack -- GRASS 3D raster files packed with r3.pack\n")
  313. read_file.write("%13s -- Projection information in PROJ.4 format\n" %
  314. (proj_file_name))
  315. read_file.write("%13s -- GRASS GIS space time %s dataset information\n" %
  316. (init_file_name, sp.get_new_map_instance(None).get_type()))
  317. read_file.write("%13s -- Time series file, lists all maps by name "
  318. "with interval\n" % (list_file_name))
  319. read_file.write(" time stamps in ISO-Format. Field separator is |\n")
  320. read_file.write("%13s -- The output of t.info\n" %
  321. (metadata_file_name))
  322. read_file.write("%13s -- This file\n" % (read_file_name))
  323. read_file.close()
  324. # Append the file list
  325. tar.add(list_file_name)
  326. tar.add(proj_file_name)
  327. tar.add(init_file_name)
  328. tar.add(read_file_name)
  329. tar.add(metadata_file_name)
  330. tar.close()
  331. os.chdir(old_cwd)
  332. # Move the archive to its destination
  333. shutil.move(os.path.join(new_cwd, tmp_tar_file_name), output)
  334. # Remove the temporary created working directory
  335. shutil.rmtree(new_cwd)