convertmodis.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #!/usr/bin/env python
  2. # class to convert/process modis data
  3. #
  4. # (c) Copyright Luca Delucchi 2010
  5. # Authors: Luca Delucchi
  6. # Email: luca dot delucchi at iasma dot it
  7. #
  8. ##################################################################
  9. #
  10. # This MODIS Python class is licensed under the terms of GNU GPL 2.
  11. # This program is free software; you can redistribute it and/or
  12. # modify it under the terms of the GNU General Public License as
  13. # published by the Free Software Foundation; either version 2 of
  14. # the License, or (at your option) any later version.
  15. # This program is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  18. # See the GNU General Public License for more details.
  19. #
  20. ##################################################################
  21. """Convert MODIS HDF file to GeoTiff file or create a HDF mosaic file for
  22. several tiles using Modis Reprojection Tools.
  23. Classes:
  24. * :class:`convertModis`
  25. * :class:`createMosaic`
  26. * :class:`processModis`
  27. Functions:
  28. * :func:`checkMRTpath`
  29. """
  30. # python 2 and 3 compatibility
  31. from __future__ import print_function
  32. import os
  33. import sys
  34. def checkMRTpath(mrtpath):
  35. """Function to check if MRT path it correct
  36. :param str mrtpath: the path to MRT directory
  37. :return: The path to 'bin' and 'data' directory inside MRT path
  38. """
  39. if os.path.exists(mrtpath):
  40. if os.path.exists(os.path.join(mrtpath, 'bin')):
  41. if os.environ['PATH'].find(os.path.join(mrtpath, 'data')) == -1:
  42. os.environ['PATH'] = "{path}:{data}".format(path=os.environ['PATH'],
  43. data=os.path.join(mrtpath, 'data'))
  44. mrtpathbin = os.path.join(mrtpath, 'bin')
  45. else:
  46. raise Exception('The path {path} does not exist'.format(path=os.path.join(mrtpath, 'bin')))
  47. if os.path.exists(os.path.join(mrtpath, 'data')):
  48. mrtpathdata = os.path.join(mrtpath, 'data')
  49. os.environ['MRTDATADIR'] = os.path.join(mrtpath, 'data')
  50. else:
  51. raise Exception('The path {path} does not exist'.format(path=os.path.join(mrtpath, 'data')))
  52. else:
  53. raise Exception('The path {name} does not exist'.format(name=mrtpath))
  54. return mrtpathbin, mrtpathdata
  55. class convertModis:
  56. """A class to convert modis data from hdf to tif using resample
  57. (from MRT tools)
  58. :param str hdfname: the full path to the hdf file
  59. :param str confile: the full path to the paramater file
  60. :param str mrtpath: the full path to mrt directory which contains
  61. the bin and data directories
  62. """
  63. def __init__(self, hdfname, confile, mrtpath):
  64. """Initialization function"""
  65. # check if the hdf file exists
  66. if os.path.exists(hdfname):
  67. self.name = hdfname
  68. else:
  69. raise Exception('{name} does not exist'.format(name=hdfname))
  70. # check if confile exists
  71. if os.path.exists(confile):
  72. self.conf = confile
  73. else:
  74. raise Exception('{name} does not exist'.format(name=confile))
  75. # check if mrtpath and subdirectories exists and set environment
  76. # variables
  77. self.mrtpathbin, self.mrtpathdata = checkMRTpath(mrtpath)
  78. def executable(self):
  79. """Return the executable of resample MRT software"""
  80. if sys.platform.count('linux') or sys.platform.count('darwin'):
  81. if os.path.exists(os.path.join(self.mrtpathbin, 'resample')):
  82. return os.path.join(self.mrtpathbin, 'resample')
  83. elif sys.platform.count('win32'):
  84. if os.path.exists(os.path.join(self.mrtpathbin, 'resample.exe')):
  85. return os.path.join(self.mrtpathbin, 'resample.exe')
  86. elif os.path.exists(os.path.join(self.mrtpathbin, 'resample')):
  87. return os.path.join(self.mrtpathbin, 'resample')
  88. raise Exception("No possible to find MRT resample executable")
  89. def run(self, quiet=False):
  90. """Exec the convertion process"""
  91. import subprocess
  92. execut = self.executable()
  93. if not os.path.exists(execut):
  94. raise Exception('The path {name} does not exist: it could be an '
  95. 'erroneus path or software'.format(name=execut))
  96. else:
  97. subprocess.call([execut, '-p', self.conf])
  98. if not quiet:
  99. print("The hdf file {name} was converted "
  100. "successfully".format(name=self.name))
  101. return True
  102. class createMosaic:
  103. """A class to convert several MODIS tiles into a mosaic
  104. :param str listfile: the path to file with the list of HDF MODIS
  105. file
  106. :param str outprefix: the prefix for output files
  107. :param str mrtpath: the full path to mrt directory which contains
  108. the bin and data directories
  109. :param str subset: a string composed by 1 and 0 according with the
  110. layer to mosaic. The string should something like
  111. '1 0 1 0 0 0 0'
  112. """
  113. def __init__(self, listfile, outprefix, mrtpath, subset=False):
  114. """Function to initialize the object"""
  115. import tempfile
  116. # check if the hdf file exists
  117. if os.path.exists(listfile):
  118. self.basepath = os.path.split(listfile)[0]
  119. self.fullpath = os.path.realpath(self.basepath)
  120. self.listfiles = listfile
  121. self.tmplistfiles = open(os.path.join(tempfile.gettempdir(),
  122. '{name}.prm'.format(name=str(os.getpid()))), 'w')
  123. self.HDFfiles = open(listfile).readlines()
  124. else:
  125. raise Exception('{name} not exists'.format(name=listfile))
  126. # check if mrtpath and subdirectories exists and set environment
  127. # variables
  128. self.mrtpathbin, self.mrtpathdata = checkMRTpath(mrtpath)
  129. self.out = os.path.join(self.basepath, outprefix + '.hdf')
  130. self.outxml = self.out + '.xml'
  131. self.subset = subset
  132. def write_mosaic_xml(self):
  133. """Write the XML metadata file for MODIS mosaic"""
  134. from .parsemodis import parseModisMulti
  135. listHDF = []
  136. for i in self.HDFfiles:
  137. if i.find(self.basepath) == -1 and i.find('.hdf.xml') == -1:
  138. print("Attention: maybe you do not have the full path in the"
  139. " HDF file list")
  140. listHDF.append(os.path.join(self.basepath, i.strip()))
  141. self.tmplistfiles.write("{name}\n".format(name=os.path.join(self.basepath, i.strip())))
  142. elif i.find('.hdf.xml') == -1:
  143. listHDF.append(i.strip())
  144. self.tmplistfiles.write("{name}\n".format(name=os.path.join(self.fullpath, i.strip())))
  145. pmm = parseModisMulti(listHDF)
  146. pmm.writexml(self.outxml)
  147. self.tmplistfiles.close()
  148. def executable(self):
  149. """Return the executable of mrtmosaic MRT software"""
  150. if sys.platform.count('linux') or sys.platform.count('darwin'):
  151. if os.path.exists(os.path.join(self.mrtpathbin, 'mrtmosaic')):
  152. return os.path.join(self.mrtpathbin, 'mrtmosaic')
  153. elif sys.platform.count('win32'):
  154. if os.path.exists(os.path.join(self.mrtpathbin, 'mrtmosaic.exe')):
  155. return os.path.join(self.mrtpathbin, 'mrtmosaic.exe')
  156. elif os.path.exists(os.path.join(self.mrtpathbin, 'mrtmosaic')):
  157. return os.path.join(self.mrtpathbin, 'mrtmosaic')
  158. raise Exception("No possible to find MRT mrtmosaic executable")
  159. def run(self, quiet=False):
  160. """Exect the mosaic process"""
  161. import subprocess
  162. execut = self.executable()
  163. if not os.path.exists(execut):
  164. raise Exception('The path {name} does not exist, it could be an '
  165. 'erroneus path or software'.format(name=execut))
  166. else:
  167. self.write_mosaic_xml()
  168. if self.subset:
  169. subprocess.call([execut, '-i', self.tmplistfiles.name, '-o',
  170. self.out, '-s', self.subset],
  171. stderr=subprocess.STDOUT)
  172. else:
  173. subprocess.call([execut, '-i', self.tmplistfiles.name, '-o',
  174. self.out], stderr=subprocess.STDOUT)
  175. if not quiet:
  176. print("The mosaic file {name} has been "
  177. "created".format(name=self.out))
  178. return True
  179. class processModis:
  180. """A class to process raw modis data from hdf to tif using swath2grid
  181. (from MRT Swath tools)
  182. :param str hdfname: the full path to the hdf file
  183. :param str confile: the full path to the paramater file
  184. :param str mrtpath: the full path to mrt directory which contains
  185. the bin and data directories
  186. """
  187. def __init__(self, hdfname, confile, mrtpath):
  188. """Function to initialize the object"""
  189. # check if the hdf file exists
  190. if os.path.exists(hdfname):
  191. self.name = hdfname
  192. else:
  193. raise Exception('%s does not exist' % hdfname)
  194. # check if confile exists
  195. if os.path.exists(confile):
  196. self.conf = confile
  197. else:
  198. raise Exception('%s does not exist' % confile)
  199. # check if mrtpath and subdirectories exists and set environment
  200. # variables
  201. self.mrtpathbin, self.mrtpathdata = checkMRTpath(mrtpath)
  202. def executable(self):
  203. """Return the executable of resample MRT software"""
  204. if sys.platform.count('linux') != -1 or sys.platform.count('darwin') != -1:
  205. if os.path.exists(os.path.join(self.mrtpathbin, 'swath2grid')):
  206. return os.path.join(self.mrtpathbin, 'swath2grid')
  207. elif sys.platform.count('win32') != -1:
  208. if os.path.exists(os.path.join(self.mrtpathbin, 'swath2grid.exe')):
  209. return os.path.join(self.mrtpathbin, 'swath2grid.exe')
  210. def run(self, quiet=False):
  211. """Exec the convertion process"""
  212. import subprocess
  213. execut = self.executable()
  214. if not os.path.exists(execut):
  215. raise Exception('The path {name} does not exist, it could be an '
  216. 'erroneus path or software'.format(name=execut))
  217. else:
  218. subprocess.call([execut, '-pf={name}'.format(name=self.conf)])
  219. if not quiet:
  220. print("The hdf file {name} has been "
  221. "converted".format(name=self.name))
  222. return True