本次app是一个水体变化频率的变化监测,这个UI界面的设计中首先是标题,然后就是区域水体变化及监测的范围和时间选择,以及我们所选择监测的指数,NDWI,ADWI,MNDWI,随机森林的结果。这里面有一个非常大的限制,虽然再APP中有注释,注:虽然随机森林的提取最好,但是运算量大,计算时间长,可能会报错,请用户合理选择,但是选择其它指数的计算依旧无法现象。这里的归一化植被指数的结果:
normalizedDifference(bandNames)
指定两个特定波段,计算(Band1-Band2)/(Band1+Band2)的值。
方法参数:
- image(Image)
Image实例。
- bandNames(List)
Image的波段名称列表,包含两个元素。
返回值:像素值类型为布尔值的Image对象。
ui.Panel(widgets,layout,style)
容器组件。
方法参数:
- ui(ui)
调用者:ui对象。
- widgets(List)
组件列表
- layout(Object)
容器布局
- style(Object)
组件样式
返回值:ui.Panel
ui.root.add(widget)
添加组件。
方法参数:
- ui(ui)
调用者:ui对象。
- widget(String)
UI组件实例。
返回值:ui.root
代码:
/** * @Name : 基于PIE-Engine的水体频率变化长时序遥感监测自动计算平台 * @Time : 2021/06/30 * @Author : 中国地质大学(武汉)水体频率小组 * @Desc : -2基于水体频率的水体类别变化检测及面积对比 * @Source : 航天宏图第四届 “航天宏图杯”PIE软件二次开发大赛云开发组二等奖获奖作品 */ //设定变量 var layerKey = null; var roiKey = null; var selectStartYear = "2016"; //选择开始年份 var selectEndYear = "2020"; //选择结束年份 var selectLBp1 = "114.338"; var selectLBp2 = "30.517"; var selectRTp1 = "114.469"; var selectRTp2 = "30.604"; //自定义感兴趣区域 var selectway = "NDWI"; //选择方法 //获取研究区域 function getROI(x1, y1, x2, y2) { var s1 = parseFloat(x1); var s2 = parseFloat(y1); var p1 = parseFloat(x2); var p2 = parseFloat(y2); // 研究区 var roi = pie.Geometry.Rectangle([ [s1, s2], [p1, p2] ], null); Map.centerObject(roi, 10); Map.addLayer(roi, { color: "#ff0000", fillColor: "#00000000" }, "roi", true); return roi; } //计算NDWI function NDWI(image) { var ndwi = image.normalizedDifference(['B3', 'B5']) var label = ndwi.gt(0).rename("Label"); return label; } //计算AWEI function AWEI(image) { var awei = image.select(["B2", "B3", "B5", "B6", "B7"]).expression( 'B2+2.5*B3-1.5*(B5+B6)-0.25*B7', { B2: image.select("B2"), B3: image.select("B3"), B5: image.select("B5"), B6: image.select("B6"), B7: image.select("B7"), }).rename('AWEI'); return awei.gt(0); }; //计算MNDWI function MNDWI(image) { var mndwi = image.normalizedDifference(['B3', 'B6']).gt(0).rename('mNDWI'); return mndwi; } //训练样本波段范围0-5000,LC08/02/SR数据集范围0-50000,除以10处理 function divide10(image) { return imgd10 = image.divide(10); } ///机器学习分类水体/ //加载机器学习的样本点和预测波段以及随机森林 function Machinelearning(images) { // 添加训练样本 var TrainingPoints = pie.FeatureCollection('user/pieadmin/ALLALL'); // 预测使用的波段 var bands = ['B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'NDVI', 'mNDWI', 'AWEI']; // 分类标签 var label = 'waterclass'; // 随机森林 var classifer = pie.Classifier.rTrees().train(TrainingPoints, label, bands); //水体指数的波段添加,然后分别然给影像都进行一次, function water_index(img) { var image = img.select(["B2", "B3", "B4", "B5", "B6", "B7"]); var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI'); var mndwi = image.normalizedDifference(['B3', 'B6']).rename('mNDWI'); var awei = image.select(["B2", "B3", "B5", "B6", "B7"]).expression( 'B2+2.5*B3-1.5*(B5+B6)-0.25*B7', { B2: image.select("B2"), B3: image.select("B3"), B5: image.select("B5"), B6: image.select("B6"), B7: image.select("B7"), }).rename('AWEI'); return img.addBands(ndvi).addBands(mndwi).addBands(awei); } var image = images.map(water_index); var resultImage = image.map(function(image) { var Rfiamge = image.select(bands).classify(classifer); return Rfiamge; }); return resultImage; } //去云 function maskL8sr(image) { var qa = image.select('QA_PIXEL'); var mask = qa.bitwiseAnd(1 << 3).eq(0) .and(qa.bitwiseAnd(1 << 4).eq(0)) .and(qa.bitwiseAnd(1 << 5).eq(0)); return image.updateMask(mask); } //计算有效像元,这里随便选择一个波段就行了,因为所有的波段都进行了掩膜了 function validPixel(image) { return image.select('B2').gte(0); }; // 计算水体频率 function Frequency(images, roi, selectway) { var pixel_validNumber = images.map(validPixel).sum().clip(roi); switch (selectway) { case "NDWI": var water_validNumber = images.map(NDWI).sum().clip(roi); break; case "AWEI": var water_validNumber = images.map(AWEI).sum().clip(roi); break; case "MNDWI": var water_validNumber = images.map(MNDWI).sum().clip(roi); break; case "随机森林": var water_validNumber = Machinelearning(images.map(divide10)).sum().clip(roi); break; } var waterFrequency = water_validNumber.divide(pixel_validNumber).rename('frequency'); //获得永久性水体 var PermanentWater = waterFrequency.gte(0.75).rename("waterclass"); //获得季节性水体 var mask1 = waterFrequency.gte(0.25); var mask2 = waterFrequency.lt(0.75); var SensonalWater = pie.ImageCollection.fromImages([mask1, mask2]).sum().eq(2).rename('waterclass'); //获得陆地小于0.25的水频率 var Land = waterFrequency.lt(0.25).rename("waterclass"); //0-1值影像乘积操作 var PW = PermanentWater.multiply(4); var SW = SensonalWater.multiply(2); var LD = Land.multiply(1); //合成影像集 var PSL = pie.ImageCollection.fromImages([PW, SW, LD]).sum().select('waterclass'); return PSL; } //点击按钮所进行的 function clickBtn() { var roi = getROI(selectLBp1, selectLBp2, selectRTp1, selectRTp2); //获取影像集并进行预处理 var imageC1 = pie.ImageCollection('LC08/02/SR') .filterBounds(roi) .filterDate(selectStartYear + "-01-01", selectEndYear + "-12-31") .select(["B2", "B3", "B4", "B5", "B6", "B7", "QA_PIXEL"]) .filter(pie.Filter.lt('cloud_cover', 30)) .map(maskL8sr); var imageC2 = pie.ImageCollection('LC08/02/SR') .filterBounds(roi) .filterDate(selectEndYear + "-01-01", selectEndYear + "-12-31") .select(["B2", "B3", "B4", "B5", "B6", "B7", "QA_PIXEL"]) .filter(pie.Filter.lt('cloud_cover', 30)) .map(maskL8sr); //得到开始年份和结束年份的图像并相减得出变化图像 var frequency1 = Frequency(imageC1, roi, selectway); var frequency2 = Frequency(imageC2, roi, selectway); var change = frequency2.subtract(frequency1).rename("change"); //获得开始年份和结束年份的水体类别0-1值图 var PWC1 = frequency1.eq(4); var SWC1 = frequency1.eq(2); var Land1 = frequency1.eq(1); var PWC2 = frequency2.eq(4); var SWC2 = frequency2.eq(2); var Land2 = frequency2.eq(1); //计算面积 function countArea(image) { var areaImage = image.updateMask(image).pixelArea().multiply(image); var waterarea = areaImage.reduceRegion(pie.Reducer.sum(), roi, 300); var image_area = image.set("Area", waterarea.get("constant")); return image_area; }; var WaterClassImgs1 = []; var PWarea1 = countArea(PWC1); WaterClassImgs1.push(PWarea1); var SWarea1 = countArea(SWC1); WaterClassImgs1.push(SWarea1); var Landarea1 = countArea(Land1); WaterClassImgs1.push(Landarea1); var PWarea2 = countArea(PWC2); WaterClassImgs1.push(PWarea2); var SWarea2 = countArea(SWC2); WaterClassImgs1.push(SWarea2); var Landarea2 = countArea(Land2); WaterClassImgs1.push(Landarea2); var class_area1 = pie.ImageCollection().fromImages(WaterClassImgs1).reduceColumns(pie.Reducer.toList(), ['Area']); print(class_area1); //生成直方图 class_area1.getInfo(function(datas) { var y1 = []; var dataList = datas.list; var y1 = dataList.Area; y1 = y1.map(area => area / 1000000); var column_options = { title: '年尺度水体类别面积', legend: [selectStartYear, selectEndYear], xAxis: ['PermanentWater', 'SensonalWater', 'Land'], xAxisName: "类别 ", yAxisName: "平方公里", series: [ [y1[0], y1[1], y1[2]], [y1[3], y1[4], y1[5]], ], chartType: "column", }; ChartArray(column_options); }); //变化图层显示样式 var vischange = { opacity: 1, uniqueValue: '-3,-2,-1,0,1,2,3', palette: '0000FF,9400D3,00BFFF,FFFFFF,808000,FF0000,FF8C00' }; Map.addLayer(change.select('change'), vischange, "Change", true); //图例 var data = { title: "水体类别变化图例", colors: ["#0000FF", "#9400D3", "#00BFFF", "#FFFFFF", "#808000", "#FF0000", "#FF8C00"], labels: ["陆地→永久", "季节→永久", "陆地→季节", "不变", "季节→陆地", "永久→季节", "永久→陆地"], step: 1 }; var style = { right: "150px", bottom: "10px", height: "70px", width: "500px" }; var legend = ui.Legend(data, style); Map.addUI(legend); } var label1 = ui.Label("基于PIE-engine的水体频率变化长时序遥感监测自动计算平台", { "font-size": "18px" }); var label2 = ui.Label("二、区域水体类别变化及检测(年尺度):", { "font-size": "17px" }); var label3 = ui.Label("请自定义用户感兴趣区,区域类型为矩形,输入坐标值:", { "font-size": "14px" }); var label4 = ui.Label("请输入开始年份和结束年份(2014—2020任选两年):", { "font-size": "14px" }); var label5 = ui.Label("请选择计算水体频率方法:", { "font-size": "14px" }); var label6 = ui.Label("注:虽然随机森林的提取最好,但是运算量大,计算时间长,可能会报错,请用户合理选择", { "font-size": "10px" }); var text1 = ui.Label("经度"); var text2 = ui.Label("纬度"); //选择研究区范围模块 var textBoxLB1 = ui.TextBox({ placeholder: "(经度,如114.338)", value: selectLBp1, onChange: function(value) { selectLBp1 = value; }, disabled: false }) var textBoxLB2 = ui.TextBox({ placeholder: "(纬度,如30.517)", value: selectLBp2, onChange: function(value) { selectLBp2 = value; }, disabled: false }) var selectLBName = ui.Label("左下角点坐标:", { "font-size": "14px" }); var selectRTName = ui.Label("右上角点坐标:", { "font-size": "14px" }); var textBoxRT1 = ui.TextBox({ placeholder: "(经度,如114.469)", value: selectRTp1, onChange: function(value) { selectRTp1 = value; }, disabled: false }) var textBoxRT2 = ui.TextBox({ placeholder: "(纬度,如30.604)", value: selectRTp2, onChange: function(value) { selectRTp2 = value; }, disabled: false }) var selectPanel1 = ui.Panel({ widgets: [text1, textBoxLB1, text2, textBoxLB2], layout: ui.Layout.flow("horizontal") }); var selectPanel3 = ui.Panel({ widgets: [text1, textBoxRT1, text2, textBoxRT2], layout: ui.Layout.flow("horizontal") }); //选择时间模块 var textBox2 = ui.TextBox({ placeholder: "请输入开始年份(如2016)", value: selectStartYear, onChange: function(value) { selectStartYear = value; }, disabled: false }) var selectstartName = ui.Label("开始年份:", { "font-size": "14px" }); var selectStartPanel = ui.Panel({ widgets: [selectstartName, textBox2], layout: ui.Layout.flow("horizontal") }); var textBox3 = ui.TextBox({ placeholder: "请输入结束年份(如2020)", value: selectEndYear, onChange: function(value) { selectEndYear = value; }, disabled: false }) var selectendName = ui.Label("结束年份:", { "font-size": "14px" }); var selectEndPanel = ui.Panel({ widgets: [selectendName, textBox3], layout: ui.Layout.flow("horizontal") }); //选择方法模块 var select1 = ui.Select({ items: ['AWEI', 'NDWI', "MNDWI", "随机森林"], placeholder: "请选择", value: selectway, multiple: false, onChange: function(value) { selectway = value; } }) var selectName = ui.Label("选择方法:", { "font-size": "14px" }); var selectPanel2 = ui.Panel({ widgets: [selectName, select1], layout: ui.Layout.flow("horizontal") }); //按钮 var btn = ui.Button({ label: "开始", type: "success", onClick: clickBtn, style: { left: "150px" } }); //界面 var panel = ui.Panel({ widgets: [ label1, label2, label3, selectLBName, selectPanel1, selectRTName, selectPanel3, label4, selectStartPanel, selectEndPanel, label5, selectPanel2, label6, btn ], style: { width: "350px", backgroundColor: "#fff" } }); ui.root.add(panel);
这个程序暂时无法执行的原因?服务繁忙,请稍后再试。