-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathee_app.js
198 lines (177 loc) · 6.23 KB
/
ee_app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This Earth Engine script runs light tree cover analysis on polygons
* representing Palm Oil Mills in Indonesia and produces a dashboard containing
* information about the mills. The dashboard contains a map that displays
* the mills and an information panel displays light analysis and a
* a link to a more advanced analytics environment.
*/
var hansen = ee.Image("UMD/hansen/global_forest_change_2020_v1_8"),
project = 'PROJECT_ID',
// asset = 'ASSET_ID',
table = ee.FeatureCollection("projects/"+project+"/assets/"+ asset),
errorMargin = 1e7,
advancedAnalyticsLink = 'ADVANCE_URL';
/**************
* Components *
**************/
var rootPanel = ui.Panel(); // Highest-level container.
var title = ui.Label("Cymbal Palm Oil Dashboard");
var mapPanel = ui.Panel();
var outputPanel = ui.Panel([],'',{'backgroundColor' : 'grey'});
// Configure the map panel.
var mainMap = ui.Map();
mainMap.setCenter(116.4194,0.5387, 6);
mapPanel.add(mainMap);
// Configure the output panel.
var advancedScriptLink = ui.Label(
'Advanced Analytics',{'color': 'black','backgroundColor':'D3D3D3',
'border': '2px solid black', 'padding':'4px'}, advancedAnalyticsLink);
var purposeHeader = ui.Label('Purpose', {fontWeight: 'bold'});
var statsHeader = ui.Label('Key Insights', {fontWeight: 'bold'});
var advancedAnalyticsHeader = ui.Label('Advanced Analytics', {fontWeight: 'bold'});
var advancedAnalyticsText = ui.Label(
'Please click the button below for more' + ' comprehensive analysis tools.');
var avgLossLabel = ui.Label('Average tree cover change in plantation areas is: ');
var totalLossLabel = ui.Label('Total tree cover change in plantation areas is: ');
var taskStatus = ui.Label('Data Import Status : ');
var taskDate = ui.Label('');
var textOutput = ui.Label('This dashboard provides information about the Plam Oil suppliers for the' +
' Cymbal Cookie Night Brand. The map on the left plots the boundaries of Palm' +
' Oil Plantations that partnering mills are likely sourcing from.');
var citation = ui.Label('[1] Source : Hansen, Potapov, Moore, Hancher et al.',
{textAlign: 'right'},'https://www.science.org/doi/10.1126/science.1244693');
outputPanel.add(taskStatus)
.add(taskDate)
.add(statsHeader)
.add(totalLossLabel)
.add(avgLossLabel)
.add(advancedAnalyticsHeader)
.add(advancedAnalyticsText)
.add(advancedScriptLink)
.add(purposeHeader)
.add(textOutput)
.add(citation);
/***********
* Styling *
***********/
title.style().set({
height: '10%',
width: '100%',
margin: 0,
textAlign: 'center',
fontSize: '24px',
backgroundColor: '444444',
color: 'white'
});
rootPanel.style().set({
height: '100%',
width: '100%'
});
mapPanel.style().set({
height: '90%',
width: '60%',
});
outputPanel.style().set({
height: '90%',
width: '50%',
backgroundColor: 'white',
});
// Configure the layouts for how the panels flow together.
ui.root.setLayout(ui.Panel.Layout.flow('vertical'));
rootPanel.setLayout(ui.Panel.Layout.flow('horizontal'));
/***************
* Composition *
***************/
ui.root.clear();
ui.root.add(title);
ui.root.add(rootPanel);
rootPanel.add(mapPanel);
rootPanel.add(outputPanel);
/* get the most data
/**********************
* Behaviors and data *
**********************/
// Get the current date
var currentDate = Date.now();
// List the assets (all with same date format as asset id)
var assetList = ee.data.listBuckets('projects/' + project);
var assets = assetList['assets'];
// Initialize variables
var smallestDiff = 0;
var desiredAsset = new Date();
// Loop thorugh assets and find the difference between today and the
// date of the asset
for (var asset in assets) {
// Set asset name is now the date
var id = assets[asset]['name'];
var assetName = id.split("/")[3];
// Create a date object
var assetDate = new Date(assetName);
// Find the difference between the date of the asset and the current date
var diff = currentDate - assetDate;
// Reset the smallestDiff if this is the first asset or if this asset is more
// recent than the current most recent asset
if ((asset == '0') || (diff < smallestDiff)) {
smallestDiff = diff
desiredAsset = assetDate
}
}
var desiredAssetString =
desiredAsset.toLocaleString('default', { month: 'short' }) +
'-' + desiredAsset.getDate( ) + '-' + desiredAsset.getFullYear( );
// Set asset with desired date as data to use.
table = ee.FeatureCollection(
'projects/' + project + '/assets/' + desiredAssetString);
// Add polygons to map.
mainMap.addLayer(table, {}, 'default display');
//Tree cover analysis
// Get the forest loss image.
var lossImage = hansen.select(['loss']);
var areaImage = lossImage.multiply(ee.Image.pixelArea());
var lossYear = hansen.select(['lossyear']);
// This function computes the feature's geometry area and forest loss and
// adds them as a properties.
var addProps = function(feature) {
var stats = areaImage.reduceRegion({
reducer: ee.Reducer.sum(),
geometry: feature.geometry(),
scale: 30,
maxPixels: 1e9
});
return feature.set( {areaHa: feature.geometry(errorMargin).area().divide(100 * 100),
forestLoss: stats.get('loss')});
};
//Populate UI with data
// Map the area and forest loss getting function over the FeatureCollection.
var propsAdded = table.map(addProps);
var totalLoss = propsAdded.aggregate_sum('forestLoss').round();
var avgLoss = propsAdded.aggregate_mean('forestLoss').round();
// Set info in UI panel
avgLoss.evaluate(function callback(value) {
var valueHA = value / 10000
avgLossLabel.setValue(
"Average tree cover change in plantation" +
" areas is: " + valueHA + " HA [1]");
});
totalLoss.evaluate(function callback(value) {
var valueHA = value / 10000
totalLossLabel.setValue(
"Total tree cover change in plantation" +
" areas is: " + valueHA + " HA [1]");
});
taskStatus.setValue("Data Import Status : " + desiredAssetString)