2

My goal is to be able to use the JRC Yearly Water classification History imageCollection to calculate the area of seasonal and permanent water for each year available in a specified extent. I am able to do this for a specific image but I am hoping to find a way to automate the process for all the images in the collection. I know that I can map over an imageCollection to analyze it, but I can't print a chart within that function or find a way for the function to return the values of the reduceRegion. The questions I have are:

1) Is there a way to map over the imageCollection and get the values of the area for each class for each image? Or should I be doing something else?

or

2) Is there a way to get a graph with the area of each class for each of the images? Or do a time series graph by class?

Here is my code for a single image. From here I would just export the csv and then combine them in a different program, but can I do it all in Google Earth Engine?

//import needed images and collections 
var img1984 = ee.Image("JRC/GSW1_1/YearlyHistory/1984"); 
var gsw = ee.Image("JRC/GSW1_1/GlobalSurfaceWater"); 
var yearSeasonality = ee.ImageCollection("JRC/GSW1_1/YearlyHistory");

var roi = ee.Geometry.Polygon([[-113.31109206384143,38.70660386074948], [-113.09136550134143,38.69588646672195], [-112.93481032556018,39.112673412644575], [-113.20672194665393,39.12332806661866], [-113.31109206384143,38.70660386074948]]);

Map.addLayer(roi);

//These are the parameters if you want to map the extent or seasonality layers 
var extentParams = {min: 0, max: 1}; 
var seasonalityParams = {min:1, max: 12, palette: ["#99D9EA", "#0000AA" ]};

//use the max extent of the water body to mask the seasonality layer 
var mask = gsw.select('max_extent') .eq(1) .clip(roi); 
var y1984 = img1984.updateMask(mask);

//calculate the area of the pixels 
var y1984Area= ee.Image.pixelArea().addBands(y1984);

var classNames = ee.List(["No Data", "Not Water", "Seasonal Water", "Permanent Water"]);

//create a chart that adds up the areas of each of the classes

var TimeChart = ui.Chart.image.byClass({ image: y1984Area, classBand: 1, region: roi, reducer: ee.Reducer.sum(), scale:30, classLabels: classNames, }); print(TimeChart);

//another way to get the total areas for each class 

var reduced1984 = y1984Area.reduceRegion({ reducer: ee.Reducer.sum().group({ groupField: 1, groupName: 'waterClass', }), geometry: roi, scale:30, bestEffort: true, });

print("reduced values",reduced1984);

Here is the code for me starting to automate the process (I'm not including the many things I tried that didn't work):

var seasonality = yearSeasonality.map (function(image){ var mask = gsw.select('max_extent') .eq(1) .clip(roi);

return image.updateMask(mask); });

var seasonalityArea = seasonality.map (function(image){ var seasons = ee.Image.pixelArea(); return ee.Image.pixelArea().addBands(image).copyProperties(image,['system:time_start','system:time_end']); }); print (seasonalityArea,"seasonality with area added,not summed");
1
  • Welcome to GIS SE. Thank you for taking the Tour. Please ask One question per Question.
    – Vince
    May 14, 2020 at 0:43

1 Answer 1

3

This script doesn't perhaps take all your requirements into account, but it should answer your two questions:

var roi = ee.Geometry.Polygon([[-113.31109206384143,38.70660386074948], [-113.09136550134143,38.69588646672195], [-112.93481032556018,39.112673412644575], [-113.20672194665393,39.12332806661866], [-113.31109206384143,38.70660386074948]])
var areas = ee.ImageCollection('JRC/GSW1_1/YearlyHistory')
  .map(areaByClass)

print(areas)
var chart = ui.Chart.feature.byFeature(areas, 'year')
print(chart)
Map.centerObject(roi)

function areaByClass(image) {  
  var classNames = ee.List(['No Data', 'Not Water', 'Seasonal Water', 'Permanent Water']);
  var groups = ee.Image.pixelArea().addBands(image)
    .reduceRegion({ 
      reducer: ee.Reducer.sum()
        .group({ groupField: 1, groupName: 'waterClass', }), 
      geometry: roi, 
      scale: 30
    }).get('groups')
  var areaByClass = ee.Dictionary(
    ee.List(groups).map(function (group) {
      group = ee.Dictionary(group)
      return [
        classNames.get(group.getNumber('waterClass')),
        group.getNumber('sum').divide(1e6) // square km 
      ]
    }).flatten()
  )
  return ee.Feature(null, areaByClass.set('year', image.get('year')))
}

https://code.earthengine.google.com/d20512d31f5d46d5d9302000ce86bc28

1
  • Thank you. It was exactly what I needed and worked great!
    – rebeccalm
    May 14, 2020 at 23:43

Your Answer

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

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