• PIE-engine 教程 ——基于PIE-engine的水体频率变化长时序遥感监测自动计算平台


    本次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

    代码:

    1. /**
    2. * @Name : 基于PIE-Engine的水体频率变化长时序遥感监测自动计算平台
    3. * @Time : 2021/06/30
    4. * @Author : 中国地质大学(武汉)水体频率小组
    5. * @Desc : -2基于水体频率的水体类别变化检测及面积对比
    6. * @Source : 航天宏图第四届 “航天宏图杯”PIE软件二次开发大赛云开发组二等奖获奖作品
    7. */
    8. //设定变量
    9. var layerKey = null;
    10. var roiKey = null;
    11. var selectStartYear = "2016"; //选择开始年份
    12. var selectEndYear = "2020"; //选择结束年份
    13. var selectLBp1 = "114.338";
    14. var selectLBp2 = "30.517";
    15. var selectRTp1 = "114.469";
    16. var selectRTp2 = "30.604"; //自定义感兴趣区域
    17. var selectway = "NDWI"; //选择方法
    18. //获取研究区域
    19. function getROI(x1, y1, x2, y2) {
    20. var s1 = parseFloat(x1);
    21. var s2 = parseFloat(y1);
    22. var p1 = parseFloat(x2);
    23. var p2 = parseFloat(y2);
    24. // 研究区
    25. var roi = pie.Geometry.Rectangle([
    26. [s1, s2],
    27. [p1, p2]
    28. ], null);
    29. Map.centerObject(roi, 10);
    30. Map.addLayer(roi, { color: "#ff0000", fillColor: "#00000000" }, "roi", true);
    31. return roi;
    32. }
    33. //计算NDWI
    34. function NDWI(image) {
    35. var ndwi = image.normalizedDifference(['B3', 'B5'])
    36. var label = ndwi.gt(0).rename("Label");
    37. return label;
    38. }
    39. //计算AWEI
    40. function AWEI(image) {
    41. var awei = image.select(["B2", "B3", "B5", "B6", "B7"]).expression(
    42. 'B2+2.5*B3-1.5*(B5+B6)-0.25*B7', {
    43. B2: image.select("B2"),
    44. B3: image.select("B3"),
    45. B5: image.select("B5"),
    46. B6: image.select("B6"),
    47. B7: image.select("B7"),
    48. }).rename('AWEI');
    49. return awei.gt(0);
    50. };
    51. //计算MNDWI
    52. function MNDWI(image) {
    53. var mndwi = image.normalizedDifference(['B3', 'B6']).gt(0).rename('mNDWI');
    54. return mndwi;
    55. }
    56. //训练样本波段范围0-5000,LC08/02/SR数据集范围0-50000,除以10处理
    57. function divide10(image) {
    58. return imgd10 = image.divide(10);
    59. }
    60. ///机器学习分类水体/
    61. //加载机器学习的样本点和预测波段以及随机森林
    62. function Machinelearning(images) {
    63. // 添加训练样本
    64. var TrainingPoints = pie.FeatureCollection('user/pieadmin/ALLALL');
    65. // 预测使用的波段
    66. var bands = ['B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'NDVI', 'mNDWI', 'AWEI'];
    67. // 分类标签
    68. var label = 'waterclass';
    69. // 随机森林
    70. var classifer = pie.Classifier.rTrees().train(TrainingPoints, label, bands);
    71. //水体指数的波段添加,然后分别然给影像都进行一次,
    72. function water_index(img) {
    73. var image = img.select(["B2", "B3", "B4", "B5", "B6", "B7"]);
    74. var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
    75. var mndwi = image.normalizedDifference(['B3', 'B6']).rename('mNDWI');
    76. var awei = image.select(["B2", "B3", "B5", "B6", "B7"]).expression(
    77. 'B2+2.5*B3-1.5*(B5+B6)-0.25*B7', {
    78. B2: image.select("B2"),
    79. B3: image.select("B3"),
    80. B5: image.select("B5"),
    81. B6: image.select("B6"),
    82. B7: image.select("B7"),
    83. }).rename('AWEI');
    84. return img.addBands(ndvi).addBands(mndwi).addBands(awei);
    85. }
    86. var image = images.map(water_index);
    87. var resultImage = image.map(function(image) {
    88. var Rfiamge = image.select(bands).classify(classifer);
    89. return Rfiamge;
    90. });
    91. return resultImage;
    92. }
    93. //去云
    94. function maskL8sr(image) {
    95. var qa = image.select('QA_PIXEL');
    96. var mask = qa.bitwiseAnd(1 << 3).eq(0)
    97. .and(qa.bitwiseAnd(1 << 4).eq(0))
    98. .and(qa.bitwiseAnd(1 << 5).eq(0));
    99. return image.updateMask(mask);
    100. }
    101. //计算有效像元,这里随便选择一个波段就行了,因为所有的波段都进行了掩膜了
    102. function validPixel(image) {
    103. return image.select('B2').gte(0);
    104. };
    105. // 计算水体频率
    106. function Frequency(images, roi, selectway) {
    107. var pixel_validNumber = images.map(validPixel).sum().clip(roi);
    108. switch (selectway) {
    109. case "NDWI":
    110. var water_validNumber = images.map(NDWI).sum().clip(roi);
    111. break;
    112. case "AWEI":
    113. var water_validNumber = images.map(AWEI).sum().clip(roi);
    114. break;
    115. case "MNDWI":
    116. var water_validNumber = images.map(MNDWI).sum().clip(roi);
    117. break;
    118. case "随机森林":
    119. var water_validNumber = Machinelearning(images.map(divide10)).sum().clip(roi);
    120. break;
    121. }
    122. var waterFrequency = water_validNumber.divide(pixel_validNumber).rename('frequency');
    123. //获得永久性水体
    124. var PermanentWater = waterFrequency.gte(0.75).rename("waterclass");
    125. //获得季节性水体
    126. var mask1 = waterFrequency.gte(0.25);
    127. var mask2 = waterFrequency.lt(0.75);
    128. var SensonalWater = pie.ImageCollection.fromImages([mask1, mask2]).sum().eq(2).rename('waterclass');
    129. //获得陆地小于0.25的水频率
    130. var Land = waterFrequency.lt(0.25).rename("waterclass");
    131. //0-1值影像乘积操作
    132. var PW = PermanentWater.multiply(4);
    133. var SW = SensonalWater.multiply(2);
    134. var LD = Land.multiply(1);
    135. //合成影像集
    136. var PSL = pie.ImageCollection.fromImages([PW, SW, LD]).sum().select('waterclass');
    137. return PSL;
    138. }
    139. //点击按钮所进行的
    140. function clickBtn() {
    141. var roi = getROI(selectLBp1, selectLBp2, selectRTp1, selectRTp2);
    142. //获取影像集并进行预处理
    143. var imageC1 = pie.ImageCollection('LC08/02/SR')
    144. .filterBounds(roi)
    145. .filterDate(selectStartYear + "-01-01", selectEndYear + "-12-31")
    146. .select(["B2", "B3", "B4", "B5", "B6", "B7", "QA_PIXEL"])
    147. .filter(pie.Filter.lt('cloud_cover', 30))
    148. .map(maskL8sr);
    149. var imageC2 = pie.ImageCollection('LC08/02/SR')
    150. .filterBounds(roi)
    151. .filterDate(selectEndYear + "-01-01", selectEndYear + "-12-31")
    152. .select(["B2", "B3", "B4", "B5", "B6", "B7", "QA_PIXEL"])
    153. .filter(pie.Filter.lt('cloud_cover', 30))
    154. .map(maskL8sr);
    155. //得到开始年份和结束年份的图像并相减得出变化图像
    156. var frequency1 = Frequency(imageC1, roi, selectway);
    157. var frequency2 = Frequency(imageC2, roi, selectway);
    158. var change = frequency2.subtract(frequency1).rename("change");
    159. //获得开始年份和结束年份的水体类别0-1值图
    160. var PWC1 = frequency1.eq(4);
    161. var SWC1 = frequency1.eq(2);
    162. var Land1 = frequency1.eq(1);
    163. var PWC2 = frequency2.eq(4);
    164. var SWC2 = frequency2.eq(2);
    165. var Land2 = frequency2.eq(1);
    166. //计算面积
    167. function countArea(image) {
    168. var areaImage = image.updateMask(image).pixelArea().multiply(image);
    169. var waterarea = areaImage.reduceRegion(pie.Reducer.sum(), roi, 300);
    170. var image_area = image.set("Area", waterarea.get("constant"));
    171. return image_area;
    172. };
    173. var WaterClassImgs1 = [];
    174. var PWarea1 = countArea(PWC1);
    175. WaterClassImgs1.push(PWarea1);
    176. var SWarea1 = countArea(SWC1);
    177. WaterClassImgs1.push(SWarea1);
    178. var Landarea1 = countArea(Land1);
    179. WaterClassImgs1.push(Landarea1);
    180. var PWarea2 = countArea(PWC2);
    181. WaterClassImgs1.push(PWarea2);
    182. var SWarea2 = countArea(SWC2);
    183. WaterClassImgs1.push(SWarea2);
    184. var Landarea2 = countArea(Land2);
    185. WaterClassImgs1.push(Landarea2);
    186. var class_area1 = pie.ImageCollection().fromImages(WaterClassImgs1).reduceColumns(pie.Reducer.toList(), ['Area']);
    187. print(class_area1);
    188. //生成直方图
    189. class_area1.getInfo(function(datas) {
    190. var y1 = [];
    191. var dataList = datas.list;
    192. var y1 = dataList.Area;
    193. y1 = y1.map(area => area / 1000000);
    194. var column_options = {
    195. title: '年尺度水体类别面积',
    196. legend: [selectStartYear, selectEndYear],
    197. xAxis: ['PermanentWater', 'SensonalWater', 'Land'],
    198. xAxisName: "类别 ",
    199. yAxisName: "平方公里",
    200. series: [
    201. [y1[0], y1[1], y1[2]],
    202. [y1[3], y1[4], y1[5]],
    203. ],
    204. chartType: "column",
    205. };
    206. ChartArray(column_options);
    207. });
    208. //变化图层显示样式
    209. var vischange = {
    210. opacity: 1,
    211. uniqueValue: '-3,-2,-1,0,1,2,3',
    212. palette: '0000FF,9400D3,00BFFF,FFFFFF,808000,FF0000,FF8C00'
    213. };
    214. Map.addLayer(change.select('change'), vischange, "Change", true);
    215. //图例
    216. var data = {
    217. title: "水体类别变化图例",
    218. colors: ["#0000FF", "#9400D3", "#00BFFF", "#FFFFFF", "#808000", "#FF0000", "#FF8C00"],
    219. labels: ["陆地→永久", "季节→永久", "陆地→季节", "不变", "季节→陆地", "永久→季节", "永久→陆地"],
    220. step: 1
    221. };
    222. var style = {
    223. right: "150px",
    224. bottom: "10px",
    225. height: "70px",
    226. width: "500px"
    227. };
    228. var legend = ui.Legend(data, style);
    229. Map.addUI(legend);
    230. }
    231. var label1 = ui.Label("基于PIE-engine的水体频率变化长时序遥感监测自动计算平台", { "font-size": "18px" });
    232. var label2 = ui.Label("二、区域水体类别变化及检测(年尺度):", { "font-size": "17px" });
    233. var label3 = ui.Label("请自定义用户感兴趣区,区域类型为矩形,输入坐标值:", { "font-size": "14px" });
    234. var label4 = ui.Label("请输入开始年份和结束年份(2014—2020任选两年):", { "font-size": "14px" });
    235. var label5 = ui.Label("请选择计算水体频率方法:", { "font-size": "14px" });
    236. var label6 = ui.Label("注:虽然随机森林的提取最好,但是运算量大,计算时间长,可能会报错,请用户合理选择", { "font-size": "10px" });
    237. var text1 = ui.Label("经度");
    238. var text2 = ui.Label("纬度");
    239. //选择研究区范围模块
    240. var textBoxLB1 = ui.TextBox({
    241. placeholder: "(经度,如114.338)",
    242. value: selectLBp1,
    243. onChange: function(value) {
    244. selectLBp1 = value;
    245. },
    246. disabled: false
    247. })
    248. var textBoxLB2 = ui.TextBox({
    249. placeholder: "(纬度,如30.517)",
    250. value: selectLBp2,
    251. onChange: function(value) {
    252. selectLBp2 = value;
    253. },
    254. disabled: false
    255. })
    256. var selectLBName = ui.Label("左下角点坐标:", { "font-size": "14px" });
    257. var selectRTName = ui.Label("右上角点坐标:", { "font-size": "14px" });
    258. var textBoxRT1 = ui.TextBox({
    259. placeholder: "(经度,如114.469)",
    260. value: selectRTp1,
    261. onChange: function(value) {
    262. selectRTp1 = value;
    263. },
    264. disabled: false
    265. })
    266. var textBoxRT2 = ui.TextBox({
    267. placeholder: "(纬度,如30.604)",
    268. value: selectRTp2,
    269. onChange: function(value) {
    270. selectRTp2 = value;
    271. },
    272. disabled: false
    273. })
    274. var selectPanel1 = ui.Panel({
    275. widgets: [text1, textBoxLB1, text2, textBoxLB2],
    276. layout: ui.Layout.flow("horizontal")
    277. });
    278. var selectPanel3 = ui.Panel({
    279. widgets: [text1, textBoxRT1, text2, textBoxRT2],
    280. layout: ui.Layout.flow("horizontal")
    281. });
    282. //选择时间模块
    283. var textBox2 = ui.TextBox({
    284. placeholder: "请输入开始年份(如2016)",
    285. value: selectStartYear,
    286. onChange: function(value) {
    287. selectStartYear = value;
    288. },
    289. disabled: false
    290. })
    291. var selectstartName = ui.Label("开始年份:", { "font-size": "14px" });
    292. var selectStartPanel = ui.Panel({
    293. widgets: [selectstartName, textBox2],
    294. layout: ui.Layout.flow("horizontal")
    295. });
    296. var textBox3 = ui.TextBox({
    297. placeholder: "请输入结束年份(如2020)",
    298. value: selectEndYear,
    299. onChange: function(value) {
    300. selectEndYear = value;
    301. },
    302. disabled: false
    303. })
    304. var selectendName = ui.Label("结束年份:", { "font-size": "14px" });
    305. var selectEndPanel = ui.Panel({
    306. widgets: [selectendName, textBox3],
    307. layout: ui.Layout.flow("horizontal")
    308. });
    309. //选择方法模块
    310. var select1 = ui.Select({
    311. items: ['AWEI', 'NDWI', "MNDWI", "随机森林"],
    312. placeholder: "请选择",
    313. value: selectway,
    314. multiple: false,
    315. onChange: function(value) {
    316. selectway = value;
    317. }
    318. })
    319. var selectName = ui.Label("选择方法:", { "font-size": "14px" });
    320. var selectPanel2 = ui.Panel({
    321. widgets: [selectName, select1],
    322. layout: ui.Layout.flow("horizontal")
    323. });
    324. //按钮
    325. var btn = ui.Button({
    326. label: "开始",
    327. type: "success",
    328. onClick: clickBtn,
    329. style: { left: "150px" }
    330. });
    331. //界面
    332. var panel = ui.Panel({
    333. widgets: [
    334. label1, label2, label3,
    335. selectLBName,
    336. selectPanel1,
    337. selectRTName,
    338. selectPanel3,
    339. label4,
    340. selectStartPanel,
    341. selectEndPanel,
    342. label5,
    343. selectPanel2,
    344. label6,
    345. btn
    346. ],
    347. style: {
    348. width: "350px",
    349. backgroundColor: "#fff"
    350. }
    351. });
    352. ui.root.add(panel);

     这个程序暂时无法执行的原因?服务繁忙,请稍后再试。

  • 相关阅读:
    ElasticSearch在windows环境启动
    【MySQL系列】 MySQL表的增删改查(进阶)
    Packet Tracer - 配置 IPv6 的 EIGRP 基本设置
    uniapp不同平台获取文件内容以及base64编码特征
    Spring Cloud Alibaba【认识分布式事物、分布式事务产生的场景、什么是两阶段提交、XA方案、Seata方案、业务说明、下载启动Seata服务】(十)
    Java刷题面试系列习题(五)
    基于单片机的智能家居安防系统设计
    springboot集成mysql、mybatis-plus、shardingsphere-jdbc实现水平分表
    数据结构之二叉查找树Java泛型版
    Linux Commands Interview questions
  • 原文地址:https://blog.csdn.net/qq_31988139/article/details/127060156