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