GEE——注意事项和练习
理解服务端和客户端
//Earth Engine Server对象是具有构造函数的对象,其构造函数以EE开头(例如EE。图像,EE.REDUCER),此类对象上的任何方法都是服务器函数。
//不能对此类对象进行客户端操作例如条件语句
//任何以这种方式构建的对象都是客户端对象。客户端对象可能来自代码编辑器(例如地图,图表)或JavaScript语言(例如日期,数学,[],{})。
//简单来说,服务端为ee.,用add,定义变量不在客户端;客户端用+
理解服务端和客户端
注意事项
Avoid ee.Algorithms.If()
Avoid converting to list unnecessarily
Avoid reproject()
//重新投影的数据和未重新投影的数据之间的像素数不同。
Filter and select() first
//在对集合进行其他任何操作之前,按时间,位置和/或元数据按时间,位置和/或元数据进行过滤。
var reasonableComputation = images
.select(bands)
.filterBounds(sf)
.filterDate('2018-01-01', '2019-02-01')
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 1))
.aside(print) // Useful for debugging.
.map(reduceFunction)
.reduce('mean')
.rename(bands);
Use updateMask() instead of mask()
var l8sr = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR');
var sf = ee.Geometry.Point([-122.40554461769182, 37.786807309873716]);
var aw3d30 = ee.Image('JAXA/ALOS/AW3D30_V1_1');
Map.centerObject(sf, 7);
var image = l8sr.filterBounds(sf)
.filterDate('2019-06-01', '2019-12-31')
.first();
var vis = {bands: ['B4', 'B3', 'B2'], min: 0, max: 3000};
Map.addLayer(image, vis, 'image', false);
//全球的高程>300米的区域黑白
var mask = aw3d30.select('AVE').gt(300);
Map.addLayer(mask, {}, 'mask', false);
//显示的是全球范围的,已经出了研究区。使用mask()会导致许多像素被揭露,而不属于感兴趣的图像的像素:
// NO! Don't do this!
var badMask = image.mask(mask);
Map.addLayer(badMask, vis, 'badMask');
//显示只有遥感影像一景影像的位置
var goodMask = image.updateMask(mask);
Map.addLayer(goodMask, vis,'goodMask', false);
Combine reducers
//果你需要从单个输入(例如一个图像区域)中获得多个统计数据(例如均值和标准差),那么组合约简会更有效
var image = ee.Image('COPERNICUS/S2/20150821T111616_20160314T094808_T30UWU');
// Get mean and SD in every band by combining reducers.
var stats = image.reduceRegion({
reducer: ee.Reducer.mean().combine({
reducer2: ee.Reducer.stdDev(),
sharedInputs: true
//sharedInputs为true,以启用通过输入像素的单次传递
}),
geometry: ee.Geometry.Rectangle([-2.15, 48.55, -1.83, 48.72]),
scale: 10,
bestEffort: true // Use maxPixels if you care about scale.
});
print(stats);
// Extract means and SDs to images.
var meansImage = stats.toImage().select('.*_mean');
var sdsImage = stats.toImage().select('.*_stdDev');
print(meansImage);是image类型有16个list 每个list是B_mean
Map.addLayer(meansImage)//一个波段只有一个值是黑色的
//ee.Dictionary.toImage
//从字典中的值创建常量的映像。图像的频带根据names参数进行排序和命名。如果没有指定名称,则按字母-数字排序。
//var toimage=stats.toImage(['B1_mean', 'B2_mean']);//是image类型有2个list
If you don’t need to clip, don’t use clip()
//可以完全跳过对输入图像的剪切,因为区域是在reduceRegion()或export调用中指定的
var table = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017');
var l8sr = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR');
var chad = table.filter(ee.Filter.eq('country_na', 'Chad')).first();
// Do NOT clip unless you need to.
var unnecessaryClip = l8sr
.select('B4') // Good.
.filterBounds(chad.geometry()) // Good.!!!
.filterDate('2019-01-01', '2019-12-31') // Good.
.map(function(image) {
return image.clip(chad.geometry()); // NO! Bad! Not necessary.
})
.median()
.reduceRegion({
reducer: ee.Reducer.mean(),
geometry: chad.geometry(),!!!
scale: 30,
maxPixels: 1e10,
});
print(unnecessaryClip);
If you need to clip with a complex collection, use clipToCollection()
//想要用于剪切的几何图形位于一个集合中,请使用clipToCollection()
var ecoregions = ee.FeatureCollection('RESOLVE/ECOREGIONS/2017');
var image = ee.Image('JAXA/ALOS/AW3D30_V1_1');
var complexCollection = ecoregions
.filter(ee.Filter.eq('BIOME_NAME',
'Tropical & Subtropical Moist Broadleaf Forests'));
//从ecoregions数据集筛选出想要的数据集
Map.addLayer(complexCollection, {}, 'complexCollection');
var clippedTheRightWay = image.select('AVE')
.clipToCollection(complexCollection);
//通过数据集complexCollection进行裁剪
Map.addLayer(clippedTheRightWay, {}, 'clippedTheRightWay', false);
Don’t use a ridiculously small scale with reduceToVectors()
//如果要将光栅转换为矢量,请使用适当的比例。指定一个非常小的规模会大大增加计算成本。设定比例尽可能高,给出所需的精度。
//例如,获取代表全球陆地的多边形
var etopo = ee.Image('NOAA/NGDC/ETOPO1');
// Approximate land boundary.
var bounds = etopo.select(0).gt(-100);
// Non-geodesic polygon.
var almostGlobal = ee.Geometry.Polygon({
coords: [[-180, -80], [180, -80], [180, 80], [-180, 80], [-180, -80]],
geodesic: false
});
Map.addLayer(almostGlobal, {}, 'almostGlobal');
var vectors = bounds.selfMask().reduceToVectors({
reducer: ee.Reducer.countEvery(),
//selfMask即把bounds非0区提取出来
//ee.Reducer.countEvery:Returns a Reducer that computes the number of inputs.
geometry: almostGlobal,
// Set the scale to the maximum possible given
// the required precision of the computation.
scale: 50000,
});
Map.addLayer(vectors, {}, 'vectors');
print(vectors)//数据类型是featurecollection
Don’t sample more data than you need不要过多增添训练数据集
var l8raw = ee.ImageCollection('LANDSAT/LC08/C01/T1_RT');
var composite = ee.Algorithms.Landsat.simpleComposite(l8raw);
//ee.Algorithms.Landsat.simpleComposite()
//从原始Landsat场景集合计算一个Landsat TOA复合。它应用标准的TOA校准,然后使用SimpleLandsatCloudScore算法为每个像素分配云分数。
//它在每个点上选择云分数的最低可能范围,然后从接受的像素中计算每个波段的百分比值
var labels = ee.FeatureCollection('projects/google/demo_landcover_labels');
// Increase the data a little bit, possibly introducing noise.
labels = labels.map(function(f) { return f.buffer(100, 10); });
//Polygon.buffer(distance, maxError, proj)
//labels也是featurecollection,是一些点状的landcover样本
var bands = ['B2', 'B3', 'B4', 'B5', 'B6', 'B7'];
var data = composite.select(bands).sampleRegions({
collection: labels,
properties: ['landcover'],
scale: 30
});
//ee.Image.sampleRegions
//Converts each pixel of an image (at a given scale) that intersects one or more regions to a Feature, returning them as a FeatureCollection.
//Each output feature will have one property per band of the input image, as well as any specified properties copied from the input feature.
print(data)//featurecollection数据集4000多个元素
Map.addLayer(data)
// Add a column of uniform random numbers called 'random'.
data = data.randomColumn();
//FeatureCollection.randomColumn(columnName, seed, distribution) 生成新属性[0-1]随机数
//将确定性伪随机数列添加到集合中。输出是双精度浮点数。当使用'均匀'分布(默认)时,输出在[0,1)的范围内。
// Partition into training and testing.
var training = data.filter(ee.Filter.lt('random', 0.5));
var testing = data.filter(ee.Filter.gte('random', 0.5));
// Tune the minLeafPopulation parameter.
var minLeafPops = ee.List.sequence(1, 10);
var accuracies = minLeafPops.map(function(p) {
var classifier = ee.Classifier.smileCart({minLeafPopulation: p})
.train({
features: training,
classProperty: 'landcover',
inputProperties: bands
});
return testing
.classify(classifier)
.errorMatrix('landcover', 'classification')
.accuracy();
});
print(ui.Chart.array.values({
array: ee.Array(accuracies),
axis: 0,
xLabels: minLeafPops
}));
Join vs. map-filter
//假设您希望根据时间、位置或某些元数据属性联接集合。通常,使用连接可以最有效地完成这一任务。