PIE-engine APP 教程 ——太湖生态环境智能监测系统

本次开发教程是基于太湖生态环境智能监测系统,这个我们首先预加载我们所选的研究区,这次研究区是在太湖研究区,首秀按需要转化为几何,预加载持续时间,颜色图层预设,波段(MODIS、Landsat的QA波段去云函数)去云效果,然后UI界面的设定,这个界面非常长,所以设定了很多label标签、复选框、按钮和textbox,当然每一个部分都在一个面板,最后就是程序的嵌套和各个部分的,本此APP主要分为三个部分:第一部分就是太湖湖泊的监测、第二部分是基于Landsat数据月季年监测、第三部分太湖周围生态监测,最后是其它功能监测,这里每一个部分其实所用到的数据基本上上是相互独立的,这样有利于减少云计算的过程,减少运算压力。每一个部分都可以拿出来单独的使用,每一个部分都是一个单独的APP。

代码:

/**
 * @Name    :   基于多源遥感的太湖生态环境智能监测系统
 * @Time    :   2020/7/21
 * @Author  :   中国矿业大学(北京)PIE小分队
 * @Version :   1.0
 * @E-mail  :   sun_yilin@yeah.net
 * @Source  :   航天宏图第四届 “航天宏图杯”PIE软件二次开发大赛云开发组一等奖获奖作品
 */
// 需要转换为geometry;
var lakes = pie.FeatureCollection("user/pieadmin/lakeDemo");
var XukouBay = lakes
    .filter(pie.Filter.eq("NAME", "XukouBay"))
    .first()
    .geometry();
var EastLake = lakes
    .filter(pie.Filter.eq("NAME", "EastLake"))
    .first()
    .geometry();
var ZhushanBay = lakes
    .filter(pie.Filter.eq("NAME", "ZhushanBay"))
    .first()
    .geometry();
var WestLake = lakes
    .filter(pie.Filter.eq("NAME", "WestLake"))
    .first()
    .geometry();
var SouthLake = lakes
    .filter(pie.Filter.eq("NAME", "SouthLake"))
    .first()
    .geometry();
var MeiliangBay = lakes
    .filter(pie.Filter.eq("NAME", "MeiliangBay"))
    .first()
    .geometry();
var GongBay = lakes.filter(pie.Filter.eq("NAME", "GongBay")).first().geometry();
var EntireLake = lakes
    .filter(pie.Filter.eq("NAME", "EntireLake"))
    .first()
    .geometry();
var CentralLake = lakes
    .filter(pie.Filter.eq("NAME", "CentralLake"))
    .first()
    .geometry();
var points = pie.FeatureCollection("user/pieadmin/lakeDemoPoints"); // 训练样本
var MOD11A2 = pie.ImageCollection("USGS/MOD11A2/006"); // 1km分辨率

Map.setCenter(120.22, 31.22, 10); // 太湖中心
var selectStartDate = "2020-08-01"; // 计算蓝藻水华初始时间
var selectEndDate = "2020-08-03";

var selectStartDate1 = "2016-05-01"; // 计算水域面积初始时间
var selectEndDate1 = "2020-09-30";

var selectStartDate2 = "2020-05-01"; // 影像显示初始时间
var selectEndDate2 = "2020-09-30";

var color1 = [
    "#040274",
    "#040281",
    "#0502a3",
    "#0502b8",
    "#0502ce",
    "#0502e6",
    "#0602ff",
    "#235cb1",
    "#307ef3",
    "#269db1",
    "#30c8e2",
    "#32d3ef",
    "#3be285",
    "#3ff38f",
    "#86e26f",
    "#3ae237",
    "#b5e22e",
    "#d6e21f",
    "#fff705",
    "#ffd611",
    "#ffb613",
    "#ff8b13",
    "#ff6e08",
    "#ff500d",
    "#ff0000",
    "#de0101",
    "#c21301",
    "#a71001",
    "#911003",
];

var color2 = [
    "#9AA5DF",
    "#0602ff",
    "#235cb1",
    "#307ef3",
    "#269db1",
    "#30c8e2",
    "#32d3ef",
    "#3be285",
    "#3ff38f",
    "#86e26f",
];

var color3 = [
    "#145999",
    "#1b76cc",
    "#1f86e6",
    "#26aaea",
    "#36b6eb",
    "#4dc0eb",
    "#60cfeb",
    "#77daef",
    "#b0dfef",
    "#d1e5ee",
    "#dce6f0",
    "#e1e7f2",
    "#dee6f1",
    "#43c370",
    "#44b772",
    "#52c88e",
    "#6fc993",
    "#7ecb97",
    "#acd2ad",
];

var color4 = [
    "#145999",
    "#1b76cc",
    "#1f86e6",
    "#26aaea",
    "#36b6eb",
    "#4dc0eb",
    "#60cfeb",
    "#77daef",
    "#b0dfef",
    "#d1e5ee",
    "#dce6f0",
    "#e1e7f2",
    "#dee6f1",
    "#43c370",
    "#44b772",
    "#52c88e",
    "#6fc993",
    "#7ecb97",
    "#acd2ad",
    "#d4c97a",
    "#d0bc59",
    "#d3b146",
    "#c78f3c",
    "#c3812d",
    "#c5762b",
    "#b95322",
    "#ae4621",
    "#ba6e78",
    "#bc8fa9",
    "#c7aac6",
    "#dbcdde",
    "#fffcff",
];

function generateVis(min, max, palette) {
    var vis = {
        min: min,
        max: max,
        palette: palette,
    };
    return vis;
}

function generateVisalg(min, max) {
    return generateVis(min, max, color1);
}

function generateVisalgOccu(min, max) {
    return generateVis(min, max, color2);
}

function addLegend(args) {
    var title = args.title || "";
    var labels = args.labels || [];
    var step = args.step || 1;
    var colors = args.colors || [];
    // 图例
    var data = {
        title: title,
        colors: colors,
        labels: labels,
        step: step,
    };
    var style = {
        right: "100px",
        bottom: "25px",
        height: "70px",
        width: "350px",
    };
    var legend = ui.Legend(data, style);
    Map.addUI(legend);
}

function addLegendToMap(args) {
    args["colors"] = color1;
    addLegend(args);
}

function addOccuLegendToMap(args) {
    args["colors"] = color2;
    addLegend(args);
}

function addDem1LegendToMap(args) {
    args["colors"] = color3;
    addLegend(args);
}

function addDem2LegendToMap(args) {
    args["colors"] = color4;
    addLegend(args);
}

function addClassLegendToMap(args) {
    var colors = ["#040274", "#269db1", "#3ae237", "#ff0000", "#911003"];
    args["colors"] = colors;
    addLegend(args);
}

var modisUtil = {
    maskClouds: function (image) {
        // 选择质量评估波段
        var QA = image.select("state_1km");
        // 1<<10表示二进制第10位,第10位表示有云
        var bitMask = 1 << 10;
        // 使得检测出含云像元置为0,进行掩膜去除含云
        return image
            .select([
                "sur_refl_b01",
                "sur_refl_b02",
                "sur_refl_b05",
                "sur_refl_b06",
                "sur_refl_b07",
            ])
            .updateMask(QA.bitwiseAnd(bitMask).eq(0));
    },
    getMOD09GA: function (startDate, endDate, roi) {
        var MOD09GA = pie.ImageCollection("USGS/MOD09GA/006"); // 500米分辨率
        var TerraGA = MOD09GA.filterDate(startDate, endDate) // 数据筛选
            .filterBounds(roi)
            .map(modisUtil.maskClouds);
        return TerraGA;
    },
    // 大气校正步骤1
    min567: function (image) {
        var b05 = image.select("sur_refl_b05").multiply(0.0001); // 841-876nm, NIR(859)
        var b06 = image.select("sur_refl_b06").multiply(0.0001); // 620-670nm, RED(645)
        var b07 = image.select("sur_refl_b07").multiply(0.0001); // 1230-1250nm, SWIR1(1240)
        var images = pie.ImageCollection().fromImages([b05, b06, b07]); // 重组影像
        var min = images.min().rename("min"); // 获取最小值影像
        return image.addBands(min);
    },

    // 大气校正步骤2
    // multiply 0.0001 is needed because the data is scaled by 10000
    jz: function (image) {
        var b01 = image.select("sur_refl_b01").multiply(0.0001);
        var b02 = image.select("sur_refl_b02").multiply(0.0001);
        var b05 = image.select("sur_refl_b05").multiply(0.0001); // 841-876nm, NIR(859)
        var min = image.select("min");
        var b011 = b01.subtract(min); // 均减去min波段
        var b021 = b02.subtract(min);
        var b051 = b05.subtract(min);
        return image.addBands(b011).addBands(b021).addBands(b051);
    },

    // 计算 FAI
    funFAI: function (image) {
        b02 = image.select("sur_refl_b02"); // 841-876nm, NIR(859)
        b01 = image.select("sur_refl_b01"); // 620-670nm, RED(645)
        b05 = image.select("sur_refl_b05"); // 1230-1250nm, SWIR1(1240)
        var temp = b01.add(b05.subtract(b01).multiply(0.359663865546)); // 构建近红外波段
        var Index = b02.subtract(temp).rename("FAI");
        return Index;
    },

    // 建立 FAI 阈值掩膜.
    mod_FAI: function (image) {
        var FAI_threshold = image.select("FAI").rename("FAI_threshold");
        FAI_threshold = FAI_threshold.updateMask(FAI_threshold.gte(-0.004));
        return FAI_threshold;
    },

    // 统计发生频率
    Binary: function (image) {
        var algae = image.select("FAI").gte(-0.004).rename("alage"); // 大于等于-0.004为1,小于则为0
        return image.addBands(algae);
    },

    //添加 IndexBands
    addIndexBands: function (image) {
        var FAI = modisUtil.funFAI(image);
        return image.addBands(FAI);
    },
};

var landsat8Util = {
    // landsat8去云处理
    removeCloud: function (image) {
        // 数据去云处理
        var qa = image.select("QA_PIXEL");
        var cloudMask = qa
            .bitwiseAnd(1 << 4)
            .eq(0)
            .and(qa.bitwiseAnd(1 << 3).eq(0));
        return image.updateMask(cloudMask);
    },

    scaleImage: function (image) {
        return image
            .select(["B2", "B3", "B4", "B5", "B6", "B7"])
            .multiply(0.0000275)
            .subtract(0.2);
    },

    //加载Landsat 8 SR
    alg: function (image) {
        var b4 = image.select("B4"); // red
        var b5 = image.select("B5"); // nir
        var b6 = image.select("B6"); // swir1

        // 计算ndvi
        var lswi = b5.subtract(b6).divide(b5.add(b6)).clip(TH_boundary);
        var fai = b5
            .subtract(b4.add(b6.subtract(b4)).multiply(0.219895287958))
            .clip(TH_boundary);

        var alg = fai
            .updateMask(fai.gte(0.05))
            .updateMask(lswi.gte(0.63))
            .rename("alg"); // 判定太湖蓝藻水华
        return image.addBands(alg); // 添加蓝藻波段
    },

    turbidity: function (image) {
        var b4 = image.select("B4");
        var b3 = image.select("B3");
        var tbd = b4
            .subtract(b3)
            .divide(b4.add(b3))
            .power(2)
            .multiply(3117.4)
            .add(b4.subtract(b3).divide(b4.add(b3)).power(2).multiply(1083.6))
            .add(106.17)
            .rename("turbidity");
        return image.addBands(tbd);
    },

    MD: function (image) {
        var b4 = image.select("B4");
        var b5 = image.select("B5");
        //计算蓝藻密度
        var md = b5
            .divide(b4)
            .power(2)
            .multiply(1352)
            .subtract(b5.divide(b4).multiply(159.08))
            .add(192.87)
            .rename("md");

        return image.addBands(md);
    },

    cha: function (image) {
        var b4 = image.select("B4");
        var b5 = image.select("B5");
        //计算叶绿素
        var cha = b5.multiply(100.49).divide(b4).subtract(15.776).rename("cha");
        return image.addBands(cha);
    },

    //ndvi
    ndvi: function (image) {
        var b4 = image.select("B4"); // red
        var b5 = image.select("B5"); // nir
        var ndvi = b5.subtract(b4).divide(b5.add(b4)).rename("ndvi");
        return image.addBands(ndvi);
    },

    //fvc
    fvc: function (image) {
        var b4 = image.select("B4"); // red
        var b5 = image.select("B5"); // nir
        var ndvi = b5.subtract(b4).divide(b5.add(b4)).rename("ndvi");
        //   var ndvi_per = ndvi.reduceRegion(pie.Reducer.percentile([2, 98]), roi, 1000).get("ndvi");
        //   var ndvi_min = pie.Number(pie.Dictionary(ndvi_per).get("p2"));
        //   var ndvi_max = pie.Number(pie.Dictionary(ndvi_per).get("p98"));
        var ndvi_min = ndvi.reduceRegion(pie.Reducer.min(), roi, 1000).get("ndvi");
        ndvi_min = pie.Number(ndvi_min);
        var ndvi_max = ndvi.reduceRegion(pie.Reducer.max(), roi, 1000).get("ndvi");
        ndvi_max = pie.Number(ndvi_max);
        var fvc = ndvi
            .subtract(ndvi_min)
            .divide(ndvi_max.subtract(ndvi_min))
            .rename("fvc");

        return image.addBands(fvc);
    },

    // wet
    wet: function (image) {
        var b2 = image.select("B2"); // blue
        var b3 = image.select("B3"); // green
        var b4 = image.select("B4"); // red
        var b5 = image.select("B5"); // nir
        var b6 = image.select("B6"); // swir1
        var b7 = image.select("B7"); // swir1
        var tem1 = b2.multiply(0.1511).add(b3.multiply(0.1973));
        var tem2 = b4.multiply(0.3283).add(b5.multiply(0.3407));
        var tem3 = b6.multiply(-0.7177).add(b7.multiply(-0.4559));
        var wet_oli = tem1.add(tem2).subtract(tem3).rename("wet");
        return image.addBands(wet_oli);
    },

    // ndbsi
    ndbsi: function (image) {
        var b2 = image.select("B2"); // blue
        var b3 = image.select("B3"); // green
        var b4 = image.select("B4"); // red
        var b5 = image.select("B5"); // nir
        var b6 = image.select("B6"); // swir1
        // var b7 = image.select("B7"); // swir1
        var tem1 = b6
            .divide(b6.add(b5))
            .multiply(2)
            .subtract(b5.divide(b6.add(b5)))
            .add(b3.divide(b3.add(b6)));
        var tem2 = b6
            .divide(b6.add(b5))
            .multiply(2)
            .add(b5.divide(b6.add(b5)))
            .add(b3.divide(b3.add(b6)));
        var ibi = tem1.divide(tem2);

        var tem3 = b6.multiply(1.0).add(b4).subtract(b5.add(b2));
        var tem4 = b6.multiply(1.0).add(b4).add(b5.add(b2));
        var si = tem3.divide(tem4);
        var ndbsi = ibi.add(si).divide(2).rename("ndbsi"); // get the ndbsi
        return image.addBands(ndbsi);
    },

    //ndbi
    ndbi: function (image) {
        var b6 = image.select("B6");
        var b5 = image.select("B5");
        var ndbi = b6.subtract(b5).divide(b6.add(b5)).rename("ndbi");
        return image.addBands(ndbi);
    },

    // evi
    evi: function (image) {
        var b2 = image.select("B2"); // blue
        var b4 = image.select("B4"); // red
        var b5 = image.select("B5"); // nir
        var evi = b5
            .subtract(b4)
            .multiply(2.5)
            .divide(b5.add(b4.multiply(6)).subtract(b2.multiply(7.5)).add(1))
            .rename("evi");
        return image.addBands(evi);
    },

    // mndwi
    mndwi: function (image) {
        var b6 = image.select("B6");
        var b3 = image.select("B3");
        var mndwi = b3.subtract(b6).divide(b3.add(b6)).rename("mndwi");
        return image.addBands(mndwi);
    },

    // rvi
    rvi: function (image) {
        var b3 = image.select("B3"); // green
        var b5 = image.select("B5"); // nir
        var rvi = b3.divide(b5).rename("rvi");
        return image.addBands(rvi);
    },

    // ndwi
    ndwi: function (image) {
        var b3 = image.select("B3"); // green
        var b5 = image.select("B5"); // nir
        var ndwi = b3.subtract(b5).divide(b3.add(b5)).rename("ndwi");
        return image.addBands(ndwi);
    },

    trans: function (image) {
        var b4 = image.select("B4"); // red
        var b5 = image.select("B5"); // nir
        //计算叶绿素
        //计算蓝藻密度
        var alg = pie
            .Image(-0.416)
            .subtract(b5.log().multiply(0.587))
            .subtract(b4.log().multiply(0.722));
        var band = alg.exp().rename("trans"); // 计算指数并裁剪区域
        return image.addBands(band); // 添加蓝藻波段
    },

    //加载Landsat 8 SR
    ss: function (image) {
        var b4 = image.select("B4"); // red
        var b2 = image.select("B2"); // nir
        //计算叶绿素
        //计算蓝藻密度
        var ss = b4.subtract(b2).divide(b4.add(b2)).rename("ss");
        return image.addBands(ss); // 添加蓝藻波段
    },

    mndwiCa: function (image) {
        var b4 = image.select("B4"); // red
        var b5 = image.select("B5"); // nir
        var b6 = image.select("B6"); // swir1
        var b2 = image.select("B2"); // blue
        var b3 = image.select("B3"); // green
        var mndwi = b3.subtract(b6).divide(b3.add(b6)).rename("mndwi");
        // var mask1 = mndwi.updateMask(mndwi.gt(ndvi).and(evi.lt(0.1))).rename('water');
        return image.addBands(mndwi);
    },

    getLandsat8: function (startDate, endDate, roi, cloud = 30) {
        var l8SR = pie.ImageCollection("LC08/02/SR");
        var l8Col = l8SR
            .filterDate(startDate, endDate)
            .filterBounds(roi)
            .filter(pie.Filter.lt("cloud_cover", cloud))
            .map(landsat8Util.removeCloud)
            .map(landsat8Util.scaleImage);
        return l8Col;
    },
};

function mergeMOD09GAData(startDate, endDate, roi, callback) {
    var TerraGA = modisUtil.getMOD09GA(startDate, endDate, roi);
    var dateList = TerraGA.reduceColumns(pie.Reducer.toList(), ["date"]);
    dateList.getInfo(function (list) {
        var dates = Array.from(new Set(list["list"]["date"]));
        dates.sort();
        callback(TerraGA, dates);
    });
}

function globalTVDI(startDate, endDate, roi) {
    // tvdi
    var images = pie
        .ImageCollection("BNU/GLOBAL_1KM_TVDI")
        .filterBounds(roi)
        .filterDate(startDate, endDate)
        .select("B1")
        .mean()
        .clip(roi);
    var tvdi = images.multiply(0.0001).rename("tvdi");
    return tvdi;
}

function getDateList(startDate, endDate) {
    var syear = parseInt(startDate.slice(0, 4)); // 获取起始日期前四位
    var sother = startDate.slice(4, 10); // 获取起始日期后6位
    var eyear = parseInt(endDate.slice(0, 4)); // 获取结束日期前四位
    var eother = endDate.slice(4, 10); // 获取结束日期后6位
    var dates = [];
    if (syear > eyear) {
        return dates;
    }
    for (var year = syear; year <= eyear; year++) {
        dates.push({
            start: year + sother,
            end: year + eother,
        });
    }
    return dates;
}

// UI界面
var panel = ui.Panel({
    style: {
        width: "400px"
    },
}); // set the panel
var style1 = {"font-size": "20px", color: "green", "font-weight": "bold"}; // set the format
var style2 = {"font-size": "16px", color: "black", "font-weight": "bold"}; // set the format
var label1 = ui.Label("基于多源遥感的太湖生态环境智能监测系统 V1.0", style1); // edit the content
var label2 = ui.Label("制作人: PIE小分队.", style2);
var label3 = ui.Label("E-mail: sun_yilin@yeah.net.", style2);
panel.add(label1).add(label2).add(label3); // add the ui panel

// 设置目录
// 第一节,太湖湖泊监测
var labelA = ui.Label("一、太湖湖泊监测", {
    "font-size": "20px",
    "font-weight": "bold",
    color: "red",
});
var labelA1 = ui.Label("1、基于MODIS数据逐日监测", {
    "font-size": "18px",
    "font-weight": "bold",
    color: "red",
});
panel.add(labelA).add(labelA1);
// 1 选择区域
var label4 = ui.Label("1) 请选择一个区域", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});

// 设置空的变量保存矢量.
var TH_boundary = [];
// Create a ui.Select widget for area selection.
var places = {
    EntireLake: EntireLake,
    CentralLake: CentralLake,
    EastLake: EastLake,
    SouthLake: SouthLake,
    WestLake: WestLake,
    GongBay: GongBay,
    MeiliangBay: MeiliangBay,
    ZhushanBay: ZhushanBay,
    XukouBay: XukouBay,
};

// 设置选择区域
var selectArea = ui.Select({
    items: Object.keys(places),
    placeholder: "Click on the select",
    value: null,
    multiple: false,
    onChange: function (key) {
        // 存储选择的矢量边界
        TH_boundary = places[key];
        return TH_boundary;
    },
});
panel.add(label4).add(selectArea);

// 显示研究区
function clickBtn() {
    Map.addLayer(
        TH_boundary, {color: "FF0000", fillColor: "00000000", width: 1},
        "roi"
    );
}

var btShow = ui.Button({
    label: "显示研究区",
    type: "success",
    onClick: clickBtn,
});
var btNotShow = ui.Button({
    label: "不显示研究区",
    type: "success",
});
var btnPanelShow = ui.Panel({
    widgets: [btShow, btNotShow],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(btnPanelShow);

// 2 选择时间
// 开始时间
var label5 = ui.Label("2) 请输入研究时间", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});

function inputSDatea(value) {
    selectStartDate = value;
}

var textBox1a = ui.DateSelect({
    type: "date",
    placeholder: "请输入数值",
    value: selectStartDate, //输入显示框显示数值
    onChange: inputSDatea,
    disabled: false,
});

var textboxName1a = ui.Label("开始时间:");
var textboxPanel1a = ui.Panel({
    widgets: [textboxName1a, textBox1a],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(label5).add(textboxPanel1a);

// 结束时间
function inputEDatea(value) {
    selectEndDate = value;
}

var textBox2a = ui.DateSelect({
    type: "date",
    placeholder: "请输入数值",
    value: selectEndDate, //输入显示框显示数值
    onChange: inputEDatea,
    disabled: false,
});

var textboxName2a = ui.Label("结束时间:");
var textboxPanel2a = ui.Panel({
    widgets: [textboxName2a, textBox2a],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(textboxPanel2a);

// 水华面积计算
var label6 = ui.Label("3) 逐日水华监测", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btArea = ui.Button({
    label: "计算每日水华面积",
    type: "success",
    onClick: function () {
        print("开始蓝藻水华面积计算");
        mergeMOD09GAData(
            selectStartDate,
            selectEndDate,
            TH_boundary,
            function (TerraGA, dates) {
                var count_images = [];
                for (var i = 0; i < dates.length; i++) {
                    var FAI_threshold = TerraGA.filter(pie.Filter.eq("date", dates[i]))
                        .map(modisUtil.min567)
                        .map(modisUtil.jz)
                        .map(modisUtil.addIndexBands)
                        .select("FAI")
                        .mosaic()
                        .clip(TH_boundary); // 镶嵌并裁剪

                    var areaPixel = FAI_threshold.gte(-0.004); // 统计方法2:生成二值影像
                    var countPixel = areaPixel.reduceRegion(
                        pie.Reducer.sum(),
                        TH_boundary,
                        500
                    ); // 计算像素数之和
                    //设置图层显示属性
                    var visalg = generateVisalg(-0.004, 0.25);
                    Map.addLayer(
                        FAI_threshold.updateMask(areaPixel),
                        visalg,
                        dates[i],
                        false
                    ); // 去云影像,绘制图层
                    count_images.push(countPixel); // 记录数量
                    print("日期:", dates[i]); // 输出日期
                    print("数量:", countPixel); // 打印结果
                }
                // Map.playLayersAnimation(dates, 0.5, 100);  // 动画演示
                // 显示图例
                addLegendToMap({
                    title: "FAI",
                    labels: ["-0.004", "0.25"],
                    step: 1,
                });
                // 通过判断设置图表属性
                if (TH_boundary == EntireLake) {
                    var line_a = {
                        title: "太湖水域蓝藻面积动态变化",
                        legend: ["蓝藻面积"],
                        xAxisName: "日期",
                        yAxisName: "蓝藻像元数量(500*500m)",
                        chartType: "line",
                        yMin: 0,
                        yMax: 25000, // 当显示为全部区域时,上限为25000
                        smooth: true,
                    };
                } else {
                    var line_a = {
                        title: "太湖水域蓝藻面积动态变化",
                        legend: ["蓝藻像元数量"],
                        xAxisName: "日期",
                        yAxisName: "蓝藻像元数量(500*500m)",
                        chartType: "line",
                        yMin: 0,
                        yMax: 2000, // 当显示为部分区域时,上限为2000
                        smooth: true,
                    };
                }
                // 显示折线图
                var countChart = ui.Chart.image(count_images, dates, line_a);
                print(countChart);
                print("结束蓝藻水华面积计算");
            }
        );
    },
});
panel.add(label6).add(btArea);

// 时间范围内蓝藻频率图
var label7 = ui.Label("4) 水华发生频率", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btOccurency = ui.Button({
    label: "计算频率影像",
    type: "success",
    onClick: function () {
        print("开始蓝藻频率计算");
        var TerraGA = modisUtil.getMOD09GA(
            selectStartDate,
            selectEndDate,
            TH_boundary
        );
        var BinarySum = TerraGA.map(modisUtil.min567)
            .map(modisUtil.jz)
            .map(modisUtil.addIndexBands)
            .map(modisUtil.Binary)
            .select("alage")
            .sum()
            .clip(TH_boundary); //对影像集中的像素求和
        //设置图层显示属性
        var visalgOccu = generateVisalgOccu(1, 10);
        Map.addLayer(BinarySum, visalgOccu, "Occurrence Frequency");

        //地图上显示图例组件
        addOccuLegendToMap({
            title: "蓝藻出现频率",
            labels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
            step: 1,
        });
        print("结束蓝藻频率计算");
    },
});
panel.add(label7).add(btOccurency);

// 蓝藻发生最早时间
function generateDateImageCollection(TerraGA, dates) {
    var images = [];
    for (var i = 0; i < dates.length; i++) {
        var image = TerraGA.filter(pie.Filter.eq("date", dates[i]))
            .mosaic()
            .clip(TH_boundary);
        image = modisUtil.funFAI(image);
        image = modisUtil.mod_FAI(image);
        var dateImage = image
            .where(image.gte(-0.004), i + 1)
            .rename("dateImage"); // 设置数据值
        images.push(dateImage);
    }
    var imageCollection = pie.ImageCollection.fromImages(images);
    return imageCollection;
}

var label71 = ui.Label("5) 水华发生起始时间", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btEarlyTime = ui.Button({
    label: "计算起始时间影像",
    type: "success",
    onClick: function () {
        print("开始计算蓝藻发生最早时间");
        mergeMOD09GAData(
            selectStartDate,
            selectEndDate,
            TH_boundary,
            function (TerraGA, dates) {
                var imageCollection = generateDateImageCollection(TerraGA, dates);
                var earlyImage = imageCollection.select("dateImage").min(); // 获得最小值天数影像
                //设置图层显示属性
                var visalgOccu = generateVisalgOccu(1, 10);
                Map.addLayer(earlyImage, visalgOccu, "earlyImage");

                // 显示图例
                addOccuLegendToMap({
                    title: "水华发生起始时间(天)",
                    labels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
                    step: 1,
                });
                print("结束计算蓝藻发生最早时间");
            }
        );
    },
});
panel.add(label71).add(btEarlyTime);

// 蓝藻发生的截止时间
var label72 = ui.Label("6) 水华发生结束时间", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btLatestTime = ui.Button({
    label: "计算结束时间影像",
    type: "success",
    onClick: function () {
        print("开始计算蓝藻消失时间");
        mergeMOD09GAData(
            selectStartDate,
            selectEndDate,
            TH_boundary,
            function (TerraGA, dates) {
                var imageCollection = generateDateImageCollection(TerraGA, dates);
                var latestImage = imageCollection.select("dateImage").max(); // 获得最小值天数影像
                //设置图层显示属性
                var visalgOccu = generateVisalgOccu(1, 10);
                Map.addLayer(latestImage, visalgOccu, "latestImage");

                // 显示图例
                addOccuLegendToMap({
                    title: "水华发生结束时间(天)",
                    labels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
                    step: 1,
                });
                print("结束计算蓝藻消失时间");
            }
        );
    },
});
panel.add(label72).add(btLatestTime);

// 蓝藻发生的持续时间
var label73 = ui.Label("7) 水华发生持续时间", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btDurationTime = ui.Button({
    label: "计算水华持续时间影像",
    type: "success",
    onClick: function () {
        print("开始计算蓝藻持续时间");
        mergeMOD09GAData(
            selectStartDate,
            selectEndDate,
            TH_boundary,
            function (TerraGA, dates) {
                var imageCollection = generateDateImageCollection(TerraGA, dates);
                var earlyImage = imageCollection.select("dateImage").min(); // 获得最小值天数影像
                var latesImage = imageCollection.select("dateImage").max(); // 获得最大值天数影像
                var durationImage = latesImage.subtract(earlyImage); // 获得蓝藻持续时间

                //设置图层显示属性
                var visalgOccu = generateVisalgOccu(1, 10);
                Map.addLayer(durationImage, visalgOccu, "durationImage");

                // 显示图例
                addOccuLegendToMap({
                    title: "水华发生持续时间(天)",
                    labels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
                    step: 1,
                });
                print("结束计算蓝藻持续时间");
            }
        );
    },
});
panel.add(label73).add(btDurationTime);

// 等级显示及直方图计算
var label74 = ui.Label("8) 蓝藻水华等级显示及统计", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btHIS = ui.Button({
    label: "显示水华等级",
    type: "success",
    onClick: function () {
        print("开始水华等级显示");
        mergeMOD09GAData(
            selectStartDate,
            selectEndDate,
            TH_boundary,
            function (TerraGA, dates) {
                var image = TerraGA.filter(pie.Filter.eq("date", dates[0]))
                    .map(modisUtil.addIndexBands)
                    .select("FAI")
                    .mosaic()
                    .clip(TH_boundary);

                print(dates[0] + "等级统计结果:");
                // Create a VCI level (Lv.2 - Lv.6) classification function.
                var VCIs = [
                    {name: "VCI_Lv1", min: -0.004, max: 0, palette: "#040274"},
                    {name: "VCI_Lv2", min: 0, max: 0.05, palette: "#269db1"},
                    {name: "VCI_Lv3", min: 0.05, max: 0.1, palette: "#3ae237"},
                    {name: "VCI_Lv4", min: 0.1, max: 0.15, palette: "#ff0000"},
                    {name: "VCI_Lv5", min: 0.15, max: null, palette: "#911003"},
                ];
                var count_images = []; // 保存数量

                print("统计结果输出:");
                for (var i = 0; i < VCIs.length; i++) {
                    var vci_image = image.rename(VCIs[i].name);
                    if (VCIs[i].min !== null) {
                        vci_image = vci_image.updateMask(vci_image.gte(VCIs[i].min));
                    }
                    if (VCIs[i].max !== null) {
                        vci_image = vci_image.updateMask(vci_image.lt(VCIs[i].max));
                    }
                    var vci_image_count = vci_image.reduceRegion(
                        pie.Reducer.count(),
                        TH_boundary,
                        500
                    );
                    print(vci_image_count);
                    count_images.push(vci_image_count);
                    Map.addLayer(vci_image, {palette: VCIs[i].palette}, VCIs[i].name);
                }

                // 显示图例
                addClassLegendToMap({
                    title: "VCI",
                    labels: ["VCI1", "VCI2", "VCI3", "VCI4", "VCI5"],
                    step: 1,
                });

                var labelui = ui.Label(dates[0] + "等级分类显示", {
                    "font-size": "22px",
                    "font-weight": "bold",
                    color: "black",
                }); //ui界面添加标题
                Map.addUI(labelui);

                // 绘制表格
                // 设置图表属性
                if (TH_boundary == EntireLake) {
                    var line_a = {
                        title: "太湖水域蓝藻等级面积统计",
                        legend: ["蓝藻面积"],
                        xAxisName: "等级",
                        yAxisName: "蓝藻像元数量(500*500m)",
                        chartType: "line",
                        yMin: 0,
                        yMax: 5000, // 当显示为全部区域时,上限为40000
                        smooth: true,
                    };
                } else {
                    var line_a = {
                        title: "太湖水域蓝藻等级面积统计",
                        legend: ["蓝藻面积"],
                        xAxisName: "等级",
                        yAxisName: "蓝藻像元数量(500*500m)",
                        chartType: "line",
                        yMin: 0,
                        yMax: 2000, // 当显示为部分区域时,上限为4000
                        // smooth: true
                    };
                }
                // 显示折线图
                var labels = ["VCI1", "VCI2", "VCI3", "VCI4", "VCI5"];
                var countChart = ui.Chart.image(count_images, labels, line_a); // 方法2
                print(countChart);
                print("结束水华等级显示");
            }
        );
    },
});
panel.add(label74).add(btHIS);

// 基于Landsat系列数据进行月季年监测
var labelA2 = ui.Label("2、基于Landsat数据月季年监测", {
    "font-size": "18px",
    "font-weight": "bold",
    color: "red",
});
panel.add(labelA2);

var label4A = ui.Label("1) 请选择一个区域", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});

var selectAreaA = ui.Select({
    items: Object.keys(places),
    placeholder: "点击选择",
    value: null,
    multiple: false,
    onChange: function (key) {
        // 存储选择的矢量边界
        TH_boundary = places[key];
        return TH_boundary;
    },
});
panel.add(label4A).add(selectAreaA);

var btShowA = ui.Button({
    label: "显示研究区",
    type: "success",
    onClick: clickBtn,
});
var btNotShowA = ui.Button({
    label: "不显示研究区",
    type: "success",
});
var btnPanelShowA = ui.Panel({
    widgets: [btShowA, btNotShowA],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(btnPanelShowA);

// 2 选择时间
// 开始时间
var selectStartDateA = "2020-06-01"; // 设置初始值
var selectEndDateA = "2020-09-31";

var label5A = ui.Label("2) 请输入研究时间及云量", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});

function inputSDateA(value) {
    selectStartDateA = value;
}

var textBox1A = ui.DateSelect({
    type: "date",
    placeholder: "请输入数值",
    value: selectStartDateA, //输入显示框显示数值
    onChange: inputSDateA,
    disabled: false,
});

var textboxName1A = ui.Label("开始时间:");
var textboxPanel1A = ui.Panel({
    widgets: [textboxName1A, textBox1A],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(label5A).add(textboxPanel1A);

// 结束时间
function inputEDateA(value) {
    selectEndDateA = value;
}

var textBox2A = ui.DateSelect({
    type: "date",
    placeholder: "请输入数值",
    value: selectEndDateA, //输入显示框显示数值
    onChange: inputEDateA,
    disabled: false,
});

var textboxName2A = ui.Label("结束时间:");
var textboxPanel2A = ui.Panel({
    widgets: [textboxName2A, textBox2A],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(textboxPanel2A);

// 筛选云量 输入数值
var textboxName2AA = ui.Label("输入云量:");

function funInputNumberA(value) {
    selectNumA = value; // 设置云量值
}

var selectNumA = 20; // 设置起始输入数据
var inputNumberA = ui.InputNumber({
    placeholder: "请输入云量",
    value: selectNumA,
    min: 0,
    max: 100,
    step: 1,
    onChange: funInputNumberA,
    disabled: false,
});
var textboxPanel2AA = ui.Panel({
    widgets: [textboxName2AA, inputNumberA],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(textboxPanel2AA);

// 蓝藻水华计算
var label81 = ui.Label("3) 月季年蓝藻水华监测", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btALG = ui.Button({
    label: "计算水华影像",
    type: "success",
    onClick: function () {
        print("开始水华面积计算");

        //设置图层显示属性
        var visalg = generateVisalg(-0.5, 0.5);
        var layerDate = []; //存储年份
        var counts = []; // 存储像元数量
        var dateList = getDateList(selectStartDateA, selectEndDateA);
        // 筛选影像
        for (var i = 0; i < dateList.length; i++) {
            var startDate = dateList[i].start;
            var endDate = dateList[i].end;
            var year = new Date(startDate).getFullYear();
            var l8Col = landsat8Util.getLandsat8(
                startDate,
                endDate,
                TH_boundary,
                selectNumA
            );
            l8Col = l8Col.map(landsat8Util.alg);
            var alg_mean = l8Col.select("alg").mean().clip(TH_boundary); // 求取平均值
            var layerName = startDate + "_" + endDate + "alg"; // 设置图层名称
            layerDate.push(year);

            var count = alg_mean.reduceRegion(pie.Reducer.count(), TH_boundary, 30); // 统计数量
            print(count);
            counts.push(count);
            Map.addLayer(alg_mean, visalg, layerName); // 加载图层
        }

        // 设置图表属性
        var line_a = {
            title: "太湖水域蓝藻动态变化",
            legend: ["蓝藻"],
            xAxisName: "日期",
            yAxisName: "蓝藻数量",
            chartType: "line",
            yMin: 0,
            yMax: 10000000,
            smooth: true,
        };

        // 显示折线图
        var chart = ui.Chart.image(counts, layerDate, line_a);
        print(chart);

        // 图例
        addLegendToMap({
            title: "FAI",
            labels: ["0", "0.05", "0.1", "0.15", "0.20", "0.25"],
            step: 30,
        });
        print("结束水华面积计算");
    },
});
panel.add(label81).add(btALG);

// 蓝藻浑浊度计算
var label8 = ui.Label("4) 月季年蓝藻浑浊度监测", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btHZ = ui.Button({
    label: "计算蓝藻浑浊度影像",
    type: "success",
    onClick: function () {
        print("开始计算蓝藻浑浊度");
        //加载Landsat 8 SR
        var layerDate = []; //存储年份
        var counts = []; // 存储像元数量
        var dateList = getDateList(selectStartDateA, selectEndDateA);
        //设置图层显示属性
        var visalg = generateVisalg(0, 1000);
        // 筛选影像
        for (var i = 0; i < dateList.length; i++) {
            var startDate = dateList[i].start; // 组合开始日期
            var endDate = dateList[i].end; // 组合结束日期
            var year = new Date(startDate).getFullYear();
            var l8Col = landsat8Util.getLandsat8(
                startDate,
                endDate,
                TH_boundary,
                selectNumA
            );
            l8Col = l8Col.map(landsat8Util.turbidity);
            var alg_mean = l8Col.select("turbidity").max().clip(TH_boundary); // 求取最大值
            var layerName = startDate + "_" + endDate + "turbidity"; // 设置图层名称
            layerDate.push(year);
            var mean_count = alg_mean
                .select("turbidity")
                .reduceRegion(pie.Reducer.mean(), TH_boundary, 30); // 统计数量
            counts.push(mean_count);
            print(mean_count);
            Map.addLayer(alg_mean, visalg, layerName); // 加载图层
        }

        // 显示图例
        addLegendToMap({
            title: "浑浊度",
            labels: ["优", "差"],
            step: 12,
        });
        // 设置图表属性
        var line_a = {
            title: "太湖水域蓝藻浑浊度动态变化",
            legend: ["蓝藻浑浊度"],
            xAxisName: "日期",
            yAxisName: "浑浊度均值)",
            chartType: "line",
            yMin: 0,
            yMax: 1000,
            smooth: true,
        };
        // 显示折线图
        var countChart = ui.Chart.image(counts, layerDate, line_a);
        print(countChart);
        print("结束计算蓝藻浑浊度");
    },
});
panel.add(label8).add(btHZ);

// 蓝藻密度计算
var label9 = ui.Label("5) 月季年蓝藻密度监测", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btMD = ui.Button({
    label: "计算蓝藻密度影像",
    type: "success",
    onClick: function () {
        print("开始计算蓝藻密度");
        var layerDate = []; //存储年份
        var counts = []; // 存储像元数量
        var dateList = getDateList(selectStartDateA, selectEndDateA);
        //设置图层显示属性
        var visalg = generateVisalg(0, 1000);
        // 筛选影像
        for (var i = 0; i < dateList.length; i++) {
            var startDate = dateList[i].start; // 组合开始日期
            var endDate = dateList[i].end; // 组合结束日期
            var year = new Date(startDate).getFullYear();
            //加载Landsat 8 SR
            var l8Col = landsat8Util.getLandsat8(
                startDate,
                endDate,
                TH_boundary,
                selectNumA
            );
            l8Col = l8Col.map(landsat8Util.MD);
            var alg_mean = l8Col.select("md").mean().clip(TH_boundary); // 求取平均值
            var layerName = startDate + "_" + endDate + "md"; // 设置图层名称
            layerDate.push(year);

            var mean_count = alg_mean
                .select("md")
                .reduceRegion(pie.Reducer.mean(), TH_boundary, 30); // 统计数量
            counts.push(mean_count);
            print(mean_count);
            Map.addLayer(alg_mean, visalg, layerName); // 加载图层
        }

        // 显示图例
        addLegendToMap({
            title: "密度",
            labels: ["低", "高"],
            step: 30,
        });

        // 绘制表格
        // 设置图表属性
        var line_a = {
            title: "太湖水域蓝藻密度动态变化",
            legend: ["蓝藻浑浊度"],
            xAxisName: "日期",
            yAxisName: "密度均值)",
            chartType: "line",
            yMin: 0,
            yMax: 100000,
            smooth: true,
        };
        // 显示折线图
        var countChart = ui.Chart.image(counts, layerDate, line_a);
        print(countChart);
        print("结束计算蓝藻密度");
    },
});
panel.add(label9).add(btMD);

// 计算叶绿素a
var label81 = ui.Label("6) 月季年叶绿素监测", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btChla = ui.Button({
    label: "计算叶绿素影像",
    type: "success",
    onClick: function () {
        print("开始计算叶绿素");
        var layerDate = []; //存储年份
        var counts = []; // 存储像元数量
        //设置图层显示属性
        var visalg = generateVisalg(-50, 1000);

        var dateList = getDateList(selectStartDateA, selectEndDateA);
        // 筛选影像
        for (var i = 0; i < dateList.length; i++) {
            var startDate = dateList[i].start; // 组合开始日期
            var endDate = dateList[i].end; // 组合结束日期
            var year = new Date(startDate).getFullYear();
            //加载Landsat 8 SR
            var l8Col = landsat8Util.getLandsat8(
                startDate,
                endDate,
                TH_boundary,
                selectNumA
            );
            l8Col = l8Col.map(landsat8Util.cha);
            var alg_mean = l8Col.select("cha").mean().clip(TH_boundary); // 求取平均值
            var layerName = startDate + "_" + endDate + "cha"; // 设置图层名称
            layerDate.push(year);

            var mean_count = alg_mean
                .select("cha")
                .reduceRegion(pie.Reducer.mean(), TH_boundary, 30); // 统计数量
            counts.push(mean_count);
            print(mean_count);
            Map.addLayer(alg_mean, visalg, layerName); // 加载图层
        }

        // 显示图例
        addLegendToMap({
            title: "叶绿素",
            labels: ["低", "高"],
            step: 30,
        });

        // 设置图表属性
        var line_a = {
            title: "太湖水域蓝藻叶绿素动态变化",
            legend: ["蓝藻浑浊度"],
            xAxisName: "日期",
            yAxisName: "叶绿素均值)",
            chartType: "line",
            yMin: 0,
            yMax: 1000,
            smooth: true,
        };
        // 显示折线图
        var countChart = ui.Chart.image(counts, layerDate, line_a);
        print(countChart);
        print("结束计算叶绿素");
    },
});
panel.add(label81).add(btChla);

// 透明度反演
var label82 = ui.Label("7) 月季年透明度监测", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btParence = ui.Button({
    label: "计算透明度影像",
    type: "success",
    onClick: function () {
        print("开始计算透明度");
        //加载Landsat 8 SR
        var layerDate = []; //存储年份
        var counts = []; // 存储像元数量
        //设置图层显示属性
        var visalg = generateVisalg(0, 200);
        var dateList = getDateList(selectStartDateA, selectEndDateA);
        // 筛选影像
        for (var i = 0; i < dateList.length; i++) {
            var startDate = dateList[i].start; // 组合开始日期
            var endDate = dateList[i].end; // 组合结束日期
            var year = new Date(startDate).getFullYear();
            var l8Col = landsat8Util.getLandsat8(
                startDate,
                endDate,
                TH_boundary,
                selectNumA
            );
            l8Col = l8Col.map(landsat8Util.trans);
            var alg_mean = l8Col.select("trans").mean().clip(TH_boundary); // 求取平均值

            var layerName = startDate + "_" + endDate + "trans"; // 设置图层名称
            layerDate.push(year);

            var mean_count = alg_mean
                .select("trans")
                .reduceRegion(pie.Reducer.mean(), TH_boundary, 30); // 统计数量

            counts.push(mean_count);
            print("均值:", mean_count);
            Map.addLayer(alg_mean, visalg, layerName); // 加载图层
        }

        // 显示图例
        addLegendToMap({title: "透明度", labels: ["低", "高"], step: 30});

        // 绘制表格
        // 设置图表属性
        var line_a = {
            title: "太湖水域蓝藻透明度动态变化",
            legend: ["蓝藻透明度"],
            xAxisName: "日期",
            yAxisName: "透明度均值",
            chartType: "line",
            yMin: 0,
            yMax: 1000,
            smooth: true,
        };

        // 显示折线图
        var countChart = ui.Chart.image(counts, layerDate, line_a);
        print(countChart);
        print("结束计算透明度");
    },
});
panel.add(label82).add(btParence);

// 归一化悬浮物指数
var label83 = ui.Label("8) 月季年归一化悬浊物监测", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btSS = ui.Button({
    label: "计算归一化悬浊物影像",
    type: "success",
    onClick: function () {
        print("开始计算归一化悬浊物");
        var layerDate = []; //存储年份
        var counts = []; // 存储像元数量
        //设置图层显示属性
        var visalg = generateVisalg(0, 1);
        var dateList = getDateList(selectStartDateA, selectEndDateA);
        // 筛选影像
        for (var i = 0; i < dateList.length; i++) {
            var startDate = dateList[i].start; // 组合开始日期
            var endDate = dateList[i].end; // 组合结束日期
            var year = new Date(startDate).getFullYear();
            var l8Col = landsat8Util.getLandsat8(
                startDate,
                endDate,
                TH_boundary,
                selectNumA
            );
            l8Col = l8Col.map(landsat8Util.ss);
            var alg_mean = l8Col.select("ss").mean().clip(TH_boundary); // 求取平均值

            var layerName = startDate + "_" + endDate + "ss"; // 设置图层名称
            layerDate.push(year);

            var mean_count = alg_mean
                .select("ss")
                .reduceRegion(pie.Reducer.mean(), TH_boundary, 30); // 统计数量

            counts.push(mean_count);
            print(mean_count);
            Map.addLayer(alg_mean, visalg, layerName); // 加载图层
        }

        // 显示图例
        addLegendToMap({title: "归一化悬浊物", labels: ["低", "高"], step: 30});

        // 绘制表格
        // 设置图表属性
        var line_a = {
            title: "太湖水域蓝藻归一化悬浊物动态变化",
            legend: ["归一化悬浊物"],
            xAxisName: "日期",
            yAxisName: "归一化悬浊物均值)",
            chartType: "line",
            yMin: 0,
            yMax: 1,
            smooth: true,
        };

        // 显示折线图
        var countChart = ui.Chart.image(counts, layerDate, line_a);
        print(countChart);
        print("结束计算归一化悬浊物");
    },
});
panel.add(label83).add(btSS);

// 计算水域面积变化
var label11 = ui.Label("8) 太湖水域面积", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btMJ = ui.Button({
    label: "计算水域面积",
    type: "success",
    onClick: function () {
        print("开始水华面积计算");
        var waterArea = []; //存储面积
        var yearDate = []; // 存储时间
        var dateList = getDateList(selectStartDateA, selectEndDateA);
        // 筛选影像
        for (var i = 0; i < dateList.length; i++) {
            var startDate = dateList[i].start; // 组合开始日期
            var endDate = dateList[i].end; // 组合结束日期
            var year = new Date(startDate).getFullYear();
            var l8Col = landsat8Util.getLandsat8(
                startDate,
                endDate,
                TH_boundary,
                selectNumA
            );
            l8Col = l8Col.map(landsat8Util.mndwiCa);
            var mndwi_max = l8Col.select("mndwi").max().clip(TH_boundary);
            var l8_water = mndwi_max.gt(0.1);
            Map.addLayer(l8_water, {palette: "#0602ff"}, year + "water");

            //根据计算的水体数据计算面积
            var areaImage = mndwi_max.pixelArea().multiply(l8_water.gt(0.1));
            var water = areaImage.reduceRegion(pie.Reducer.sum(), TH_boundary, 30);
            var water_area = pie.Number(water.get("constant")).divide(1000000);
            waterArea.push(water_area.getInfo()); // 保存面积,需用getInfo
            yearDate.push(year); // 存储年份
            print(
                year + "水体面积是(单位:平方千米): ",
                pie.Number(water.get("constant")).divide(1000000)
            ); //进行单位换算
        }

        // 设置图表属性
        var line_options = {
            title: "太湖水域面积动态变化",
            legend: ["水域面积"],
            xAxis: yearDate,
            xAxisName: "年",
            yAxisName: "平方千米",
            series: [waterArea],
            chartType: "line",
        };
        //调用绘制折线图的方法
        var chart = ui.Chart.array(line_options);
        print(chart);
        //动画显示
        Map.playLayersAnimation(dates, 0.5, -1);
    },
});
panel.add(label11).add(btMJ);

var label111 = ui.Label("9) 太湖水域温度", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btLST = ui.Button({
    label: "计算水域温度",
    type: "success",
    onClick: function () {
        var layerDate = []; //存储年份
        var counts = []; // 存储像元数量
        //设置图层显示属性
        var visalg = generateVisalg(0, 40);
        var dateList = getDateList(selectStartDateA, selectEndDateA);
        // 筛选影像
        for (var i = 0; i < dateList.length; i++) {
            var startDate = dateList[i].start; // 组合开始日期
            var endDate = dateList[i].end; // 组合结束日期
            var year = new Date(startDate).getFullYear();
            // 筛选影像
            var rawLST = MOD11A2.filterDate(startDate, endDate)
                .filterBounds(TH_boundary)
                .select("LST_Day_1km")
                .mean()
                .clip(TH_boundary);
            var lst = rawLST.select("LST_Day_1km").multiply(0.02).subtract(273.15);

            var layerName = startDate + "_" + endDate + "LSTmean";

            Map.addLayer(lst, visalg, layerName);
            var mean = lst.reduceRegion(pie.Reducer.mean(), TH_boundary, 1000); // 统计温度均值
            counts.push(mean);
            layerDate.push(year);
        }

        // 显示图例
        addLegendToMap({
            title: "湖面温度",
            labels: ["0", "10 ", " 20", "30"],
            step: 12,
        });

        // 绘制表格
        // 设置图表属性
        var line_a = {
            title: "太湖水域温度均值变化",
            legend: ["温度均值"],
            xAxisName: "年份",
            yAxisName: "温度均值(℃)",
            chartType: "line",
            yMin: 0,
            yMax: 40,
            smooth: true,
        };

        // 显示折线图
        var countChart = ui.Chart.image(counts, layerDate, line_a);
        print(countChart);
    },
});
panel.add(label111).add(btLST);

// 第二节,太湖周围生态监测
// 基于Landsat系列数据计算太湖周围生态指数
var labelB = ui.Label("二、太湖周围生态监测", {
    "font-size": "20px",
    "font-weight": "bold",
    color: "red",
});
panel.add(labelB);

var label1B1 = ui.Label("1、指数计算", {
    "font-size": "18px",
    "font-weight": "bold",
    color: "red",
});
panel.add(label1B1);

// 2 选择时间
// 开始时间
var selectStartDateAA = "2014-03-01"; // 设置初始值
var selectEndDateAA = "2020-10-31";

var label5AA = ui.Label("1) 请输入研究时间及缓冲距离", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});

function inputSDateAA(value) {
    selectStartDateAA = value;
}

var textBox1AA = ui.DateSelect({
    type: "date",
    placeholder: "请输入数值",
    value: selectStartDateAA, //输入显示框显示数值
    onChange: inputSDateAA,
    disabled: false,
});

var textboxName1AA = ui.Label("开始时间:");
var textboxPanel1AA = ui.Panel({
    widgets: [textboxName1AA, textBox1AA],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(label5AA).add(textboxPanel1AA);

// 结束时间
function inputEDateAA(value) {
    selectEndDateAA = value;
}

var textBox2AA = ui.DateSelect({
    type: "date",
    placeholder: "请输入数值",
    value: selectEndDateAA, //输入显示框显示数值
    onChange: inputEDateAA,
    disabled: false,
});

var textboxName2AA = ui.Label("结束时间:");
var textboxPanel2AA = ui.Panel({
    widgets: [textboxName2AA, textBox2AA],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(textboxPanel2AA);

//获取缓冲区
// 输入数值
var textboxName2AAA = ui.Label("请输入缓冲距离(km):");

function funInputNumberAA(value) {
    selectNumAA = value; // 设置值
}

var selectNumAA = 30; // 设置起始输入数据
var inputNumberAA = ui.InputNumber({
    placeholder: "请输入缓冲距离",
    value: selectNumAA,
    min: 0,
    max: 100,
    step: 1,
    onChange: funInputNumberAA,
    disabled: false,
});
var textboxPanel2AA = ui.Panel({
    widgets: [textboxName2AAA, inputNumberAA],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(textboxPanel2AA);

// 1缓冲区温度反演
var label11 = ui.Label("2) 温度显示", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btlst = ui.Button({
    label: "计算温度",
    type: "success",
    onClick: function () {
        print("开始计算温度");

        var Th_buffer_1km = EntireLake.buffer(selectNumAA * 1000);
        var Th_buffer_dif = Th_buffer_1km.difference(EntireLake);

        var layerDate = []; //存储年份
        var counts = []; // 存储像元数量
        var layers = [];
        //设置图层显示属性
        var visalg = generateVisalg(0, 40);
        var dateList = getDateList(selectStartDateAA, selectEndDateAA);
        // 筛选影像
        for (var i = 0; i < dateList.length; i++) {
            var startDate = dateList[i].start; // 组合开始日期
            var endDate = dateList[i].end; // 组合结束日期
            var year = new Date(startDate).getFullYear();
            // 筛选影像
            var rawLST = MOD11A2.filterDate(startDate, endDate)
                .filterBounds(Th_buffer_dif)
                .select("LST_Day_1km")
                .mean()
                .clip(Th_buffer_dif);
            var lst = rawLST.select("LST_Day_1km").multiply(0.02).subtract(273.15);

            var layerName = startDate + "_" + endDate + "mean";
            layers.push(layerName);

            Map.addLayer(lst, visalg, layerName);
            var mean = lst.reduceRegion(pie.Reducer.mean(), Th_buffer_dif, 1000); // 统计温度均值
            print(mean);
            counts.push(mean);
            layerDate.push(year);
        }

        // 显示图例
        addLegendToMap({
            title: "湖面温度",
            labels: ["0", "10 ", " 20", "30", "40"],
            step: 12,
        });

        // 绘制表格
        // 设置图表属性
        var line_a = {
            title: "太湖水域周围" + selectNumAA + "km温度均值变化",
            legend: ["温度均值(℃)"],
            xAxisName: "年份",
            yAxisName: "温度均值(℃)",
            chartType: "line",
            yMin: 0,
            yMax: 40,
            smooth: true,
        };

        // 显示折线图
        var countChart = ui.Chart.image(counts, layerDate, line_a);
        print(countChart);
        //动画显示
        Map.playLayersAnimation(layers, 0.5, -1);
        print("结束计算温度");
    },
});
panel.add(label11).add(btlst);

// 缓冲区绿度反演
var label12 = ui.Label("3) NDVI显示", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btNdvi = ui.Button({
    label: "计算NDVI",
    type: "success",
    onClick: function () {
        print("开始计算NDVI");
        var Th_buffer_1km = EntireLake.buffer(selectNumAA * 1000);
        var Th_buffer_dif = Th_buffer_1km.difference(EntireLake);

        var layerDate = []; //存储年份
        var counts = []; // 存储像元数量
        var layers = [];
        //设置图层显示属性
        var visalg = generateVisalg(-1, 1);

        var dateList = getDateList(selectStartDateAA, selectEndDateAA);
        // 筛选影像
        for (var i = 0; i < dateList.length; i++) {
            var startDate = dateList[i].start; // 组合开始日期
            var endDate = dateList[i].end; // 组合结束日期
            var year = new Date(startDate).getFullYear();
            // 筛选影像
            var l8Col = landsat8Util.getLandsat8(
                startDate,
                endDate,
                Th_buffer_dif,
                20
            );
            l8Col = l8Col
                .map(landsat8Util.ndvi)
                .select("ndvi")
                .max()
                .clip(Th_buffer_dif);

            var layerName = startDate + "_" + endDate + "mean";
            layers.push(layerName);

            Map.addLayer(l8Col, visalg, layerName);
            var mean = l8Col
                .select("ndvi")
                .reduceRegion(pie.Reducer.mean(), Th_buffer_dif, 30); // 统计ndvi均值
            print(mean);
            counts.push(mean);
            layerDate.push(year);
        }

        // 显示图例
        addLegendToMap({
            title: "NDVI",
            labels: ["-1", "-0.5 ", " 0", "0.5", "1"],
            step: 12,
        });

        // 设置图表属性
        var line_a = {
            title: "太湖水域周围" + selectNumAA + "kmNDVI均值变化",
            legend: ["NDVI均值"],
            xAxisName: "年份",
            yAxisName: "NDVI均值",
            chartType: "line",
            yMin: 0,
            yMax: 1,
            smooth: true,
        };

        // 显示折线图
        var countChart = ui.Chart.image(counts, layerDate, line_a);
        print(countChart);
        //动画显示
        Map.playLayersAnimation(layers, 0.5, -1);
        print("结束计算NDVI");
    },
});
panel.add(label12).add(btNdvi);

// 计算植被覆盖度
var label121 = ui.Label("4) 植被覆盖度显示", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btfvc = ui.Button({
    label: "计算FVC",
    type: "success",
    onClick: function () {
        print("开始计算FVC");
        var Th_buffer_1km = EntireLake.buffer(selectNumAA * 1000);
        var Th_buffer_dif = Th_buffer_1km.difference(EntireLake);
        var layers = [];
        //设置图层显示属性
        var visalg = generateVisalg(0, 1);
        var dateList = getDateList(selectStartDateAA, selectEndDateAA);
        var startDate = dateList[0].start; // 组合开始日期
        var endDate = dateList[0].end; // 组合结束日期

        // 筛选影像
        var l8Col = landsat8Util.getLandsat8(startDate, endDate, Th_buffer_dif, 20);
        var ndvi = l8Col
            .map(landsat8Util.ndvi)
            .select("ndvi")
            .max()
            .clip(Th_buffer_dif);

        var result = pie.Dictionary(
            ndvi.reduceRegion(pie.Reducer.percentile([5, 95]), Th_buffer_dif, 30)
        );
        var ndvi_p5 = pie.Dictionary(result.get("ndvi")).getNumber("p5").getInfo();
        //反演区域植被覆盖度并加载
        var fvc = ndvi.subtract(ndvi_p5).divide(1.2).rename("fvc");

        var layerName = startDate + "_" + endDate + "mean";
        layers.push(layerName);

        Map.addLayer(fvc.select("fvc"), visalg, layerName);
        var mean = fvc
            .select("fvc")
            .reduceRegion(pie.Reducer.mean(), Th_buffer_dif, 30); // 统计ndvi均值
        print("fvc均值:", mean);

        // 显示图例
        addLegendToMap({
            title: "FVC",
            labels: ["0", "0.2 ", " 0.4", "0.6", "0.8", "1"],
            step: 12,
        });
        print("结束计算FVC");
    },
});
panel.add(label121).add(btfvc);

// 计算湿度
var label13 = ui.Label("5) Wet显示", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btWet = ui.Button({
    label: "计算Wet",
    type: "success",
    onClick: function () {
        print("开始计算wet");
        var Th_buffer_1km = EntireLake.buffer(selectNumAA * 1000);
        var Th_buffer_dif = Th_buffer_1km.difference(EntireLake);
        var layerDate = []; //存储年份
        var counts = []; // 存储像元数量
        var layers = [];
        //设置图层显示属性
        var visalg = generateVisalg(-0.5, 0.5);
        var dateList = getDateList(selectStartDateAA, selectEndDateAA);
        // 筛选影像
        for (var i = 0; i < dateList.length; i++) {
            var startDate = dateList[i].start; // 组合开始日期
            var endDate = dateList[i].end; // 组合结束日期
            var year = new Date(startDate).getFullYear();
            // 筛选影像
            var l8Col = landsat8Util.getLandsat8(
                startDate,
                endDate,
                Th_buffer_dif,
                20
            );
            var wet = landsat8Util.wet(
                l8Col.select(["B2", "B3", "B4", "B5", "B6", "B7"]).mean()
            );
            wet = wet.select("wet").clip(Th_buffer_dif);

            var layerName = startDate + "_" + endDate + "mean";
            layers.push(layerName);

            Map.addLayer(wet, visalg, layerName);
            var mean = wet
                .select("wet")
                .reduceRegion(pie.Reducer.mean(), Th_buffer_dif, 30); // 统计WET均值
            print("均值:", mean);
            counts.push(mean);
            layerDate.push(year);
        }

        // 显示图例
        addLegendToMap({
            title: "Wet",
            labels: ["-0.5", "-0.25 ", " 0", "0.25", "0.5"],
            step: 12,
        });

        // 设置图表属性
        var line_a = {
            title: "太湖水域周围" + selectNumAA + "kmWet均值变化",
            legend: ["Wet均值"],
            xAxisName: "年份",
            yAxisName: "Wet均值",
            chartType: "line",
            yMin: -0.5,
            yMax: 0.5,
            smooth: true,
        };

        // 显示折线图
        var countChart = ui.Chart.image(counts, layerDate, line_a);
        print(countChart);
        //动画显示
        // Map.playLayersAnimation(layers, 0.5, -1);
        print("结束计算Wet");
    },
});
panel.add(label13).add(btWet);

// 城镇建筑指数
var label14 = ui.Label("6) NDBSI显示", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btNdbsi = ui.Button({
    label: "计算NDBSI",
    type: "success",
    onClick: function () {
        print("开始计算NDBSI");
        var Th_buffer_1km = EntireLake.buffer(selectNumAA * 1000);
        var Th_buffer_dif = Th_buffer_1km.difference(EntireLake);
        var layerDate = []; //存储年份
        var counts = []; // 存储像元数量
        //设置图层显示属性
        var visalg = generateVisalg(-0.1, 1);
        var dateList = getDateList(selectStartDateAA, selectEndDateAA);
        // 筛选影像
        for (var i = 0; i < dateList.length; i++) {
            var startDate = dateList[i].start; // 组合开始日期
            var endDate = dateList[i].end; // 组合结束日期
            var year = new Date(startDate).getFullYear();
            // 筛选影像
            var l8Col = landsat8Util.getLandsat8(
                startDate,
                endDate,
                Th_buffer_dif,
                selectNumA
            );
            l8Col = l8Col.select(["B2", "B3", "B4", "B5", "B6"]).mean();
            var ndbsi = landsat8Util.ndbsi(l8Col).select("ndbsi").clip(Th_buffer_dif);
            var layerName = startDate + "_" + endDate + "mean";

            Map.addLayer(ndbsi, visalg, layerName);
            var mean = ndbsi.reduceRegion(pie.Reducer.mean(), Th_buffer_dif, 30); // 统计ndvi均值
            print("均值:", mean);
            counts.push(mean);
            layerDate.push(year);
        }

        // 显示图例
        addLegendToMap({
            title: "NDBSI",
            labels: ["0", "0.2 ", " 0.4", "0.6", "0.8", "1"],
            step: 12,
        });

        // 设置图表属性
        var line_a = {
            title: "太湖水域周围" + selectNumAA + "kmNDBSI均值变化",
            legend: ["Wet均值"],
            xAxisName: "年份",
            yAxisName: "NDBSI均值",
            chartType: "line",
            yMin: -0.1,
            yMax: 1,
            smooth: true,
        };

        // 显示折线图
        var countChart = ui.Chart.image(counts, layerDate, line_a);
        print(countChart);
        print("结束计算NDBSI");
    },
});
panel.add(label14).add(btNdbsi);

// 监督分类
// 第二节,土地利用监测
// 基于Landsat系列数据对太湖周边地区进行土地利用监测
var label1B2 = ui.Label("2、土地利用监测", {
    "font-size": "18px",
    "font-weight": "bold",
    color: "red",
});
panel.add(label1B2);

function classifyLand(tag) {
    Map.centerObject(EntireLake, 11);

    var counts = []; // 存储像元数量
    var Th_buffer_1km = EntireLake.buffer(selectNumAA * 1000);
    var Th_buffer_dif = Th_buffer_1km.difference(EntireLake);

    var dateList = getDateList(selectStartDateAA, selectEndDateAA);
    // 筛选影像
    for (var i = 0; i < dateList.length; i++) {
        var startDate = dateList[i].start; // 组合开始日期
        var endDate = dateList[i].end; // 组合结束日期
        var year = new Date(startDate).getFullYear();
        var l8Col = landsat8Util.getLandsat8(startDate, endDate, Th_buffer_dif, 10);
        var image = l8Col.select(["B2", "B3", "B4", "B5", "B6", "B7"]).median();
        image = landsat8Util.ndvi(image);
        image = landsat8Util.mndwi(image);
        image = image.clip(Th_buffer_dif);

        // 获得训练样本,并且按照8:2分成训练样本和验证样本
        var sampleFeatureCollection = image.sampleRegions(
            points,
            ["landcover"],
            30
        );
        sampleFeatureCollection = sampleFeatureCollection.filter(pie.Filter.notNull(["B2",
            "B3",
            "B4",
            "B5",
            "B6",
            "B7",
            "ndvi",
            "mndwi"
        ]))
        sampleFeatureCollection = sampleFeatureCollection.randomColumn("random");
        var sampleTrainingFeatures = sampleFeatureCollection.filter(
            pie.Filter.lte("random", 0.8)
        );
        var sampleTestingFeatures = sampleFeatureCollection.filter(
            pie.Filter.gt("random", 0.8)
        );

        var methods = {
            rTrees: pie.Classifier.rTrees,
            svm: pie.Classifier.svm,
            normalBayes: pie.Classifier.normalBayes,
        };

        // 构建RT分类器,并训练数据
        var classifer = methods[tag]().train(sampleTrainingFeatures, "landcover", [
            "B2",
            "B3",
            "B4",
            "B5",
            "B6",
            "B7",
            "ndvi",
            "mndwi",
        ]);

        // 影像分类,并加载显示
        var resultImage = image.classify(classifer, "classifyA");

        // 形态学运算
        resultImage = resultImage.focal_max(1); // 膨胀运算
        resultImage = resultImage.focal_min(1); //腐蚀运算
        var visParam = {
            opacity: 1,
            uniqueValue: "1,2,3,4,5",
            palette: "#040274,#269db1,#3ae237,#ff0000,#911003",
        };
        Map.addLayer(resultImage, visParam, year + "-" + tag + "-Image");
        Map.addLayer(
            image, {min: 0, max: 0.3, bands: ["B4", "B3", "B2"]},
            year + "-Original Image"
        );
        var counts = [];
        for (var i = 1; i <= 5; i++) {
            var areaImg = pie.Image().pixelArea();
            var count = areaImg
                .multiply(resultImage.eq(i))
                .reduceRegion(pie.Reducer.sum(), Th_buffer_dif, 30); // 类别数量统计
            counts.push(count);
        }

        // 设置图表属性
        var line_a = {
            title: dateList[i].start.slice(0, 4) + "年太湖水域周边地物面积统计",
            legend: ["不同地物面积"],
            xAxisName: "类别",
            yAxisName: "面积(平方千米)",
            chartType: "line",
            yMin: 0,
            yMax: 20000,
        };

        var labels = ["水体", "建设用地", "林地", "耕地", "裸地"];
        var countChart = ui.Chart.image(counts, labels, line_a); // 方法2
        print(countChart);
    }

    // 添加图例
    addLegend({
        title: "土地利用分类",
        colors: ["#040274", "#269db1", "#3ae237", "#ff0000", "#911003"],
        labels: ["水体", "建设用地", "林地", "耕地", "裸地"],
        step: 1,
    });
    // 评估训练样本的精度
    var checkM = classifer.confusionMatrix();
    print("训练矩阵:", checkM);
    print(
        "训练矩阵-ACC系数:",
        checkM.acc(),
        "训练矩阵-Kappa系数:",
        checkM.kappa()
    );

    // 评估验证样本的精度
    var predictResult = sampleTestingFeatures.classify(
        classifer,
        "classification"
    );
    var errorM = predictResult.errorMatrix("landcover", "classification");
    print("验证矩阵:", errorM);
    print(
        "验证矩阵-ACC系数:",
        errorM.acc(),
        "验证矩阵-Kappa系数:",
        errorM.kappa()
    );
}

// 城市建筑用地情况
var label15 = ui.Label("1) 随机森林分类", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btClass = ui.Button({
    label: "开始分类",
    type: "success",
    onClick: function () {
        // 获得样本点
        print("开始随机森林分类");
        classifyLand("rTrees");
        print("结束随机森林分类");
    },
});
panel.add(label15).add(btClass);

// 支持向量机分类
var label16 = ui.Label("2) 支持向量机分类", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btSVCClass = ui.Button({
    label: "开始分类",
    type: "success",
    onClick: function () {
        // 获得样本点
        print("开始支持向量机分类");
        classifyLand("svm");
        print("结束支持向量机分类");
    },
});
panel.add(label16).add(btSVCClass);

// 正太贝叶斯分类
var label17 = ui.Label("3) 正太贝叶斯分类", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
var btNBClass = ui.Button({
    label: "开始分类",
    type: "success",
    onClick: function () {
        // 获得样本点
        print("开始正太贝叶斯分类");
        classifyLand("normalBayes");
        print("结束正太贝叶斯分类");
    },
});
panel.add(label17).add(btNBClass);

// k-mean分类
var label18 = ui.Label("4) 非监督分类", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
panel.add(label18);

function clusterLand(tag) {
    Map.centerObject(EntireLake, 11);
    var Th_buffer_1km = EntireLake.buffer(selectNumAA * 1000);
    var Th_buffer_dif = Th_buffer_1km.difference(EntireLake);

    var dateList = getDateList(selectStartDateAA, selectEndDateAA);
    // 筛选影像
    for (var i = 0; i < dateList.length; i++) {
        var startDate = dateList[i].start; // 组合开始日期
        var endDate = dateList[i].end; // 组合结束日期
        var year = new Date(startDate).getFullYear();

        var l8Col = landsat8Util.getLandsat8(startDate, endDate, Th_buffer_dif, 10);
        var image = l8Col.select(["B2", "B3", "B4", "B5", "B6", "B7"]).median();
        var ndvi = landsat8Util.ndvi(image).select("ndvi");
        var mndwi = landsat8Util.mndwi(image).select("mndwi");
        image = image.addBands(ndvi).addBands(mndwi).clip(Th_buffer_dif);

        // 随机采集样本,30米下采集200个点分类
        var training = image.sample(Th_buffer_dif, 30, "", "", 200);

        var methods = {
            kMeans: pie.Clusterer.kMeans,
            em: pie.Clusterer.em,
        };
        // 创建分类器,并进行训练
        var cluster = methods[tag](selectNumAAA).train(training);
        // 分类数据并显示
        var resultImage = image.cluster(cluster, "clusterA");
        // 形态学运算
        resultImage = resultImage.focal_max(1); // 膨胀运算
        resultImage = resultImage.focal_min(1); //腐蚀运算

        var visParam = {
            opacity: 1,
            classify: "0,1,2,3,4,5,6",
            palette: "FF0000,00FFFF,00FF00,FF00FF,0000FF,FFFF00,FF8000,00AAFF",
        };
        Map.addLayer(resultImage, visParam, year + "-" + tag + "-resultImage", false);

        var vis = {
            min: 0,
            max: 0.3,
            opacity: 0.9,
            bands: ["B4", "B3", "B2"],
        };
        Map.addLayer(image.select(["B4", "B3", "B2"]), vis, year + "-Landsat8 RGB", false);
    }
}

//获取类别
// 输入数值
var textboxName2AAAA = ui.Label("请输入k:");

function funInputNumberAAA(value) {
    selectNumAAA = value; // 设置值
}

var selectNumAAA = 2; // 设置起始输入数据
var inputNumberAAA = ui.InputNumber({
    placeholder: "请输入k",
    value: selectNumAAA,
    min: 0,
    max: 5,
    step: 1,
    onChange: funInputNumberAAA,
    disabled: false,
});
var textboxPanel2AAA = ui.Panel({
    widgets: [textboxName2AAAA, inputNumberAAA],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(textboxPanel2AAA);

var btkmeanClass = ui.Button({
    label: "k-means分类",
    type: "success",
    onClick: function () {
        // 获得样本点
        print("开始k-means分类");
        clusterLand("kMeans");
        print("结束k-means分类");
    },
});
panel.add(btkmeanClass);

// 最大期望算法
var btemClass = ui.Button({
    label: "最大期望算法",
    type: "success",
    onClick: function () {
        // 获得样本点
        print("开始最大期望分类");
        clusterLand("em");
        print("结束最大期望分类");
    },
});
panel.add(btemClass);

// 第三节,其他功能
var labelC = ui.Label("三、其他功能", {
    "font-size": "20px",
    "font-weight": "bold",
    color: "red",
});
panel.add(labelC);
var label510 = ui.Label("1) 请输入行政区划", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
panel.add(label510);
var label5101 = ui.Label(
    "[注]:行政区划网址:http://www.mca.gov.cn/article/sj/xzqh/2020/", {
        "font-size": "16px",
        "font-weight": "bold",
        color: "black"
    }
);
panel.add(label5101);

// 单选按钮,选择省、城市、县
var selectDis = "县行政区划";

function funRadio(value) {
    selectDis = value;
}

var radio = ui.Radio({
    label: ["省行政区划", "县行政区划"],
    value: selectDis,
    onChange: funRadio,
    disabled: false,
});
var textboxName31 = ui.Label("行政级别:");
var textboxPanel31 = ui.Panel({
    widgets: [textboxName31, radio],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(textboxPanel31);

//定义常量参数
var layerKey = null;
var roiKey = null;
var selectCode = "110114";

// 输入行政区划
//获取指定的ROI数据
function getROI(code) {
    if (selectDis == "县行政区划") {
        var fCol = pie.FeatureCollection("NGCC/CHINA_COUNTY_BOUNDARY");
    } else if (selectDis == "省行政区划") {
        var fCol = pie.FeatureCollection("NGCC/CHINA_PROVINCE_BOUNDARY");
    }
    var roi = fCol
        .filter(pie.Filter.eq("code", parseInt(code)))
        .first()
        .geometry();
    if (roiKey != null) {
        Map.removeLayer(roiKey);
    }
    var geometry = roi.centroid(); // 中心点
    var roiPoint = pie.FeatureCollection(pie.Feature(geometry));
    Map.addLayer(
        roiPoint, {color: "00AAFF", fillColor: "00000000"},
        "centroidPoint",
        true
    );
    Map.centerObject(geometry, 10);

    var label1a = ui.Label("行政区划代码:" + code, {
        "font-size": "20px",
        "font-weight": "bold",
        color: "black",
    });
    Map.addUI(label1a);

    roiKey = Map.addLayer(
        roi, {color: "#ff0000", fillColor: "#00000000"},
        "roi"
    );
    return roi;
}

function inputArea(value) {
    if (value > 99999) {
        selectCode = value;
        var roi = getROI(selectCode);
        print("行政区划的面积是(平方千米):");
        print(roi.area().divide(1000000)); // 计算面积
    }
}

var textBox3 = ui.TextBox({
    placeholder: "请输入行政区划编码",
    value: selectCode,
    onChange: inputArea,
    disabled: false,
});
var textboxName3 = ui.Label("行政区划:");
var textboxPanel3 = ui.Panel({
    widgets: [textboxName3, textBox3],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(textboxPanel3);

// 导出数据
function clickBtExpShp() {
    var roi = getROI(selectCode);
    Export.table({
        collection: roi,
        description: "ExportShp" + selectCode,
        assetId: selectCode + "shp",
    });
}

var btExpShp = ui.Button({
    label: "导出行政边界",
    type: "success",
    onClick: clickBtExpShp,
});
panel.add(btExpShp);

// 输入时间
// 开始时间
var label511 = ui.Label("2) 请输入查询时间", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});

function inputSDate(value) {
    selectStartDate2 = value;
}

var textBox11 = ui.DateSelect({
    type: "date",
    placeholder: "请输入数值",
    value: selectStartDate2, //输入显示框显示数值
    onChange: inputSDate,
    disabled: false,
});

var textboxName11 = ui.Label("开始时间:");
var textboxPanel1 = ui.Panel({
    widgets: [textboxName11, textBox11],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(label511).add(textboxPanel1);

// 结束时间
function inputEDate(value) {
    selectEndDate2 = value;
}

var textBox21 = ui.DateSelect({
    type: "date",
    placeholder: "请输入数值",
    value: selectEndDate2, //输入显示框显示数值
    onChange: inputEDate,
    disabled: false,
});

var textboxName21 = ui.Label("结束时间:");
var textboxPanel21 = ui.Panel({
    widgets: [textboxName21, textBox21],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(textboxPanel21);

// 查询影像
var label19 = ui.Label("3) 显示数据", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});

function changeSelect(value) {
    var roi = getROI(selectCode);
    print("选择的数据:" + value);
    if (value == "Landsat8") {
        var imageCollection = landsat8Util
            .getLandsat8(selectStartDate2, selectEndDate2, roi, 100)
            .select(["B4", "B3", "B2"]);
        print("影像集合", imageCollection.limit(1));
        print("影像数量", imageCollection.size());
        var image_median = imageCollection.median().clip(roi);
        print(image_median);
        var vis = {
            min: [0, 0, 0],
            max: [20000, 20000, 20000],
            opacity: 0.9,
            bands: ["B4", "B3", "B2"],
        };
        Map.addLayer(image_median, vis, "Landsat8");
    } else if (value == "GF1") {
        var imageCollection = pie
            .ImageCollection("GF1/L1A/WFV_SR")
            .filterBounds(roi)
            .filterDate(selectStartDate2, selectEndDate2)
            .select(["B3", "B2", "B1"]);
        print("影像集合", imageCollection.limit(1));
        print("影像数量", imageCollection.size());
        var image_median = imageCollection.median().clip(roi);
        var vis = {min: 0, max: 0.3, opacity: 0.9, bands: ["B3", "B2", "B1"]};
        Map.addLayer(image_median, vis, "GF1");
    } else {
        // 哨兵二号去云2
        function removeCloud2(image) {
            var qa = image.select("QA60");
            var cloudBitMask = 1 << 10;
            var cirrusBitMask = 1 << 11;
            var mask = qa
                .bitwiseAnd(cloudBitMask)
                .eq(0)
                .and(qa.bitwiseAnd(cirrusBitMask).eq(0));
            return image.updateMask(mask);
        }

        var imageCollection = pie
            .ImageCollection("S2/L1C")
            .filterBounds(roi)
            .filterDate(selectStartDate2, selectEndDate2)
            .map(removeCloud2)
            .select(["B4", "B3", "B2"]); // 真彩色
        print("影像集合", imageCollection.limit(1));
        print("影像数量", imageCollection.size());
        var image_median = imageCollection.median().clip(roi);
        var vis = {min: 0, max: 10000, opacity: 0.9, bands: ["B4", "B3", "B2"]};
        Map.addLayer(image_median, vis, "Sentinel-2");
    }
}

var selectId = ui.Select({
    items: ["Landsat8", "Sentinel-2", "GF1"],
    placeholder: "请选择",
    value: "Landsat8",
    multiple: false,
    onChange: changeSelect,
});
panel.add(label19).add(selectId);

// 地形显示
var label20 = ui.Label("4) 地形显示", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
panel.add(label20);

var selectTag1A = "DEM"; // 设置初始值
// select
function changeSelect1A(value) {
    selectTag1A = value;
    var roi = getROI(selectCode);
    var dem = pie
        .ImageCollection("DEM/ASTGTM_003")
        .filterBounds(roi)
        .select("dem")
        .mean()
        .clip(roi);
    var visParam;
    if (value == "DEM") {
        visParam = {
            opacity: 0.8,
            classify: "-100,0,100,200,300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,2000,2100,2200,2300,2400,2500,2600,2700,2800,2900,3000,3100",
            palette: "145999,1b76cc,1f86e6,26aaea,36b6eb,4dc0eb,60cfeb,77daef,b0dfef,d1e5ee,dce6f0,e1e7f2,dee6f1,43c370,44b772,52c88e," +
                "6fc993,7ecb97,acd2ad,d4c97a,d0bc59,d3b146,c78f3c,c3812d,c5762b,b95322,ae4621,ba6e78,bc8fa9,c7aac6,dbcdde,fffcff",
        };
        Map.addLayer(dem, visParam, "DEM");
        var mean = dem.select("dem").reduceRegion(pie.Reducer.mean(), roi, 30);
        print("DEM均值:" + mean.get("dem").getInfo() + "m");

        // 添加图例
        addDem2LegendToMap({
            title: "DEM",
            labels: ["-100", "500", "1000", "1500", "2000", "2500", "3000"],
            step: 100,
        });
    } else if (value == "坡向") {
        var aspect = pie.Terrain.aspect(dem); // 计算坡向
        visParam = {
            opacity: 0.8,
            classify: "0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,310,320",
            palette: "145999,1b76cc,1f86e6,26aaea,36b6eb,4dc0eb,60cfeb,77daef,b0dfef,d1e5ee,dce6f0,e1e7f2,dee6f1,43c370,44b772,52c88e," +
                "6fc993,7ecb97,acd2ad,d4c97a,d0bc59,d3b146,c78f3c,c3812d,c5762b,b95322,ae4621,ba6e78,bc8fa9,c7aac6,dbcdde,fffcff",
        };
        Map.addLayer(aspect, visParam, "Aspect");

        // 添加图例
        addDem2LegendToMap({
            title: "坡向",
            labels: ["0", "50", "100", "150", "200", "250", "300"],
            step: 10,
        });
    } else if (value == "坡度") {
        var slope = pie.Terrain.slope(dem).multiply(180 / 3.1415926); // 计算坡度
        visParam = {
            opacity: 0.8,
            classify: "0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180",
            palette: "145999,1b76cc,1f86e6,26aaea,36b6eb,4dc0eb,60cfeb,77daef,b0dfef,d1e5ee,dce6f0,e1e7f2,dee6f1,43c370,44b772,52c88e," +
                "6fc993,7ecb97,acd2ad",
        };
        Map.addLayer(slope, visParam, "slope");

        // 添加图例
        addDem1LegendToMap({
            title: "坡度",
            labels: ["0", "30", "60", "90", "120", "150", "180"],
            step: 10,
        });
    } else {
        var imageShade = pie.Terrain.hillShade(dem, 45, 315, 8); // 山体阴影
        visParam = {
            opacity: 0.8,
            classify: "-1100,-800,-700,-600,-500,-400,-300,-200,-100,-50,-20,-10,-5,0,5,10,25,50,75,100,125,150,175,200,250,300,350,400,450,500,550,600,880",
            palette: "145999,1b76cc,1f86e6,26aaea,36b6eb,4dc0eb,60cfeb,77daef,b0dfef,d1e5ee,dce6f0,e1e7f2,dee6f1,43c370,44b772,52c88e," +
                "6fc993,7ecb97,acd2ad,d4c97a,d0bc59,d3b146,c78f3c,c3812d,c5762b,b95322,ae4621,ba6e78,bc8fa9,c7aac6,dbcdde,fffcff",
        };
        Map.addLayer(imageShade, visParam, "imageShade");

        // 添加图例
        addDem1LegendToMap({
            title: "山体阴影",
            labels: ["0", "50", "100", "150", "200", "250", "300"],
            step: 10,
        });
    }
}

var select1A = ui.Select({
    items: ["DEM", "坡向", "坡度", "山体阴影"],
    placeholder: "请选择",
    value: selectTag1A,
    multiple: false,
    onChange: changeSelect1A,
});
var selectName1A = ui.Label("选择地形:");
var selectPanel1A = ui.Panel({
    widgets: [selectName1A, select1A],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(selectPanel1A);

//导出数据
function clickbtExport() {
    print(selectTag1A);
    var roi = getROI(selectCode);

    var dem = pie
        .ImageCollection("DEM/ASTGTM_003")
        .filterBounds(roi)
        .select("dem")
        .mean()
        .clip(roi);

    var aspect = pie.Terrain.aspect(dem); // 计算坡向
    var slope = pie.Terrain.slope(dem).multiply(180 / 3.1415926); // 计算坡度
    var imageShade = pie.Terrain.hillShade(dem, 45, 315, 8); // 山体阴影
    var config = {
        DEM: dem,
        坡度: slope,
        坡向: aspect,
        山体阴影: imageShade,
    };
    Export.image({
        image: config[selectTag1A],
        description: "ExportImage:" + selectTag1A,
        assetId: "test",
        region: roi,
        scale: 30,
    });
}

var btExport = ui.Button({
    label: "导出数据",
    type: "success",
    onClick: clickbtExport,
});
panel.add(btExport);

// 指数计算
var label21 = ui.Label("5) 指数计算", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
panel.add(label21);

function changeSelect1B(value) {
    selectTag1B = value;
    var roi = getROI(selectCode);
    var l8Col = landsat8Util.getLandsat8(
        selectStartDate2,
        selectEndDate2,
        roi,
        20
    );
    l8Col = l8Col.select(["B2", "B3", "B4", "B5", "B6", "B7"]).median().clip(roi);
    if (value == "ndvi") {
        var ndvi = landsat8Util.ndvi(l8Col).select("ndvi");
        //设置图层显示属性
        var visalg = generateVisalg(-1, 1);
        Map.addLayer(ndvi, visalg, "NDVI");
        var mean = ndvi.select("ndvi").reduceRegion(pie.Reducer.mean(), roi, 30);
        print("ndvi均值:" + mean.get("ndvi").getInfo());

        // 显示图例
        addLegendToMap({
            title: "NDVI",
            labels: ["-1", "-0.5 ", " 0", "0.5", "1"],
            step: 30,
        });
    } else if (value == "fvc") {
        var fvc = landsat8Util.fvc(l8Col).select("fvc");
        var visalg = generateVisalg(0, 1);
        Map.addLayer(fvc, visalg, "fvc");
        var mean = fvc.select("fvc").reduceRegion(pie.Reducer.mean(), roi, 30);
        print("fvc均值:" + mean.get("fvc").getInfo());

        // 显示图例
        addLegendToMap({
            title: "fvc",
            labels: ["0", "0.2 ", " 0.4", "0.6", "0.8", "1"],
            step: 30,
        });
    } else if (value == "rvi") {
        var rvi = landsat8Util.rvi(l8Col).select("rvi");
        var visalg = generateVisalg(0, 1);
        Map.addLayer(rvi, visalg, "rvi");
        var mean = rvi.select("rvi").reduceRegion(pie.Reducer.mean(), roi, 30);
        print("rvi均值:" + mean.get("rvi").getInfo());
        // 显示图例
        addLegendToMap({
            title: "rvi",
            labels: ["0", "0.2 ", " 0.4", "0.6", "0.8", "1"],
            step: 30,
        });
    } else if (value == "evi") {
        var evi = landsat8Util.evi(l8Col).select("evi");
        //设置图层显示属性
        var visalg = generateVisalg(-1, 1);
        Map.addLayer(evi, visalg, "evi");
        var mean = evi.select("evi").reduceRegion(pie.Reducer.mean(), roi, 30);
        print("evi均值:" + mean.get("evi").getInfo());

        // 显示图例
        addLegendToMap({
            title: "evi",
            labels: ["-1", "-0.5 ", " 0", "0.5", "1"],
            step: 30,
        });
    } else if (value == "wet") {
        var wet = landsat8Util.wet(l8Col).select("wet");
        var visalg = generateVisalg(-1, 1);
        Map.addLayer(wet, visalg, "wet_oli");
        var mean = wet_oli.select("wet").reduceRegion(pie.Reducer.mean(), roi, 30);
        print("wet均值:" + mean.get("wet").getInfo());
        // 显示图例
        addLegendToMap({
            title: "wet",
            labels: ["-1", "-0.5 ", " 0", "0.5", "1"],
            step: 30,
        });
    } else if (value == "ndbsi") {
        var ndbsi = landsat8Util.ndbsi(l8Col).select("ndbsi");
        var visalg = generateVisalg(0, 0.5);
        Map.addLayer(ndbsi, visalg, "ndbsi");
        var mean = ndbsi.select("ndbsi").reduceRegion(pie.Reducer.mean(), roi, 30);
        print("ndbsi均值:" + mean.get("ndbsi").getInfo());

        // 显示图例
        addLegendToMap({
            title: "ndbsi",
            labels: ["0", "0.1", " 0.2", "0.3", "0.4"],
            step: 30,
        });
    } else if (value == "ndbi") {
        var ndbi = landsat8Util.ndbi(l8Col).select("ndbi");
        var visalg = generateVisalg(-0.5, 0.5);
        var ndbi = b6.subtract(b5).divide(b6.add(b5)).rename("ndbi");
        Map.addLayer(ndbi, visalg, "ndbi");
        var mean = ndbi.select("ndbi").reduceRegion(pie.Reducer.mean(), roi, 30);
        print("ndbi均值:" + mean.get("ndbi").getInfo());

        // 显示图例
        addLegendToMap({
            title: "ndbi",
            labels: ["-0.5", "-0.25", " 0", "0.25", "0.5"],
            step: 30,
        });
    } else if (value == "lai") {
        //加载Terra星全球500m叶面积指数/FPAR 8天合成产品(MOD15A2H V6)
        var images = pie
            .ImageCollection("USGS/MOD15A2H/006")
            .filterDate(selectStartDate2, selectEndDate2);
        //选择LAI波段,计算LAI均值
        var lai = images
            .select("Lai_500m")
            .map(function (image) {
                return image.updateMask(image.lt(200));
            })
            .mean()
            .clip(roi)
            .rename("lai");

        //设置图层显示属性
        var visalg = generateVisalg(0, 100);
        Map.addLayer(lai, visalg, "lai");
        var mean = lai.select("lai").reduceRegion(pie.Reducer.mean(), roi, 500);
        print("lai均值:" + mean.get("lai").getInfo());

        // 显示图例
        addLegendToMap({
            title: "lai",
            labels: ["0", "30 ", " 60", "90"],
            step: 30,
        });
    } else if (value == "fpar") {
        //加载Terra星全球500m叶面积指数/FPAR 8天合成产品(MOD15A2H V6)
        var images = pie
            .ImageCollection("USGS/MOD15A2H/006")
            .filterDate(selectStartDate2, selectEndDate2);
        //选择FPAR波段,计算FPAR均值
        var fpar = images.select("Fpar_500m").mean().clip(roi).rename("fpar");

        //设置图层显示属性
        var visalg = generateVisalg(0, 100);
        Map.addLayer(fpar, visalg, "fpar");
        var mean = fpar.select("fpar").reduceRegion(pie.Reducer.mean(), roi, 500);
        print("fpar均值:" + mean.get("fpar").getInfo());

        // 显示图例
        addLegendToMap({
            title: "fpar",
            labels: ["0", "30 ", " 60", "90"],
            step: 30,
        });
    } else if (value == "lst") {
        var lst = MOD11A2.filterDate(selectStartDate2, selectEndDate2)
            .filterBounds(roi)
            .select("LST_Day_1km")
            .mean()
            .multiply(0.02)
            .subtract(273.15)
            .clip(roi)
            .rename("lst");

        //设置图层显示属性
        var visalg = generateVisalg(0, 30);
        Map.addLayer(lst, visalg, "lst");
        var mean = lst.select("lst").reduceRegion(pie.Reducer.mean(), roi, 1000);
        print("lst均值:" + mean.get("lst").getInfo());

        // 显示图例
        addLegendToMap({
            title: "温度",
            labels: ["0", "10 ", " 20", "30"],
            step: 30,
        });
    } else if (value == "tvdi") {
        var image = globalTVDI(selectStartDate2, selectEndDate2, roi);
        //设置图层显示属性
        var visalg = generateVisalg(0, 1);
        Map.addLayer(image, visalg, "tvdi");
        var mean = image.reduceRegion(pie.Reducer.mean(), roi, 1000);
        print("tvdi均值:", mean.get("tvdi"));

        // 显示图例
        addLegendToMap({
            title: "tdvi",
            labels: ["0", "0.2 ", " 0.4", "0.6", "0.8", "1"],
            step: 30,
        });
    } else if (value == "ndwi") {
        var ndwi = landsat8Util.ndwi(l8Col).select("ndwi");
        var visalg = generateVisalg(-0.5, 0.5);
        Map.addLayer(ndwi, visalg, "ndwi");

        // 显示图例
        addLegendToMap({
            title: "ndwi",
            labels: ["-0.5", "-0.25 ", " 0", "0.25", "0.5"],
            step: 30,
        });
    } else if (value == "mndwi") {
        var mndwi = landsat8Util.mndwi(l8Col).select("mndwi");
        var visalg = generateVisalg(-0.5, 0.5);
        Map.addLayer(mndwi, visalg, "mndwi");

        // 显示图例
        addLegendToMap({
            title: "mndwi",
            labels: ["-0.5", "-0.25 ", " 0", "0.25", "0.5"],
            step: 30,
        });

        //根据计算的水体数据计算面积
        var areaImage = mndwi
            .select("water")
            .pixelArea()
            .multiply(mndwi.select("water").gt(0.1));
        var water = areaImage.reduceRegion(pie.Reducer.sum(), roi, 30);
        print(water);

        print(
            "水体面积是(单位:平方千米): ",
            pie.Number(water.get("constant").getInfo()).divide(1000000)
        ); //进行单位换算
    }
}

var selectTag1B = "ndvi"; // 设置初值
var select1B = ui.Select({
    items: [
        "ndvi",
        "rvi",
        "evi",
        "fvc",
        "lai",
        "fpar",
        "wet",
        "lst",
        "ndbsi",
        "ndbi",
        "tvdi",
        "mndwi",
        "ndwi",
    ],
    placeholder: "请选择",
    value: selectTag1B,
    multiple: false,
    onChange: changeSelect1B,
});
var selectName1B = ui.Label("选择指数:");
var selectPanel1B = ui.Panel({
    widgets: [selectName1B, select1B],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(selectPanel1B);

function clickbtExport1() {
    print(selectTag1B);
    var roi = getROI(selectCode);
    var l8Col = landsat8Util.getLandsat8(
        selectStartDate2,
        selectEndDate2,
        roi,
        20
    );
    l8Col = l8Col.select(["B2", "B3", "B4", "B5", "B6", "B7"]).median().clip(roi);

    // tvdi
    var tvdi = globalTVDI(selectStartDate2, selectEndDate2, roi);

    // lst
    var lst = MOD11A2.filterDate(selectStartDate2, selectEndDate2)
        .filterBounds(roi)
        .select("LST_Day_1km")
        .mean()
        .multiply(0.02)
        .subtract(273.15)
        .rename("lst")
        .clip(roi);

    // lai
    //加载Terra星全球500m叶面积指数/FPAR 8天合成产品(MOD15A2H V6)
    var images1 = pie
        .ImageCollection("USGS/MOD15A2H/006")
        .filterDate(selectStartDate2, selectEndDate2);
    //选择LAI波段,计算LAI均值
    var lai = images1
        .select("Lai_500m")
        .map(function (image) {
            return image.updateMask(image.lt(200));
        })
        .mean()
        .clip(roi)
        .rename("lai");

    // fpar
    //选择FPAR波段,计算FPAR均值
    var fpar = images1.select("Fpar_500m").mean().clip(roi).rename("fpar");

    l8Col = landsat8Util.ndvi(l8Col);
    l8Col = landsat8Util.wet(l8Col);
    l8Col = landsat8Util.ndbsi(l8Col);
    l8Col = landsat8Util.evi(l8Col);
    l8Col = landsat8Util.mndwi(l8Col);
    l8Col = landsat8Util.fvc(l8Col);
    l8Col = landsat8Util.rvi(l8Col);
    l8Col = landsat8Util.ndbi(l8Col);
    l8Col = l8Col
        .addBands(ndwi.rename("ndwi"))
        .addBands(lst.rename("lst"))
        .addBands(tvdi.rename("tvdi"))
        .addBands(lai.rename("lai"))
        .addBands(fpar.rename("fpar"));
    //导出影像
    Export.image({
        image: l8Col.select(selectTag1B),
        description: "ExportImage:" + selectTag1B,
        assetId: "test",
        region: roi,
        scale: 30,
    });
}

//导出数据
var btExport1 = ui.Button({
    label: "导出数据",
    type: "success",
    onClick: clickbtExport1,
});
panel.add(btExport1);

// 回归分析
var label22 = ui.Label("6) 回归分析", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
panel.add(label22);

function changeCheckbox(value) {
    var roi = getROI(selectCode);
    print("开始回归分析");

    // 裁剪
    function clip(image) {
        image = image.clip(roi);
        return image;
    }

    var l8Col = landsat8Util.getLandsat8(
        selectStartDate2,
        selectEndDate2,
        roi,
        20
    );
    l8Col = l8Col
        .select(["B2", "B3", "B4", "B5", "B6", "B7"])
        .map(clip)
        .map(landsat8Util.ndvi)
        .map(landsat8Util.wet)
        .map(landsat8Util.evi);

    var visParam1 = {
        min: [0, 0.5, 0],
        max: [0.3, 2, 0.3],
        opacity: 1,
        bands: ["offset", "scale", "offset"],
    };
    var image1 = l8Col.select(["ndvi", "evi"]).reduce(pie.Reducer.linearFit()); // 回归算法
    Map.addLayer(image1, visParam1, "linearFit");
    print("结束回归分析");
}

var checkbox = ui.Checkbox({
    label: ["ndvi", "evi", "wet"],
    value: [],
    disabled: [],
    onChange: changeCheckbox,
});
panel.add(checkbox);

// 土地堵盖类型显示
var label23 = ui.Label("7) 土地覆盖类型显示", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
panel.add(label23);

function clickbtLandShow() {
    var roi = getROI(selectCode);
    //加载全球地表覆盖GlobeLand30数据
    var sdate = new Date(selectStartDate2).getFullYear() + "-01-01"; // 获取起始日期前四位
    var edate = new Date(selectEndDate2).getFullYear() + "-12-31"; // 获取结束日期前四位
    var img = pie
        .ImageCollection("NGCC/GLOBELAND30")
        .filterBounds(roi)
        .filterDate(sdate, edate)
        .select("B1")
        .mosaic()
        .clip(roi);
    //按不同地表覆盖类型值设定预览参数
    var colors = [
        "#00FF00",
        "#00e900",
        "#00dF00",
        "#00ce00",
        "#00ba00",
        "#0002FF",
        "#97FF00",
        "#FF0000",
        "#FFce00",
        "#FFFFFF",
    ];
    var visGL = {
        uniqueValue: "10, 20, 30, 40, 50, 60, 70, 80, 90, 100",
        palette: colors,
    };
    //加载显示影像
    Map.addLayer(img, visGL, "img");

    // 图例
    addLegend({
        title: "地表覆盖",
        colors: colors,
        labels: [
            "耕地",
            "林地",
            "草地",
            "灌木地",
            "湿地",
            "水体",
            "苔原",
            "人造地表",
            "裸地",
            "积雪",
        ],
        step: 1,
    });
}

var btLandShow = ui.Button({
    label: "显示",
    type: "success",
    onClick: clickbtLandShow,
});
panel.add(btLandShow);

// 时间转换
var label24 = ui.Label("8) 时间转换", {
    "font-size": "16px",
    "font-weight": "bold",
    color: "red",
});
panel.add(label24);
var selectStartDateAAA = "2021-06-30";

function inputSDateAAA(value) {
    selectStartDateAAA = value;
}

var textBox1AAA = ui.DateSelect({
    type: "date",
    placeholder: "请输入数值",
    value: selectStartDateAAA, //输入显示框显示数值
    onChange: inputSDateAAA,
    disabled: false,
});

var textboxName1AAA = ui.Label("输入转换日期:");
var textboxPanel1AAA = ui.Panel({
    widgets: [textboxName1AAA, textBox1AAA],
    layout: ui.Layout.flow("horizontal"),
});
panel.add(textboxPanel1AAA);

// 转换天数,输入数据为pieNumber类型
function convertYearToDay(dateStr) {
    var now = new Date(dateStr);
    var start = new Date(now.getFullYear(), 0, 0);
    var diff = (now - start) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
    var oneDay = 1000 * 60 * 60 * 24;
    var day = Math.floor(diff / oneDay);
    return day;
}

function clickbtCon() {
    var dateNum = convertYearToDay(selectStartDateAAA); //转换为1年中的某一天
    print("转换后的天数:" + dateNum);
}

var btCon = ui.Button({
    label: "转换",
    type: "success",
    onClick: clickbtCon,
});
panel.add(btCon);
ui.root.add(panel);

结果:

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

此星光明

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值