أكثر

لا يمكن استيراد ملفات MODIS MOD07_L2 .hdf بشكل صحيح إلى R باستخدام rgdal

لا يمكن استيراد ملفات MODIS MOD07_L2 .hdf بشكل صحيح إلى R باستخدام rgdal


لقد كنت أحاول استيراد بعض ملفات .hdf ومعالجتها بدقة من منتج MODIS Atmospheric Profile (MOD07_L2) في R لعدة أيام حتى الآن. مع ذلك ، هناك خطأ ما يحدث أثناء استيراد البيانات. يمكن إعادة إنتاج الكود أدناه باستخدام ملف .hdf نموذجي واحد (MOD07_L2.A2013001.0835.006.2013001192145.hdf) يمكن تنزيله من Dropbox.

library (rgdal) # استخراج البيانات الوصفية من خلال اسم ملف 'GDALinfo' <- "MOD07_L2.A2013001.0835.006.2013001192145.hdf" gdalinfo <- GDALinfo (filename، returnScaleOffset = FALSE) metadata <- attr (gdalinfo، ") من سلسلة SDS للمعلمة 'Skin_Temperature' (المعروفة سابقًا باسم 'Surface_Temperature') sds <- البيانات الوصفية [grep ("Skin_Temperature" ، البيانات الوصفية) [1]] sds <- sapply (strsplit (sds، "=")، "["، 2) # استيراد البيانات النقطية عبر sds.rg 'readGDAL' <- readGDAL (sds)

حتى الآن ، جيد جدًا ، ولكن هنا يأتي الجزء المربك:

> ملخص (sds.rg $ band1) كحد أدنى. 1st Qu. متوسط ​​متوسط ​​3rd Qu. الأعلى. NA's-14870-14850-14850-14840-14840-14820 53529

بالنظر إلى حقيقة أن Skin_Temperature له نطاق رسمي صالح من 150 إلى 350 كلفن (انظر MOD07_L2: التنسيق والمحتوى) ، فإن المتوسط ​​سيرث قيمة

> (-14840 - (-15000)) * 0.01 [1] 1.6

بعد النظر في add_offset المقابل (-15000) و scale_factor (0.01). لاحظ أننا ما زلنا نتحدث عن كلفن ، وليس درجة مئوية. استخراج SDS رقم 8 ، أي درجة حرارة الجلد ، باستخدام

مكتبة (gdalUtils) gdal_translate (اسم الملف ، dst_dataset = "tmp.tif" ، sd_index = 8)

وفتح الملف الناتج المسمى "tmp.tif" في QGIS نتج عنه قيم موثوقة على ما يبدو تتمحور حول 15000 ، أي ما يقرب من 27 درجة مئوية. ومع ذلك ، فإن استيراد "tmp.tif" مرة أخرى إلى R باستخدامالنقطيةأدى مرة أخرى إلى قيم مماثلة لتلك الموضحة أعلاه:

> ملخص (نقطية ("tmp.tif")) tmp دقيقة. -14867.31 الشوط الأول. -14848.13 متوسط ​​-14845.89 الربع الثالث. -14840.53 كحد أقصى. -14819.93 غير متوفر 0.00

لقد كنت أبحث في الإنترنت ووجدت مشاكل مماثلة متعلقة بـ rgdal. ومع ذلك ، عندما حاولت أن يلقيtoUnSignedفي النطاق 1 من "SpatialGridDataFrame" الذي تم إنشاؤه مسبقًا ، تلقيت رسالة الخطأ التالية:

> toUnSigned (sds.rg $ band1، 16) خطأ في toUnSigned (sds.rg $ band1، 16): النطاق ليس عددًا صحيحًا

على ما يبدو ، فإن البيانات التي يتم استيرادها إلى R ليست حتى من نوع عدد صحيح (ما يفترض أن تكون) ، ولكنها رقمية:

> sds.rg $ band1 [1: 5] [1] NA NA -14839.40 -14840.25 -14839.26

هل هناك خطأ واضح في الكود الخاص بي ، أو هل هناك أي نقطة أفتقدها عند استيراد ملفات .hdf و. tif باستخدامرجدال؟ سأكون ممتنا للغاية لأي نوع من المساعدة.


الجواب بسيط بشكل مدهش.

sgr_lst <- readGDAL (sds، as.is = TRUE)

يحل المشكلة. الشيء الوحيد المتبقي لفعله هو تحويل الناتجSpatialGridDataFrameلليمينالنقطية *الكائن باستخدامنقطية (). لهذا الغرض ، من الضروري استرداد إحداثيات الحدود الغربية والشرقية والجنوبية والشمالية (انظر؟مدى: xmin، xmax، ymin، ymax) من البيانات الوصفية على سبيل المثال عبر

meta <- attr (gdalinfo، "mdata") ## أنماط السلسلة crd_str <--aste0 (c ("WEST"، "EAST"، "SOUTH"، "NORTH")، "BOUNDINGCOORDINATE") ## البحث عن الأنماط في البيانات الوصفية crd_id <- sapply (crd_str، function (i) grep (i، meta)) ## استخراج المعلومات crd <- meta [crd_id] ## إنشاء كائن 'مدى' crd <- as.numeric (sapply (strsplit (crd، " = ")،" [["، 2)) ext <- مدى (crd)

يمكن بعد ذلك تمرير المدى المحدد بهذه الطريقة (جنبًا إلى جنب مع كود EPSG) إلى ما تم إنشاؤه أخيرًاالنقطيةوالتي ، بعد تطبيق عامل المقياس والإزاحة ، تبدو جيدة بالتأكيد الآن.

## تنقيط وتطبيق الإزاحة وعامل القياس rst_lst <- (النقطية (sgr_lst) - -1.5e + 04) * 1.0e-02 ## تعيين المدى ومدى الإحداثيات المرجعية (rst_lst) <- إسقاط crd (rst_lst) <- "+ init = epsg: 4326"


لم أتمكن من القيام بذلك في R أيضًا ... وقضيت أيضًا ساعات لا تحصى. ما أفعله الآن هو هذا:

  1. استخدم أداة ModisReprojection لاستخراج الطبقات وملفات
    مجموعات فرعية أحتاجها كملفات ثنائية
  2. قراءة الملفات الثنائية وتحويلها إذا لزم الأمر إلى كائنات "نقطية". أنا أستخدمها بشكل أساسي كمصفوفة وفي النهاية حولها إلى كائنات نقطية لكتابتها بتنسيق TIFF

الكود لتشغيل MRT:

# إعادة الإسقاط من HDF إلى ثنائي عادي باستخدام MRT setwd ('/ Volumes / Archive1 / MOD11C3V5 /') DIR <- getwd () # قم بتشغيل أداة Modis Reproject Tool مرة واحدة باستخدام ملف HDF واحفظ المعلمات المطلوبة في ملف .prm # استخدم ملف .prm هذا هنا: ReprojectionParamter <- 'Pamir0.05_binray.prm' # الحصول على قائمة الملفات التي تريد معالجة FileList <- list.files () FileListHDF <- FileList [الذي (regexpr (pattern = 'hdf) $ '، FileList)> 0)] # ملفات hdf فقط وليس ملفات hdf.xml ### تعيين المتغيرات البيئية لـ MRT_DATA_DIR Sys.setenv (MRT_DATA_DIR =' / Volumes / DATA / ModisReprojectionTool / data ') Sys.setenv (MRTDATADIR = '/ Volumes / DATA / ModisReprojectionTool / data') لـ (أنا في FileListHDF) {النظام (الأمر = لصق ('/ Volumes / DATA / ModisReprojectionTool / bin / resample -p' ، ReprojectionParamter ، '-i' ، DIR ، '/'، i، '-o'، DIR، '/ binary_small /'، i، '. hdr'، sep = ")، انتظر = T،)}

ثم يتعين عليك تعيين الوسيطة "ماذا" في readBin إلى int ، و numeric ، وما إلى ذلك ... لدي دائمًا نفس النطاق من ملفاتي (المحددة في ملف "prm") أحصل على المدى والدقة مباشرة من هناك:

ReprojectionParamter <- scan ('Pamir0.05_binary2.prm'، nmax = 90، what = 'character') SpatExtent.minLon <- as.numeric (ReprojectionParamter [31]) SpatExtent.minLat <- as.numeric (ReprojectionParamter [36] ) SpatExtent.maxLon <- as.numeric (ReprojectionParamter [37]) SpatExtent.maxLat <- as.numeric (ReprojectionParamter [30]) SpatExtent.RES <- as.numeric (ReprojectionParamter [72]) # readBinary function UInt8_LST (f ،…) readBin (f ، what = "عدد صحيح" ، موقع = FALSE ، endian = "قليل" ، الحجم = 2 ،…) # اقرأ البيانات أخيرًا ؛ Nlat و Nlon وما إلى ذلك يمكنك حسابه بسهولة من المعلومات الموجودة في ملف prm ؛ 0.02 كان عامل القياس الخاص بي NC.LST_night <- المصفوفة (UInt8_LST (f = LST_night.filename ، n = Nlon * Nlat)) ، nrow = Nlat ، ncol = Nlon ، byrow = T) * 0.02-273.15

ربما يساعد.


أريد فقط أن أقول إن إجابة fdetsch قد لا تكون صحيحة لأن المدى الذي تم إنشاؤه منلونمين,لونماكس,لاتمين,لاتماكسقد لا تتطابق مع حدود الشبكة الفعلية. عادة ما تكون الصورة مائلة.

رابط صندوق الإسقاط غير صالح ، لذا أقوم بتنزيل ملف التاريخ نفسه (الإصدار المحدث) من هنا

فيما يلي ما رسمته برمز fdetsch:

أدناه هو رمز بلدي ومؤامرة:

hdfname = "MOD07_L2.A2013001.0835.061.2017296134818.hdf" GDALinfo (hdfname، returnScaleOffset = FALSE) # لاحظ أن مجموعتي البيانات الفرعية 29 و 30 هما خط العرض والخط الأول <- getSds (hdfname) lat = نقطية (readS4g (واحد $ SDfname) 29]، as.is = TRUE)) lon = نقطية (readGDAL (واحد $ SDS4gdal [30]، as.is = TRUE)) Skin_Temperature <- brick (readGDAL (one $ SDS4gdal [8]، as.is = TRUE) ) درجة حرارة الجلد <- (درجة حرارة الجلد - (-15000)) * 0.009999999776482582 # يبدو أن عامل التحجيم تغير بعد تحديث البيانات اللون <- rev (terrain.colors (100)) [as.numeric (cut (Skin_Temperature [] ، فواصل = 100))] المؤامرة (lon [] ، lat [] ، pch = 20 ، col = color ، xlab = "lon" ، ylab = "lat") # مؤامرة


شاهد الفيديو: سيراميك ارضيات سيراميك حمامات الوان واشكال رائعة