Google Earth Engine(GEE)——容易犯的错误2(避免不必要地转换为列表、避免ee.Algorithms.If()和避免reproject() )

2024-05-24 08:51:10 浏览数 (3)

避免不必要地转换为列表

Earth Engine 中的集合使用优化进行处理,这些优化通过将集合转换为 aListArray类型而被破坏。除非您需要随机访问集合元素(即您需要获取集合的第 i 个元素),否则请在集合上使用过滤器来访问单个集合元素。以下示例说明了类型转换(不推荐)和过滤(推荐)以访问集合中的元素之间的区别:

- 不要不必要地转换为列表!

代码语言:javascript复制
var table = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017');

// 不要这么做
var list = table.toList(table.size());
print(list.get(13)); // User memory limit exceeded.


//更好的方式:
print(table.filter(ee.Filter.eq('country_na', 'Niger')).first());

请注意,您可以通过将集合不必要地转换为列表来轻松触发错误。更安全的方法是使用filter()

请注意,您应该在分析中尽早使用过滤器。

避免ee.Algorithms.If()

不要ee.Algorithms.If()用于实现分支逻辑,尤其是在映射函数中。如以下示例所示,ee.Algorithms.If() 可能会占用大量内存,不推荐使用:

- 不要使用If()

代码语言:javascript复制
var table = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017');

// Do NOT do this!
var veryBad = table.map(function(f) {
  return ee.Algorithms.If({
    condition: ee.String(f.get('country_na')).compareTo('Chad').gt(0),
    trueCase: f,      // Do something.
    falseCase: null   // Do something else.
  });
}, true);
print(veryBad); // User memory limit exceeded.

// If() may evaluate both the true and false cases.

请注意,的第二个参数map()true。这意味着映射的函数可能会返回空值,并且它们将被删除到结果集合中。这可能很有用(没有If()),但这里最简单的解决方案是使用过滤器:

代码语言:javascript复制
print(table.filter(ee.Filter.eq('country_na', 'Chad')));

如本教程所示,使用过滤器的函数式编程方法是将一种逻辑应用于集合的某些元素并将另一种逻辑应用于集合的其他元素的正确方法。

记住,在GEE中能使用filter可以进行的事情就不要选择用这些可能在JAVA中常用的筛选方式!

避免reproject()

除非绝对必要,否则不要使用 reproject。您可能想要使用的一个原因 reproject()是强制代码编辑器计算以特定比例进行,以便您可以在所需的分析比例下检查结果。在下一个示例中,计算热点像素的补丁并计算每个补丁中的像素数。运行示例并单击其中一个补丁。请注意,重新投影的数据和未重新投影的数据之间的像素数不同

代码语言:javascript复制
var l8sr = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR');
var sf = ee.Geometry.Point([-122.405, 37.786]);
Map.centerObject(sf, 13);

// 重新投影的原因 - 计算像素并以交互方式探索。
var image = l8sr.filterBounds(sf)
    .filterDate('2019-06-01', '2019-12-31')
    .first();
Map.addLayer(image, {bands: ['B10'], min: 2800, max: 3100}, 'image');

var hotspots = image.select('B10').gt(3100)
  .selfMask()
  .rename('hotspots');
var objectSize = hotspots.connectedPixelCount(256);

Map.addLayer(objectSize, {min: 1, max: 256}, 'Size No Reproject', false);

// 小心reproject!不要缩小reproject的数据。false
var reprojected = objectSize.reproject(hotspots.projection());
Map.addLayer(reprojected, {min: 1, max: 256}, 'Size Reproject', false);

出现差异的原因是分析的比例是由代码编辑器缩放级别设置的。通过调用reproject() 您可以设置计算的规模,而不是代码编辑器。reproject()出于本文档中描述的原因,请谨慎 使用 。

0 人点赞