ald*_*pia 2 javascript dictionary loops for-loop google-earth-engine
在Google Earth Engine Developer's Guide 中,有一个避免for()循环的建议。他们建议使用map()函数作为这个例子:
// to avoid
var clientList = [];
for(var i = 0; i < 8; i++) {
clientList.push(i + 1);
}
print(clientList);
// to use
var serverList = ee.List.sequence(0, 7);
serverList = serverList.map(function(n) {
return ee.Number(n).add(1);
});
print(serverList);
Run Code Online (Sandbox Code Playgroud)
我试图在计算 VCI 之前从每个月/年中选择 MODIS 场景。因此,我采用的方法是使用双循环:
modis = ee.ImageCollection("MODIS/MYD13A1");
var modis_list = [];
for(var i = 1; i <13; i++) {
for(var j = 2000; j <2018; j++){
modis_list.push(modis.filter(ee.Filter.calendarRange(i, i, 'month'))
.filter(ee.Filter.calendarRange(j, j, 'year')));
}
}
print(modis_list);
Run Code Online (Sandbox Code Playgroud)
有没有办法用map()函数复制这样的双循环以达到服务器端方法?
小智 7
做到这一点的简单方法是在您关心的“几个月”内使用一张地图。
// Collect images for each month, starting from 2000-01-01.
var months = ee.List.sequence(0, 18*12).map(function(n) {
var start = ee.Date('2000-01-01').advance(n, 'month')
var end = start.advance(1, 'month')
return ee.ImageCollection("MODIS/MYD13A1").filterDate(start, end)
})
print(months.get(95))
Run Code Online (Sandbox Code Playgroud)
这将返回一个 ImageCollections 列表。大多数月份只有一张图片,因为 MYD13A1 包含 16 天的图片,但有些会有两张。95 月是 2008 年 1 月,有两个月。
或者,您可以使用日期集合加入集合,但这更简单。
如果可能,您应该更喜欢 filterDate 而不是 calendarRange,因为它已经过优化。
假设您只是想了解 GEE 的map()功能,以及如何等效于普通 js for loop,代码将是:
var map_m = function(i) {
i = ee.Number(i)
var years = ee.List.sequence(2000, 2017)
var filtered_col = years.map(function(j) {
var filtered = modis.filter(ee.Filter.calendarRange(i, i, 'month'))
.filter(ee.Filter.calendarRange(j, j, 'year'))
return filtered
})
return filtered_col
}
var months = ee.List.sequence(1, 12)
var modis_list2 = months.map(map_m).flatten()
Run Code Online (Sandbox Code Playgroud)
此代码复制了一个正常的for loop. 首先,它逐项逐项进行年列表,然后逐项逐项进行月列表,然后,一旦您有了年和月,过滤集合并将其添加到列表中(map自动执行此操作)。当您使用 2 个map函数(一个超过数年,另一个超过数月)时,您会得到一个列表列表,因此可以获取ImageCollection该flatten()函数的使用列表。不知何故,打印的对象有点不同,但我相信结果是一样的。