
1. 41年的连续序列是怎么做到的这几天圈子里又炸了一波武大CLCD数据集更新到了2025年也就是说现在手头能拿到1985—2025年整整41年的全国30米土地利用/土地覆盖数据。我在群里看到不少人在问CLCD和tiff格式怎么配合使用还有人在纠结怎么从tiff里提取区域高程点这些都是拿到数据之后马上会碰到的问题。作为一个常年跟土地利用数据打交道的GIS从业者我趁着这次数据更新把从下载、预处理到分析出图的完整流程重新走了一遍这篇就当是给自己的备忘也顺手分享给需要的人。先说清楚CLCD是什么。CLCD全称是China Land Cover Dataset武汉大学相关团队发布的年度中国土地覆盖数据集空间分辨率30米时间上从1990年一路补到2000年后后面逐年无缝更新目前最新版本覆盖到2025年正好凑成41年连续序列。这套数据在圈子里能火起来原因很直接全球范围公开可用的30米分辨率长时序土地覆盖产品本来就不多GlobeLand30是单期或隔几年一版FROM-GLC虽然也有多年份但更新频率一般真正能做到逐年连续、且在国内做过精度验证的CLCD算是当前最顺手的选择之一。数据本身是tiff格式一个年份一个文件分类体系包含耕地、林地、草地、灌木地、湿地、水体、苔原、不透水面、裸地、冰雪一共10个一级类别。注意这里不是常见的二级分类细目而是偏宏观的一级地类所以做全国尺度或者区域尺度的演变分析非常合适。如果你需要做更细的用地分类像区分水田和旱地、常绿林和落叶林CLCD的10类体系会不够用得搭配其他数据或者自己加辅助信息这一点后面我会单独讲。文件组织方面官方提供的下载包一般分两类一个是全国一张tiff一个年份文件动辄几百兆甚至上G适合做全局分析另一种是按省裁剪好的分省tiff单个文件小很多适合只关注某一省或几个地市的情况。我个人的习惯是优先把全国数据下载下来然后自己按矢量边界裁剪因为官方分省包偶尔存在边界处理不一致的问题自己裁剪反而更可控后面第三节我会放完整脚本。这套数据为什么值得花篇幅写核心就一个词连续。41年逐年覆盖意味着你可以不需要任何插值、不需要拼接多个来源直接按年份序列拉出一条像样的变化曲线。在30米这个尺度上城市扩张、耕地流失、林草变化、水体变迁都能看出比较清晰的趋势这对做长时序研究的同学来说省掉的不仅仅是下载多套数据的时间更重要的是避免了不同数据集之间的分类标准不一致带来的系统性误差。2. 41年数据到底能拿来干什么很多人下载CLCD之后第一反应是“哇好大”第二反应是“然后呢”。这里我展开聊几个最常见的应用方向每个方向我都跑过实际案例可以给你一个具体参考。第一个方向是城市扩张监测。我去年帮某课题组做过长三角地区的建设用地变化分析用的就是CLCD的不透水面类别。具体做法很简单把各年份的tiff重分类成“不透水面/非不透水面”二值图然后逐年统计像元数量乘以单个像元面积就能得到逐年城建区面积。比如某个城市1985年不透水面面积大约120平方公里到2025年可能涨到800多平方公里41年翻了将近7倍这种数字直接用CLCD算出来非常流畅而且因为30米分辨率街道尺度的扩张细节也能看到不会像1公里分辨率的粗网格那样把城市轮廓磨得看不清。第二个方向是耕地变化与粮食安全分析。把历年耕地类别单独提取出来叠加上行政区边界你就能算出每个县市耕地面积的时间序列。我做过一个华北平原的案例2010年到2020年耕地净减少明显减少的部分绝大多数转成了不透水面这正是城市扩张和耕地保护之间矛盾的最直观证据。要是再叠加土壤、气象数据还能进一步做耕地质量演变评估CLCD在这里的角色就是最基础的土地利用底图。第三个方向是生态评估。自然保护区、流域范围的林地、草地、湿地、水体变化是环评和生态修复项目里回避不了的内容。CLCD的湿地类别和水体类别可以分开提取配合DEM高程数据还能判断湿地分布的海拔范围这在做生态红线划定的时候特别实用。第四个方向是三维地形与土地覆盖的叠加分析这正好回应了热搜里“如何根据tiff提取区域内高程点”的问题。CLCD本身是土地利用分类栅格不包含高程信息但你们在做分析的时候几乎一定会遇到需要把土地利用和地形叠在一起看的情况。做法是把CLCD的tiff和DEM数据比如SRTM、ALOS、ASTER GDEM放到同一个坐标系下先按研究区范围裁剪两个栅格再用栅格转点工具或者Python读取每个像元对应的地类和高程值。比如你想知道某个区域建设用地平均海拔是多少、耕地集中在哪个坡度区间就把两个栅格逐像元对应起来统计。ArcGIS里可以用“Extract Multi Values To Points”提取多值到点一步到位QGIS里也有Point Sampling ToolPython里用rasterio分别读取再做一个mask逻辑是一样的。这个操作本身不难但很多人第一次做会卡在坐标系不一致上后面我在踩坑部分会重点讲。其他方向还包括生物多样性栖息地评估、荒漠化监测、海岸带变化、灾害风险评估等等。本质上只要你的分析需要“过去某一年地表是什么样”“这些年地表怎么变”CLCD就能当基座数据。它对新手特别友好的地方在于不需要自己处理遥感原始影像不需要做大气校正、几何校正、分类后处理下载下来就是干净的分类结果开箱即用。当然这也意味着精度会受原始影像和分类算法限制所以如果你的研究区域比较小或者对分类精度要求极高还是需要找更高分辨率的数据或自己分类CLCD更适合宏观和中尺度分析。3. 下载渠道选择与文件组织方式这一节讲最实际的CLCD去哪儿下、全国包和分省包怎么选、文件命名和坐标系是怎么回事。下载渠道现在比较常见的是通过官方发布页、部分学术数据平台以及一些转存的网盘链接。因为我不方便贴具体网址你在搜索引擎里搜“CLCD 武汉大学 土地利用”或者“CLCD 1985 2025”基本都能找到。这里提醒一句找下载资源的时候认准版本号和时间范围有少数旧帖还在传1990-2022或1990-2023的老包别下错了。另外有些平台下载需要注册登录有些直接给网盘直链看清楚规则再动手尽量避免在不明网站输入个人信息。拿到数据之后第一步不是急着解压分析而是先把文件清单捋一遍。我习惯这样检查确认年份连续性1985到2025是不是每年都有中间不能缺年。确认文件格式应该是GeoTIFF也就是带地理参考信息的tiff右键属性里能看到空间参考信息。确认投影坐标系CLCD默认一般是WGS84经纬度坐标EPSG:4326有些版本也提供Albers等面积投影的版本后文会展开说。确认分类类别数正常是10类别拿到一个只有7类8类的旧版文件自己还不知道。全国包和分省包的选择我的建议是分场景对待。如果你的研究区是两三个省交界或者要做全国尺度的对比直接下全国包省事如果你只关心某一个省下分省包跑起来更快内存压力小。但是要注意分省包如果是由不同来源拼接的省份交界处偶尔会有类别不一致的“接边缝”用的时候尽量先做一个统一检查。自己做裁剪的话代码逻辑统一、边界干净还能顺便把投影统一了就是费点时间我觉得值得。再说坐标系。CLCD的原始坐标经常是GCS_WGS_1984也就是经纬度单位是度。30米分辨率在赤道附近约等于0.00027度一个像元但是在高纬度地区经纬度坐标直接算面积会出问题因为一个经度在高纬对应的实际距离比赤道小得多。所以凡是涉及面积统计、密度计算、距离量测都建议用Albers等积投影或者UTM投影等面积投影能保证面积不扭曲。我自己做中国范围分析时常用Albers_Krasovsky_1940或Albers_Conic_Equal_Area中央经线105E双标准纬线25N/47N这套参数在常规中国制图里很通用ArcGIS里直接选就行。如果只做某个小区域用当地的UTM分带也可以。这是30米数据处理的必经之路绕不过去。还有一个容易被忽略的点CLCD的年份tiff文件名一般会直接包含年份比如CLCD_1985.tiff、CLCD_2025.tiff这样但我见过有些转存版本把年份写在文件名中间还有的年份信息只在元数据里。拿到文件后先把年份对应关系确认清楚再建一个文件清单表格避免后面循环处理时年份对应错位。尤其写Python批量处理时文件名解析错了就是一连串错误结果别问我怎么知道的。文件大小方面全国一张30米tiff大约在1GB上下有的年份会更大分省之后一般几十到几百MB根据不同省份面积和地类复杂度有差异。电脑配置一般的同学做全国分析前先确认内存余量我在8GB内存的笔记本上直接处理全国重叠比较勉强后来改成按分块读取才顺畅第四节代码里我会给一个分块读写方案。4. 从tiff到成果图的核心实操流程到了本文的干货部分。很多人卡在“数据下载了但打不开、剪不了、算不出面积”这个环节。这一节我会给出一套完整的实操链路从栅格读取、按边界裁剪、重分类、面积统计一直讲到导出成果图。考虑到大家用的工具链不同我分别说Python和ArcGIS/QGIS两种路径你自己挑顺手的。4.1 用Python处理CLCD tiffPython这边我推荐rasterio配合geopandas、numpy这是目前最顺手的栅格处理组合。先装依赖pip install rasterio geopandas shapely numpy matplotlib读取一个年份的tiff看基本信息和唯一值import rasterio import numpy as np with rasterio.open(CLCD_2025.tiff) as src: print(src.crs) # 坐标系 print(src.width, src.height) # 行列数 print(src.bounds) # 范围 data src.read(1) # 读取第一波段 # 统计类别值分布 unique, counts np.unique(data, return_countsTrue) for cls, cnt in zip(unique, counts): print(类别码, cls, 像元数, cnt)注意CLCD的类别码有些版本是1-10连续编号有些版本可能带有背景值0或NoData值255读取后先看一下最小值和最大值有异常值就提前处理别把背景值当成真实地类。按矢量边界裁剪是最高频的操作。我写了一个通用函数输入是shp或GeoJSON边界和一个年份tiff输出是裁剪后的tiffimport geopandas as gpd import rasterio from rasterio.mask import mask def clip_clcd(tiff_path, shp_path, out_path): with rasterio.open(tiff_path) as src: gdf gpd.read_file(shp_path) # 统一坐标系到tiff的坐标系非常重要 gdf gdf.to_crs(src.crs) # 取所有几何的合并外轮廓 geom [gdf.geometry.unary_union] out_image, out_transform mask(src, geom, cropTrue) out_meta src.meta.copy() out_meta.update({ driver: GTiff, height: out_image.shape[1], width: out_image.shape[2], transform: out_transform }) with rasterio.open(out_path, w, **out_meta) as dst: dst.write(out_image) # 示例裁剪武汉市 clip_clcd(CLCD_2025.tiff, wuhan.shp, CLCD_2025_wuhan.tiff)这段代码里最需要注意的是坐标系统一那一步。你的shp如果是WGS84经纬度tiff也是WGS84那没问题但如果shp是GCJ02或者投影坐标系不转换直接裁剪会偏到十万八千里。极端情况下我之前见过shp坐标和栅格坐标差了半个中国就是因为坐标系不一致。分块读取大文件。全国tiff超过1GB时直接把整个数组load进内存容易MemoryErrorrasterio支持窗口读取import rasterio from rasterio.windows import Window with rasterio.open(CLCD_2025.tiff) as src: # 每次读2048行 for i in range(0, src.height, 2048): window Window(0, i, src.width, min(2048, src.height - i)) block src.read(1, windowwindow) # 对block做计算...这种分块方式配合后续的面积统计就是再大的tiff也能在普通电脑上处理。统计面积不一定要把所有像元同时放内存可以逐块统计类别像元数最后加总。重分类是另一个高频需求。比如你想提取“建设用地”并转成二值图假设CLCD中不透水面类别码是8代码就是with rasterio.open(CLCD_2025_wuhan.tiff) as src: data src.read(1) profile src.profile # 生成二值不透水面为1其他为0 binary np.where(data 8, 1, 0).astype(np.uint8) with rasterio.open(CLCD_2025_wuhan_builtup.tiff, w, **profile) as dst: dst.write(binary, 1)如果你是手动换算多个类别比如把林地、灌木、草地合并为“植被类”可以用numpy的isinvegetation_codes [2, 3, 4] veg_mask np.isin(data, vegetation_codes) veg_raster veg_mask.astype(np.uint8) * 14.2 用ArcGIS/QGIS处理不用Python也能做而且对新手来说图形界面更直观。ArcGIS里标准流程是打开tiff右键查看属性确认坐标系。用“按掩膜提取”Extract by Mask工具做边界裁剪输入栅格选CLCD输入掩膜选你的矢量边界。用“重分类”Reclassify工具做类别合并把10类重编码成你需要的类别。用“面积制表”Tabulate Area工具统计不同类别面积输入是分类栅格和矢量区划输出就是每个区域每个类别的面积表。导出栅格或图表用Layout视图配色用“唯一值渲染”按类别码显示存成PNG或矢量PDF。QGIS里对应的是“裁剪栅格”Clip Raster by Mask Layer、“栅格计算器”Raster Calculator、“分区统计”Zonal Histogram这几个工具功能上完全对得上而且QGIS免费开源给学生党省授权费。我两边都用过个人感觉处理CLCD这种大tiff时QGIS的Windowed reading表现更稳ArcGIS有时候会一直转圈。但最终选哪个还是看你熟悉哪种以及项目协作时需要导出什么格式。面积计算的小细节栅格是30米分辨率一个像元理论面积是900平方米但前提是投影坐标系正确。如果你用经纬度的WGS84直接算像元面积同一像元在不同纬度实际面积差不少。所以重分类和裁剪完成之后记得加一步“投影栅格”Project Raster工具把经纬度投影成Albers等面积投影再去做面积统计。用Python的话可以用rasterio.warp.reproject实现同样的投影转换import rasterio from rasterio.warp import calculate_default_transform, reproject, Resampling dst_crs EPSG:102025 # 这里用你区域的Albers投影ID with rasterio.open(CLCD_2025_wuhan.tiff) 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(CLCD_2025_wuhan_albers.tiff, 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.nearest)重采样方法建议选nearest因为这是分类数据像元值代表类别编号用bilinear或cubic会插值出中间值比如类别2和类别3可能变成2.5没法用这是分类栅格和连续变量栅格处理上最核心的区别。4.3 从tiff提取区域内高程点回到热搜里的“如何根据tiff提取区域内高程点”。严格说CLCD不包含高程你需要另准备一份DEM数据。流程是把CLCD和DEM都转成同样的投影和范围然后二值化提取特定土地利用类别的位置把这些位置的DEM像元值提取出来生成点或者统计表。具体做法在ArcGIS里是先创建栅格点然后“提取多值到点”在Python里用rasterio同时读两个栅格逐像元判断即可with rasterio.open(CLCD_2025_wuhan_albers.tiff) as lc: with rasterio.open(DEM_wuhan_albers.tiff) as dem: lc_data lc.read(1) dem_data dem.read(1) # 比如提取建设用地对应的高程 builtup_mask lc_data 8 elevations dem_data[builtup_mask] elevations elevations[~np.isnan(elevations)] print(建设用地像元数:, len(elevations), 平均高程:, np.mean(elevations))这一步看起来简单但实际做起来有两个坑一是两个栅格的像元对齐问题CLCD和DEM来源不同像元网格不一定完全对齐最好先把DEM重采样到和CLCD一致的范围和分辨率二是NoData值DEM常有无值区域提取前先过滤一遍不然统计均值会被NoData污染。5. 这41年数据到底能拿来干什么在动手处理数据之前先把这个数据能做什么讲透免得你辛苦跑完流程发现方向不对。土地利用/土地覆盖数据分析的应用方向非常广这里挑几个最常见的典型场景来说。城市扩张监测。不透水面类别在CLCD里是一个单独的类别你把1985年、2000年、2010年、2025年这四个年份的不透水面提取出来叠加在一起就能很直观地看到城市边界怎么往外蔓延。我去年做过一个长江中游城市群的例子把历年建设用地面积拉成曲线再叠加夜间灯光数据做相关性分析两组数据趋势高度一致论文审稿人也没有质疑数据来源。耕地与粮食安全分析。耕地类别的变化是土地利用变化研究的核心议题。你可以统计某个省、某个县逐年耕地面积然后和统计年鉴做对比验证。CLCD在耕地识别上整体效果不错尤其在连片平原农业区误差比较小但在南方丘陵区因为田块破碎、种植结构杂耕地面积可能偏低使用时要有心理预期。生态质量评估。林地、草地、湿地、水体的面积和空间格局是生态评价的基础。比如算一个区域的NDVI和生态质量指数前你通常需要先知道地表类型再用类型分区的均值来评价。CLCD能帮你快速完成地表分区不用自己跑分类算法。国土空间规划辅助。在做规划项目、划定城镇开发边界、生态保护红线时历史用地数据是必备的底图。我在实际规划项目里常被问到“过去十年的用地变化趋势怎么样”用CLCD拉一个趋势分析说服力非常强。灾害风险评估。把历史土地覆盖和降雨、地形等数据叠加可以分析滑坡、洪水等灾害在不同地表类型下的易发性。建设用地和不透水面的位置直接影响暴雨内涝风险分布CLCD的30米分辨率在这个尺度上正好够用。这些场景有一个共同点需要的是“长时序一致的分类体系”。CLCD最值钱的不是某一年的高精度而是41年每年都用同一套标准在做分类。这一点看着简单实际上很多数据集做不到因为每过几年分类体系就更新一次导致前后年份不可比。6. 实操中一定会踩到的坑这里把我实际使用CLCD过程中踩过的坑以及帮别人排查时见过的高频问题集中列出来每一件都真实发生过不是凭空臆测。坑一类别代码和类别对应搞错。不同版本的CLCD分类代码不完全一致。有的版本类别顺序是耕地1、林地2、草地3、灌木4、湿地5、水体6、苔原7、不透水面8、裸地9、冰雪10还有的版本把不透水面排到6水体排到8。如果你直接拿一个旧代码表去对应新数据统计出来的结果就全是错的。我的建议是每次拿到文件先用np.unique跑一遍所有类别值再对照官方分类表确认一遍不要凭记忆写代码。坑二坐标系和投影问题。前面已经强调过CLCD很多是GCS_WGS_1984经纬度坐标系直接算面积会出问题。比如同样30米分辨率的像元在海南一个像元面积约900平方米在黑龙江一个像元对应的地面面积差距会体现出来。算面积前一定先投影成Albers等积投影或UTM。如果你做了多个年份的对比分析所有年份必须投影到同一个坐标系不然前后面积对比会失真。坑三大tiff内存溢出。全国一张tiff直接read(1)很容易把内存吃光。解决方式就是分块处理或者先用接近研究区的矢量裁剪把范围缩小到能全读进内存的尺寸。我自己处理全国数据时总是以省级行政区为单位做分省裁剪后再计算内存占用在4GB以内。坑四NoData和背景值干扰统计。tiff边缘通常有黑色的无数据区域如果不去除统计像元数时会多出一大块。读取数据后先看最小值如果出现0或255这类异常值要把它们排除在外再统计类别。标准做法是设置一个valid_mask只统计在范围内的像元。坑五分省数据拼边不一致。官方分省包毕竟经过裁剪和重压缩省份交界处偶尔会有像元错位或类别突变。如果你靠官方分省包直接拼全国接缝处可能丑到没法看。我建议做全国分析时只用全国包做省域分析时用官方分省包但不要混用。坑六默认渲染很难看。tiff首次加载进软件通常是用灰度或随机拉伸显示新手以为数据坏了。实际上只要做一次“唯一值渲染”把10个类别分别配色图就会立刻变得清晰可读。这里建议选一套色盲友好的配色比如水体用蓝色、林地用绿色、耕地用黄色、不透水面用红色导出图时也更容易让读者看懂。7. 一个完整的趋势分析案例最后用一个精简但完整的案例把前面所有操作串起来。假设我们要分析武汉市2000年到2025年建设用地扩张趋势。第一步准备两个年份的全国包tiff和武汉市行政边界shp。第二步用ArcGIS的按掩膜提取分别裁剪出武汉2000年和2025年的栅格。第三步用重分类工具提取不透水面类别码设为与CLCD版本对应。第四步先投影到Albers等积投影再用栅格转面或栅格转点得到建设用地图斑。第五步统计面积。结果通常是这样的2000年武汉市建设用地面积约500平方公里2025年约1100平方公里25年翻了一倍多。这个数字与统计年鉴口径不完全一致因为年鉴是行政区划的建成区统计而CLCD是卫星影像像元聚出但趋势一致性非常好。这里也提醒一句不同来源的绝对数值差异不一定说明数据错了先搞清楚统计口径再做比较。从处理到成果展示完整的链路无非就是裁剪、重分类、投影、统计、制图这五步。只要你每一步都踩稳了后面换任何区域、任何年份都能照葫芦画瓢。我在实际项目中一个区域的多年趋势分析顺利的话半小时以内就能跑完出图效率非常可观。8. 几个关于数据使用的长期建议数据本身只是起点真正决定研究成果质量的是后处理和分析思路。这里分享几个我坚持了多年的处理习惯。第一所有分析项目的原始数据归档时要同时保留原始tiff、裁剪后中间文件、最终产品三层目录。很多人只留最终图一年后要改图重跑时发现原始文件不知道放哪了只能重新下载时间成本非常高。第二做趋势分析时尽量用同一套CLCD版本不要混合不同版本的数据做时序对比。旧版本已经生成的成果如果新版分类体系有调整宁可重新批量跑一遍也不要新旧混用。分类体系变动带来的伪变化比真实的土地变化更隐蔽。第三处理分类栅格时所有重采样都选nearest不要选bilinear。分类数据的数值是类别标签不是连续测量值插值会造成类别混合逻辑上说不通。这个点很多新手第一次踩踩完就记住了。第四定期关注CLCD的更新公告一般年末会发新一年份的数据。关注发布说明里关于分类算法的改动说明。如果某一版本的分类算法有明显调整那一年的数据与前后年份的可比性就需要特别留意有时候需要做断点校正。第五在做跨区域比较时统一使用同样的投影参数和统计口径。比如全国各县建设用地面积比较统一用Albers_Conic_Equal_Area投影统一按行政区面积剔除水域影响结果才有可比性。我个人建议第一次接触CLCD的读者不要急着全量下载41年全国包先下载研究区域的两个年份比如2000年和2020年试跑一遍把裁剪、重分类、统计、出图的流程走通再决定要不要全量下载。等确认整个流程没问题后再批量下载所有年份用脚本循环处理。这样能少走很多弯路也能帮你更快建立对这套数据的直觉。