2
# -*- coding: utf-8 -*-
3
############################################################################
6
# AUTHOR(S): Luca Delucchi
8
# PURPOSE: Unpack up a vector map packed with v.pack
9
# COPYRIGHT: (C) 2010-2013 by the GRASS Development Team
11
# This program is free software under the GNU General
12
# Public License (>=v2). Read the file COPYING that
13
# comes with GRASS for details.
15
#############################################################################
18
#% description: Unpacks a vector map packed with v.pack.
23
#%option G_OPT_F_INPUT
24
#% description: Name of input pack file
26
#%option G_OPT_V_OUTPUT
27
#% label: Name for output vector map
28
#% description: Default: taken from input file internals
33
#% description: Override projection check (use current location's projection)
42
from grass.script.utils import diff_files, try_rmdir
43
from grass.script import core as grass
44
from grass.script import db as grassdb
45
from grass.exceptions import CalledModuleError
53
infile = options['input']
55
# create temporary directory
57
tmp_dir = grass.tempdir()
58
grass.debug('tmp_dir = %s' % tmp_dir)
60
# check if the input file exists
61
if not os.path.exists(infile):
62
grass.fatal(_("File <%s> not found") % infile)
64
# copy the files to tmp dir
65
input_base = os.path.basename(infile)
66
shutil.copyfile(infile, os.path.join(tmp_dir, input_base))
68
tar = tarfile.TarFile.open(name=input_base, mode='r')
70
data_name = tar.getnames()[0]
72
grass.fatal(_("Pack file unreadable"))
76
map_name = options['output']
81
gisenv = grass.gisenv()
82
mset_dir = os.path.join(gisenv['GISDBASE'],
83
gisenv['LOCATION_NAME'],
86
new_dir = os.path.join(mset_dir, 'vector', map_name)
88
gfile = grass.find_file(name=map_name, element='vector', mapset='.')
89
overwrite = os.getenv('GRASS_OVERWRITE')
90
if gfile['file'] and overwrite != '1':
91
grass.fatal(_("Vector map <%s> already exists") % map_name)
92
elif overwrite == '1' and gfile['file']:
93
grass.warning(_("Vector map <%s> already exists and will be overwritten") % map_name)
94
grass.run_command('g.remove', flags='f', quiet=True, type='vector',
96
shutil.rmtree(new_dir, True)
100
if os.path.exists(os.path.join(map_name, 'coor')):
102
elif os.path.exists(os.path.join(map_name, 'cell')):
103
grass.fatal(_("This GRASS GIS pack file contains raster data. Use "
104
"r.unpack to unpack <%s>" % map_name))
106
grass.fatal(_("Pack file unreadable"))
108
# check projection compatibility in a rather crappy way
109
loc_proj = os.path.join(mset_dir, '..', 'PERMANENT', 'PROJ_INFO')
110
loc_proj_units = os.path.join(mset_dir, '..', 'PERMANENT', 'PROJ_UNITS')
112
diff_result_1 = diff_result_2 = None
113
if not grass.compare_key_value_text_files(filename_a=os.path.join(tmp_dir, 'PROJ_INFO'),
114
filename_b=loc_proj, proj=True):
115
diff_result_1 = diff_files(os.path.join(tmp_dir, 'PROJ_INFO'),
118
if not grass.compare_key_value_text_files(filename_a=os.path.join(tmp_dir, 'PROJ_UNITS'),
119
filename_b=loc_proj_units,
121
diff_result_2 = diff_files(os.path.join(tmp_dir, 'PROJ_UNITS'),
124
if diff_result_1 or diff_result_2:
126
grass.warning(_("Projection information does not match. Proceeding..."))
129
grass.warning(_("Difference between PROJ_INFO file of packed map "
130
"and of current location:\n{diff}").format(diff=''.join(diff_result_1)))
132
grass.warning(_("Difference between PROJ_UNITS file of packed map "
133
"and of current location:\n{diff}").format(diff=''.join(diff_result_2)))
134
grass.fatal(_("Projection information does not match. Aborting."))
137
fromdb = os.path.join(tmp_dir, 'db.sqlite')
139
shutil.copytree(data_name, new_dir)
141
if os.path.exists(fromdb):
142
# the db connection in the output mapset
143
dbconn = grassdb.db_connection(force=True)
144
todb = dbconn['database']
146
list_fromtable = grass.read_command('db.tables', driver='sqlite',
147
database=fromdb).splitlines()
149
# return the list of old connection for extract layer number and key
150
dbln = open(os.path.join(new_dir, 'dbln'), 'r')
151
dbnlist = dbln.readlines()
153
# check if dbf or sqlite directory exists
154
if dbconn['driver'] == 'dbf' and not os.path.exists(os.path.join(mset_dir, 'dbf')):
155
os.mkdir(os.path.join(mset_dir, 'dbf'))
156
elif dbconn['driver'] == 'sqlite' and not os.path.exists(os.path.join(mset_dir, 'sqlite')):
157
os.mkdir(os.path.join(mset_dir, 'sqlite'))
158
# for each old connection
160
# it split the line of each connection, to found layer number and key
161
if len(t.split('|')) != 1:
162
values = t.split('|')
164
values = t.split(' ')
166
from_table = values[1]
167
layer = values[0].split('/')[0]
168
# we need to take care about the table name in case of several layer
169
if options["output"]:
171
to_table = "%s_%s" % (map_name, layer)
175
to_table = from_table
177
grass.verbose(_("Coping table <%s> as table <%s>") % (from_table,
180
# copy the table in the default database
182
grass.run_command('db.copy', to_driver=dbconn['driver'],
183
to_database=todb, to_table=to_table,
184
from_driver='sqlite',
185
from_database=fromdb,
186
from_table=from_table)
187
except CalledModuleError:
188
grass.fatal(_("Unable to copy table <%s> as table <%s>") % (from_table, to_table))
190
grass.verbose(_("Connect table <%s> to vector map <%s> at layer <%s>") %
191
(to_table, map_name, layer))
193
# and connect the new tables with the right layer
195
grass.run_command('v.db.connect', flags='o', quiet=True,
196
driver=dbconn['driver'], database=todb,
197
map=map_name, key=values[2],
198
layer=layer, table=to_table)
199
except CalledModuleError:
200
grass.fatal(_("Unable to connect table <%s> to vector map <%s>") %
201
(to_table, map_name))
203
grass.message(_("Vector map <%s> succesfully unpacked") % map_name)
205
if __name__ == "__main__":
206
options, flags = grass.parser()
207
atexit.register(cleanup)