I have several image collections: september_CCI (chlorophyll-carotenoid index), SDD (snow disappearance date), cumulative_summer_VPD (vapor pressure deficit), and cumulative_summer_precipitation. Each image collection covers the same years (2000-2020) and they are the same spatial dimensions.
CCI is the dependent variable. SDD, cumulative_summer_VPD, and cumulative_summer_precipitation are the independent variables.
I would like to compute the pixel-wise R-squared between CCI and each of the independent variables.
Here's some code that I found elsewhere and have tried to adapt to my case:
// 1. Join datasets. First, define filter. This is based on the date.
var filter = ee.Filter.equals({
leftField: 'system:time_start',
rightField: 'system:time_start'
});
// 2. Create the join.
var innerJoin = ee.Join.inner('primary', 'secondary');
// 3. Apply the join.
var merge = innerJoin.apply(septCCI, sdd2, filter);
// 4. Merge both collections.
var mergedCCI_SDD = merge.map(function(f){
var cci = ee.Image(f.get('primary')).rename('cci');
var sdd = ee.Image(f.get('secondary')).rename('sdd');
return cci.addBands(sdd).copyProperties(cci);
});
var covariance = function(mergedCCI_SDD, cci, sdd) {
return mergedCCI_SDD.select([cci, sdd]).map(function(image) {
return image.toArray();
}).reduce(ee.Reducer.covariance(), 8);
};
var correlation = function(vcArrayImage) {
var covariance = ee.Image(vcArrayImage).arrayGet([0, 1]);
var sd0 = ee.Image(vcArrayImage).arrayGet([0, 0]).sqrt();
var sd1 = ee.Image(vcArrayImage).arrayGet([1, 1]).sqrt();
return covariance.divide(sd0).divide(sd1).rename('correlation');
};
// Compute and display cross-covariance.
var covCCI_SDD = covariance(mergedCCI_SDD, 'cci', 'sdd');
Map.addLayer(covCCI_SDD.arrayGet([0, 1]), {}, 'CCI-SDD cov');
// Compute and display cross-correlation.
var corrCCI_SDD = correlation(covCCI_SDD);
Map.addLayer(corrCCI_SDD, {min: -0.5, max: 0.5}, 'CCI-SDD corr');
When I try to run this (within a much larger piece of code), I get the following error, which corresponds to the line on which
there is this code: return image.toArray();
Line 643: Required argument (properties) missing to function: Feature.toArray(feature, properties)
Creates an array from the given properties of an object, which must all be numbers.
Args:
feature (Feature): The object from which to select array properties.
properties (List): The property selectors for each array element.
Thanks for any help you can provide.
Related
I am about to calculate Chorophyll-a in the water bodies in one region, as I outlined above. I have created a mask, with water=1, land=0(transparent). And I want to calculate quality formula (NDCI, refer to normalized difference chl-a index) over the mask I created in the last step. Here are my code.
function maskS2clouds(image) {
var qa = image.select('QA60')
var cloudBitMask = 1 << 10;
var cirrusBitMask = 1 << 11;
var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(
qa.bitwiseAnd(cirrusBitMask).eq(0))
return image.updateMask(mask).divide(10000)
.select("B.*")
.copyProperties(image, ["system:time_start"])
}
var tiles = ['29UNV']
var collection = ee.ImageCollection("COPERNICUS/S2_SR")
.filterDate('2020-01-01', '2020-12-31')
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
.filter(ee.Filter.inList('MGRS_TILE', tiles))
print(collection)
var minmin = collection.map(maskS2clouds)
print(minmin)
var calndwi = function(image){
//water mask
var NDWI = image.normalizedDifference(['B3', 'B8']).rename('NDWI');
return image.addBands(NDWI).updateMask(NDWI.gt(0));
};
print(minmin.map(calndwi));
//Add NDWI to the clipped image collection
var withNDWI = minmin.map(calndwi).select('NDWI');
print("NDWI collection", withNDWI);
var bb = withNDWI.first();
Map.addLayer(bb,{},'ss');
var addNDCI = function(image) {
var ndci = image.normalizedDifference(['B5', 'B4']).rename('NDCI');
return image.addBands(ndci);
};
var withNDCI = minmin.map(addNDCI).select('NDCI');
print("NDCI collection", withNDCI);
var MASK = function(image) {
var mask = bb.mask(image);
return image.addBands(mask);
};
var maskk = withNDCI.map(MASK).select('mask');
print(maskk)**
and it give me the bug like ImageCollection (Error)
Error in map(ID=20200106T114451_20200106T114531_T29UNV):Image.select: Pattern 'mask' did not match any bands.what should I do? thanks a million
The maskk object does not contain any bands named mask, because your MASK function does not create or add any bands with that name.
What your code does, as you've currently written it, is this:
var MASK = function(image) {
// Apply a mask over the 'bb' image.
var mask = bb.mask(image);
// return 'image' (which was the 'mask' parameter above),
// with ALL bands from the object 'mask', which is now a 'masked' version of bb.
// since mask = bb.mask(image), all the bands from bb will be added.
return image.addBands(mask);
};
var maskk = withNDCI
// Map the 'MASK' function over the 'withNDCI' collection
.map(MASK)
// Attempt to select a band named 'mask' (which does not exist).
.select('mask');
I'm not sure what you're looking for when you try to select the mask 'band' - I assume what you want is the masked NCDI image. That's essentially what you have already - but the band names of the 'maskk' object are "NDWI" and "NDCI", since it is derived from the bb, and those are the bands that bb contains. There is no band named "mask".
I calculated the MNDWI value of the picture collection
function MNDWI(image) {
var mndwi = image.normalizedDifference(['SR_B6', 'SR_B3']).rename('mndwi');
return image.addBands(mndwi);
}
// display MNDWI layer
var withMndwi = filtered.map(MNDWI);
var composite = withMndwi.median().clip(polygon);
var MndwiComposite = composite.select('mndwi');
I also use statistic to calculate the threshold
var chart = ui.Chart.image.seriesByRegion({
imageCollection: withMndwi,
regions: pol,
band: 'mndwi',
reducer:ee.Reducer.mean(),
scale:10, });
Now I want to consider every single value of the image collection, I did try something as recommendation in this [post][1] like:
function masking (image){
var sample = image.sample();
var threshold = sample.gte(chart); // gte = greater (gt) + equal (eq)
var mask = threshold.updateMask(threshold);
return image.updateMask(mask);
}
But it notices that: sample.gte is not a function
What should I do for now?
[1]: extract the values for all pixels in a polygon in google earth engine
I used the .combine command to convert two image collections into a two-band image collection (in the last line) to use in a function in the next step. This command is executed but writes 0 elements in the console. Where does this problem come from?
code link: https://code.earthengine.google.com/ed0992093ff830d926c7dd14403477c6
Code:
var ndvi = function(img){
var bands = img.select(['B2','B3','B4','B8']).multiply(0.0001)
.clip(geometry);
var index = bands.normalizedDifference(['B8','B4']).rename('NDVI_S2');
return index
.copyProperties(img,['system:time_start','system:time_end','system:index']);
};
var S2 = ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(geometry)
.filterDate('2018-10-24','2019-06-30')
//.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE',20))
.map(ndvi);
print(S2);
var START = '2018-10-24';
var END = '2019-06-30';
var DATES = [ '2018-12-19', '2018-12-29', '2019-01-23', '2019-02-12', '2019-03-04',
'2019-03-19', '2019-04-08', '2019-04-13', '2019-05-13', '2019-05-18', '2019-05-23',
'2019-05-28', '2019-06-02', '2019-06-07', '2019-06-12', '2019-06-17', '2019-06-22',
'2019-06-27'];
var addTime = function(x) {
return x.set('Date', ee.Date(x.get('system:time_start')).format("YYYY-MM-dd"))};
var Sentinel = ee.ImageCollection(S2)
.filter(ee.Filter.date(START, END))
.map(addTime)
.filter(ee.Filter.inList('Date',ee.List(DATES)));
print(Sentinel);
var PMODIS =
ee.Image('MODIS/006/MCD43A4/2018_12_19').select('Nadir_Reflectance_Band4');
var MODProjection = PMODIS.projection();
print('MODIS projection:', MODProjection);
var Viz = {min: 0, max: 1, palette: ['be6c44','ca3a3a','e4ae0c','565c04','819536']};
var S2_resampled = Sentinel.map(function(img){
var S2Mean = img
// Force the next reprojection to aggregate instead of resampling.
.reduceResolution({
reducer: ee.Reducer.mean(),
maxPixels: 2146
})
// Request the data at the scale and projection of the Sentinel image.
.reproject({
crs: MODProjection
});
return S2Mean
.copyProperties(img,['system:time_start','system:time_end','system:index']);
});
Map.addLayer(S2_resampled)
var M_ndvi = function(img){
var bands =
img.select(['Nadir_Reflectance_Band1','Nadir_Reflectance_Band5']).multiply(0.0001)
.clip(geometry);
var index=bands
.normalizedDifference(['Nadir_Reflectance_Band1','Nadir_Reflectance_Band5'])
.rename(
'NDVI_MOD');
return index
.copyProperties(img,['system:time_start','system:time_end','system:index']);
};
var MOD = ee.ImageCollection('MODIS/006/MCD43A4')
.filterBounds(geometry)
.filterDate('2018-10-24','2019-06-30')
.map(M_ndvi);
var MODIS = ee.ImageCollection(MOD)
.filter(ee.Filter.date(START, END))
.map(addTime)
.filter(ee.Filter.inList('Date',ee.List(DATES)));
print(MODIS);
var S2_and_MOD = S2_resampled.combine(MODIS, false);
print(S2_and_MOD);
var Diff = S2_and_MOD.map(function(img){
var clip = img.clip(geometry);
var Diffe = clip.expression('NDVI_S2 - NDVI_MOD',
{'NDVI_S2':clip.select('NDVI_S2') ,
'NDVI_MOD':clip.select('NDVI_MOD')}).rename('Diff');
return Diffe
.copyProperties(img,['system:time_start','system:time_end']); });
print(Diff);
ee.Image.combine() uses the system:ID property to join the 2 images. See the documentation here. Since your images do not match, the resulting collection has no images.
A solution that should fit your needs utilizes the ee.Join.inner() to take advantage of the Date property that you have created to join the 2 image collections. A similar question was answered here.
Using inner join, I was able to accomplish what appeared to be your goal of finding the difference in NDVI between the S2 and MODIS collections. The full working script can be found here: https://code.earthengine.google.com/dc45df1b7cf83723d53e9f7917975e2d
Code:
// Function - Calculate S2 NDVI
var ndvi = function(img){
var bands = img.select(['B2','B3','B4','B8']).multiply(0.0001)
.clip(geometry);
var index = bands.normalizedDifference(['B8','B4']).rename('NDVI_S2');
return index
.copyProperties(img,['system:time_start','system:time_end','system:index']);
};
// Get S2 NDVI images
var S2 = ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(geometry)
.filterDate('2018-10-24','2019-06-30')
//.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE',20))
.map(ndvi);
print('S2 NDVI ImageCollection',S2);
// Set Date Parameters
var START = '2018-10-24';
var END = '2019-06-30';
// Create Date List
var DATES = [ '2018-12-19', '2018-12-29', '2019-01-23', '2019-02-12', '2019-03-04',
'2019-03-19', '2019-04-08', '2019-04-13', '2019-05-13', '2019-05-18', '2019-05-23',
'2019-05-28', '2019-06-02', '2019-06-07', '2019-06-12', '2019-06-17', '2019-06-22',
'2019-06-27'];
// Function - Add 'Date' field to image
var addTime = function(x) {
return x.set('Date', ee.Date(x.get('system:time_start')).format("YYYY-MM-dd"))};
// Run addTime on S2 ImageCollection
var Sentinel = ee.ImageCollection(S2)
.filter(ee.Filter.date(START, END))
.map(addTime)
.filter(ee.Filter.inList('Date',ee.List(DATES)));
print('Date Added S2', Sentinel);
// Get MODIS Projection
var PMODIS = ee.Image('MODIS/006/MCD43A4/2018_12_19').select('Nadir_Reflectance_Band4');
var MODProjection = PMODIS.projection();
print('MODIS projection:', MODProjection);
// Set Visualization Parameters
var Viz = {min: 0, max: 1, palette: ['be6c44','ca3a3a','e4ae0c','565c04','819536']};
// Reproject S2 images to MODIS projection
var S2_resampled = Sentinel.map(function(img){
var S2Mean = img
// Force the next reprojection to aggregate instead of resampling.
.reduceResolution({
reducer: ee.Reducer.mean(),
maxPixels: 2146
})
// Request the data at the scale and projection of the Sentinel image.
.reproject({
crs: MODProjection
});
return S2Mean
.copyProperties(img,['system:time_start','system:time_end','system:index']);
});
print('S2_resampled',S2_resampled);
Map.addLayer(S2_resampled);
// Function - Calculate MODIS NDVI
var M_ndvi = function(img){
var bands = img.select(['Nadir_Reflectance_Band1','Nadir_Reflectance_Band5']).multiply(0.0001)
.clip(geometry);
var index = bands.normalizedDifference(['Nadir_Reflectance_Band1','Nadir_Reflectance_Band5']).rename('NDVI_MOD');
return index
.copyProperties(img,['system:time_start','system:time_end','system:index']);
};
// Get MODIS NDVI Images
var MOD = ee.ImageCollection('MODIS/006/MCD43A4')
.filterBounds(geometry)
.filterDate('2018-10-24','2019-06-30')
.map(M_ndvi);
// Run addTime on MODIS ImageCollection
var MODIS = ee.ImageCollection(MOD)
.filter(ee.Filter.date(START, END))
.map(addTime)
.filter(ee.Filter.inList('Date',ee.List(DATES)));
print('MODIS',MODIS);
// Combine MODIS and S2 Image Collections using Date
// Specify the join type
var join_type = ee.Join.inner();
// Set the join parameter
var filter = ee.Filter.equals({
leftField: 'Date',
rightField: 'Date'
});
// Execute the join
var inner_join = ee.ImageCollection(join_type.apply(MODIS,S2_resampled,filter));
// Flatten joined images into a single image with 2 bands
var S2_and_MOD = inner_join.map(function(feature) {
return ee.Image.cat(feature.get('primary'), feature.get('secondary'));
});
print('Combined S2 and MODIS Collection:',S2_and_MOD);
// Calculate the difference between S2 and MODIS NDVI values
var Diff = S2_and_MOD.map(function(img){
var clip = img.clip(geometry);
var Diffe = clip.expression('NDVI_S2 - NDVI_MOD',
{'NDVI_S2':clip.select('NDVI_S2') , 'NDVI_MOD':clip.select('NDVI_MOD')}).rename('Diff');
return Diffe
.copyProperties(img,['system:time_start','system:time_end']); });
print('NDVI Difference Collection',Diff);
I am working on a land use classification program using the RS algorithm of the GEE platform. The codes are as the following link.
https://code.earthengine.google.com/7e99f1de58c1251bd9bff0ff7af9368b
Specific codes:
var table = ee.FeatureCollection("users/zongxuli/Jing_Jin_Ji");
//Set up bands and corresponding band names
var inBands = ee.List([1,2,3,4,5,7,6,'pixel_qa'])
var outBands = ee.List(['blue','green','red','nir','swir1','temp', 'swir2','pixel_qa'])
// Get Landsat data
var l8s = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR")
.filterDate(2019-01-01,2019-12-31)
.filterBounds(table)
.select(inBands,outBands)
.filter(ee.Filter.lt("CLOUD_COVER",10))
function getIndexes(image){
// Normalized Difference Vegitation Index(NDWI)
var ndvi = image.normalizedDifference(['nir','red']).rename("ndvi");
image = image.addBands(ndvi);
// Normalized Difference Snow Index(NDWI)
var ndsi = image.normalizedDifference(['green','swir1']).rename("ndsi");
image = image.addBands(ndsi);
// Normalized Difference Water Index(NDWI)
var ndwi = image.normalizedDifference(['nir','swir1']).rename("ndwi");
image = image.addBands(ndwi);
// add Enhanced Vegetation Indexes
var evi = image.expression('2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {
'NIR' : image.select('nir'),
'RED' : image.select('red'),
'BLUE': image.select('blue') }).float();
image = image.addBands(evi.rename('evi'));
// Add Index-Based Built-Up Index (IBI)
var ibiA = image.expression('2 * SWIR1 / (SWIR1 + NIR)', {
'SWIR1': image.select('swir1'),
'NIR' : image.select('nir')}).rename(['IBI_A']);
var ibiB = image.expression('(NIR / (NIR + RED)) + (GREEN / (GREEN + SWIR1))', {
'NIR' : image.select('nir'),
'RED' : image.select('red'),
'GREEN': image.select('green'),
'SWIR1': image.select('swir1')}).rename(['IBI_B']);
var ibiAB = ibiA.addBands(ibiB);
var ibi = ibiAB.normalizedDifference(['IBI_A', 'IBI_B']);
image = image.addBands(ibi.rename('ibi'));
return(image);
}
function getTopography(image,elevation) {
// Calculate slope, aspect and hillshade
var topo = ee.Algorithms.Terrain(elevation);
// From aspect (a), calculate eastness (sin a), northness (cos a)
var deg2rad = ee.Number(Math.PI).divide(180);
var aspect = topo.select(['aspect']);
var aspect_rad = aspect.multiply(deg2rad);
var eastness = aspect_rad.sin().rename(['eastness']).float();
var northness = aspect_rad.cos().rename(['northness']).float();
// Add topography bands to image
topo = topo.select(['elevation','slope','aspect']).addBands(eastness).addBands(northness);
image = image.addBands(topo);
return(image);
}
// Get an image to train and apply classification to.
var image = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
.filterBounds(table)
.first();
// get bands
var bands=image.bandNames();
print(bands);
// integers starting from zero in the training data.
var label = 'lcode';
// Overlay the points on the imagery to get training.
var trainings = image.select(bands).sampleRegions({
collection: l8s, //.filterDate(2019-01-01,2019-12-31),
properties: [label],
scale: 30
});
// The randomColumn() method will add a column of uniform random
// numbers in a column named 'random' by default.
var sample = trainings.randomColumn();
var split = 0.7; // Roughly 70% training, 30% testing.
var training = sample.filter(ee.Filter.lt('random', split));
print(training.size());
// Random forest
var classifier = (ee.Classifier.smileRandomForest(15)
.train({
features: training,
classProperty: label,
inputProperties: bands
}));
var classified = image.classify(classifier);
print(classified);
So far, I always received the wrong message "Number (Error) Empty date ranges not supported for the current operation." when running the program. What am I doing wrong?
There is a quotation problem in image collection date filtering:
// Get Landsat data
var l8s = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR")
.filterDate(2019-01-01,2019-12-31)
.filterBounds(table)
.select(inBands,outBands)
.filter(ee.Filter.lt("CLOUD_COVER",10))
it must be:
// Get Landsat data
var l8s = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR")
.filterDate('2019-01-01','2019-12-31')
.filterBounds(table)
.select(inBands,outBands)
.filter(ee.Filter.lt("CLOUD_COVER",10))
And in training for classifier section:
// Overlay the points on the imagery to get training.
var trainings = image.select(bands).sampleRegions({
collection: l8s, //.filterDate(2019-01-01,2019-12-31),
properties: [label],
scale: 30 });
it must be :
// Overlay the points on the imagery to get training.
var trainings =
image.select(bands).sampleRegions({
collection: table,
properties: [label],
scale: 30 });
How I can extract index vegetation points over collections by adapting this beautiful code by #Rodrigo E. Principe:
Extract pixel values by points and convert to a table in Google Earth Engine
I try extract all values mas GEE is crashing, so only NDVI or EVI can works fine.
I did it with this tutorial https://developers.google.com/earth-engine/tutorial_api_06
// Dataset do sensor LS8
var dataset = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
.filterDate('2018-04-01', '2019-03-31')
.select('B5', 'B4')
.filterBounds(aoi6010)
.filter(ee.Filter.lt('CLOUD_COVER', 20));
var addNDVI = function(image) {
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
return image.addBands(ndvi);
};
var withNDVI = dataset.map(addNDVI);
print(withNDVI);
// Empty Collection to fill
var ft = ee.FeatureCollection(ee.List([]))
var fill = function(img, ini) {
// type cast
var inift = ee.FeatureCollection(ini)
// gets the values for the points in the current img
var ft2 = img.reduceRegions(p601018, ee.Reducer.first(),30)
// gets the date of the img
var date = img.date().format()
// writes the date in each feature
var ft3 = ft2.map(function(f){return f.set("date", date)})
// merges the FeatureCollections
return inift.merge(ft3)
}
// Iterates over the ImageCollection
var newft = ee.FeatureCollection(withNDVI.iterate(fill, ft))