0

I want to summarize values in a 500x500m MODIS image that fall within individual gridcells in a different 0.5x0.5 degree resolution image. Each pixel in the 0.5 degree image has a unique value. I use these zones or groups to do a grouped Reduction in Earth Engine. The result of the reduction is a nested list with a unique 'gridcell' value, and the 'mean' of the MODIS NDVI values that fell within that gridcell.

What I want is an image of the results of the mean reducer, where each gridcell has the calculated mean as its value, with the resolution and geometry of the original 0.5x0.5 degree image. I am stuck as to how to join the values of the nested list to my original image in the Earth Engine API. Or how to create a new image from a list that lacks the original geometry.

In this example code, the test 0.5 degree image is called 'gridimage' and the results of the grouped reduction by pixel is stored in the list 'pixel_stats'. I need help either creating a new band for gridimage with the 'mean' from pixel_stats. Or creating a new image with the same geometry.

Here is a link to my code: https://code.earthengine.google.com/ae9fdd7f896960dfa65fdd04f0fa9c2d

    //////////////////////////////////////////////////////////////
// Asset List
//////////////////////////////////////////////////////////////
// Load example image that is 3x3 pixels, 0.5x0.5 degree resolution. Each pixel has unique value.
var imageCollection = ee.ImageCollection("MODIS/MYD13A1");
var gridimage = ee.Image("users/janerfoster/ex_grid_pt5_degree_gridcells_with_id");
print('gridimage',gridimage);

// Use MODIS Veg Indices as high resolution NDVI image. Filter to 2012, growing season dates.
var modis = ee.ImageCollection(imageCollection)
            .filterDate('2012-06-01', '2012-08-31')
            .filterBounds(gridimage.geometry());

// Select first modis image and the NDVI band.
modis = ee.Image(modis.select('NDVI').first());
print(modis);

// Clip modis image to small area of interest
var mod2000 = modis.clip(gridimage.geometry());

// Add gridimage pixel id band to mod2000 Modis NDVI image.
// Need this for zonal, grouped reduction
mod2000 = mod2000.addBands(gridimage.select('gridcell'));
print('mod2000',mod2000);

// Add layers to map to vizualize
Map.setCenter(-83.0,37.0,8);
Map.addLayer(mod2000.select('NDVI'));
var imageVisParam = {"opacity":1,"bands":["gridcell"],"min":63031.461062352275,"max":87147.64774593788,"gamma":1};
Map.addLayer(gridimage,imageVisParam);

// Get a dictionary with band names as keys, pixel lists as values.
var result = gridimage.reduceRegion(ee.Reducer.toList(),gridimage.geometry());
print('result',result);

// Convert the zones of the gridimage to vectors.
var vectorPixid = gridimage.reduceToVectors({
  geometry: gridimage.geometry(),
  geometryType: 'polygon',
  eightConnected: false,
  labelProperty: 'zone',
  reducer: ee.Reducer.first().group({
    groupField: 0,
    groupName: 'gridcell',
  }),
});
print('vectorPixid',vectorPixid);
Map.addLayer(vectorPixid);

// Code to summarize by modis image by grid cell and use result to create new image

//////////////////////////////////////////////////////////////
// Helper functions
//////////////////////////////////////////////////////////////

// Create a feature for a pixels that includes the mean of MODIS NDVI
function createFeature(pixel_stats) {
  pixel_stats = ee.Dictionary(pixel_stats);
  var class_number = pixel_stats.get('gridcell');
  var result = {
      pixel_number: class_number,
      mean: pixel_stats.get('mean')
  };
  return ee.Feature(null, result);   // Creates a feature without a geometry.
}

//////////////////////////////////////////////////////////////
// Calculations
//////////////////////////////////////////////////////////////

// None here

// Summarize MODIS NDVI within 0.5x0.5 degree gridcells (pixels) mod2000
// Grouped a mean reducer: by grid cell pixel id.
var reduction_results = mod2000.reduceRegion({
  reducer: ee.Reducer.mean().group({
    groupField: 1,
    groupName: 'gridcell',
  }),
  geometry: gridimage.geometry(),
  maxPixels: 1e12
});

var pixel_stats = ee.List(reduction_results.get('groups'));
print('pixel_stats',pixel_stats);

var pixel_stats_fc = ee.FeatureCollection(pixel_stats.map(createFeature));
print('pixel_stats_fc', pixel_stats_fc);

// How can I create a new band for gridimage where values equal 'mean' property in the list "pixel_stats"?
1

I found one solution that works using the "remap" function in the API. Remap takes two lists as arguments, so I had to create helper functions to extract the lists out of the nested lists created by the grouped reducer. I'm happy to hear suggestions if there is a better way to do this, but I will share my solution here. This version is cleaned up and simplified from original post.

Link to code: https://code.earthengine.google.com/763edf7b9c50f65223b9f6308407e336

//////////////////////////////////////////////////////////////
// Asset List
//////////////////////////////////////////////////////////////
// Load example image that is 3x3 pixels, 0.5x0.5 degree resolution. Each 
pixel has unique value.
var imageCollection = ee.ImageCollection("MODIS/MYD13A1");
var gridimage = 
ee.Image("users/janerfoster/ex_grid_pt5_degree_gridcells_with_id");
print('gridimage',gridimage);

// Use MODIS Veg Indices as high resolution NDVI image. Filter to 2012, 
growing season dates.
var modis = ee.ImageCollection(imageCollection)
            .filterDate('2012-06-01', '2012-08-31')
            .filterBounds(gridimage.geometry());

// Select first modis image and the NDVI band.
modis = ee.Image(modis.select('NDVI').first());
print(modis);

// Clip modis image to small area of interest
var mod2000 = modis.clip(gridimage.geometry());

// Add gridimage pixel id band to mod2000 Modis NDVI image.
// Need this for zonal, grouped reduction
mod2000 = mod2000.addBands(gridimage.select('gridcell'));
print('mod2000',mod2000);

// Add layers to map to vizualize
Map.setCenter(-83.0,37.0,8);
Map.addLayer(mod2000.select('NDVI'));
var imageVisParam = {"opacity":1,"bands": 
["gridcell"],"min":63031.461062352275,"max":87147.64774593788,"gamma":1};
Map.addLayer(gridimage,imageVisParam);

// Code to summarize by modis image by grid cell and use result to create 
new image

//////////////////////////////////////////////////////////////
// Helper functions
//////////////////////////////////////////////////////////////

// Create a function for looking up values in a nested list from grouped 
reduction.
function lookup_gridcells(list) {
  // Extract gridcell from nested list.
  var pixelid = ee.Dictionary(list).get('gridcell');
  return pixelid;
}

// Create a function for looking up stats in a nested list from grouped 
reduction.
function lookup_stat(list) {
  // Extract computed stat from nested list.
  var pixelstat = ee.Dictionary(list).get('mean');
  return pixelstat;
}

//////////////////////////////////////////////////////////////
// Calculations
//////////////////////////////////////////////////////////////

// Summarize MODIS NDVI within 0.5x0.5 degree gridcells (pixels) mod2000
// Grouped a mean reducer: by grid cell pixel id.
var reduction_results = mod2000.reduceRegion({
  reducer: ee.Reducer.mean().group({
    groupField: 1,
    groupName: 'gridcell',
  }),
  geometry: gridimage.geometry(),
  maxPixels: 1e12
});

var pixel_stats = ee.List(reduction_results.get('groups'));
print('pixel_stats',pixel_stats);

// Apply helper functions to extract nested lists into two individual lists
// These can be used by the remap algorithm on the original pixel value 
image
var gridcell_list = pixel_stats.map(lookup_gridcells);
print('gridcell_list',gridcell_list);

var stat_list = pixel_stats.map(lookup_stat);
print('stat_list',stat_list);

// Use remap to create new image with computed stats as values.
var remapped = gridimage.select('gridcell').remap({
  from: gridcell_list,
  to: stat_list,
 bandName: 'gridcell'
});

print('remapped image',remapped);

Map.addLayer(remapped, {}, 'remapped')
0

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.