2

I want to calculate a area of NDWI for a region for each month over for 10 years in Google earth engine. I have a starting date and Ending date array for every month for each year.Using Image collection function I need calculate NDWI and its area for the image availability month and add it in a array. If image not available for a month then add zero in the array and so on.

Here is the Link for my code: https://code.earthengine.google.com/322b02e03dffed8d02327eef3474c1d9

function comps(yearArray, SD, ED) {
  var collection = [];
  for (var idx = 0; idx < SD.length; idx++) {
    var year = SD[idx].split('-')[0];
    var month = SD[idx].split('-')[1];
    var Date = year + '-' + month;
    timeseries.Year.push(Date);
    if (year <= 2013) {
      var SD_1 = SD[idx];
      var ED_1 = ED[idx];
      collection = colLT5.filterDate(SD_1, ED_1)
        .filterBounds(ER)
        .filter(ee.Filter.lt('CLOUD_COVER', 10));
      var Count = collection.size();
      Image_count.push(Count);
      if (Count.gt(0)) {
        Map.addLayer(collection.mosaic().clip(ER), vizParams_L5, 'FCC_' + year, false);
        var NDWIcomp_L5 = collection.map(NDWI_L5).mosaic().clip(ER);
        var L5_Aqua = NDWIcomp_L5.updateMask(NDWIcomp_L5.gte(-0.1));
        Map.addLayer(L5_Aqua, {
          bands: 'NDWI',
          min: -1,
          max: 1,
          palette: ['#eff3ff', '#bdd7e7', '#6baed6', '#3182bd', '#08519c']
        }, 'NDWI_' + year, false);

        var Water_Count_L5 = Pixel_Count(L5_Aqua);
        var ndwi_area_L5 = (Water_Count_L5.multiply(900)).divide(1000000);
        timeseries.Area.push(ndwi_area_L5);
      } else {
        timeseries.Area.push(0);
      }

This is the relevant part of code. If the collection.size()>0 then calculate NDWI and area. Push the area in the Area array otherwise zero value to be pushed in the area for that date

  • 2
    Please include the relevant chunk of code and a complete description of the error/problem in the body of your question. – Vince Mar 2 at 11:59
2

Code you write in Earth Engine often look quite different from what many are used to. You have to keep track of which code is evaluated server-side and client-side, which can be tricky. To simplify things, it's often best to try to stick to only server-side code, as far as possible at least. That, amongst other things, means no for or while loops and no if statements.

Below is a take on how you might solve your problems the "Earth Engine way". It probably doesn’t do exactly what you want, but it's hopefully a starting point:

var region = Map.getBounds(true)
var startDate = ee.Date('1997-01-01')
var endDate = ee.Date('2016-01-01')

var l5 = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR')
  .select(['B2', 'B4', 'pixel_qa'], ['green', 'nir', 'pixel_qa'])

var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
  .select(['B3', 'B5', 'pixel_qa'], ['green', 'nir', 'pixel_qa'])

var ndwiCollection = l5.merge(l8)
  .filterBounds(region)
  .map(function (image) {
    return image
      .select([]).addBands( // Replace bands to keep properties
        image.normalizedDifference(['green', 'nir'])
      )
      .updateMask(landsatMask(image))
      .rename('NDWI')
  })

var monthCount = endDate.difference(startDate, 'months').round()
var monthlyNdwi = ee.FeatureCollection(
  ee.List.sequence(0, monthCount.subtract(1))
    .map(function (monthsOffset) {
      var start = startDate.advance(monthsOffset, 'months')
      var end = start.advance(1, 'months')
      var ndwi = selectOrEmpty(ndwiCollection
        .filterDate(start, end)
        .median(), ['NDWI']
      )
      var water = ndwi.gte(-0.1).selfMask()
      return ee.Feature(null, {
        'area': area(water),
        'month': start.format('MMM'),
        'year': start.format('yyyy'),
        'system:time_start': start.millis()
      })

    })
  )

print(monthlyNdwi)

var chart = ui.Chart.feature.groups({
  features: monthlyNdwi, 
  xProperty: 'year', 
  yProperty: 'area', 
  seriesProperty: 'month'
})
print(chart)


function selectOrEmpty(image, bands) {
  var defaults = ee.Image(
    ee.List(bands).iterate(function (bandName, acc) { 
      return ee.Image(acc).addBands(
        ee.Image().rename(ee.String(bandName))
      )
    }, ee.Image([]))
  )
  return image.addBands(defaults).select(bands)
}


function area(image) {
  return ee.Image.pixelArea()
    .updateMask(image.mask())
    .reduceRegion({
      reducer: ee.Reducer.sum(), 
      geometry: region, 
      scale: 30
    }).get('area')
}


function landsatMask(image) {
  var qa = image.select('pixel_qa')
  var clean = qa.bitwiseAnd(1 << 1)
  var water = qa.bitwiseAnd(1 << 2)
  return clean.or(water)
}

https://code.earthengine.google.com/82ccbf6725374e053238fbc4f942c696

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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