GeometryConstructors.Polygon: LinearRing requires at least 3 points - google-earth-engine

I am trying to run the following code to extract the change map using the Land Trendr algorithm in Google Earth Engine. Everything seems to be running fine when I use a point as my area of interest, but once I try to use a polygon as my aoi file it throws me an error. I am attaching my code here :
//##########################################################################################
// START INPUTS
//##########################################################################################
// define collection parameters
var startYear = 1985;
var endYear = 2017;
var startDay = '06-20';
var endDay = '09-20';
//var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var coords = ([70.9361058400289,28.387332974875402],
[83.5044652150289,28.387332974875402],
[83.5044652150289,37.305336609850876],
[70.9361058400289,37.305336609850876],
[70.9361058400289,28.387332974875402]);
var aoi = ee.Geometry.Polygon(coords);
var index = 'NBR';
var maskThese = ['cloud', 'shadow', 'snow', 'water'];
// define landtrendr parameters
var runParams = {
maxSegments: 6,
spikeThreshold: 0.9,
vertexCountOvershoot: 3,
preventOneYearRecovery: true,
recoveryThreshold: 0.25,
pvalThreshold: 0.05,
bestModelProportion: 0.75,
minObservationsNeeded: 6
};
// define change parameters
var changeParams = {
delta: 'loss',
sort: 'greatest',
year: {checked:false, start:2000, end:2010},
mag: {checked:true, value:200, operator: '\>', dsnr:false},
dur: {checked:true, value:4, operator: '\<'},
preval: {checked:true, value:300, operator: '\>'},
mmu: {checked:true, value:11},
};
//##########################################################################################
// END INPUTS
//##########################################################################################
// load the LandTrendr.js module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
// add index to changeParams object
changeParams.index = index;
// run landtrendr
var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, [], runParams, maskThese);
// get the change map layers
var changeImg = ltgee.getChangeMap(lt, changeParams);
// set visualization dictionaries
var palette = ['#9400D3', '#4B0082', '#0000FF', '#00FF00', '#FFFF00', '#FF7F00', '#FF0000'];
var yodVizParms = {
min: startYear,
max: endYear,
palette: palette
};
var magVizParms = {
min: 200,
max: 800,
palette: palette
};
// display the change attribute map - note that there are other layers - print changeImg to console to see
Map.centerObject(aoi, 11);
Map.addLayer(changeImg.select(['mag']), magVizParms, 'Magnitude of Change');
Map.addLayer(changeImg.select(['yod']), yodVizParms, 'Year of Detection');
// export change data to google drive
var region = aoi.buffer(1000).bounds();
var exportImg = changeImg.clip(region).unmask(0).short();
Export.image.toDrive(
{image: exportImg,description: 'lt-gee_disturbance_map',
folder: 'lt-gee_disturbance_map',
fileNamePrefix: 'lt-gee_disturbance_map',
region: region,
scale: 30,
crs: 'EPSG:5070',
maxPixels: 1e13});
It is throwing an error: Line 75: GeometryConstructors.Polygon: LinearRing requires at least 3 points. I am not sure what I am doing wrong here. Thank you for your help.

Related

Exporting NDWI values with Dates as CSV from Google Earth Engine

my goal is to create a csv file from the data that is chosen between dates. This was the code that I used for creating the NDWI values. I want to export that data with date so that I can create a graph from time series of NDWI - date. But I could not found how, any help is appreciated, thanks.
Map.centerObject(areaOfInterest);
Map.addLayer(areaOfInterest);
var startDate = '2018-07-01';
var endDate = '2018-07-31';
var sentinelImageCollection = ee.ImageCollection('COPERNICUS/S2')
.filterBounds(areaOfInterest)
.filterDate(startDate, endDate);
print("Number of images = ", sentinelImageCollection.size());
// We select the image with the smallest cloudy pixel percentage
var sentinelImage = sentinelImageCollection.sort('CLOUDY_PIXEL_PERCENTAGE')
.first()
.clip(areaOfInterest);
print("Sentinel image taken at = ", sentinelImage.date());
// Visualize using RGB
Map.addLayer(sentinelImage, {min: 0.0, max: 2000, bands: ['B4', 'B3', 'B2']}, 'RGB');
// Visualize using NDWI
var ndwi = sentinelImage.normalizedDifference(['B3', 'B8']).rename('NDWI');
Map.addLayer(ndwi, {palette: ['red', 'yellow', 'green', 'cyan', 'blue']}, 'NDWI');
// Calculate the area of our region of interest
var aoiArea = ee.Image.pixelArea().divide(1e6).reduceRegion({
reducer: ee.Reducer.sum(),
geometry: areaOfInterest,
scale: 10,
}).get('area');
print('AOI area (km2):', aoiArea);
// Create NDWI mask
var ndwiThreshold = ndwi.gte(0.0);
var ndwiMask = ndwiThreshold.updateMask(ndwiThreshold);
Map.addLayer(ndwiThreshold, {palette:['black','white']}, 'NDWI Binary Mask');
Map.addLayer(ndwiMask, {palette:['blue']}, 'NDWI Mask');
// We can now calculate the masked areas pixel area
var ndwiPixelArea = ee.Image.pixelArea().addBands(ndwiMask.select('NDWI')).divide(1e6).reduceRegion({
reducer: ee.Reducer.sum().group(1),
geometry: areaOfInterest,
scale: 10,
bestEffort: true
});
var list = ee.List(ee.Dictionary(ndwiPixelArea).get('groups'));
var group0 = ee.Dictionary(list.get(0));
var ndwiWaterArea = ee.Number(group0.get('sum')).float();
print("Water area (km2):", ndwiWaterArea);

I need to create an NDWI diagram in GEE, but I get an error

I want to generate a NDWI chart, but I get this error:
Error generating chart: No features contain non-null values of "system:time_start".
enter code here
var L8 = ee.ImageCollection("LANDSAT/LC08/C02/T1_RT_TOA")
.filterDate('2021-01-01', '2021-12-31')
.filterBounds(VolRn)
.filterMetadata('CLOUD_COVER', 'less_than', 1.5)
.mean()
.clip(VolRn);
var green = L8.select('B3');
var nir = L8.select('B5');
var ndwi = green.subtract(nir).divide(green.add(nir)).rename('NDWI');
var ndwiParams = {
min: -1,
max: 1,
palette: ['green', 'white', 'blue']
};
var ndwiMasked = ndwi.updateMask(ndwi.gte(0.001))
Map.setCenter(44.5858, 48.8047, 7);
Map.addLayer(ndwi, ndwiParams, 'NDWI image');
var options = {
title: 'Landsat Spectral Indexes',
hAxis: {title: 'Date'},
vAxis: {title: 'Value'},
lineWidth: 1,
maxPixels: 1e9,
series: {
0: {color: 'blue'}, // NDWI
}};
print(Chart.image.series(ndwi, VolRn, ee.Reducer.mean(), 200).setOptions(options));
enter code here
Can you please explain what this error is and how to fix it.
I am completely new to GEE and can't find information about this error.
I will be very grateful

How do I solve the 0 element problem 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);

How can I apply cloud masking to mndwi image in Earth Engine?

I want to apply cloud masking to a MDNWI image but I get the error message "s2SR.map is not a function". I don't know how to resolve it.
var geometry=ee.Geometry.Polygon([[41.55427215633343,41.57962485896675],
[41.607143860434995,41.57962485896675],
[41.607143860434995,41.62429558047125],
[41.55427215633343,41.62429558047125],
[41.55427215633343,41.57962485896675]]);
var s2SR = ee.ImageCollection('COPERNICUS/S2_SR')
//filter start and end date
.filter(ee.Filter.calendarRange(2018,2018,'year'))
.filter(ee.Filter.calendarRange(9,10,'month'))
//filter according to drawn boundary
.filterBounds(geometry)
.filterMetadata('CLOUD_COVERAGE_ASSESSMENT', 'less_than',1)
.mean();
//print(typeof(s2SR))
//print("s2SR", s2SR);
//Map.addLayer(s2SR, {bands: ['B4', 'B3', 'B2'], min: 0, max: 2000}, 'Sentinel ');
Map.centerObject(geometry,10)
var Green = s2SR.select("B3");
var SWIR = s2SR.select("B11");
var mndwi = Green.subtract(SWIR).divide(Green.add(SWIR)).rename('MNDWI');
//Map.addLayer(mndwi, {min:0, max:1}, 'mndwı');
///// Cloud
var S2maskedVeg = function(image) {
var MNDWI = image.select(['MNDWI']);
return image.addBands(ee.Image(1).updateMask(mndwi.gte(0.95)).rename('MNDVI_mask'));
};
var S2collection = s2SR.map(mndwi).map(S2maskedVeg)
Map.addLayer(S2collection,{}, 'S2 NDWI mask');
(https://code.earthengine.google.com/6835ca74e985d40df906681039358ee1)
Here, you already calculate the MNDWI over the whole collection:
var mndwi = Green.subtract(SWIR).divide(Green.add(SWIR)).rename('MNDWI');
Therefore, this line does not make much sense:
var S2collection = s2SR.map(mndwi).map(S2maskedVeg)
map() requires a function as input, but it is an ImageCollection. You can just skip this part and map your S2maskedVeg() function over mndwi directly:
var S2collection = mndwi.map(S2maskedVeg)

" image.select(bands).sampleRegions is not a function error. what must i do?

I am trying to conduct a lulc classification on google earth engine using landsat5 data for 2000, but every time it is showing me the error:
image.select(bands).sampleRegions is not a function
var shp = ee.FeatureCollection(mws)
Map.addLayer(shp, {}, 'My Polygon')
var pol = ee.FeatureCollection(poly2000)
Map.addLayer(pol, {} )
//landcover for 2000//
var dataset = ee.ImageCollection("LANDSAT/LT05/C01/T1_TOA")
.filterBounds(roi1)
.filterDate('2000-01-01', '2000-01-31')
.map(function(image){return image.clip(mws)});
var trueColor432 = dataset.select(['B4', 'B3', 'B2']);
var trueColor432Vis = {};
Map.setCenter(88.41713038056656,26.861987108179317);
Map.addLayer(trueColor432, trueColor432Vis, 'True Color (432)');
var image = trueColor432;
// merging sample points together
var landcover = forest.merge(water).merge(clearing).merge(built_up);
print(landcover);
// selecting bands
var bands= ['B2','B3','B4'];
//sampling the input imagery to get a featurecollection of a training data
var training = image.select(bands).sampleRegions({
collection: landcover,
properties: ['landcover'],
scale: 30
});
//training the classifier
var classifier= ee.Classifier.svm().train({
features: training,
classProperty : 'landcover',
inputProperties: bands
});
//classifying the input imagery
var classified= image.select(bands).classify(classifier);
sampleRegions samples the pixels of an image: https://developers.google.com/earth-engine/apidocs/ee-image-sampleregions
Maybe adding .toBands() works?
var training = image.toBands().select(bands).sampleRegions({
collection: landcover,
properties: ['landcover'],
scale: 30
});

Resources