Visualisation ImageCollection

Les images qui composent une ImageCollection peuvent être visualisées sous forme d'animation ou de série de miniatures appelées "filmstrip". Ces méthodes permettent d'évaluer rapidement le contenu d'une ImageCollection et constituent un moyen efficace de constater les changements spatiotemporels (figure 1).

Les sections suivantes décrivent comment préparer une ImageCollection pour la visualisation, fournissent un exemple de code pour chaque méthode de visualisation de la collection et couvrent plusieurs techniques d'animation avancées.


Figure 1. Animation montrant l'évolution des ouragans de l'Atlantique sur trois jours en septembre 2017.

Préparation de la collecte

Filtrez, composez, triez et stylisez les images d'une collection pour n'afficher que celles qui vous intéressent ou pour mettre en avant un phénomène. Vous pouvez fournir n'importe quel ImageCollection comme entrée aux fonctions de visualisation, mais une collection sélectionnée en tenant compte des plages de dates inter- et intra-annuelles, de l'intervalle d'observation, de l'étendue régionale, de la qualité et de la représentation peut donner de meilleurs résultats.

Filtrage

Filtrez une collection d'images pour n'inclure que les données pertinentes qui servent l'objectif de la visualisation. Tenez compte des dates, de l'étendue spatiale, de la qualité et d'autres propriétés spécifiques à un ensemble de données donné.

Par exemple, filtrez une collection de réflectance de surface Sentinel-2 par:

une seule période,

Éditeur de code (JavaScript)

var s2col = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterDate('2018-01-01', '2019-01-01');

une plage de jours de l'année,

Éditeur de code (JavaScript)

var s2col = ee.ImageCollection('COPERNICUS/S2_SR')
  .filter(ee.Filter.calendarRange(171, 242, 'day_of_year'));

une région d'intérêt,

Éditeur de code (JavaScript)

var s2col = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterBounds(ee.Geometry.Point(-122.1, 37.2));

ou une propriété d'image.

Éditeur de code (JavaScript)

var s2col = ee.ImageCollection('COPERNICUS/S2_SR')
  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 50));

Enchaîner plusieurs filtres.

Éditeur de code (JavaScript)

var s2col = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterDate('2018-01-01', '2019-01-01')
  .filterBounds(ee.Geometry.Point(-122.1, 37.2))
  .filter('CLOUDY_PIXEL_PERCENTAGE < 50');

Composition

Combinez des plages de dates intra- et interannuelles pour réduire le nombre d'images dans une collection et améliorer la qualité. Par exemple, imaginons que vous souhaitiez créer une visualisation du NDVI annuel pour l'Afrique. Vous pouvez simplement filtrer une collection NDVI MODIS de 16 jours pour inclure toutes les observations de 2018.

Éditeur de code (JavaScript)

var ndviCol = ee.ImageCollection('MODIS/006/MOD13A2')
  .filterDate('2018-01-01', '2019-01-01')
  .select('NDVI');

Composite interannuel par filtre et réduction

La visualisation de la collection ci-dessus montre un bruit considérable dans les régions boisées où la couverture nuageuse est importante (figure 2a). Une meilleure représentation peut être obtenue en réduisant les plages de dates séquentielles en fonction de la médiane pour toutes les années de la collection MODIS.

Éditeur de code (JavaScript)

// Make a day-of-year sequence from 1 to 365 with a 16-day step.
var doyList = ee.List.sequence(1, 365, 16);

// Import a MODIS NDVI collection.
var ndviCol = ee.ImageCollection('MODIS/006/MOD13A2').select('NDVI');

// Map over the list of days to build a list of image composites.
var ndviCompList = doyList.map(function(startDoy) {
  // Ensure that startDoy is a number.
  startDoy = ee.Number(startDoy);

  // Filter images by date range; starting with the current startDate and
  // ending 15 days later. Reduce the resulting image collection by median.
  return ndviCol
    .filter(ee.Filter.calendarRange(startDoy, startDoy.add(15), 'day_of_year'))
    .reduce(ee.Reducer.median());
});

// Convert the image List to an ImageCollection.
var ndviCompCol = ee.ImageCollection.fromImages(ndviCompList);

L'animation issue de cette collection est moins bruyante, car chaque image représente la médiane d'un composite NDVI sur 16 jours pour plus de 20 ans de données (figure 1b). Pour en savoir plus sur cette animation, consultez ce tutoriel.

Figure 2a. NDVI annuel sans composition interannuelle. Figure 2b. NDVI annuel avec composition interannuelle.

Composite intra-annuel par filtre et réduction

L'exemple précédent applique une composition interannuelle. Il peut également être utile de composer une série d'observations intra-annuelles. Par exemple, les données Landsat sont collectées tous les 16 jours pour une scène donnée par capteur, mais une partie des images est souvent masquée par des nuages. Masquer les nuages et composer plusieurs images de la même saison peut produire une représentation plus claire. Prenons l'exemple suivant, où les images Landsat 5 de juillet et d'août sont composées à l'aide de la médiane pour chaque année de 1985 à 2011.

Éditeur de code (JavaScript)

// Assemble a collection of Landsat surface reflectance images for a given
// region and day-of-year range.
var lsCol = ee.ImageCollection('LANDSAT/LT05/C02/T1_L2')
  .filterBounds(ee.Geometry.Point(-122.9, 43.6))
  .filter(ee.Filter.dayOfYear(182, 243))
  // Add the observation year as a property to each image.
  .map(function(img) {
    return img.set('year', ee.Image(img).date().get('year'));
  });


// Define a function to scale the data and mask unwanted pixels.
function maskL457sr(image) {
  // Bit 0 - Fill
  // Bit 1 - Dilated Cloud
  // Bit 2 - Unused
  // Bit 3 - Cloud
  // Bit 4 - Cloud Shadow
  var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0);
  var saturationMask = image.select('QA_RADSAT').eq(0);

  // Apply the scaling factors to the appropriate bands.
  var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);
  var thermalBand = image.select('ST_B6').multiply(0.00341802).add(149.0);

  // Replace the original bands with the scaled ones and apply the masks.
  return image.addBands(opticalBands, null, true)
      .addBands(thermalBand, null, true)
      .updateMask(qaMask)
      .updateMask(saturationMask);
}

// Define a list of unique observation years from the image collection.
var years = ee.List(lsCol.aggregate_array('year')).distinct().sort();

// Map over the list of years to build a list of annual image composites.
var lsCompList = years.map(function(year) {
  return lsCol
    // Filter image collection by year.
    .filterMetadata('year', 'equals', year)
    // Apply cloud mask.
    .map(maskL457sr)
    // Reduce image collection by median.
    .reduce(ee.Reducer.median())
    // Set composite year as an image property.
    .set('year', year);
});

// Convert the image List to an ImageCollection.
var lsCompCol = ee.ImageCollection.fromImages(lsCompList);

Composite intra-annuel par jointure et réduction

Notez que les deux méthodes de composition précédentes mappent sur une List de jours et d'années pour définir progressivement de nouvelles dates à filtrer et à composer. Vous pouvez également effectuer cette opération en appliquant une jointure. Dans l'extrait de code suivant, une collection d'année unique est définie, puis une jointure saveAll est appliquée pour identifier toutes les images correspondant à une année donnée. Les images appartenant à une année donnée sont regroupées dans un objet List, qui est stocké en tant que propriété du représentant de l'année respective dans la collection d'années distinctes. Les composites annuels sont générés à partir de ces listes en réduisant les ImageCollections définies par elles dans une fonction mappée sur la collection d'années distinctes.

Éditeur de code (JavaScript)

// Assemble a collection of Landsat surface reflectance images for a given
// region and day-of-year range.
var lsCol = ee.ImageCollection('LANDSAT/LT05/C02/T1_L2')
  .filterBounds(ee.Geometry.Point(-122.9, 43.6))
  .filter(ee.Filter.dayOfYear(182, 243))
  // Add the observation year as a property to each image.
  .map(function(img) {
    return img.set('year', ee.Image(img).date().get('year'));
  });

// Make a distinct year collection; one image representative per year.
var distinctYears = lsCol.distinct('year').sort('year');

// Define a join filter; one-to-many join on ‘year’ property.
var filter = ee.Filter.equals({leftField: 'year', rightField: 'year'});

// Define a join.
var join = ee.Join.saveAll('year_match');

// Apply the join; results in 'year_match' property being added to each distinct
// year representative image. The list includes all images in the collection
// belonging to the respective year.
var joinCol = join.apply(distinctYears, lsCol, filter);

// Define a function to scale the data and mask unwanted pixels.
function maskL457sr(image) {
  // Bit 0 - Fill
  // Bit 1 - Dilated Cloud
  // Bit 2 - Unused
  // Bit 3 - Cloud
  // Bit 4 - Cloud Shadow
  var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0);
  var saturationMask = image.select('QA_RADSAT').eq(0);

  // Apply the scaling factors to the appropriate bands.
  var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);
  var thermalBand = image.select('ST_B6').multiply(0.00341802).add(149.0);

  // Replace the original bands with the scaled ones and apply the masks.
  return image.addBands(opticalBands, null, true)
      .addBands(thermalBand, null, true)
      .updateMask(qaMask)
      .updateMask(saturationMask);
}

// Map over the distinct years collection to build a list of annual image
// composites.
var lsCompList = joinCol.map(function(img) {
  // Get the list of images belonging to the given year.
  return ee.ImageCollection.fromImages(img.get('year_match'))
    // Apply cloud mask.
    .map(maskL457sr)
    // Reduce image collection by median.
    .reduce(ee.Reducer.median())
    // Set composite year as an image property.
    .copyProperties(img, ['year']);
});

// Convert the image List to an ImageCollection.
var lsCompCol = ee.ImageCollection(lsCompList);

Composite du même jour par association et réduction

Un autre cas de composition consiste à créer des mosaïques d'images contiguës spatialement. Supposons que votre région d'intérêt s'étende sur deux lignes Landsat dans le même chemin, et que votre objectif soit d'afficher une mosaïque d'images des deux images pour chaque orbite Landsat 8 en 2017 et 2018. Ici, après avoir filtré la collection par chemin et ligne, une opération de jointure est utilisée pour créer une mosaïque d'images Landsat de la même orbite, définie par la date d'acquisition.

Éditeur de code (JavaScript)

var lsCol = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
  .filterDate('2017-01-01', '2019-01-01')
  .filter('WRS_PATH == 38 && (WRS_ROW == 28 || WRS_ROW == 29)')
  .map(function(img) {
    var date = img.date().format('YYYY-MM-dd');
    return img.set('date', date);
  });

var distinctDates = lsCol.distinct('date').sort('date');
var filter = ee.Filter.equals({leftField: 'date', rightField: 'date'});
var join = ee.Join.saveAll('date_match');
var joinCol = join.apply(distinctDates, lsCol, filter);

var lsColMos = ee.ImageCollection(joinCol.map(function(col) {
  return ee.ImageCollection.fromImages(col.get('date_match')).mosaic();
}));

Tri

Triez une collection par date pour assurer une séquence chronologique correcte ou triez-la par propriété de votre choix. Par défaut, la série de cadres de visualisation est triée dans l'ordre naturel de la collection. La disposition de la série peut être modifiée à l'aide de la méthode de collection sort, dans laquelle une propriété Image est sélectionnée pour le tri par ordre croissant ou décroissant. Par exemple, pour trier par heure d'observation, utilisez la propriété system:time_start omniprésente.

Éditeur de code (JavaScript)

var s2col = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterBounds(ee.Geometry.Point(-122.1, 37.2))
  .sort('system:time_start');

L'ordre pourrait également être défini en fonction de l'augmentation de l'opacité des nuages, comme dans le cas des images Sentinel-2.

Éditeur de code (JavaScript)

var s2col = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterBounds(ee.Geometry.Point(-122.1, 37.2))
  .sort('CLOUDY_PIXEL_PERCENTAGE');

L'ordre peut également être défini par une propriété dérivée, telle que l'indice NDVI régional moyen. Ici, l'indice NDVI régional est ajouté en tant que propriété à chaque image dans une fonction mappée, suivie d'un tri sur la nouvelle propriété.

Éditeur de code (JavaScript)

// Define an area of interest geometry.
var aoi = ee.Geometry.Point(-122.1, 37.2).buffer(1e4);

// Filter MODIS NDVI image collection by a date range.
var ndviCol = ee.ImageCollection('MODIS/061/MOD13A1')
  .filterDate('2018-01-01', '2019-01-01')
  .select('NDVI')
  // Map over the image collection to calculate regional mean NDVI and add
  // the result to each image as a property.
  .map(function(img) {
    var meanNdvi = img.reduceRegion({
      reducer: ee.Reducer.mean(), geometry: aoi, scale: 500});
    return img.set('meanNdvi', meanNdvi.get('NDVI'));
  })
  // Sort the collection by descending regional mean NDVI.
  .sort('meanNdvi', false);

Visualisation des images

La visualisation d'images transforme les chiffres en couleurs. Il existe trois façons de contrôler la représentation des données d'image sous forme de couleur dans les méthodes de visualisation de la collection:

  1. Fournissez des arguments de visualisation directement à getVideoThumbURL et getFilmstripThumbURL.
  2. Mappez la méthode d'image visualize sur la collection d'images avant d'appliquer getVideoThumbURL et getFilmstripThumbURL.
  3. Mappez la méthode d'image sldStyle sur la collection d'images avant d'appliquer getVideoThumbURL et getFilmstripThumbURL. Pour en savoir plus, consultez la section Styled Layer Descriptor.

Les exemples de ce guide utilisent les options 1 et 2, où la visualisation est obtenue en mappant trois bandes d'image d'une image multibande sur les canaux de couleur rouge, vert et bleu, ou en graduant les valeurs d'une seule bande de manière linéaire le long d'une palette de couleurs. Les paramètres de visualisation incluent les suivants:

Paramètres de visualisation
Paramètre Description Type
bandes Liste des trois noms de bandes à mapper sur RGB, séparés par une virgule list
min Valeur(s) à mapper sur 0 nombre ou liste de trois nombres, un pour chaque bande
max Valeur(s) à mapper sur 255 nombre ou liste de trois nombres, un pour chaque bande
gain Valeur(s) à multiplier par chaque valeur de pixel nombre ou liste de trois nombres, un pour chaque bande
biais Valeur(s) à ajouter à chaque DN nombre ou liste de trois nombres, un pour chaque bande
gamma Facteur(s) de correction de gamma nombre ou liste de trois nombres, un pour chaque bande
palette Liste des chaînes de couleur de style CSS (images à bande unique uniquement) Liste de chaînes hexadécimales séparées par une virgule
opacité Opacité du calque (0,0 correspond à une transparence totale et 1,0 à une opacité totale) Total

Utilisez l'argument bands pour sélectionner la ou les bandes que vous souhaitez visualiser. Fournissez une liste d'un à trois noms de groupes. Pour les images multibandes, les trois premières bandes sont sélectionnées par défaut. L'ordre des noms de bande détermine l'attribution des couleurs. Les bandes 1, 2 et 3 sont mappées respectivement sur le rouge, le vert et le bleu.

La mise à l'échelle de la plage de données est un élément important à prendre en compte lors de la visualisation d'images. Par défaut, les valeurs de données à virgule flottante comprises entre 0 et 1 (inclus) sont mises à l'échelle entre 0 et 255 (inclus). Les valeurs en dehors de cette plage sont forcées sur 0 et 255, selon qu'elles sont inférieures à 0 ou supérieures à 1, respectivement. En ce qui concerne les données entières, la capacité totale définie par son type est mise à l'échelle entre 0 et 255 (par exemple, les données signées 16 bits ont une plage allant de −32 768 à 32 767, qui est mise à l'échelle sur [0, 255] par défaut). Accepter les valeurs par défaut peut souvent entraîner des visualisations avec peu ou pas de contraste entre les éléments de l'image. Utilisez min et max pour améliorer le contraste et mettre en avant une plage de données spécifique. En règle générale, définissez min et max sur des valeurs qui représentent les 2e et 98e centiles des données dans votre domaine d'intérêt. Consultez l'exemple suivant pour calculer ces valeurs pour un modèle numérique d'élévation.

Éditeur de code (JavaScript)

// Import SRTM global elevation model.
var demImg = ee.Image('USGS/SRTMGL1_003');

// Define a rectangular area of interest.
var aoi = ee.Geometry.Polygon(
  [[
    [-103.84153083119054, 49.083004219142886],
    [-103.84153083119054, 25.06838270664608],
    [-85.64817145619054, 25.06838270664608],
    [-85.64817145619054, 49.083004219142886]
  ]],
  null, false);

// Calculate the 2nd and 98th percentile elevation values from rescaled (to
// 500m) pixels intersecting the area of interest. A Dictionary is returned.
var percentClip = demImg.reduceRegion({
  reducer: ee.Reducer.percentile([2, 98]),
  geometry: aoi,
  scale: 500,
  maxPixels: 3e7
});

// Print the regional 2nd and 98th percentile elevation values. Get the
// dictionary keys and use them to get the values for each percentile summary.
var keys = percentClip.keys();
print('Set vis min to:', ee.Number(percentClip.get(keys.get(0))).round());
print('Set vis max to:', ee.Number(percentClip.get(keys.get(1))).round());

Le paramètre palette définit les couleurs à utiliser pour représenter l'image d'affichage 8 bits. Il ne s'applique qu'aux représentations monobandes. Si vous le spécifiez avec une image multibande, vous recevrez une erreur. Si les données sont monobandes ou si vous souhaitez visualiser une seule bande à partir d'une image multibande, définissez le paramètre forceRgbOutput sur true (inutile si l'argument palette est fourni). Utilisez les paramètres min et max pour définir la plage de valeurs à mettre à l'échelle linéaire entre 0 et 255.

Vous trouverez ci-dessous un exemple de mappage d'une fonction de visualisation sur une collection d'images monobandes. Une collection NDVI MODIS est importée, les arguments de visualisation de la méthode visualization sont définis et une fonction qui transforme les valeurs en représentations d'images RVB est mappée sur la collection NDVI.

Éditeur de code (JavaScript)

// Filter MODIS NDVI image collection by a date range.
var ndviCol = ee.ImageCollection('MODIS/061/MOD13A1')
  .filterDate('2018-01-01', '2019-01-01')
  .select('NDVI');

// Define visualization arguments.
var visArgs = {
  min: 0,
  max: 9000,
  palette: [
    'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
    '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
    '012E01', '011D01', '011301'
  ]
};

// Define a function to convert an image to an RGB visualization image and copy
// properties from the original image to the RGB image.
var visFun = function(img) {
  return img.visualize(visArgs).copyProperties(img, img.propertyNames());
};

// Map over the image collection to convert each image to an RGB visualization
// using the previously defined visualization function.
var ndviColVis = ndviCol.map(visFun);

Voici un exemple de mappage d'une fonction de visualisation sur une collection d'images multibandes:

Éditeur de code (JavaScript)

// Assemble a collection of Sentinel-2 surface reflectance images for a given
// region and date range.
var s2col = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterBounds(ee.Geometry.Point(-96.9037, 48.0395))
  .filterDate('2019-06-01', '2019-10-01');

// Define visualization arguments.
var visArgs = {bands: ['B11', 'B8', 'B3'], min: 300, max: 3500};

// Define a function to convert an image to an RGB visualization image and copy
// properties from the original image to the RGB image.
var visFun = function(img) {
  return img.visualize(visArgs).copyProperties(img, img.propertyNames());
};

// Map over the image collection to convert each image to an RGB visualization
// using the previously defined visualization function.
var s2colVis = s2col.map(visFun);

Dans ce cas, aucun argument de palette n'est fourni, car trois bandes sont fournies, qui définissent l'intensité pour chaque calque RVB. Notez que les deux exemples utilisent les paramètres min et max pour contrôler les valeurs étirées jusqu'aux limites des données RVB 8 bits.

Miniature vidéo

La fonction getVideoThumbURL() génère une animation à partir de toutes les images d'un ImageCollection, où chaque image représente un frame. Le workflow général pour créer une animation est le suivant:

  1. Définissez une Geometry dont les limites déterminent l'étendue régionale de l'animation.
  2. Définissez un ImageCollection.
  3. Envisagez la visualisation d'images: mappez une fonction de visualisation d'images sur la collection ou ajoutez des arguments de visualisation d'images à l'ensemble d'arguments d'animation.
  4. Définissez les arguments d'animation et appelez la méthode getVideoThumbURL.

Le résultat de getVideoThumbURL est une URL. Imprimez l'URL dans la console, puis cliquez dessus pour démarrer les serveurs Earth Engine qui génèrent l'animation instantanément dans un nouvel onglet du navigateur. Vous pouvez également afficher l'animation dans la console de l'éditeur de code en appelant la fonction ui.Thumbnail sur la collection et ses arguments d'animation correspondants. Une fois l'animation générée, vous pouvez la télécharger en effectuant un clic droit dessus et en sélectionnant les options appropriées dans le menu contextuel.

L'exemple suivant illustre la génération d'une animation représentant les températures mondiales sur 24 heures. Notez que cet exemple inclut des arguments de visualisation ainsi que des arguments d'animation, au lieu de mapper d'abord une fonction de visualisation sur ImageCollection. Lorsque vous exécutez ce script, une animation semblable à la figure 3 doit s'afficher dans la console de l'éditeur de code.

Éditeur de code (JavaScript)

// Define an area of interest geometry with a global non-polar extent.
var aoi = ee.Geometry.Polygon(
  [[[-179.0, 78.0], [-179.0, -58.0], [179.0, -58.0], [179.0, 78.0]]], null,
  false);

// Import hourly predicted temperature image collection for northern winter
// solstice. Note that predictions extend for 384 hours; limit the collection
// to the first 24 hours.
var tempCol = ee.ImageCollection('NOAA/GFS0P25')
  .filterDate('2018-12-22', '2018-12-23')
  .limit(24)
  .select('temperature_2m_above_ground');

// Define arguments for animation function parameters.
var videoArgs = {
  dimensions: 768,
  region: aoi,
  framesPerSecond: 7,
  crs: 'EPSG:3857',
  min: -40.0,
  max: 35.0,
  palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red']
};

// Print the animation to the console as a ui.Thumbnail using the above defined
// arguments. Note that ui.Thumbnail produces an animation when the first input
// is an ee.ImageCollection instead of an ee.Image.
print(ui.Thumbnail(tempCol, videoArgs));

// Alternatively, print a URL that will produce the animation when accessed.
print(tempCol.getVideoThumbURL(videoArgs));


Figure 3. Température de surface horaire pour le solstice d'hiver dans l'hémisphère nord représentée sous forme d'image GIF animée.

Pellicule

La fonction getFilmstripThumbUrl génère une seule image statique représentant la concaténation de toutes les images d'un ImageCollection dans une série nord-sud. La séquence des images de la pellicule suit l'ordre naturel de la collection.

Le résultat de getFilmstripThumbUrl est une URL. Imprimez l'URL dans la console, puis cliquez dessus pour démarrer les serveurs Earth Engine qui génèrent l'image instantanément dans un nouvel onglet du navigateur. Une fois l'image affichée, vous pouvez la télécharger en effectuant un clic droit dessus et en sélectionnant les options appropriées dans son menu contextuel.

L'extrait de code suivant utilise la même collection que l'exemple d'aperçu vidéo ci-dessus. Lorsque vous exécutez ce script, une pellicule semblable à la figure 4 doit s'afficher dans la console de l'éditeur de code.

Éditeur de code (JavaScript)

// Define an area of interest geometry with a global non-polar extent.
var aoi = ee.Geometry.Polygon(
  [[[-179.0, 78.0], [-179.0, -58.0], [179.0, -58.0], [179.0, 78.0]]], null,
  false);

// Import hourly predicted temperature image collection for northern winter
// solstice. Note that predictions extend for 384 hours; limit the collection
// to the first 24 hours.
var tempCol = ee.ImageCollection('NOAA/GFS0P25')
  .filterDate('2018-12-22', '2018-12-23')
  .limit(24)
  .select('temperature_2m_above_ground');

// Define arguments for the getFilmstripThumbURL function parameters.
var filmArgs = {
  dimensions: 128,
  region: aoi,
  crs: 'EPSG:3857',
  min: -40.0,
  max: 35.0,
  palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red']
};

// Print a URL that will produce the filmstrip when accessed.
print(tempCol.getFilmstripThumbURL(filmArgs));


Figure 4. Température de surface horaire pour le solstice d'hiver dans l'hémisphère nord représentée sous forme d'image PNG de pellicule. Notez que la pellicule a été divisée en quatre sections à des fins d'affichage. Le résultat de getFilmstripThumbURL est une seule série d'images de collection jointes du nord au sud.

Techniques avancées

Les sections suivantes décrivent comment utiliser le masquage, l'opacité et la composition de calques pour améliorer les visualisations en ajoutant des bordures de polygone, en mettant en avant des régions d'intérêt et en comparant des images dans une collection.

Notez que tous les exemples suivants de cette section utilisent la même ImageCollection de base définie ici:

Éditeur de code (JavaScript)

// Import hourly predicted temperature image collection for northern winter
// solstice. Note that predictions extend for 384 hours; limit the collection
// to the first 24 hours.
var tempCol = ee.ImageCollection('NOAA/GFS0P25')
  .filterDate('2018-12-22', '2018-12-23')
  .limit(24)
  .select('temperature_2m_above_ground');

// Define visualization arguments to control the stretch and color gradient
// of the data.
var visArgs = {
  min: -40.0,
  max: 35.0,
  palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red']
};

// Convert each image to an RGB visualization image by mapping the visualize
// function over the image collection using the arguments defined previously.
var tempColVis = tempCol.map(function(img) {
  return img.visualize(visArgs);
});

// Import country features and filter to South American countries.
var southAmCol = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017')
  .filterMetadata('wld_rgn', 'equals', 'South America');

// Define animation region (South America with buffer).
var southAmAoi = ee.Geometry.Rectangle({
  coords: [-103.6, -58.8, -18.4, 17.4], geodesic: false});

Superpositions

Vous pouvez superposer plusieurs images à l'aide de la méthode Image blend, où les pixels qui se chevauchent de deux images sont mélangés en fonction de leurs masques (opacité).

Superposition vectorielle

Ajouter des polygones de limites administratives et d'autres géométries à une image peut fournir un contexte spatial précieux. Considérons l'animation de la température de surface quotidienne mondiale ci-dessus (figure 3). Les limites entre la terre et l'océan sont quelque peu discernables, mais elles peuvent être explicitées en ajoutant un calque de polygone des pays.

Les données vectorielles (Features) sont dessinées sur les images en appliquant la méthode paint. Vous pouvez peindre des éléments sur une image existante, mais il est préférable de les peindre sur une image vierge, de leur appliquer un style, puis de mélanger le résultat avec d'autres calques d'images stylisés. Traiter chaque couche d'une pile de visualisation indépendamment permet de mieux contrôler le style.

L'exemple suivant montre comment peindre les frontières des pays d'Amérique du Sud sur une Image vierge et mélanger le résultat avec chaque Image de la collection de températures quotidiennes mondiales (figure 5). Les frontières des pays superposées permettent de distinguer les terres de l'eau et de mettre en contexte les tendances de température.

Éditeur de code (JavaScript)

// Define an empty image to paint features to.
var empty = ee.Image().byte();

// Paint country feature edges to the empty image.
var southAmOutline = empty
  .paint({featureCollection: southAmCol, color: 1, width: 1})
  // Convert to an RGB visualization image; set line color to black.
  .visualize({palette: '000000'});

// Map a blend operation over the temperature collection to overlay the country
// border outline image on all collection images.
var tempColOutline = tempColVis.map(function(img) {
  return img.blend(southAmOutline);
});

// Define animation arguments.
var videoArgs = {
  dimensions: 768,
  region: southAmAoi,
  framesPerSecond: 7,
  crs: 'EPSG:3857'
};

// Display the animation.
print(ui.Thumbnail(tempColOutline, videoArgs));


Figure 5. Ajoutez des superpositions vectorielles aux images d'une collection pour fournir un contexte spatial.

Images superposées

Vous pouvez superposer plusieurs images pour obtenir le style souhaité. Supposons que vous souhaitiez mettre en avant une zone d'intérêt. Vous pouvez créer une copie atténuée d'une visualisation d'image en tant que calque de base, puis superposer une version tronquée de la visualisation d'origine. S'appuyant sur l'exemple précédent, le script suivant génère la figure 6.

Éditeur de code (JavaScript)

// Define an empty image to paint features to.
var empty = ee.Image().byte();

// Paint country feature edges to the empty image.
var southAmOutline = empty
  .paint({featureCollection: southAmCol, color: 1, width: 1})
  // Convert to an RGB visualization image; set line color to black.
  .visualize({palette: '000000'});

// Map a blend operation over the temperature collection to overlay the country
// border outline image on all collection images.
var tempColOutline = tempColVis.map(function(img) {
  return img.blend(southAmOutline);
});

// Define a partially opaque grey RGB image to dull the underlying image when
// blended as an overlay.
var dullLayer = ee.Image.constant(175).visualize({
  opacity: 0.6, min: 0, max: 255, forceRgbOutput: true});

// Map a two-part blending operation over the country outline temperature
// collection for final styling.
var finalVisCol = tempColOutline.map(function(img) {
  return img
    // Blend the dulling layer with the given country outline temperature image.
    .blend(dullLayer)
    // Blend a clipped copy of the country outline temperature image with the
    // dulled background image.
    .blend(img.clipToCollection(southAmCol));
});

// Define animation arguments.
var videoArgs = {
  dimensions: 768,
  region: southAmAoi,
  framesPerSecond: 7,
  crs: 'EPSG:3857'
};

// Display the animation.
print(ui.Thumbnail(finalVisCol, videoArgs));


Figure 6. Mettez en avant une zone d'intérêt en coupant l'image et en la superposant à une copie en demi-teinte.

Vous pouvez également mélanger des données d'image avec un calque de base en ombres portées pour indiquer le relief et donner de la profondeur à la visualisation (figure 7).

Éditeur de code (JavaScript)

// Define a hillshade layer from SRTM digital elevation model.
var hillshade = ee.Terrain.hillshade(ee.Image('USGS/SRTMGL1_003')
  // Exaggerate the elevation to increase contrast in hillshade.
  .multiply(100))
  // Clip the DEM by South American boundary to clean boundary between
  // land and ocean.
  .clipToCollection(southAmCol);

// Map a blend operation over the temperature collection to overlay a partially
// opaque temperature layer on the hillshade layer.
var finalVisCol = tempColVis.map(function(img) {
  return hillshade
    .blend(img.clipToCollection(southAmCol).visualize({opacity: 0.6}));
});

// Define animation arguments.
var videoArgs = {
  dimensions: 768,
  region: southAmAoi,
  framesPerSecond: 7,
  crs: 'EPSG:3857'
};

// Display the animation.
print(ui.Thumbnail(finalVisCol, videoArgs));


Figure 7. Afficher le relief en superposant des données d'image partiellement transparentes sur un calque d'ombres portées

Transitions

Personnalisez une collection d'images pour produire des animations qui révèlent les différences entre deux images d'une collection à l'aide de transitions de fondu, de clignotement et de diapositive. Chacun des exemples suivants utilise la même visualisation de base générée par le script suivant:

Éditeur de code (JavaScript)

// Define an area of interest geometry with a global non-polar extent.
var aoi = ee.Geometry.Polygon(
  [[[-179.0, 78.0], [-179.0, -58.0], [179.0, -58.0], [179.0, 78.0]]], null,
  false);

// Import hourly predicted temperature image collection.
var temp = ee.ImageCollection('NOAA/GFS0P25')

// Define a northern summer solstice temperature image.
var summerSolTemp = temp
  .filterDate('2018-06-21', '2018-06-22')
  .filterMetadata('forecast_hours', 'equals', 12)
  .first()
  .select('temperature_2m_above_ground');

// Define a northern winter solstice temperature image.
var winterSolTemp = temp
  .filterDate('2018-12-22', '2018-12-23')
  .filterMetadata('forecast_hours', 'equals', 12)
  .first()
  .select('temperature_2m_above_ground');

// Combine the solstice images into a collection.
var tempCol = ee.ImageCollection([
  summerSolTemp.set('season', 'summer'),
  winterSolTemp.set('season', 'winter')
]);

// Import international boundaries feature collection.
var countries = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017');

// Define visualization arguments.
var visArgs = {
  min: -40.0,
  max: 35.0,
  palette: ['blue', 'purple', 'cyan', 'green', 'yellow', 'red']
};

// Convert the image data to RGB visualization images.
// The clip and unmask combination sets ocean pixels to black.
var tempColVis = tempCol.map(function(img) {
  return img
    .visualize(visArgs)
    .clipToCollection(countries)
    .unmask(0)
    .copyProperties(img, img.propertyNames());
});

Flicker

S'il n'y a que deux images dans une collection, comme c'est le cas ici, le scintillement est la représentation par défaut lors de l'animation de la collection. Ajustez l'argument d'animation framesPerSecond pour accélérer ou ralentir la fréquence de clignotement. Les arguments de visualisation suivants appliqués à la collection ci-dessus génèrent la figure 8.

Éditeur de code (JavaScript)

// Define arguments for animation function parameters.
var videoArgs = {
  dimensions: 768,
  region: aoi,
  framesPerSecond: 2,
  crs: 'EPSG:3857'
};

// Display animation to the Code Editor console.
print(ui.Thumbnail(tempColVis, videoArgs));


Figure 8. Exemple de clignotement entre 12h GMT et la température de surface pour le solstice d'hiver et le solstice d'été.

Fondu

Une transition de fondu entre deux calques est obtenue en diminuant simultanément l'opacité de l'un tout en augmentant l'opacité de l'autre sur une séquence d'incréments d'opacité allant de près de 0 à 1 (figure 9).

Éditeur de code (JavaScript)

// Define a sequence of decreasing opacity increments. Note that opacity cannot
// be 0, so near 1 and 0 are used. Near 1 is needed because a compliment is
// calculated in a following step that can result in 0 if 1 is an element of the
// list.
var opacityList = ee.List.sequence({start: 0.99999, end: 0.00001, count: 20});

// Filter the summer and winter solstice images from the collection and set as
// image objects.
var summerImg = tempColVis.filter(ee.Filter.eq('season', 'summer')).first();
var winterImg = tempColVis.filter(ee.Filter.eq('season', 'winter')).first();

// Map over the list of opacity increments to iteratively adjust the opacity of
// the two solstice images. Returns a list of images.
var imgList = opacityList.map(function(opacity) {
  var opacityCompliment = ee.Number(1).subtract(ee.Number(opacity));
  var winterImgFade = winterImg.visualize({opacity: opacity});
  var summerImgFade = summerImg.visualize({opacity: opacityCompliment});
  return summerImgFade.blend(winterImgFade).set('opacity', opacity);
});

// Convert the image list to an image collection; the forward phase.
var fadeForward = ee.ImageCollection.fromImages(imgList);

// Make a copy of the collection that is sorted by ascending opacity to
// represent the reverse phase.
var fadeBackward = fadeForward.sort({property: 'opacity'});

// Merge the forward and reverse phase frame collections.
var fadeCol = fadeForward.merge(fadeBackward);

// Define animation arguments.
var videoArgs = {
  dimensions: 768,
  region: aoi,
  framesPerSecond: 25,
  crs: 'EPSG:3857'
};

// Display the animation.
print(ui.Thumbnail(fadeCol, videoArgs));


Figure 9. Exemple de fondu entre la température de surface à midi (GMT) pour l'été et le solstice d'hiver.

Curseur

Une transition de curseur affiche et masque progressivement la couche d'image sous-jacente. Pour ce faire, il suffit d'ajuster de manière itérée l'opacité de l'image superposée sur une plage de longitudes (figure 10).

Éditeur de code (JavaScript)

// Define a sequence of longitude increments. Start and end are defined by the
// min and max longitude of the feature to be provided to the region parameter
// of the animation arguments dictionary.
var lonSeq = ee.List.sequence({start: -179, end: 179, count: 20});

// Define a longitude image.
var longitude = ee.Image.pixelLonLat().select('longitude');

// Filter the summer and winter solstice images from the collection and set as
// image objects.
var summerImg = tempColVis.filter(ee.Filter.eq('season', 'summer')).first();
var winterImg = tempColVis.filter(ee.Filter.eq('season', 'winter')).first();

// Map over the list of longitude increments to iteratively adjust the mask
// (opacity) of the overlying image layer. Returns a list of images.
var imgList = lonSeq.map(function(lon) {
  lon = ee.Number(lon);
  var mask = longitude.gt(lon);
  return summerImg.blend(winterImg.updateMask(mask)).set('lon', lon);
});

// Convert the image list to an image collection; concealing phase.
var sliderColForward = ee.ImageCollection.fromImages(imgList);

// Make a copy of the collection that is sorted by descending longitude to
// represent the revealing phase.
var sliderColbackward = sliderColForward
  .sort({property: 'lon', ascending: false});

// Merge the forward and backward phase frame collections.
var sliderCol = sliderColForward.merge(sliderColbackward);

// Define animation arguments.
var videoArgs = {
  dimensions: 768,
  region: aoi,
  framesPerSecond: 25,
  crs: 'EPSG:3857'
};

// Display the animation.
print(ui.Thumbnail(sliderCol, videoArgs));


Figure 10. Exemple de transition glissante entre la température de surface à midi (GMT) pour le solstice d'été et d'hiver.