0

I am a beginner at GEE and I want to run a simulation where I calculate some zonal stats for NDVI for a bunch of random points within a specified region of interest and plot them on a histogram. This is being used to get a distribution of NDVI scores for my specified area, which I can use to inform my study which uses actual survey respondent locations. The zonal stats I want to calculate are mean, median, 25th percentile, and 75th percentile. I am using Harmonized Sentinel 2 MSI

Not shown, but I started by getting an NDVI time series for my area, and picked a time where NDVI was stable to create a composite (this time also aligns with when my survey was conducted).

Generating the map, masking clouds and water and getting my buffered points seems to be working well (please if you see red flags or have constructive criticisms of this please let me know as well). I am running into issues when I am calculating my zonal stats, and I am getting an error when I try to actually run the simulation.

Error generating chart: Collection, argument 'features': Invalid type. Expected type: List. Actual type: List<Dictionary>. Actual value: [{nd_p25=0.28888888888888886, nd_median=0.394647466376851, nd_p75=0.5630733944954128,.....

Here is my code that is working

// Add the camp boundaries.
var campBoundaries = Map.addLayer(campBoundaries, {}, "Camp Boundaries");

var pointKT = ee.Geometry.Point([92.1635,21.2127]); //Get the location
Map.centerObject(pointKT); //Get to the location

var vegPalette = ['red', 'white', 'green'];

//Cloud cover mask
function cloudMask(KTimage){
    var scl = KTimage.select('SCL'); //Scene classification layer.
    var mask = scl.eq(3).or(scl.gte(7).and(scl.lte(10)));
    return KTimage.updateMask(mask.eq(0));
}

var KTimage = s2
              .filterBounds(pointKT)
              .filterDate(startDate,endDate)
              .map(cloudMask)
              .median();
//NDVI
var ndvi = KTimage.normalizedDifference(['B8','B4']);
  // Add the layer to our map with a palette.

// Filter NDVI where less than -0.06 (Cutoff that masked almost all water pixels)
var ndviMasked = ndvi.updateMask(ndvi.gte(-0.06));

//Masked NDVI layer
Map.addLayer(ndviMasked, {
  min: -1,
  max: 1,
  palette: vegPalette
}, 'NDVI April-May');

// Define the bufferPoints function with a circular buffer
function bufferPoints(radius) {
    return function (pt) {
        pt = ee.Feature(pt);
        return pt.buffer(radius);
    };
}

// Generate 10000 random points within the geometry
var randomPoints = ee.FeatureCollection.randomPoints(roi, 10000);

// Apply the bufferPoints function with a radius of 30 to the random points
var bufferedPoints = randomPoints.map(bufferPoints(30));

// Add the buffered points to the map
Map.addLayer(bufferedPoints, { color: '0000FF' }, 'Buffered Points');

Here is my code that is not working

// Calculate the mean, median, 25th percentile, and 75th percentile of each circular buffer
var bufferStats = bufferedPoints.map(function (point) {
    var buffer = bufferPoints(30)(point);
    var stats = ndvi.reduceRegion({
        reducer: ee.Reducer.percentile([25, 50, 75], ['p25', 'median', 'p75']).combine({
            reducer2: ee.Reducer.mean(),
            sharedInputs: true
        }),
        geometry: buffer.geometry(), // Extract the geometry from the feature
        scale: 30,
        maxPixels: 1e13 // set maxPixels to a high value
    });
    return point.setMulti(stats);
});

// Convert the bufferStats FeatureCollection to a List
var bufferList = bufferStats.toList(bufferStats.size());

// Extract the statistical values from the List
var bufferValues = bufferList.map(function (feature) {
    return ee.Feature(feature).toDictionary();
});

// Convert the list of features to a FeatureCollection
var featureCollection = ee.FeatureCollection(bufferValues);
// Create histograms for the statistical values
print(ui.Chart.feature.histogram(ee.FeatureCollection(bufferValues), '30m mean'));
print(ui.Chart.feature.histogram(ee.FeatureCollection(bufferValues), '30m p25'));
print(ui.Chart.feature.histogram(ee.FeatureCollection(bufferValues), '30m median'));
print(ui.Chart.feature.histogram(ee.FeatureCollection(bufferValues), '30m p75'));
0

1 Answer 1

0

It's easier to help you if you provide a complete, executable script, so your problem can be easily reproduced. Make sure all assets are shared, and remove as much unrelated bits and pieces as you possible can. It's helpful with an EE Code Editor link too (use the Get Link button).

With the caveat that I'm unable to run your code, I'd say your problem is ee.FeatureCollection(bufferValues). You cannot create a feature collection based on a list of dictionaries.

In general, try to work with collections instead of lists whenever you can. In this case, I don't see any reason not to simply use bufferValues for your chart directly.

var bufferStats = ee.FeatureCollection([
  ee.Feature(null, {'30m mean': 1}),
  ee.Feature(null, {'30m mean': 2}),
  ee.Feature(null, {'30m mean': 2}),
  ee.Feature(null, {'30m mean': 3}),
])
print(ui.Chart.feature.histogram(bufferStats, '30m mean'))

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

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.