0

I'm trying to extract different indices vales at random points in Google Earth Engine. I have calculated NDVI, NDBI, NDSI for the area from the Landsat 5 image. Then created a mosaic of these three indices. After that trying to reduceRegions() to extract the values from the mosaiced image at random points.

//---------------------------------------------------------------------------
//------------- --------------INDICES CALCULATION----------------------------
//---------------------------------------------------------------------------

// import the boundary layer of Mumbai
var mumbai = ee.FeatureCollection('users/badalmohanty/GreaterBombay');
Map.centerObject(mumbai, 10);

//------------- import Landsat 5 dataset 9th March 1990----------------------

var dataset = ee.ImageCollection('LANDSAT/LT05/C02/T1_L2')
    .filter(ee.Filter.eq('WRS_PATH', 148))
    .filter(ee.Filter.eq('WRS_ROW', 47))
    .filterDate('1990-03-01', '1990-04-01');
// Applies scaling factors.
function applyScaleFactors(image) {
  var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);
  var thermalBand = image.select('ST_B6').multiply(0.00341802).add(149.0);
  return image.addBands(opticalBands, null, true)
              .addBands(thermalBand, null, true);
}
dataset = dataset.map(applyScaleFactors);
// take least clouded image
var image = ee.Image(dataset.sort('CLOUD_COVER').first().clip(mumbai));

// calculate NDVI
var ndvi = image.normalizedDifference(['SR_B4', 'SR_B3']);
// calculate NDBI
var ndbi = image.normalizedDifference(['SR_B5', 'SR_B4']);
// calculate NDSI
var ndsi = image.normalizedDifference(['SR_B7', 'SR_B2']);

var mosaic = ee.ImageCollection([
  ndbi.visualize({palette: 'blue'}),
  ndvi.visualize({palette: 'green'}),
  ndsi.visualize({palette: 'red'})
]).mosaic();
Map.addLayer(mosaic, {}, 'custom mosaic');

//---------------------------------------------------------------------------
//------------- ----------EXTRACTION AT RANDOM POINTS------------------------
//---------------------------------------------------------------------------

// load the random points
var randomPoints = ee.FeatureCollection('users/badalmohanty/GreaterMumbaiRandomPoints');

// reduce the region
var poinData = mosaic.reduceRegions({
  collection: randomPoints,
  reducer: ee.Reducer.first()
});

// print it.
print(poinData);

// export it.
Export.table.toDrive(poinData, "test1");

There are several problems in this which I am not able to solve.

  1. The data type of all the bands of the mosaic image is uint8 and CRS is EPSG:4326. Where as individual indices images (NDVI, NDBI, NDSI) have data type of float ∈ [-1, 1] and CRS are EPSG:32643.
  2. the code shows the following error,
FeatureCollection (Error) 
Image.reduceRegions: The default WGS84 projection is invalid for aggregations. Specify a scale or crs & crs_transform.

Why these issues are coming and how to solve them?

My aim here is to extract the indices data at those random points. instead of doing that for individual indices one by one, I tried to make a composite and extract all values at once. If my method is very wrong, can anyone suggest how I can achieve this result?

I have attached the asset link to the used feature collections. Also the drive link.

  1. GreaterBombay feature collection (Drive link).
  2. GreaterMumbaiRandomPoints feature collection (Drive link).

2 Answers 2

1

I believe when you define a imageCollection like that you 'lose' the projection data (scale and CRS). So you need to define that in your reduceRegions function specifically.

// reduce the region
var poinData = mosaic.reduceRegions({
  collection: randomPoints,
  crs: ee.Projection('EPSG:4326'),
  scale:30,
  reducer: ee.Reducer.first()
});

https://code.earthengine.google.com/54971088c2b66f96984c50075b0e16f4?asset=users%2Fbadalmohanty%2FGreaterBombay

3
  • Thanks, I tried to do this as you have mentioned on the code sample. I added indices as bands in the feater collection and then took one image from that to which I applied reduceRegions function. But with this along with indices values, I am getting values of different bands. Is there any way I can get only selected band values in the output of reduceRegions?
    – Badal
    Commented Sep 10, 2021 at 11:36
  • 1
    mosaic.select(['YOUR_BAND_NAME1', 'YOUR_BAND_NAME2']).reduceRegions({ collection: randomPoints, crs: ee.Projection('EPSG:4326'), scale:30, reducer: ee.Reducer.first() });
    – Jobbo90
    Commented Sep 10, 2021 at 11:57
  • Thank you. It worked nicely.
    – Badal
    Commented Sep 11, 2021 at 5:11
0

Your method is right, but you should specify a scale (and crs if you want) in your .reduceRegions() call.

When you use mosaic(), as you also noticed, the scale is being set to 1 degree and the crs to WGS84, this is the default projection in Earth Engine.

Since most people do not want to do aggregations at this very coarse scale, Earth Engine warns you if you try to use an aggregation with the default projection.

// reduce the region
var poinData = mosaic.reduceRegions({
  collection: randomPoints,
  reducer: ee.Reducer.first(),
  scale: 30
});

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.