GEE学习笔记 三十八:寻找失踪的马航

日期:

2018.9.4日晚,看到一篇新闻报道讲的是英国的一位专家在东南亚热带雨林中找到了失踪的马航MH340。

下面是在Google地图中的截图,确实有一架飞机

 

9.9日时候长光发布消息是调用高分辨率卫星查找没有飞机,确定那是一架飞行中的飞机。

 


整个时间长达5天,高分辨率的商业卫星调动虽然可以清楚了解到现场情况,但是这个中间调动卫星、处理数据时间却是非常久,而且普通人或者是普通公司都无法参与的。

 

GEE平台上存在很多免费的影像数据,而且历史数据非常齐全,那么使用免费卫星数据是否可以达到查找的目的呢?

 

1、landsat-8卫星,多光谱分辨率是30米,重访周期16天。

2、sentinel-2卫星,多光谱分辨率是10米,重访周期10天。

 

考虑到飞机长度大约是60-70米,那么landsat-8卫星不太合适,sentinel-2卫星比较合适,而且在GEE上sentinel-2的数据是从2015年10月开始有的,所以也适合查找历史的状况。

 

相关代码如下,其中涉及到的功能点,如何方便查询一个历史影像集合、导出视频数据到Google Drive中、影像添加到地图上、GEE的UI设计(按钮等)等功能。

 

var s2 = ee.ImageCollection("COPERNICUS/S2"), 
  point = /* color: #98ff00 */ee.Geometry.Point([104.1518138888889, 12.089097222222222]); 


/**
* search MH370
* 2014年3月8日凌晨,马航MH370航班从吉隆坡飞往北京。
* */
var startDate = "2014-3-8";
var endDate = "2018-10-1";
var region = /* color: #d63000 */ee.Geometry.Polygon(
        [[[104.14991488490637, 12.087570791362724],
          [104.15350904498632, 12.087486863640155],
          [104.15340712104376, 12.090791497822375],
          [104.14986124072607, 12.09080198865953]]]);
var roi = /* color: #0b4a8b */ee.Geometry.Polygon(
        [[[104.15145447288091, 12.089309662940087],
          [104.15146520171697, 12.088890026791695],
          [104.15218403373296, 12.088884781335663],
          [104.15218403373296, 12.089325399282842]]]);
Map.centerObject(point, 16);
Map.setOptions("SATELLITE");
Map.style().set('cursor', 'crosshair');
var empty = ee.Image().toByte();
var bounds = empty.paint({
  featureCollection:region,
  color:0,
  width:1
});
Map.addLayer(ee.Image());
Map.addLayer(bounds, {palette: "0000ff"}, "searchRegion");


var empty = ee.Image().toByte();
var bounds = empty.paint({
  featureCollection:roi,
  color:0,
  width:1
});
Map.addLayer(bounds, {palette: "ff0000"}, "airplane");


var rmcloud = function(image) {
  var quality = image.select("QA60").unmask();
  return image.updateMask(quality.eq(0));
};


var s2Col = s2.filterDate(startDate, endDate)
              .filterBounds(region)
              .map(rmcloud)
              .map(function(img) {
                var time_start = img.get("system:time_start");
                img = img.unitScale(0, 10000);
                img = img.clip(region);
                img = img.addBands(img.normalizedDifference(["B8", "B4"]).rename("NDVI"));
                img = img.set("system:time_start", time_start);
                return img;
              });


var exportCol = s2Col.map(function(img) {
                        return img.multiply(768).uint8();
                      });
//export video
Export.video.toDrive({
  collection: exportCol.select(["B4", "B3", "B2"]),
  description: "FindMH370",
  fileNamePrefix: "FindMH370",
  framesPerSecond: 10,
  region: region,
  scale:10,
  maxPixels: 1e13
});

print("find sentinel-2 image size is: ", s2Col.size());
print("find first image", s2Col.first());

var id_list = s2Col.reduceColumns(ee.Reducer.toList(), ['system:index'])
                   .get('list');
id_list.evaluate(function(ids) {
  print("sentinel-2 id list:", ids);
  var total = ids.length;
  var showTitle = ui.Label("", {fontWeight: 'bold'});
  var curIndex = 0;
  var bPlus = ui.Button("+", function() {
    curIndex += 1;
    if (curIndex >= total) {
      curIndex = 0;
    }
    showTitle.setValue(ids[curIndex]);
    showSelectRawImage(ids[curIndex]);
  });
  var bReduce = ui.Button("-", function() {
    curIndex -= 1;
    if (curIndex < 0) {
      curIndex = total - 1;
    }
    showTitle.setValue(ids[curIndex]);
    showSelectRawImage(ids[curIndex]);
  });
  showTitle.setValue(ids[curIndex]);
  showSelectRawImage(ids[curIndex]);
  var main = ui.Panel({
    widgets: [
      ui.Label('click "+" or "-" to move time window', {fontWeight: 'bold'}),
      bPlus, bReduce,
      ui.Label("select date: ", {fontWeight: 'bold'}),
      showTitle
    ],
    style: {width: '330px', padding: '2px'}
  });
  ui.root.insert(0, main);
 
});


function showSelectRawImage(key) {
  print("show select image id is: " + key);
  var image = ee.Image(s2Col.filter(ee.Filter.eq("system:index", key)).first());
  var rawLayer = ui.Map.Layer(image, {bands:["B4","B3","B2"], min:0, max:0.3}, key);
  Map.layers().set(0, rawLayer);
}

 

结果:

2015.10.22日的数据

 

2018.9.6日的数据

 

导出的视频上传不了,我上传到了百度网盘中,有需要可以看一下。
链接:https://pan.baidu.com/s/1RFP4Dk6G2Qdu6k01o4WlFA 密码: 05g8。

 

大家可以自己实验一下相关代码,点击左侧加号可以查看后一期影像,点击减号可以查看前一期影像。


可能有人会怀疑sentinel-2数据能否看到飞机,这里我找到了一景影像(国外某位闲着无聊找到的)

var geometry = ee.Geometry.Point([27.982423114776566, 43.264964799041586]);
var s2  = ee.ImageCollection('COPERNICUS/S2')
            .filter(ee.Filter.eq('PRODUCT_ID','S2A_MSIL1C_20170503T085601_N0205_R007_T35TNH_20170503T090332'));
Map.centerObject(geometry, 15);
var vis = {min:0, max:2500, gamma:1.4, bands: ['B4', 'B3', 'B2']};
Map.addLayer(s2, vis);

 

显示结果:

 

可以看到飞机还是非常清楚的,这是同一架飞机。为什么会显示成这样解释比较麻烦,以后有机会在介绍吧。