其实,早在一年前大约就想写这么一篇文章了,起因是看到GOOGLE_Dynamic world数据的调用代码,对里面的一个函数使用非常感兴趣。我相信很多人会有同样的感受。
首先,我们来看下GOOGLE_Dynamic world数据的调用代码,以及其对应的效果。代码其实很短,就下面几行:
// Construct a collection of corresponding Dynamic World and Sentinel-2 for
// inspection. Filter by region and date.
var START = ee.Date('2021-04-02');
var END = START.advance(1, 'day');
var colFilter = ee.Filter.and(
ee.Filter.bounds(ee.Geometry.Point(20.6729, 52.4305)),
ee.Filter.date(START, END));
var dwCol = ee.ImageCollection('GOOGLE/DYNAMICWORLD/V1').filter(colFilter);
var s2Col = ee.ImageCollection('COPERNICUS/S2_HARMONIZED');
// Link DW and S2 source images.
var linkedCol = dwCol.linkCollection(s2Col, s2Col.first().bandNames());
// Get example DW image with linked S2 image.
var linkedImg = ee.Image(linkedCol.first());
// Create a visualization that blends DW class label with probability.
// Define list pairs of DW LULC label and color.
var CLASS_NAMES = [
'water', 'trees', 'grass', 'flooded_vegetation', 'crops',
'shrub_and_scrub', 'built', 'bare', 'snow_and_ice'];
var VIS_PALETTE = [
'419bdf', '397d49', '88b053', '7a87c6', 'e49635', 'dfc35a', 'c4281b',
'a59b8f', 'b39fe1'];
// Create an RGB image of the label (most likely class) on [0, 1].
var dwRgb = linkedImg
.select('label')
.visualize({min: 0, max: 8, palette: VIS_PALETTE})
.divide(255);
// Get the most likely class probability.
var top1Prob = linkedImg.select(CLASS_NAMES).reduce(ee.Reducer.max());
// Create a hillshade of the most likely class probability on [0, 1];
var top1ProbHillshade =
ee.Terrain.hillshade(top1Prob.multiply(100))
.divide(255);
// Combine the RGB image with the hillshade.
var dwRgbHillshade = dwRgb.multiply(top1ProbHillshade);
// Display the Dynamic World visualization with the source Sentinel-2 image.
Map.setCenter(20.6729, 52.4305, 12);
Map.addLayer(
linkedImg, {min: 0, max: 3000, bands: ['B4', 'B3', 'B2']}, 'Sentinel-2 L1C');
Map.addLayer(
dwRgbHillshade, {min: 0, max: 0.65}, 'Dynamic World V1 - label hillshade');
其实现的效果如下所示:
很显然,这些代码实现了将Sentinel-2影像数据和其分类结果图链接到了一起,如上图所示。这个功能虽说不复杂,其主要功能实现的是一种GEE中经常遇到的操作,有人可能听说过,叫Join的操作,也就是把数据集根据有些属性组合到一起。
在常用的Join中,是需要定义过滤条件,涉及到一些繁琐的步骤。很多人可能到现在也不是很理解。但是,看上面的代码就会发现,使用了一个叫linkCollection的函数,而这个函数就起到了Join的作用,其作用解释如下:
是不是把Join很复杂的功能就实现了呢?
当我们早在一年前第一次看到这个代码的时候,就觉得非常的开心。因为这样的功能在把复杂的事情简单化,让大家用起来就很舒服。这个例子总是在提醒我Google的工程师们,至少是做Google Earth Engine的工程师们,在做很多有用、有趣的工作,这一点非常让人敬佩。
反思到自己的工作,包括我们自己的文章,很多时候并没有把一些很好的东西讲清楚,甚至有时候把简单的事情复杂化了。更重要的是,我们很可能只是实现了某一功能,但是却没有“完美”某一功能。举个例子,我了解到的很多科研工作者在实现了一个idea后,就没有完善相关的代码,更没有做好优化,导致最后的工作只是一些零零散散的片段,实际上要真的实现可靠工程方案的时候,距离还很远,维护成本很高。所以,我总有一种自己做研究做了甚至不到一半的感觉,很难做出非常吸引人的成功和产品。当然,这也是为什么我们一直在优化自己的研究和相关产品。
当然,上面只是简单的记录一些自己的想法,希望新的一年能够改正这些,做出更好的研究和产品。