首页 > 其他分享 >【GEE笔记6】数据连接Join

【GEE笔记6】数据连接Join

时间:2022-10-08 16:32:47浏览次数:84  
标签:Join ee 笔记 Filter 2018 GEE var 数据


连接​​ee.Join​​​用于根据 ​​ee.Filter​​​ 指定的条件组合来自不同集合(例如 ImageCollection 或 FeatureCollection)的元素。
过滤器由每个集合中相互关联的属性的参数构成。具体来说,leftField 指定主集合中与辅助集合中的 rightField 相关的属性。
过滤器的类型(例如,equals、greaterThanOrEquals、lessThan 等)表示字段之间的关系。

连接的类型表示集合中元素之间的一对多或一对一关系以及要保留多少匹配项。
连接的输出由 ​​​join.apply()​​ 生成,并且会根据连接的类型而有所不同。

具体方法有:

  1. 只保留左侧数据集
  • 筛选符合条件的
ee.Join.simple()
  • 反选符合条件的
ee.Join.inverted()
  1. 两侧数据集均保留(数据集合并)
ee.Join.inner()
  1. 对符合要求的数据集以属性形式添加左侧数据集内
  • 用于确定符合要求的右侧数据集,结果标记在左侧新增属性字段内
ee.Join.saveAll()
  • 确定最优数据集,返回在属性字段内,只保留最优图像
ee.Join.saveBest()
  • 只保留右侧第一个符合要求数据影像
ee.Join.saveFirst()
  1. 空间连接(空间筛选器)
  • 基于距离对数据集进行连接
ee.Filter.withinDistance()
  • 基于几何位置进行连接
ee.Filter.intersects()

1. 只保留左侧数据集

筛选符合条件的

ee.Join.simple()
  • 代码详解
'用于筛选数据集影像之间相差times以内的数据集'
var filter_1 = ee.Filter.maxDifference(
{
difference: times,
'通过系统时间联系数据集(system:time_start)'
leftField: 'system:time_start',//左字段的选择器,类型为time_start,即从起始计时,单位毫秒
rightField: 'system:time_start' //右字段的选择器'
//注意:左右字段(Field)与左右对象只能选其一,如果有左右对象则无选择器(字段的单位已经存在);有选择器时,不能有对象,对象目前为未知
});
//其中times单位为毫秒,例如1天为1*24*60*60*1000

'定义一个空的simpleJoin,后边应用筛选器时是选择符合条件的结果'
var simpleJoin = ee.Join.simple();
'定义一个空的invetJoin,后边应用筛选器时是选择不符合条件的结果'
var invetJoin = ee.Join.inverted();

'对simpleJoin应用筛选器'
var simpleJoined = simpleJoin.apply(数据集1, 数据集2, filter_1);
print(simpleJoined); //可以打印查看满足条件的数据集1影像名称
  • 案例
// 引入Landsat8和Sentinal数据,利用重庆市点进行地理筛选
var L8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
.filterBounds(ee.Geometry.Point(106.3737, 29.9262));
var Sentinel = ee.ImageCollection("COPERNICUS/S2")
.filterBounds(ee.Geometry.Point(106.3737, 29.9262));
// 筛选出2018年的图像
var L8_2018= L8.filterDate('2018-01-01','2018-12-31')
var ST_2018= Sentinel.filterDate('2018-01-01','2018-12-31')
// 定义1天的变量
var One_Day_Millis = 1*24*60*60*1000
// 通过maxDifference定义Sentinel图像获取前后一天内的图像
// 单位为毫秒,1*24*60*60*1000就是一整天
var L8_Within_Sentinel = ee.Filter.maxDifference({
difference: One_Day_Millis,
leftField: 'system:time_start',
rightField: 'system:time_start'
})
// 定义一个simpleJoin
var simpleJoin = ee.Join.simple();
// 应用SimpleJoin.
var simpleJoined = simpleJoin.apply(L8_2018, ST_2018, L8_Within_Sentinel);
// 打印结果.
print('Simple join: ', simpleJoined);

【GEE笔记6】数据连接Join_云计算

反选符合条件的

ee.Join.inverted()
  • 代码详解
'用于筛选两影像某字段之间满足条件的数据集'
var filter_1 = ee.Filter.eq(
{
leftField: '字段1名称',
rightField: '字段2名称'
});

'定义一个空的innerJoin,应用筛选器时是选择符合条件的结果'
var innerJoin = ee.Join.inner('名称1', '名称2');
//定义生成结果的合成两产品的名称

'对innerJoin应用筛选器'
var toyJoin = innerJoin.apply(数据集1, 数据集2, filter_1);
print(toyJoin);
//可以打印查看满足条件的两个影像名称,分别对应前边的名称1与名称2
  • 案例
// 引入Landsat8和Sentinal数据,利用重庆市点进行地理筛选
var L8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
.filterBounds(ee.Geometry.Point(106.3737, 29.9262));
var Sentinel = ee.ImageCollection("COPERNICUS/S2")
.filterBounds(ee.Geometry.Point(106.3737, 29.9262));
// 筛选出2018年的图像
var L8_2018 = L8.filterDate('2018-01-01','2018-12-31')
var ST_2018 = Sentinel.filterDate('2018-01-01','2018-12-31')
// 定义1天的变量
var One_Day_Millis = 1*24*60*60*1000
// 通过maxDifference定义Sentinel图像获取前后一天内的图像
var L8_Within_Sentinel = ee.Filter.maxDifference({
difference: One_Day_Millis,
leftField: 'system:time_start',
rightField: 'system:time_start'
})
// 定义一个invertJoin
var Invet_Join = ee.Join.inverted();
// 应用invertJoin
var Invet_Join_Results = Invet_Join.apply(L8_2018, ST_2018, L8_Within_Sentinel);
// 打印结果.
print('Invet_Join: ', Invet_Join_Results);

【GEE笔记6】数据连接Join_遥感_02

2. 两侧数据集均保留(数据集合并)

并且会增加字段,表示左侧第几个位置和右侧第几个位置的数据符合筛选条件

ee.Join.inner()
  • 代码详解
'用于筛选两影像某字段之间满足条件的数据集'
var filter_1 = ee.Filter.eq(
{
leftField: '字段1名称',
rightField: '字段2名称'
});

'定义一个空的innerJoin,应用筛选器时是选择符合条件的结果'
var innerJoin = ee.Join.inner('名称1', '名称2');
//定义生成结果的合成两产品的名称

'对innerJoin应用筛选器'
var toyJoin = innerJoin.apply(数据集1, 数据集2, filter_1);
print(toyJoin);
//可以打印查看满足条件的两个影像名称,分别对应前边的名称1与名称2
  • 案例1
// 创建FeatureCollection_1.
var primaryFeatures = ee.FeatureCollection([
ee.Feature(null, {foo: 0, label: 'a'}),
ee.Feature(null, {foo: 1, label: 'b'}),
ee.Feature(null, {foo: 1, label: 'c'}),
ee.Feature(null, {foo: 2, label: 'd'}), ]);
//创建FeatureCollection_2.
var secondaryFeatures = ee.FeatureCollection([
ee.Feature(null, {bar: 1, label: 'e'}),
ee.Feature(null, {bar: 1, label: 'f'}),
ee.Feature(null, {bar: 2, label: 'g'}),
ee.Feature(null, {bar: 3, label: 'h'}), ]);
// 定义一个ee.Filter.equals,要求foo=bar.
var toyFilter = ee.Filter.equals({
leftField: 'foo',
rightField: 'bar'
});
// 定义一个innerJoin.包括左侧数据集的名称primary和右侧数据集的名称secondary
var innerJoin = ee.Join.inner('primary', 'secondary');
// 运用innerJoin.
// 打印结果. var toyJoin = innerJoin.apply(primaryFeatures, secondaryFeatures, toyFilter);

print('Inner join toy example:', toyJoin);

【GEE笔记6】数据连接Join_数据集_03

图中,有​​5个Feature​​​满足要求,编号为​​01234​​(编号是从0开始的,0就是第1个,4就是第5个)。

在编号为0的元素(element)中,也就是​​Feature 1_0​​​ ,左侧​​primary​​​的数据为​​primaryFeatures​​​里面的第2个,编号为1,也就是​​Feature 1 ---> ee.Feature(null, {foo: 1, label: 'b'})​​​,因为条件是​​foo eq bar​​​, 所以满足这个条件的右侧数据是​​ee.Feature(null, {bar: 1, label: 'e'})​​​,也就是第1个,编号为0,所以是​​Feature 0​​。

因此,第一个满足要求的数据就是​​Feature 1_0​​(左边第2个=右边第1个)

  • 案例2
    将相同时间段内的2个数据集连接成一个数据集合
// 定义时间filter.
var dateFilter = ee.Filter.date('2014-01-01', '2014-02-01');
// 引入 MODIS 图像(EVI产品).
var mcd43a4 = ee.ImageCollection('MODIS/MCD43A4_006_EVI')
.filter(dateFilter);
// 引入 MODIS 图像(Quality产品).
var mcd43a2 = ee.ImageCollection('MODIS/006/MCD43A2')
.filter(dateFilter);
// 定义Inner Join.
var innerJoin = ee.Join.inner();
// 定义ee.Filter.equals,通过“系统时间”联系两种产品.
var filterTimeEq = ee.Filter.equals({
leftField: 'system:time_start',
rightField: 'system:time_start'
});
// 运用Inner Join.
var innerJoinedMODIS = innerJoin.apply(mcd43a4, mcd43a2, filterTimeEq);
// 显示结果,结果为FeatureCollection.
print('Inner join output:', innerJoinedMODIS);
// 利用map命令将两种产品整合.
var joinedMODIS = innerJoinedMODIS.map(function(feature) {
return ee.Image.cat(feature.get('primary'), feature.get('secondary'));
});
// 打印结果.
print('Inner join, merged bands:', joinedMODIS);

【GEE笔记6】数据连接Join_云计算_04


​primary​​​数据有​​1个band(element)​​​,​​secondary​​​数据有​​19个bands(elements)​​​(如上图所示)整合后的数据集有​​20个bands(elements)​​(如下图所示)

【GEE笔记6】数据连接Join_GEE_05

3. 对符合要求的数据集以属性形式添加左侧数据集内

用于确定符合要求的右侧数据集,结果标记在左侧新增属性字段内

ee.Join.saveAll()
  • 代码详解
var filter_1 = ee.Filter.maxDifference(
{
difference: times,
leftField: 'system:time_start',
rightField: 'system:time_start'
});

var saveAllJoin = ee.Join.saveAll(
{
matchesKey: 属性名称,
ordering: 'system:time_start', //排序字段
ascending:true //升序
});

'对saveAllJoin应用筛选器'
var saveAll_Join_Images = saveAllJoin.apply(数据集1, 数据集2, filter_1);
print(saveAll_Join_Images);
  • 案例
// 引入Landsat8和Sentinal数据,利用重庆市点进行地理筛选
var L8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
.filterBounds(ee.Geometry.Point(106.3737, 29.9262));
var Sentinel = ee.ImageCollection("COPERNICUS/S2")
.filterBounds(ee.Geometry.Point(106.3737, 29.9262));
// 筛选出2018年的图像
var L8_2018= L8.filterDate('2018-01-01','2018-12-31')
var ST_2018= Sentinel.filterDate('2018-01-01','2018-12-31')
// 定义1天的变量
var One_Day_Millis = 1*24*60*60*1000
// 通过maxDifference定义Sentinel图像获取前后一天内的图像
var L8_Within_Sentinel = ee.Filter.maxDifference({
difference: One_Day_Millis,
leftField: 'system:time_start',
rightField: 'system:time_start'
})
// 定义一个simpleJoin
var SaveALL_Join = ee.Join.saveAll({
matchesKey: 'Sentinel_Match', // 符合要求的时候形成的数据集的名称
ordering: 'system:time_start',
ascending: true
});
// 应用SimpleJoin.
var SaveAll_Join_Images = SaveALL_Join.apply(L8_2018, ST_2018, L8_Within_Sentinel);
// 打印结果.
print('SaveALL_Join: ', SaveAll_Join_Images);

【GEE笔记6】数据连接Join_javascript_06


【GEE笔记6】数据连接Join_javascript_07


新增的​​Sentinel_Match​​,把右侧的数据(sentinel)添加到左侧数据(landsat)中去(如上图所示)

确定最优数据集,返回在属性字段内,只保留最优图像

筛选符合条件的所有数据,通过差值选择最优的数据

ee.Join.saveBest()
  • 代码详解
var filter_1 = ee.Filter.maxDifference(
{
difference: times,
leftField: 'system:time_start',
rightField: 'system:time_start'
});

var saveBestJoin = ee.Join.saveBest(
{
matchesKey: 属性名称,
measureKey: 测量字段 //返回测量结果,例如时间差距毫秒 timeDiff
});

'对saveBestJoin应用筛选器'
var saveBest_Join_Images = saveBestJoin.apply(数据集1, 数据集2, filter_1);
print(saveBest_Join_Images);
  • 案例
// 加载Landsat8图像
var primary = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
.filterDate('2014-04-01', '2014-06-01')
.filterBounds(ee.Geometry.Point(-122.092, 37.42));
// 加载 GRIDMET 气象图像数据
var gridmet = ee.ImageCollection('IDAHO_EPSCOR/GRIDMET');
// 利用maxDifference定义两种产品的最大时间差为2天.
var maxDiffFilter = ee.Filter.maxDifference({
difference: 2 * 24 * 60 * 60 * 1000,
leftField: 'system:time_start',
rightField: 'system:time_start'
});
//定义SaveBest join.
var saveBestJoin = ee.Join.saveBest({
matchKey: 'bestImage',
measureKey: 'timeDiff'
});
// 应用SaveBest join.
var landsatMet = saveBestJoin.apply(primary, gridmet, maxDiffFilter);
// 打印结果.
print(landsatMet);

【GEE笔记6】数据连接Join_javascript_08


【GEE笔记6】数据连接Join_云计算_09

只保留右侧第一个符合要求数据影像

ee.Join.saveFirst()
  • 案例
// 加载Landsat8图像
var primary = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
.filterDate('2014-04-01', '2014-06-01')
.filterBounds(ee.Geometry.Point(-122.092, 37.42));
// 加载 GRIDMET 气象图像数据
var gridmet = ee.ImageCollection('IDAHO_EPSCOR/GRIDMET');
// 利用maxDifference定义两种产品的最大时间差为2天.
var maxDiffFilter = ee.Filter.maxDifference({
difference: 2 * 24 * 60 * 60 * 1000,
leftField: 'system:time_start',
rightField: 'system:time_start'
});
//定义SaveFirst join.
var saveFirstJoin = ee.Join.saveFirst({
matchKey: 'First_Image',
});
// 应用SaveFirstjoin.
var landsatMet = saveFirstJoin.apply(primary, gridmet, maxDiffFilter);
// 打印结果.
print(landsatMet);

【GEE笔记6】数据连接Join_GEE_10

【GEE笔记6】数据连接Join_云计算_11

  1. 空间连接(空间筛选器)

基于距离对数据集进行连接

ee.Filter.withinDistance()
  • 代码详解
var filter_1 = ee.Filter.withinDistance({
distance: 距离,
leftField: '.geo', //.geo特指空间属性
rightField: '.geo',
maxError: 10 //运行电脑最大缩放误差
});
  • 案例
// 引入Landsat-8图像并进行时间和地点筛选.
var primary = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
.filterDate('2014-04-01', '2014-06-01')
.filterBounds(ee.Geometry.Point(-122.09, 37.42));
// 引入FLUXNET 站点数据.
var fluxnet = ee.FeatureCollection('ft:1f85fvccyKSlaZJiAta8ojlXGhgf-LPPNmICG9kQ');
// 定义空间筛选:筛选100km以内数据.
var distFilter = ee.Filter.withinDistance({
distance: 100000,
leftField: '.geo', // .geo 特指空间属性
rightField: '.geo',
maxError: 10
});
// 定义SaveAll-Join.
var distSaveAll = ee.Join.saveAll({
matchesKey: 'points',
measureKey: 'distance'
});
// 应用SaveAll-Join.
var spatialJoined = distSaveAll.apply(primary, fluxnet, distFilter);
// 打印结果.
print(spatialJoined);

【GEE笔记6】数据连接Join_GEE_12


【GEE笔记6】数据连接Join_javascript_13

左侧数据集和右侧数据集都会被保存起来,左侧被保存为​​feature​​​,右侧被保存为​​geometry point​​。

基于几何位置进行连接

ee.Filter.intersects()
  • 代码详解
var filter_1 = ee.Filter.intersects({
leftField: '.geo', //.geo特指空间属性
rightField: '.geo',
maxError: 10 //运行电脑最大缩放误差
});
  • 案例
// 引入加州行政边界.
var cali = ee.FeatureCollection('ft:1fRY18cjsHzDgGiJiS2nnpUU3v9JPDc2HNaR7Xk8')
.filter(ee.Filter.eq('Name', 'California'));
// 引入Landsat卫星轨道数据.
var wrs = ee.FeatureCollection('ft:1_RZgjlcqixp-L9hyS6NYGqLaKOlnhSC35AB5M5Ll');
// 定义空间筛选:利用边界进行叠加筛选.
var spatialFilter = ee.Filter.intersects({
leftField: '.geo',
rightField: '.geo',
maxError: 10
});
// 定义SaveAll-Join.
var saveAllJoin = ee.Join.saveAll({
matchesKey: 'scenes',
});
//运用SaveAll-Join.
var intersectJoined = saveAllJoin.apply(cali, wrs, spatialFilter);
// 显示结果.
var intersected = ee.FeatureCollection(ee.List(intersectJoined.first().get('scenes')));
Map.centerObject(cali);
Map.addLayer(intersected, {}, 'WRS-2 polygons');
Map.addLayer(cali, {color: 'FF0000'}, 'California polygon');

【GEE笔记6】数据连接Join_GEE_14

参考资料:

​GEE(Google Earth Engine)学习——常用筛选器Filter操作​​​​第10节 GEE的参数类型 (Filter,Join)​

​Inner Joins​

【GEE笔记6】数据连接Join_GEE_15


标签:Join,ee,笔记,Filter,2018,GEE,var,数据
From: https://blog.51cto.com/u_15813863/5738329

相关文章

  • 【GEE笔记4】GEE的数据下载和上传(Google Drive和Google Assets)
    虽然GEE有很多在线数据,但我们在使用的过程中有很多场景需要用到自己独有的数据,比如shp数据、csv数据等。GEE中,有多个存储空间​​GoogleDrive​​​​https://drive.google......
  • 【GEE笔记3】发布APP(简易版)
    何为GEE发布APP就是GEE发布一些APP(应用)用官方的话说就是Dynamic,publiclyaccessibleuserinterfacesforEarthEngineanalyses(用于地球引擎分析的动态、可公开访问的......
  • 区间dp学习笔记
    区间DP惯用手段区间dp中比较明显的阶段一般就是要合并的字段的长度;先枚举要处理的长度,之后用短的序列求出长的即可;P3146248这题长得和P3147长得一模一样给定......
  • devops学习笔记-jenkins pipeline流水线发布
    jenkinspipeline介绍要实现CD,先要实现CI。CDPipeline就是一个代码文件,里面把你项目业务场景都通过Groovy代码和Pipeline语法实现,一个一个业务串联起来,全部实现自动化,从代......
  • SpringBoot实战派读书笔记---响应式编程
    1.什么是WebFlux?WebFlux不需要ServletAPI,在完全异步且无阻塞,并通过Reactor项目实现了ReactorStreams规范。WebFlux可以在资源有限的情况下提高系统的吞吐量和......
  • Java小白自学笔记——线程
    一、线程的相关概念1.程序:是为完成特定任务,用某种语言编写的一组指令的集合。简单地说:就是我们写的代码2.进程:(1)进程是指运行中的程序,启动了一个进程,操作系统就......
  • 小程序学习笔记
    微信小程序在小程序中 <view></view>标签替换 <div></div> , <imgagesrc=""mode="widthFix"></image>替换 <img> 。image标签中mode的含义为图片裁剪缩放的......
  • java学习笔记33
    面向对象(构造器详解)、无参构造packageoop2;​publicclassperson{  //一个类即使什么都不写,它也会存在一个方法  //显示的定义构造器  //无参构造(初始化......
  • PADS应用笔记:Layout输出Gerber让时阻焊桥过小或者消失处理方法
    问题在画好图纸出Gerber时,检查预览发现芯片焊盘间的阻焊桥不见了方法在出Gerber时,一般阻焊桥需要设置下是否缩放,如果阻焊桥预览跟自己想象的不一样,可以检查下把缩放......
  • PADS应用笔记:Layout时输出的Gerber让铜箔或者散热焊盘有阻焊层
    问题通过铜箔和焊盘关联的方法花了个PCB天线,但出Gerber时候看到这个天线是露铜的,这样会容易腐蚀影响性能,想盖上绿油要怎么操作方法在出Gerber时设置阻焊层设置,选择具有......