組成 ImageCollection
的圖片可視為動畫或一系列縮圖,稱為「膠片帶」。這些方法可快速評估 ImageCollection
的內容,並提供有效的媒介,讓您觀察時空變化 (圖 1)。
getVideoThumbURL()
會產生動畫圖片系列getFilmstripThumbURL()
會產生一系列縮圖圖片
以下各節將說明如何為圖像製作 ImageCollection
、提供每個集合圖像製作方法的程式碼範例,以及介紹幾種進階動畫技巧。
圖 1. 動畫:顯示 2017 年 9 月大西洋颶風的三天進展。
收集資料
您可以篩選、組合、排序及設定集合內圖片的樣式,只顯示感興趣的圖片或強調某種現象。任何 ImageCollection
都可以做為視覺化函式的輸入內容,但經過精心挑選的收集資料,考量了年內和年際日期範圍、觀測間隔、區域範圍、品質和表示方式,可以獲得更好的結果。
篩選
篩選圖片集合,只納入可支援視覺化呈現目的的相關資料。請考量日期、空間範圍、品質和其他特定資料集的屬性。
舉例來說,您可以依據下列方式篩選 Sentinel-2 地表反射率集合:
單一日期範圍
程式碼編輯器 (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterDate('2018-01-01', '2019-01-01');
序列化的年內日期範圍
程式碼編輯器 (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filter(ee.Filter.calendarRange(171, 242, 'day_of_year'));
感興趣的區域
程式碼編輯器 (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2));
或圖片屬性。
程式碼編輯器 (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 50));
鏈結多個篩選器。
程式碼編輯器 (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');
合成
將年度內和年度間的日期範圍組合,以減少集合中的圖片數量並提升品質。舉例來說,假設您要建立非洲地區的年度 NDVI 圖表,其中一個方法是篩選 MODIS 16 天 NDVI 集合,納入所有 2018 年觀測資料。
程式碼編輯器 (JavaScript)
var ndviCol = ee.ImageCollection('MODIS/006/MOD13A2') .filterDate('2018-01-01', '2019-01-01') .select('NDVI');
依篩選器和減少值繪製跨年複合圖
上述集合的視覺化結果顯示,在雲層覆蓋率高的森林區域中,雜訊相當明顯 (圖 2a)。您可以根據 MODIS 集合中所有年份的中位數,縮短序列日期範圍,以便更準確地呈現資料。
程式碼編輯器 (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);
由於每張圖片都代表 20 多年資料的 16 天 NDVI 合成圖的中位數 (圖 1b),因此這個集合產生的動畫雜訊較少。如要進一步瞭解這項動畫,請參閱這個教學課程。
![]() |
![]() |
---|---|
圖 2a. 年度 NDVI 不含跨年合成。 | 圖 2b. 年度 NDVI 與年度間合成。 |
依篩選器和減少值計算年度內的複合值
上一個範例會套用跨年合成的功能。您也可以將一系列年度內觀測資料合成。舉例來說,每個感應器每 16 天就會收集一次 Landsat 資料,針對特定場景,但圖像的某些部分經常會被雲遮蔽。遮蔽雲朵並合成同一季節的多張圖片,可以產生更無雲的圖像。請參考以下範例,其中 1985 年至 2011 年各年的 Landsat 5 圖像,是使用中位數進行合成。
程式碼編輯器 (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);
透過彙整和減少作業進行年度內組合
請注意,前兩種合成方法會對日期和年份的 List
進行對應,以逐步定義要篩選和合成的日期。應用彙整是另一種執行此作業的方法。在以下程式碼片段中,我們定義了一個不重複的年份集合,然後套用 saveAll
彙整作業,找出與特定年份相對應的所有圖片。屬於特定年份的圖片會歸入 List
物件,並儲存為不同年份集合中相應年份代表的屬性。這些年度綜合圖表是從這些清單產生,方法是減少這些清單在映射至不同年份集合的函式中定義的 ImageCollections
。
程式碼編輯器 (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);
透過彙整和減少作業進行同日組合
另一種合成的情況是建立空間連續的圖片馬賽克。假設您感興趣的區域橫跨同一路徑內的兩個 Landsat 資料列,且您的目標是針對 2017 年和 2018 年每個 Landsat 8 軌道,顯示兩張圖片的圖像馬賽克。在這裡,在依路徑和資料列篩選集合後,會使用彙整作業,將根據擷取日期定義的同一軌道 Landsat 圖片拼接在一起。
程式碼編輯器 (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(); }));
排序
您可以依時間排序,確保正確的時間順序,也可以依所選屬性排序。根據預設,視覺化框架序列會依照集合的自然順序排序。您可以使用 sort
集合方法變更系列的排列方式,藉此選取 Image
屬性,以遞增或遞減順序排序。舉例來說,如要依觀察時間排序,請使用無所不在的 system:time_start
屬性。
程式碼編輯器 (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2)) .sort('system:time_start');
或者,您也可以依據雲量增加的程度來定義順序,例如 Sentinel-2 圖像的情況。
程式碼編輯器 (JavaScript)
var s2col = ee.ImageCollection('COPERNICUS/S2_SR') .filterBounds(ee.Geometry.Point(-122.1, 37.2)) .sort('CLOUDY_PIXEL_PERCENTAGE');
順序也可以由衍生屬性 (例如區域平均 NDVI) 定義。在這裡,區域 NDVI 會新增為已對應函式中的每張圖片的屬性,接著對新屬性進行排序。
程式碼編輯器 (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);
圖像視覺化
圖像視覺化功能會將數字轉換為顏色。您可以透過三種方式,控制在收藏品視覺化方法中,圖片資料以顏色呈現的方式:
- 直接將視覺化引數提供給
getVideoThumbURL
和getFilmstripThumbURL
。 - 在套用
getVideoThumbURL
和getFilmstripThumbURL
之前,先將visualize
圖片方法對應至圖片集合。 - 在套用
getVideoThumbURL
和getFilmstripThumbURL
之前,先將sldStyle
圖片方法對應至圖片集合。詳情請參閱「樣式圖層描述元」。
本指南的範例使用了選項 1 和 2,其中視覺化效果是透過將多頻帶圖像的三個圖像頻帶對應至紅、綠和藍色色彩管道,或將單一頻帶的評分值沿著色板線性化,視覺化參數包括:
參數 | 說明 | 類型 |
---|---|---|
bands | 以半形逗號分隔的清單,列出三個要對應至 RGB 的頻帶名稱 | list |
min | 要對應至 0 的值 | 三個數字的數字或清單,每個頻帶一個 |
max | 要對應至 255 的值 | 三個數字的數字或清單,每個頻帶一個 |
gain | 用來乘上每個像素值的值 | 三個數字的數字或清單,每個頻帶一個 |
偏見 | 要新增至每個 DN 的值 | 三個數字的數字或清單,每個頻帶一個 |
gamma | Gamma 校正因數 | 三個數字的數字或清單,每個頻帶一個 |
palette | CSS 樣式顏色字串清單 (僅限單頻帶圖像) | 以半形逗號分隔的十六進制字串清單 |
opacity | 圖層的不透明度 (0.0 表示完全透明,1.0 表示完全不透明) | 數字 |
使用 bands
引數選取要視覺化的頻帶。請提供一或三個樂團名稱的清單。對於多頻帶影像,系統預設會選取前三個頻帶。頻帶名稱順序會決定顏色指派方式;列出的第 1、第 2 和第 3 個頻帶分別對應至紅色、綠色和藍色。
在以圖表呈現圖像時,資料範圍縮放是重要的考量因素。根據預設,介於 0 和 1 (含) 之間的浮點資料值會縮放至介於 0 和 255 (含) 之間。系統會將超出範圍的值強制設為 0 和 255,具體取決於值是否小於 0 或大於 1。就整數資料而言,其類型定義的完整容量會縮放至 0 到 255 之間 (例如,帶符號的 16 位元資料範圍為 −32,768 到 32,767,預設會縮放至 [0, 255])。接受預設值通常會導致視覺呈現的圖像特徵之間幾乎沒有對比。使用 min
和 max
可改善對比度,並強調特定資料範圍。建議您將 min
和 max
設為代表您感興趣的領域中資料的第 2 和第 98 百分位數的值。請參考以下範例,瞭解如何計算數位高程模型的這些值。
程式碼編輯器 (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());
palette
參數會定義用來代表 8 位元圖像可視化的顏色。這項屬性僅適用於單頻帶表示法;如果使用多頻帶圖片指定這項屬性,會導致發生錯誤。如果資料是單一頻帶,或是您想要從多頻帶圖像中以視覺化方式呈現單一頻帶,請將 forceRgbOutput
參數設為 true
(如果提供 palette
引數,則不必設定)。使用 min
和 max
參數定義值範圍,以便在 0 到 255 之間線性縮放。
以下是將視覺化函式對應至單一頻帶圖像集合的範例。匯入 MODIS NDVI 集合、設定 visualization
方法的示意圖引數,並將將值轉換為 RGB 圖像表示法的函式對應至 NDVI 集合。
程式碼編輯器 (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);
以下是將視覺化函式對應至多頻圖像集合的範例:
程式碼編輯器 (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);
在這種情況下,系統會提供三個頻帶,用於定義每個 RGB 圖層的強度,因此不會提供色版引數。請注意,兩個範例都使用 min
和 max
參數,用來控制哪些值會拉伸至 8 位元 RGB 資料的極限。
影片縮圖
getVideoThumbURL()
函式會根據 ImageCollection
中的所有圖片產生動畫,其中每張圖片代表一個影格。製作動畫的一般工作流程如下:
- 定義
Geometry
,其邊界會決定動畫的區域範圍。 - 定義
ImageCollection
。 - 考慮圖像示意圖:在集合上對應圖像示意圖函式,或將圖像示意圖引數新增至動畫引數集合。
- 定義動畫引數並呼叫
getVideoThumbURL
方法。
getVideoThumbURL
的結果是網址。將網址輸出至控制台,然後按一下該網址,即可啟動 Earth Engine 伺服器,在新的瀏覽器分頁中即時產生動畫。或者,您也可以在 Code Editor 主控台中查看動畫,方法是對集合和其對應的動畫引數呼叫 ui.Thumbnail
函式。在算繪完成後,您可以按一下動畫的滑鼠右鍵,然後從內容選單中選取適當的選項,即可下載動畫。
以下範例說明如何產生動畫,呈現全球 24 小時的溫度變化。請注意,這個範例包含了可視化引數和動畫引數,而非先在 ImageCollection
上對應可視化函式。執行此指令碼後,Code Editor 主控台應會顯示類似圖 3 的動畫。
程式碼編輯器 (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));
圖 3. 北半球冬至的每小時地表溫度,以 GIF 動畫圖片呈現。
剪輯畫面
getFilmstripThumbUrl
函式會產生單一靜態圖片,代表將 ImageCollection
中的所有圖片連結為南北系列。幻燈片影格序列會依照集合的自然順序排列。
getFilmstripThumbUrl
的結果是網址。將網址輸出至控制台,然後按一下該網址,即可啟動 Earth Engine 伺服器,在新瀏覽器分頁中即時產生圖像。在算繪完成後,只要在圖片上按一下滑鼠右鍵,然後從內容選單中選取適當的選項,即可下載圖片。
以下程式碼片段與上方影片縮圖示例使用相同的集合。執行這個指令碼後,Code Editor 主控台應會顯示類似圖 4 的膠卷。
程式碼編輯器 (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));
圖 4. 北半球冬至的每小時地表溫度,以膠卷 PNG 圖片呈現。請注意,電影膠片已分成四個部分供顯示;getFilmstripThumbURL
的結果是一系列收集的圖片,以南北方向相連。
進階技巧
以下各節將說明如何使用裁剪、不透明度和圖層合成功能,藉由新增多邊形邊框、強調感興趣的區域,以及比較集合內的圖片,來強化視覺化效果。
請注意,本節中所有後續範例都會使用此處定義的相同基礎 ImageCollection
:
程式碼編輯器 (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});
重疊說明
您可以使用 blend
Image
方法疊加多張圖片,其中兩張圖片重疊的像素會根據其遮罩 (透明度) 進行混合。
向量重疊
在圖片中加入行政區域邊界多邊形和其他幾何圖形,可以提供寶貴的空間背景資訊。請參考上方的全球每日地表溫度動畫 (圖 3)。陸地和海洋之間的邊界雖然可辨識,但您可以加入國家/地區的多邊形重疊圖,讓邊界更清楚。
透過套用 paint
方法,將向量資料 (Features
) 繪製至圖片。您可以將功能繪製至現有圖片,但較佳做法是將功能繪製至空白圖片,並為其設定樣式,然後將結果與其他樣式圖片圖層混合。獨立處理視覺化堆疊的各個圖層,可進一步控制樣式。
以下範例說明如何將南美洲國家邊界繪製到空白的 Image
,並將結果與全球每日溫度收集資料集的每個 Image
混合 (圖 5)。疊加的國家/地區邊界可區分陸地和水域,並提供溫度模式的背景資訊。
程式碼編輯器 (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));
圖 5. 在珍藏內容中的圖片中加入向量疊加圖層,提供空間背景。
圖片重疊
您可以重疊多張圖片,以獲得所需的樣式。假設您想強調感興趣的區域。您可以建立圖像示意圖的靜音副本做為底層,然後疊加原始示意圖的裁剪版本。接續先前的範例,下列指令碼會產生圖 6。
程式碼編輯器 (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));
圖 6. 裁剪圖片並疊加在靜音副本上,強調感興趣的區域。
您也可以將圖片資料與陰影地形基本圖層混合,以便標示地形並為視覺化效果增添深度 (圖 7)。
程式碼編輯器 (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));
圖 7. 在丘陵陰影圖層上疊加部分透明的圖片資料,以顯示地形。
轉場
自訂圖片集合,使用淡出、閃爍和滑動轉場效果,製作出能顯示集合內兩張圖片之間差異的動畫。以下每個範例都使用由下列指令碼產生的相同基本圖表:
程式碼編輯器 (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
在本例中,集合中只有兩張圖片,因此集合動畫的預設呈現方式為閃爍。調整 framesPerSecond
動畫引數,加快或減慢閃爍率。套用至上述集合的以下圖像化引數會產生圖 8。
程式碼編輯器 (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));
圖 8. 格林威治標準時間中午 12 點之間的表面溫度,北半球和冬至的閃爍範例。
淡出
在兩個圖層之間產生淡出轉場效果的方法,是同時降低一個圖層的透明度,同時提高另一個圖層的透明度,並以從 0 到 1 的透明度增量序列進行 (圖 9)。
程式碼編輯器 (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));
圖 9. 夏季和冬季夏至的格林威治標準時間中午 12 點之間地表溫度淡出效果示例。
滑桿
滑桿轉場效果會逐步顯示及隱藏底層圖片圖層。這項效果是透過在經度範圍內重複調整覆蓋圖片的不透明度而達成 (圖 10)。
程式碼編輯器 (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));
圖 10. 夏季和冬季至點的格林威治標準時間下午 12 點表面溫度之間的滑動轉換範例。