)
GEE土地利用转移矩阵实战5分钟搞定CGLS-LC100数据集分析附完整代码当我们需要分析某地区10年间森林如何变成农田或者城市扩张占用了多少湿地时土地利用转移矩阵就像一台时间机器能清晰呈现地表变化的来龙去脉。传统GIS软件处理这类分析往往需要下载海量数据而Google Earth EngineGEE的云端计算能力让这一切变得触手可及。本文将手把手带您用CGLS-LC100数据集在5分钟内完成从数据准备到矩阵生成的全流程。1. 认识CGLS-LC100数据集CGLS-LC100是欧盟哥白尼计划推出的100米分辨率全球土地覆盖产品其核心优势在于时间覆盖2015-2019年逐年数据Proba-V卫星和2020年起年度数据Sentinel-3分类体系代码类型代码类型20灌木丛50稀疏植被30草地60裸露地面40耕地80水域数据质量总体精度超过80%尤其擅长区分农田与自然植被提示在GEE中调用该数据集时discrete_classification波段存储了上述分类代码而continuous_classification波段则提供概率信息适合高级用户使用。2. 快速搭建分析环境2.1 初始化GEE工作区首先在GEE代码编辑器https://code.earthengine.google.com/新建脚本粘贴以下基础配置// 定义分析区域以昆明为例 var roi ee.Geometry.Rectangle([102.3, 24.8, 103.1, 25.3]); Map.centerObject(roi, 9); // 加载2018和2020年土地覆盖数据 var lc2018 ee.Image(COPERNICUS/Landcover/100m/Proba-V-C3/Global/2018) .select(discrete_classification) .clip(roi); var lc2020 ee.Image(COPERNICUS/Landcover/100m/Proba-V-C3/Global/2020) .select(discrete_classification) .clip(roi); // 可视化参数 var visParams { min: 20, max: 80, palette: [#ffff64, #aaf0f0, #dcf064, #c8c864] }; Map.addLayer(lc2018, visParams, 2018土地覆盖);2.2 数据预处理技巧处理跨年度数据时常见两个陷阱年度间分类代码不一致有些年份会新增细分类型云遮挡导致的缺失值需要填充或掩膜处理用这段代码确保数据一致性// 统一分类体系示例保留共同类别 var commonClasses [20, 30, 40, 50, 60, 80]; var filterClasses function(image) { return image.remap(commonClasses, commonClasses) .set(system:time_start, image.get(system:time_start)); };3. 转移矩阵核心算法解析3.1 数学原理可视化转移矩阵本质是一个二维 contingency table其构建过程可分为三步编码组合将两期数据合并为唯一编码前期代码×1000 后期代码面积统计计算每种编码组合的像元面积总和矩阵重组将统计结果按行列格式排列3.2 关键代码实现以下是最核心的面积统计模块// 生成转移编码图像 var transferCode lc2018.multiply(1000).add(lc2020); // 计算各编码组合面积平方公里 var areaStats ee.Image.pixelArea() .addBands(transferCode) .reduceRegion({ reducer: ee.Reducer.sum().group({ groupField: 1, groupName: transfer_code }), geometry: roi, scale: 100, maxPixels: 1e13 }); // 解析编码为前后期类型 var parseFeatures function(group) { var code ee.Number(group.get(transfer_code)); return ee.Feature(null, { from: code.divide(1000).int(), to: code.mod(1000).int(), area_km2: group.get(sum).divide(1e6) }); };4. 完整工作流与结果导出4.1 自动化矩阵生成将上述模块封装成函数实现一键生成function generateMatrix(firstImg, secondImg, scale) { // 获取所有存在的类别 var classes firstImg.addBands(secondImg) .reduceRegion({ reducer: ee.Reducer.frequencyHistogram(), geometry: roi, scale: scale }) .get(discrete_classification); // ...接完整统计代码 // 构建矩阵表格 var headers ee.List([from]).cat(classes); var rows classes.map(function(from) { return ee.List([from]).cat( classes.map(function(to) { return transferDict.get(from.cat(_).cat(to)) || 0; }) ); }); return ee.FeatureCollection(rows.map(function(row) { return ee.Feature(null, ee.Dictionary.fromLists(headers, row)); })); }4.2 结果导出与美化导出CSV后推荐用Python进行可视化import seaborn as sns import pandas as pd df pd.read_csv(transfer_matrix.csv) plt.figure(figsize(10,8)) sns.heatmap(df.iloc[:,1:], annotTrue, fmt.1f, xticklabelsclass_names, yticklabelsclass_names) plt.title(Land Use Transition Matrix (km²))处理实际项目时我发现三个实用技巧当研究区较大时将scale参数调整为500米可显著加快计算使用clipToCollection而非clip可以避免几何无效错误导出前用.limit(1000)防止超过GEE的导出限制