web-dev-qa-db-fra.com

Lecture de fichiers hdf en Conversion et conversion de personnes-ci en rasters geoTIFF

J'essaie de lire les fichiers de données MODIS 17 dans R, de les manipuler (rognage, etc.), puis de les sauvegarder en tant que fichiers geoTIFF. Les fichiers de données sont au format .hdf et il ne semble pas être facile de les lire en R.

Comparé à d’autres sujets, il n’ya pas beaucoup de conseils et la plupart d’entre eux ont plusieurs années. Certains conseillent également d’utiliser des programmes supplémentaires, mais je veux rester avec juste utiliser R.

Quel paquet/s utilise-t-on pour traiter les fichiers .hdf dans R?

8
James

Ok, mes fichiers hdf MODIS étaient donc au format hdf4 plutôt que hdf5. C'était étonnamment difficile à découvrir, MODIS ne le mentionne pas sur leur site Web, mais il existe quelques allusions dans divers blogs et publications d'échange. À la fin, je devais télécharger HDFView pour le savoir à coup sûr.

R ne fait pas les fichiers hdf4 et pratiquement tous les paquets (comme rgdal) ne supportent que les fichiers hdf5. Il y a quelques articles sur le téléchargement des pilotes et la compilation de rgdal à partir des sources, mais tout semblait assez compliqué et les articles étaient pour MAC ou Unix et j'utilise Windows.

Fondamentalement, gdal_translate du paquet gdalUtils est la grâce de tous ceux qui souhaitent utiliser des fichiers hdf4 en R. Il convertit les fichiers hdf4 en fichiers geoTIFF sans les lire en R. Cela signifie que vous ne pouvez pas les manipuler du tout. en les recadrant, il est donc intéressant d’obtenir les plus petites tuiles possibles (pour les données MODIS via Reverb) afin de réduire le temps de calcul.

Voici et exemple du code:

library(gdalUtils)

# Provides detailed data on hdf4 files but takes ages

gdalinfo("MOD17A3H.A2000001.h21v09.006.2015141183401.hdf")

# Tells me what subdatasets are within my hdf4 MODIS files and makes them into a list

sds <- get_subdatasets("MOD17A3H.A2000001.h21v09.006.2015141183401.hdf")
sds

[1] "HDF4_EOS:EOS_GRID:MOD17A3H.A2000001.h21v09.006.2015141183401.hdf:MOD_Grid_MOD17A3H:Npp_500m"   
[2] "HDF4_EOS:EOS_GRID:MOD17A3H.A2000001.h21v09.006.2015141183401.hdf:MOD_Grid_MOD17A3H:Npp_QC_500m"

# I'm only interested in the first subdataset and I can use gdal_translate to convert it to a .tif

gdal_translate(sds[1], dst_dataset = "NPP2000.tif")

# Load and plot the new .tif

rast <- raster("NPP2000.tif")
plot(rast)

# If you have lots of files then you can make a loop to do all this for you

files <- dir(pattern = ".hdf")
files

 [1] "MOD17A3H.A2000001.h21v09.006.2015141183401.hdf" "MOD17A3H.A2001001.h21v09.006.2015148124025.hdf"
 [3] "MOD17A3H.A2002001.h21v09.006.2015153182349.hdf" "MOD17A3H.A2003001.h21v09.006.2015166203852.hdf"
 [5] "MOD17A3H.A2004001.h21v09.006.2015099031743.hdf" "MOD17A3H.A2005001.h21v09.006.2015113012334.hdf"
 [7] "MOD17A3H.A2006001.h21v09.006.2015125163852.hdf" "MOD17A3H.A2007001.h21v09.006.2015169164508.hdf"
 [9] "MOD17A3H.A2008001.h21v09.006.2015186104744.hdf" "MOD17A3H.A2009001.h21v09.006.2015198113503.hdf"
[11] "MOD17A3H.A2010001.h21v09.006.2015216071137.hdf" "MOD17A3H.A2011001.h21v09.006.2015230092603.hdf"
[13] "MOD17A3H.A2012001.h21v09.006.2015254070417.hdf" "MOD17A3H.A2013001.h21v09.006.2015272075433.hdf"
[15] "MOD17A3H.A2014001.h21v09.006.2015295062210.hdf"

filename <- substr(files,11,14)
filename <- paste0("NPP", filename, ".tif")
filename

[1] "NPP2000.tif" "NPP2001.tif" "NPP2002.tif" "NPP2003.tif" "NPP2004.tif" "NPP2005.tif" "NPP2006.tif" "NPP2007.tif" "NPP2008.tif"
[10] "NPP2009.tif" "NPP2010.tif" "NPP2011.tif" "NPP2012.tif" "NPP2013.tif" "NPP2014.tif"

i <- 1

for (i in 1:15){
  sds <- get_subdatasets(files[i])
  gdal_translate(sds[1], dst_dataset = filename[i])
}

Vous pouvez maintenant lire vos fichiers .tif dans R en utilisant, par exemple, raster à partir du package raster et travailler normalement. J'ai comparé les fichiers résultants avec quelques-uns que j'ai convertis manuellement à l'aide de QGIS et ils correspondent, ce qui fait que je suis convaincu que le code fonctionne comme je le crois. Merci à Loïc Dutrieux et this pour l’aide!

14
James

Ce script a été très utile et j'ai réussi à convertir un lot de 36 fichiers en l'utilisant. Cependant, mon problème est que la conversion ne semble pas correcte. Lorsque je le fais à l'aide de l'outil Créer une couche NetCDF Raster d'ArcGIS, j'obtiens des résultats différents. Je peux convertir les nombres en C à partir de Kelvin à l'aide d'une formule simple: RasterValue * 0.02 - 273.15. Avec les résultats de la conversion R, je n'obtiens pas les bons résultats après la conversion, ce qui me laisse penser que la conversion ArcGIS est bonne et que la conversion R renvoie une erreur.

library(gdalUtils)
library(raster)

setwd("D:/Data/Climate/MODIS")

# Get a list of sds names
sds <- get_subdatasets('MOD11C3.A2009001.006.2016006051904.hdf')
# Isolate the name of the first sds
name <- sds[1]
filename <- 'Rasterinr.tif'

gdal_translate(sds[1], dst_dataset = filename)
# Load the Geotiff created into R
r <- raster(filename)

# Identify files to read:
rlist=list.files(getwd(), pattern="hdf$", full.names=FALSE)


# Substract last 5 digits from MODIS filename for use in a new .img filename
substrRight <- function(x, n){
        substr(x, nchar(x)-n+1, nchar(x))
}

filenames0 <- substrRight(rlist,9)
# Suffixes for MODIS files for identyfication:
filenamessuffix <- substr(filenames0,1,5)

listofnewnames <- c("2009.01.MODIS_","2009.02.MODIS_","2009.03.MODIS_","2009.04.MODIS_","2009.05.MODIS_",
                    "2009.06.MODIS_","2009.07.MODIS_","2009.08.MODIS_","2009.09.MODIS_","2009.10.MODIS_",
                    "2009.11.MODIS_","2009.12.MODIS_",
                    "2010.01.MODIS_","2010.02.MODIS_","2010.03.MODIS_","2010.04.MODIS_","2010.05.MODIS_",
                    "2010.06.MODIS_","2010.07.MODIS_","2010.08.MODIS_","2010.09.MODIS_","2010.10.MODIS_",
                    "2010.11.MODIS_","2010.12.MODIS_",
                    "2011.01.MODIS_","2011.02.MODIS_","2011.03.MODIS_","2011.04.MODIS_","2011.05.MODIS_",
                    "2011.06.MODIS_","2011.07.MODIS_","2011.08.MODIS_","2011.09.MODIS_","2011.10.MODIS_",
                    "2011.11.MODIS_","2011.12.MODIS_")

# Final new names for converted files:
newnames <- vector()
for (i in 1:length(listofnewnames)) {
        newnames[i] <- paste0(listofnewnames[i],filenamessuffix[i],".img")
}

# Loop converting files to raster from NetCDF
for (i in 1:length(rlist)) {
        sds <- get_subdatasets(rlist[i])
        gdal_translate(sds[1], dst_dataset = newnames[i])
}
1
MIH

Ce qui suit a fonctionné pour moi. C'est un programme court qui prend juste le nom du dossier d'entrée. Assurez-vous de connaître les sous-données que vous souhaitez. Je me suis intéressé aux sous-données 1.

library(raster)
library(gdalUtils)

inpath <- "E:/aster200102/ast_200102"

setwd(inpath)

filenames <- list.files(,pattern=".hdf$",full.names = FALSE)

for (filename in filenames)
{
     sds <- get_subdatasets(filename)
     gdal_translate(sds[1], dst_dataset=paste0(substr(filename, 1, nchar(filename)-4) ,".tif"))
}
0
Rajasweta Datta

Utilisez la boîte à outils HEG fournie par la NASA pour convertir votre fichier hdf en fichier géotiff, puis utilisez n’importe quel package ("raster" par exemple) pour lire le fichier. Je fais la même chose pour les anciens et les nouveaux fichiers hdf.

Voici le lien: https://newsroom.gsfc.nasa.gov/sdptoolkit/HEG/HEGHome.html

Jetez un coup d'œil aux produits de la NASA pris en charge ici: https://newsroom.gsfc.nasa.gov/sdptoolkit/HEG/HEGProductList.html

J'espère que cela t'aides.

0
Dhruva Kathuria