目录
一、研究区设置与地图初始化
二、Landsat 8 影像加载与筛选
三、归一化建筑指数(NDBI)计算
四、建设用地提取(核心阈值法)
五、面积计算函数定义
六、总面积与密度分级面积计算
(一)建设用地总面积计算
(二)密度分级计算(核心逻辑:按 NDBI 值细分)
七、数据导出(本地存储)
八、地图图例添加(可视化优化)
九、代码核心特点与注意事项
十、运行结果
若觉得代码对您的研究 / 项目有帮助,欢迎点击打赏支持!需要完整代码的朋友,打赏后可在后台私信(复制文章标题发给我),我会尽快发您完整可运行代码,感谢支持!
本代码基于 Google Earth Engine(GEE)平台,以 2023 年 Landsat 8 卫星影像为数据源,通过计算归一化建筑指数(NDBI)实现研究区建设用地的提取,并按照 NDBI 数值范围划分低密度、中密度、高密度三个等级,最终完成面积统计、可视化展示与数据导出。核心流程可概括为:设置研究区→加载影像→计算 NDBI→建设用地提取→面积计算→密度分级→数据导出→图例添加,全程围绕 “从影像到专题信息” 的提取逻辑展开。
本代码可用于城市扩张监测、建设用地时空变化分析、城市规划评估等场景,例如:
- 计算某城市 2023 年建设用地总面积及密度分布,为城市总体规划提供数据支撑。
- 对比不同年份的建设用地提取结果,分析城市扩张速度与方向。
- 结合其他指数(如 NDVI、MNDWI)优化地类提取精度,实现建设用地与水体、植被的精准区分。
一、研究区设置与地图初始化
var roi = table; Map.addLayer(roi, {}, '研究区'); Map.centerObject(roi, 9);- 核心功能:定义研究区范围并在地图上可视化,同时调整地图视角。
- 关键说明:
roi = table:table是 GEE 中已导入的矢量数据集(如行政区划边界),此处直接作为研究区(Region of Interest),后续所有操作均限定在该范围内。Map.addLayer():将研究区矢量边界添加到地图画布,第三个参数为图层名称,便于在地图界面区分。Map.centerObject(roi, 9):将地图中心定位到研究区,第二个参数 “9” 为缩放级别(范围 1-20,数值越大视角越近、细节越清晰)。
二、Landsat 8 影像加载与筛选
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterDate('2023-01-01', '2023-12-31') .filterBounds(roi) .sort('CLOUD_COVER') .first(); print('影像元数据:', collection);- 核心功能:筛选 2023 年覆盖研究区、云量最少的 Landsat 8 表面反射率(SR)影像。
- 关键参数与逻辑:
- 影像集合 ID:
LANDSAT/LC08/C02/T1_L2是 Landsat 8 的 Level 2 级产品(经过大气校正、辐射定标等预处理),数据质量更高,可直接用于指数计算。 - 筛选条件:
filterDate():限定影像时间范围为 2023 全年,确保数据的时间一致性。filterBounds(roi):仅保留覆盖研究区的影像,剔除无关区域数据,提高计算效率。sort('CLOUD_COVER').first():按 “云量(CLOUD_COVER)” 升序排序后取第一幅,即云量最少的影像,避免云层对后续指数计算的干扰。
print():在 GEE 控制台输出影像元数据(如拍摄时间、云量、分辨率等),用于数据质量校验。
- 影像集合 ID:
三、归一化建筑指数(NDBI)计算
var ndbi = collection.normalizedDifference(['SR_B6', 'SR_B5']); var ndbiClipped = ndbi.clip(roi); Map.addLayer(ndbiClipped, {min: -1, max: 1, palette: ['blue', 'white', 'green']}, 'NDBI');- 核心原理:NDBI 是识别建设用地的核心指数,利用短波红外(SWIR)与近红外(NIR)波段的差异突出建筑用地(建筑用地在 SWIR 波段反射率高,NIR 波段反射率低,NDBI 值为正;植被、水体 NDBI 值为负)。
- 关键解析:
- 波段对应:Landsat 8 的
SR_B6为短波红外波段(SWIR),SR_B5为近红外波段(NIR),符合 NDBI 计算公式:NDBI = (SWIR - NIR) / (SWIR + NIR)。 normalizedDifference():GEE 内置函数,直接计算两波段的归一化差值,结果范围为 [-1,1]。clip(roi):将 NDBI 影像按研究区裁剪,剔除研究区外的无效数据。- 可视化设置:
min: -1, max: 1限定显示范围,palette设置颜色映射(蓝色→负值区,白色→接近 0,绿色→正值区),直观区分不同地类的 NDBI 特征。
- 波段对应:Landsat 8 的
四、建设用地提取(核心阈值法)
var ndbiThreshold = 0; var builtUpArea = ndbiClipped.gt(ndbiThreshold) .selfMask() .rename('BuiltUpArea'); Map.addLayer(builtUpArea, {palette: 'FFF000'}, '建设用地');- 核心逻辑:基于 NDBI 的物理意义,设定阈值(此处为 0),将 NDBI 值大于 0 的区域判定为建设用地。
- 关键步骤:
gt(ndbiThreshold):gt是 “大于(greater than)” 的缩写,返回布尔影像(NDBI>0 的像素为 1,否则为 0)。selfMask():掩膜操作,仅保留值为 1 的像素(建设用地),值为 0 的区域透明显示,避免干扰可视化。rename():为结果影像命名,便于后续面积计算和导出。- 可视化:采用黄色(FFF000)显示建设用地,与其他地类形成明显区分。
五、面积计算函数定义
var calculateArea = function(image) { var pixelArea = ee.Image.pixelArea().divide(1e4); // 转为公顷 return image.multiply(pixelArea); };- 核心功能:定义通用面积计算函数,将影像像素值转换为实际面积(公顷)。
- 原理说明:
ee.Image.pixelArea():GEE 内置函数,返回每个像素的面积(单位:平方米),Landsat 8 影像分辨率为 30 米,单个像素面积为 30×30=900 平方米。divide(1e4):1 公顷 = 10000 平方米,将面积单位从平方米转为公顷,便于实际应用。image.multiply(pixelArea):将布尔影像(1 表示建设用地,0 表示非建设用地)与像素面积相乘,得到每个建设用地像素的实际面积,非建设用地像素面积为 0。
六、总面积与密度分级面积计算
(一)建设用地总面积计算
var builtUpAreaWithArea = calculateArea(builtUpArea); var totalArea = builtUpAreaWithArea.reduceRegion({ reducer: ee.Reducer.sum(), geometry: roi, scale: 30, maxPixels: 1e9 }); print('建设用地总面积(公顷):', totalArea.get('BuiltUpArea'));calculateArea(builtUpArea):调用面积计算函数,得到每个建设用地像素的面积影像。reduceRegion():对影像进行区域统计,核心参数:reducer: ee.Reducer.sum():统计方式为 “求和”,即所有建设用地像素的面积总和。geometry: roi:统计范围为研究区。scale: 30:统计分辨率,与 Landsat 8 影像原始分辨率一致,确保面积精度。maxPixels: 1e9:设置最大处理像素数,避免因研究区过大导致计算报错。
print():在控制台输出总面积结果,get('BuiltUpArea')提取统计结果中的面积值。
(二)密度分级计算(核心逻辑:按 NDBI 值细分)
// 低密度:0 ~ 0.05 var lowDensityBuiltUpArea = ndbiClipped.gt(0).and(ndbiClipped.lt(0.05)) .selfMask().rename('LowDensityBuiltUpArea'); var lowDensityArea = calculateArea(lowDensityBuiltUpArea).reduceRegion({...}); print('低密度建设区面积(公顷):', lowDensityArea.get('LowDensityBuiltUpArea')); // 中密度:0.05 ~ 0.10 var mediumDensityBuiltUpArea = ndbiClipped.gt(0.05).and(ndbiClipped.lt(0.10)) .selfMask().rename('MediumDensityBuiltUpArea'); // 高密度:> 0.10 var highDensityBuiltUpArea = ndbiClipped.gt(0.10) .selfMask().rename('HighDensityBuiltUpArea');- 分级依据:NDBI 值越大,代表建筑用地的 “密集程度” 越高(如高层密集城区 NDBI 值高,城郊低矮建筑区 NDBI 值低),因此按 NDBI 区间划分密度等级:
- 低密度:0 < NDBI < 0.05(如城郊散户、低矮建筑区)
- 中密度:0.05 ≤ NDBI < 0.10(如普通城区、多层建筑群)
- 高密度:NDBI ≥ 0.10(如中心商务区、高层密集区)
- 关键语法:
and()是逻辑 “与” 操作,用于限定 NDBI 的区间范围;中密度、高密度的面积计算逻辑与低密度一致,均调用calculateArea()函数和reduceRegion()统计,最终在控制台输出各等级面积。 - 可视化区分:低密度(橙色 FFA500)、中密度(红色 FF0000)、高密度(深红色 8B0000),颜色深浅对应密度高低,直观展示研究区建设用地的密度分布。
七、数据导出(本地存储)
// 导出建设用地影像 Export.image.toDrive({ image: builtUpArea.uint8(), description: 'BuiltUp_Area_Image', folder: 'GEE_Export', scale: 30, region: roi }); // 导出NDBI影像(GeoTIFF) Export.image.toDrive({ image: ndbiClipped, description: 'NDBI_Full', folder: 'GEE_Export', scale: 30, region: roi.geometry().bounds(), fileFormat: 'GeoTIFF' });- 核心功能:将计算得到的专题影像(建设用地、各密度等级、NDBI)导出到 Google Drive,便于后续在 ArcGIS 等软件中进一步分析。
- 关键参数说明:
image: builtUpArea.uint8():将布尔影像转换为 8 位无符号整数类型(uint8),减少文件体积,便于存储。description:导出文件名称,需唯一且明确。folder:Google Drive 中存储文件的文件夹名称(需提前创建)。scale: 30:导出分辨率,与原始影像一致,保证数据精度。region:导出范围,建设用地影像按研究区矢量范围导出,NDBI 影像按研究区边界的外接矩形导出,避免漏边。fileFormat: 'GeoTIFF':导出格式为 GeoTIFF(地理空间数据标准格式),支持坐标系统,可直接用于 GIS 软件。
八、地图图例添加(可视化优化)
var legend = ui.Panel({style: {position: 'bottom-left', padding: '8px 15px'}}); var legendTitle = ui.Label({value: '研究区基于NDBI的建设用地分级', style: {fontWeight: 'bold', fontSize: '18px'}}); legend.add(legendTitle); var makeRow = function(color, name, value) { var colorBox = ui.Label({style: {backgroundColor: '#' + color, padding: '8px'}}); var description = ui.Label({value: name, style: {margin: '0 0 4px 6px'}}); var valueLabel = ui.Label({value: value ? value + ' 公顷' : '', style: {margin: '0 0 4px 6px', fontWeight: 'bold'}}); return ui.Panel({widgets: [colorBox, description, valueLabel], layout: ui.Panel.Layout.Flow('horizontal')}); }; lowvalue.evaluate(function(val) { mediumvalue.evaluate(function(val2) { highvalue.evaluate(function(val3) { legend.add(makeRow('FFA500', '低密度', val)); legend.add(makeRow('FF0000', '中密度', val2)); legend.add(makeRow('8B0000', '高密度', val3)); }); }); }); Map.add(legend);- 核心作用:在地图界面添加自定义图例,关联各密度等级的颜色、名称与面积值,提升可视化结果的可读性。
- 关键逻辑:
ui.Panel():创建图例面板,设置位置(左下角)和内边距,避免遮挡地图主体。makeRow()函数:定义图例的每一行结构,包含 “颜色块 + 等级名称 + 面积值” 三个组件,采用水平布局(Flow ('horizontal'))。evaluate():由于 GEE 中的数据为服务器端对象(ee.Number),需通过evaluate()将其转换为客户端 JavaScript 数值,才能在图例中显示具体面积。- 动态更新:图例中的面积值与前文计算结果联动,无需手动输入,确保数据一致性。
九、代码核心特点与注意事项
核心特点:
- 流程化设计:从数据加载到结果导出,步骤清晰、逻辑闭环,可直接适配不同研究区(仅需替换
table矢量数据)。 - 精度可控:采用 Landsat 8 Level 2 级数据,结合 30 米分辨率和阈值法,平衡计算效率与提取精度。
- 可视化丰富:多图层叠加(研究区、NDBI、建设用地、密度分级)+ 自定义图例,直观展示分析结果。
注意事项:
- 阈值调整:NDBI 阈值(0)为通用值,实际应用中需根据研究区地类特征(如植被覆盖率、水体分布)调整,可通过试错法或混淆矩阵验证最优阈值。
- 数据质量:若研究区 2023 年无云量极低的影像,可扩大时间范围或调整
sort('CLOUD_COVER')为filter(ee.Filter.lt('CLOUD_COVER', 10))(筛选云量 < 10% 的影像)。 - 导出限制:GEE 导出文件大小有限制,若研究区过大,可拆分研究区或降低导出分辨率(需权衡精度)。
- 矢量数据:
table需提前导入 GEE(支持 Shapefile、KML 等格式),且需与影像坐标系统一致(默认 WGS84)。
十、运行结果
若觉得代码对您的研究 / 项目有帮助,欢迎点击打赏支持!需要完整代码的朋友,打赏后可在后台私信(复制文章标题发给我),我会尽快发您完整可运行代码,感谢支持!