导读:
1.以点为中心缓冲成方形或者圆形;
2.编写和应用带有可选参数的函数;
3.学习什么是区域统计并使用reducer;
4.将计算结果导出到表中;
5.将属性从一个图像复制到另一个图像。
一、原理
1.1从给定区域内的栅格计算统计数据称为区域统计。
1.2在第22章和23章中使用ee.Image.ReduceRegions计算分区统计。本章提出了一个更通用的方式——自定义函数——计算区域统计,适用单幅的影像或者影像集合。(ee.Image 和ee.ImageCollection objects.)这种通用的方式除了比较灵活之外,也不容易出现“计算值太大”的错误。(当使用ReduceRegions处理比较复杂或者数据较大的影像集合时通常会出现“计算值太大”的问题)
二、函数
2.1 bufferPoints()参数
function bufferPoints(radius, bounds) { return function(pt) { pt = ee.Feature(pt); return bounds ? pt.buffer(radius).bounds() : pt.buffer(radius); }; }
- var ptsTopo = pts.map(bufferPoints(45, false)); //缓冲半径为45,缓冲的形状为圆形
- var ptsTopo1 = pts.map(bufferPoints(45, true));//缓冲半径为45,缓冲的形状为正方形
2.2 zonalStats()参数
function zonalStats(ic, fc, params) { // 初始化内部参数字典。 var _params = { reducer: ee.Reducer.mean(), scale: null, crs: null, bands: null, bandsRename: null, imgProps: null, imgPropsRename: null, datetimeName: 'datetime', datetimeFormat: 'YYYY-MM-dd HH:mm:ss' }; // 用提供的参数替换初始化的参数。 if (params) { for (var param in params) { _params[param] = params[param] || _params[param]; } } // 根据图像代表设置默认参数. var imgRep = ic.first(); var nonSystemImgProps = ee.Feature(null) .copyProperties(imgRep).propertyNames(); if (!_params.bands) _params.bands = imgRep.bandNames(); if (!_params.bandsRename) _params.bandsRename = _params.bands; if (!_params.imgProps) _params.imgProps = nonSystemImgProps; if (!_params.imgPropsRename) _params.imgPropsRename = _params .imgProps; // 对影像集合迭代使用reduceRegions函数. var results = ic.map(function(img) { // 选择波段 (可选重命名),设置日期时间和时间戳属性。. img = ee.Image(img.select(_params.bands, _params .bandsRename)) // Add datetime and timestamp features. .set(_params.datetimeName, img.date().format( _params.datetimeFormat)) .set('timestamp', img.get('system:time_start')); // Define final image property dictionary to set in output features. var propsFrom = ee.List(_params.imgProps) .cat(ee.List([_params.datetimeName, 'timestamp'])); var propsTo = ee.List(_params.imgPropsRename) .cat(ee.List([_params.datetimeName, 'timestamp'])); var imgProps = img.toDictionary(propsFrom).rename( propsFrom, propsTo); // Subset points that intersect the given image. var fcSub = fc.filterBounds(img.geometry()); // Reduce the image by regions. return img.reduceRegions({ collection: fcSub, reducer: _params.reducer, scale: _params.scale, crs: _params.crs }) // Add metadata to each feature. .map(function(f) { return f.set(imgProps); }); // Converts the feature collection of feature collections to a single //feature collection. }).flatten(); return results; }
代码解释:
这段代码定义了一个名为 zonalStats
的函数,用于对指定的影像集合(ic
)内的每个影像在给定的要素集合(fc
)内进行区域统计分析。该函数使用了多个参数,允许用户自定义统计分析的具体细节。下面是对这个函数的详细解释:
函数参数
-
ic
:要分析的影像集合(ee.ImageCollection
)。fc
:要在其中进行统计分析的要素集合(ee.FeatureCollection
),通常代表一组地理区域。params
:一个包含多个可选参数的对象,用于控制分析的细节。
参数字典 _params
的初始化与自定义
-
_params
:一个内部参数字典,初始化包含默认的统计分析参数,例如使用ee.Reducer.mean()
作为默认简化器(reducer),意味着默认计算区域的平均值。- 如果提供了
params
参数,代码会使用params
中的值来更新_params
中的相应值。
设置默认参数
-
- 通过影像集合的第一个影像(
imgRep
)来设置一些默认参数,例如波段名(bands)和非系统影像属性(nonSystemImgProps
)。
- 通过影像集合的第一个影像(
影像集合的迭代处理
-
- 对
ic
中的每个影像进行迭代,为每个影像执行以下操作:- 选择并可选地重命名波段。
- 设置日期时间和时间戳属性。
- 定义最终输出要素(features)中要设置的影像属性字典。
- 对
减少区域操作
-
- 对每个影像,使用
reduceRegions
函数将影像数据按照fc
中定义的区域进行聚合。聚合操作根据_params
中的简化器、比例尺(scale)和坐标参考系统(CRS)来执行。 - 每个区域(feature)的统计结果被添加上影像的属性。
- 对每个影像,使用
返回结果
-
- 最后,
map
函数的调用结果(一个特征集合的集合)被flatten
,转换成一个单一的特征集合。这个结果集合包含了原始fc
中每个区域针对ic
中每个影像计算得到的统计结果。
- 最后,
使用场景
这个 zonalStats
函数可以用于多种场景,如计算给定区域内的平均温度、降水量、植被指数等,或者进行时间序列分析,以监测某个区域随时间的环境变化。通过提供不同的简化器,用户可以计算总和、最大值、最小值等统计量。此外,该函数的灵活性允许用户根据需求调整比例尺、坐标参考系统以及进行统计分析的波段。
三、创建点要素集合
var pts = ee.FeatureCollection([ ee.Feature(ee.Geometry.Point([-118.6010, 37.0777]), { plot_id: 1 }), ee.Feature(ee.Geometry.Point([-118.5896, 37.0778]), { plot_id: 2 }), ee.Feature(ee.Geometry.Point([-118.5842, 37.0805]), { plot_id: 3 }), ee.Feature(ee.Geometry.Point([-118.5994, 37.0936]), { plot_id: 4 }), ee.Feature(ee.Geometry.Point([-118.5861, 37.0567]), { plot_id: 5 }) ]); print('Points of interest', pts); Map.addLayer(pts,{plette:'red'}); Map.centerObject(pts,9);
四、邻域统计示例
4.1 地形变量 Topographic Variables
//==========================section 1============================================= var pts = ee.FeatureCollection([ ee.Feature(ee.Geometry.Point([-118.6010, 37.0777]), { plot_id: 1 }), ee.Feature(ee.Geometry.Point([-118.5896, 37.0778]), { plot_id: 2 }), ee.Feature(ee.Geometry.Point([-118.5842, 37.0805]), { plot_id: 3 }), ee.Feature(ee.Geometry.Point([-118.5994, 37.0936]), { plot_id: 4 }), ee.Feature(ee.Geometry.Point([-118.5861, 37.0567]), { plot_id: 5 }) ]); print('Points of interest', pts); //Map.addLayer(pts); //Map.centerObject(pts,9); //==========================section 2 定义函数 bufferPoints和zonalStats ============================================= function bufferPoints(radius, bounds) { return function(pt) { pt = ee.Feature(pt); return bounds ? pt.buffer(radius).bounds() : pt.buffer(radius); }; } function zonalStats(ic, fc, params) { // 初始化内部参数字典。 var _params = { reducer: ee.Reducer.mean(), scale: null, crs: null, bands: null, bandsRename: null, imgProps: null, imgPropsRename: null, datetimeName: 'datetime', datetimeFormat: 'YYYY-MM-dd HH:mm:ss' }; // 用提供的参数替换初始化的参数。 if (params) { for (var param in params) { _params[param] = params[param] || _params[param]; } } // 根据图像代表设置默认参数. var imgRep = ic.first(); var nonSystemImgProps = ee.Feature(null) .copyProperties(imgRep).propertyNames(); if (!_params.bands) _params.bands = imgRep.bandNames(); if (!_params.bandsRename) _params.bandsRename = _params.bands; if (!_params.imgProps) _params.imgProps = nonSystemImgProps; if (!_params.imgPropsRename) _params.imgPropsRename = _params .imgProps; // 对影像集合迭代使用reduceRegions函数. var results = ic.map(function(img) { // 选择波段 (可选重命名),设置日期时间和时间戳属性。. img = ee.Image(img.select(_params.bands, _params .bandsRename)) // Add datetime and timestamp features. .set(_params.datetimeName, img.date().format( _params.datetimeFormat)) .set('timestamp', img.get('system:time_start')); // Define final image property dictionary to set in output features. var propsFrom = ee.List(_params.imgProps) .cat(ee.List([_params.datetimeName, 'timestamp'])); var propsTo = ee.List(_params.imgPropsRename) .cat(ee.List([_params.datetimeName, 'timestamp'])); var imgProps = img.toDictionary(propsFrom).rename( propsFrom, propsTo); // Subset points that intersect the given image. var fcSub = fc.filterBounds(img.geometry()); // Reduce the image by regions. return img.reduceRegions({ collection: fcSub, reducer: _params.reducer, scale: _params.scale, crs: _params.crs }) // Add metadata to each feature. .map(function(f) { return f.set(imgProps); }); // Converts the feature collection of feature collections to a single //feature collection. }).flatten(); return results; } //========================== section 3 调用 bufferPoints ===================================== // Buffer the points. var ptsTopo = pts.map(bufferPoints(45, false)); print('ptsTopo', ptsTopo); //var ptsTopo1 = pts.map(bufferPoints(45, true)); //print('ptsTopo1', ptsTopo1); //Map.addLayer(ptsTopo); //Map.addLayer(ptsTopo1); //==========================section 4 调用zonalStats============================================= //!!!zonalStats函数中的ic参数是影像集合,如果只有单张影像的话,要放到影像集合中。 //此外,影像集合中的每一幅影像必须有‘system:time_start’ 属性,一般影像都会有,没有的话,添加上. // Import the MERIT global elevation dataset. var elev = ee.Image('MERIT/DEM/v1_0_3'); // 根据DEM计算坡度. var slope = ee.Terrain.slope(elev); // Concatenate elevation and slope as two bands of an image. // Computed images do not have a 'system:time_start' property; add one based on when the data were collected. var topo = ee.Image.cat(elev, slope) .set('system:time_start', ee.Date('2000-01-01').millis()); // Wrap the single image in an ImageCollection for use in the zonalStats function. var topoCol = ee.ImageCollection([topo]); // Define parameters for the zonalStats function. var params = { bands: [0, 1], bandsRename: ['elevation', 'slope'] }; // Extract zonal statistics per point per image. var ptsTopoStats = zonalStats(topoCol, ptsTopo, params); print('Topo zonal stats table', ptsTopoStats); // ================================section 5 Display the layers on the map. =============================================== Map.setCenter(-118.5957, 37.0775, 13); Map.addLayer(topoCol.select(0), { min: 2400, max: 4200 }, 'Elevation'); Map.addLayer(topoCol.select(1), { min: 0, max: 60 }, 'Slope'); Map.addLayer(pts, { color: 'purple' }, 'Points'); Map.addLayer(ptsTopo, { color: 'yellow' }, 'Points w/ buffer');
代码解释:
.set('system:time_start', ee.Date('2000-01-01').millis())
:这部分代码使用 .set()
方法为上面创建的组合影像设置一个属性,具体是设置 system:time_start
属性的值。ee.Date('2000-01-01').millis()
生成了一个代表2000年1月1日的 ee.Date
对象,并通过 .millis()
方法将这个日期转换为毫秒值(自1970年1月1日以来的毫秒数)。这意味着新的组合影像被赋予了一个时间戳,标记为2000年1月1日。
续:
//===============================第二个例子 MODIS Time Series======================================== var ptsModis = pts.map(bufferPoints(50, true)); var modisCol = ee.ImageCollection('MODIS/006/MOD09A1') .filterDate('2015-01-01', '2020-01-01') .filter(ee.Filter.calendarRange(183, 245, 'DAY_OF_YEAR')); //.filter(ee.Filter.calendarRange(183, 245, 'DAY_OF_YEAR')): //这个方法进一步过滤影像集合,只保留每年的第183天至第245天之间的影像。 //这个日期范围大约对应每年的7月初到9月初,常用于分析特定季节的地表特征,如植被生长情况。 // Define parameters for the zonalStats function. var params = { reducer: ee.Reducer.median(), scale: 500, crs: 'EPSG:5070', bands: ['sur_refl_b01', 'sur_refl_b02', 'sur_refl_b06'], bandsRename: ['modis_red', 'modis_nir', 'modis_swir'], datetimeName: 'date', datetimeFormat: 'YYYY-MM-dd' }; // Extract zonal statistics per point per image. var ptsModisStats = zonalStats(modisCol, ptsModis, params); print('Limited MODIS zonal stats table', ptsModisStats.limit(50)); //===============================第3个例子 Landsat Time Series ======================================== //--------------- Mask clouds from images and apply scaling factors.-------------------------- function maskScale(img) { var qaMask = img.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0); var saturationMask = img.select('QA_RADSAT').eq(0); // Apply the scaling factors to the appropriate bands. var getFactorImg = function(factorNames) { var factorList = img.toDictionary().select(factorNames) .values(); return ee.Image.constant(factorList); }; var scaleImg = getFactorImg(['REFLECTANCE_MULT_BAND_.']); var offsetImg = getFactorImg(['REFLECTANCE_ADD_BAND_.']); var scaled = img.select('SR_B.').multiply(scaleImg).add( offsetImg); // Replace the original bands with the scaled ones and apply the masks. return img.addBands(scaled, null, true) .updateMask(qaMask) .updateMask(saturationMask); } // ------------------------Selects and renames bands of interest for Landsat OLI-------------------. function renameOli(img) { return img.select( ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7'], ['Blue', 'Green', 'Red', 'NIR', 'SWIR1', 'SWIR2']); } // ----------------------Selects and renames bands of interest for TM/ETM+.--------------------- function renameEtm(img) { return img.select( ['SR_B1', 'SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B7'], ['Blue', 'Green', 'Red', 'NIR', 'SWIR1', 'SWIR2']); } // Prepares (cloud masks and renames) OLI images. function prepOli(img) { img = maskScale(img); img = renameOli(img); return img; } // Prepares (cloud masks and renames) TM/ETM+ images. function prepEtm(img) { img = maskScale(img); img = renameEtm(img); return img; } var ptsLandsat = pts.map(bufferPoints(15, true)); var oliCol = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterBounds(ptsLandsat) .map(prepOli); var etmCol = ee.ImageCollection('LANDSAT/LE07/C02/T1_L2') .filterBounds(ptsLandsat) .map(prepEtm); var tmCol = ee.ImageCollection('LANDSAT/LT05/C02/T1_L2') .filterBounds(ptsLandsat) .map(prepEtm); var landsatCol = oliCol.merge(etmCol).merge(tmCol); //---------------------------Calculate Zonal Statistics---------------------------------------- // Define parameters for the zonalStats function. var params = { reducer: ee.Reducer.max(), scale: 30, crs: 'EPSG:5070', bands: ['Blue', 'Green', 'Red', 'NIR', 'SWIR1', 'SWIR2'], bandsRename: ['ls_blue', 'ls_green', 'ls_red', 'ls_nir', 'ls_swir1', 'ls_swir2' ], imgProps: ['SENSOR_ID', 'SPACECRAFT_ID'], imgPropsRename: ['img_id', 'satellite'], datetimeName: 'date', datetimeFormat: 'YYYY-MM-dd' }; // Extract zonal statistics per point per image. // Filter out observations where image pixels were all masked. var ptsLandsatStats = zonalStats(landsatCol, ptsLandsat, params) .filter(ee.Filter.notNull(params.bandsRename)); print('Limited Landsat zonal stats table', ptsLandsatStats.limit(50)); Export.table.toAsset({ collection: ptsLandsatStats, description: 'EEFA_export_Landsat_to_points', assetId: 'EEFA_export_values_to_points' }); Export.table.toDrive({ collection: ptsLandsatStats, folder: 'EEFA_outputs', // this will create a new folder if it doesn't exist description: 'EEFA_export_values_to_points', fileFormat: 'CSV' });
五、其他
5.1 Weighted Versus Unweighted Region Reduction
5.2 Copy Properties to Computed Images
copyProperties()
5.3 Understanding Which Pixels Are Included in Polygon Statistics
标签:function,img,C24,ee,区域,params,GEE,var,影像 From: https://www.cnblogs.com/bltstop/p/18113199