本入门指南旨在帮助您快速开始使用 Earth Engine JavaScript API 进行编程。如需简要了解 JavaScript 以及有关 Earth Engine API 的更深入练习,请参阅教程。如需了解推荐的 JavaScript 编码风格,请参阅 Google JavaScript 风格指南。
借助 Google Earth Engine,用户可以在 Google 基础������上存���的地理参照图像和矢量上运行算法。Google Earth Engine API 提供了一个函数库,可应用于数据以进行显示和分析。Earth Engine 的公共数据目录包含大量公开图像和矢量数据集。您还可以在用户的个人文件夹中创建不公开的资源。
如何使用这些文档
Earth Engine 文档面向熟悉地理空间数据分析的用户。这些文档主要按数据类型进行构建。例如,左侧导航栏包含指向与重要数据类型(例如 Image
、ImageCollection
、Feature
、FeatureCollection
、Geometry
、Reducer
、Chart
、Join
和 Array
)相关的部分或页面的链接。本指南仅介绍了这些类型的相关信息,仅供您参考。还有一些部分介绍了机器学习、专用算法或特定于传感器的算法(例如 Landsat 算法)、面向公众的应用、数据(资产)管理,以及 Earth Engine 内部运作的重要详细信息。
在深入了解这些内容之前,请先从这里开始!
代码编辑器
代码编辑器是一个用于开发 Earth Engine 应用的交互式环境(图 1)。中间面板提供了一个 JavaScript 代码编辑器。编辑器上方有用于保存当前脚本、运行脚本和清除映射的按钮。获取链接按钮会在地址栏中为脚本生成唯一的网址。底部面板中的地图包含脚本添加的图层。顶部有一个用于搜索数据集和地点的搜索框。左侧面板包含代码示例、已保存的脚本、可搜索的 API 参考文档以及私密数据的资源管理器。右侧面板包含用于查询地图的检查器、输出控制台,以及用于长时间运行的任务的管理器。 右上角的“帮助”按钮 代码编辑器指南和获取帮助指南。
包含指向本指南和其他帮助资源的链接。 如需了解详情,请参阅
在代码编辑器中打开和运行代码
以下步骤演示了如何打开 Earth Engine 并执行用于显示图片的自定义脚本。为了获得最佳效果,您可能需要安装最新版本的 Chrome(Google 的网络浏览器),该版本可在此处获取。
- 前往以下网址打开 Earth Engine 代码编辑器: code.earthengine.google.com。
- 前往代码编辑器最左侧的脚本标签页。您可以在此处找到一系列用于访问、显示和分析 Earth Engine 数据的示例脚本。
- 在“图片集合”下,选择“滤除的复合图”示例。您会在中央控制台中看到一个脚本。按 Run 按钮以执行脚本。“经过过滤的合成图”示例会选择与科罗拉多州和犹他州重叠或位于其边界内的 Landsat 7 图像。然后,它会显示所选图片的真实彩色合成图像。这些示例向您介绍了常用的方法,例如
filter()
、clip()
和Map.addLayer()
。
Earth Engine 数据结构
Earth Engine 中最重要的两个地理数据结构是 Image
和 Feature
,分别对应于光栅数据类型和矢量数据类型。图片由波段和属性字典组成。
地图项由 Geometry
和属性字典组成。一堆图像(例如图像时间序列)由 ImageCollection
处理。一组地图项由 FeatureCollection
处理。Earth Engine 中的其他基本数据结构包括 Dictionary
、List
、Array
、Date
、Number
和 String
(如需详细了解基本数据类型,请参阅此教程)。请��必注���,这些都是服务器端对象,其操作方式与客户端 JavaScript 对象不同(了解详情)。
Earth Engine 算法
您可以通过多种方式在 API 中运行操作:
- 调用附加到对象的方法。
- 调用算法。
- 调用 Code Editor 专用函数。
- 定义新函数。
代码编辑器的 Docs(文档)标签页列出了每个 API 类的方法。例如,Image
类具有 add()
方法:
Code Editor (JavaScript)
var image3 = image1.add(image2);
此方法会将 image2
的频段添加到 image1
的频段。
ee.Algorithms
类别包含目前支持的专用或特定于领域的处理算法列表。例如,如需根据输入数字地形模型 (DEM) 创建地形图层,请执行以下操作:
Code Editor (JavaScript)
var terrainImage = ee.Algorithms.Terrain(dem);
代码编辑器专用函数包括 Map
和 Export
方法,分别用于控制如何将图层添加到地图面板或导出到 Google 云端硬盘。您还可以使用以下方法在 JavaScript 中创建函数
Code Editor (JavaScript)
var myFunction = function(args) { // do something return something; };
如“映射”部分所示,用户定义的函数非��适用于使用以下方法创建自定义功能或修改集合的元素:
Code Editor (JavaScript)
var collection2 = collection1.map(aFunction);
以下部分将通过各种简单的用例来说明这些概念。
'Hello world!' JavaScript
将信息输出到控制台是一项基本任务,可用于获取有关对象的信息、显示计算的数值结果、显示对象元数据或帮助调试。代码编辑器中标志性的“Hello World!”示例为:
Code Editor (JavaScript)
print('Hello world!');
将这行代码复制到 Code Editor 的代码编辑器中,然后点击 Run。请注意,输出结果会显示在代码编辑器右侧的控制台标签页中。下面的示例与遥感更相关,它会输出 Landsat 8 图像的元数据:
Code Editor (JavaScript)
print(ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318'));
仔细检查控制台中的输出,查看可用于 Landsat 图像的元数据。
向地图添加数据
除了将信息输出到控制台之外,向 Map
添加数据也是可视化地理数据的方法。请使用 Map.addLayer()
执行此操作。在以下示例中,使用 ee.Image()
实例化了 Image
(稍后会介绍如何查找这些图片),并使用 Map.addLayer()
将其添加到地图中,然后将地图居中显示在图片上:
Code Editor (JavaScript)
// Load an image. var image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318'); // Center the map on the image. Map.centerObject(image, 9); // Display the image. Map.addLayer(image);
Map.centerObject()
的第二个参数是缩放级别,数字越大,比例越大(放得越大)。Map
函数的参数在 API 参考文档中进行了详细介绍,您可以通过文档标签页访问该文档。如果图片的外观不令人满意,请使用 Map.addLayer()
的附加参数配置显示参数。例如:
Code Editor (JavaScript)
// Load the image from the archive. var image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318'); // Define visualization parameters in an object literal. var vizParams = {bands: ['B5', 'B4', 'B3'], min: 0.02, max: 0.4, gamma: 1.3}; // Center the map on the image and display. Map.centerObject(image, 9); Map.addLayer(image, vizParams, 'Landsat 8 false color');
请注意,可视化参数由对象字面量定义,其中包括要显示的波段列表、最小反射率值和最大反射率值,以及伽玛值。 (如需详细了解 Landsat 波段,请点击此处。)如需详细了解图片可视化,请点击此处。
使用 Map.addLayer()
将地图项和地图项集合添加到地图。例如:
Code Editor (JavaScript)
var counties = ee.FeatureCollection('TIGER/2018/Counties'); Map.addLayer(counties, {}, 'counties');
查找图片、图片集和地图项集合
您可以通过搜索 Earth Engine 数据目录来发现图片、图片集和地图项集。例如,在搜索字段中输入“Landsat 8”会显示一个栅格数据集列表。(如需查看 Earth Engine 数据集的完整列表,请访问 Earth Engine 数据目录)。 点击数据集名称即可获取简短说明、时间可用性信息、数据提供方和合集 ID。点击 Import 按钮,系统会在脚本顶部自动创建一个 Imports 部分,并为此集合添加一个变量。
或者,复制集合 ID 并将其粘贴到代码中。例如,选择“Landsat 8”搜索的 Tier 1 TOA 结果,然后复制 ID,如下所示:
Code Editor (JavaScript)
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA');
由于这是一个包含许多图片的集合,这些图片涵盖了地球陆地表面,因此若要在该集合中查找单张图片,需要进行过滤以缩小搜索范围。 或者,您也可以使用合成和拼接技术将图片集合缩减为单张图片。如需详细了解过滤和合成(请参阅减少),请参阅下一部分。
您还可以通过数据目录使用地图项集合。与图像集相比,它们的表示方式较小,但您可以找到国际边界、人口普查区边界、水系边界和保护区边界等。如需详细了解如何导入您自己的矢量数据集,请点击此处。
过滤和排序
通常需要按空间和/或时间过滤集合,以限制结果数量。例如,假设您要对 Landsat 8 场景集进行排序,以便查找旧金山的无云场景。首先,需要定义感兴趣的区域。这时,���个点通常���有用。激活 Code Editor 右侧的 Inspector 标签页,然后点击感兴趣区域的中心附近,复制 Inspector 标签页中的坐标,然后使用以下代码构建 Point
:
Code Editor (JavaScript)
var point = ee.Geometry.Point(-122.262, 37.8719);
构建开始日期和结束日期:
Code Editor (JavaScript)
var start = ee.Date('2014-06-01'); var finish = ee.Date('2014-10-01');
使用点和日期过滤 Landsat 8 集合,然后使用元数据属性(在检查 Landsat 8 场景元数据期间发现)进行排序:
Code Editor (JavaScript)
var filteredCollection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA') .filterBounds(point) .filterDate(start, finish) .sort('CLOUD_COVER', true);
您可以放心地打印和检查此合集。(如果合集包含的图片过多,则打印速度会非常慢、超时或返回错误)。请注意,集合中的图片是存储在 ImageCollection
的“features”属性中的 List
。您可以像上面所示那样,将该集合中的任何图片的 ID 复制到 Image
构造函数中。或者,获取第一张图片(云层覆盖率最低):
Code Editor (JavaScript)
var first = filteredCollection.first();
使用 filter()
作为实参来访问完整的 Earth Engine 过滤功能。ee.Filter
(上面使用的 filterBounds()
和 filterDate()
方法是快捷方式)。例如,以下代码会创建 Filter
,使用它过滤 FeatureCollection
并显示结果:
Code Editor (JavaScript)
// Load a feature collection. var featureCollection = ee.FeatureCollection('TIGER/2016/States'); // Filter the collection. var filteredFC = featureCollection.filter(ee.Filter.eq('NAME', 'California')); // Display the collection. Map.setCenter(-119.604, 37.798, 6); Map.addLayer(filteredFC, {}, 'California');
频段计算
使用 Image
方法对图片执行数学运算。这可能包括波段重组(光谱指数)、图像差分或数学运算(例如乘以常数)。例如,计算相隔 20 年的常态化差值植生指标 (NDVI) 图像之间的差异:
Code Editor (JavaScript)
// This function gets NDVI from Landsat 5 imagery. var getNDVI = function(image) { return image.normalizedDifference(['B4', 'B3']); }; // Load two Landsat 5 images, 20 years apart. var image1 = ee.Image('LANDSAT/LT05/C02/T1_TOA/LT05_044034_19900604'); var image2 = ee.Image('LANDSAT/LT05/C02/T1_TOA/LT05_044034_20100611'); // Compute NDVI from the scenes. var ndvi1 = getNDVI(image1); var ndvi2 = getNDVI(image2); // Compute the difference in NDVI. var ndviDifference = ndvi2.subtract(ndvi1);
请注意,此示例中使用了用户定义的 function
。如需详细了解函数,请参阅下一部分。
映射(在 for 循环之外可以执行的操作)
使用 map()
遍历集合中的项。(在 Earth Engine 中,for 循环并非执行此操作的正确方式,应避免使用)。map()
函数可应用于 ImageCollection
、FeatureCollection
或 List
,并接受 function
作为其参数。函数的参数是其映射到的集合的元素。这对于以相同方式修改集合的每��元素(例如添加)非常有用。例如,以下代码会向 ImageCollection
中的每个图片添加 NDVI 波段:
Code Editor (JavaScript)
// This function gets NDVI from Landsat 8 imagery. var addNDVI = function(image) { return image.addBands(image.normalizedDifference(['B5', 'B4'])); }; // Load the Landsat 8 TOA data, filter by location and date. var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA') .filterBounds(ee.Geometry.Point(-122.262, 37.8719)) .filterDate('2014-06-01', '2014-10-01'); // Map the function over the collection. var ndviCollection = collection.map(addNDVI);
另一项常见任务是向 FeatureCollection
中的地图项添加新属性(或“属性”或“字段”)。在以下示例中,新属性是涉及两个现有属性的计算:
Code Editor (JavaScript)
// This function creates a new property that is the sum of two existing properties. var addField = function(feature) { var sum = ee.Number(feature.get('property1')).add(feature.get('property2')); return feature.set({'sum': sum}); }; // Create a FeatureCollection from a list of Features. var features = ee.FeatureCollection([ ee.Feature(ee.Geometry.Point(-122.4536, 37.7403), {property1: 100, property2: 100}), ee.Feature(ee.Geometry.Point(-118.2294, 34.039), {property1: 200, property2: 300}), ]); // Map the function over the collection. var featureCollection = features.map(addField); // Print a selected property of one Feature. print(featureCollection.first().get('sum')); // Print the entire FeatureCollection. print(featureCollection);
请注意,为了使用 add()
方法,需要将属性值转换为 ee.Number
,以便系统将其识别为数字。集合的类型可以通过 map()
更改。例如:
Code Editor (JavaScript)
// This function returns the image centroid as a new Feature. var getGeom = function(image) { return ee.Feature(image.geometry().centroid(), {foo: 1}); }; // Load a Landsat 8 TOA collection. var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA') .filterBounds(ee.Geometry.Point(-122.262, 37.8719)) .filterDate('2014-06-01', '2014-10-01'); // Map the function over the ImageCollection. var featureCollection = ee.FeatureCollection(collection.map(getGeom)); // Print the collection. print(featureCollection);
请注意,根据图片重心创建的每个地图项都添加了属性 (foo
)。在最后一行中,转换会使生成的集合可识别为 FeatureCollection
。
减少
在 Earth Engine 中,缩减是指跨时间、空间、波段、数组和其他数据结构聚合数据的方法。API 中提供了多种用于此目的的方法。例如,如需对 ImageCollection
进行合成,请使用 reduce()
将集合中的图片缩减为一张图片。一个简单的示例是,创建之前定义的 Landsat 8 集合中云量最少的五个场景的中位数合成图:
Code Editor (JavaScript)
// Load a Landsat 8 TOA collection. var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA') // Filter by date and location. .filterBounds(ee.Geometry.Point(-122.262, 37.8719)) .filterDate('2014-01-01', '2014-12-31') // Sort by increasing cloudiness. .sort('CLOUD_COVER'); // Compute the median of each pixel for each band of the 5 least cloudy scenes. var median = collection.limit(5).reduce(ee.Reducer.median());
缩减也是获取 Feature
或 FeatureCollection
定义的区域中图片的统计信息的方法。假设任务是计算感兴趣区域内的像素平均值。为此,请使用 reduceRegion()
。例如:
Code Editor (JavaScript)
// Load and display a Landsat TOA image. var image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318'); Map.addLayer(image, {bands: ['B4', 'B3', 'B2'], max: 0.3}); // Create an arbitrary rectangle as a region and display it. var region = ee.Geometry.Rectangle(-122.2806, 37.1209, -122.0554, 37.2413); Map.addLayer(region); // Get a dictionary of means in the region. Keys are bandnames. var mean = image.reduceRegion({ reducer: ee.Reducer.mean(), geometry: region, scale: 30 });
如需详细了解 reducer,请参阅 “Reducer”文档。
遮盖
ee.Image
中的每个像素都有一个值和一个掩码,值介于 0(无数据)到 1 之间,掩码介于 0(无数据)到 1 之间。系统会将已掩码的像素(其中 mask==0)视为无数据。当掩码值介于 0 到 1 之间时,像素具有值,但在进行数值计算时,该值会按掩码进行加权。
您可以使用遮罩使像素透明或将其从分析中排除。当蒙版值为零时,像素会被遮盖。继续使用图片差异示例,使用掩码来显示差异间隔内 NDVI 增加和减少的区域:
// This function gets NDVI from Landsat 5 imagery. var getNDVI = function(image) { return image.normalizedDifference(['B4', 'B3']); }; // Load two Landsat 5 images, 20 years apart. var image1 = ee.Image('LANDSAT/LT05/C02/T1_TOA/LT05_044034_19900604'); var image2 = ee.Image('LANDSAT/LT05/C02/T1_TOA/LT05_044034_20100611'); // Compute NDVI from the scenes. var ndvi1 = getNDVI(image1); var ndvi2 = getNDVI(image2); // Compute the difference in NDVI. var ndviDifference = ndvi2.subtract(ndvi1); // Load the land mask from the SRTM DEM. var landMask = ee.Image('CGIAR/SRTM90_V4').mask(); // Update the NDVI difference mask with the land mask. var maskedDifference = ndviDifference.updateMask(landMask); // Display the masked result. var vizParams = {min: -0.5, max: 0.5, palette: ['FF0000', 'FFFFFF', '0000FF']}; Map.setCenter(-122.2531, 37.6295, 9); Map.addLayer(maskedDifference, vizParams, 'NDVI difference');
请注意,在此示例中,NDVI 差异的掩码会由包含 updateMask()
的土地掩码更新。这会将 NDVI 差异像素的遮罩设置为土地遮罩,只要 NDVI 差异遮罩不为零,就会执行此操作。
遮盖功能还可用于从分析中排除数据。请考虑“缩减”部分中的 reduceRegion()
示例。假设任务是计算加利福尼亚州圣克拉拉县的季节性平均 NDVI,不包括多云像素。以下示例演示了多种概念:过滤、映射、缩减和使用云遮罩:
Code Editor (JavaScript)
// This function gets NDVI from a Landsat 8 image. var addNDVI = function(image) { return image.addBands(image.normalizedDifference(['B5', 'B4'])); }; // This function masks cloudy pixels. var cloudMask = function(image) { var clouds = ee.Algorithms.Landsat.simpleCloudScore(image).select(['cloud']); return image.updateMask(clouds.lt(10)); }; // Load a Landsat collection, map the NDVI and cloud masking functions over it. var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA') .filterBounds(ee.Geometry.Point([-122.262, 37.8719])) .filterDate('2014-03-01', '2014-05-31') .map(addNDVI) .map(cloudMask); // Reduce the collection to the mean of each pixel and display. var meanImage = collection.reduce(ee.Reducer.mean()); var vizParams = {bands: ['B5_mean', 'B4_mean', 'B3_mean'], min: 0.02, max: 0.4}; Map.addLayer(meanImage, vizParams, 'mean'); // Load a region in which to compute the mean and display it. var counties = ee.FeatureCollection('TIGER/2018/Counties'); var santaClara = ee.Feature(counties.filter(ee.Filter.eq('NAME', 'Santa Clara')).first()); Map.addLayer(santaClara); // Get the mean of NDVI in the region. var mean = meanImage.select(['nd_mean']).reduceRegion({ reducer: ee.Reducer.mean(), geometry: santaClara.geometry(), scale: 30 }); // Print mean NDVI for the region. mean.get('nd_mean').evaluate(function(val){ print('Santa Clara spring mean NDVI:', val); });