v.unpack.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. # check if the input file exists
  47. if not os.path.exists(infile):
  48. grass.fatal(_("File <%s> not found") % infile)
  49. # create temporary directory
  50. global tmp_dir
  51. tmp_dir = grass.tempdir()
  52. grass.debug('tmp_dir = %s' % tmp_dir)
  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. if not grass.compare_key_value_text_files(os.path.join(tmp_dir,'PROJ_INFO'), loc_proj) or \
  88. not grass.compare_key_value_text_files(os.path.join(tmp_dir,'PROJ_UNITS'), loc_proj_units):
  89. if flags['o']:
  90. grass.warning(_("Projection information does not match. Proceeding..."))
  91. else:
  92. grass.fatal(_("Projection information does not match. Aborting."))
  93. # new db
  94. fromdb = os.path.join(tmp_dir, 'db.sqlite')
  95. # copy file
  96. shutil.copytree(data_name, new_dir)
  97. # exist fromdb
  98. if os.path.exists(fromdb):
  99. # the db connection in the output mapset
  100. dbconn = grassdb.db_connection()
  101. todb = dbconn['database']
  102. # return all tables
  103. list_fromtable = grass.read_command('db.tables', driver = 'sqlite',
  104. database = fromdb).splitlines()
  105. # return the list of old connection for extract layer number and key
  106. dbln = open(os.path.join(new_dir,'dbln'), 'r')
  107. dbnlist = dbln.readlines()
  108. dbln.close()
  109. # check if dbf or sqlite directory exists
  110. if dbconn['driver'] == 'dbf' and not os.path.exists(os.path.join(mset_dir, 'dbf')):
  111. os.mkdir(os.path.join(mset_dir, 'dbf'))
  112. elif dbconn['driver'] == 'sqlite' and not os.path.exists(os.path.join(mset_dir, 'sqlite')):
  113. os.mkdir(os.path.join(mset_dir, 'sqlite'))
  114. # for each old connection
  115. for t in dbnlist:
  116. # it split the line of each connection, to found layer number and key
  117. if len(t.split('|')) != 1:
  118. values = t.split('|')
  119. else:
  120. values = t.split(' ')
  121. from_table = values[1]
  122. layer = values[0].split('/')[0]
  123. # we need to take care about the table name in case of several layer
  124. if options["output"]:
  125. to_table = "%s_%s"%(map_name, layer)
  126. else:
  127. to_table = from_table
  128. grass.verbose(_("Coping table <%s> as table <%s>") % (from_table, to_table))
  129. # copy the table in the default database
  130. if 0 != grass.run_command('db.copy', to_driver = dbconn['driver'],
  131. to_database = todb, to_table = to_table,
  132. from_driver = 'sqlite', from_database = fromdb,
  133. from_table = from_table):
  134. grass.fatal(_("Unable to copy table <%s> as table <%s>") % (from_table, to_table))
  135. grass.verbose(_("Connect table <%s> to vector map <%s> at layer <%s>") % \
  136. (to_table, map_name, layer))
  137. # and connect the new tables with the right layer
  138. if 0 != grass.run_command('v.db.connect', flags = 'o', quiet = True,
  139. driver = dbconn['driver'], database = todb,
  140. map = map_name, key = values[2],
  141. layer = layer, table = to_table):
  142. grass.fatal(_("Unable to connect table <%s> to vector map <%s>") % \
  143. (to_table, map_name))
  144. grass.message(_("Vector map <%s> succesfully unpacked") % map_name)
  145. if __name__ == "__main__":
  146. options, flags = grass.parser()
  147. atexit.register(cleanup)
  148. sys.exit(main())