Google Earth Engine: как отобразить функцию на совокупность всех датчиков Landsat для создания временных рядов NDVI
Я пытаюсь объединить все датчики Landsat (L4-18) 1980-х годов для представления в Google Earth Engine и рассчитать временные ряды индекса NDVI (после удаления облаков)
Я попытался найти способ обойти проблему, заключающуюся в том, что L8 использует разные полосы для NIR и RED, чем L4-L7, добавляя код из другого Q & A ( Google Earth Engine: замаскируйте облака и сопоставьте функцию с коллекцией изображений разные датчики)
Я получаю коллекцию изображений, содержащую все наборы данных landat с одной группой 'NDVI'. Однако когда я добавляю код для создания диаграммы временных рядов, я получаю следующую ошибку:
'Ошибка генерации диаграммы: ни одна функция не содержит ненулевые значения "system:time_start"'
Мне интересно, если это потому, что сбор производится из разных наборов данных датчика, но не знаю, как решить эту проблему.
Кто-нибудь может мне помочь?
Спасибо.
Ниже приведен код [ИЗМЕНЕНО, чтобы сделать код воспроизводимым]:
//Define a region of interest - Baringo county, kenya
var Baringo2 = /* color: #98ff00 */ee.Geometry.Polygon(
[[[35.69382363692023, 1.4034169899773616],
[35.69382363692023, 1.2606333558875118],
[35.61691934004523, 1.0079975313237526],
[35.58945351973273, 0.6509798625215468],
[35.71030312910773, 0.35436075019447294],
[35.72128945723273, 0.18956774160826206],
[35.61691934004523, 0.18407460674896256],
[35.58945351973273, 0.13463632293582842],
[35.71030312910773, 0.04125265421470341],
[35.68283730879523, -0.0466379620709295],
[35.74875527754523, -0.18945988757796725],
[35.96848184004523, 0.05223897866641199],
[36.09482461348273, 0.002800509340276178],
[36.27060586348273, 0.2719645271288622],
[36.23215371504523, 0.45872822561768967],
[36.32004434004523, 0.6509798625215468],
[36.47934609785773, 0.8651943843139164],
[36.32004434004523, 0.9915205478901427],
[36.18271523848273, 1.1672705367627716],
[36.08933144942023, 1.1892385469740003],
[35.79270059004523, 1.6944479915417494]]]);
//print (Baringo2);
//define land cover categories and sample points:
//DEG, 'Open Access Grazing'
var DEG2 = /* color: #d63000 */ee.Geometry.MultiPoint(
[[35.981082916259766, 0.44974818893112445],
[35.98460465669632, 0.4510302452289453],
[35.987091064453125, 0.451808061701256],
[35.98616033792496, 0.4483427545719104],
[35.987573862075806, 0.4297931417762091],
[35.9996223449707, 0.45043481325254864],
[36.06963872909546, 0.3470539601321629],
[36.06938123703003, 0.3475260202469071],
[36.069630682468414, 0.34738386578302555],
[36.070003509521484, 0.3475903920789125],
[36.06644153594971, 0.35022933035465353],
[36.05863630771637, 0.3589468796649346],
[36.05862021446228, 0.3589039651627689],
[35.98088979721069, 0.4486537280584078],
[36.07082426548004, 0.37428880110513496],
[36.07011079788208, 0.3772229960862265],
[36.032023429870605, 0.627012774441952],
[36.03208780288696, 0.6266319235542508],
[36.03143334388733, 0.6271683332472826],
[35.98740756511688, 0.4303348413873794],
[35.997237861156464, 0.44501955275654603]]);
//GM, 'Managed Grazing'
var GM2 = /* color: #8b1062 */ee.Geometry.MultiPoint(
[[36.030564308166504, 0.6268519274914895],
[36.03069305419922, 0.6269592094299815],
[36.03039264678955, 0.6268948402671484],
[36.03148698806763, 0.6315292660507418],
[36.03124022483826, 0.6309284876929263],
[36.03038191795349, 0.630005863651221],
[36.03060722351074, 0.6335886212975799],
[35.99500894513767, 0.5747552592254358],
[36.02037191456475, 0.5758710045457109],
[36.01653099125542, 0.5782526853495346],
[36.017239094435354, 0.5785959906083284],
[36.017346383450786, 0.5729096907628695],
[36.015372277615825, 0.5705065511240786],
[36.04236602652236, 0.5423771737070896],
[36.040499209047994, 0.539373233463203],
[36.04056358337402, 0.38151398068151043],
[36.03893280029297, 0.3785528870665109]]);
//REF, Nature Conservancy
var REF2 = /* color: #98ff00 */ee.Geometry.MultiPoint(
[[36.094207763671875, 0.22436084629270164],
[36.0926628112793, 0.2264207668774221],
[36.090946197509766, 0.23088392713673156],
[36.089229583740234, 0.23672036535773863],
[36.09781265258789, 0.6451750427539986],
[36.096739768981934, 0.6450033922571318],
[36.097726821899414, 0.6443597028423275],
[36.09734058380127, 0.6434156248868509],
[36.0975980758667, 0.642686109983424],
[36.123390197753906, 0.6421282455751846],
[36.124634742736816, 0.6414845557977334]]);
//CRO, 'Crops'
var CRO2 = /* color: #5980ff */ee.Geometry.MultiPoint(
[[36.044254302978516, 0.5421843671379806],
[36.04090690481826, 0.47892844903645376],
[36.041936873079976, 0.4832198321871975],
[36.03189468252822, 0.48802617809656],
[36.02786064016982, 0.4869962471182337],
[36.02193832266494, 0.4859663159825207],
[36.014471052767476, 0.47772686127176456],
[36.02193832266494, 0.47437957996379887],
[36.018505095125875, 0.4748087186837464],
[36.00992202627822, 0.47746937815196017],
[36.00906371939345, 0.4767827564520509],
[36.00382804739638, 0.47626779013219045],
[36.003398893954, 0.4747228909418917],
[36.010007856966695, 0.4700881913046016],
[36.014471052767476, 0.47128978039605285],
[36.01962089407607, 0.4713756081803616],
[36.02485656607314, 0.47970089820257816],
[36.02511405813857, 0.4857088331740545],
[36.04159355032607, 0.4773835504432214],
[36.032752989412984, 0.47377878571117404],
[36.00447177886963, 0.42708894038807443],
[36.002798080444336, 0.4288055062751536],
[36.00245475769043, 0.42777556678899614],
[36.00425720214844, 0.4239562066570169],
[36.00627422332764, 0.42588734403892814],
[36.00099563598633, 0.4293204759663003],
[36.00425720214844, 0.4286767638469664],
[36.00425720214844, 0.4327965204722641],
[36.008548736572266, 0.4323244651387205],
[36.01219654083252, 0.42425660583700076]]);
//mask clouds for L8, and then L5-7
// Function to cloud mask Landsat 8.
var maskL8SR = function(image) {
// Bits 3 and 5 are cloud shadow and cloud, respectively.
var cloudShadowBitMask = ee.Number(2).pow(3).int();
var cloudsBitMask = ee.Number(2).pow(5).int();
// Get the QA band.
var qa = image.select('pixel_qa');
// Both flags should be set to zero, indicating clear conditions.
var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0).and(
qa.bitwiseAnd(cloudsBitMask).eq(0));
return image
// Scale the data to reflectance and temperature.
.select(['B4', 'B5'], ['Red', 'NIR']).multiply(0.0001)
.updateMask(mask);
};
// Function to cloud mask Landsats 4-7
var maskL57SR = function(image) {
var qa = image.select('pixel_qa');
// Second bit must be zero, meaning none to low cloud confidence.
var mask1 = qa.bitwiseAnd(ee.Number(2).pow(7).int()).eq(0).and(
qa.bitwiseAnd(ee.Number(2).pow(3).int()).lte(0)); // cloud shadow
// This gets rid of noise at the edge of the images.
var mask2 = image.select('B.*').gt(0).reduce('min');
return image
.select(['B3', 'B4'], ['Red', 'NIR']).multiply(0.0001)
.updateMask(mask1.and(mask2));
};
//NDVI functions
//NDVI functions for l8
var addNDVI_l8 = function(image) {
var ndvi = image.normalizedDifference(['NIR', 'Red']).rename('NDVI');
return image.addBands(ndvi);
};
//NDVI functions for l4-7
var addNDVI_l457 = function(image) {
var ndvi = image.normalizedDifference(['NIR', 'Red']).rename('NDVI');
return image.addBands(ndvi);
};
// find all data and filter them by date and add NDVI
var lst5 = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR')
.filterDate('1984-10-01', '2011-10-01')
.filterBounds(Baringo2) // filter to area-of-interest;
.map(maskL57SR)
.map(addNDVI_l457).select('NDVI');
var lst7 = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR')
.filterDate('2011-10-01', '2013-04-07')
.filterBounds(Baringo2) // filter to area-of-interest;
.map(maskL57SR)
.map(addNDVI_l457).select('NDVI');
var lst8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
.filterDate('2013-04-07', '2018-05-01')
.filterBounds(Baringo2) // filter to area-of-interest;
.map(maskL8SR)
.map(addNDVI_l8).select('NDVI');
var lst7_08 = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR')
.filterDate('2007-12-01', '2008-02-01')
.filterBounds(Baringo2) // filter to area-of-interest;
.map(maskL57SR)
.map(addNDVI_l457).select('NDVI');
var lst7_92 = ee.ImageCollection('LANDSAT/LT04/C01/T1_SR')
.filterDate('1992-01-02', '1992-04-01')
.filterBounds(Baringo2) // filter to area-of-interest;
.map(maskL57SR)
.map(addNDVI_l457).select('NDVI');
// Combine all landsat data, 1985 through 2015
var everything = ee.ImageCollection(lst5.merge(lst7));
everything = everything.merge(lst8);
everything = everything.merge(lst7_08);
everything = everything.merge(lst7_92);
print(everything);
//NDVI time-series
// Create a time series chart for different land cover catergories.
// Define and display a FeatureCollection of three known locations.
var points = ee.FeatureCollection([
ee.Feature(DEG2, {'label': 'Open Access Grazing'}),
ee.Feature(GM2, {'label': 'Managed Grazing'}),
ee.Feature(REF2, {'label': 'Nature Conservancy'}),
ee.Feature(CRO2, {'label': 'Crops'})
]);
// Create a time series chart.
var NDVITimeSeriesAll = ui.Chart.image.seriesByRegion(
everything, points, ee.Reducer.mean(), 'NDVI', 30, 'system:time_start','label')
.setChartType('ScatterChart')
.setOptions({
title: 'Mean NDVI, plotted ~monthly, from 1984 to 2017 in 4 LC categories - Baringo Kenya',
hAxis: {title: ' Date'},
vAxis: {title: 'NDVI value (-1 to +1)', minValue: -0.0, maxValue: 0.8},
lineWidth: 1,
pointSize: 4,
series: {
0: {color: 'FF0000'}, // Unmanaged Grazing
1: {color: '00FF00'}, // Managed Grazing
2: {color: '0000FF'}, // Nature Conservancy
3: {color: '00FFFF'} // Cropland
}});
// Display.
print(NDVITimeSeriesAll);
1 ответ
system:time_start
собственность была потеряна на этапе маскировки. Это свойство необходимо для построения временных рядов, так как оно используется для построения временной оси. Измените эти две функции, чтобы переназначить это свойство изображению, которое возвращают функции, например:
var maskL8SR = function(image) {
// Bits 3 and 5 are cloud shadow and cloud, respectively.
var cloudShadowBitMask = ee.Number(2).pow(3).int();
var cloudsBitMask = ee.Number(2).pow(5).int();
// Get the QA band.
var qa = image.select('pixel_qa');
// Both flags should be set to zero, indicating clear conditions.
var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
.and(qa.bitwiseAnd(cloudsBitMask).eq(0));
return image
// Scale the data to reflectance and temperature.
.select(['B4', 'B5'], ['Red', 'NIR']).multiply(0.0001)
.updateMask(mask)
.set('system:time_start', image.get('system:time_start'));
};
Что в прошлом set()
функция принимает system:time_start
свойство из исходного входного изображения и назначает его выходному изображению, гарантируя, что все изображения в вашей выходной коллекции изображений содержат исходные метки времени. С set()
Функция, включенная в обе маскирующие функции, позволила создать графики временных рядов, написанные в вашем коде.