v.unpack.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. ############################################################################
  4. #
  5. # MODULE: v.unpack
  6. # AUTHOR(S): Luca Delucchi
  7. #
  8. # PURPOSE: Unpack up a vector map packed with v.pack
  9. # COPYRIGHT: (C) 2010-2013 by the GRASS Development Team
  10. #
  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.
  14. #
  15. #############################################################################
  16. #%module
  17. #% description: Unpacks a vector map packed with v.pack.
  18. #% keywords: vector, import, copying
  19. #%end
  20. #%option G_OPT_F_INPUT
  21. #% gisprompt: old,bin,file
  22. #% description: Name of input pack file
  23. #% required : yes
  24. #%end
  25. #%option G_OPT_V_OUTPUT
  26. #% label: Name for output vector map
  27. #% description: Default: taken from input file internals
  28. #% required : no
  29. #%end
  30. #%flag
  31. #% key: o
  32. #% description: Override projection check (use current location's projection)
  33. #%end
  34. import os
  35. import sys
  36. import shutil
  37. import tarfile
  38. import atexit
  39. import filecmp
  40. from grass.script import core as grass
  41. from grass.script import db as grassdb
  42. def cleanup():
  43. grass.try_rmdir(tmp_dir)
  44. def main():
  45. infile = options['input']
  46. # create temporary directory
  47. global tmp_dir
  48. tmp_dir = grass.tempdir()
  49. grass.debug('tmp_dir = %s' % tmp_dir)
  50. # check if the input file exists
  51. if not os.path.exists(infile):
  52. grass.fatal(_("File <%s> not found") % infile)
  53. # copy the files to tmp dir
  54. input_base = os.path.basename(infile)
  55. shutil.copyfile(infile, os.path.join(tmp_dir, input_base))
  56. os.chdir(tmp_dir)
  57. tar = tarfile.TarFile.open(name = input_base, mode = 'r')
  58. try:
  59. data_name = tar.getnames()[0]
  60. except:
  61. grass.fatal(_("Pack file unreadable"))
  62. # set the output name
  63. if options['output']:
  64. map_name = options['output']
  65. else:
  66. map_name = data_name
  67. # grass env
  68. gisenv = grass.gisenv()
  69. mset_dir = os.path.join(gisenv['GISDBASE'],
  70. gisenv['LOCATION_NAME'],
  71. gisenv['MAPSET'])
  72. new_dir = os.path.join(mset_dir, 'vector', map_name)
  73. gfile = grass.find_file(name = map_name, element = 'vector',
  74. mapset = '.')
  75. overwrite = os.getenv('GRASS_OVERWRITE')
  76. if gfile['file'] and overwrite != '1':
  77. grass.fatal(_("Vector map <%s> already exists") % map_name)
  78. elif overwrite == '1' and gfile['file']:
  79. grass.warning(_("Vector map <%s> already exists and will be overwritten") % map_name)
  80. grass.run_command('g.remove', quiet = True, vect = map_name)
  81. shutil.rmtree(new_dir,True)
  82. # extract data
  83. tar.extractall()
  84. # check projection compatibility in a rather crappy way
  85. loc_proj = os.path.join(mset_dir, '..', 'PERMANENT', 'PROJ_INFO')
  86. loc_proj_units = os.path.join(mset_dir, '..', 'PERMANENT', 'PROJ_UNITS')
  87. diff_result_1 = diff_result_2 = None
  88. if not grass.compare_key_value_text_files(os.path.join(tmp_dir,'PROJ_INFO'), loc_proj):
  89. diff_result_1 = grass.diff_files(os.path.join(tmp_dir,'PROJ_INFO'), loc_proj)
  90. if not grass.compare_key_value_text_files(os.path.join(tmp_dir,'PROJ_UNITS'), loc_proj_units):
  91. diff_result_2 = grass.diff_files(os.path.join(tmp_dir,'PROJ_UNITS'), loc_proj_units)
  92. if diff_result_1 or diff_result_2:
  93. if flags['o']:
  94. grass.warning(_("Projection information does not match. Proceeding..."))
  95. else:
  96. if diff_result_1:
  97. grass.warning(_("Difference between PROJ_INFO file of packed map "
  98. "and of current location:\n{diff}").format(diff=''.join(diff_result_1)))
  99. if diff_result_2:
  100. grass.warning(_("Difference between PROJ_UNITS file of packed map "
  101. "and of current location:\n{diff}").format(diff=''.join(diff_result_2)))
  102. grass.fatal(_("Projection information does not match. Aborting."))
  103. # new db
  104. fromdb = os.path.join(tmp_dir, 'db.sqlite')
  105. # copy file
  106. shutil.copytree(data_name, new_dir)
  107. # exist fromdb
  108. if os.path.exists(fromdb):
  109. # the db connection in the output mapset
  110. dbconn = grassdb.db_connection()
  111. todb = dbconn['database']
  112. # return all tables
  113. list_fromtable = grass.read_command('db.tables', driver = 'sqlite',
  114. database = fromdb).splitlines()
  115. # return the list of old connection for extract layer number and key
  116. dbln = open(os.path.join(new_dir,'dbln'), 'r')
  117. dbnlist = dbln.readlines()
  118. dbln.close()
  119. # check if dbf or sqlite directory exists
  120. if dbconn['driver'] == 'dbf' and not os.path.exists(os.path.join(mset_dir, 'dbf')):
  121. os.mkdir(os.path.join(mset_dir, 'dbf'))
  122. elif dbconn['driver'] == 'sqlite' and not os.path.exists(os.path.join(mset_dir, 'sqlite')):
  123. os.mkdir(os.path.join(mset_dir, 'sqlite'))
  124. # for each old connection
  125. for t in dbnlist:
  126. # it split the line of each connection, to found layer number and key
  127. if len(t.split('|')) != 1:
  128. values = t.split('|')
  129. else:
  130. values = t.split(' ')
  131. from_table = values[1]
  132. layer = values[0].split('/')[0]
  133. # we need to take care about the table name in case of several layer
  134. if options["output"]:
  135. if len(dbnlist) > 1:
  136. to_table = "%s_%s" % (map_name, layer)
  137. else:
  138. to_table = map_name
  139. else:
  140. to_table = from_table
  141. grass.verbose(_("Coping table <%s> as table <%s>") % (from_table, to_table))
  142. # copy the table in the default database
  143. if 0 != grass.run_command('db.copy', to_driver = dbconn['driver'],
  144. to_database = todb, to_table = to_table,
  145. from_driver = 'sqlite', from_database = fromdb,
  146. from_table = from_table):
  147. grass.fatal(_("Unable to copy table <%s> as table <%s>") % (from_table, to_table))
  148. grass.verbose(_("Connect table <%s> to vector map <%s> at layer <%s>") % \
  149. (to_table, map_name, layer))
  150. # and connect the new tables with the right layer
  151. if 0 != grass.run_command('v.db.connect', flags = 'o', quiet = True,
  152. driver = dbconn['driver'], database = todb,
  153. map = map_name, key = values[2],
  154. layer = layer, table = to_table):
  155. grass.fatal(_("Unable to connect table <%s> to vector map <%s>") % \
  156. (to_table, map_name))
  157. grass.message(_("Vector map <%s> succesfully unpacked") % map_name)
  158. if __name__ == "__main__":
  159. options, flags = grass.parser()
  160. atexit.register(cleanup)
  161. sys.exit(main())