Google earth engine(GEE):基于MODIS的LST(地表温度数据)计算一定时间序列的城市热岛强度(UHI),并绘制直方图

        今天的内容是复制本人自己的实验报告,放心食用。最后放全部代码!如果不想看前面的东西就直接拉到后面!前面的代码懒得一个一个插代码段了,要复制的拉到最后去复制。本篇涵盖了之前写的好几篇博客的内容。

 

一.实验目的与数据

       计算粤港澳城市群2005,2015,和2022三年的城市热岛强度。

       使用的数据为MODIS_061_MYD11A2,即Aqua拍摄的地表温度数据,过境时间约为下午1:30和凌晨1:30。

二.实验流程图

三.实验步骤

  1. 研究区域斑块制作

  • 去除水体

在上一次不透水面提取的实验基础上,基于不透水面的斑块,计算这个斑块范围内的MNDWI(如图1),设置阈值为0,筛选出MNDWI<0的区域。代码如下,其中的and运算就做了一个不透水面和非水体的区域取交集的运算。

图 1 MNDWI计算结果

  1. // set thresold for built by MNDWI  
  2. var notwater5 = mndwi5.lt(mndwi_t).clipToCollection(roi);  
  3. notwater5=notwater5.mask(notwater5);  
  4. var notwater4 = mndwi4.lt(mndwi_t).clipToCollection(roi);  
  5. notwater4=notwater4.mask(notwater4);  
  6. var notwater3 = mndwi3.lt(mndwi_t).clipToCollection(roi);  
  7. notwater3=notwater3.mask(notwater3);  
  8.   
  9. // remove water  
  10. var city3=built3.and(notwater3);  
  11. var city4=built4.and(notwater4);  
  12. var city5=built5.and(notwater5);  
  • 不透水面转矢量

        转矢量使用的是reduceToVectors函数,同时给转好的矢量添加面积字段。因为转之后的向量一般有好几个,其中只有一个是最大的,基本涵盖了原始image的全部范围。所以之后根据面积筛选最大的斑块。因为大部分代码和上一次实验相同,就不展示了,最后是哟女export函数导出结果,命名为city,这个collection是3年的城市矢量,一年一个。详见我写的博客:http://t.csdn.cn/MeoJY。

  1. Export.table.toAsset({  
  2.   collection:ee.FeatureCollection(citys),   
  3.   description:"citys"})  

  • 计算矢量边界内的高程均值(包括城市和乡村)

         计算UHI需要剔除高程的影响。下面的代码只需要运行一次,就可以得到研究区域的DEM的均值。筛选出研究区域内高程在均值±100m范围内的部分。具体的reduceRegion求均值的解释可以看我的这一篇博客:http://t.csdn.cn/BwqqJ。

  1. var dem_city = DEM.select('elevation')  
  2. //---------- calculate the mean dem (Just run once!) ----------  
  3. var means = roi.map(function(roi){  
  4.   var rural_city = roi.buffer(5000,1000);  
  5.   var meanDict = dem_city.reduceRegion({  
  6.     reducer: ee.Reducer.mean(),  
  7.     geometry:rural_city.geometry(),   
  8.     scale: 1000,  
  9.     maxPixels: 1e9  
  10.   });  
  11.   var dem_mean = ee.Image.constant(meanDict.values());  
  12.   // find the region where elev is larger than the mean value of the total study area  
  13.   return dem_mean  // 2005:mean:21.54201520.85202221.53  
  14. })  
  • 排除掉高于高程100m以上的区域,做掩膜

        下面的lt()函数内部就是每一年研究区域均值+100m的结果,因为研究区域没有高程-100m的地方,所以就不做下限的约束。

  1. // find the city region with dem < 100+mean;  
  2. var city_less1 = dem_city.lt(121.54).clip(city1)  //image,"elevation", int  [0, 1]  
  3. var city_less2 = dem_city.lt(120.84).clip(city2)  
  4. var city_less3 = dem_city.lt(121.53).clip(city3)  
  5. var citys = ee.ImageCollection([city_less1,city_less2,city_less3]) 

  • 得到三年城市和乡村的矢量边界

这里直接选取了5km作为缓冲区半径,往外做5km的缓冲区。得到了乡村和城市的区域之和。为了得到纯乡村,用缓冲区.difference(城市)就可以得到去掉了城市区域的缓冲区,即乡村。同理,对乡村也做高程的约束。

  1. // -------------------------get each year's rural+city region--------------------------  
  2. var rural_citys = roi.map(function(roi){  
  3.   var rural_city = roi.buffer(5000,1000);  
  4.   return rural_city// Feature, with 8 properties  
  5. })  
  6.   
  7. // -------------------------get each year's rural region--------------------------  
  8. var rural1=ee.Feature(rural_citys.filter(ee.Filter.eq('ID',1)).first()).difference(city1);  
  9. var rural2=ee.Feature(rural_citys.filter(ee.Filter.eq('ID',2)).first()).difference(city2);  
  10. var rural3=ee.Feature(rural_citys.filter(ee.Filter.eq('ID',3)).first()).difference(city3);  
  11.   
  12. // -------------------------get each year's rural(dem region (It's Image!!!)--------------------------  
  13. var rural_less1 = dem_city.lt(121.54).clip(rural1);// image, with one band: "elevation", int  [0, 1]   
  14. var rural_less2 = dem_city.lt(120.84).clip(rural2);  
  15. var rural_less3 = dem_city.lt(121.53).clip(rural3);  
  16. var rurals = ee.ImageCollection([rural_less1,rural_less2,rural_less3])  

2. 制作时间序列影像集

1)生成等间隔的时间序列

         现在开始使用MODIS的LST数据,计算城市和乡村的一段时间序列中的日夜平均温度。这一大节“2.制作时间序列影像集”具体解释可以看我写的这一篇博客:http://t.csdn.cn/71SdO。5年总共有138景影像。

Google earth engine(GEE):基于MODIS的LST(地表温度数据)计算一定时间序列的城市热岛强度(UHI),并绘制直方图_第1张图片

图 2 得到一定时间序列的影像集

  1. var get_start_value=ee.List([2005,2015,2022]).map(function(year){  
  2.   var year = ee.Number(year).format("%04d").cat("-01-01");  
  3.   var Date_From_YMD = ee.Date(year).millis( );// 可以得到value, 不是用.value()哈!  
  4.   
  5.   return Date_From_YMD  
  6. })  
  7.   
  8. var date_sequence= ee.List(get_start_value).map(function(num){  
  9.   var start_day=ee.Number(num);  
  10.   var end_day=start_day.add(365*24*60*60*1000)  
  11.   var num_seq=ee.List.sequence(start_day,end_day,8*24*60*60*1000);  
  12.   var date_seq=num_seq.map(function(day_num){  
  13.     var date=ee.Date(day_num);  
  14.     return date  
  15.   })  
  16.   return date_seq  
  17. })  
  18. // print(date_sequence)  
  19.   
  20. var date_list=date_sequence.flatten() //reshape the sequence into one dimension 

2)根据时间序列和研究范围得到全部可能的影像

  1. var false_temperature_city = date_list.map(function(day){  
  2.   var day = ee.Date(day);  
  3.   //---------------------- Select the clip table!!!---------------  
  4.   var year = day.get( 'year' );  
  5.   var city_poly=ee.Algorithms.If(ee.Number(year).eq(2005),city1,(ee.Algorithms.If(ee.Number(year).eq(2015),city2,city3))); // city  
  6.   
  7.   //-----------------------Load image and clip it! ---------------  
  8.   var imgs = ee.ImageCollection("MODIS/061/MYD11A2")  
  9.     .filterBounds(table).filterDate(day,day.advance(8,"day"));//is imagecollection  
  10.   var size = ee.Number(imgs.size())  
  11.   var img = imgs.max();  
  12.   var final = img.set('system:time_start',day).set('bandnumber',size).set('city_or_rural',1).clip(ee.Feature(city_poly).geometry());  
  13.       
  14.   return final  
  15.   })  
  16. var false_temperature_rural = date_list.map(function(day){  
  17.   var day = ee.Date(day);  
  18.   //---------------------- Select the clip table!!!---------------  
  19.   var year = day.get( 'year' );  
  20.   var rural_poly=ee.Algorithms.If(ee.Number(year).eq(2005),rural1,(ee.Algorithms.If(ee.Number(year).eq(2015),rural2,rural3))); // rural  
  21.   //-----------------------Load image and clip it! ---------------  
  22.   var imgs = ee.ImageCollection("MODIS/061/MYD11A2")  
  23.     .filterBounds(table).filterDate(day,day.advance(8,"day"))  
  24.   var size = ee.Number(imgs.size())  
  25.   var img = imgs.max();  
  26.   var final = img.set('system:time_start',day).set('bandnumber',size).set('city_or_rural',2).clip(ee.Feature(rural_poly).geometry());     
  27.   return final  
  28.   }) 

3)筛选掉空的影像

  1. false_temperature_city=ee.ImageCollection(false_temperature_city).filterMetadata('bandnumber','greater_than',0)  
  2. false_temperature_rural=ee.ImageCollection(false_temperature_city).filterMetadata('bandnumber','greater_than',0)  

3.温度转摄氏度

1) 温度转摄氏度

MODIS的LST数据的温度是开尔文温度,需要转成摄氏度。代码里面的false_temperature 代指开尔文温度,而tru_temperature代指摄氏度。计算公式是:真实的地表温度 = MODIS中的地表温度*0.02-273.15;之后我们把每一天的早晚温度算出来,加在属性中。

  1. // ---------Control the quality and Convert temperature to Celsius.-------------------  
  2. var convert = function(img){  
  3.   var img = ee.Image(img)  
  4.   var date = img.get('system:time_start');   
  5.   //control the quality  
  6.   var lstDay = img.select('LST_Day_1km');  
  7.   var lstNight = img.select('LST_Night_1km');  
  8.   var qcDay = img.select('QC_Day');  
  9.   var qcNight = img.select('QC_Night');  
  10.     
  11.   // ---------calculate the Celsius------------------------------------------  
  12.   var day_wendu = lstDay.multiply(0.02).subtract(273.15);  
  13.   var night_wendu = lstNight.multiply(0.02).subtract(273.15);  
  14.   var final = qcDay.addBands(day_wendu).addBands(night_wendu).addBands(qcNight).set('system:time_start',date);  
  15.     
  16.   return final;  
  17. };  

2) 质量控制函数,求出高质量像元面积占整个研究范围的面积:

        对于数据需要做一下质量控制,筛选出受云的影响较小,且成像质量高的影像。下面的函数可以提取指定位置qc二进制码。

        注意这个函数只能接受QC波段为int类型,不可为double,如果前面从imagecollection筛选影像的时候用到了median或者mean,就会把影像的全部波段都变成double类型,包括QC波段。因此,前面为了将imagecollection中唯一的那一个影像转成image,要使用max或者min。

  1. var bitwiseExtract = function(input, fromBit, toBit) {  
  2.   var maskSize = ee.Number(1).add(toBit).subtract(fromBit);  
  3.   var mask = ee.Number(1).leftShift(maskSize).subtract(1);  
  4.   return input.rightShift(fromBit).bitwiseAnd(mask);  
  5. };  

        然后将城市和乡村的时间序列影像集都过一遍这个函数,得到QC波段指定比特位置的数字。根据MODIS_GEE的指南,我们需要提取下面的代码仅展示城市影像集的,乡村的同理。

Google earth engine(GEE):基于MODIS的LST(地表温度数据)计算一定时间序列的城市热岛强度(UHI),并绘制直方图_第2张图片

图 3 GEE关于MODIS数据各波段的说明

Google earth engine(GEE):基于MODIS的LST(地表温度数据)计算一定时间序列的城市热岛强度(UHI),并绘制直方图_第3张图片

图 4 QC_DAY波段的每一个bit的含义说明

// calculate the quality of each image
var qc_account_city = tru_city.map(function(img){
  var img_temp = ee.Image(img)
  var date = img_temp.get('system:time_start');
  var year = ee.Date(date).get( 'year' );
  var city_poly=ee.Algorithms.If(ee.Number(year).eq(2005),city1,(ee.Algorithms.If(ee.Number(year).eq(2015),city2,city3))); // city
  var poly_area = ee.Feature(city_poly).get('area');
  var newband = ee.Image.constant(1)
  img_temp = img_temp.addBands(newband)
  var area_image = img_temp.multiply(ee.Image.pixelArea())
  
  var qcDay = img.select('QC_Day');
  var qcNight = img.select('QC_Night');
  
  var qadayMask = bitwiseExtract(qcDay, 0, 1).lte(1)
  var dataQualityMask1 = bitwiseExtract(qcDay, 2, 3).eq(0)
  var qanightMask = bitwiseExtract(qcNight, 0, 1).lte(1)
  var dataQualityMask2 = bitwiseExtract(qcNight, 2, 3).eq(0)
  
  var mask1 = qadayMask.and(dataQualityMask1)
  var mask2 = qanightMask.and(dataQualityMask2)
  
  var area1 = area_image.updateMask(mask1).reduceRegion({
    reducer: ee.Reducer.sum(),
    geometry: ee.Feature(city_poly).geometry(),
    scale: 1000,
    maxPixels: 10e15,
  });
  //convert sqkm  //面积比例
  var area_sqkm1 = ee.Number(area1.get('constant')).divide(1e6)
  var day_account = area_sqkm1.divide(poly_area).multiply(100).round();

  var area2 = area_image.updateMask(mask2).reduceRegion({
    reducer: ee.Reducer.sum(),
    geometry: ee.Feature(city_poly).geometry(),
    scale: 1000,
    maxPixels: 10e15,
  });
  //convert sqkm  //面积比例
  var area_sqkm2 = ee.Number(area2.get('constant')).divide(1e6)
  var night_account = area_sqkm2.divide(poly_area).multiply(100).round();
  
  return img_temp.set('day_account',day_account).set('night_account',night_account);
})

3) 筛选高质量像元占比大于10%的影像

  1. var qc_tru_city = qc_account_city.filter(ee.Filter.gt('day_account',10)).filter(ee.Filter.gt('night_account',10));  
  2. var qc_tru_rural = qc_account_rural.filterMetadata('day_account','greater_than',10).filterMetadata('night_account','greater_than',10); 

4. 计算温度均值

1) 计算温度均值并添加到属性中。仅展示城市的,乡村同理。

  1. var city_means_wendu = qc_tru_city.map(function(img){  
  2.   var day = img.get('system:time_start');  
  3.   var year = ee.Date(day).get( 'year' );  
  4.   var city_poly=ee.Algorithms.If(ee.Number(year).eq(2005),city1,(ee.Algorithms.If(ee.Number(year).eq(2015),city2,city3))); // city  
  5.   var meanDict = img.reduceRegion({  
  6.     reducer: ee.Reducer.mean(),  
  7.     geometry:ee.Feature(city_poly).geometry(),   
  8.     scale: 1000,  
  9.     maxPixels: 1e9  
  10.   });  
  11.   var mean_day = meanDict.values().get(0);  
  12.   var mean_night = meanDict.values().get(1);    
  13.   var mean = img.set('mean_day',mean_day).set('mean_night',mean_night);  
  14.     
  15.   // var mean = img.set('mean_day',meanDict.values());  
  16.   return mean   
  17. }) 

2) 匹配同一时刻的乡村和城市计算结果,求UHI

        将城市和乡村的每期影像的平均温度求出后,需要匹配同一拍摄时间的城市和乡村的影像。这里用到了join,它有点像是数据库的操作,没有改变原始数据,而是生成了一个新的collection,将两个数据关联了起来,这里是直接把两个数据同等级地存在了一起,用的函数是ee.Join.inner,如果用其他的函数join出来的结果是有包含关系的。

  1. //----------------- join the city and the rural imagecollection-----------------------------  
  2. var join_filter = ee.Filter.equals({  
  3.     // difference: One_Day_Millis,  
  4.     leftField: 'system:time_start',  
  5.     rightField: 'system:time_start'  
  6.   })  
  7.   
  8. var Inner_Join = ee.Join.inner('primary''secondary');// 定义一个invertJoin  
  9. var Inner_Join_Results = Inner_Join.apply(city_means_wendu, rural_means_wendu, join_filter);// 应用invertJoin  
  10. // print('Inner_Join_Results: ', Inner_Join_Results);  
  11.   
  12. var joined = Inner_Join_Results.map(function(feature) {  
  13.   var city = feature.get('primary');  
  14.   var rural = feature.get('secondary');  
  15.   var city_wendu_day = ee.Feature(city).get('mean_day');  
  16.   var city_wendu_night = ee.Feature(city).get('mean_night');  
  17.   var rural_wendu_day = ee.Feature(rural).get('mean_day');  
  18.   var rural_wendu_night = ee.Feature(rural).get('mean_night');  
  19.   var uhiday = ee.Number(city_wendu_day).subtract(ee.Number(rural_wendu_day));  
  20.   var uhinight = ee.Number(city_wendu_night).subtract(ee.Number(rural_wendu_night));    
  21.   var final = ee.Image.cat(feature.get('primary'), feature.get('secondary'))  
  22.     .set('uhiday',uhiday).set('uhinight',uhinight);  
  23.       
  24.   return final  
  25. })  

5. 作图

1) 直方图制作

        这里用的是ui.Chart.feature.byFeature来做图,参数分别为需要作图的数据,横坐标数据(属性名),纵坐标数据(属性名)。制作的是直方图。

  1. // --------------------出图 --------------------
  2. var data = ee.FeatureCollection(joined.map(function(img) {    
  3.   var day = img.get('system:time_start');  
  4.   var year = ee.Date(day).get( 'year' );  
  5.   return ee.Feature(null,{time:day,UHI_day:img.get('uhiday'),UHI_night:img.get('uhinight'),year:year})    
  6. }));    
  7.   
  8. var chart_day = ui.Chart.feature.byFeature(data.sort('time').filterMetadata('year','equals',2005),'time','UHI_day')    
  9.                       .setChartType('ColumnChart')    
  10.                       .setOptions({    
  11.                         title: '白天城市热岛强度',    
  12.                         hAxis: {title: 'Date'},    
  13.                         vAxis: {title: 'UHI'}    
  14.                       });   
  15.                         
  16. var chart_night = ui.Chart.feature.byFeature(data.sort('time').filterMetadata('year','equals',2005),'time','UHI_night')    
  17.                       .setChartType('ColumnChart')    
  18.                       .setOptions({    
  19.                         title: '夜间城市热岛强度',    
  20.                         hAxis: {title: 'Date'},    
  21.                         vAxis: {title: 'UHI'}    
  22.                       });   
  23.   
  24. print(chart_day);  
  25. print(chart_night); 

        效果如下图所示:

Google earth engine(GEE):基于MODIS的LST(地表温度数据)计算一定时间序列的城市热岛强度(UHI),并绘制直方图_第4张图片

       综合三年的结果,如下图所示:可以看出,白天的城市热岛强度普遍低于夜间。

        季节方面。虽然夏季的高质量影响较少,但可以看出白天城市热岛强度在夏季最强,从八月份之后逐渐减弱,八月后的热岛强度有非常线性的关系。2005和2015年春夏季的热岛强度随季节无明显变化,而2022年城市热岛强度随月份的递增有明显的上升趋势。而夜间热岛强度无规则的月度和季度变化。

Google earth engine(GEE):基于MODIS的LST(地表温度数据)计算一定时间序列的城市热岛强度(UHI),并绘制直方图_第5张图片

图 5 三年白天和晚上的城市热岛强度,(a)(b)为2005年,(c)(d)为2015年,(e)(f)为2022年

年际变化。从整体趋势来看,热岛强度逐年递增,且增速较为平稳。2015年有三年中的最大值和最小值,离散程度也最大,也是唯一的白天出现负的热岛强度的一年。

Google earth engine(GEE):基于MODIS的LST(地表温度数据)计算一定时间序列的城市热岛强度(UHI),并绘制直方图_第6张图片

        夜间热岛强度的平均值随着年份的递增呈波动趋势,但中位数和最大值略有上升。最小值依然出现在2015年,但最大值出现在了2022年。离散程度最大的目测仍是2015年。

Google earth engine(GEE):基于MODIS的LST(地表温度数据)计算一定时间序列的城市热岛强度(UHI),并绘制直方图_第7张图片

  【代码大放送!下面代码很长,谨慎点开】

// load the study area
var roi = ee.FeatureCollection(table);
Map.addLayer(roi, {}, 'roi',false);
Map.centerObject(roi,8);//Feature with MultiPolygon
var dem_city = DEM.select('elevation')
// //--------------------------- calculate the mean dem (Just run once!) ----------
// var means = roi.map(function(roi){
//   var rural_city = roi.buffer(5000,1000);
//   var meanDict = dem_city.reduceRegion({
//     reducer: ee.Reducer.mean(),
//     geometry:rural_city.geometry(), 
//     scale: 1000,
//     maxPixels: 1e9
//   });
//   var dem_mean = ee.Image.constant(meanDict.values());
//   // find the region where elev is larger than the mean value of the total study area
//   return dem_mean  // 2005:mean:21.54,2015:20.85,2022:21.53
// })
// -------------------------get each year's 【city】 region(feature)--------------------------
var city1=roi.filter(ee.Filter.eq('ID',1)).first(); // 
var city2=roi.filter(ee.Filter.eq('ID',2)).first();
var city3=roi.filter(ee.Filter.eq('ID',3)).first();

// find the city region with dem < 100+mean;
var city_less1 = dem_city.lt(121.54).clip(city1)  //image,"elevation", int ∈ [0, 1]
var city_less2 = dem_city.lt(120.84).clip(city2)
var city_less3 = dem_city.lt(121.53).clip(city3)
var citys = ee.ImageCollection([city_less1,city_less2,city_less3])
// -------------------------get each year's 【rural+city】 region--------------------------
var rural_citys = roi.map(function(roi){
  var rural_city = roi.buffer(5000,1000);
  return rural_city// Feature, with 8 properties
})

// -------------------------get each year's 【rural】 region--------------------------
var rural1=ee.Feature(rural_citys.filter(ee.Filter.eq('ID',1)).first()).difference(city1);
var rural2=ee.Feature(rural_citys.filter(ee.Filter.eq('ID',2)).first()).difference(city2);
var rural3=ee.Feature(rural_citys.filter(ee.Filter.eq('ID',3)).first()).difference(city3);

// -------------------------get each year's 【rural(demImage (3 bands)

// ---------Control the quality and Convert temperature to Celsius.-------------------
var convert = function(img){
  var img = ee.Image(img)
  var date = img.get('system:time_start'); 
  //control the quality
  var lstDay = img.select('LST_Day_1km');
  var lstNight = img.select('LST_Night_1km');
  var qcDay = img.select('QC_Day');
  var qcNight = img.select('QC_Night');
  
  // ---------calculate the Celsius------------------------------------------
  var day_wendu = lstDay.multiply(0.02).subtract(273.15);
  var night_wendu = lstNight.multiply(0.02).subtract(273.15);
  var final = qcDay.addBands(day_wendu).addBands(night_wendu).addBands(qcNight).set('system:time_start',date);
  
  return final;
};
  
var tru_city = false_temperature_city.map(convert);//ImageCollection (129 elements)->Image (4 bands),5 properties
var tru_rural = false_temperature_rural.map(convert);
// print('tru_city',tru_city)
// Map.addLayer(ee.Feature(city1))

// calculate the quality of each image
var qc_account_city = tru_city.map(function(img){
  var img_temp = ee.Image(img)
  var date = img_temp.get('system:time_start');
  var year = ee.Date(date).get( 'year' );
  var city_poly=ee.Algorithms.If(ee.Number(year).eq(2005),city1,(ee.Algorithms.If(ee.Number(year).eq(2015),city2,city3))); // city
  var poly_area = ee.Feature(city_poly).get('area');
  var newband = ee.Image.constant(1)
  img_temp = img_temp.addBands(newband)
  var area_image = img_temp.multiply(ee.Image.pixelArea())
  
  var qcDay = img.select('QC_Day');
  var qcNight = img.select('QC_Night');
  
  var qadayMask = bitwiseExtract(qcDay, 0, 1).lte(1)
  var dataQualityMask1 = bitwiseExtract(qcDay, 2, 3).eq(0)
  var qanightMask = bitwiseExtract(qcNight, 0, 1).lte(1)
  var dataQualityMask2 = bitwiseExtract(qcNight, 2, 3).eq(0)
  
  var mask1 = qadayMask.and(dataQualityMask1)
  var mask2 = qanightMask.and(dataQualityMask2)
  
  var area1 = area_image.updateMask(mask1).reduceRegion({
    reducer: ee.Reducer.sum(),
    geometry: ee.Feature(city_poly).geometry(),
    scale: 1000,
    maxPixels: 10e15,
  });
  //convert sqkm  //面积比例
  var area_sqkm1 = ee.Number(area1.get('constant')).divide(1e6)
  var day_account = area_sqkm1.divide(poly_area).multiply(100).round();

  var area2 = area_image.updateMask(mask2).reduceRegion({
    reducer: ee.Reducer.sum(),
    geometry: ee.Feature(city_poly).geometry(),
    scale: 1000,
    maxPixels: 10e15,
  });
  //convert sqkm  //面积比例
  var area_sqkm2 = ee.Number(area2.get('constant')).divide(1e6)
  var night_account = area_sqkm2.divide(poly_area).multiply(100).round();
  
  return img_temp.set('day_account',day_account).set('night_account',night_account);
})

var qc_account_rural = tru_rural.map(function(img){
  var img_temp = ee.Image(img)
  var date = img_temp.get('system:time_start');
  var year = ee.Date(date).get( 'year' );
  var rural_poly=ee.Algorithms.If(ee.Number(year).eq(2005),rural1,(ee.Algorithms.If(ee.Number(year).eq(2015),rural2,rural3))); // rural
  var poly_area = ee.Feature(rural_poly).get('area');
  var newband = ee.Image.constant(1)
  img_temp = img_temp.addBands(newband)
  var area_image = img_temp.multiply(ee.Image.pixelArea())
  
  var qcDay = img.select('QC_Day');
  var qcNight = img.select('QC_Night');
  
  var qadayMask = bitwiseExtract(qcDay, 0, 1).lte(1)
  var dataQualityMask1 = bitwiseExtract(qcDay, 2, 3).eq(0)
  var qanightMask = bitwiseExtract(qcNight, 0, 1).lte(1)
  var dataQualityMask2 = bitwiseExtract(qcNight, 2, 3).eq(0)
  
  var mask1 = qadayMask.and(dataQualityMask1)
  var mask2 = qanightMask.and(dataQualityMask2)
  
  var area1 = area_image.updateMask(mask1).reduceRegion({
    reducer: ee.Reducer.sum(),
    geometry: ee.Feature(rural_poly).geometry(),
    scale: 1000,
    maxPixels: 10e15,
  });
  var area_sqkm1 = ee.Number(area1.get('constant')).divide(1e6)
  var day_account = area_sqkm1.divide(poly_area).multiply(100).round();
  
  var area2 = area_image.updateMask(mask2).reduceRegion({
    reducer: ee.Reducer.sum(),
    geometry: ee.Feature(rural_poly).geometry(),
    scale: 1000,
    maxPixels: 10e15,
  });
  var area_sqkm2 = ee.Number(area2.get('constant')).divide(1e6)
  var night_account = area_sqkm2.divide(poly_area).multiply(100).round();
  
  return img_temp.set('day_account',day_account).set('night_account',night_account);
})

var qc_tru_city = qc_account_city.filter(ee.Filter.gt('day_account',10)).filter(ee.Filter.gt('night_account',10));
var qc_tru_rural = qc_account_rural.filterMetadata('day_account','greater_than',10).filterMetadata('night_account','greater_than',10);
// print('qc_tru_city',qc_tru_city)
// print('qc_tru_rural',qc_tru_rural)

var city_means_wendu = qc_tru_city.map(function(img){
  var day = img.get('system:time_start');
  var year = ee.Date(day).get( 'year' );
  var city_poly=ee.Algorithms.If(ee.Number(year).eq(2005),city1,(ee.Algorithms.If(ee.Number(year).eq(2015),city2,city3))); // city
  var meanDict = img.reduceRegion({
    reducer: ee.Reducer.mean(),
    geometry:ee.Feature(city_poly).geometry(), 
    scale: 1000,
    maxPixels: 1e9
  });
  var mean_day = meanDict.values().get(0);
  var mean_night = meanDict.values().get(1);  
  var mean = img.set('mean_day',mean_day).set('mean_night',mean_night);
  
  // var mean = img.set('mean_day',meanDict.values());
  return mean 
})
// print(city_means_wendu)
var rural_means_wendu = qc_tru_rural.map(function(img){
  var day = img.get('system:time_start');
  var year = ee.Date(day).get( 'year' );
  var rural_poly=ee.Algorithms.If(ee.Number(year).eq(2005),rural1,(ee.Algorithms.If(ee.Number(year).eq(2015),rural2,rural3))); // city
  var meanDict = img.reduceRegion({
    reducer: ee.Reducer.mean(),
    geometry:ee.Feature(rural_poly).geometry(), 
    scale: 1000,
    maxPixels: 1e9
  });
  var mean_day = meanDict.values().get(0);
  var mean_night = meanDict.values().get(1);  
  var mean = img.set('mean_day',mean_day).set('mean_night',mean_night);
  return mean
})
// Map.addLayer(city_means_wendu.first().select('LST_Day_1km'), {min: 10, max: 30, palette: ['green','yellow', 'red']},'city_Day');
// Map.addLayer(city_means_wendu.first().select('LST_Night_1km'), {min: 10, max: 30, palette: ['green','yellow', 'red']},'city_Night');

// Map.addLayer(rural_means_wendu.first().select('LST_Day_1km'), {min: 10, max: 30, palette: ['green','yellow', 'red']},'rural_Day');
// Map.addLayer(rural_means_wendu.first().select('LST_Night_1km'), {min: 10, max: 30, palette: ['green','yellow', 'red']},'rural_Night');

// print('city_means_wendu',city_means_wendu)
// print('rural_means_wendu',rural_means_wendu)

//----------------- join the city and the rural imagecollection-----------------------------
var join_filter = ee.Filter.equals({
    // difference: One_Day_Millis,
    leftField: 'system:time_start',
    rightField: 'system:time_start'
  })

var Inner_Join = ee.Join.inner('primary', 'secondary');// 定义一个invertJoin
var Inner_Join_Results = Inner_Join.apply(city_means_wendu, rural_means_wendu, join_filter);// 应用invertJoin
// print('Inner_Join_Results: ', Inner_Join_Results);

var joined = Inner_Join_Results.map(function(feature) {
  var city = feature.get('primary');
  var rural = feature.get('secondary');
  var city_wendu_day = ee.Feature(city).get('mean_day');
  var city_wendu_night = ee.Feature(city).get('mean_night');
  var rural_wendu_day = ee.Feature(rural).get('mean_day');
  var rural_wendu_night = ee.Feature(rural).get('mean_night');
  var uhiday = ee.Number(city_wendu_day).subtract(ee.Number(rural_wendu_day));
  var uhinight = ee.Number(city_wendu_night).subtract(ee.Number(rural_wendu_night));  
  var final = ee.Image.cat(feature.get('primary'), feature.get('secondary'))
    .set('uhiday',uhiday).set('uhinight',uhinight);
    
  return final
})
// print(joined)

// ------------------------------------------------------出图 -------------------------------------------  
var data = ee.FeatureCollection(joined.map(function(img) {  
  var day = img.get('system:time_start');
  var year = ee.Date(day).get( 'year' );
  return ee.Feature(null,{time:day,UHI_day:img.get('uhiday'),UHI_night:img.get('uhinight'),year:year})  
}));  

var chart_day = ui.Chart.feature.byFeature(data.sort('time').filterMetadata('year','equals',2005),'time','UHI_day')  
                      .setChartType('ColumnChart')  
                      .setOptions({  
                        title: '白天城市热岛强度',  
                        hAxis: {title: 'Date'},  
                        vAxis: {title: 'UHI'}  
                      }); 
                      
var chart_night = ui.Chart.feature.byFeature(data.sort('time').filterMetadata('year','equals',2005),'time','UHI_night')  
                      .setChartType('ColumnChart')  
                      .setOptions({  
                        title: '夜间城市热岛强度',  
                        hAxis: {title: 'Date'},  
                        vAxis: {title: 'UHI'}  
                      }); 

print(chart_day);
print(chart_night);

你可能感兴趣的:(GEE入门,遥感,数据库,云计算,数据挖掘,大数据)