r.pack.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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(_("Pack file <%s> already exists and will be overwritten") % outfile)
  63. try_remove(outfile)
  64. else:
  65. grass.fatal(_("option <output>: <%s> exists.") % outfile)
  66. grass.message(_("Packing <%s> to <%s>...") % (gfile['fullname'], outfile))
  67. basedir = os.path.sep.join(os.path.normpath(gfile['file']).split(os.path.sep)[:-2])
  68. olddir = os.getcwd()
  69. # copy elements
  70. info = grass.parse_command('r.info', flags='e', map=infile)
  71. vrt_files = {}
  72. if info['maptype'] == 'virtual':
  73. map_file = grass.find_file(
  74. name=infile, element='cell_misc',
  75. )
  76. if map_file['file']:
  77. vrt = os.path.join(map_file['file'], 'vrt')
  78. if os.path.exists(vrt):
  79. with open(vrt, 'r') as f:
  80. for r in f.readlines():
  81. map, mapset = r.split('@')
  82. map_basedir = os.path.sep.join(
  83. os.path.normpath(
  84. map_file['file'],
  85. ).split(os.path.sep)[:-2],
  86. )
  87. vrt_files[map] = map_basedir
  88. for element in [
  89. 'cats', 'cell', 'cellhd', 'cell_misc', 'colr', 'fcell',
  90. 'hist',
  91. ]:
  92. path = os.path.join(basedir, element, infile)
  93. if os.path.exists(path):
  94. grass.debug('copying %s' % path)
  95. if os.path.isfile(path):
  96. shutil.copyfile(
  97. path, os.path.join(tmp_dir, element),
  98. )
  99. else:
  100. shutil.copytree(
  101. path, os.path.join(tmp_dir, element),
  102. )
  103. # Copy vrt files
  104. if vrt_files:
  105. for f in vrt_files.keys():
  106. f_tmp_dir = os.path.join(tmp, f)
  107. if not os.path.exists(f_tmp_dir):
  108. os.mkdir(f_tmp_dir)
  109. path = os.path.join(vrt_files[f], element, f)
  110. if os.path.exists(path):
  111. grass.debug("copying vrt file {}".format(path))
  112. if os.path.isfile(path):
  113. shutil.copyfile(
  114. path, os.path.join(f_tmp_dir, element),
  115. )
  116. else:
  117. shutil.copytree(
  118. path, os.path.join(f_tmp_dir, element),
  119. )
  120. if not os.listdir(tmp_dir):
  121. grass.fatal(_("No raster map components found"))
  122. # copy projection info
  123. # (would prefer to use g.proj*, but this way is 5.3 and 5.7 compat)
  124. gisenv = grass.gisenv()
  125. for support in ['INFO', 'UNITS', 'EPSG']:
  126. path = os.path.join(gisenv['GISDBASE'], gisenv['LOCATION_NAME'],
  127. 'PERMANENT', 'PROJ_' + support)
  128. if os.path.exists(path):
  129. shutil.copyfile(path, os.path.join(tmp_dir, 'PROJ_' + support))
  130. # pack it all up
  131. os.chdir(tmp)
  132. if compression_off:
  133. tar = tarfile.TarFile.open(name=outfile_base, mode='w:')
  134. else:
  135. tar = tarfile.TarFile.open(name=outfile_base, mode='w:gz')
  136. tar.add(infile, recursive=True)
  137. if vrt_files:
  138. for f in vrt_files.keys():
  139. tar.add(f, recursive=True)
  140. tar.close()
  141. try:
  142. shutil.move(outfile_base, outfile)
  143. except shutil.Error as e:
  144. grass.fatal(e)
  145. os.chdir(olddir)
  146. grass.verbose(_("Raster map saved to '%s'" % outfile))
  147. if __name__ == "__main__":
  148. options, flags = grass.parser()
  149. atexit.register(cleanup)
  150. sys.exit(main())