v.unpack.py 6.1 KB

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