r.pack.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #!/usr/bin/env python3
  2. ############################################################################
  3. #
  4. # MODULE: r.pack
  5. # AUTHOR(S): Hamish Bowman, Otago University, New Zealand
  6. # Converted to Python by Martin Landa <landa.martin gmail.com>
  7. # PURPOSE: Pack up a raster map, collect raster map elements => gzip
  8. # COPYRIGHT: (C) 2004-2013 by the GRASS Development Team
  9. #
  10. # This program is free software under the GNU General
  11. # Public License (>=v2). Read the file COPYING that
  12. # comes with GRASS for details.
  13. #
  14. #############################################################################
  15. # %module
  16. # % description: Exports a raster map as GRASS GIS specific archive file
  17. # % keyword: raster
  18. # % keyword: export
  19. # % keyword: copying
  20. # %end
  21. # %option G_OPT_R_INPUT
  22. # % description: Name of raster map to pack up
  23. # %end
  24. # %option G_OPT_F_OUTPUT
  25. # % description: Name for output file (default is <input>.pack)
  26. # % required : no
  27. # %end
  28. # %flag
  29. # % key: c
  30. # % description: Switch the compression off
  31. # %end
  32. import os
  33. import sys
  34. import shutil
  35. import atexit
  36. import tarfile
  37. from grass.script.utils import try_rmdir, try_remove
  38. from grass.script import core as grass
  39. def cleanup():
  40. try_rmdir(tmp)
  41. def main():
  42. infile = options["input"]
  43. compression_off = flags["c"]
  44. mapset = None
  45. if "@" in infile:
  46. infile, mapset = infile.split("@")
  47. if options["output"]:
  48. outfile_path, outfile_base = os.path.split(os.path.abspath(options["output"]))
  49. else:
  50. outfile_path, outfile_base = os.path.split(os.path.abspath(infile + ".pack"))
  51. outfile = os.path.join(outfile_path, outfile_base)
  52. global tmp
  53. tmp = grass.tempdir()
  54. tmp_dir = os.path.join(tmp, infile)
  55. os.mkdir(tmp_dir)
  56. grass.debug("tmp_dir = %s" % tmp_dir)
  57. gfile = grass.find_file(name=infile, element="cell", mapset=mapset)
  58. if not gfile["name"]:
  59. grass.fatal(_("Raster map <%s> not found") % infile)
  60. if os.path.exists(outfile):
  61. if os.getenv("GRASS_OVERWRITE"):
  62. grass.warning(
  63. _("Pack file <%s> already exists and will be overwritten") % outfile
  64. )
  65. try_remove(outfile)
  66. else:
  67. grass.fatal(_("option <output>: <%s> exists.") % outfile)
  68. grass.message(_("Packing <%s> to <%s>...") % (gfile["fullname"], outfile))
  69. basedir = os.path.sep.join(os.path.normpath(gfile["file"]).split(os.path.sep)[:-2])
  70. olddir = os.getcwd()
  71. # copy elements
  72. info = grass.parse_command("r.info", flags="e", map=infile)
  73. vrt_files = {}
  74. if info["maptype"] == "virtual":
  75. map_file = grass.find_file(
  76. name=infile,
  77. element="cell_misc",
  78. )
  79. if map_file["file"]:
  80. vrt = os.path.join(map_file["file"], "vrt")
  81. if os.path.exists(vrt):
  82. with open(vrt, "r") as f:
  83. for r in f.readlines():
  84. map, mapset = r.split("@")
  85. map_basedir = os.path.sep.join(
  86. os.path.normpath(map_file["file"],).split(
  87. os.path.sep
  88. )[:-2],
  89. )
  90. vrt_files[map] = map_basedir
  91. for element in [
  92. "cats",
  93. "cell",
  94. "cellhd",
  95. "cell_misc",
  96. "colr",
  97. "fcell",
  98. "hist",
  99. ]:
  100. path = os.path.join(basedir, element, infile)
  101. if os.path.exists(path):
  102. grass.debug("copying %s" % path)
  103. if os.path.isfile(path):
  104. shutil.copyfile(
  105. path,
  106. os.path.join(tmp_dir, element),
  107. )
  108. else:
  109. shutil.copytree(
  110. path,
  111. os.path.join(tmp_dir, element),
  112. )
  113. # Copy vrt files
  114. if vrt_files:
  115. for f in vrt_files.keys():
  116. f_tmp_dir = os.path.join(tmp, f)
  117. if not os.path.exists(f_tmp_dir):
  118. os.mkdir(f_tmp_dir)
  119. path = os.path.join(vrt_files[f], element, f)
  120. if os.path.exists(path):
  121. grass.debug("copying vrt file {}".format(path))
  122. if os.path.isfile(path):
  123. shutil.copyfile(
  124. path,
  125. os.path.join(f_tmp_dir, element),
  126. )
  127. else:
  128. shutil.copytree(
  129. path,
  130. os.path.join(f_tmp_dir, element),
  131. )
  132. if not os.listdir(tmp_dir):
  133. grass.fatal(_("No raster map components found"))
  134. # copy projection info
  135. # (would prefer to use g.proj*, but this way is 5.3 and 5.7 compat)
  136. gisenv = grass.gisenv()
  137. for support in ["INFO", "UNITS", "EPSG"]:
  138. path = os.path.join(
  139. gisenv["GISDBASE"], gisenv["LOCATION_NAME"], "PERMANENT", "PROJ_" + support
  140. )
  141. if os.path.exists(path):
  142. shutil.copyfile(path, os.path.join(tmp_dir, "PROJ_" + support))
  143. # pack it all up
  144. os.chdir(tmp)
  145. if compression_off:
  146. tar = tarfile.TarFile.open(name=outfile_base, mode="w:")
  147. else:
  148. tar = tarfile.TarFile.open(name=outfile_base, mode="w:gz")
  149. tar.add(infile, recursive=True)
  150. if vrt_files:
  151. for f in vrt_files.keys():
  152. tar.add(f, recursive=True)
  153. tar.close()
  154. try:
  155. shutil.move(outfile_base, outfile)
  156. except shutil.Error as e:
  157. grass.fatal(e)
  158. os.chdir(olddir)
  159. grass.verbose(_("Raster map saved to '%s'" % outfile))
  160. if __name__ == "__main__":
  161. options, flags = grass.parser()
  162. atexit.register(cleanup)
  163. sys.exit(main())