【GEE笔记6】数据连接Join

15 篇文章 17 订阅

连接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);

在这里插入图片描述

反选符合条件的

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);

在这里插入图片描述

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);

在这里插入图片描述

图中,有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);

在这里插入图片描述
primary数据有1个band(element)secondary数据有19个bands(elements)(如上图所示)

整合后的数据集有20个bands(elements)(如下图所示)
在这里插入图片描述

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);

在这里插入图片描述
在这里插入图片描述
新增的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);

在这里插入图片描述
在这里插入图片描述

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

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);

在这里插入图片描述

在这里插入图片描述

  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);

在这里插入图片描述
在这里插入图片描述

左侧数据集和右侧数据集都会被保存起来,左侧被保存为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(Google Earth Engine)学习——常用筛选器Filter操作
第10节 GEE的参数类型 (Filter,Join)
Inner Joins
在这里插入图片描述

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vigo*GIS_RS

来瓶可乐~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值