r.unpack.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #!/usr/bin/env python
  2. ############################################################################
  3. #
  4. # MODULE: r.unpack
  5. # AUTHOR(S): Hamish Bowman, Otago University, New Zealand
  6. # Converted to Python by Martin Landa <landa.martin gmail.com>
  7. # PURPOSE: Unpack up a raster map packed with r.pack
  8. # COPYRIGHT: (C) 2010-2017 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: Imports a raster map as GRASS GIS specific archive file (packed with r.pack)
  17. #% keyword: raster
  18. #% keyword: import
  19. #% keyword: copying
  20. #%end
  21. #%option G_OPT_F_BIN_INPUT
  22. #% description: Name of input pack file
  23. #% key_desc: name.pack
  24. #%end
  25. #%option G_OPT_R_OUTPUT
  26. #% description: Name for output raster map (default: taken from input file internals)
  27. #% required: no
  28. #% guisection: Output settings
  29. #%end
  30. #%flag
  31. #% key: o
  32. #% label: Override projection check (use current location's projection)
  33. #% description: Assume that the dataset has same projection as the current location
  34. #% guisection: Output settings
  35. #%end
  36. #%flag
  37. #% key: p
  38. #% label: Print projection information of input pack file and exit
  39. #% guisection: Print
  40. #%end
  41. import os
  42. import sys
  43. import shutil
  44. import tarfile
  45. import atexit
  46. from grass.script.utils import diff_files, try_rmdir
  47. from grass.script import core as grass
  48. # i18N
  49. import gettext
  50. gettext.install('grassmods', os.path.join(os.getenv("GISBASE"), 'locale'))
  51. def cleanup():
  52. try_rmdir(tmp_dir)
  53. def main():
  54. infile = options['input']
  55. global tmp_dir
  56. tmp_dir = grass.tempdir()
  57. grass.debug('tmp_dir = {tmpdir}'.format(tmpdir=tmp_dir))
  58. if not os.path.exists(infile):
  59. grass.fatal(_('File {name} not found.'.format(name=infile)))
  60. gisenv = grass.gisenv()
  61. mset_dir = os.path.join(gisenv['GISDBASE'],
  62. gisenv['LOCATION_NAME'],
  63. gisenv['MAPSET'])
  64. input_base = os.path.basename(infile)
  65. shutil.copyfile(infile, os.path.join(tmp_dir, input_base))
  66. os.chdir(tmp_dir)
  67. tar = tarfile.TarFile.open(name=input_base, mode='r')
  68. try:
  69. data_name = tar.getnames()[0]
  70. except:
  71. grass.fatal(_("Pack file unreadable"))
  72. if flags['p']:
  73. # print proj info and exit
  74. try:
  75. for fname in ['PROJ_INFO', 'PROJ_UNITS']:
  76. f = tar.extractfile('{}/{}'.format(data_name, fname))
  77. sys.stdout.write(f.read())
  78. except KeyError:
  79. grass.fatal(_("Pack file unreadable: file '{}' missing".format(fname)))
  80. tar.close()
  81. return 0
  82. if options['output']:
  83. map_name = options['output']
  84. else:
  85. map_name = data_name.split('@')[0]
  86. gfile = grass.find_file(name=map_name, element='cell', mapset='.')
  87. if gfile['file']:
  88. if os.environ.get('GRASS_OVERWRITE', '0') != '1':
  89. grass.fatal(_('Raster map <{name}> already exists'.format(name=map_name)))
  90. else:
  91. grass.warning(
  92. _('Raster map <{name}> already exists and will be overwritten'.format(name=map_name)))
  93. # extract data
  94. tar.extractall()
  95. tar.close()
  96. os.chdir(data_name)
  97. if os.path.exists('cell'):
  98. pass
  99. elif os.path.exists('coor'):
  100. grass.fatal(_('This GRASS GIS pack file contains vector data. Use '
  101. 'v.unpack to unpack <{name}>'.format(name=map_name)))
  102. else:
  103. grass.fatal(_("Pack file unreadable"))
  104. # check projection compatibility in a rather crappy way
  105. if flags['o']:
  106. grass.warning(_("Overriding projection check (using current location's projection)."))
  107. else:
  108. diff_result_1 = diff_result_2 = None
  109. proj_info_file_1 = 'PROJ_INFO'
  110. proj_info_file_2 = os.path.join(mset_dir, '..', 'PERMANENT', 'PROJ_INFO')
  111. skip_projection_check = False
  112. if not os.path.exists(proj_info_file_1):
  113. if os.path.exists(proj_info_file_2):
  114. grass.fatal(
  115. _("PROJ_INFO file is missing, unpack raster map in XY (unprojected) location."))
  116. skip_projection_check = True # XY location
  117. if not skip_projection_check:
  118. if not grass.compare_key_value_text_files(filename_a=proj_info_file_1,
  119. filename_b=proj_info_file_2,
  120. proj=True):
  121. diff_result_1 = diff_files(proj_info_file_1, proj_info_file_2)
  122. proj_units_file_1 = 'PROJ_UNITS'
  123. proj_units_file_2 = os.path.join(mset_dir, '..', 'PERMANENT', 'PROJ_UNITS')
  124. if not grass.compare_key_value_text_files(filename_a=proj_units_file_1,
  125. filename_b=proj_units_file_2,
  126. units=True):
  127. diff_result_2 = diff_files(proj_units_file_1, proj_units_file_2)
  128. if diff_result_1 or diff_result_2:
  129. if diff_result_1:
  130. grass.warning(_("Difference between PROJ_INFO file of packed map "
  131. "and of current location:\n{diff}").format(diff=''.join(diff_result_1)))
  132. if diff_result_2:
  133. grass.warning(_("Difference between PROJ_UNITS file of packed map "
  134. "and of current location:\n{diff}").format(diff=''.join(diff_result_2)))
  135. grass.fatal(_("Projection of dataset does not appear to match current location."
  136. " In case of no significant differences in the projection definitions,"
  137. " use the -o flag to ignore them and use"
  138. " current location definition."))
  139. # install in $MAPSET
  140. for element in ['cats', 'cell', 'cellhd', 'cell_misc', 'colr', 'fcell', 'hist']:
  141. if not os.path.exists(element):
  142. continue
  143. path = os.path.join(mset_dir, element)
  144. if not os.path.exists(path):
  145. os.mkdir(path)
  146. if element == 'cell_misc':
  147. path = os.path.join(mset_dir, element, map_name)
  148. if os.path.exists(path):
  149. shutil.rmtree(path)
  150. shutil.copytree('cell_misc', path)
  151. else:
  152. shutil.copyfile(element, os.path.join(mset_dir, element, map_name))
  153. grass.message(_('Raster map <{name}> unpacked'.format(name=map_name)))
  154. if __name__ == "__main__":
  155. options, flags = grass.parser()
  156. atexit.register(cleanup)
  157. sys.exit(main())