#!/usr/bin/env python3 ############################################################################ # # MODULE: r.unpack # AUTHOR(S): Hamish Bowman, Otago University, New Zealand # Converted to Python by Martin Landa # PURPOSE: Unpack up a raster map packed with r.pack # COPYRIGHT: (C) 2010-2017 by the GRASS Development Team # # This program is free software under the GNU General # Public License (>=v2). Read the file COPYING that # comes with GRASS for details. # ############################################################################# #%module #% description: Imports a GRASS GIS specific raster archive file (packed with r.pack) as a raster map #% keyword: raster #% keyword: import #% keyword: copying #%end #%option G_OPT_F_BIN_INPUT #% description: Name of input pack file #% key_desc: name.pack #%end #%option G_OPT_R_OUTPUT #% description: Name for output raster map (default: taken from input file internals) #% required: no #% guisection: Output settings #%end #%flag #% key: o #% label: Override projection check (use current location's projection) #% description: Assume that the dataset has same projection as the current location #% guisection: Output settings #%end #%flag #% key: p #% label: Print projection information of input pack file and exit #% guisection: Print #%end import os import sys import shutil import tarfile import atexit from grass.script.utils import diff_files, try_rmdir from grass.script import core as grass def cleanup(): try_rmdir(tmp_dir) def main(): infile = options['input'] global tmp_dir tmp_dir = grass.tempdir() grass.debug('tmp_dir = {tmpdir}'.format(tmpdir=tmp_dir)) if not os.path.exists(infile): grass.fatal(_('File {name} not found.'.format(name=infile))) gisenv = grass.gisenv() mset_dir = os.path.join(gisenv['GISDBASE'], gisenv['LOCATION_NAME'], gisenv['MAPSET']) input_base = os.path.basename(infile) shutil.copyfile(infile, os.path.join(tmp_dir, input_base)) os.chdir(tmp_dir) tar = tarfile.TarFile.open(name=input_base, mode='r') try: data_name = tar.getnames()[0] except: grass.fatal(_("Pack file unreadable")) if flags['p']: # print proj info and exit try: for fname in ['PROJ_INFO', 'PROJ_UNITS']: f = tar.extractfile('{}/{}'.format(data_name, fname)) sys.stdout.write(f.read().decode()) except KeyError: grass.fatal(_("Pack file unreadable: file '{}' missing".format(fname))) tar.close() return 0 if options['output']: map_name = options['output'] else: map_name = data_name.split('@')[0] gfile = grass.find_file(name=map_name, element='cell', mapset='.') if gfile['file']: if os.environ.get('GRASS_OVERWRITE', '0') != '1': grass.fatal(_('Raster map <{name}> already exists'.format(name=map_name))) else: grass.warning( _('Raster map <{name}> already exists and will be overwritten'.format(name=map_name))) # extract data tar.extractall() tar.close() os.chdir(data_name) if os.path.exists('cell'): pass elif os.path.exists('coor'): grass.fatal(_('This GRASS GIS pack file contains vector data. Use ' 'v.unpack to unpack <{name}>'.format(name=map_name))) else: grass.fatal(_("Pack file unreadable")) # check projection compatibility in a rather crappy way if flags['o']: grass.warning(_("Overriding projection check (using current location's projection).")) else: diff_result_1 = diff_result_2 = None proj_info_file_1 = 'PROJ_INFO' proj_info_file_2 = os.path.join(mset_dir, '..', 'PERMANENT', 'PROJ_INFO') skip_projection_check = False if not os.path.exists(proj_info_file_1): if os.path.exists(proj_info_file_2): grass.fatal( _("PROJ_INFO file is missing, unpack raster map in XY (unprojected) location.")) skip_projection_check = True # XY location if not skip_projection_check: if not grass.compare_key_value_text_files(filename_a=proj_info_file_1, filename_b=proj_info_file_2, proj=True): diff_result_1 = diff_files(proj_info_file_1, proj_info_file_2) proj_units_file_1 = 'PROJ_UNITS' proj_units_file_2 = os.path.join(mset_dir, '..', 'PERMANENT', 'PROJ_UNITS') if not grass.compare_key_value_text_files(filename_a=proj_units_file_1, filename_b=proj_units_file_2, units=True): diff_result_2 = diff_files(proj_units_file_1, proj_units_file_2) if diff_result_1 or diff_result_2: if diff_result_1: grass.warning(_("Difference between PROJ_INFO file of packed map " "and of current location:\n{diff}").format(diff=''.join(diff_result_1))) if diff_result_2: grass.warning(_("Difference between PROJ_UNITS file of packed map " "and of current location:\n{diff}").format(diff=''.join(diff_result_2))) grass.fatal(_("Projection of dataset does not appear to match current location." " In case of no significant differences in the projection definitions," " use the -o flag to ignore them and use" " current location definition.")) # install in $MAPSET for element in ['cats', 'cell', 'cellhd', 'cell_misc', 'colr', 'fcell', 'hist']: if not os.path.exists(element): continue path = os.path.join(mset_dir, element) if not os.path.exists(path): os.mkdir(path) if element == 'cell_misc': path = os.path.join(mset_dir, element, map_name) if os.path.exists(path): shutil.rmtree(path) shutil.copytree('cell_misc', path) else: shutil.copyfile(element, os.path.join(mset_dir, element, map_name)) grass.message(_('Raster map <{name}> unpacked'.format(name=map_name))) if __name__ == "__main__": options, flags = grass.parser() atexit.register(cleanup) sys.exit(main())