MODIS 2022中国1km地表温度数据集:从下载到城市热岛分析全流程避坑指南
发布时间:2026/10/3 4:59:52 锦皓数字建站

简介本资源为2022年中国区域1km地表温度LST空间分布数据集面向遥感、地理信息、气候与生态等方向的研究人员和学生用于开展地表热环境、城市热岛及区域气候分析。数据源自NASA MOD11A2产品经提取子数据集、拼接、投影转换、单位换算与裁剪后按年对8天合成栅格取平均得到年尺度1km LST结果投影为Albers等面积投影椭球WGS84中央经线105°标准纬线25°与47°。压缩包共7个文件约64.55MB包含开氏与摄氏两套温度tif栅格、说明txt、xml元数据及ovr、tfw等辅助文件便于直接读取与制图。已有743人学习下载适合需要现成中国区年LST数据、快速开展空间分析与论文写作的用户可省去繁琐预处理直接用于热环境评估与可视化。1. 拿到 MODIS 2022 年中国 1km 地表温度数据集先搞清楚它到底能干什么很多人第一次接触 MODIS 2022 年中国 1km 地表温度LST空间分布数据集.zip第一反应是「下载下来直接扔进模型不就行了」。我当年也这么想结果打开一看一整年的数据、上千个瓦片、还有莫名其妙的填充值直接懵了。这个数据集的核心价值在于它把 NASA 的 MOD11A2 产品8 天合成、1km 分辨率裁剪到了中国范围并做了年度合成让你不用自己处理 HDF 投影和拼接。适合做城市热岛分析、干旱监测、农业旱情评估、地表能量平衡研究的人。但前提是——你得知道它的空间参考、时间合成方式和无效值标记否则后面全是坑。这一章先把这个数据集讲透后面再动手。2. 拆开 zip 之前MODIS LST 的投影、合成与无效值到底怎么理解2.1 为什么 1km 分辨率下中国区要特别关注投影MODIS 原始产品是正弦投影Sinusoidal每个瓦片覆盖 1200×1200 像素。中国跨了大约 10 个瓦片h23v04 到 h28v06 附近直接拼接会出现明显的边缘错位。这个 zip 里的数据通常已经转成了等经纬度投影Geographic Lat/Lon, WGS84像元大小 0.01 度左右对应约 1km。但你要注意有些版本只做了重投影没做重采样导致边缘像元被拉伸。我一般会先用gdalinfo看一眼元数据确认Pixel Size是不是接近(0.01, 0.01)以及SRS是不是EPSG:4326。如果不是后面所有面积统计都会偏。2.2 8 天合成到年度最大值合成还是平均值合成MODIS MOD11A2 本身是 8 天合成用的是「最大值合成法」因为云污染通常降低 LST取最大值能抑制云影响。但这个 zip 叫「2022 年中国 1km 地表温度空间分布数据集」它很可能是把 46 个 8 天合成做成了年均值或年最大值。常见做法是先剔除无效值-9999 或 0再对每个像元求平均。如果你拿到的是年最大值那夏季高温区会偏热冬季冷区会偏冷做趋势分析时不能用。我一般会检查数据直方图年均值应该在 -20°C 到 45°C 之间如果出现大量 0 或 -9999说明没做无效值掩膜。2.3 无效值标记-9999 和 0 的区别MODIS LST 的填充值是 -9999但有些中国区裁剪版本会把海洋或境外区域设为 0。0°C 在 LST 里是合法值冬季北方常见所以不能把 0 当无效值直接删。正确做法是先看数据说明如果没有说明就用numpy统计 0 的占比。如果 0 集中在东南沿海和境外边界那大概率是填充。我一般会同时掩膜 -9999 和 0但保留 0 附近的真实低温像元——这需要结合 NDVI 或土地覆盖做交叉验证。2.4 用 Python 快速检查数据质量的最小命令import rasterio import numpy as np # 打开 zip 解压后的第一个 tif 文件 with rasterio.open(LST_2022_China_1km.tif) as src: print(投影:, src.crs) print(像元大小:, src.res) print(范围:, src.bounds) data src.read(1) # 统计无效值 valid data[(data ! -9999) (data ! 0)] print(有效像元占比:, valid.size / data.size) print(LST 范围: {:.2f} ~ {:.2f} °C.format(valid.min(), valid.max())) print(均值: {:.2f} °C.format(valid.mean()))这段代码先看投影和像元大小确认是 WGS84 且约 0.01 度。然后读第一个波段用(data ! -9999) (data ! 0)做初步掩膜但注意 0 可能误伤。最后输出有效像元占比和温度范围。如果有效占比低于 60%说明云污染或填充太多这个年份的数据可能不可用。参数上src.read(1)读的是第一波段如果 zip 里是多波段比如 12 个月你需要循环读。3. 从 zip 到可用栅格裁剪、重采样与无效值掩膜的完整操作3.1 解压后先别急着合并检查瓦片命名和坐标系zip 解压后通常是一堆 tif命名可能是LST_2022_01.tif到LST_2022_12.tif也可能是按瓦片编号。先ls看一下然后用gdalinfo批量检查。如果发现有的瓦片是正弦投影有的是地理投影那就得先统一。我一般用gdalwarp批量转for f in *.tif; do gdalwarp -t_srs EPSG:4326 -tr 0.01 0.01 -r bilinear -of GTiff $f wgs84_$f done-t_srs EPSG:4326指定目标投影-tr 0.01 0.01设像元大小-r bilinear用双线性插值LST 连续双线性比最近邻更合适。注意如果原数据已经是地理投影这步会重采样可能引入误差所以先确认再跑。3.2 用 GDAL 做中国区掩膜避免境外像元干扰很多 zip 里的数据已经裁过中国边界但边界外可能有 0 或 -9999。如果你要做全国统计必须用中国行政边界 shp 做精确掩膜。常见做法是gdalwarp -cutline china.shp -crop_to_cutline。但注意-cutline会按 shp 范围裁剪如果 shp 有多个多边形可能会生成多个文件。我一般先用ogr2ogr把 shp 合并成一个再裁。ogr2ogr -dissolve FIELD_NAME china_merged.shp china.shp gdalwarp -cutline china_merged.shp -crop_to_cutline -dstnodata -9999 wgs84_LST_2022.tif china_LST_2022.tif-dissolve按字段合并-dstnodata -9999把边界外设为 -9999。这样后续统计就不会把境外像元算进去。3.3 无效值掩膜用 numpy 做条件替换裁剪后用 Python 做无效值掩膜。注意不要直接data[data 0] np.nan因为 0°C 是真实值。我一般会结合土地覆盖数据如 MOD12Q1判断如果像元是水体或海洋且 LST 为 0才设为 NaN。import rasterio import numpy as np with rasterio.open(china_LST_2022.tif) as src: lst src.read(1).astype(np.float32) profile src.profile # 掩膜 -9999 lst[lst -9999] np.nan # 掩膜 0 但仅限水体区域假设有水体掩膜 water_mask.tif with rasterio.open(water_mask.tif) as wsrc: water wsrc.read(1) lst[(water 1) (lst 0)] np.nan # 保存 profile.update(dtyperasterio.float32, nodatanp.nan) with rasterio.open(china_LST_2022_masked.tif, w, **profile) as dst: dst.write(lst, 1)这段代码先转 float32 以便存 NaN然后掩膜 -9999再用水体掩膜处理 0。profile.update里nodatanp.nan让后续 GIS 软件能识别。注意如果 zip 里没有水体掩膜你可以用 MOD44W 或中国湖泊 shp 自己生成。3.4 重采样到统一网格为什么 1km 不是真的 1kmMODIS 1km 是星下点分辨率中国范围跨纬度大实际像元面积从 0.8km² 到 1.2km² 不等。如果你要做面积统计必须用等面积投影如 Albers。常见做法是先转 Albers再重采样到 1km 网格。gdalwarp -t_srs projaea lat_125 lat_247 lat_00 lon_0105 datumWGS84 -tr 1000 1000 -r bilinear china_LST_2022_masked.tif albers_LST_2022.tifprojaea是 Albers 等面积投影lat_1和lat_2是中国标准纬线。-tr 1000 1000单位是米。这样每个像元面积都是 1km²统计才准确。4. 避坑MODIS LST 中国区数据集最常见的 5 个翻车现场4.1 现象统计出来全国平均 LST 只有 5°C明显偏低原因把 -9999 和 0 都当无效值删了但 0°C 在冬季北方是真实值删掉后低温区被过度剔除导致均值偏高不对这里偏低是因为把 -9999 当有效值算进去了。-9999 是填充值如果没掩膜直接求平均会拉低整体。解决先data[data -9999] np.nan再统计。4.2 现象裁剪后中国边界外还有一圈 0 值原因gdalwarp -cutline默认不设置-dstnodata边界外像元被设为 0。解决加-dstnodata -9999或者裁剪后用rasterio按 shp 掩膜。4.3 现象重投影后 LST 范围变成 -200°C 到 200°C原因用了最近邻插值-r near导致填充值 -9999 被插值到有效区域。解决用双线性或三次卷积并且先掩膜无效值再重投影。如果已经错了重新用-r bilinear跑一遍。4.4 现象年度合成后夏季高温区消失原因用了平均值合成但 8 天合成里云污染导致某些月份全是 -9999平均后有效值被稀释。解决改用最大值合成或者先做云掩膜用 MOD11A2 的 QC 波段再平均。4.5 现象用 QGIS 打开显示全黑或全白原因数据是 float32 且含 NaNQGIS 默认拉伸把 NaN 当极值。解决在 QGIS 里设置Min/Max为实际有效范围如 -20 到 45或者先转成整型并设 nodata 为 -9999。5. 进阶用 LST 做城市热岛强度计算与年际对比的实操技巧5.1 城市热岛强度用缓冲区法还是城乡二分法我一般用缓冲区法以城市中心为原点做 5km、10km、20km 缓冲区分别统计 LST 均值然后算SUHI LST_urban - LST_rural。但注意MODIS 1km 下城市边界模糊缓冲区半径小于 5km 会混入郊区。常见做法是用不透水面数据如 GAIA提取城市像元再算城乡温差。import geopandas as gpd import rasterio import numpy as np from rasterio.mask import mask # 读城市边界 city gpd.read_file(beijing.shp) with rasterio.open(albers_LST_2022.tif) as src: # 城市内 LST out_image, _ mask(src, city.geometry, cropTrue) urban_lst out_image[out_image ! -9999].mean() # 郊区城市外 20km 缓冲区 buffer city.geometry.buffer(20000) out_image_buf, _ mask(src, buffer, cropTrue) rural_lst out_image_buf[out_image_buf ! -9999].mean() print(SUHI: {:.2f} °C.format(urban_lst - rural_lst))mask函数按几何裁剪buffer(20000)是 20km 缓冲区。注意缓冲区可能包含其他城市所以最好用土地覆盖数据剔除。5.2 年际对比2022 年比 2021 年热了多少如果你有 2021 和 2022 两年数据先确保投影和网格一致。然后做差值with rasterio.open(albers_LST_2021.tif) as src1, rasterio.open(albers_LST_2022.tif) as src2: lst1 src1.read(1) lst2 src2.read(1) diff lst2 - lst1 diff[(lst1 -9999) | (lst2 -9999)] np.nan print(平均增温: {:.2f} °C.format(np.nanmean(diff)))注意两年数据必须来自同一合成方法都是年均值或都是年最大值否则差值无意义。5.3 一个我踩过的坑用 0.01 度网格做面积统计0.01 度在赤道约 1.1km在北纬 40 度约 0.85km。如果你直接用像元数乘 1km²北方会高估面积。我后来统一转 Albers 再统计误差从 15% 降到 2% 以内。这个习惯救了我好几次。5.4 验证方法用地面气象站数据做交叉验证找中国气象数据网CMA的 2022 年日均温和 LST 做相关。注意LST 是地表温度气温是 1.5m 高度两者差 2-5°C 正常。我一般看 R²如果低于 0.6说明数据质量有问题。常见做法是选 10 个站做散点图看斜率。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。