mercoledì 11 febbraio 2026

Analisi multitemporale NDVI con Google Earth Engine

Qualche esperimento con Google Earth Engine per vedere come si modifica nel tempo NDVI (arco di decenni fornito da Landsat)

 


 

// 1. Coordinate e Geometria
//var lon = 10.913507726271437;
//var lat = 43.01194709215584;

var lon = 10.926468160041452;
var lat = 43.01919548868449;


var poi = ee.Geometry.Point([lon, lat]);

// 2. Funzione di pre-elaborazione (Mask Cloud e Scaling)
// Valida per Landsat 5 e Landsat 7 (Collection 2 Level 2)
function preprocessLandsat(image) {
  var qa = image.select('QA_PIXEL');
  
  // Maschera per nuvole, ombre e cirri
  var mask = qa.bitwiseAnd(1 << 1).eq(0)
    .and(qa.bitwiseAnd(1 << 2).eq(0))
    .and(qa.bitwiseAnd(1 << 3).eq(0))
    .and(qa.bitwiseAnd(1 << 4).eq(0));

  // Fattori di scala per Collection 2
  var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);
  
  // Calcolo NDVI (NIR è B4, RED è B3 per entrambi i sensori L5 e L7)
  var ndvi = opticalBands.normalizedDifference(['SR_B4', 'SR_B3']).rename('NDVI');
  
  return image.addBands(ndvi).updateMask(mask);
}

// 3. Caricamento Collezione LANDSAT 5 (1985 - 2010)
var l5Col = ee.ImageCollection("LANDSAT/LT05/C02/T1_L2")
  .filterBounds(poi)
  .filterDate('1985-01-01', '2010-01-01')
  .map(preprocessLandsat);

// 4. Caricamento Collezione LANDSAT 7 (2010 - 2024)
var l7Col = ee.ImageCollection("LANDSAT/LE07/C02/T1_L2")
  .filterBounds(poi)
  .filterDate('2010-01-01', '2024-01-01')
  .map(preprocessLandsat);

// 5. Unione delle due collezioni
var mergedCol = l5Col.merge(l7Col);

// 6. Creazione del Grafico Temporale
var chart = ui.Chart.image.series({
  imageCollection: mergedCol.select('NDVI'),
  region: poi,
  reducer: ee.Reducer.mean(),
  scale: 30,
  xProperty: 'system:time_start'
})
.setOptions({
  title: 'Serie Storica NDVI: Landsat 5 e Landsat 7 (1985-2024)',
  vAxis: {title: 'NDVI', viewWindow: {min: -0.1, max: 1}},
  hAxis: {title: 'Anno', format: 'YYYY'},
  lineWidth: 1,
  pointSize: 2,
  trendlines: {0: {color: 'red', lineWidth: 1, opacity: 0.7}}, // Linea di tendenza globale
  series: {
    0: {color: '228B22'} // Colore verde foresta
  }
});

// 7. Visualizzazione
print(chart);
Map.centerObject(poi, 13);
Map.addLayer(poi, {color: 'red'}, 'Sito di analisi'); 

 

 

uno script piu' evoluto si puo'trovare qui. L'interesse e' che non viene calcolato un singolo punto ma il valore medio di un'area che risulta sicuramente piu' significativo
 

modificando per l'area di interesse

 

// 1. Definizione dell'Area di Studio (Rettangolo)
var areaOfInterest = ee.Geometry.Polygon([
  [[10.910535746643099, 43.01138938313477],
   [10.91448395831302, 43.01138938313477],
   [10.91448395831302, 43.00825125524326],
   [10.910535746643099, 43.00825125524326],
   [10.910535746643099, 43.01138938313477]]
]);

Map.centerObject(areaOfInterest, 15);
Map.addLayer(areaOfInterest, {color: 'd63000'}, 'Area di Studio');

// 2. Funzione Processamento con Soglia NDVI > 0.55
var processLandsat = function(image, nir, red) {
  var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);
  var ndvi = opticalBands.normalizedDifference([nir, red]).rename('NDVI');
  
  // FILTRO: Manteniamo solo i pixel dove NDVI è maggiore di 0.55
  var maskThreshold = ndvi.gt(0.55);
  
  return image.addBands(ndvi).select('NDVI')
    .updateMask(maskThreshold) // Rimuove i valori bassi
    .copyProperties(image, ['system:time_start']);
};

// 3. Caricamento Collezioni
var L5 = ee.ImageCollection("LANDSAT/LT05/C02/T1_L2").filterBounds(areaOfInterest)
  .map(function(img) { return processLandsat(img, 'SR_B4', 'SR_B3'); });

var L7 = ee.ImageCollection("LANDSAT/LE07/C02/T1_L2").filterBounds(areaOfInterest)
  .map(function(img) { return processLandsat(img, 'SR_B4', 'SR_B3'); });

var L8 = ee.ImageCollection("LANDSAT/LC08/C02/T1_L2").filterBounds(areaOfInterest)
  .map(function(img) { return processLandsat(img, 'SR_B5', 'SR_B4'); });

var L9 = ee.ImageCollection("LANDSAT/LC09/C02/T1_L2").filterBounds(areaOfInterest)
  .map(function(img) { return processLandsat(img, 'SR_B5', 'SR_B4'); });

var mergedNDVI = L5.merge(L7).merge(L8).merge(L9);

// 4. Composizione Mensile (Massimo Valore)
var years = ee.List.sequence(1984, 2024);
var months = ee.List.sequence(1, 12);

var monthlyNDVI = ee.ImageCollection.fromImages(
  years.map(function(y) {
    return months.map(function(m) {
      var d = ee.Date.fromYMD(y, m, 1);
      return mergedNDVI
        .filter(ee.Filter.calendarRange(y, y, 'year'))
        .filter(ee.Filter.calendarRange(m, m, 'month'))
        .max() // Seleziona il valore più alto (più verde) del mese
        .set('system:time_start', d.millis());
    });
  }).flatten()
);

// Rimuoviamo i periodi senza dati (es. inverno o periodi sotto soglia)
var monthlyNDVI_Clean = monthlyNDVI.filter(ee.Filter.listContains('system:band_names', 'NDVI'));

// 5. Grafico
var chart = ui.Chart.image.series({
  imageCollection: monthlyNDVI_Clean,
  region: areaOfInterest,
  reducer: ee.Reducer.mean(),
  scale: 30,
  xProperty: 'system:time_start'
})
.setOptions({
  title: 'NDVI Filtrato (>0.55) - Peak Vegetation Trend',
  vAxis: {title: 'NDVI', viewWindow: {min: 0.55, max: 0.9}},
  hAxis: {title: 'Anno', format: 'YYYY'},
  trendlines: {0: {color: 'red', lineWidth: 1}},
  series: {0: {color: '228B22', pointSize: 2, lineWidth: 1}}
});

print(chart); 

 


 


in generale sembra che NDVI sia migliorato a partire dal 2013

Nessun commento:

Posta un commento

Mappa NDVI medio annuale con Google Earth Engine

Al contrario del precedente post https://debiaonoldcomputers.blogspot.com/2026/02/analisi-multitemporale-ndvi-con-google.html  qui l'ide...