TransWikia.com

Google Earth Engine: Black Landsat 8 Image to corresponding samples

Geographic Information Systems Asked by Luc Schmid on November 28, 2020

I am very new to the GEE. I’m trying to create reference labels for samples interpretation. When I try to display the corresponding Landsat images for the sample units, all Landsat images would just be black.
Following the script description and the script. URL link at the end. Is someone able to help?

/* Sample interpretation tool for determining reference labels for
a sample derived from a mapped dataset. The sample must have Landsat
time series information in its metadata, which can be generated with
‘Save Feature Timeseries’ tool. Each unique sample location much have
an identifier, such as ‘ID’. */

var years = ['2004','2005','2006','2007','2008','2009','2010','2011','2012','2013','2014','2015','2016','2017','2018','2019','2020']

var changeTypes = [
  'Change Type', // The first value is a placeholder
  'None',
  'Water',
  'Mining Site',
  'Infrastructure',
  'Agriculture',
  'Forest undisturbed',
  'Forest disturbed',
  'Marsh',
]
 
// Unique sample identifier
var sampleIdentifier = 'ID'
 
// Global variables
var latlon, sampleData, pointList;
var IMAGEADDED = false
 
// Define start and end to the time series in a parameter Dictionary.
var start = '2004-01-01'
var end = '2020-01-01'

var params = ee.Dictionary(
  {
    'start': start,
    'end': end,
  }
)

var utils = require('users/parevalo_bu/gee-ccdc-tools:ccdcUtilities/inputs.js')

var allLandsat = utils.getLandsat(
  {
    start: start, 
    end: end,
    targetBands: ['SWIR1','NIR','RED','GREEN','BLUE','SWIR2','NDFI']
  }
)


var visLabels = {
  fontWeight: 'bold', 
  fontSize: '14px', 
  width: '260px',
  padding: '0px 0px 0px 0px',
  border: '2px solid black',
  color: 'white',
  backgroundColor: 'black',
  textAlign: 'center'
  }

var refresh_layers = function(point) {
  // Refresh map at a sample location

  Map.layers().reset();
 
  var select_style = {color: 'FF0000',pointRadius: 4}; 
  Map.centerObject(point.geometry(),14);

  var pointOutline = ee.Image().byte().paint(
    {
      featureCollection: ee.FeatureCollection(point),
      color: 1,
      width: 4
    }
   )
 
   Map.addLayer(pointOutline, {palette: 'red'}, 'pixel')

   Map.setOptions('SATELLITE');
};

var getImageRegion = function(region, date) {
  
  var col = allLandsat.filterBounds(region)

  var imDate = ee.Date(date)
  var befDate = imDate.advance(-1, 'day')
  var aftDate = imDate.advance(1, 'day')

  var selectedImage = col.filterDate(befDate, aftDate).first()
  
  messages.add(loadLabel)  
  
  IMAGEADDED = true 
  var pointOutline = ee.Image().byte().paint(
    {
      featureCollection: ee.FeatureCollection(cur_point),
      color: 1,
      width: 4
    }
  );
  
  selectedImage.get('system:index').evaluate(
    function(obj) {
      Map.layers()
        .set(
          0, 
          ui.Map.Layer(ee.Image(selectedImage).unmask(), 
            visParams, 
            obj), 
          obj);
      Map.addLayer(
        pointOutline, 
        {palette: 'red'}, 
        'pixel'
      );
      messages.clear()
      messages.add(thumbsUp)
    }
  )
  
  return selectedImage
}



var makeSinglePlot = function(x, y, bandName, position, ymin, ymax, region){
  // Make time series plot with y axis based on data min and max

  var yminNew = ee.Number(ee.List(y).reduce(ee.Reducer.min()))
  var ymaxNew = ee.Number(ee.List(y).reduce(ee.Reducer.max()))

  var chart = ui.Chart.array.values(y, 0, x)
    .setSeriesNames([bandName])
    .setOptions({
      title: bandName,
      hAxis: {'title': 'year'},
      vAxis: {'title': bandName, 
        viewWindow: {
          min: yminNew, 
          max: ymaxNew
        }
      },
      pointSize: 4,
      lineWidth: 0
    })
                    
  chart.onClick(function(coords) {
    getImageRegion(
      ee.Feature(region).geometry(), 
      coords)
  });
  panel.add(chart)
}

var makeImagePlot = function(iCol, region, point, bandName, position){
  // Make time series plot from image collection

  var yminNew = ee.Image(iCol.min())
                  .reduceRegion({
                    reducer: ee.Reducer.mean(),
                    geometry: region,
                    scale: 30
                  })
  var ymaxNew = ee.Image(iCol.max())
                  .reduceRegion({
                    reducer: ee.Reducer.mean(),
                    geometry: region,
                    scale: 30
                  })
  
  var chart = ui.Chart.image.series(
    ee.ImageCollection(iCol).select(bandName), 
    region, 
    ee.Reducer.mean(), 
    30
  )
  .setOptions({
    title: bandName,
    vAxis: {'title': bandName},
    lineWidth: 0,
    pointSize: 6,
   });
                 
  chart.onClick(function(coords) {
    getImageRegion(
      ee.Feature(point).geometry(), 
      coords
    )
  });

  panel.add(chart); 
  
}

var makePlots = function(sampleID, point){
  // Function to make time series plots from saved results
                                                      
  var sampleDates = sampleID.aggregate_array('Date')
  var sampleNDFI = sampleID.aggregate_array('NDFI')

  var sampleRed = sampleID.aggregate_array('Red')
  var sampleNIR = sampleID.aggregate_array('NIR')
  var sampleSWIR1 = sampleID.aggregate_array('SWIR1')
  panel.clear()
  panel.add(select_stretch)
  panel.add(resetButton)

  makeSinglePlot(sampleDates, sampleNDFI, 'NDFI',10, 0, 2000, point)

  makeSinglePlot(sampleDates, sampleRed, 'Red',11, 0, 2000, point)
  makeSinglePlot(sampleDates, sampleNIR, 'NIR', 12, 0, 3000, point)
  makeSinglePlot(sampleDates, sampleSWIR1, 'SWIR1', 13, 0, 2000, point)

}


var addSubtractID = function(button, increment, cur_points) {
  // Zooms to the current point based on next and previous buttons

  var collectionLength = cur_points.size();

  selectedIndex = selectedIndex + increment

  if (selectedIndex === 0) selectedIndex = pointTotal;
  if (selectedIndex > (pointTotal)) selectedIndex = 1;

  text_in.setValue(selectedIndex)
};


var setZoom_abs = function(cur_val,cur_points) {
  // Zooms to current point based on drop box selection

  var collectionLength = cur_points.size();

  selectedIndex = parseInt(cur_val)
  cur_point = ee.Feature(
                    ee.FeatureCollection(cur_points.filterMetadata('ID', 'equals', selectedIndex))
                      .toList(1).get(0))

  cur_point = cur_point.buffer(14).bounds()
  if (dataButton.getValue()) {
    var curPointData = sampleData.filterMetadata('ID','equals',selectedIndex).sort('Date')

    refresh_layers(cur_point);
    makePlots(curPointData,cur_point)
  }  else {
    refresh_layers(cur_point);
    notSaved(cur_point)
  }
};


var notSaved = function(pgeo){
  // Load a time series for a sample point that is not saved

  panel.clear()
  panel.widgets().set(2, resetButton)
  panel.widgets().set(3, select_stretch)
  var coords = ee.List(pgeo.geometry().coordinates().get(0)).get(0)
    .evaluate(function(coords) {
      var lat = coords[1]
      var lon = coords[0]
      var latlon = ui.Label('Lat, Lon: ' + lat + ', ' + lon)
      panel.add(latlon)
    })

  var landsatData = allLandsat.filterBounds(pgeo.geometry())

  // Add a red dot to the map where the user clicked.
  var pointOutline = ee.Image().byte().paint(
    {
      featureCollection: ee.FeatureCollection(pgeo),
      color: 1,
      width: 4
    }
  );
  Map.addLayer(pointOutline, {palette: 'red'}, 'pixel');
  makeImagePlot(landsatData,pgeo, pgeo, 'NDFI', 4)
  makeImagePlot(landsatData,pgeo, pgeo, 'RED', 4)
  makeImagePlot(landsatData,pgeo, pgeo, 'NIR', 4)
  makeImagePlot(landsatData,pgeo, pgeo, 'SWIR1', 4)


}


// Load data button
var dataButton = ui.Checkbox(
  'Load data from feature collection', 
  true
);

// Stretch button
var stretch_321 = {
  bands: ['RED', 'GREEN', 'BLUE'], 
  min: 0, 
  max: 1400
};

var stretch_543 = {
  bands: ['SWIR1', 'NIR', 'RED'], 
  min: 0, 
  max: 7000
};

var stretches = {
  Stretch_321: stretch_321,
  Stretch_543: stretch_543
};
  
var select_stretch = ui.Select({
    items: Object.keys(stretches),
    onChange: function(key) {
      visParams = stretches[key];
    }
  });
  
select_stretch.setPlaceholder('Select Stretch');

// Reset button
var resetButton = ui.Button({
  label: 'Reset Map Layers',
  onClick: function() {
    Map.layers().reset();
    Map.setOptions('SATELLITE');
    var pointOutline = ee.Image().byte().paint({
      featureCollection: ee.FeatureCollection(cur_point),
      color: 1,
      width: 4
    });
    Map.addLayer(pointOutline, {palette: 'red'}, 'pixel');
   }
});
  
// Panel to hold it  
var panel = ui.Panel({style: {width: '400px'}})
  .add(dataButton)

// Feature information panel 
var inspector = ui.Panel({style: {shown: false, width: '200px'}});
inspector.style().set({position: 'bottom-left'});
Map.add(inspector);

// Message box
// Feature information panel 
var messages = ui.Panel({style: {shown: true}});
var loadLabel = ui.Label('Thinking...')
var thumbsUp = ui.Label('?')

var saveErr1 = ui.Label('Please specify confidence!')
var saveErr2 = ui.Label('Please specify land cover!')
var saveErr3 = ui.Label('Please specify year!')
var saveErr4 = ui.Label('Somethings wrong!')

messages.style().set({position: 'bottom-right'});
messages.add(loadLabel)
Map.add(messages);

// search and change feature
var text_in = new ui.Textbox('Search ID');
text_in.style().set({width: '80px',margin: '2px'});

// Sets up next and previous buttons used to navigate through previews of the
// images in the collection.
var prevButton = new ui.Button('Previous', null, false, {margin: '0 auto 0 0'});
var nextButton = new ui.Button('Next', null, false, {margin: '0 0 0 auto'});
var buttonPanel = new ui.Panel(
    [prevButton, text_in, nextButton],
    ui.Panel.Layout.Flow('horizontal'));
    
    
// Buttons for interpretation
var lcSelector = ui.Select(
  [
   'Land Cover',
   'Forest',
   'NonForest',
   'Change'
  ], 
  'Land Cover', 
  null)
  
var yearSelector = ui.Select(years, 'Year', null)
var confidenceSelector = ui.Select(['1','2','3'],'Confidence?')
// var lcSelector = ui.Select(['Land Cover','Forest','NonForest'], 'Land Cover', null)
var distSelector = ui.Select(
  [
    'Change Type',
    'Stable',
    'Change',
    'Deforestation',
    'Degradation',
    'Other'
  ], 
  'Change Type', 
  null)


var changeTypeSelector = ui.Select(
  changeTypes, 
  'Change Type', 
  'None'
)
  


// Function for saving
var saveFunction = function(button) {
  messages.clear()
  // Check all the dropdowns
  // if (!confidenceSelector.getValue()) {
  //   messages.add(saveErr1)
  //   return
  // }
  
  // if (!lcSelector.getValue()) {
  //   messages.add(saveErr2)
  //   return
  // }

  var lcValue = lcSelector.getValue()
  var changeValue = distSelector.getValue()
  var typeValue = changeTypeSelector.getValue()
  
  var refValue = 0
  var refDistType = 0

  if (lcValue == 'Forest'){
    refValue = 1
    distSelector.setValue('Stable')

  } else if (lcValue == 'NonForest') {
    refValue = 2
    distSelector.setValue('Stable')

  } else if (changeValue == 'Degradation') {
    refValue = 3
    refDistType = typeValue
  } else if (changeValue == 'Deforestation') {
    refValue = 4
    refDistType = typeValue
  } else if (changeValue == 'Other') {
    refValue = 5
    refDistType = typeValue
  } else {
    messages.add(saveErr4)
    return
  }

  var geo = cur_point.geometry()
  var coords = ee.List(geo.coordinates()).get(0).getInfo()
  var lat = coords[0][1]
  var lon = coords[0][0]

  var params = {
    reference: refValue,
    refDistType: refDistType,
    year: yearSelector.getValue(),
    ID: selectedIndex,
    latitude: lat,
    longitude: lon,
    notes: notes.getValue(),
    confidence: confidenceSelector.getValue()
  }
  var newPointName = saveFolder.getValue() + '/sample_' + selectedIndex

  try {
    ee.data.copyAsset(
      'users/bullocke/assessmentExamples/emptyAsset',
      newPointName, 
      false
    )
    ee.data.setAssetProperties(
      newPointName,
      params
    )
    print('Sample ' + selectedIndex + ' saved')
  }
  catch(err) {
    messages.clear()
    messages.add(ui.Label('Sample already exists!'))
  }


  yearSelector.setValue(null)
  lcSelector.setValue(null)
  confidenceSelector.setValue(null)
  notes.setValue('Any notes?')
  addSubtractID(button, 1, sampleData)
  changeTypeSelector.setValue('None')
  distSelector.setValue('Change Type')

}

/**
 * Save all the assets into one feature collection
*/ 
var exportAllFunc = function(widg) {

  var samples = ee.data.getList({'id': saveFolder.getValue()})

  var outList = []
    
  for (var i = 0; i< samples.length; i++) {
    var newFc = ee.FeatureCollection(samples[i]['id'])
    var newFeat = ee.Feature(newFc.first())
      .setGeometry(
        ee.Geometry.Point(
          [
            newFc.get('longitude'), 
            newFc.get('latitude')
          ]
        )
      )
      .copyProperties(newFc)
      .set(
        'refDistType',
        ee.String(newFc.get('refDistType'))
      )
    outList.push(newFeat)
  }
  
  var today = new Date();
  var dd = String(today.getDate())
  var mm = String(today.getMonth() + 1)
  var yyyy = today.getFullYear();
  
  today = mm + '_' + dd + '_' + yyyy;
  
  var user = ee.data.getAssetRoots()[0].id.split('/')[1]
  var outName = user + '_' + today
  var outFC = ee.FeatureCollection(outList)
  Export.table.toAsset(ee.FeatureCollection(outList), outName)
}


var sampleBox = ui.Textbox({placeholder: 'users/Luc_Schmid/0411_stratified_random_sample', 
  value: 'users/Luc_Schmid/0411_stratified_random_sample',
  onChange: function(text, widg) {
    sampleData = ee.FeatureCollection(text)
  }
})

var notes = ui.Textbox('Any notes?',null)

sampleData = ee.FeatureCollection(sampleBox.getValue())

var saveButton = ui.Button('Save',saveFunction)
  
var lcPanel = ui.Panel(
  [
    lcSelector, 
    yearSelector
  ],
  ui.Panel.Layout.Flow('horizontal')
)
  
var distPanel = ui.Panel(
  [
    distSelector, 
    changeTypeSelector
  ],
  ui.Panel.Layout.Flow('horizontal')
)  

var exportAll = ui.Button(
  'Export All',
  exportAllFunc
)  
  
var savePanel = ui.Panel(
  [
    saveButton,
    exportAll
  ],
  ui.Panel.Layout.Flow('horizontal'))
  
var saveFolder = ui.Textbox(
  {
    placeholder: 'Path to folder to save results',
    value: 'users/Luc_Schmid/timeseries'
  }
)

var samplePanel = ui.Panel(
  [
    ui.Label('Path to FC:'), 
    sampleBox
  ],
  ui.Panel.Layout.Flow('horizontal')
)    

var folderPanel = ui.Panel(
  [
    ui.Label('Save Folder:'), 
    saveFolder
  ],
  ui.Panel.Layout.Flow('horizontal')
)    

var notesConfPanel = ui.Panel(
  [
    notes, 
    confidenceSelector
  ],
  ui.Panel.Layout.Flow('horizontal')
)

var sectionBreak1 = ui.Label(
  'Input and Outputs', 
  visLabels
)

var sectionBreak2 = ui.Label(
  'Sample Interpretation', 
  visLabels
)

var sectionBreak3 = ui.Label(
  'Save', 
  visLabels
)

// Previous next and search pannel
var mainPanel = ui.Panel({
  widgets: 
    [
      sectionBreak1, samplePanel, folderPanel, 
      sectionBreak2, buttonPanel, lcPanel, notesConfPanel,
      distPanel, sectionBreak3, savePanel
    ],
  style: 
    {
      position: 'bottom-left', 
      width: '280px', 
      stretch: 'vertical'
    }
});


// Set up display
Map.style().set('cursor', 'crosshair');
Map.setOptions('SATELLITE');
Map.add(mainPanel);

// Set up the next and previous buttons.
prevButton.onClick(
  function(button) { 
    addSubtractID(
      button, 
      -1, 
      sampleData
    ); 
  }
);

nextButton.onClick(
  function(button) { 
    addSubtractID(
      button, 
      1, 
      sampleData
    ); 
  }
);

text_in.onChange(function(val) {
  setZoom_abs(
    val,
    sampleData); 
});

// Add the panel to the ui.root.
ui.root.add(panel);





// Variables
var selectedIndex = 0;
var selectedID = 0
var visParams = {bands: ['RED', 'GREEN', 'BLUE'], min: 0, max: 1400};
var cur_point = '';
var pointTotal = 0

ee.List(sampleData.aggregate_array('ID'))
  .distinct()
  .evaluate(function(obj) {
    pointList = []
    for (var i=0; i<obj.length; i++) {
      pointList.push(obj[i])
      pointTotal = pointTotal + 1
    }
    messages.clear()
    messages.add(thumbsUp)
  })

Here is the corresponding script: https://code.earthengine.google.com/?accept_repo=users%2Fbullocke%2Fcoded&scriptPath=users%2FLuc_Schmid%2FTestTraining%3A0411_Interpretation

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP