简介面向遥感、GIS与地球观测初学者的MODIS入门文档聚焦MODIS数据背景、获取与处理流程帮助读者快速建立从传感器参数到产品应用的系统认识。压缩包仅含1个doc文件约503KB内容围绕Terra/Aqua双星、36个波段、250m至1000m分辨率、正弦投影产品及NASA免费下载方式展开并延伸至HDF格式读取、ENVI/ArcGIS处理、去云校正、时序合成与植被指数、地表温度提取等环节。已有304人学习适合课程学习、科研入门和实习准备时作为速查资料也能为土地覆被、气候与灾害监测等应用提供参数依据和操作思路。1. 很多人第一次打开一景 MODIS 数据都会觉得这套标称参数漂亮得不像二十多年前的设计36 个波段、2330 公里幅宽、1 到 2 天扫一遍全球MODIS 数据几乎是遥感入门绕不开的第一份真实数据。但真正用起来第一件卡住人的事往往不是算法而是那一堆看起来毫无必要的麻烦一个文件里躺着几十个数据集1 公里产品和 250 米产品混在同一个产品族里下载页面给的时间比本地时间少 8 小时文件名长得像一串密码投个影还得先拼接再转换。这些都不是随手设计的产物而是一整套被固定下来的数据契约——波段怎么切、分辨率怎么分、文件怎么命名、格网怎么铺、版本怎么迭代。把这套契约的来龙去脉搞明白后面的下载、拼接、重投影才不至于变成玄学。2. 36 个波段与三种分辨率一台传感器为什么要同时干三份活2.1 焦平面不是一块芯片而是几组探测器拼在同一个望远镜后面把 MODIS 想成一台“相机”是理解偏差的起点。它前面是一套口径 17.78 厘米的望远镜后面是一个焦平面不同波段的光落在焦平面的不同位置上被不同的探测器阵列接收。设计上最关键的一个约束是——同一个波段组里的探测元沿扫描方向是并排排列的扫一次就能同时得到若干条扫描线。这就带来了分辨率的分野。常见的实现思路是250 米波段1、2 波段每个扫描行排 40 个探测元500 米波段3 至 7 波段排 20 个1 公里波段8 至 36 波段排 10 个。探测元尺寸越小、排得越密瞬时视场越小地面分辨率就越高。但这不是白拿的探测元面积缩小接收到的光子数按面积下降信噪比随之恶化。250 米波段之所以只放两个是因为这两个波段承担的是植被叶绿素吸收和云/土地覆盖这类需要高空间细节、同时对辐射精度要求相对宽容的任务而 8 至 36 波段要做的是大气廓线、海面温度、云顶高度这类定量反演靠的是辐射精度而不是空间锐度1 公里完全够用把探测元做大反而换来了更好的噪声表现。波段组波段号星下点分辨率每行探测元典型主要约束可见/近红外高分辨率1–2250 m40空间细节优先信噪比预算紧可见/近红外中分辨率3–7500 m20陆表/云特征兼顾细节与辐射可见/短波红外8–19、261000 m10海洋水色、气溶胶弱信号需长积分热红外20–25、27–361000 m10噪声等效温差靠大探测元压噪声这张表解释了一个常被忽略的事实MODIS 的分辨率不是一个数而是三套并行的采样几何。你在一个 HDF 文件里同时拿到 250 米、500 米和 1 公里三层数据彼此之间不是缩放关系而是不同物理通道各自采样后再对齐的结果。用 pyhdf 打开一景 1B 数据能直接看到这种分层from pyhdf.SD import SD, SDC f SD(MOD02QKM.A2002032.1015.003.hdf, SDC.READ) # datasets() 返回文件内所有科学数据集名字本身就说明了分层 for name, info in f.datasets().items(): dims, dtype, attrs info print(name, dims, dtype) # 1B 里存的是整型 DN 值必须读 scales/offsets 才能还原物理量 sds f.select(EV_250_Aggr1km_RefSB) attrs sds.attributes() print(attrs[scales], attrs[offsets], attrs[band_names]) data sds[:] f.end()这段代码里最关键的不是读数据而是scales和offsets两个属性。HDF-EOS 里为了压缩存储把浮点反射率或辐亮度线性映射成 16 位整型物理量 DN × scale offset。跳过这一步直接拿原始 DN 值去算 NDVI得到的数值范围会完全不对——这是新手最常见的翻车点之一而且不会报错只会让结果悄悄错掉。2.2 像元大小会随扫描角膨胀星下点的 250 米在边缘不是 250 米MODIS 采用双面镜旋转扫描扫描速率 20.3 转/分每转约 2.96 秒产生两条沿轨 10 公里宽的扫描带。镜面摆动使视线从一侧 55 度扫到另一侧 55 度视场在地面展开成 2330 公里的弧。问题就出在这个“弧”上星下点视线垂直向下瞬时视场投影到地面最小越靠近扫描边缘视线越斜同一个瞬时视场在地面上拉出一个长椭圆。后果有两层。第一层是几何上的边缘像元的沿轨尺寸会被拉长到星下点的数倍250 米标称在扫描边缘可能实际覆盖上千米这就是常说的“蝴蝶结”bowtie效应——相邻扫描带在边缘互相重叠同一块地面被扫了两次。第二层是后续处理的如果你把 1B 数据当成规则格网直接做空间统计边缘区域的像元权重会被系统性高估。所以真正做定量应用时一般不会直接拿 1B 条带数据算面积或做时间序列而是走两条路要么用定位数据把每个像元投到规则格网上重采样要么直接用已经格网化的 3 级以上产品。这个取舍后面还会反复出现——MODIS 的设计哲学是“原始数据尽量保真规整工作交给下游”。2.3 反射波段和发射波段是两套物理机制不能用同一套定标思路把 36 个波段分成两组看会清楚很多。1 至 19 波段加 26 波段是反射波段接收的是地表反射的太阳辐射物理量是反射率只在白天有效且强烈依赖太阳高度角和观测几何。20 至 25、27 至 36 波段是发射波段接收的是地物自身的热辐射物理量是辐亮度或亮温昼夜都能用。这两组波段的星上定标方式完全不同反射波段靠太阳漫反射板把已知辐亮度的光引入视场做参考发射波段靠黑体做参考源。因此 1B 产品里反射波段给你的是反射率发射波段给你的是辐亮度两者在同一个文件里但语义不同。混着算——比如把热红外辐亮度当成反射率归一化——是另一个典型的静默错误。记住一个判断法则需要太阳的短波部分对应“地表长什么样”自发辐射的长波部分对应“地表有多热、大气有多冷”。前者决定了大部分陆地产品后者支撑了地表温度、云顶高度、大气廓线这一整条产品线。3. 1 到 2 天覆盖全球2330 公里幅宽和正弦格网背后的几何账3.1 覆盖频次不是拍脑袋定的是一道除法题705 公里高度、太阳同步近极轨、约 98.8 分钟一圈一天大致能转 14 到 15 圈。赤道周长约 4 万公里单条轨道的观测幅宽 2330 公里两者相除大约是 17.2——也就是说要把赤道完整铺满一遍需要 17 条左右的相邻轨道。单颗星一天只能提供 14 到 15 条凑不满一圈于是单星的重访周期落在 2 天附近。两颗星错开相位运行互补之后就压到了 1 天。这个算法值得自己算一遍因为它是理解后面所有“为什么”的钥匙为什么高纬度地区一天能被覆盖好几次轨道在此收敛相邻轨道重叠严重为什么赤道地区总有缝隙为什么某些日期某个区域就是没有数据——不是下载失败是几何上根本没扫到。98 度的轨道倾角让卫星能覆盖到极区这也是极轨气象卫星的标准做法。太阳同步的含义是降交点地方时基本固定Terra 在上午 10:30 左右由北向南过赤道Aqua 在下午 13:30 左右由南向北过赤道。地方时固定带来的好处是光照条件一致同一地区每次观测的太阳高度角相近时间序列才好比较代价是永远看不到某些时刻的地表状态。3.2 上午星和下午星不是简单备份而是各看各的时段把两颗星理解成“多发一份数据”就浪费了。上午 10:30 前后地表经过一夜冷却边界层还没充分发展云量相对少对陆地表面观测更友好下午 13:30 前后地表受热充分对流云发展旺盛大气中的水汽和云信息更丰富。所以陆地产品大量来自上午星大气和海洋产品对下午星的依赖更重这不是随意分配而是观测时段决定的。同时两颗星过境时间相差约 3 小时这个时间差本身就是信息。同一地区在一天内被两个不同时刻观测可以用来捕捉云、地表温度、气溶胶的日变化趋势。合成产品里常见的“上午星 下午星联合”文件名前缀为 MCD 系列就是把这个时间差利用起来而不是简单挑一张更好的。提示处理时间序列时务必确认产品族前缀。MOD 前缀来自上午星MYD 来自下午星MCD 是两者合成。混用会在时间序列里引入系统性的时刻偏差尤其在研究地表温度日变化时表现明显。3.3 正弦投影和 36×18 瓦片等积优先于好看大多数标准 MODIS 格网产品使用正弦投影把全球切成 36 列 × 18 行、每块 10 度 × 10 度的瓦片行号从左上角 (0,0) 编到右下角 (35,17)。赤道处一块瓦片大约 1110 公里见方。为什么偏偏选正弦投影因为它的核心性质是等积球面上任意一块区域投影到平面上面积比例保持不变。对全球尺度的碳收支、能量平衡、植被生产力统计来说面积不能变形是刚性需求——如果投影会让高纬面积虚增那么全球总和就永远算不准。代价是高纬度形状和角度严重变形地图看起来被拉扯得很奇怪但做定量统计的人不在乎这个。这也解释了为什么瓦片编号值得记住。行列号本质上是一个空间索引拿到 h25v04 就知道它大致落在什么经纬度范围找相邻瓦片只需加减行列号。拼接多幅影像时如果瓦片不相邻接缝处会出现明显断裂更隐蔽的问题是跨瓦片边界的像元被切开统计时被算了两次——这在中低纬度不明显在高纬度重叠区会累积成可观误差。4. 从 0 级到 4 级产品分级和命名规则其实是一份可解析的契约4.1 L1A 到 L1B 之间那一步决定了数据能不能定量用地面站直接收到的原始码流是 0 级数据包含全部信息但完全没有结构。把它按仪器扫描时序重建、做时间配准、加上辅助数据注解得到的就是 1A 级数据——注意这一步还没有做辐射定标里面存的仍是原始计数值用途主要是追溯和重新定标。1A 到 1B 这一步做的是辐射定标用星上参考源和发射前实验室标定系数把计数值换算成有物理意义的反射率和辐亮度。这一步做得好不好直接决定了后面所有反演的天花板。因此定标组是一个独立的学科组长期监测仪器状态衰减并在新版本里更新定标系数——这就是版本号collection存在的原因。同一景数据不同版本的处理结果可能有系统性差异做长时序分析必须统一版本。1B 之后才进入应用处理。2 级产品是在 1B 基础上反演出的、与原观测具有相同空间分辨率和覆盖范围的结果比如大气气溶胶、云、地表反射率3 级产品则把不同时间的 2 级结果投影到统一的时间-空间格网上变成可以直接做统计和时间序列的规整数据4 级是在 3 级基础上再跑模型得到的衍生量比如净初级生产力。级别代表产品几何形态时间粒度典型用途L1AMOD01扫描条带单轨重新定标、追溯L1BMOD02 MOD03扫描条带单轨自定义反演、几何纠正L2MOD04、MOD09、MOD11扫描条带日局地精细分析L3MOD13、MOD10、MOD11A2瓦片或 CMG 格网日/旬/月/年区域统计、时间序列L4MOD17瓦片旬/年生产力建模一个容易踩的坑是2 级产品是条带形态不同日期的条带覆盖范围不完全一致直接做多天叠加会出现错位要做时序必须用 3 级格网产品或者自己完成重投影。这个区别在文件名里看不出来只能靠产品号判断。4.2 文件名不是随机字符串每一段都有固定语义拿一个真实结构的文件名拆开看MOD01.A2002032.1015.003.2002034184356.hdf。字段值含义产品短名MOD01产品标识MOD 为上午星MYD 为下午星MCD 为合成年份2002观测年份年积日032一年中的第几天032 即 2 月 1 日时刻1015UTC 时间 10:15版本003数据集版本号影响定标系数生产时间2002034184356年 年积日 时分秒共 13 位扩展名hdf文件格式把这个规则写成解析函数比手动改文件名可靠得多import re from datetime import datetime, timedelta PAT re.compile( r^(?Pprod[A-Z0-9]{5,7})\.A(?Pyear\d{4})(?Pdoy\d{3})\. r(?Phhmm\d{4})\.(?Pver\d{3})\.(?Pprodtime\d{13})\.(?Pext\w)$ ) def parse(name): m PAT.match(name) if not m: raise ValueError(f不符合命名契约: {name}) d m.groupdict() # 年积日从 1 开始减 1 才是 timedelta 的天数 t datetime(int(d[year]), 1, 1) timedelta( daysint(d[doy]) - 1, hoursint(d[hhmm][:2]), minutesint(d[hhmm][2:]) ) return d[prod], t, d[ver], d[ext] print(parse(MOD01.A2002032.1015.003.2002034184356.hdf)) # (MOD01, datetime(2002, 2, 1, 10, 15), 003, hdf)这段代码的价值在批量处理时体现几千个文件按时间排序、按版本过滤、检测重复下载都可以靠文件名完成不需要打开文件读元数据速度快一个数量级。doy转日期时那一句减 1 是最容易写错的地方忘了减就会整体偏移一天而这种偏移在结果里完全看不出来。注意文件名里的时间是 UTC。换算到东八区要加 8 小时跨日时年积日也要跟着变。比如要取某地 1 月 16 日一整天的数据实际检索范围要从 1 月 15 日 16:00 UTC 开始——少算这一步会稳定地丢掉每天前 8 小时的数据而且丢得毫无提示。4.3 四十多种产品为什么按大气、陆地、海洋三线切分产品编号从 MOD04 排到 MOD44中间还有若干未定义的编号空位看起来杂乱其实是按“学科 反演链”两条线组织的。大气线从气溶胶、可降水量、云、大气廓线一直到栅格化的日/旬/月合成陆地线从地表反射率出发派生出雪覆盖、地表温度、土地覆盖、植被指数、叶面积指数、光合有效辐射、蒸腾、生产力、热异常、BRDF 参数、植被覆盖转换海洋线围绕水色展开叶绿素、色素浓度、悬浮物、海面温度、海冰、初级生产力。这个结构的逻辑是一个上游产品的输出是若干下游产品的输入。地表反射率是植被指数的输入植被指数和叶面积指数是生产力的输入所以编号大致沿着反演链推进。理解这条链就能在需要某个变量时判断该拿哪一级产品而不是从一长串编号里试。5. 从定位到重投影处理链上最容易出问题的几个地方5.1 1B 数据本身没有经纬度定位信息在另一个文件里这是很多人第一次处理 MODIS 时最意外的一点1B 产品的每个像元并没有附带经纬度坐标因为存下来会占用巨大空间而且定位信息对所有波段是共用的。真正的定位数据在单独的地理定位文件里与 1B 同轨同时刻包含每个像元对应的经纬度、太阳和观测天顶角方位角。缺了它1B 就只是一堆数字无法落到地图上。几何纠正的常规路径是用定位文件为每个像元建立地面坐标再按目标投影重采样。商业软件里直接点“地理校正”往往效果不好因为它默认按规则格网处理而 1B 是条带形态、边缘还有蝴蝶结重叠容易在边缘拉出条纹。专门的纠正工具会同时处理扫描几何和重叠问题速度快、边缘干净这也是为什么老手宁可多装一个工具也不在通用软件里硬做。提示订购 1B 数据时同一天同一轨的地理定位文件必须一起下。事后补下往往会发现该轨已归档到别的目录检索条件要对齐时间段和轨道号比较费时。5.2 重投影工具的顺序是先拼接再投影这个顺序不能反多幅影像做区域制图时标准流程是把同一时间段的多幅瓦片一起导入工具先按原投影完成拼接再整体做投影转换。这个顺序有实际意义——如果先各自投影再拼接接缝两侧会经历两次重采样边界处出现模糊带先拼接后投影整块区域只重采样一次信息损失最小。重采样方式一般选双线性对连续型变量反射率、温度、植被指数比较合适最近邻只适合分类产品因为它不产生新值能保住类别编码不被插值破坏。用错重采样方式处理土地覆盖分类数据会插出一堆不存在的类别编号这是分类产品处理里的经典事故。投影参数这块中低纬度区域制图常用 Albers 等积圆锥投影双标准纬线分别设在 25 度和 47 度中央经线 105 度原点纬度 0 度。椭球长短半轴留空时程序会按 WGS84 默认值补上长半轴 6378137 米、短半轴约 6356752.31 米。这里有个细节如果只填了标准纬线和中央经线而没管椭球默认值可能因工具版本不同而不同导致输出有几十米的系统性偏移。稳妥做法是把椭球参数显式写进去别依赖默认。5.3 五条实际遇到的问题现象、原因、解决第一下载的数据时间总是差 8 小时。现象是按日期检索出来的结果覆盖不全总觉得缺了前半天。原因是检索界面用的是 UTC而心里的预期是本地时间。解决办法是把目标日期的本地零点换算成前一天 16:00 UTC 作为起点终点是当天 16:00 UTC跨月跨年时年积日也要跟着改。第二拿到 1B 数据打不开或者读出来全是空的。现象是软件提示格式不支持或者读出的数据集列表为空。原因是 HDF4 和 HDF5 是两种完全不兼容的格式老版本工具只认其中一种而不同产品可能用不同版本。解决办法是先确认文件实际格式再选对应的库用 Python 时HDF4 走 pyhdfHDF5 走 h5py别拿一个库硬套所有文件。第三拼出来的影像边缘有重复条纹。现象是相邻扫描带交界处出现明暗交替的条带或重影。原因是扫描边缘的蝴蝶结重叠同一地面被采样两次直接按行列拼接就会叠加。解决办法是裁剪掉扫描边缘一定比例的像元或者直接用格网化的 3 级产品绕开这个问题。第四重投影后波段名变长、文件名多出一串后缀。现象是批量脚本按固定文件名找不到输出。原因是重投影工具会在输出文件名后自动追加波段信息和投影标识。解决办法是脚本里用通配符匹配前缀而不是写死全名或者在工具里显式指定输出名并接受它追加的部分。第五投影结果整体偏移几十米到几百米。现象是与底图套合时对不上但形状是对的。原因是投影参数里椭球或假东假北没设对或者用了默认值而默认值并非预期。解决办法是把长半轴、短半轴、标准纬线、中央经线、原点纬度全部显式写出输出后拿一个已知控制点核对坐标。6. 把复杂度推给用户是一种刻意为之的取舍回过头看MODIS 这套设计处处透着同一个取向原始数据尽量保真规整和解释的成本交给下游。1B 不存经纬度因为定位信息可以共用条带数据不做重采样因为重采样不可逆反射波段和发射波段用不同的物理量因为强行统一会损失精度投影选正弦因为面积不变形比地图好看重要得多。这些选择单看都不友好放在一起却自洽它服务的是一群要做全球尺度定量分析的人而不是要快速出图的人。代价也很清楚。使用者必须自己承担几何纠正、格式兼容、时间换算、版本统一这些工作任何一步理解偏差都不会报错只会让结果悄悄错掉。这也是为什么这份资料的价值不在“告诉你点哪个按钮”而在于把波段分组、覆盖几何、分级体系、命名规则这几件事串成一条能自洽推演的线——知道为什么 250 米波段只有两个就知道不该拿它去做大气廓线知道单星两天才能铺满赤道就不会因为某天某地没数据而怀疑下载出错知道文件名是可解析的契约批量处理就不用打开每个文件读元数据。验证思路其实很朴素拿一景数据用地理定位文件算出的经纬度范围去和检索时框选的范围比对能对上说明定位链没断用文件名解析出的时间和文件内部记录的时间比对能对上说明命名理解没错把重投影结果和一个已知控制点套合偏差在百米内说明投影参数没填错。三个比对做完整条链的可信度就有了底。我自己的习惯是任何一批 MODIS 数据进流程之前先抽一景做这三项核对宁可慢半天也不要在跑完几千景之后才发现时间整体偏了一天。这种错误回头改的代价远不是重跑一遍能概括的。希望这些经验能帮到你少走几段弯路。这份资料把发射背景、技术指标、波段表、产品分级、命名规则、下载路径、格式说明和重投影参数整理成了一份完整的对照文档适合放在手边当查询手册用——遇到拿不准的产品编号或投影参数翻一下比重新检索快得多。本文还有配套的精品资源点击获取