Google Earth Engine(GEE)——提取指定矢量集合中的NDVI值并附时间属性

2024-02-02 14:39:42 浏览数 (2)

本教程的主要目的是实现影像转化为数组,然后我们需要直到其转化为的数组的轴,然后根据轴的信息进行切片,切片后完成时间属性的标准转化,这里一定要对影像结果提取完成后再对矢量集合进行操作,最后就可以提取指定的属性信息。

阵列排序对于获得自定义质量的马赛克非常有用,这涉及到根据不同波段的值reduce图像波段的子集。下面的例子按NDVI排序,然后得到集合中NDVI值最高的观测值子集的值:

与线性建模的例子一样,使用arraySlice()沿波段轴将感兴趣的波段与排序索引(NDVI)分开。然后用arraySort()按排序索引对感兴趣的波段进行排序。在像素按NDVI降序排序后,沿imageAxis使用arraySlice(),得到20%的最高NDVI像素。最后,沿着imageAxis应用arrayReduce(),用一个平均减速器得到最高NDVI像素的平均值。最后一步是将阵列图像转换为多波段图像进行显示 

函数:

toArray()

Converts an image collection into an image of 2D arrays. At each pixel, the images that have valid (unmasked) values in all bands are laid out along the first axis of the array in the order they appear in the image collection. The bands of each image are laid out along the second axis of the array, in the order the bands appear in that image. The array element type will be the union of the types of each band.

将一个图像集合转换为一个二维数组的图像。在每个像素点上,在所有波段中具有有效(未屏蔽)值的图像,按照它们在图像集合中出现的顺序,沿着阵列的第一轴排列。每幅图像的波段沿数组的第二轴排列,以波段在该图像中出现的顺序排列。数组元素的类型将是每个波段的类型的结合。

Arguments:

this:collection (ImageCollection):

Image collection to convert to an array image. Bands must have scalar values, not array values.

Returns: Image

first(image2)

Selects the value of the first value for each matched pair of bands in image1 and image2. If either image1 or image2 has only 1 band, then it is used against all the bands in the other image. If the images have the same number of bands, but not the same names, they're used pairwise in the natural order. The output bands are named for the longer of the two inputs, or if they're equal in length, in image1's order. The type of the output pixels is the union of the input types.

 选择图像1和图像2中每一对匹配的波段的第一个值。如果图像1或图像2只有1个条带,那么它将被用来对付另一个图像中的所有条带。如果图像有相同数量的条带,但名字不一样,它们就按自然顺序成对使用。输出的带子以两个输入中较长的命名,或者如果它们的长度相等,则以图像1的顺序命名。输出像素的类型是输入类型的联合。

Arguments:

this:image1 (Image):

The image from which the left operand bands are taken.

image2 (Image):

The image from which the right operand bands are taken.

Returns: Image

arraySlice(axisstartendstep)

Creates a subarray by slicing out each position along the given axis from the 'start' (inclusive) to 'end' (exclusive) by increments of 'step'. The result will have as many dimensions as the input, and the same length in all directions except the slicing axis, where the length will be the number of positions from 'start' to 'end' by 'step' that are in range of the input array's length along 'axis'. This means the result can be length 0 along the given axis if start=end, or if the start or end values are entirely out of range.

创建一个子数组,沿着给定的轴从'开始'(包括)到'结束'(不包括)按'步长'的增量切出每个位置。结果将具有与输入相同的维度,并且在所有方向上具有相同的长度,除了切片轴之外,长度将是沿'轴'的输入数组长度范围内的从'开始'到'结束'的'步'的位置数。这意味着如果start=end,或者start或end的值完全不在范围内,结果可以是沿给定轴的长度为0。 

Arguments:

this:input (Image):

Input array image.

axis (Integer, default: 0):

Axis to subset.

start (Image, default: null):

The coordinate of the first slice (inclusive) along 'axis'. Negative numbers are used to position the start of slicing relative to the end of the array, where -1 starts at the last position on the axis, -2 starts at the next to last position, etc. There must one band for start indices, or one band per 'input' band. If this argument is not set or masked at some pixel, then the slice at that pixel will start at index 0.

end (Image, default: null):

The coordinate (exclusive) at which to stop taking slices. By default this will be the length of the given axis. Negative numbers are used to position the end of slicing relative to the end of the array, where -1 will exclude the last position, -2 will exclude the last two positions, etc. There must be one band for end indices, or one band per 'input' band. If this argument is not set or masked at some pixel, then the slice at that pixel will end just after the last index.

step (Integer, default: 1):

The separation between slices along 'axis'; a slice will be taken at each whole multiple of 'step' from 'start' (inclusive) to 'end' (exclusive). Must be positive.

Returns: Image

arraySort(keys)

Sorts elements of each array pixel along one axis.沿着一个轴对每个阵列像素的元素进行排序。

Arguments:

this:image (Image):

Array image to sort.

keys (Image, default: null):

Optional keys to sort by. If not provided, the values are used as the keys. The keys can only have multiple elements along one axis, which determines the direction to sort in.

Returns: Image

arrayFlatten(coordinateLabels, separator)

Converts a single band image of equal-shape multidimensional pixels to an image of scalar pixels, with one band for each element of the array.

将等形多维像素的单波段图像转换为标量像素的图像,阵列的每个元素都有一个波段。

Arguments:

this:image (Image):

Image of multidimensional pixels to flatten.

coordinateLabels (List):

Name of each position along each axis. For example, 2x2 arrays with axes meaning 'day' and 'color' could have labels like [['monday', 'tuesday'], ['red', 'green']], resulting in band names'monday_red', 'monday_green', 'tuesday_red', and 'tuesday_green'.

separator (String, default: "_"):

Separator between array labels in each band name.

Returns: Image

arrayProject(axes)

Projects the array in each pixel to a lower dimensional space by specifying the axes to retain. Dropped axes must be at most length 1.

通过指定要保留的轴,将每个像素的数组投影到一个较低维度的空间。被放弃的轴必须最多长度为1。

Arguments:

this:input (Image):

Input image.

axes (List):

The axes to retain. Other axes will be discarded and must be at most length 1.

Returns: Image

代码:

代码语言:javascript复制
//导入需要进行采样的点数据
var table = ee.FeatureCollection("projects/ee-nimrabanuhphd18/assets/Karnataka"),
    fc = /* color: #d63000 */ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Point([74.99433244730658, 15.254586051704365]),
            {
              "system:index": "0"
            }),
        ee.Feature(
            ee.Geometry.Point([74.99438595166671, 15.518067901203736]),
            {
              "system:index": "1"
            }),
        ee.Feature(
            ee.Geometry.Point([75.25805782666671, 15.506158494397534]),
            {
              "system:index": "2"
            }),
        ee.Feature(
            ee.Geometry.Point([75.26904415479171, 15.402914915549081]),
            {
              "system:index": "3"
            }),
        ee.Feature(
            ee.Geometry.Point([75.21685909619796, 15.296970799825159]),
            {
              "system:index": "4"
            })]);
var roi = fc

//NDVI函数
var getNDVI = function(img){
  return img.normalizedDifference(['sur_refl_b02','sur_refl_b01']).rename('ndvi')
    .copyProperties(img, ['system:time_start'])
};

//添加时间属性给每一个需要采样的点
var addTime = function(img){
  return img.addBands(ee.Image.constant(img.get('system:time_start')).long().rename('time'))
};

//进行应先国家在
var MOD = ee.ImageCollection('MODIS/006/MOD09A1').
          filterDate('2022-11-15','2023-04-01').
          filterBounds(roi);
print(MOD)
var NDVI = MOD.map(getNDVI).map(addTime);
print(NDVI.first())

//讲影像转化为数组
// see https://developers.google.com/earth-engine/guides/arrays_sorting_reducing
var array = NDVI.toArray()
Map.addLayer(array, {}, 'array', false) // for inspector

// 预设要进行数组切片的轴
var imageAxis = 0;
var bandAxis = 1;

// 获取NDVI切片和感兴趣的波段。
var bandNames = NDVI.first().bandNames();
var bands = array.arraySlice(bandAxis, 0, bandNames.length());
var ndvi = array.arraySlice(bandAxis, 0, 1);

// 从高到低筛选数组
var sorted = bands.arraySort(ndvi.multiply(-1));
Map.addLayer(sorted, {}, 'sorted', false) // for inspector, from high to low

// 获取每个像素的最高NDVI观测值。
var numImages = 1
var highestNdvi = sorted.arraySlice(imageAxis, 0, numImages);

// 将reduce的阵列图像变成多波段图像进行显示。
var maxImage = highestNdvi.arrayProject([bandAxis]).arrayFlatten([bandNames]);

print(maxImage)
Map.addLayer(maxImage, {}, 'max NDVI value   time', false)

// 获取值和事件,因为这里由高到低排行了,所以只选取第一个值即可
var maxValues = maxImage.reduceRegions(fc, ee.Reducer.first(), 100)

// 将其事件标准化
maxValues = maxValues.map(function(f) {
  return f.set({ time: ee.Date(f.get('time')).format('YYYY-MM-dd HH:mm:ss') })
})

print(maxValues)

代码2:

代码语言:javascript复制
// Define a function that scales and masks Landsat 8 surface reflectance images
// and adds an NDVI band.
function prepSrL8(image) {
  // Develop masks for unwanted pixels (fill, cloud, 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 thermalBands = image.select('ST_B.*').multiply(0.00341802).add(149.0);

  // Calculate NDVI.
  var ndvi = opticalBands.normalizedDifference(['SR_B5', 'SR_B4'])
      .rename('NDVI');

  // Replace original bands with scaled bands, add NDVI band, and apply masks.
  return image.addBands(opticalBands, null, true)
      .addBands(thermalBands, null, true)
      .addBands(ndvi)
      .updateMask(qaMask)
      .updateMask(saturationMask);
}

// Define an arbitrary region of interest as a point.
var roi = ee.Geometry.Point(-122.26032, 37.87187);

// Load a Landsat 8 surface reflectance collection.
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
  // Filter to get only imagery at a point of interest.
  .filterBounds(roi)
  // Filter to get only six months of data.
  .filterDate('2021-01-01', '2021-07-01')
  // Prepare images by mapping the prepSrL8 function over the collection.
  .map(prepSrL8)
  // Select the bands of interest to avoid taking up unneeded memory.
  .select('SR_B.|NDVI');

// Convert the collection to an array.
var array = collection.toArray();

// Label of the axes.
var imageAxis = 0;
var bandAxis = 1;

// Get the NDVI slice and the bands of interest.
var bandNames = collection.first().bandNames();
var bands = array.arraySlice(bandAxis, 0, bandNames.length());
var ndvi = array.arraySlice(bandAxis, -1);

// Sort by descending NDVI.
var sorted = bands.arraySort(ndvi.multiply(-1));

// Get the highest 20% NDVI observations per pixel.
var numImages = sorted.arrayLength(imageAxis).multiply(0.2).int();
var highestNdvi = sorted.arraySlice(imageAxis, 0, numImages);

// Get the mean of the highest 20% NDVI observations by reducing
// along the image axis.
var mean = highestNdvi.arrayReduce({
  reducer: ee.Reducer.mean(),
  axes: [imageAxis]
});

// Turn the reduced array image into a multi-band image for display.
var meanImage = mean.arrayProject([bandAxis]).arrayFlatten([bandNames]);
Map.centerObject(roi, 12);
Map.addLayer(meanImage, {bands: ['SR_B6', 'SR_B5', 'SR_B4'], min: 0, max: 0.4});

0 人点赞