@hisptz/dhis2-analytics 1.0.51 → 1.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +29 -0
- package/build/cjs/components/Visualization/components/AnalyticsDataProvider/index.js +8 -5
- package/build/es/components/Visualization/components/AnalyticsDataProvider/index.js +8 -5
- package/package.json +4 -4
- package/.gitignore +0 -5
- package/d2.config.js +0 -8
- package/i18n/en.pot +0 -439
- package/src/components/ChartAnalytics/ChartAnalytics.test.tsx +0 -51
- package/src/components/ChartAnalytics/components/DownloadMenu/components/Menu.tsx +0 -48
- package/src/components/ChartAnalytics/components/DownloadMenu/constants/menu.ts +0 -38
- package/src/components/ChartAnalytics/components/DownloadMenu/index.tsx +0 -65
- package/src/components/ChartAnalytics/components/DownloadMenu/interfaces/menu.ts +0 -1
- package/src/components/ChartAnalytics/hooks/useChart.ts +0 -35
- package/src/components/ChartAnalytics/index.tsx +0 -28
- package/src/components/ChartAnalytics/models/bar.ts +0 -20
- package/src/components/ChartAnalytics/models/column.ts +0 -52
- package/src/components/ChartAnalytics/models/index.ts +0 -111
- package/src/components/ChartAnalytics/models/line.ts +0 -31
- package/src/components/ChartAnalytics/models/multi-series.ts +0 -115
- package/src/components/ChartAnalytics/models/pie.ts +0 -54
- package/src/components/ChartAnalytics/services/export.ts +0 -38
- package/src/components/ChartAnalytics/styles/custom-highchart.css +0 -48
- package/src/components/ChartAnalytics/types/props.tsx +0 -48
- package/src/components/ChartAnalytics/utils/chart.ts +0 -128
- package/src/components/CircularProgressDashboard/CircularProgressIndicator.test.tsx +0 -9
- package/src/components/CircularProgressDashboard/index.tsx +0 -36
- package/src/components/CircularProgressDashboard/types/props.tsx +0 -17
- package/src/components/CustomPivotTable/components/Table/index.tsx +0 -23
- package/src/components/CustomPivotTable/components/TableBody/TableBody.module.css +0 -12
- package/src/components/CustomPivotTable/components/TableBody/index.tsx +0 -96
- package/src/components/CustomPivotTable/components/TableHeaders/TableHeaders.module.css +0 -10
- package/src/components/CustomPivotTable/components/TableHeaders/index.tsx +0 -94
- package/src/components/CustomPivotTable/index.tsx +0 -63
- package/src/components/CustomPivotTable/interfaces/index.ts +0 -1
- package/src/components/CustomPivotTable/services/engine.ts +0 -102
- package/src/components/CustomPivotTable/state/engine.tsx +0 -22
- package/src/components/Map/components/EarthEngineLayerConfiguration/EarthEngineLayerConfigModal.stories.tsx +0 -28
- package/src/components/Map/components/EarthEngineLayerConfiguration/EarthEngineLayerConfiguration.stories.tsx +0 -34
- package/src/components/Map/components/EarthEngineLayerConfiguration/index.tsx +0 -412
- package/src/components/Map/components/MapArea/index.tsx +0 -83
- package/src/components/Map/components/MapArea/interfaces/index.ts +0 -39
- package/src/components/Map/components/MapControls/components/CustomControl/index.tsx +0 -24
- package/src/components/Map/components/MapControls/components/DownloadControl/index.tsx +0 -11
- package/src/components/Map/components/MapControls/components/FullscreenControl/index.tsx +0 -7
- package/src/components/Map/components/MapControls/index.tsx +0 -24
- package/src/components/Map/components/MapLayer/components/BoundaryLayer/hooks/useBoundaryData.ts +0 -7
- package/src/components/Map/components/MapLayer/components/BoundaryLayer/index.tsx +0 -55
- package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/components/EarthEngineLegend.tsx +0 -74
- package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/constants/index.ts +0 -430
- package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/hooks/index.ts +0 -34
- package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/index.tsx +0 -185
- package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/interfaces/index.ts +0 -56
- package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/services/api.js +0 -34241
- package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/services/engine.ts +0 -431
- package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/utils/index.ts +0 -105
- package/src/components/Map/components/MapLayer/components/LegendArea/LegendArea.module.css +0 -12
- package/src/components/Map/components/MapLayer/components/LegendArea/components/LegendCardHeader/index.tsx +0 -17
- package/src/components/Map/components/MapLayer/components/LegendArea/index.tsx +0 -167
- package/src/components/Map/components/MapLayer/components/PointLayer/components/PointLegend/index.tsx +0 -44
- package/src/components/Map/components/MapLayer/components/PointLayer/hooks/index.ts +0 -8
- package/src/components/Map/components/MapLayer/components/PointLayer/index.tsx +0 -36
- package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Bubble/components/BubbleLegend/components/Bubble.tsx +0 -48
- package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Bubble/components/BubbleLegend/components/Bubbles.tsx +0 -150
- package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Bubble/components/BubbleLegend/index.tsx +0 -39
- package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Bubble/index.tsx +0 -57
- package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Choropleth/components/ChoroplethLegend.tsx +0 -43
- package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Choropleth/index.tsx +0 -38
- package/src/components/Map/components/MapLayer/components/ThematicLayer/components/CustomTooltip/index.tsx +0 -26
- package/src/components/Map/components/MapLayer/components/ThematicLayer/hooks/config.ts +0 -10
- package/src/components/Map/components/MapLayer/components/ThematicLayer/index.tsx +0 -46
- package/src/components/Map/components/MapLayer/components/ThematicLayer/styles/legends.css +0 -62
- package/src/components/Map/components/MapLayer/index.tsx +0 -32
- package/src/components/Map/components/MapLayer/interfaces/index.ts +0 -139
- package/src/components/Map/components/MapProvider/components/MapLayerProvider/hooks/index.tsx +0 -368
- package/src/components/Map/components/MapProvider/components/MapLayerProvider/index.tsx +0 -105
- package/src/components/Map/components/MapProvider/hooks/index.ts +0 -14
- package/src/components/Map/components/MapProvider/index.tsx +0 -93
- package/src/components/Map/components/MapUpdater/index.tsx +0 -8
- package/src/components/Map/components/ThematicLayerConfiguration/ThematicLayerConfigModal.stories.tsx +0 -28
- package/src/components/Map/components/ThematicLayerConfiguration/ThematicLayerConfiguration.stories.tsx +0 -34
- package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/components/ColorScale/index.tsx +0 -24
- package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/constants/colors.ts +0 -433
- package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/index.tsx +0 -50
- package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/styles/ColorScale.module.css +0 -15
- package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/styles/ColorScaleSelect.module.css +0 -12
- package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/utils/colors.ts +0 -91
- package/src/components/Map/components/ThematicLayerConfiguration/components/CustomLegend/index.tsx +0 -45
- package/src/components/Map/components/ThematicLayerConfiguration/components/IndicatorSelectorModal/index.tsx +0 -47
- package/src/components/Map/components/ThematicLayerConfiguration/components/LegendSetSelector/index.tsx +0 -57
- package/src/components/Map/components/ThematicLayerConfiguration/index.tsx +0 -248
- package/src/components/Map/constants/colors.ts +0 -434
- package/src/components/Map/constants/legendSet.ts +0 -19
- package/src/components/Map/hooks/map.ts +0 -47
- package/src/components/Map/index.tsx +0 -65
- package/src/components/Map/interfaces/index.ts +0 -57
- package/src/components/Map/state/index.tsx +0 -31
- package/src/components/Map/utils/colors.ts +0 -95
- package/src/components/Map/utils/helpers.ts +0 -15
- package/src/components/Map/utils/map.ts +0 -150
- package/src/components/SingleValueContainer/SingleValueContainer.test.tsx +0 -24
- package/src/components/SingleValueContainer/components/SingleValueItem/SingleValueItem.tsx +0 -46
- package/src/components/SingleValueContainer/components/SingleValueItem/SingleValuePercentage.tsx +0 -12
- package/src/components/SingleValueContainer/index.tsx +0 -37
- package/src/components/SingleValueContainer/styles/SingleValueContainer.module.css +0 -39
- package/src/components/SingleValueContainer/types/props.tsx +0 -16
- package/src/components/Visualization/components/AnalyticsDataProvider/index.tsx +0 -76
- package/src/components/Visualization/components/DimensionsProvider/index.tsx +0 -51
- package/src/components/Visualization/components/LayoutProvider/index.tsx +0 -34
- package/src/components/Visualization/components/VisualizationDimensionSelector/index.tsx +0 -59
- package/src/components/Visualization/components/VisualizationProvider/index.tsx +0 -31
- package/src/components/Visualization/components/VisualizationSelector/index.tsx +0 -157
- package/src/components/Visualization/components/VisualizationTypeProvider/index.tsx +0 -40
- package/src/components/Visualization/components/VisualizationTypeSelector/index.tsx +0 -46
- package/src/components/Visualization/index.tsx +0 -103
- package/src/index.ts +0 -6
- package/src/locales/en/translations.json +0 -138
- package/src/locales/index.js +0 -16
- package/tsconfig.build.json +0 -46
- package/tsconfig.json +0 -51
package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/services/engine.ts
DELETED
|
@@ -1,431 +0,0 @@
|
|
|
1
|
-
import {MapOrgUnit} from "../../../../../interfaces";
|
|
2
|
-
import {EarthEngineOptions, EarthEngineToken, RefreshToken} from "../interfaces";
|
|
3
|
-
import {
|
|
4
|
-
combineReducers,
|
|
5
|
-
getFeatureCollectionProperties,
|
|
6
|
-
getHistogramStatistics,
|
|
7
|
-
getInfo,
|
|
8
|
-
getScale,
|
|
9
|
-
hasClasses
|
|
10
|
-
} from "../utils";
|
|
11
|
-
import {find, head, isEmpty} from "lodash";
|
|
12
|
-
|
|
13
|
-
// async function importEEModule(): Promise<any> {
|
|
14
|
-
// // @ts-ignore
|
|
15
|
-
// if (import.meta.env.STORYBOOK_BUILD === "true") {
|
|
16
|
-
// return await import("@google/earthengine");
|
|
17
|
-
// }
|
|
18
|
-
// return await import("./api");
|
|
19
|
-
// }
|
|
20
|
-
// const EE = await importEEModule();
|
|
21
|
-
//@ts-ignore
|
|
22
|
-
import EE from "./api";
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
const ee = EE as any;
|
|
25
|
-
// @ts-ignore
|
|
26
|
-
window.ee = ee;
|
|
27
|
-
|
|
28
|
-
const FEATURE_STYLE = {color: "FFA500", strokeWidth: 2};
|
|
29
|
-
const DEFAULT_TILE_SCALE = 1;
|
|
30
|
-
|
|
31
|
-
export class EarthEngine {
|
|
32
|
-
token?: EarthEngineToken;
|
|
33
|
-
options: EarthEngineOptions;
|
|
34
|
-
refresh?: RefreshToken;
|
|
35
|
-
orgUnits?: MapOrgUnit[];
|
|
36
|
-
initialized = false;
|
|
37
|
-
period?: string | string[];
|
|
38
|
-
instance: any;
|
|
39
|
-
scale?: any;
|
|
40
|
-
image: any;
|
|
41
|
-
aggregationData: any;
|
|
42
|
-
|
|
43
|
-
constructor({options}: { options: EarthEngineOptions }) {
|
|
44
|
-
this.options = options;
|
|
45
|
-
this.initialized = true;
|
|
46
|
-
this.getInstance();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
static async setToken(token: EarthEngineToken, refresh: RefreshToken): Promise<void> {
|
|
50
|
-
const tokenType = "Bearer";
|
|
51
|
-
|
|
52
|
-
function refreshToken(authArgs: { scope: any }, callback: (props: any) => void) {
|
|
53
|
-
refresh().then(({token}: { token: EarthEngineToken }) => {
|
|
54
|
-
callback({
|
|
55
|
-
...token,
|
|
56
|
-
token_type: tokenType ?? "Bearer",
|
|
57
|
-
state: authArgs?.scope,
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
await new Promise((resolve, reject) => {
|
|
63
|
-
if (ee.data.getAuthToken()) {
|
|
64
|
-
ee.initialize(null, null, resolve, reject);
|
|
65
|
-
}
|
|
66
|
-
if (token) {
|
|
67
|
-
const {access_token, client_id, expires_in} = token;
|
|
68
|
-
ee.data.setAuthToken(
|
|
69
|
-
client_id,
|
|
70
|
-
tokenType ?? "Bearer",
|
|
71
|
-
access_token,
|
|
72
|
-
expires_in,
|
|
73
|
-
null,
|
|
74
|
-
() => {
|
|
75
|
-
ee.initialize(null, null, resolve, reject);
|
|
76
|
-
},
|
|
77
|
-
false
|
|
78
|
-
);
|
|
79
|
-
ee.data.setAuthTokenRefresher(refreshToken);
|
|
80
|
-
}
|
|
81
|
-
resolve("Token not found");
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
setOrgUnits(orgUnits: MapOrgUnit[]): EarthEngine {
|
|
86
|
-
this.orgUnits = orgUnits;
|
|
87
|
-
return this;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
setPeriod(period: string) {
|
|
91
|
-
this.period = period;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async getValue(geoJSON: any, type: string) {
|
|
95
|
-
return new Promise((resolve, reject) => {
|
|
96
|
-
const point = this.getGeometryByType(geoJSON);
|
|
97
|
-
const reducer = this.getReducerByType(type);
|
|
98
|
-
const image = this.getImage();
|
|
99
|
-
|
|
100
|
-
const reducedImage = image.reduceRegion(reducer, point, 1);
|
|
101
|
-
|
|
102
|
-
reducedImage.evaluate((data: unknown, error: any) => {
|
|
103
|
-
if (error) {
|
|
104
|
-
reject(error);
|
|
105
|
-
} else {
|
|
106
|
-
resolve(data);
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
async getPeriod() {
|
|
113
|
-
const {type} = this.options;
|
|
114
|
-
if (type !== "ImageCollection") {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const imageCollection = this.instance.distinct("system:time_start").sort("system:time_start", false);
|
|
119
|
-
const featureCollection = ee.FeatureCollection(imageCollection).select(["system:time_start", "system:time_end"], null, false);
|
|
120
|
-
|
|
121
|
-
return getInfo(featureCollection);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
async info() {
|
|
125
|
-
return new Promise((resolve) => {
|
|
126
|
-
this.instance.getInfo(resolve);
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async getScale() {
|
|
131
|
-
try {
|
|
132
|
-
const {type} = this.options;
|
|
133
|
-
switch (type) {
|
|
134
|
-
case "ImageCollection":
|
|
135
|
-
this.scale = await getScale(this.instance.first());
|
|
136
|
-
break;
|
|
137
|
-
default:
|
|
138
|
-
this.scale = await getScale(this.getImage());
|
|
139
|
-
}
|
|
140
|
-
} catch (e) {
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
async getFeatureCollectionAggregation() {
|
|
145
|
-
const {datasetId} = this.options;
|
|
146
|
-
const dataset = ee.FeatureCollection(datasetId);
|
|
147
|
-
const collection = this.getFeatureCollection() as any;
|
|
148
|
-
const aggFeatures = collection
|
|
149
|
-
?.map((feature: any) => {
|
|
150
|
-
feature = ee.Feature(feature);
|
|
151
|
-
const count = dataset.filterBounds(feature.geometry()).size();
|
|
152
|
-
|
|
153
|
-
return feature.set("count", count);
|
|
154
|
-
})
|
|
155
|
-
.select(["count"], null, false);
|
|
156
|
-
|
|
157
|
-
return getInfo(aggFeatures).then(getFeatureCollectionProperties);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
async getHistogramAggregations() {
|
|
161
|
-
try {
|
|
162
|
-
const aggregation = head(this.options.aggregations) ?? "";
|
|
163
|
-
const reducer = ee.Reducer.frequencyHistogram();
|
|
164
|
-
const collection = this.getFeatureCollection();
|
|
165
|
-
const legend = this.options.legend?.items;
|
|
166
|
-
const scale = this.scale;
|
|
167
|
-
const tileScale = this.options.tileScale ?? DEFAULT_TILE_SCALE;
|
|
168
|
-
const scaleValue = await getInfo(scale);
|
|
169
|
-
|
|
170
|
-
const image = this.getImage();
|
|
171
|
-
const features = Object.values(
|
|
172
|
-
await getInfo(
|
|
173
|
-
image
|
|
174
|
-
.reduceRegions({
|
|
175
|
-
collection,
|
|
176
|
-
reducer,
|
|
177
|
-
scale,
|
|
178
|
-
tileScale,
|
|
179
|
-
})
|
|
180
|
-
.select(["histogram"], null, false)
|
|
181
|
-
).then((data) =>
|
|
182
|
-
getHistogramStatistics({
|
|
183
|
-
data,
|
|
184
|
-
scale: scaleValue,
|
|
185
|
-
aggregationType: aggregation,
|
|
186
|
-
legend,
|
|
187
|
-
})
|
|
188
|
-
)
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
return features.map((feature: any, index: number) => {
|
|
192
|
-
return {
|
|
193
|
-
orgUnit: this.orgUnits?.[index],
|
|
194
|
-
data: feature,
|
|
195
|
-
};
|
|
196
|
-
});
|
|
197
|
-
} catch (e: any) {
|
|
198
|
-
throw Error("Could not get histogram", {
|
|
199
|
-
cause: e,
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
async getAggregations() {
|
|
205
|
-
await this.getScale();
|
|
206
|
-
const {type} = this.options;
|
|
207
|
-
if (type === "FeatureCollection") {
|
|
208
|
-
this.aggregationData = await this.getFeatureCollectionAggregation();
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
const aggregations = this.options.aggregations;
|
|
212
|
-
if (!aggregations) return;
|
|
213
|
-
|
|
214
|
-
if (hasClasses(head(aggregations) ?? "")) {
|
|
215
|
-
this.aggregationData = await this.getHistogramAggregations();
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const reducer = combineReducers(ee)(aggregations);
|
|
220
|
-
const collection = this.getFeatureCollection();
|
|
221
|
-
const image = this.getImage();
|
|
222
|
-
const scale = this.scale;
|
|
223
|
-
const tileScale = this.options.tileScale ?? DEFAULT_TILE_SCALE;
|
|
224
|
-
const aggregatedFeatures = image
|
|
225
|
-
.reduceRegions({
|
|
226
|
-
collection,
|
|
227
|
-
reducer,
|
|
228
|
-
scale,
|
|
229
|
-
tileScale,
|
|
230
|
-
})
|
|
231
|
-
.select(aggregations, null, false);
|
|
232
|
-
|
|
233
|
-
const features = Object.values(getFeatureCollectionProperties(await getInfo(aggregatedFeatures))) as any[];
|
|
234
|
-
if (!isEmpty(features) && features.length === this.orgUnits?.length) {
|
|
235
|
-
//Mapping features to orgUnits using index.
|
|
236
|
-
this.aggregationData = features.map((feature: any, index: number) => {
|
|
237
|
-
return {
|
|
238
|
-
orgUnit: this.orgUnits?.[index],
|
|
239
|
-
data: feature,
|
|
240
|
-
};
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
getAggregation(orgUnit: MapOrgUnit) {
|
|
246
|
-
if (isEmpty(this.aggregationData)) {
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
return find(this.aggregationData, (aggregation) => aggregation.orgUnit.id === orgUnit.id);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
async url(): Promise<string> {
|
|
253
|
-
if (!this.initialized) throw "You need to call init() first";
|
|
254
|
-
return this.visualize(this.getImage());
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
protected applyPeriod(imageCollection: any) {
|
|
258
|
-
const period = this.period;
|
|
259
|
-
if (period) {
|
|
260
|
-
return imageCollection.filterDate(period);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
protected applyMask(image: any) {
|
|
265
|
-
if (this.options.mask) {
|
|
266
|
-
return image.updateMask(image.gt(0));
|
|
267
|
-
} else {
|
|
268
|
-
return image;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
protected applyBand(imageCollection: any) {
|
|
273
|
-
if (this.options.selectedBands) {
|
|
274
|
-
return imageCollection.select(this.options.selectedBands);
|
|
275
|
-
} else {
|
|
276
|
-
return imageCollection;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
protected getReducerByType(type: string) {
|
|
281
|
-
return ee.Reducer[type].call();
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
protected getGeometryByType(geoJSON: any) {
|
|
285
|
-
return ee.Geometry(geoJSON?.geometry);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
protected getFeatureByType(geoJSON: any) {
|
|
289
|
-
const featureType = geoJSON.type;
|
|
290
|
-
const features = geoJSON.features ?? [];
|
|
291
|
-
const geometry = this.getGeometryByType(geoJSON);
|
|
292
|
-
switch (featureType) {
|
|
293
|
-
case "Feature":
|
|
294
|
-
return ee.Feature(geometry);
|
|
295
|
-
case "FeatureCollection":
|
|
296
|
-
return ee.FeatureCollection([...features.map((feature: any) => ee.Feature(this.getGeometryByType(feature)))]);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
protected getFeatureCollection(): unknown {
|
|
301
|
-
if (this.orgUnits) {
|
|
302
|
-
return ee.FeatureCollection(this.orgUnits.map((orgUnit: MapOrgUnit) => this.getFeatureByType(orgUnit.geoJSON)));
|
|
303
|
-
} else {
|
|
304
|
-
throw "You need to set org units first";
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
protected getParamsFromLegend() {
|
|
309
|
-
if (!this.options.legend) return;
|
|
310
|
-
const legend = this.options.legend.items;
|
|
311
|
-
const keys = legend.map((l) => l.id);
|
|
312
|
-
const min = Math.min(...keys);
|
|
313
|
-
const max = Math.max(...keys);
|
|
314
|
-
const palette = legend.map((l) => l.color).join(",");
|
|
315
|
-
return {min, max, palette};
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
protected async visualize(image: any): Promise<string> {
|
|
319
|
-
const {min, max, palette} = this.getParamsFromLegend() ??
|
|
320
|
-
this.options.params ?? {
|
|
321
|
-
min: null,
|
|
322
|
-
max: null,
|
|
323
|
-
palette: null,
|
|
324
|
-
};
|
|
325
|
-
return (
|
|
326
|
-
(await new Promise((resolve, reject) => {
|
|
327
|
-
image.getMap({min, max, palette}, resolve);
|
|
328
|
-
})) as any
|
|
329
|
-
)?.urlFormat;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
protected getImageCollectionInstance() {
|
|
333
|
-
const {datasetId} = this.options;
|
|
334
|
-
let imageCollection = ee.ImageCollection(datasetId);
|
|
335
|
-
if (this.period) {
|
|
336
|
-
imageCollection = this.applyPeriod(imageCollection);
|
|
337
|
-
}
|
|
338
|
-
imageCollection = this.applyBand(imageCollection);
|
|
339
|
-
return imageCollection;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
protected getImageFromImageCollection() {
|
|
343
|
-
const {mosaic} = this.options;
|
|
344
|
-
const imageCollection = this.instance;
|
|
345
|
-
return mosaic
|
|
346
|
-
? imageCollection.mosaic().clipToCollection(this.getFeatureCollection())
|
|
347
|
-
: ee.Image(imageCollection.first()).clipToCollection(this.getFeatureCollection());
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
protected getImageInstance() {
|
|
351
|
-
const {datasetId} = this.options;
|
|
352
|
-
return ee.Image(datasetId).clipToCollection(this.getFeatureCollection());
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
protected getImageFromImage() {
|
|
356
|
-
return this.instance;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
protected getFeatureInstance() {
|
|
360
|
-
const {datasetId} = this.options;
|
|
361
|
-
const feature = ee.Feature(datasetId);
|
|
362
|
-
this.instance = feature;
|
|
363
|
-
return feature;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
protected getImageFromFeature() {
|
|
367
|
-
return this.instance;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
protected getFeatureCollectionInstance() {
|
|
371
|
-
const {datasetId} = this.options;
|
|
372
|
-
let featureCollection = ee.FeatureCollection(datasetId);
|
|
373
|
-
if (this.period) {
|
|
374
|
-
featureCollection = this.applyPeriod(featureCollection);
|
|
375
|
-
}
|
|
376
|
-
return featureCollection;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
protected getImageFromFeatureCollection() {
|
|
380
|
-
let featureCollection = this.instance;
|
|
381
|
-
return featureCollection.draw(FEATURE_STYLE).clipToCollection(this.getFeatureCollection());
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
protected getInstance() {
|
|
385
|
-
const {type} = this.options;
|
|
386
|
-
switch (type) {
|
|
387
|
-
case "Feature":
|
|
388
|
-
this.instance = this.getFeatureInstance();
|
|
389
|
-
break;
|
|
390
|
-
case "FeatureCollection":
|
|
391
|
-
this.instance = this.getFeatureCollectionInstance();
|
|
392
|
-
break;
|
|
393
|
-
case "Image":
|
|
394
|
-
this.instance = this.getImageInstance();
|
|
395
|
-
break;
|
|
396
|
-
case "ImageCollection":
|
|
397
|
-
this.instance = this.getImageCollectionInstance();
|
|
398
|
-
break;
|
|
399
|
-
default:
|
|
400
|
-
this.instance = this.getImageFromImage();
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
protected getImage(): any {
|
|
405
|
-
if (this.image) {
|
|
406
|
-
return this.image;
|
|
407
|
-
}
|
|
408
|
-
const {type} = this.options;
|
|
409
|
-
let image;
|
|
410
|
-
switch (type) {
|
|
411
|
-
case "Feature":
|
|
412
|
-
image = this.getImageFromFeature();
|
|
413
|
-
break;
|
|
414
|
-
case "FeatureCollection":
|
|
415
|
-
image = this.getImageFromFeatureCollection();
|
|
416
|
-
break;
|
|
417
|
-
case "Image":
|
|
418
|
-
image = this.getImageFromImage();
|
|
419
|
-
break;
|
|
420
|
-
case "ImageCollection":
|
|
421
|
-
image = this.getImageFromImageCollection();
|
|
422
|
-
break;
|
|
423
|
-
default:
|
|
424
|
-
image = this.getImageFromImage();
|
|
425
|
-
}
|
|
426
|
-
image = this.applyMask(image);
|
|
427
|
-
image = this.applyBand(image);
|
|
428
|
-
this.image = image;
|
|
429
|
-
return image;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import {EarthEngineOptions} from "../interfaces";
|
|
2
|
-
|
|
3
|
-
export const combineReducers = (ee: any) => (types: string[]) =>
|
|
4
|
-
types.reduce(
|
|
5
|
-
(r: any, t: any, i: any) =>
|
|
6
|
-
i === 0
|
|
7
|
-
? r[t]()
|
|
8
|
-
: r.combine({
|
|
9
|
-
reducer2: ee.Reducer[t](),
|
|
10
|
-
sharedInputs: true,
|
|
11
|
-
}),
|
|
12
|
-
ee.Reducer
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
export const getInfo = (instance: any) =>
|
|
16
|
-
new Promise((resolve, reject) =>
|
|
17
|
-
instance.evaluate((data: any, error: Error) => {
|
|
18
|
-
if (error) {
|
|
19
|
-
reject(error);
|
|
20
|
-
} else {
|
|
21
|
-
resolve(data);
|
|
22
|
-
}
|
|
23
|
-
})
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
export const getFeatureCollectionProperties = (data: any) =>
|
|
27
|
-
data.features.reduce(
|
|
28
|
-
(obj: any, f: any) => ({
|
|
29
|
-
...obj,
|
|
30
|
-
[f.id]: f.properties,
|
|
31
|
-
}),
|
|
32
|
-
{}
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
export const getScale = async (image: any) => {
|
|
36
|
-
return image.select(0).projection().nominalScale();
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const getParamsFromLegend = (legend: any[]) => {
|
|
40
|
-
const keys = legend.map((l) => l.id);
|
|
41
|
-
const min = Math.min(...keys);
|
|
42
|
-
const max = Math.max(...keys);
|
|
43
|
-
const palette = legend.map((l) => l.color).join(",");
|
|
44
|
-
|
|
45
|
-
return { min, max, palette };
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export const getClassifiedImage = (eeImage: any, { legend: legends, params }: EarthEngineOptions) => {
|
|
49
|
-
const legend = legends?.items ?? [];
|
|
50
|
-
if (!params) {
|
|
51
|
-
// Image has classes (e.g. landcover)
|
|
52
|
-
return { eeImage, params: getParamsFromLegend(legend) };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const min = 0;
|
|
56
|
-
const max = legend.length - 1;
|
|
57
|
-
const { palette } = params;
|
|
58
|
-
let zones;
|
|
59
|
-
|
|
60
|
-
for (let i = min, item; i < max; i++) {
|
|
61
|
-
item = legend[i] as any;
|
|
62
|
-
|
|
63
|
-
if (!zones) {
|
|
64
|
-
zones = eeImage.gt(item.to);
|
|
65
|
-
} else {
|
|
66
|
-
zones = zones.add(eeImage.gt(item.to));
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return { eeImage: zones, params: { min, max, palette } };
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
const squareMetersToHectares = (value: number) => value / 10000;
|
|
74
|
-
|
|
75
|
-
const squareMetersToAcres = (value: number) => value / 4046.8564224;
|
|
76
|
-
|
|
77
|
-
const classAggregation = ["percentage", "hectares", "acres"];
|
|
78
|
-
|
|
79
|
-
export const hasClasses = (type: string) => classAggregation.includes(type);
|
|
80
|
-
|
|
81
|
-
export const getHistogramStatistics = ({ data, scale, aggregationType, legend }: { data: any; scale: any; aggregationType: string; legend: any }) =>
|
|
82
|
-
data.features.reduce((obj: Record<any, any>, { id, properties }: { id: string; properties: any }) => {
|
|
83
|
-
const { histogram } = properties;
|
|
84
|
-
const sum: number = Object.values(histogram).reduce((a: any, b: any) => a + b, 0) as number;
|
|
85
|
-
obj[id] = legend.reduce((values: any, { id }: { id: string }) => {
|
|
86
|
-
const count = histogram[id] || 0;
|
|
87
|
-
const sqMeters = count * (scale * scale);
|
|
88
|
-
let value;
|
|
89
|
-
switch (aggregationType) {
|
|
90
|
-
case "hectares":
|
|
91
|
-
value = Math.round(squareMetersToHectares(sqMeters));
|
|
92
|
-
break;
|
|
93
|
-
case "acres":
|
|
94
|
-
value = Math.round(squareMetersToAcres(sqMeters));
|
|
95
|
-
break;
|
|
96
|
-
default:
|
|
97
|
-
value = (count / sum) * 100; // percentage
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
values[id] = value;
|
|
101
|
-
|
|
102
|
-
return values;
|
|
103
|
-
}, {});
|
|
104
|
-
return obj;
|
|
105
|
-
}, {});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import {IconLaunch16} from "@dhis2/ui";
|
|
2
|
-
import React from "react";
|
|
3
|
-
|
|
4
|
-
export default function LegendCardHeader({ title, collapsible, onCollapse }: { title: string; onCollapse?: () => void; collapsible?: boolean }) {
|
|
5
|
-
return (
|
|
6
|
-
<div className="row w-100 space-between align-items-center">
|
|
7
|
-
<h4 style={{ margin: 0 }} className="legend-header">
|
|
8
|
-
{title}
|
|
9
|
-
</h4>
|
|
10
|
-
{collapsible && (
|
|
11
|
-
<div onClick={onCollapse}>
|
|
12
|
-
<IconLaunch16 />
|
|
13
|
-
</div>
|
|
14
|
-
)}
|
|
15
|
-
</div>
|
|
16
|
-
);
|
|
17
|
-
}
|