How to clip an image collection to a feature collection's geometry - google-earth-engine

I'm trying to clip an image collection to the province of Alberta, but filterBounds is not working. Thank you for any help you can offer! I would like the image collection to be clipped, not just the layer on the map, so when I perform operations on the image collection they will only be performed for Alberta
var Admins = ee.FeatureCollection("FAO/GAUL/2015/level1");
var Alberta = Admins.filter(ee.Filter.eq('ADM1_NAME', 'Alberta'));
print(Alberta)
Map.addLayer(Alberta, {}, 'Alberta')
Map.centerObject(Alberta, 6)
//Load NTL data for 2018, find the median value for each pixel
var dataset = ee.ImageCollection('NOAA/VIIRS/DNB/MONTHLY_V1/VCMSLCFG')
.filter(ee.Filter.date('2018-12-01', '2018-12-31'))
.filterBounds(Alberta); //here I'm trying to clip the image collection
var nighttime = dataset.select('avg_rad');
var nighttimeVis = {min: 0.0, max: 60.0};
print(nighttime)
Map.addLayer(nighttime.median(), nighttimeVis, 'Nighttime'); //this layer still shows the whole world :-(

One simple way is:
var dataset = ee.ImageCollection('NOAA/VIIRS/DNB/MONTHLY_V1/VCMSLCFG')
.filter(ee.Filter.date('2018-12-01', '2018-12-31'))
.map(function(image){return image.clip(Alberta)});

I figured it out. I wrote a function to clip the images and applied it over the image collection.
//Create feature for Alberta Boundary
var Admins = ee.FeatureCollection("FAO/GAUL/2015/level1");
var Alberta = Admins.filter(ee.Filter.eq('ADM1_NAME', 'Alberta'));
print(Alberta)
Map.addLayer(Alberta, {}, 'Alberta')
Map.centerObject(Alberta, 6)
//Load NTL data for 2018, find the median value for each pixel
var dataset = ee.ImageCollection('NOAA/VIIRS/DNB/MONTHLY_V1/VCMSLCFG')
.filter(ee.Filter.date('2018-12-01', '2018-12-31'))
.filterBounds(Alberta); //here I'm trying to clip the image to Alberta
function clp(img) {
return img.clip(Alberta)
}
var clippedVIIRS = dataset.map(clp)
print(clippedVIIRS)
var nighttime = clippedVIIRS.select('avg_rad');
var nighttimeVis = {min: 0.0, max: 60.0};
Map.addLayer(nighttime.median(), nighttimeVis, 'Nighttime');

Related

computing the math formula on the mask (google earth engine)

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".

consider the values for all pixels in a polygon in google earth engine

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

" 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
});

How to get the difference image of this month and the previous month in Google Earth Engine with a smart way?

How to get the difference image of this month and the previous month in Google Earth Engine with a smart way?
study area 25E-75E,5S-35N。
// study area 25E-75E,5S-35N。
var geometry =
ee.Geometry.Polygon(
[[[25, 35],
[25, 5],
[75, 5],
[75, 35]]], null, false);
var regions = ee.FeatureCollection([
ee.Feature(geometry)
]);
// imgCol
var now = ee.Date(Date.now());
var NDVICollection=ee.ImageCollection('MODIS/006/MOD13Q1')
.filterDate('2010-01-01',now)
.filterBounds(regions)
.select('NDVI');
var col = NDVICollection.map(function(img){
return img.multiply(0.0001)
.copyProperties(img,['system:time_start','system:time_end']);
});
// grouped by month
var months = ee.List([11,12,1,2]);
var byMonth = ee.ImageCollection.fromImages(
months.map(function (m) {
return col.filterDate('2019-11-01',now).filter(ee.Filter.calendarRange(m, m, 'month'))
.select('NDVI').mean()
.set('month', m);
}));
mask
var meanNDVI = byMonth.reduce(ee.Reducer.mean());
var mask = meanNDVI.gt(0.1);
Create difference image
**var img12 = byMonth.filter(ee.Filter.eq('month', ee.Number(12))).first().updateMask(mask);
var img11 = byMonth.filter(ee.Filter.eq('month', ee.Number(11))).first().updateMask(mask);
var img1 = byMonth.filter(ee.Filter.eq('month', ee.Number(1))).first().updateMask(mask);
var img2 = byMonth.filter(ee.Filter.eq('month', ee.Number(2))).first().updateMask(mask);
var ndviChange_12 = img12.subtract(img11).set('name','ndviChange_12');
var ndviChange_1 = img1.subtract(img12).set('name','ndviChange_1');
var ndviChange_2 = img12.subtract(img1).set('name','ndviChange_2');
var ndviChange = ee.ImageCollection([ndviChange_12,ndviChange_1,ndviChange_2]);**
I want make it much more smart, what should I do? make a function or something else?
Show the image
Map.centerObject(regions);
Map.addLayer(byMonth);
Map.addLayer(ndviChange);
I think the solution is to use iterate on your byMonth collection . Check this example in the documentations.
https://developers.google.com/earth-engine/ic_iterating

Dealing with MODIS equator gaps in GEE

I am trying to run a time series analysis for a Lake in Africa. Since my area of interest is at the equator it is affected by gaps every few days where the sensor has not covered the full area (see Figure below). An example is given in the code below for the 2nd October 2015, where only the edge of the lake is included in the MODIS path. If i include this image in my time series then the average across the AOI for that day is incorrect. So, I am looking for a way to filter the imageCollection to exclude dates when the full Area of Interest was not covered.
//Import image
var image = ee.Image('MOD09GA/MOD09GA_005_2015_10_02');
//Area of interest
var AOI = /* color: #d63000 */ee.Geometry.Polygon(
[[[35.48583984375, 2.1967272417616712],
[36.97998046875, 2.1967272417616712],
[37.1337890625, 4.631179340411012],
[35.3759765625, 4.653079918274051]]]);
// True Colour Composite
var visParams = {bands: ['sur_refl_b01', 'sur_refl_b04', 'sur_refl_b03']};
//Add to map
Map.addLayer(image, visParams, '2ndOct2015');
Image of MODIS daily path with gaps at equator:
https://eoimages.gsfc.nasa.gov/images/imagerecords/0/687/world_2000_110_rgb143_lrg.jpg
Thank you!
You could do something like this:
var mod09 = ee.ImageCollection("MODIS/006/MOD09GA");
var image = ee.Image('MOD09GA/MOD09GA_005_2015_10_02');
var visParams = {bands: ['sur_refl_b01', 'sur_refl_b04', 'sur_refl_b03']};
Map.addLayer(image, visParams, '2ndOct2015');
//Area of interest
var AOI = /* color: #d63000 */ee.Geometry.Polygon(
[[[35.48583984375, 2.1967272417616712],
[36.97998046875, 2.1967272417616712],
[37.1337890625, 4.631179340411012],
[35.3759765625, 4.653079918274051]]]);
Map.centerObject(AOI);
Map.addLayer(AOI);
var count = image.select('sur_refl_b01').unmask().reduceRegion({
reducer: 'count',
geometry: AOI,
scale: image.select('sur_refl_b01').projection().nominalScale(),
});
print(count);
var counter = function(image) {
return image.set(image.select('sur_refl_b01').unmask().reduceRegion({
reducer: ee.Reducer.count(),
geometry: AOI,
scale: image.select('sur_refl_b01').projection().nominalScale(),
}));
};
var filteredCollection = mod09
.filterDate('2016-01-01', '2016-12-31')
.map(counter)
// You probably want to add some delta here.
.filter(ee.Filter.gte('sur_refl_b01', count.get('sur_refl_b01')));
print(filteredCollection);
This seems to work, which i adapted from a thread on GEE help forum.
////// MODIS COLLECTION ////////
var ci = ee.ImageCollection('MOD09GA').filterDate('2015-10-01', '2016 08-05');
// Function to exclude MODIS swath gaps
function filterEmpty(imageCollection, polygon) {
var scale = 500
return imageCollection.map(function(i) {
return i.set('first_value', i.select(0)
.reduceRegion({reducer: ee.Reducer.firstNonNull(), geometry: polygon, scale: scale})
.values().get(0))
}).filter(ee.Filter.eq('first_value', 1))
}
var c = filterEmpty(ci, Turkana);
print(c);

Resources