v.unpack.py 6.7 KB

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