土地利用数据|气象数据|社会经济数据|npp数据|ndvi数据-地理遥感生态网

GEE学习笔记 四十七:使用GEE常见错误及解决方案(三)

GEE学习笔记 四十七:使用GEE常见错误及解决方案(三)
GEE学习笔记 四十七:使用GEE常见错误及解决方案(三)

详细信息

在Google Earth Engine(GEE)中map方法是非常常用的,它在很多数据结构中都有使用,比如:集合(FeatureCollection、ImageCollection等)、列表(List)、字典(Dictionary)等。这些map的方法定义非常类似,我这里就以ImageCollection中的map方法为例来讲一下常见的一些错误和需要注意的问题。

map函数的定义:


第一个参数的一个方法,第二个参数是一个布尔值(通常默认就可以)。

map函数常见错误以及解决方法

  • map中不能使用客户端执行的方法,比如print()、getInfo()、getDownloadURL()等

先看一段代码:

var geometry = ee.Geometry.Point([-104.78007812499999, 37.07682857623016]); 
var l8Col = ee.ImageCollection("LANDSAT/LC08/C01/T1_RT_TOA") 
              .filterDate("2018-2-1", "2018-5-1") 
              .filterBounds(geometry) 
              .map(function(image) { 
                return image.addBands(image.normalizedDifference(["B5", "B4"]).rename("NDVI")); 
              }) 
              .select("NDVI"); 
print("l8Col", l8Col); 


//错误 
var newCol = l8Col.map(function(image){ 
  var time_start = image.get("system:time_start"); 
  var year = ee.Date(time_start).get("year"); 
  image = image.set("year", year); 
  //map中不能直接使用print 
  print("year", year); 
  return image; 
}); 

相关错误如下:

分析:这里可以看到调用print()方法常量可以输出,但是计算的结果不能输出,所以一定要注意这个问题。

 

  • map中不能使用Map、ui.Chart、Export、Chart(已经废弃类)这些类中的方法

看下面的代码

var geometry = ee.Geometry.Point([-104.78007812499999, 37.07682857623016]); 
var l8Col = ee.ImageCollection("LANDSAT/LC08/C01/T1_RT_TOA") 
              .filterDate("2018-2-1", "2018-5-1") 
              .filterBounds(geometry) 
              .map(function(image) { 
                return image.addBands(image.normalizedDifference(["B5", "B4"]).rename("NDVI")); 
              }) 
              .select("NDVI"); 
print("l8Col", l8Col); 


//错误 
var newCol = l8Col.map(function(image){ 
  var time_start = image.get("system:time_start"); 
  var year = ee.Date(time_start).get("year"); 
  image = image.set("year", year); 
  //不能调用Map中的方法 
  Map.addLayer(image, {min:0, max:0.8, palette:"ff0000,00ff00,0000ff"}, "image"); 
  return image; 
}); 

输出结果如下:

分析:由于map中调用了Map.addLayer()方法,所以这里报错了。

类似的如下代码:

var newCol = l8Col.map(function(image){ 
  var time_start = image.get("system:time_start"); 
  var year = ee.Date(time_start).get("year"); 
  image = image.set("year", year); 
  //这里调用print(chart)会报错 
  var chart = ui.Chart.image.byClass({ 
    image: image, 
    classBand: "B1" 
  }); 
  print(chart); 
  return image; 
}); 
  • map必须有返回值

看看如下代码

var geometry = ee.Geometry.Point([-104.78007812499999, 37.07682857623016]); 
var l8Col = ee.ImageCollection("LANDSAT/LC08/C01/T1_RT_TOA") 
              .filterDate("2018-2-1", "2018-5-1") 
              .filterBounds(geometry) 
              .map(function(image) { 
                return image.addBands(image.normalizedDifference(["B5", "B4"]).rename("NDVI")); 
              }) 
              .select("NDVI"); 
print("l8Col", l8Col); 
//这里必须有返回值,否则会报错 
var newCol = l8Col.map(function(image){ 
  var time_start = image.get("system:time_start"); 
  var year = ee.Date(time_start).get("year"); 
  image = image.set("year", year); 
}); 
print(newCol); 

输出结果:

分析:map方法必须有返回值,否则会报错。
  • map的返回值类型必须符合方法定义

每一个map方法都有自己特定的返回类型,比如imageCollection中的map返回值就是必须是imageCollection,所以每一个map中必须返回一个image。经常出现的错误如下:

var geometry = ee.Geometry.Point([-104.78007812499999, 37.07682857623016]); 
var l8Col = ee.ImageCollection("LANDSAT/LC08/C01/T1_RT_TOA") 
              .filterDate("2018-2-1", "2018-5-1") 
              .filterBounds(geometry) 
              .map(function(image) { 
                return image.addBands(image.normalizedDifference(["B5", "B4"]).rename("NDVI")); 
              }) 
              .select("NDVI"); 
print("l8Col", l8Col); 
//必须返回特定的值 
var newCol = l8Col.map(function(image){ 
  var time_start = image.get("system:time_start"); 
  var year = ee.Date(time_start).get("year"); 
  image = image.set("year", year); 
  return image.get("year"); 
}); 
print(newCol); 

输出结果如下:

神奇方法:aside()

上面说了map中不能使用print方法,但是我们经常会遇到各种调试问题,那么这个问题应该如何解决?这里就不得不说一个非常神奇的方法aside()。

先看一下方法的定义:

从定义中可以看到这个方法就是一个回调方法,通过它可以调用其他的方法。这里举个例子,如下:

 

//aside 
var geometry = ee.Geometry.Point([-104.78007812499999, 37.07682857623016]); 
var l8Col = ee.ImageCollection("LANDSAT/LC08/C01/T1_RT_TOA") 
              .filterDate("2018-2-1", "2018-5-1") 
              .filterBounds(geometry) 
              .map(function(image) { 
                return image.addBands(image.normalizedDifference(["B5", "B4"]).rename("NDVI")); 
              }) 
              .select("NDVI"); 
print("l8Col", l8Col); 
var newCol = l8Col.map(function(image){ 
  var time_start = image.get("system:time_start"); 
  var year = ee.Date(time_start).get("year"); 
  image = image.set("year", year); 
  return image; 
}) 
//这里会输出上一个map筛选后的影像集合 
.aside(print) 
//这里会在地图上加载显示集合拼接影像 
.aside(Map.addLayer, {min:0, max:0.8, palette:"ff0000,00ff00,0000ff"}, "image"); 

输出结果如下:

 

地图显示: