解决方案

GEE初学者笔记之快速上手篇

seo靠我 2023-09-26 06:39:41

1.基础概念

(1)谷歌云平台

整个GEE是基于Google Cloud云平台的一整套API开发环境。因此整个数据的处理全部都是在Google Cloud平台上实现的,无需本地机器参与运算。一般开发流程是SEO靠我在线/离线编辑代码,然后提交服务器端运行,完成之后会输出给我们一些结果。这个思路适合离线本地开发不太一样的。处理的时候,整个算法还有数据都是在云端的,所以不要想着用本地Python环境就可以离线开发或SEO靠我使用GEE。它本身只是一个包装好的API供你调用,核心是云端的服务器。这点需要注意。正式因为这种本地-服务器端的差别,所以GEE也专门有自己的变量类型,基本是ee.xxx形式。我们在写代码的时候要区分SEO靠我JS自己的类型和GEE的数据类型。这在下面会进一步介绍。

(2)函数化编程

由于整个GEE是在云端的,所以官方建议尽可能所有操作都可并行,这样可以大大提升执行效率。这点是有点类似于CUDA的编程思想。简而SEO靠我言之就是对于很多重复的操作,你要做的就是定义好这个操作本身,然后循环遍历的工作就交给系统就好,他会自动并行帮你完成。官方文档中对于常见的循环、条件判断、累加三个操作进行了举例。这在之后再详细介绍。

2.SEO靠我基本数据类型

上面也提到了,由于整个代码是运行在云端的,所以GEE自定义了自己的数据类型,基本是ee.xxx形式,包括ee.String、ee.Number、ee.List、ee.Dictionary、SEO靠我ee.Date等。它们的定义及使用基本还是遵循常规方法,所以这里就简单演示一下。代码如下。

// 新建一个服务器上的字符串 var serverString = ee.String(ThSEO靠我is is on the server.); print(String on the server:, serverString);// 新建一个服务器上的数字 varSEO靠我 serverNumber = ee.Number(3.14159); print(number=,serverNumber);// 新建一个服务器上的列表 var sSEO靠我erverList = ee.List([1,5,6,9,2]); print(Sequence:,serverList); // 注意,由于是服务器上的List,所以SEO靠我需要通过get()函数获得内容,而不是直接索引 print(item 2:,serverList.get(2));// 新建一个服务器上的字典,包含三个键值对 var SEO靠我serverDict = ee.Dictionary({e:Math.E,pi:Math.PI,phi:(1+Math.sqrt(5))/2 }); // 和上面一样,SEO靠我需要通过get()函数获取数据 print(Golden ratio:,serverDict.get(phi)); print(Keys:,serverDict.keySEO靠我s());// 新建一个服务器上的日期 var serverDate = ee.Date(2020-10-13); print(date:,serverDate);

控制SEO靠我台输出结果如下所示。

3.基本语法

        这里的基本语法并不是指JS的基本语法,而是指上面提到的对于循环、条件判断以及累加操作的并行化写法。

(1)循环

        一个适合于GEE的并行的循环写法如下。

// This genSEO靠我erates a list of numbers from 1 to 10. var myList = ee.List.sequence(1, 10);// The map() opeSEO靠我ration takes a function that works on each element independently // and returns a value. YouSEO靠我 define a function that can be applied to the input. var computeSquares = function(number) {SEO靠我// We define the operation using the EE API.return ee.Number(number).pow(2); };// Apply yourSEO靠我 function to each item in the list by using the map() function. var squares = myList.map(comSEO靠我puteSquares); print(squares); // [1, 4, 9, 16, 25, 36, 49, 64, 81]

(2)条件判断

下面代码演示了如何遍历一个List,寻SEO靠我找到其中的奇数。其实核心在于对每个元素对2取余,然后删除那些为0的元素,即可得到奇数。这个例子通过数学计算,避免了if/else的判断。是一种值得学习的思路。

// The following funcSEO靠我tion determines if a number is even or odd. The mod(2) // function returns 0 if the number iSEO靠我s even and 1 if it is odd (the remainder // after dividing by 2). The input is multipled by SEO靠我this remainder so even // numbers get set to 0 and odd numbers are left unchanged. vSEO靠我ar getOddNumbers = function(number) {number = ee.Number(number); // Cast the input to a Number so weSEO靠我 can use mod.var remainder = number.mod(2);return number.multiply(remainder); };// This geneSEO靠我rates a list of numbers from 1 to 10. var myList = ee.List.sequence(1, 10);// filtering SEO靠我 var newList = myList.map(getOddNumbers);// Remove the 0 values. var oddNumbers = newListSEO靠我.removeAll([0]); print(oddNumbers);

        另外,对于二维的影像而言,同样可以采用类似的操作来避免if/else判断,如下面的例子所示。

var collectSEO靠我ion = ee.ImageCollection(LANDSAT/LC08/C01/T1_TOA);// Divide the collection into 2 subsets and apply SEO靠我a different algorithm on them. var subset1 = collection.filter(ee.Filter.lt(SUN_ELEVATION, 4SEO靠我0)); var subset2 = collection.filter(ee.Filter.gte(SUN_ELEVATION, 40));var processed1 = subsSEO靠我et1.map(function(image) {return image.multiply(2); }); var processed2 = subset2;// MSEO靠我erge the collections to get a single collection. var final = processed1.merge(processed2); SEO靠我 print(Original collection size, collection.size()); print(Processed collection size, SEO靠我final.size());

        这里ee.Filter.lt()是表示过滤那些比给定值小的数据,ee.Filter.gte()表示过滤那些比给定值大的数据。

(3)累加

        下面代码展示了生成斐波那契数列。

varSEO靠我 algorithm = function(current, previous) {previous = ee.List(previous);var n1 = ee.Number(previous.gSEO靠我et(-1));var n2 = ee.Number(previous.get(-2));return previous.add(n1.add(n2)); };// Compute 1SEO靠我0 iterations. var numIteration = ee.List.repeat(1, 10); var start = [0, 1]; SEO靠我var sequence = numIteration.iterate(algorithm, start); print(sequence); // [0, 1, 1, 2, 3, 5SEO靠我, 8, 13, 21, 34, 55, 89]

4.可视化影像与波段

在上面的部分介绍了GEE JS API的相关基本语法。这部分主要介绍一些比较具体的内容。如何利用GEE在地图上可视化影像。实现对影像SEO靠我数据的可视化非常简单,主要有三步:创建影像实例、设置地图中心点、添加图层。其中中间这一步不是必须的,核心就是创建一个影像实例,然后将这个实例添加到地图图层中。下面代码演示了可视化STRM数据。

// ISEO靠我nstantiate an image with the Image constructor. var image = ee.Image(CGIAR/SRTM90_V4);// ZooSEO靠我m to a location. Map.setCenter(117.3798, 32.9049, 4); // Center on the Bengbu City.// DisplaSEO靠我y the image on the map. Map.addLayer(image);

下面对代码进行简单解析。首先,对于影像实例,直接通过ee.Image()构造函数生成即可,传入的SEO靠我参数是要显示的数据的Image ID。关于这个ID,可以在GEE的数据库里寻找,找到后把那一串代码复制过来就好。第二行是调用Map类的成员函数setCenter()设置地图的中心点,参数分别是经度、纬SEO靠我度和缩放等级。缩放等级越大地图越放大。最后一行是将我们刚刚获取到的影像放到Map的图层中进行展示。

对于一个影像,我们可以通过print()函数来输出它的相关信息。比如,我们在上面代码的最后增加一行prSEO靠我int(SRTM image,image);。控制台中会出现如下内容。

可以看到,显示了SRTM数据的一些基本信息,包括数据类型(signed int16)、影像大小(432000×144000)等等,SEO靠我非常丰富。

        另外,我们可以在addLayer()的时候增加一些参数,使得可视化更符合我们的需求,如下是该函数的文档。

比如说,我们可以设置显示范围,像这样修改上面代码的最后一行为Map.addLayer(SEO靠我image, {min: 0, max: 3000}, custom visualization);。这里我们将显示的搞高程范围限制在了0到3000m,图层的名称为custom visualizatiSEO靠我on,可以看到如下效果。而之前的效果是这样的。可以看到显示效果差异非常大。一个很重要的原因就在于,在原始的SRTM中是存在负值的(上面输出的SRTM信息),最小值为-32768。所以就会导致显示出来的SEO靠我效果很差了。

我们除了可以控制数据显示的范围,同样也可以数据显示的颜色等级。比如将上面代码的最后一行换成下面这样:Map.addLayer(image, {min: 0, max: 3000, paleSEO靠我tte: [Moccasin, Orange, Coral]},custom palette);。我们可以通过标准颜色名称(标准颜色名称可以参考这里),或者十六进制字符串指定颜色。效果如下。

5.影像集SEO靠我

        影像集(Image Collection)可以理解为是多个影像(Image)组成的集合。这里以一个例子展示如何对影像进行过滤和筛选,最后显示在地图上。代码如下。

// 获取Landsat8 TOA影像 SEO靠我 var l8 = ee.ImageCollection(LANDSAT/LC08/C01/T1_TOA);// 定义一个目标点 var point = ee.GeomeSEO靠我try.Point(117.0721,33.2363);// 调用filterBounds筛选位置 var spatialFiltered = l8.filterBounds(poinSEO靠我t); print(spatialFiltered,spatialFiltered);// 再调用filterDate筛选时间 var temporalFilteredSEO靠我 = spatialFiltered.filterDate(2015-01-01,2015-12-31); print(temporalFiltered,temporalFiltereSEO靠我d);// 到这一步之后,还可能有很多影像的,我们可以进一步按照云层覆盖进行排序 var sorted = temporalFiltered.sort(CLOUD_COVER); SEO靠我 // 选取含云量最少的那一景 var scene = sorted.first();// 将影像放到当前地图的中心,缩放9级 Map.centerObjecSEO靠我t(scene,9);// Landsat8的RGB波段分别是B4、B3、B2 // 最大值设为0.3,最小值默认为0 var visParams = {bands:[SEO靠我B4,B3,B2],max:0.3};// 展示影像,名称为true-color composite Map.addLayer(scene,visParams,true-color cSEO靠我omposite);

        最后的效果如下。

通过指定一目标点,我们对数据集在空间上进行了过滤,然后又在时间上进行了限制。最后,选出云量最少的一景作为展示。同事注意Landsat8的数据RGB波段的顺序,最后进SEO靠我行展示。

6.实例练习-基于Landsat数据计算NDVI

综合前面的知识,我们下面就可以做一些实际的、有意义的事情了——计算NDVI。我们知道NDVI(Normalized Difference VegSEO靠我etation Index)可以反映一个地区的植被覆盖情况,计算公式为(NIR-Red)/(NIR+Red)。这里,我们以Landsat8的数据为例,计算某个区域的NDVI并可视化到地图上,代码如下所SEO靠我示。

// 指定某个目标点 var point = ee.Geometry.Point([117.0721,33.2363]);// 导入Landsat-8 TOA影像数据集 SEO靠我 var l8 = ee.ImageCollection(LANDSAT/LC08/C01/T1_TOA);// 获取2015年云量最少的影像 var image = ee.ImaSEO靠我ge(l8.filterBounds(point).filterDate(2015-01-01, 2015-12-31).sort(CLOUD_COVER).first() );// SEO靠我计算Normalized Difference Vegetation Index (NDVI) // Landsat8 第5波段是近红外(NIR),第4波段是红波段(Red) SEO靠我 var nir = image.select(B5); var red = image.select(B4); // 套用NDVI计算公式(NIR-Red)/(SEO靠我NIR+Red) var ndvi = nir.subtract(red).divide(nir.add(red)).rename(NDVI);// 设置影像到地图中心 SEO靠我 Map.centerObject(image,9); // 设置最大最小值和显示颜色 var ndviParams = {min:-1,max:1,palette:[SEO靠我blue,white,green]}; // 向地图中添加图层 Map.addLayer(ndvi,ndviParams,NDVI image);

运行代码后,效果如下图SEO靠我所示。

值得注意的是,NDVI的这种计算模式在遥感中其实是非常常见的,因此,在GEE中,我们完全可以不用自己写公式,GEE已经帮我们定义好了相关函数,直接调用就行。具体是.normalizedDiffeSEO靠我rence()函数。使用也非常简单,把上面代码中计算ndvi的一行用以下内容替代var ndvi = image.normalizedDifference([B5,B4]).rename(NDVI);SEO靠我运行的效果和自己写是一样的。

        在上面的实例中,我们对单景影像计算了NDVI。GEE同样支持对多景影像同时计算NDVI。示例代码如下。

// 导入Landsat-8 TOA影像数据集 varSEO靠我 l8 = ee.ImageCollection(LANDSAT/LC08/C01/T1_TOA);var addNDVI = function(image) {var ndvi = image.noSEO靠我rmalizedDifference([B5, B4]).rename(NDVI);return image.addBands(ndvi); };// 利用GEE的map函数并行计算NSEO靠我DVI var withNDVI = l8.map(addNDVI);// 我们可用计算好的NDVI找到所有影像中最“绿”的像素 var greenest = withSEO靠我NDVI.qualityMosaic(NDVI);// 展示结果 var visParams = {bands: [B4, B3, B2], max: 0.3}; MaSEO靠我p.addLayer(greenest, visParams, Greenest pixel composite);

在这里,我们利用GEE的map()函数并行计算NDVI。在计算好以后,我们基于这个NSEO靠我DVI的数值来寻找影像中最“绿”的像素组成新的影像。这里最“绿”的影像意思是,别忘了,这里我们获取到的是一个影像集合,并非一个影像。同一个地方,这些影像里肯定有些时间是有植被的,有些是没有的。最“绿”SEO靠我的就是植被最茂盛的影像。

7.数据导出

GEE虽然是云端处理,但显然是支持数据的导出和下载的,不然运行的结果没法使用。数据的导出主要分为两类,一类是运算的数值类型数据的导出以及绘图,一类是影像的导出。下面SEO靠我分别介绍。

(1)数值与绘图

        下面演示了计算某个区域的NDVI的值并绘制出NDVI随时间变化的折线图。

// Import the Landsat 8 TOA image collection. SEO靠我 var l8 = ee.ImageCollection(LANDSAT/LC08/C01/T1_TOA);// Map a function over the Landsat 8 TOA colSEO靠我lection to add an NDVI band. var withNDVI = l8.map(function(image) {// Get a cloud score in SEO靠我[0, 100].var cloud = ee.Algorithms.Landsat.simpleCloudScore(image).select(cloud);// Create a mask ofSEO靠我 cloudy pixels from an arbitrary threshold.var mask = cloud.lte(20);// Compute NDVI.var ndvi = imageSEO靠我.normalizedDifference([B5, B4]).rename(NDVI);// Return the masked image with an NDVI band.return imaSEO靠我ge.addBands(ndvi).updateMask(mask); });// Define ROI. var roi = ee.Geometry.Polygon(SEO靠我[[117.211,32.847], [117.464,32.847], [117.464,32.995], [117.211,32.995], SEO靠我 [117.211,32.847]]);// Create a chart. var chart = ui.Chart.image.series({imageCollectioSEO靠我n: withNDVI.select(NDVI),region: roi,reducer: ee.Reducer.first(),scale: 30 }).setOptions({tiSEO靠我tle: NDVI over time});// Display the chart in the console. print(chart); Map.centerOSEO靠我bject(roi,11); Map.addLayer(roi);

控制台输出效果如下。

从代码层面简单解释一下,可以看到相比于前面计算NDVI的步骤,这里多了很多东西。主要原因在于是为了SEO靠我去除云层的影响。我们在折线图的右上角可以看到个箭头,点击就可以进一步预览图片。        如果我们想输出原始数据,点击右上角的”Download CSV”即可,如果想保存折线图,点击”DownloSEO靠我ad SVG/PNG”即可,十分方便。

(2)保存影像

上面保存的都是处理后的数值与绘图,那么遥感影像呢?也非常简单,主要是利用GEE的Export包实现。对于影像导出,GEE支持三种模式:导出到GoogSEO靠我le Drive、导出到Google Cloud Storage、导出到项目的Asset。如果是想下载的话,一般可以使用第一种,导出到Google Drive以后,再进行下载。这里我们以刚刚在第六部分SEO靠我计算的单景NDVI影像为例,演示导出至Google Drive。示例代码如下。

// 指定某个目标点 var point = ee.Geometry.Point([117.0721,33SEO靠我.2363]);// 导入Landsat-8 TOA影像数据集 var l8 = ee.ImageCollection(LANDSAT/LC08/C01/T1_TOA);// 获取20SEO靠我15年云量最少的影像 var image = ee.Image(l8.filterBounds(point).filterDate(2015-01-01, 2015-12-31).soSEO靠我rt(CLOUD_COVER).first() );// 计算Normalized Difference Vegetation Index (NDVI) // LandSEO靠我sat8 第5波段是近红外(NIR),第4波段是红波段(Red) var nir = image.select(B5); var red = image.select(SEO靠我B4); // 套用NDVI计算公式(NIR-Red)/(NIR+Red) var ndvi = nir.subtract(red).divide(nir.add(reSEO靠我d)).rename(NDVI);// 设置影像到地图中心 Map.centerObject(image,9); // 设置最大最小值和显示颜色 varSEO靠我 ndviParams = {min:-1,max:1,palette:[blue,white,green]}; // 向地图中添加图层 Map.addLayer(ndSEO靠我vi,ndviParams,NDVI image);// 上面的代码都一样 // 这里,调用Export的toDrive函数导出 Export.image.toDrivSEO靠我e({image: ndvi,description: NDVI,scale: 30 });

运行代码以后,除了会得到之前的结果外,在右上角的“Tasks”里也会看到有新的任务,点击“RSEO靠我un”,弹出如下对话框。填入相关信息,即可开始导出,导出完成后就会在你的Google Drive里看到对应的文件了,下载即可。如下图所示。

“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2