
简介这份MODIS大数据说明书经典版是一份面向遥感、地理信息系统与生态环境研究人员的实用速查文档系统介绍了中分辨率成像光谱仪主要陆地数据产品的体系结构重点涵盖地表反射率、植被指数、陆地水面掩膜、地表温度与发射率、CMG全球拼接产品等核心数据集可帮助读者快速理解产品命名规则、分辨率、时间合成周期与适用领域有效解决数据筛选和调用时的分类困惑。资源包共1个文档doc格式大小约659KB内容以清晰表格为主逐项对照各产品系列的名称、平台、波段、空间分辨率及更新频率适合科研人员、研究生及相关从业者案头常备。目前已有222人学习浏览。通过这份经典说明书读者能够一站式掌握常用MODIS产品的关键参数与使用特点快速定位适用于植被监测、气候变化、火点和热异常分析等方向的数据集大幅提升数据获取与研究效率。1. 从一份老文档说起为什么还要读 MODIS 大数据说明书如果你刚接触遥感数据处理第一次拿到乌云 MODIS 数据的 HDF 文件时大概率是懵的一个文件多大、内含几个波段、投影是什么、像元值怎么定标这些问题就像一团迷雾。这也是为什么一份«MODIS大数据说明书(经典).doc»能成为很多实验室和学生电脑里的“传家宝”——尽管它只是备忘录式的技术笔记却把 MODIS 数据产品从命名规则到处理流程讲得清清楚楚比很多论文附录都实用。这篇博文要做的就是把这份经典说明书的“干货”拆开从数据产品体系、批量下载到预处理重投影再到大数据量场景下的拼接、取均值、气象参数提取给你一条能照做的路径。适合刚接手 MODIS 数据的研究生、做环境监测和农业遥感的工程师以及想把自己的批处理脚本升级成半自动化流水线的开发者。读完后你至少能搞清楚我需要哪个产品、该去哪里拿、拿到后怎么处理、以及哪些坑可以绕开。2. MODIS 数据产品体系拿到文件先看懂命名和投影2.1 从 250m 到 1km三种空间分辨率的“产品家族”MODIS 搭载在 Terra 和 Aqua 两颗卫星上虽然扫描幅宽达到 2330km但空间分辨率并不是统一的。公开数据里最常见的是三类250m 分辨率仅第 1、2 波段红光 620-670nm、近红外 841-876nm主要用于植被指数计算。500m 分辨率第 1-7 波段覆盖可见光到短波红外适合土地覆盖、积雪、气溶胶等产品。1000m 分辨率全 36 个波段气象、海洋、热异常等产品都建立在这一档上。这个区分直接决定你下载文件的大小。一个 250m 的 MOD02QKM 文件可能只有 50MB 左右而 1km 的 MOD021KM 则可能接近 130MB。下载前先想明白你的研究需要哪些波段如果只需要 NDVI没必要下全波段的 MOD02 再自己筛选直接找 MOD13 产品更省事。2.2 MxD 与 MCD 开头六个字符背后的卫星和产品类型MODIS 文件名的第一段字符是产品简称例如 MOD09GA、MYD11A1、MCD43A4。规则如下前缀含义示例MODTerra 卫星数据MOD13Q1Terra 植被指数 16 天合成MYDAqua 卫星数据MYD11A1Aqua 地表温度日产品MCDTerraAqua 联合产品MCD43A3BRDF 校正后的反照率同一产品名称后跟的数字与字母组合代表不同处理级别0 级为原始数据1 级为定标后的辐亮度2 级为 geolocated 产品带经纬度3 级为网格化产品正弦投影4 级及以上是模型输出。在大多数地表应用里你接触的是 2 级和 3 级产品。提示文件名开头“MOD”与“MYD”不要混用。如果你做植被物候分析Terra 和 Aqua 的过境时间不同混用可能导致时间序列不连续。2.3 正弦投影为什么 MODIS 的“平铺直叙”反而麻烦L3 级 MODIS 产品采用正弦投影Sinusoidal每个瓦片大小为 10°×10°纬度方向和约 10°×10°经度方向全球被划分为水平 36 列、垂直 18 行共 648 个瓦片。文件名的后半段如 h25v05就代表瓦片行列号其中 h 为水平编号0-35v 为垂直编号0-17。问题在于大多数使用者熟悉的 WGS84 经纬度坐标并不会和正弦投影对齐。如果直接用 GDAL 打开 HDF 文件并转为 GeoTIFF会遇到影像“歪着”或出现黑边的情况。后续处理必须先做重投影通常投影到 UTM 或 Albers 等面积投影具体选哪个取决于你的研究区是否跨带。2.4 哪些数据集能获取气象信息说明书里最常被翻到的部分是“如何从 MODIS 提取气象相关参数”。这里整理几个实用产品MOD05/MYD05总可降水量PWL单位 cm分辨率 1km能反映大气水汽含量。MOD06/MYD06云顶温度、云顶气压、云相态这些对气象和气候研究很有价值。MOD07/MYD07大气剖面数据包含温度、湿度廓线分辨率 5km也是气象数据常用来源。MOD11/MYD11地表温度LST有白天和夜间两个过境时刻的数据分辨率为 1km 或 6km。这些产品之间相互配合比如计算地表能量平衡时需要同时用 MOD07 的大气廓线去校正 MOD11 的地表温度。说明书往往只告诉你这些产品的名称但不会告诉你“怎么用”这正是本文后半部分想补充的内容。3. 批量下载 MODIS 数据的四个渠道与脚本化方案3.1 官方渠道优先级排序从 LAADS 到 Earthdata Search获取 MODIS 数据的官方渠道有很多但如果追求效率和自动化我一般这样排序LAADS DAACLevel-1 and Atmosphere Archive Distribution System适合下载 L1 和大气产品支持按时间范围批量检索且无需申请即可下载大部分 MODIS 数据。NASA Earthdata Search适合按瓦片和日期精确选框需要注册 Earthdata 账号系统会自动生成下载链接列表。USGS EarthExplorer适合同时需要 MODIS 和 Landsat 等多源数据的用户。AppEEARS不需要下载整景影像只提取点或区域均值时很高效。注意NASA 的下载系统针对不同产品分了不同数据池部分产品如 MOD09GA在 LAADS 上可以直接找到而 MOD13Q1 则优先出现在 Earthdata 检索里。检索不到时先切换数据源不要怀疑自己。3.2 用 Python 脚本自动搜索并下载以 MODIS NPP 为例如果你要下载 MOD17A3H年 NPP 产品手动点击可能要点几百次。更高效的方式是用 Python 配合requests库直接调用 CMRCommon Metadata Repository搜索接口。以下是我常用的一个脚本模板import requests def search_modis(product, start_date, end_date, bbox, token): 通过 CMR API 搜索 MODIS 产品下载链接 product: 产品名如 MOD17A3H start_date/end_date: 如 2020-01-01, 2021-01-01 bbox: 经纬度范围 [min_lon, min_lat, max_lon, max_lat] token: Earthdata 登录后的 token cmr_url https://cmr.earthdata.nasa.gov/search/granules.json params { short_name: product, bounding_box: ,.join(map(str, bbox)), temporal: f{start_date},{end_date}, page_size: 200, token: token } resp requests.get(cmr_url, paramsparams, timeout60) resp.raise_for_status() items resp.json().get(feed, {}).get(entry, []) links [item[links][0][href] for item in items if item.get(links)] return links # 使用示例 if __name__ __main__: token 你的 earthdata token links search_modis( productMOD17A3H, start_date2020-01-01, end_date2020-12-31, bbox[100, 30, 110, 40], tokentoken ) print(f共找到 {len(links)} 个文件) for link in links[:5]: print(link)这段代码的逻辑是先调 CMR 搜索接口获取文件下载地址再拿到链接后交给后续下载逻辑。这里的关键参数是bounding_box经纬度顺序是“西、南、东、北”写反会检索不到结果。page_size最大可以设为 2000但建议保持小批量避免响应超时。拿到链接后下载时还需要注意CMR 返回的链接往往带临时令牌直接复制到浏览器里能下载但用wget批量下载时需要附带Authorization: Bearer头。更省事的做法是用earthaccess库它封装了认证和下载流程pip install earthaccessimport earthaccess earthaccess.login(strategynetrc) files earthaccess.search_data( short_nameMOD17A3H, bounding_box(100, 30, 110, 40), temporal(2020-01-01, 2020-12-31) ) earthaccess.download(files, local_path./modis_npp)3.3 解决下载超时与断点续传MODIS 文件通常不小网络不稳定时容易中断。在 Linux 下用wget加-c参数能实现断点续传在 Python 里则建议用requests配合流式写入并处理异常import requests, os def download_with_resume(url, local_path): 带断点续传的下载适合大文件 headers {} if os.path.exists(local_path): headers[Range] fbytes{os.path.getsize(local_path)}- with requests.get(url, streamTrue, headersheaders, timeout120) as r: r.raise_for_status() mode ab if headers else wb with open(local_path, mode) as f: for chunk in r.iter_content(chunk_size1024 * 1024): f.write(chunk)用 Range 头告诉服务器从哪个字节开始续传前提是服务器支持断点续传LAADS 是支持的。此外建议在脚本里加随机延时1~3 秒避免请求频率过高被限流。4. 预处理流程拼接、重投影与裁剪4.1 先拼接还是先重投影拿到多个瓦片后处理顺序会影响输出质量。我的默认流程是先拼接再重投影最后裁剪研究区。原因是 MODIS L3 级产品的瓦片边界本身有重叠先拼接能保证瓦片接边处的像元值保持一致避免逐瓦片重投影后因插值引起的边缘错位。但如果你只处理一个瓦片且研究区横跨两个瓦片那么最好先用HDF-EOS To GeoTIFF Conversion Tool (HEG)或 GDAL 的 VRT 机制做处理具体流程如下用gdalbuildvrt拼接多个 HDF或已转换的 GeoTIFF为 VRT 虚拟文件。对 VRT 做投影转换输出 GeoTIFF。再用gdalwarp裁剪。这样不会产生中间大文件的 I/O 浪费VRT 只在需要时读底层文件。4.2 用 GDAL 完成重投影和裁剪的最小命令以 500m 地表反射率产品 MOD09GA 为例研究区范围是一个 shp 边界。这是一个可复用的命令序列# 1. 将 HDF 中的地理定位科学数据集提取出来得到带地理参考的 VRT gdalbuildvrt mod09ga.vrt HDF4_EOS:MODIS_Grid_500m_2D:MOD09GA.hdf:sur_refl_b01 # 2. 查看投影信息 gdalinfo mod09ga.vrt # 3. 重投影到 WGS84并使用研究区范围裁剪 gdalwarp -t_srs EPSG:4326 -cutline study_area.shp -crop_to_cutline \ -r bilinear -of GTiff mod09ga.vrt mod09ga_wgs84_cut.tif # 4. 检查输出 gdalinfo mod09ga_wgs84_cut.tif | grep -E Pixel Size|Corner参数说明-t_srs EPSG:4326表示把输出投影设置为 WGS84 经纬度。-cutline指定裁剪矢量边界文件-crop_to_cutline让输出严格贴合矢量范围。-r bilinear是指定重采样算法。反射率这类连续变量用双线性插值即可如果是分类数据如土地覆盖类型要改成-r near。4.3 Python xarray 实现批量处理如果你有几十块瓦片、多个时间点命令行逐条跑会非常痛苦。更高效的方式是 xarray rioxarray 配合处理。这里给出一个封装好的处理片段import rioxarray import xarray as xr from glob import glob def mosaic_by_date(date_str, tile_list, output_path): 对某一天的多个瓦片做拼接重投影输出 date_str: 日期字符串如 20200601 tile_list: 瓦片对路径 [h25v05, ...]实际是文件路径列表 ds_list [] for tile in tile_list: # 打开子数据集 ds rioxarray.open_rasterio(fHDF4_EOS:MODIS_Grid_500m_2D:{tile}:sur_refl_b01) ds_list.append(ds) # 拼接 combined xr.concat(ds_list, dimy) # 重投影到 4326 combined combined.rio.reproject(EPSG:4326, resampling0) # 0 nearest # 裁剪假设有 study_area combined.rio.set_crs(EPSG:4326, inplaceTrue) combined.rio.clip(study_area.geometry, study_area.crs, dropTrue) combined.rio.to_raster(output_path) mosaic_by_date(20200601, glob(MOD09GA.A2020152*.hdf), out_20200601.tif)这里需要注意xr.concat的dim如果是瓦片之间的空间关系应沿 “y” 拼接而不是 “x”。不同瓦片的行列号并不连续直接拼接会让图像空间错位。更稳妥的做法是先给每个数据集赋坐标或经纬度维度再用merge方式合并或者直接依赖rio.composite。4.4 表常见重采样方法与适用场景重采样方法适用变量类型说明nearest分类数据、土地利用保持原始像元值不变避免产生伪类别bilinear连续型变量反射率、NDVI处理平滑计算快cubic/cubicspline连续性强的气象参数LST、水汽边缘可能过冲需检查结果范围average从高分辨率聚合到低分辨率对降尺度数据平均效果最好对于 LST 这类温度产品优先用 cubic 但不建议做大幅降尺度否则在城市热岛研究中边界会产生明显伪差。5. 气象信息提取技巧从 LST 和水汽到 5km 剖面5.1 MOD11A1 的地表温度定标与去云检查得到每天的 MOD11A1 产品后不能直接拿 DN 值当温度用。地表温度科学数据集LST_Day_1km的缩放系数是 0.02偏移是 0所以实际温度单位 K需要乘以 0.02。同时像元质量标识QC信息必须查看推荐做法是# 用 gdal_calc 把无效像元置为 NaN gdal_calc.py -A MOD11A1.tif -B MOD11A1_QC.tif \ --outfileLST_valid.tif \ --calcwhere(B 3, A*0.02, ——值) \ --NoDataValue0QC 取 0 表示“良好质量”1 为“次优”2 为“较差”3 为“云遮挡或无效”。在合成日地表温度序列前先把 QC 阈值放宽到 1再对有效像元求平均这样能在数据覆盖率和精度之间取得平衡。5.2 从 MOD07 提取温度廓线并作垂直插值MOD07_L2 的空间分辨率是 5km包含 20 层气压层的温度、湿度数据。提取时要把 HDF 层转成二维数组并按气压值进行线性插值才能得到指定高度如 850hPa的温度# 提取 MOD07 的某层温度并插值到目标气压层 from scipy.interpolate import interp1d def extract_temperature_at_pressure(ds, pressure_levels, target_pressure): ds: 读取的 MOD07 温度数据20层 pressure_levels: 各层对应的气压值hPa target_pressure: 目标气压层如 850 temps ds.sel(levelpressure_levels).values f interp1d(pressure_levels, temps, axis0, fill_valueextrapolate) return float(f(target_pressure))注意interp1d默认不允许外推而野外观测站气压有时会低于最低层的气压值所以必须显式设置fill_valueextrapolate否则边界点会出现空值。5.3 月度合成的一个实际案例2020 年夏季地表温度平均取 2020 年 6-8 月每天白天的 LST做逐像元平均合成夏季平均地表温度。一个高效的写法是import xarray as xr import glob files glob.glob(LST_valid_2020060*.tif) # 6月1-10日 data xr.open_mfdataset(files, combineby_coords) summer_lst data.mean(dimtime) summer_lst.rio.to_raster(summer_lst_2020.tif)open_mfdataset会自动按时间维度拼接前提是每景影像的像元坐标完全对齐。如果你在重投影阶段用了不同的目标分辨率或重采样方式坐标不对齐combineby_coords会直接报错。所以预处理时就要统一约定所有影像按同一-tr参数输出分辨率重采样。6. 大数据量场景下的加速方案与常见报错6.1 文件检索阶段的预筛选不必下载全部数据MODIS 大数据集动辄数百个文件但很多是云盖度高的无效数据。在 LAADS 或 CMR 里可以根据C loud percent属性筛选。比如 CMR 检索时增加一个条件params.update({cloud_cover: [0,20]})这个参数会过滤掉云量大于 20% 的影像对光学数据来说能大幅减少无效下载。但注意这个属性并不是每个产品都提供对 MOD02 通常有效对 MOD11 这类温度产品则不一定。6.2 分布式处理思路从单机脚本到集群部署当研究区跨多个瓦片且时间序列长达 10 年单机跑重投影可能要一天一夜。常见做法是把任务按“瓦片-年份”分块丢到多核或集群上。用 GNU Parallel 是最轻量的方式cat task_list.txt | parallel -j 8 python process.py {1}每个{1}是一行参数。如果你有 Spark 或 Dask 环境则可以让xarray.open_mfdataset直接对接 Dask 分布式调度器对瓦片分块读取和计算。要注意的是 Dask 的惰性求值很容易把内存打满建议在open_mfdataset时显式指定chunks{x: 1000, y: 1000}。6.3 三个高频坑Grid 偏移、Tile 边界、QC 矩阵在真正的数据生产里我会反复检查三件事Grid 偏移MODIS 正弦投影的分块网格在赤道附近会有约 0.05° 的偏移拼接时若直接按行列号对齐会产生“锯齿”。解决办法是一律用经纬度坐标进行重投影后再拼接而不是直接凭 HDF 的行列坐标。Tile 边界相邻瓦片在接边处的像元值往往有明显跳跃尤其是反射率产品可能是因光照角度差异。如果不做镶嵌羽化直接拼接会看到亮暗分界线。GDAL 提供了-dstalpha或-wo BLEND_NUM_TILES1做平滑但更可靠的是用 MODIS MCD43 产品已经做了 BRDF 校正这类接边问题会小很多。QC 矩阵很多产品如 MOD13Q1包含独立的像元可靠性矩阵每像素还另有质量标志。别人给你数据做分析时一定要检查两套质量信息是否一致否则 NDVI 时序里会掺入云污染点导致物候识别出错。6.4 把例行检查固化成一个小脚本最后分享一个小习惯每批数据处理好后我会用一个 20 行的 Python 脚本做基础质控内容包括像元范围、均值、标准差、无效像元占比。这类脚本的意义在于你可以把质控标准固化下来新数据来了跑一遍在进入分析之前就能发现问题而不是等到趋势图出现异常后才回头排查。import rasterio import numpy as np def quick_check(tif_path): with rasterio.open(tif_path) as src: data src.read(1).astype(float32) nodata src.nodatavals[0] valid data[data ! nodata] print(f文件: {tif_path}) print(f有效像元数: {len(valid)}, 占比 {100*len(valid)/data.size:.2f}%) print(f均值: {np.nanmean(valid):.3f}, 标准差: {np.nanstd(valid):.3f}) print(f最小/最大: {np.nanmin(valid):.3f}/{np.nanmax(valid):.3f})本文还有配套的精品资源点击获取