GEE学习笔记 四十六:使用GEE常见错误及解决方案(二)
日期:
继续来说一下GEE中一些常见错误以及解决方案。
- GEE中计算时候错误使用四则运算
先看一个具体的例子
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");
var img = l8Col.mosaic();
print("img", img);
Map.addLayer(img, {min:0, max:0.8, palette:"ff0000,00ff00,0000ff"}, "NDVI");
//错误:直接将影像加1
var img1 = img + 1;
print("img1", img1);
先看一下输出结果:

分析:直接运行这段代码并没有任何错误,但是输出结果可以看到第一个img是正常影像,第二个img1却是一个json的字符串(其实这里是img1的数据描述)。有的小伙伴在写程序的时候,如果一不小心将其写为这样,在使用这个影像的时候就会出现错误。
我们测试使用一下这个资源:
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");
var img = l8Col.mosaic();
print("img", img);
Map.addLayer(img, {min:0, max:0.8, palette:"ff0000,00ff00,0000ff"}, "NDVI");
//error
var img1 = img + 1;
// print("img1", img1);
Map.addLayer(img1, {min:1, max:1.8, palette:"ff0000,00ff00,0000ff"}, "NDVI1");
输出结果:

分析:这里很明确指出了添加的image不是一个影像,而是一堆Json数据。
正确的写法,使用GEE内部封装好的方法:add() subtract() multiply() divide() 等等。
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");
var img = l8Col.mosaic();
print("img", img);
Map.addLayer(img, {min:0, max:0.8, palette:"ff0000,00ff00,0000ff"}, "NDVI");
//error
// var img1 = img + 1;
// print("img1", img1);
// Map.addLayer(img1, {min:1, max:1.8, palette:"ff0000,00ff00,0000ff"}, "NDVI1");
//correct
var img1 = img.add(1);
print("img1", img1);
Map.addLayer(img1, {min:1, max:1.8, palette:"ff0000,00ff00,0000ff"}, "NDVI1");
我们点击一点验证一下是否计算成功,从结果可以看到数据已经更新成功。

总结:在GEE中的各种计算,我们一定要记住使用GEE已经封装好的方法,而不是我们通常编程使用的“+-*/”之类。
- 影像添加属性失败
这个非常普遍,尤其是接触GEE时间不是很久的用户,经常会出现想要添加属性,最终却发现属性丢失的状况。先看如下一段代码
var geometry = ee.Geometry.Point([-104.78007812499999, 37.07682857623016]);
var l8Img = ee.ImageCollection("LANDSAT/LC08/C01/T1_RT_TOA")
.filterDate("2018-2-1", "2018-10-1")
.filterBounds(geometry)
.first();
print("img1", l8Img);
var time_start = l8Img.get("system:time_start");
var year = ee.Date(time_start).get("year");
//错误方法,虽然设置了属性 year ,但是为将设置后的影像重新赋值给 l8Img
l8Img.set("year", year);
print("img2", l8Img);
//正确方法
l8Img = l8Img.set("year", year);
print("img3", l8Img);
先看一下输出结果:

分析:从结果输出可以看到img2没有将属性“year”添加到影像中,而img3添加成功。这里我们需要注意的是在GEE中的方法大部分都是有返回值的,它是将数据进行计算后然后将计算结果返回,而不是修改原有的数据,所以我们在使用的时候一定要记得将数据重新赋值。
- 影像属性丢失,找不到相关属性
这个问题比较隐蔽,如果不注意很容易出现,先看一段代码
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");
var img = l8Col.first();
var index = img.get("system:index");
var time_start = img.get("system:time_start");
print("img", img);
print("img system:index", img.get("system:index"));
print("img system:time_start", img.get("system:time_start"));
//这里有个隐藏的问题
var img1 = img.add(1);
print("img1", img1);
print("img1 system:index", img1.get("system:index"));
print("img1 system:time_start", img1.get("system:time_start"));
运算结果:

分析:影像进行四则运算,不光是波段会发生变化,同样的属性也会随之发生变化。尤其是一张影像和一个常量进行四则运算后,结果的属性是丢失了的,这个是GEE的运算规则决定的。因此我们在实际开发中遇到这种情况如果需要保留某些属性,一定要记着重新赋值。
相关代码如下
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");
var img = l8Col.first();
var index = img.get("system:index");
var time_start = img.get("system:time_start");
print("img", img);
print("img system:index", img.get("system:index"));
print("img system:time_start", img.get("system:time_start"));
// var img1 = img.add(1);
// print("img1", img1);
// print("img1 system:index", img1.get("system:index"));
// print("img1 system:time_start", img1.get("system:time_start"));
// 将原有的属性复制过来
var img2 = img.add(1);
img2 = img2.set("system:index", index);
img2 = img2.set("system:time_start", time_start);
print("img2", img2);
print("img2 system:index", img2.get("system:index"));
print("img2 system:time_start", img2.get("system:time_start"));
显示结果:

下一篇会讲解一下map相关错误。