4

I have a code which is calculating NDVI for Sentinel data and creating DateSlider for this image collection for selected study area. Is there a way to filter and visualize in DataSlider only the dates when Sentinel images available?

https://code.earthengine.google.com/910fdca59ff1a98c9b27cd997d110401

1
  • 1
    I think you're out of luck. I don't see anything in the ui.DateSlider API that would allow for disabling specific dates. Commented Mar 18, 2020 at 15:42

1 Answer 1

3

DateSlider does indeed not have that functionality. Maybe a `ui.Select' suites your needs? That will only contain of the dates actually available:

var allDates = ee.List(sentinel_dataset.aggregate_array('system:time_start'));
var allDatesFormatted = allDates.map(function(date){
        return ee.Date(date).format('YYYY-MM-dd')
    }).distinct();


// UI widgets needs client-side data. evaluate()
// to get client-side values
allDatesFormatted.evaluate(renderSlider) 

function renderSlider(dates) {
  var selector = ui.Select({
                  items: dates, 
                  placeholder: 'Select a Date', 
                  value: dates[0], 
                  onChange: renderDateRange,
  });
  Map.add(selector);
}

function renderDateRange(date) {
  var image = collection
    .filterDate(ee.Date(date), ee.Date(date).advance(1, 'day'))
    .median()

  var vis = {min: 0, max: 1, palette: [
    'FFFFFF', 'CE7E45', 'FCD163', '66A000', '207401',
    '056201', '004C00', '023B01', '012E01', '011301'
  ]}  
  var layer = ui.Map.Layer(image, vis, 'NDVI')
  Map.layers().reset([layer])
}

Link to this code

On the other hand, you might want to used the nice visual slide functionality, but always want to return an image. You could set the dateslider range at one day, and force the output to always add the image with the date closest to the user-defined date.

var collection = sentinel_dataset.map(function(image) {
  return image.select().addBands(image.normalizedDifference(['B8', 'B4'])).rename('NDVI')
  // set dates to simple date 
     .set('system:time_start', 
          ee.Date(ee.Date(image.date()).format('YYYY-MM-dd')).millis())
});

var allDates = ee.List(sentinel_dataset.aggregate_array('system:time_start'));
var allDatesSimple = allDates.map(function(date){
    // make a simple date, transform to millis to get similar dateNumbers per day
  return ee.Date(ee.Date(date).format('YYYY-MM-dd')).millis();
}).distinct();

// UI widgets needs client-side data. evaluate()
// to get client-side values of start and end period
ee.Dictionary({start: Start_period, end: End_period})
  .evaluate(renderSlider) 

function renderSlider(dates) {
  var slider = ui.DateSlider({
    start: dates.start.value, 
    end: dates.end.value, 
    period: 1, // Every 1 day
    onChange: renderDateRange
  })
  Map.add(slider)
}

function renderDateRange(dateRange) {

  // change date to the nearest available date
  var diff = allDatesSimple.map(function(dateNumber){
    return ee.Date(dateNumber).difference(dateRange.start(), 'hour').abs();
  });
  var hourDiff = diff.sort().getNumber(0).add(1);
         // add one hour to work around empty date ranges

  var image = collection
    .filterDate(dateRange.start().advance(hourDiff.multiply(-1), 'hour'), 
                dateRange.start().advance(hourDiff, 'hour'))
    .median()

  var vis = {min: 0, max: 1, palette: [
    'FFFFFF', 'CE7E45', 'FCD163', '66A000', '207401',
    '056201', '004C00', '023B01', '012E01', '011301'
  ]}  
  var layer = ui.Map.Layer(image, vis, 'NDVI')
  Map.layers().reset([layer])
}

link to this code

2
  • Thanks for the suggestions! Is there a way to edit the position of ui.Select? Commented Mar 24, 2020 at 11:37
  • Check the style documentation
    – Kuik
    Commented Mar 24, 2020 at 19:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.