utils.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. """
  2. @package utils.py
  3. @brief Misc utilities for GRASS wxPython GUI
  4. (C) 2007-2008 by the GRASS Development Team
  5. This program is free software under the GNU General Public
  6. License (>=v2). Read the file COPYING that comes with GRASS
  7. for details.
  8. @author Martin Landa, Jachym Cepicky
  9. @date 2007-2008
  10. """
  11. import os
  12. import sys
  13. import grass
  14. import globalvar
  15. import gcmd
  16. import grassenv
  17. try:
  18. import subprocess
  19. except:
  20. compatPath = os.path.join(globalvar.ETCWXDIR, "compat")
  21. sys.path.append(compatPath)
  22. import subprocess
  23. def GetTempfile(pref=None):
  24. """
  25. Creates GRASS temporary file using defined prefix.
  26. @todo Fix path on MS Windows/MSYS
  27. @param pref prefer the given path
  28. @return Path to file name (string) or None
  29. """
  30. import gcmd
  31. tempfileCmd = gcmd.Command(["g.tempfile",
  32. "pid=%d" % os.getpid()])
  33. tempfile = tempfileCmd.ReadStdOutput()[0].strip()
  34. # FIXME
  35. # ugly hack for MSYS (MS Windows)
  36. if subprocess.mswindows:
  37. tempfile = tempfile.replace("/", "\\")
  38. try:
  39. path, file = os.path.split(tempfile)
  40. if pref:
  41. return os.path.join(pref, file)
  42. else:
  43. return tempfile
  44. except:
  45. return None
  46. def GetLayerNameFromCmd(dcmd, fullyQualified=False, param=None,
  47. layerType=None):
  48. """Get map name from GRASS command
  49. @param dcmd GRASS command (given as list)
  50. @param fullyQualified change map name to be fully qualified
  51. @param force parameter otherwise 'input'/'map'
  52. @param update change map name in command
  53. @param layerType check also layer type ('raster', 'vector', '3d-raster', ...)
  54. @return map name
  55. @return '' if no map name found in command
  56. """
  57. mapname = ''
  58. if len(dcmd) < 1:
  59. return mapname
  60. if 'd.grid' == dcmd[0]:
  61. mapname = 'grid'
  62. elif 'd.geodesic' in dcmd[0]:
  63. mapname = 'geodesic'
  64. elif 'd.rhumbline' in dcmd[0]:
  65. mapname = 'rhumb'
  66. elif 'labels=' in dcmd[0]:
  67. mapname = dcmd[idx].split('=')[1]+' labels'
  68. else:
  69. for idx in range(len(dcmd)):
  70. if param and param in dcmd[idx]:
  71. break
  72. elif not param:
  73. if 'map=' in dcmd[idx] or \
  74. 'input=' in dcmd[idx] or \
  75. 'red=' in dcmd[idx] or \
  76. 'h_map=' in dcmd[idx] or \
  77. 'reliefmap' in dcmd[idx]:
  78. break
  79. if idx < len(dcmd):
  80. try:
  81. mapname = dcmd[idx].split('=')[1]
  82. except IndexError:
  83. return ''
  84. if fullyQualified and '@' not in mapname:
  85. if layerType in ('raster', 'vector', '3d-raster'):
  86. try:
  87. if layerType == 'raster':
  88. findType = 'cell'
  89. else:
  90. findType = layerType
  91. result = grass.find_file(mapname, element=findType)
  92. except AttributeError, e: # not found
  93. return ''
  94. if result:
  95. mapname = result['fullname']
  96. else:
  97. mapname += '@' + grassenv.GetGRASSVariable('MAPSET')
  98. else:
  99. mapname += '@' + grassenv.GetGRASSVariable('MAPSET')
  100. dcmd[idx] = dcmd[idx].split('=')[0] + '=' + mapname
  101. return mapname
  102. def GetValidLayerName(name):
  103. """Make layer name SQL compliant, based on G_str_to_sql()
  104. @todo: Better use directly GRASS Python SWIG...
  105. """
  106. retName = str(name).strip()
  107. # check if name is fully qualified
  108. if '@' in retName:
  109. retName, mapset = retName.split('@')
  110. else:
  111. mapset = None
  112. for c in retName:
  113. # c = toascii(c)
  114. if not (c >= 'A' and c <= 'Z') and \
  115. not (c >= 'a' and c <= 'z') and \
  116. not (c >= '0' and c <= '9'):
  117. c = '_'
  118. if not (retName[0] >= 'A' and retName[0] <= 'Z') and \
  119. not (retName[0] >= 'a' and retName[0] <= 'z'):
  120. retName = 'x' + retName[1:]
  121. if mapset:
  122. retName = retName + '@' + mapset
  123. return retName
  124. def ListOfCatsToRange(cats):
  125. """Convert list of category number to range(s)
  126. Used for example for d.vect cats=[range]
  127. @param cats category list
  128. @return category range string
  129. @return '' on error
  130. """
  131. catstr = ''
  132. try:
  133. cats = map(int, cats)
  134. except:
  135. return catstr
  136. i = 0
  137. while i < len(cats):
  138. next = 0
  139. j = i + 1
  140. while j < len(cats):
  141. if cats[i + next] == cats[j] - 1:
  142. next += 1
  143. else:
  144. break
  145. j += 1
  146. if next > 1:
  147. catstr += '%d-%d,' % (cats[i], cats[i + next])
  148. i += next + 1
  149. else:
  150. catstr += '%d,' % (cats[i])
  151. i += 1
  152. return catstr.strip(',')
  153. def ListOfMapsets(all=False):
  154. """Get list of available/accessible mapsets
  155. @param all if True get list of all mapsets
  156. @return list of mapsets
  157. """
  158. mapsets = []
  159. ### FIXME
  160. # problem using Command here (see preferences.py)
  161. # cmd = gcmd.Command(['g.mapsets', '-l'])
  162. if all:
  163. cmd = subprocess.Popen(['g.mapsets' + globalvar.EXT_BIN, '-l'],
  164. stdout=subprocess.PIPE)
  165. try:
  166. # for mset in cmd.ReadStdOutput()[0].split(' '):
  167. for line in cmd.stdout.readlines():
  168. for mset in line.strip('%s' % os.linesep).split(' '):
  169. if len(mset) == 0:
  170. continue
  171. mapsets.append(mset)
  172. except:
  173. raise gcmd.CmdError(_('Unable to get list of available mapsets.'))
  174. else:
  175. # cmd = gcmd.Command(['g.mapsets', '-p'])
  176. cmd = subprocess.Popen(['g.mapsets' + globalvar.EXT_BIN, '-p'],
  177. stdout=subprocess.PIPE)
  178. try:
  179. # for mset in cmd.ReadStdOutput()[0].split(' '):
  180. for line in cmd.stdout.readlines():
  181. for mset in line.strip('%s' % os.linesep).split(' '):
  182. if len(mset) == 0:
  183. continue
  184. mapsets.append(mset)
  185. except:
  186. raise gcmd.CmdError(_('Unable to get list of accessible mapsets.'))
  187. ListSortLower(mapsets)
  188. return mapsets
  189. def ListSortLower(list):
  190. """Sort list items (not case-sensitive)"""
  191. list.sort(cmp=lambda x, y: cmp(x.lower(), y.lower()))
  192. def reexec_with_pythonw():
  193. """Re-execute Python on Mac OS"""
  194. if sys.platform == 'darwin' and \
  195. not sys.executable.endswith('MacOS/Python'):
  196. print >> sys.stderr, 're-executing using pythonw'
  197. os.execvp('pythonw', ['pythonw', __file__] + sys.argv[1:])