GEE笔记:多日期滑动组件


前言

最近在进行土地覆被变化验证的相关研究,看到了Cohen等人为LandTrendr开发的 基于Landsat时间序列影像的验证工具:TimeSync。为了满足自己的需要(好像TimeSync在GEE上使用还要先将影像下载到本地???),本菜鸡参考大神们的代码,基于GEE平台弄了一个显示Landsat系列可以进行目视解译验证的工具(萌新求轻喷)。


一、GEE官方的日期滑动组件代码

代码如下(原文链接:https://developers.google.com/earth-engine/guides/ui_widgets)

// Use a DateSlider to create annual composites of this collection.
var collection = ee.ImageCollection('LANDSAT/LC08/C01/T1');
// Use the start of the collection and now to bound the slider.
var start = ee.Image(collection.first()).date().get('year').format();
var now = Date.now();
var end = ee.Date(now).format();

// Run this function on a change of the dateSlider.
var showMosaic = function(range) {
  var mosaic = ee.Algorithms.Landsat.simpleComposite({
    collection: collection.filterDate(range.start(), range.end())
  });
  // Asynchronously compute the name of the composite.  Display it.
  range.start().get('year').evaluate(function(name) {
    var visParams = {bands: ['B4', 'B3', 'B2'], max: 100};
    var layer = ui.Map.Layer(mosaic, visParams, name + ' composite');
    Map.layers().set(0, layer);
  });
};

// Asynchronously compute the date range and show the slider.
var dateRange = ee.DateRange(start, end).evaluate(function(range) {
  var dateSlider = ui.DateSlider({
    start: range['dates'][0],
    end: range['dates'][1],
    value: null,
    period: 365,
    onChange: showMosaic
  });
  Map.add(dateSlider.setValue(now));
});

二、多日期滑动组件

代码如下(示例):

代码看起来很长主要分为两部分:

  1. 对Landsat SR影像的一些预处理(云掩膜、波段计算等等)
  2. 通过日期滑动组件分别展示研究区的Lansat-5,7,8年度中值合成影像
var roi = ee.FeatureCollection("xxx");

//######################################################################################
//#                                   Preparing                                      #\\
//######################################################################################

//1.-------------------------------------------------------------------
// Define function to get and rename bands of interest from ETM+.
var renameETM =function(img) {
  return img.select(
		['B1', 'B2', 'B3', 'B4', 'B5', 'B7', 'pixel_qa', 'radsat_qa'],
		['B1', 'B2', 'B3', 'B4', 'B5', 'B7', 'pixel_qa', 'radsat_qa']
  );
};

// Define function to get and rename bands of interest from OLI.
var renameOLI = function(img) {
  return img.select(
    ['B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'pixel_qa'],
    ['B1', 'B2', 'B3', 'B4', 'B5', 'B7', 'pixel_qa']
    );
};

//2.-------------------------------------------------------------------.
//cloud mask------------------------------------------------
var cloudMaskL457 = function(image) {
  var qa = image.select('pixel_qa');
  // If the cloud bit (5) is set and the cloud confidence (7) is high
  // or the cloud shadow bit is set (3), then it's a bad pixel.
  var cloud = qa.bitwiseAnd(1 << 5)
          .and(qa.bitwiseAnd(1 << 7))
          .or(qa.bitwiseAnd(1 << 3))
  // Remove edge pixels that don't occur in all bands
  var mask2 = image.mask().reduce(ee.Reducer.min());
  var maskObersaturation = image.select('radsat_qa').eq(0)
  return image.updateMask(cloud.not()).updateMask(mask2.and(maskObersaturation));
};

var maskL8sr = function(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 the masked image, scaled to reflectance, without the QA bands.
  return image.updateMask(mask);
}

//3.-------------------------------------------------------------------
//Add bands--------------------------------------------------
var addbands = function(img) {
  var ndvi = img.normalizedDifference(["B4", "B3"]).rename(["NDVI"]);
  var img1 = img.addBands(ndvi)
                .set('system:time_start', img.get('system:time_start'));
  return img1;
};

//4.-------------------------------------------------------------------
//divide-----------------------------------------------------
var divide = function(img){
      img = img.select('B1', 'B2', 'B3', 'B4', 'B5','B7')
               .divide(10000)
               .set('system:time_start', img.get('system:time_start'));
  return img;
};

//5.-------------------------------------------------------------------
// Define function to prepare OLI images.
var prepOLI = function(img) {
  var orig = img;
  img = renameOLI(img);
  img = maskL8sr(img);
  img = divide(img);
  img = addbands(img);
  return ee.Image(img.copyProperties(orig, orig.propertyNames()));
}

// Define function to prepare ETM+ images.
var prepETM = function(img) {
  var orig = img;
  img = renameETM(img);
  img = cloudMaskL457(img);
  //img = etm2oli(img);
  img = divide(img);
  img = addbands(img);
  return ee.Image(img.copyProperties(orig, orig.propertyNames()));
}

//6.-------------------------------------------------------------------
var visParams = {
  bands: ['B3', 'B2', 'B1'],
  min: 0,
  max: 0.3,
  gamma: 1.4,
};

Map.centerObject(roi, 9);

var sidePanel = ui.Panel();

//######################################################################################
//#                                    L5 part                                       #\\
//######################################################################################

var L5 = ee.ImageCollection("LANDSAT/LT05/C01/T1_SR");

var start_1 = "1986-1-1";
var end_1 = "2011-12-31";

var showImage_1 = function(range){
  print("---L5", range);
  var colFilter = ee.Filter.and(
    ee.Filter.bounds(roi),
    ee.Filter.date(range.start(), range.end()),
    //ee.Filter.lt('CLOUD_COVER', 50),
    ee.Filter.lt('GEOMETRIC_RMSE_MODEL', 30),
    ee.Filter.or(
      ee.Filter.eq('IMAGE_QUALITY', 9),
      ee.Filter.eq('IMAGE_QUALITY', 7)
      )
      );
      
  // Filter collections and prepare them for merging.
  var col_L5 = L5.filter(colFilter).map(prepETM).map(function(image){return image.clip(roi)});
  var imgL5_med = col_L5.reduce(ee.Reducer.median())
  .select(
    ['B1_median', 'B2_median', 'B3_median', 'B4_median','B5_median','B7_median', 'NDVI_median'],
    ['B1', 'B2', 'B3', 'B4', 'B5','B7', 'NDVI']);
  
  range.start().get('year').evaluate(function(name) {
    var layer_1 = ui.Map.Layer(imgL5_med, visParams, name + ' Landsat 5 composite');
    Map.layers().set(0, layer_1);
  });
};

showImage_1(ee.DateRange(start_1, ee.Date(start_1).advance(1, "year")));

ee.DateRange(start_1, end_1).evaluate(function(range) {
  print("+++L5",range);
  var dateSlider = ui.DateSlider({
    start: range['dates'][0],
    end: range['dates'][1],
    value: start_1,
    period: 365,
    onChange: showImage_1,
    style: {
      width: "500px",
      padding: "2px"
    }
  });
  var main_panel_1 = ui.Panel({
    widgets: [
      ui.Label('Landsat 5 compsites 1986-2011', {fontWeight: 'bold'}),
      dateSlider
      ],
    style: {
      width: "520px",
      padding: "4px"
    }
  });
  sidePanel.add(main_panel_1);
});

//######################################################################################
//#                                    L7 part                                       #\\
//######################################################################################

var L7 = ee.ImageCollection("LANDSAT/LE07/C01/T1_SR");

var start_2 = "1999-1-1";
var end_2 = "2019-12-31";

var showImage_2 = function(range){
  print("---L7", range);
  var colFilter_2 = ee.Filter.and(
    ee.Filter.bounds(roi),
    ee.Filter.date(range.start(), range.end()),
    //ee.Filter.lt('CLOUD_COVER', 50),
    ee.Filter.lt('GEOMETRIC_RMSE_MODEL', 30),
    ee.Filter.or(
      ee.Filter.eq('IMAGE_QUALITY', 9),
      ee.Filter.eq('IMAGE_QUALITY', 7)
      )
      );
      
  // Filter collections and prepare them for merging.
  var col_L7 = L7.filter(colFilter_2).map(prepETM).map(function(image){return image.clip(roi)});
  var imgL7_med = col_L7.reduce(ee.Reducer.median())
  .select(
    ['B1_median', 'B2_median', 'B3_median', 'B4_median','B5_median','B7_median', 'NDVI_median'],
     ['B1', 'B2', 'B3', 'B4', 'B5','B7', 'NDVI']);
  
  range.start().get('year').evaluate(function(name) {
    var layer_2 = ui.Map.Layer(imgL7_med, visParams, name + ' Landsat 7 composite');
    Map.layers().set(1, layer_2);
  });
};

showImage_2(ee.DateRange(start_2, ee.Date(start_2).advance(1, "year")));

ee.DateRange(start_2, end_2).evaluate(function(range) {
  print("+++L7",range);
  var dateSlider = ui.DateSlider({
    start: range['dates'][0],
    end: range['dates'][1],
    value: start_2,
    period: 365,
    onChange: showImage_2,
    style: {
      width: "500px",
      padding: "2px"
    }
  });
  var main_panel_2 = ui.Panel({
    widgets: [
      ui.Label('Landsat 7 compsites 2013-2019', {fontWeight: 'bold'}),
      dateSlider
      ],
    style: {
      width: "520px",
      padding: "4px"
    }
  });
  sidePanel.add(main_panel_2);
});

//######################################################################################
//#                                    L8 part                                       #\\
//######################################################################################

var L8 = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR");

var start_3 = "2013-1-1";
var end_3 = "2019-12-31";

var showImage_3 = function(range){
  print("---L8", range);
  var colFilter = ee.Filter.and(
    ee.Filter.bounds(roi),
    ee.Filter.date(range.start(), range.end()),
    //ee.Filter.lt('CLOUD_COVER', 50),
    ee.Filter.lt('GEOMETRIC_RMSE_MODEL', 30),
    ee.Filter.or(
      ee.Filter.eq('IMAGE_QUALITY', 9),
      ee.Filter.eq('IMAGE_QUALITY_OLI', 9)
      )
      );
      
  // Filter collections and prepare them for merging.
  var col_L8 = L8.filter(colFilter).map(prepOLI).map(function(image){return image.clip(roi)});
  var imgL8_med = col_L8.reduce(ee.Reducer.median())
  .select(
    ['B1_median', 'B2_median', 'B3_median', 'B4_median','B5_median','B7_median', 'NDVI_median', ],
    ['B1', 'B2', 'B3', 'B4', 'B5','B7', 'NDVI']);
  
  range.start().get('year').evaluate(function(name) {
    var layer_3 = ui.Map.Layer(imgL8_med, visParams, name + ' Landsat 8 composite');
    Map.layers().set(2, layer_3);
  });
};

showImage_3(ee.DateRange(start_3, ee.Date(start_3).advance(1, "year")));

ee.DateRange(start_3, end_3).evaluate(function(range) {
  print("+++L8",range);
  var dateSlider = ui.DateSlider({
    start: range['dates'][0],
    end: range['dates'][1],
    value: start_3,
    period: 365,
    onChange: showImage_3,
    style: {
      width: "300px",
      padding: "2px"
    }
  });
  var main_panel_3 = ui.Panel({
    widgets: [
      ui.Label('Landsat 8 compsites 2013-2019', {fontWeight: 'bold'}),
      dateSlider
      ],
    layout: "flow",
    style: {
      width: "520px",
      padding: "4px"
    }
  });
  sidePanel.add(main_panel_3);
});

ui.root.add(sidePanel);

最终的效果图:
在这里插入图片描述


总结

  1. 通过这个组件可以很方便的利用Landsat时间序列影像进行目视解译验证,未来希望可以加上验证点的某参数时间序列折线图(比如在GEE中导入一个FeatureCollection, 通过点击某个点就可以显示时间序列NDVI折线图)。

  2. 不知道大家除了TimeSync和GE之外还知道其他可以利用时间序列遥感影像验证的工具嘛?

最后,希望大家能够多与我交流指出错误,我会虚心接受!!!

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值