GEEer成长日记十三:Landsat_SR计算地表温度时间序列

更多精彩内容请关注微信公众号:GEEer成长日记


  上期我们介绍了Modis_LST产品MODIS/006/MOD11A1的时间序列,因为这款产品是官方已经经过各种矫正和处理的产品,精度较高,且范围广,排除了云雨条件等影响。

  今天我们介绍Landsat_SR影像在LST计算方面的研究~


LANDSAT/LC08/C01/T1_SR

 先看看官方介绍:This dataset is the atmospherically corrected surface reflectance from the Landsat 8 OLI/TIRS sensors. These images contain 5 visible and near-infrared (VNIR) bands and 2 short-wave infrared (SWIR) bands processed to orthorectified surface reflectance, and two thermal infrared (TIR) bands processed to orthorectified brightness temperature

These data have been atmospherically corrected using LaSRC and includes a cloud, shadow, water and snow mask produced using CFMASK, as well as a per-pixel saturation mask.

Strips of collected data are packaged into overlapping "scenes" covering approximately 170km x 183km using a standardized reference grid.

See also the USGS page on SR QA bands.

SR can only be produced for Landsat assets processed to the L1TP level

Data provider notes:

  • Although Surface Reflectance can be processed only from the Operational Land Imager (OLI) bands, SR requires combined OLI/Thermal Infrared Sensor (TIRS) product (LC8) input in order to generate the accompanying cloud mask. Therefore, OLI only (LO8), and TIRS only (LT8) data products cannot be calculated to SR.

  • SR is not run for a scene with a solar zenith angle greater than 76°.

  • Users are cautioned to avoid using SR for data acquired over high latitudes (> 65°).

  • The panchromatic band (ETM+ Band 7, OLI Band 8) is not processed to Surface Reflectance.

  • Efficacy of SR correction will be likely reduced in areas where atmospheric correction is affected by adverse conditions:

    • Hyper-arid or snow-covered regions

    • Low sun angle conditions

    • Coastal regions where land area is small relative to adjacent water

    • Areas with extensive cloud contamination

更多关于地表反射率产品的介绍请参考

https://www.usgs.gov/landsat-missions/landsat-collection-1-surface-reflectance

        分辨率:30m

  我们介绍两种计算时间序列的方法,一种是计算得到FeatureCollection,将Value值的时间序列进行展示。另一种是将时间序列的影像进行月平均,通过月平均影像的统计构建时间序列图表。

  首先第一种,构建FeatureCollection从而得到时间序列。

//还是老样子哈,以广东省为目标
var geometry = ee.FeatureCollection('users/ZhengkunWang/guangdongsheng')
Map.centerObject(geometry,7)
// Define Star year and end year 
var startYr = 2020;
var endYr = 2020; 

// year sequence 
var startDate = ee.Date.fromYMD(startYr,01,01);
var endDate = ee.Date.fromYMD(endYr+1,01,01);
//**NOTE: the end date in .filterDate() is exclusive, so this allows all days in 2019 to be included

// Define the mskL8sr funciton for masking clouds, etc.
function maskL8sr(image) {
  /// Bits 3 and 5 are cloud shadow and cloud, respectively.
  var cloudShadowBitMask = (1 << 3);
  var cloudsBitMask = (1 << 5);
  // Get the pixel QA band.
  var qa = image.select('pixel_qa');
  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
                 .and(qa.bitwiseAnd(cloudsBitMask).eq(0));
  return image.updateMask(mask);
}


// Load the collection 
var l8 = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR");
// Filter the dates
var l8lst = l8.filterDate(startDate, endDate)
              .filterBounds(geometry)
               // To mask clouds and shadows from this collection
               .map(maskL8sr);
               

//** Visualization parameters
var vizParams = {
  bands: ['B6', 'B5', 'B4'],
  min: 0,
  max: 3200,
  gamma: 1.4,
};
Map.addLayer(l8lst.mean().clip(geometry),vizParams,'l8 imagery');
//--------------------------------------

//Projection of Landsat imagery,
//it shows an error if bands of the image don't have all the same
var l8proj = ee.Image(l8lst.first()).projection();
// print('l8proj:', l8proj);


//** Calculate number of months withiin the specified time period
var dateDiff = endDate.difference(startDate,'month');
var noMonths = ee.Number(dateDiff).round().subtract(1);

//** Create list of dates, one for each month in the time period
var allMonths = ee.List.sequence(0,noMonths,1);
var dateList = allMonths.map(function(monthNo){
  return startDate.advance(monthNo,'month');
});
// print(dateList);

//** FUNCTION: for calculating monthly LST values
var calcMonthlyLST = function(date){
  
  //** Filter collection by month
  var start = ee.Date(date);
  var end = start.advance(1,'month');
  var collection = l8lst.filterDate(start,end);
  
  //** Create median composite for that month
  var monthMed = collection.median();
  
  //** Create NDVI and Thermal Band images from composite
  var ndvi = monthMed.normalizedDifference(['B5','B4']);
  var thermalImg = monthMed.select('B10').multiply(0.1);
  
  //*8 Calculate min and max NDVI
  var minNDVI = ee.Number(ndvi.reduceRegion({
  reducer: ee.Reducer.min(),
  geometry: geometry,
  scale: 30,
  maxPixels: 1e13
  }).values().get(0));
  
  var maxNDVI = ee.Number(ndvi.reduceRegion({
  reducer: ee.Reducer.max(),
  geometry: geometry,
  scale: 30,
  maxPixels: 1e13
  }).values().get(0));
  
  //** Fraction of vegetation (use 'if' statement so that where entire image is masked and
  //    minNDVI and maxNDVI are null, produce a null image)
  var fv = ee.Algorithms.If({
    condition: minNDVI && maxNDVI,
    trueCase: ndvi.subtract(minNDVI).divide(maxNDVI.subtract(minNDVI)).rename('FV'),
    falseCase: ee.Image()
  });
  //** Recast to ee.Image object
  fv = ee.Image(fv);

  //** Emissivity (again use 'if' statement for cases of null inputs)
  var a = ee.Number(0.004);
  var b = ee.Number(0.986);
  var EM = ee.Algorithms.If({
    condition: fv.bandNames(),
    trueCase: fv.multiply(a).add(b).rename('EMM'),
    falseCase: ee.Image()
  });
  //** Recast to ee.Image object
  EM = ee.Image(EM);
  
  //** Land surface temperature (again use 'if' statement for cases of null inputs)
  var LST = ee.Algorithms.If({
    condition: EM.bandNames(),
    trueCase: thermalImg.expression(
    '(Tb/(1 + (0.0010895* (Tb / 1.438))*log(Ep)))-273.15', {
      'Tb': thermalImg.select('B10'),
      'Ep': EM.select('EMM')
    }).rename('LST'),
    falseCase: ee.Image().rename('LST')
  });

  //**  Use reduceRegion() to extract per-region value for this month
  var meanVal = ee.Image(LST).reduceRegion({
    reducer: ee.Reducer.mean(),
    geometry: geometry,
    scale: 30,
  maxPixels: 1e13,
    crs: l8proj
  });

  //** Create feature with desired data/properties and empty geometry, for charting by feature
  var ft = ee.Feature(null, {
    'system:time_start': date,
    'date': date.format('YYYY-MM-dd'),
    'value': meanVal.get('LST')
  });
  return ft;
};

//** Create feature collection, one for each month, wherein a property 'status' is
//    added to indicate whether there is an empty collection for that month 
var dateFeats = dateList.map(function(date){
  var thisColl = l8lst.filterDate(ee.Date(date), ee.Date(date).advance(1,'month'));
  return ee.Algorithms.If({
    condition: thisColl.first(),
    trueCase: ee.Feature(null, {'date':date, 'status':1}),
    falseCase: ee.Feature(null, {'date':date, 'status':0})
  });
});
dateFeats = ee.FeatureCollection(dateFeats);
// print('dateFeats:', dateFeats);

//** Map over date features and create per-month/year mean LST composites
var perYrMonthlyLST = dateFeats.map(function(feature){
  var startDate = ee.Date(feature.get('date'));
  
  //** If month represented by this feature has imagery for it,
  //    calculate per-monnth LST; otherwise set LST to 0 (can't be 'null' for charting)
  var outFeat = ee.Algorithms.If({
    condition: ee.Number(feature.get('status')).eq(1),
    trueCase: ee.Feature(calcMonthlyLST(startDate)),
    falseCase: ee.Feature(null, {
      'system:time_start': startDate.millis(),
      'date': startDate,
      'value': 0
    })
  });
  return outFeat;
});
perYrMonthlyLST = ee.FeatureCollection(perYrMonthlyLST);
print('perYrMonthlyLST',perYrMonthlyLST);

//** Create new graph for monthly temperatures over multiple years
var multiYrGraph = ui.Chart.feature.byFeature({
  features:perYrMonthlyLST,
  xProperty:'system:time_start',
  yProperties: 'value'});

//** Print graph to console
print(multiYrGraph.setChartType("ColumnChart")
          .setOptions({vAxis: {title: 'LST [deg. C]'},
                        hAxis: {title: 'Date'}}));

计算地表温度的方法步骤:

  这篇文章对此介绍的很详细,大家可以去好好研读。


  第二种则是通过生成月均值影像,通过统计的方法计算得到地表温度时间序列。我们计算了2016-2020五年的月均值进行分析。

// 具体计算LST的流程和上述步骤一样,就不过多介绍了
// 这边主要介绍一下月均值影像的生成和时间序列的计算
var years = ee.List.sequence(2016, 2020);
var months = ee.List.sequence(1, 12);
var monthlyLST =  ee.ImageCollection.fromImages(
  years.map(function (y) {
    return months.map(function(m) {
    return LST.filter(ee.Filter.calendarRange(y,y, 'year')).filter(ee.Filter.calendarRange(m, m, 'month')).mean().set('year', y).set('month', m).set('system:time_start', ee.Date.fromYMD(y, m, 1))
    .set('system:index',y+m);
    });
  }).flatten()
);
print(monthlyLST)
var monthlychart = ui.Chart.image.series(monthlyLST.select('LST'), geometry,ee.Reducer.mean(),500)
              .setChartType('LineChart').setOptions({
                interpolateNulls: true,
                title: 'LST monthly time series',
                hAxis: {title: 'Date'},
                vAxis: {title: 'LST',viewWindowMode: 'explicit', gridlines: {count: 10,}},
                trendlines: { 0: {title: 'LST_trend',type:'linear', showR2: true,  color:'red', visibleInLegend: true}}});
// Display.
print(monthlychart);
Map.addLayer(monthlyLST.select('LST'),{min: -30, max: 32, palette: ['white','blue','green','yellow' ,'red']},'LST_Monthly');

  本期我们介绍了两种地表温度的时间序列。第一种方法适用于只得到图表,不下载影像,而第二种方法则可以加入下载影像的代码,边生成时间序列边下载影像分析。

  获取第一种方法的代码请在公众号回复:010401 ;

  获取第二种方法的代码请在公众号回复:010402。

  如果真的可以帮到你,记得给小编点个赞哦~

  

参考博客:

  官方论坛资深用户Jen Hird

 

  • 7
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值