在进行CCDC监测时,我们首先要做的就是获取研究区的长时间序列影像,让其保存在你的资产中,方便后面调用,这里我们要做的额就是根据代码,将我们时间范围进行选取和指定的研究区边界,剩下的采用默认参数即可。最后出现的结果是将ccdc代码中所需要的波段和影像中一些光谱波段加载到一起作为最终的影像参与分类和监测。
Parameter Name | Description | Recommended Value | Effect of Increasing |
breakPointBands | Bands to use to calculate test statistic and test for spectral change | Green, Red, NIR, SWIR1, SWIR2 | N/A |
tmaskBands | Bands to use for multi-temporal cloud and cloud-shadow masking | Green, SWIR2 | N/A |
minObservations | Number of consecutive observations exceeding threshold to flag a change | 4 | Less breaks detected |
chiSquare Probability | Threshold on test statistic, which is calculated from the model residuals and follows a chiSquare distribution | 0.995 | Less breaks detected |
minNumOfYears Scaler | Number of years after which a new model fit is calculated during training period | 1.33 | Decrease regression model refitting |
dateFormat | Format to store date information. 0: julian years, 1: fractional years, 2: unix time. | 1 | N/A |
lambda | Lambda value for LASSO regression fitting | .002 | More parameters shrinking to 0 |
maxIterations | Maximum iterations to perform LASSO regression fitting | 20,000 | Attempt more LASSO fits to reach convergence |
当我们打开代码的时候,我们就需要根据我们的需要监测的时间进行设定,这里按照标准的年月日进行设定,而 startDOY和endDOY分别指的是你在整个1987-2023年之间每一年要调用的影像的具体时间,设定范围为1-365,后台会自动按照你设定的时间进行指定范围内的影像筛选,在mask Image则是我们选择去云后有效的影像还是都要选,而Landsat系列影像一般都要囊括进去,这样才能保证长时序的监测,另外,我们还可以选择哨兵1好数据来加载到我们要下载的影像集合中。
这些参数的设定主要是特定的参数设置,所以这里一般情况下我选择默认参数,一般没有特殊需求既保持默认即可。
这里我们可以通过在地图上画,或者按照单个瓦片,或者多个瓦片,以及中线点等方式在地图上选择我们要导出的研究区。特别注意,慢慢点击地图上的五个点,应用程序就会生成一个矩形,作为输出范围的几何图形。最后一个点闭合的时候一定要靠近绘制的起始点。
这里可以选择导出到谷歌硬盘或者GEE资产中,一般建议后者,因为可以进行后续的CCDC操作。
我的研究区最终结果如下:共有1635景影像,每年影像涵盖25个波段。
//加载一个点用于定位
var geometry = /* color: #d63000 */ee.Geometry.Point([-69.68833790720782, -11.422826263974468]);
//加载两个定义好的函数库
var utils = require('users/parevalo_bu/gee-ccdc-tools:ccdcUtilities/inputs.js')
var ccdc_utils = require('users/parevalo_bu/gee-ccdc-tools:ccdcUtilities/ccdc.js')
var composite = require("users/google/toolkits:landcover/impl/composites.js").Composites
/**
* UI app等定义可视化参数和样式。
*
* 第一个字典包含标题参数,第二个字典包含 "运行 CCDC "按钮的样式。
* 第二个字典包含 "运行 CCDC "按钮的样式。
*/
var visLabels = {
fontWeight: 'bold',
fontSize: '14px',
width: '590px',
padding: '4px 4px 4px 4px',
border: '1px solid black',
color: 'white',
backgroundColor: 'black',
textAlign: 'left'
}
var runStyle = {
fontWeight: 'bold',
fontSize: '14px',
width: '590px',
padding: '4px 4px 4px 4px',
border: '1px solid black',
color: 'black',
backgroundColor: 'white',
textAlign: 'center'
}
var sensor = 'landsat'
/**
* 全球 GLANCE 陆地网格。
*
* 该特征集包含所有大陆与陆地重叠区域的
* 与陆地重叠区域的所有大陆的网格系统。
* 有关 GLANCE 和网格的更多信息,请点击此处:
* http://sites.bu.edu/measures/
*/
var grids = ee.FeatureCollection('projects/GLANCE/GRIDS/GEOG_LAND/GLANCE_v01_GLOBAL_TILE_LAND')
/**
* 用于放置 ui.Widgets 的面板。
*
* 有一个放置所有内容的主面板,以及一个名为geoPanel 的面板,用于放置选择输出范围的选项。
*/
var mainPanel = ui.Panel({style: {width: '600px'}})
.add(ui.Label('Continuous Change Detection and Classification (CCDC)',visLabels))
.add(ui.Label('User interface for submitting CCDC'))
.add(ui.Label('Please see instructions'))
.add(ui.Label('Input Parameters',visLabels))
ui.root.add(mainPanel)
var geoPanel = ui.Panel()
/**
* 定义全局变量
*
* 这样方便控件之间的交互变得更容易。
*/
//定义变量名称和常量变量
var outGeo, outGeos, outGeosSize, tool, drive, asset
var h = 0
var v = 0
var r = 0
var geoType = 0
var regionList = ['Select Method','Draw on Map','Single Tile','Tile Intersecting Point','Multiple Tiles','Draw Multiple Tiles on Map']
/**
* 在地图上画出研究区的引用
*
* Written by Justin Braaten (I think): https://emapr.github.io/LT-GEE/
* https://code.earthengine.google.com/82b08b69bd596ada4747cb4bb7ea9526
*
* 此功能可让您在地图上点击,点击 5 次后,这些位置就会连接起来,形成一个多边形。该多边形可用作 分析的地理范围。
*/
var DrawAreaTool = function() {
var map = Map
var drawingToolLayer = ui.Map.Layer({name: 'Area Selection Tool', visParams: {palette:'#4A8BF4', color:'#4A8BF4' }});
this.map = map;
this.selection = null;
this.active = false;
this.points = [];
this.area = null;
this.listeners = [];
var tool = this;
this.initialize = function() {
this.map.onClick(this.onMouseClick);
map.layers().reset()
map.layers().set(0, drawingToolLayer);
};
this.startDrawing = function() {
this.active = true;
this.points = [];
this.map.style().set('cursor', 'crosshair');
drawingToolLayer.setShown(true);
};
this.stopDrawing = function() {
tool.active = false;
tool.map.style().set('cursor', 'hand');
if(tool.points.length < 2) {
return;
}
var closedPoints = tool.points.slice(0,-1);
tool.area = ee.Geometry.Polygon(closedPoints)///.bounds();
var empty = ee.Image().byte();
var test = empty.paint({
featureCollection: ee.FeatureCollection(tool.area),
color: 1,
width: 4
});
drawingToolLayer.setEeObject(test);
tool.listeners.map(function(listener) {
listener(tool.area);
});
runButton.widgets().get(0).setDisabled(false)
runButton.widgets().get(0).style().set('backgroundColor','#5ab4ac')
};
this.onMouseClick = function(coords) {
if(!tool.active) {
return;
}
tool.points.push([coords.lon, coords.lat]);
var geom = tool.points.length > 1 ? ee.Geometry.LineString(tool.points) : ee.Geometry.Point(tool.points[0]);
drawingToolLayer.setEeObject(geom);
if(tool.points.length > 4) {
tool.stopDrawing();
}
};
this.onFinished = function(listener) {
tool.listeners.push(listener);
};
this.initialize();
};
/**
* 绘制输出范围的辅助函数。
*
* 使用DrawAreaTool() 函数绘制输出范围。
*/
function doAreaTool() {
geoPanel.add(ui.Label('Slowly click five points on the map and the application will generate a rectangle for the output extent geometry.'))
tool = new DrawAreaTool();
tool.startDrawing();
tool.onFinished(function(geometry) {
outGeo = ee.Feature(geometry);
});
}
/**
* 绘制输出范围和查找重叠瓦片的辅助函数
*
* 使用DrawAreaTool() 函数绘制输出范围。
*/
function drawMultipleTiles() {
geoPanel.add(ui.Label('Slowly click five points on the map and the application will generate a rectangle for the output extent geometry.'))
tool = new DrawAreaTool();
tool.startDrawing();
tool.onFinished(function(geometry) {
var tempGeo = grids.filterBounds(geometry);
tempGeo.size().evaluate(function(val) {
if (val > 0) {
outGeos = ee.FeatureCollection(tempGeo)
Map.addLayer(outGeos, {},'Output Geometry')
Map.centerObject(outGeos)
runButton.widgets().get(0).setDisabled(false)
runButton.widgets().get(0).style().set('backgroundColor','#5ab4ac')
outGeosSize