基于 GEE 的城市热岛效应分析——可视化地表温度 LST 与归一化植被指数 NDVI 的关联

发布于:2025-03-14 ⋅ 阅读:(12) ⋅ 点赞:(0)

目录

1 前言

2 研究方法及数据处理

3 完整代码

4 运行结果


1 前言

随着全球气候变化的不断加剧,城市热岛效应逐渐成为了城市可持续发展中的重大挑战之一。城市热岛效应是指城市区域内由于人为活动、建筑材料、地面铺装方式等因素导致的温度明显高于周边郊区的现象。这种效应不仅对城市居民的舒适度造成了显著影响,还可能加剧能源消耗、空气污染,甚至对公共健康产生威胁。因此,研究城市地表温度(Land Surface Temperature,简称 LST)及其与归一化植被指数(Normalized Difference Vegetation Index,简称 NDVI)的关系,成为了当前城市环境研究领域的重要课题。

因此本文分享通过遥感技术,基于 Google Earth Engine 平台与 Landsat 8 卫星影像,分析研究区 2020 年 4 月至 7 月期间的地表温度特征,并进一步探讨地表温度与植被指数之间的关系。

2 研究方法及数据处理

(1)NDVI 计算:NDVI 是植被覆盖状况的重要指标,计算公式为:(NIR - Red) / (NIR + Red),其中 NIR 为近红外波段(波段 5),Red 为红波段(波段 4),较高的 NDVI 值通常表示更丰富的植被覆盖。

(2)地表发射率估算:地表发射率是计算地表温度的重要参数之一,本研究根据 NDVI 估算地表发射率,采用的经验公式为:发射率 = NDVI × 0.0003342 + 0.1。

(3)地表温度(LST)推算:通过 Landsat 8 热红外波段(波段 10),首先将影像的数字量值(DN)转换为辐射亮度,然后根据亮度推算亮温,最后考虑地表发射率的修正,得到实际地表温度。具体的计算过程包括以下步骤:

①将 DN 值转换为辐射亮度;

②根据 Landsat 8 提供的校准常数,进一步转换为亮温(摄氏度);

③利用发射率和亮温推算实际地表温度。

本文利用皮尔逊相关系数Pearson correlation coefficient)方法,进一步分析了 NDVILST 之间的相关性。结果显示,两者之间存在明显的负相关趋势,即植被覆盖越高的区域,地表温度越低。这充分证明了植被对城市热岛效应的显著缓解作用。

通过进一步采样分析,建立了 NDVILST 的散点图,直观展示相关趋势,进一步凸显了植被在调节城市生态环境方面的重要价值。

为了更好地展示结果,可以在代码运行后点击“选择地图”分别查看不同区域的地表温度分布和植被覆盖情况。

3 完整代码

// 定义研究区域(AOI)和时间范围
var AOI = table;
Map.addLayer(AOI, {}, "城市边界");
Map.centerObject(AOI, 10);

// 加载Landsat 8影像
var landsat8 = ee.ImageCollection('LANDSAT/LC08/C02/T1')
    .filterDate('2024-04-01', '2024-07-31') // 过滤日期范围
    .filter(ee.Filter.lt('CLOUD_COVER', 10)) // 选择云量低于10%的影像
    .median() // 计算中值合成影像
    .clip(AOI); // 裁剪到研究区域

// 计算NDVI的函数
var calculateNDVI = function (image) {
    // NDVI计算公式:(B5 - B4)/(B5 + B4)
    var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
    return image.addBands(ndvi);
};

// 计算地表发射率的函数
var calculateEmissivity = function (image) {
    var ndvi = image.select('NDVI');
    var emissivity = ndvi.multiply(0.0003342).add(0.1); // 基于NDVI的发射率估算公式
    return image.addBands(emissivity.rename('EMISSIVITY'));
};

// 计算地表温度(LST)的函数
var calculateLST = function (image) {
    var thermalBand = image.select('B10'); // 热红外波段

    // Landsat 8校准常数
    var K1 = 774.8853; // 校准常数1
    var K2 = 1321.0789; // 校准常数2

    // 将DN值转换为大气顶层辐射亮度
    var toaRadiance = thermalBand.multiply(0.0003342).add(0.1);

    // 将辐射亮度转换为亮温(单位:摄氏度)
    var brightnessTemp = toaRadiance.expression(
        '(K2 / (log((K1 / L) + 1))) - 273.15', {
            'K1': K1,
            'K2': K2,
            'L': toaRadiance
        }
    ).rename('BRIGHTNESS_TEMP');

    // 使用发射率计算真实地表温度
    var emissivity = image.select('EMISSIVITY');
    var lst = brightnessTemp.expression(
        '(BT / (1 + (0.00115 * BT / 1.4388) * log(emissivity)))', {
            'BT': brightnessTemp,
            'emissivity': emissivity
        }
    ).rename('LST');

    return image.addBands(lst);
};

// 执行计算流程
var ndviImage = calculateNDVI(landsat8); // 计算NDVI
var emissivityImage = calculateEmissivity(ndviImage); // 计算发射率
var lstImage = calculateLST(emissivityImage); // 计算地表温度

// 打印LST图像信息
print('地表温度图像:', lstImage);

// 计算区域统计值
var lstValue = lstImage.select('LST').reduceRegion({
    reducer: ee.Reducer.min().combine({
        reducer2: ee.Reducer.max(),
        sharedInputs: true
    }).combine({
        reducer2: ee.Reducer.mean(),
        sharedInputs: true
    }),
    geometry: AOI, // 统计区域
    scale: 30, // 空间分辨率
    maxPixels: 1e13 // 最大像素数
});
print("地表温度统计:", lstValue);

// 提取统计值并格式化
var minLST = lstValue.get('LST_min');
var maxLST = lstValue.get('LST_max');
var meanLST = lstValue.get('LST_mean');

// 创建统计结果显示面板
var lst_Stats_Text = [
    ['最小值', minLST.getInfo().toFixed(2) + ' °C'],
    ['最大值', maxLST.getInfo().toFixed(2) + ' °C'],
    ['平均值', meanLST.getInfo().toFixed(2) + ' °C']
];

// 统计面板样式设置
var lst_stat_panel = ui.Panel({
    style: {
        position: 'bottom-left', // 面板位置
        padding: '10px 10px', // 内边距
        backgroundColor: 'white', // 背景颜色
        border: '1px solid black' // 边框样式
    }
});

// 统计标题
var lst_stat_heading = ui.Label({
    value: '地表温度统计',
    style: {
        fontWeight: 'bold', // 加粗字体
        fontSize: '20px', // 字号
        margin: '0 0 4px 0', // 外边距
        color: 'black', // 文字颜色
        position: 'top-center' // 标题位置
    }
});

// 构建统计信息表格
lst_stat_panel.add(lst_stat_heading);
for (var i = 0; i < lst_Stats_Text.length; i++) {
    var row = ui.Panel({
        layout: ui.Panel.Layout.flow('horizontal'),
        style: { margin: '0 0 4px 0' }
    });
    for (var j = 0; j < lst_Stats_Text[i].length; j++) {
        row.add(ui.Label({
            value: lst_Stats_Text[i][j],
            style: { padding: '4px 4px', fontSize: '14px', color: 'black' }
        }));
    }
    lst_stat_panel.add(row);
}

// 采样分析NDVI与LST相关性
var sample = lstImage.select(['LST', 'NDVI']).sample({
    region: AOI, // 采样区域
    scale: 30, // 采样分辨率
    numPixels: 1000 // 采样点数量
});

// 计算皮尔逊相关系数
var correlation = sample.reduceColumns({
    reducer: ee.Reducer.pearsonsCorrelation(), // 相关性分析算法
    selectors: ['LST', 'NDVI'] // 分析字段
});
print('LST与NDVI相关系数:', correlation);

// 创建散点图
var chart = ui.Chart.feature.byFeature({
    features: sample,
    xProperty: 'NDVI',
    yProperties: 'LST'
}).setChartType('ScatterChart').setOptions({
    title: 'LST与NDVI相关性分析', // 图表标题
    hAxis: { title: 'NDVI' }, // X轴标签
    vAxis: { title: 'LST (°C)' }, // Y轴标签
    pointSize: 1, // 点大小
    trendlines: { 0: { color: 'red' } } // 趋势线
});
print(chart);

// 可视化参数设置
var LST_VIS = { min: 20, max: 45, palette: ["0400ff", "37ff00", "fff875", "ffb1d7", "ff0000"] };
var NDVI_VIS = { min: -1, max: 1, palette: ["0008ff", "ff0808", "fffd2a", "5aff5c", "16b300"] };

// 创建图例函数
function createLSTLegend() {
    var legend = ui.Panel({
        style: {
            position: 'bottom-right',
            padding: '8px 15px',
            backgroundColor: 'white',
            border: '1px solid black'
        }
    });

    var title = ui.Label({
        value: '地表温度 (°C)',
        style: { fontWeight: 'bold', fontSize: '14px', margin: '0 0 4px 0' }
    });
    legend.add(title);

    var palette = LST_VIS.palette;
    var labels = ['20 - 25 (极低)', '25 - 30 (低)', '30 - 35 (中)', '35 - 40 (高)', '40 - 45 (极高)'];

    for (var i = 0; i < palette.length; i++) {
        var colorBox = ui.Label({
            style: {
                backgroundColor: '#' + palette[i],
                padding: '8px',
                margin: '0 0 4px 0'
            }
        });
        var label = ui.Label({
            value: labels[i],
            style: { margin: '0 0 4px 10px', fontSize: '12px' }
        });
        var row = ui.Panel({
            widgets: [colorBox, label],
            layout: ui.Panel.Layout.flow('horizontal')
        });
        legend.add(row);
    }
    return legend;
}

function createNDVILegend() {
    var legend = ui.Panel({
        style: {
            position: 'bottom-right',
            padding: '8px 15px',
            backgroundColor: 'white',
            border: '1px solid black'
        }
    });

    var title = ui.Label({
        value: 'NDVI 指数',
        style: { fontWeight: 'bold', fontSize: '14px', margin: '0 0 4px 0' }
    });
    legend.add(title);

    var palette = NDVI_VIS.palette;
    var min = NDVI_VIS.min;
    var max = NDVI_VIS.max;
    var step = (max - min) / palette.length;

    for (var i = 0; i < palette.length; i++) {
        var start = (min + i * step).toFixed(1);
        var end = (min + (i + 1) * step).toFixed(1);
        var colorBox = ui.Label({
            style: {
                backgroundColor: '#' + palette[i],
                padding: '8px',
                margin: '0 0 4px 0'
            }
        });
        var label = ui.Label({
            value: start + ' - ' + end,
            style: { margin: '0 0 4px 10px', fontSize: '12px' }
        });
        var row = ui.Panel({
            widgets: [colorBox, label],
            layout: ui.Panel.Layout.flow('horizontal')
        });
        legend.add(row);
    }
    return legend;
}

// 全局变量管理图例
var currentLegend = null;

// 修改地图切换控件
var dropdown = ui.Select({
    items: ['选择地图', '地表温度', '植被指数'],
    style: { position: 'top-left' },
    onChange: function (selected) {
        Map.layers().reset();
        // 清除之前的图例和统计面板
        if (currentLegend) {
            Map.remove(currentLegend);
            currentLegend = null;
        }
        if (selected !== '地表温度') {
            Map.remove(lst_stat_panel);
        }

        if (selected === '选择地图') {
            Map.addLayer(AOI.style({ color: '000000', fillColor: '00000000', width: 1 }), {}, "城市边界");
            Map.centerObject(AOI, 9.6);
        } else if (selected === '地表温度') {
            Map.add(lst_stat_panel);
            Map.addLayer(AOI, {}, "城市边界");
            Map.addLayer(lstImage.select('LST'), LST_VIS, '地表温度');
            currentLegend = createLSTLegend();
            Map.add(currentLegend);
        } else if (selected === '植被指数') {
            Map.addLayer(AOI, {}, "城市边界");
            Map.addLayer(ndviImage.select('NDVI'), NDVI_VIS, '植被指数');
            currentLegend = createNDVILegend();
            Map.add(currentLegend);
        }
    }
});

// 初始化地图
Map.add(dropdown);
dropdown.setValue('选择地图');    

4 运行结果

控制台运行结果
LST与NDVI相关性分析
点击选择地图
地表温度图层可视化结果
归一化植被指数图层可视化结果

网站公告

今日签到

点亮在社区的每一天
去签到