MODIS 2020年中国1km地表温度数据集处理全流程:从HDF到城市热岛分析

发布时间:2026/10/7 16:59:49
MODIS 2020年中国1km地表温度数据集处理全流程:从HDF到城市热岛分析 简介该数据集提供2020年中国区域1km空间分辨率的地表温度LST栅格成果面向遥感、地理信息、气候与生态环境等方向的研究人员和学生可用于地表热环境分析、城市热岛研究、干旱监测及模型输入等场景。数据源自NASA MODIS MOD11A2产品经提取子数据集、拼接、投影转换、单位换算与裁剪后按8天合成再年均得到年尺度LST采用Albers等积投影与WGS84椭球中央经线105°、标准纬线25°与47°。压缩包共11个文件约66.16MB包含2个tif栅格开氏与摄氏两套温度、2个tfw坐标文件、4个xml元数据、2个txt说明及1个ovr金字塔文件便于直接加载与快速渲染。已有3545人学习下载适合需要现成中国区年LST底图、希望省去预处理环节并快速开展空间分析的用户。1. MODIS 2020年中国1km地表温度数据集从下载到出图的完整路径2020年夏季长江中下游持续高温不少做城市热岛、农业干旱监测的同行都在找一套能覆盖全国、时间连续、空间分辨率够用的地表温度数据。MODIS 2020年中国1km地表温度LST空间分布数据集正是冲着这个需求来的它把MOD11A1/MYD11A1这类每日1km产品经过拼接、裁剪、单位换算、无效值剔除后整理成一份可直接用于全国尺度分析的栅格数据。适合谁做遥感入门的学生、做城市热环境的研究者、做旱情监测的业务人员以及需要一份基准LST底图来对比其他年份的工程师。它解决的核心问题不是“有没有数据”而是“怎么把原始HDF变成能算均值、能出图、能进GIS的干净栅格”。2. 先搞懂MODIS LST的物理含义与2020年数据选型2.1 LST不是气温MOD11A1和MYD11A1到底选哪个很多新手拿到MODIS LST第一反应是“这不就是气温吗”翻车往往从这里开始。LST是地表皮肤温度是卫星传感器在热红外波段反演出来的辐射温度代表的是地表土壤、植被冠层、建筑屋顶向外辐射的能量所对应的温度。它和气象站百叶箱里测的1.5米气温不是一回事晴天正午裸土LST可能比气温高20℃以上夜间植被覆盖好的区域LST又可能低于气温。做城市热岛你要的是LST做气象分析你要的是气温。两者混用结论直接崩。MODIS提供LST的主要产品是MOD11Terra星和MYD11Aqua星空间分辨率1km时间分辨率每日。2020年数据选型时常见做法是只做白天、只做全国年均MOD11A1够用过境时间约地方时10:30适合看白天热特征。要捕捉夜间热岛或昼夜温差必须同时用MOD11A1和MYD11A1Aqua过境约13:30和01:30夜间信息更完整。如果做月合成直接找MOD11A28天合成或MOD11C3月合成更省事但空间分辨率还是1km时间分辨率换空间连续性。我一般会先明确分析目标是“白天热”还是“昼夜热”再决定下哪一套。2020年这个年份本身没有特殊性但它是很多研究对比2021、2022的基准年所以数据完整性比单年精度更重要。2.2 1km分辨率在中国区域的实际覆盖与投影问题MODIS 1km产品原始投影是正弦投影Sinusoidal全球分块中国区域大概落在h26v04、h26v05、h27v04、h27v05、h28v04、h28v05这几个瓦片里。直接拼接后中国地图会呈现明显的正弦投影变形东西向拉伸南北向压缩。如果你要算面积、做行政区统计必须重投影到Albers等面积投影或WGS84经纬度。这里有个血泪经验很多人拼接完直接裁剪中国边界发现边界和底图对不上以为是数据错了其实是投影没转。正确顺序是原始HDF → 拼接瓦片 → 重投影 → 按中国边界裁剪 → 单位换算。顺序错了后面全白干。另外1km分辨率在中国西部和东部表现不一样。东部城市密集区1km像元里可能混合了建筑、道路、绿地LST是混合温度西部荒漠区1km像元相对均一。做城市热岛时1km分辨率对中小城市偏粗对大城市群够用。如果你要做街区尺度得换Landsat 8/9的热红外100m重采样到30m但那是另一套流程。2.3 2020年数据版本与质量波段怎么读MODIS LST产品每个HDF文件里包含多个数据集LST_Day_1km、LST_Night_1km、QC_Day、QC_Night、View_Angle等。2020年常见版本是061Collection 6.1相比055在反演算法和QC波段上有调整。你不需要记住所有版本差异但必须会读QC波段。QC_Day是一个8位整数不同位代表不同质量信息。常见做法是只保留QC0最高质量或QC≤1好质量的像元其余设为无效。如果你不做QC过滤云污染、气溶胶、视角过大的像元会混进来全国均值直接偏高或偏低。单位换算也是必踩的坑LST_Day_1km的存储值是整数比例因子0.02单位开尔文。真实LST 存储值 × 0.02。如果你忘了乘0.02得到的是几万度的“温度”出图全黑。转摄氏度再减273.15。这一步在代码里必须写死不能靠记忆。3. 用Python把2020年MODIS HDF处理成中国1km LST栅格3.1 环境准备与依赖库安装处理MODIS数据Python生态里最稳的组合是GDAL rasterio numpy geopandas。GDAL负责读HDF和重投影rasterio做栅格读写geopandas处理中国边界矢量。安装时建议用conda避免GDAL编译问题。conda create -n modis_lst python3.9 conda activate modis_lst conda install -c conda-forge gdal rasterio geopandas numpy逻辑说明GDAL是底层栅格库rasterio是它的Python封装geopandas依赖GDAL和shapely。用conda-forge频道能保证版本兼容。参数上python3.9是稳妥选择3.10以上部分GDAL版本有兼容问题。如果你已经装了ArcGIS或QGIS系统里可能有GDAL但Python绑定不一定全建议独立环境。3.2 批量读取HDF并提取LST子数据集MODIS HDF是分层结构一个文件里多个子数据集。用rasterio打开时需要指定子数据集编号或名称。下面这段代码批量读取2020年某天的MOD11A1瓦片提取LST_Day_1km和QC_Day。import rasterio import numpy as np import glob import os def read_modis_lst(hdf_path): 读取单个MODIS HDF返回LST和QC数组 with rasterio.open(hdf_path) as src: # 列出所有子数据集 subdatasets src.subdatasets lst_ds None qc_ds None for ds in subdatasets: if LST_Day_1km in ds: lst_ds ds if QC_Day in ds: qc_ds ds # 读取LST with rasterio.open(lst_ds) as lst_src: lst lst_src.read(1).astype(np.float32) profile lst_src.profile # 读取QC with rasterio.open(qc_ds) as qc_src: qc qc_src.read(1).astype(np.uint8) return lst, qc, profile # 示例处理一个瓦片 hdf_file MOD11A1.A2020200.h27v05.061.2020202034534.hdf lst, qc, profile read_modis_lst(hdf_file) print(LST shape:, lst.shape, QC shape:, qc.shape)逻辑说明src.subdatasets返回HDF内所有子数据集的路径字符串通过关键字匹配找到LST和QC。rasterio.open子数据集路径后read(1)读第一波段。参数上astype(np.float32)是为了后续乘0.02不丢精度QC用uint8因为原始就是8位。profile保存了地理变换和投影信息后面写文件要用。注意不同版本HDF子数据集命名可能略有差异061版本通常是“LST_Day_1km”和“QC_Day”如果匹配不到打印subdatasets看一眼。3.3 拼接、重投影与按中国边界裁剪单个瓦片处理完需要把中国区域涉及的瓦片拼起来再重投影到Albers最后用中国边界裁剪。下面用rasterio的merge和warp功能。from rasterio.merge import merge from rasterio.warp import calculate_default_transform, reproject, Resampling import geopandas as gpd from rasterio.mask import mask def merge_tiles(hdf_list): 拼接多个瓦片的LST src_files [] for hdf in hdf_list: lst, qc, profile read_modis_lst(hdf) # 这里简化实际应把lst写成临时tif再merge # 为演示假设已有临时tif列表 # 实际流程先各自转tif再merge pass def reproject_to_albers(src_path, dst_path): 重投影到Albers等面积投影 dst_crs projaea lat_125 lat_247 lat_00 lon_0105 x_00 y_00 datumWGS84 unitsm no_defs with rasterio.open(src_path) as src: transform, width, height calculate_default_transform( src.crs, dst_crs, src.width, src.height, *src.bounds) kwargs src.meta.copy() kwargs.update({ crs: dst_crs, transform: transform, width: width, height: height }) with rasterio.open(dst_path, w, **kwargs) as dst: for i in range(1, src.count 1): reproject( sourcerasterio.band(src, i), destinationrasterio.band(dst, i), src_transformsrc.transform, src_crssrc.crs, dst_transformtransform, dst_crsdst_crs, resamplingResampling.bilinear ) def clip_to_china(src_path, shp_path, dst_path): 按中国边界裁剪 gdf gpd.read_file(shp_path) with rasterio.open(src_path) as src: out_image, out_transform mask(src, gdf.geometry, cropTrue) out_meta src.meta.copy() out_meta.update({ height: out_image.shape[1], width: out_image.shape[2], transform: out_transform }) with rasterio.open(dst_path, w, **out_meta) as dst: dst.write(out_image)逻辑说明重投影用Albers等面积投影参数lat_125、lat_247是中国常用双标准纬线lon_0105是中央经线。重采样用双线性LST是连续量双线性比最近邻更平滑。裁剪用geopandas读中国边界shpmask函数按几何范围裁。参数上cropTrue表示裁剪到几何边界不是外接矩形。注意中国边界shp要提前准备好坐标系必须和重投影后的栅格一致否则mask会报错或裁出空白。3.4 单位换算、QC过滤与无效值处理拼接裁剪完最后一步是单位换算和QC过滤。这一步不做数据不能用。def clean_lst(lst, qc): 单位换算 QC过滤 无效值处理 # 单位换算存储值 × 0.02 开尔文 lst_k lst * 0.02 # QC过滤只保留QC0最高质量 lst_k[qc ! 0] np.nan # 无效值原始填充值0或-1 lst_k[lst_k 200] np.nan lst_k[lst_k 350] np.nan # 转摄氏度 lst_c lst_k - 273.15 return lst_c # 应用 lst_clean clean_lst(lst, qc) print(有效像元比例:, np.sum(~np.isnan(lst_clean)) / lst_clean.size)逻辑说明先乘0.02转开尔文再按QC过滤。QC0是最高质量QC1是好质量但可能有少量云。如果你要最大覆盖可以放宽到QC≤1。无效值处理用物理范围卡LST开尔文低于200K或高于350K都不合理。最后转摄氏度。参数上200和350是经验阈值中国区域LST一般在220K到330K之间。注意如果你做的是夜间LSTQC_Night的过滤逻辑一样但阈值可以略调夜间极端低温可能到210K。4. 避坑与排查MODIS LST处理中最容易翻车的5个地方4.1 现象拼接后中国地图变形严重边界对不上原因原始MODIS是正弦投影直接拼接不重投影中国区域会被拉伸。解决拼接后立即重投影到Albers或WGS84再裁剪。顺序不能反。4.2 现象LST值几万度出图全黑或全白原因忘了乘比例因子0.02或者把填充值当有效值。解决检查代码里有没有lst * 0.02有没有把0和-1设为NaN。出图前先打印np.nanmin和np.nanmax正常范围是-50到60摄氏度。4.3 现象全国均值明显偏高夏季超过50℃原因没做QC过滤云污染像元混入。云在热红外波段表现为低温但云边缘混合像元可能异常。解决用QC_Day过滤只保留QC0或QC≤1。如果均值还是高检查是不是把夜间LST当白天用了。4.4 现象裁剪后边界外有值或者边界内大片空白原因中国边界shp和栅格坐标系不一致或者shp本身有拓扑错误。解决用gdf.crs检查shp坐标系用src.crs检查栅格坐标系不一致先统一。shp拓扑错误用gdf.buffer(0)修复。4.5 现象处理速度极慢一天数据跑几小时原因逐像元循环或者没做分块处理。解决用numpy向量化操作避免for循环。大区域处理用rasterio的窗口读取分块处理。如果内存不够用rioxarray的chunk功能。5. 进阶用2020年LST做全国城市热岛强度快速验证5.1 城市热岛强度的定义与计算城市热岛强度SUHI常用定义是城市建成区LST均值减去郊区参考LST均值。2020年数据做这个关键是城市边界和郊区缓冲区的划定。我一般用中国城市行政边界shp城市核心区取建成区郊区取城市边界外10-20km缓冲环。import geopandas as gpd import rasterio import numpy as np from rasterio.mask import mask def calc_suhi(lst_path, city_shp, buffer_km15): 计算单个城市SUHI city gpd.read_file(city_shp) with rasterio.open(lst_path) as src: # 城市核心区 city_mask, _ mask(src, city.geometry, cropTrue) city_lst city_mask[0] city_mean np.nanmean(city_lst) # 郊区缓冲区 city_buffer city.geometry.buffer(buffer_km * 1000) outer city_buffer.difference(city.geometry) outer_mask, _ mask(src, outer, cropTrue) outer_lst outer_mask[0] outer_mean np.nanmean(outer_lst) return city_mean - outer_mean # 示例 suhi calc_suhi(china_lst_2020.tif, beijing.shp, buffer_km15) print(北京2020年SUHI:, suhi, ℃)逻辑说明mask函数按几何裁剪city_mean是城市核心区LST均值outer_mean是郊区缓冲环均值差值就是SUHI。参数上buffer_km15是经验值平原城市可以10km山区城市可以20km。注意缓冲区要排除城市本身用difference。5.2 用2020年数据验证热岛强度的三个检查点第一检查城市核心区LST是否高于郊区。如果反了可能是城市边界画到了山区或水体。第二检查SUHI是否在合理范围。中国大城市夏季白天SUHI一般2-6℃超过8℃要怀疑QC过滤不严。第三检查夜间SUHI。夜间热岛通常比白天弱但更稳定。如果你只有白天数据结论要谨慎。我自己的习惯是先算全国省会城市SUHI排序看异常值。如果拉萨、西宁这种高原城市SUHI异常高大概率是郊区缓冲区包含了荒漠或裸土LST本身高不是热岛。这时候要手动调整缓冲区或者用植被指数NDVI辅助筛选郊区参考像元。5.3 一个具体技巧用QC和NDVI联合筛选参考像元单纯用缓冲区算郊区LST容易把裸土、沙地算进去。更稳的做法是在缓冲区内只保留NDVI0.3且QC0的像元作为郊区参考。NDVI可以从MOD13A21km月合成获取和LST同分辨率配准后联合筛选。def calc_suhi_ndvi(lst_path, ndvi_path, city_shp, buffer_km15, ndvi_thresh0.3): 用NDVI筛选郊区参考像元 city gpd.read_file(city_shp) with rasterio.open(lst_path) as lst_src, rasterio.open(ndvi_path) as ndvi_src: city_mask, _ mask(lst_src, city.geometry, cropTrue) city_lst city_mask[0] city_mean np.nanmean(city_lst) city_buffer city.geometry.buffer(buffer_km * 1000) outer city_buffer.difference(city.geometry) outer_lst_mask, _ mask(lst_src, outer, cropTrue) outer_ndvi_mask, _ mask(ndvi_src, outer, cropTrue) outer_lst outer_lst_mask[0] outer_ndvi outer_ndvi_mask[0] # 只保留NDVI0.3的像元 valid outer_ndvi ndvi_thresh outer_lst_valid outer_lst[valid] outer_mean np.nanmean(outer_lst_valid) return city_mean - outer_mean逻辑说明NDVI0.3表示有植被覆盖排除裸土和建筑。参数上ndvi_thresh0.3是经验值北方干旱区可以降到0.2南方可以升到0.4。注意NDVI和LST要提前配准到同一网格否则mask结果对不上。这个技巧我用了三年比单纯缓冲区稳得多。代价是多一步NDVI数据处理但SUHI结果更可信。如果你只是快速验证缓冲区法够用如果要发论文或做业务报告建议上NDVI联合筛选。最后说个习惯每次处理完2020年数据我都会随机抽10个像元手动对照原始HDF的QC和LST值确认换算和过滤没错。这个后悔药比出图后再返工便宜得多。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询