In Google Earth Engine I am calculating Sentinel-2 NDVI and then want to rescale my ndvi imagery from 10m to 30m to match Landsat. Finally, I want to combine the 30m Sentinel-2 with the Landsat imagery to give a two band image and export them in a specific projection (UTM). I know that with composites (such as ndvi) the projection information is lost. I have tried to correct for this but my code below doesn't seem to work - plotting the data shows the Sentinel-2 is still at 10m. And if I try and export the data I get the error "Error: Can't transform (224518.0,-661010.5)".
How can I reassign the projection correctly and create a 30m resolution ndvi image for Sentinel-2?
All the other examples I can find are for simple images rather than composites.
// Cloud mask Landsat 8
function cloudMaskL8sr(image) {
var cloudShadowBitMask = (1 << 3);
var cloudsBitMask = (1 << 5);
var qa = image.select('QA_PIXEL');
var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
.and(qa.bitwiseAnd(cloudsBitMask).eq(0));
return image.multiply(0.0000275).add(-0.2).updateMask(mask);
}
// Cloud mask using the Sentinel-2 QA band.
function maskS2clouds(image) {
var qa = image.select('QA60');
var cloudBitMask = Math.pow(2, 10);
var cirrusBitMask = Math.pow(2, 11);
var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(
qa.bitwiseAnd(cirrusBitMask).eq(0));
return image.divide(10000).updateMask(mask).copyProperties(image, ['system:time_start']);
}
// Get landsat 8 collection
var ls8_collection = ee.ImageCollection("LANDSAT/LC08/C02/T1_L2")
.filterBounds(geometry)
.filterDate(ee.Date.fromYMD(2020,1,1),ee.Date.fromYMD(2020,12,31))
.map(cloudMaskL8sr)
.select(['SR_B4','SR_B5']);
// Calculate landsat ndvi
var ls8_ndvi = ls8_collection
.median()
.normalizedDifference(['SR_B5','SR_B4'])
.clip(geometry)
.rename('LS8_NDVI');
// reset scale and projection
ls8_ndvi = ls8_ndvi.setDefaultProjection({
crs: 'EPSG:32360',
scale: 30
})
// Get Sentinel-2 data
var s2_collection = ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(geometry)
.filterDate(ee.Date.fromYMD(2020,1,1),ee.Date.fromYMD(2020,12,31))
.filterMetadata('CLOUDY_PIXEL_PERCENTAGE','less_than',50) // Need to include this to reduce teh amount of data
.map(maskS2clouds)
.select(['B4','B8'])
// calculate ndvi
var s2_ndvi = s2_collection
.median()
.normalizedDifference(['B8','B4'])
.clip(geometry)
.rename('S2_NDVI');
// Change resolution and assign projection
s2_ndvi = s2_ndvi.setDefaultProjection({
crs: 'EPSG:32360',
scale: 30
})
// Combine Landsat and Sentinel-2 into a single two-band image
var combined = ee.Image.cat([s2_ndvi,ls8_ndvi])
print(combined)
// Plot (as a test)
var ndviParams = {min:-0.25, max:1, palette:'CE7E45,DF923D,F1B555,FCD163,99B718,74A901,66A000,529400,3E8601,207401,056201,004C00,023B01,012E01,011D01,011301'};
Map.addLayer(s2_ndvi, ndviParams, 'S2');
Map.addLayer(ls8_ndvi, ndviParams, 'LS8');
// Export image to drive
Export.image.toDrive({
image: combined,
description : 'combined',
scale : 30,
crs: 'EPSG:32360',
region : geometry
})