@hisptz/dhis2-analytics 1.0.3 → 1.0.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hisptz/dhis2-analytics",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "",
5
5
  "license": "BSD-3-Clause",
6
6
  "scripts": {
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@dhis2/app-runtime": "^3.7.0",
29
- "@hisptz/dhis2-ui": "^1.0.3",
29
+ "@hisptz/dhis2-ui": "^1.0.5",
30
30
  "async-es": "^3.2.4",
31
31
  "d3-color": "^3.1.0",
32
32
  "d3-scale": "^4.0.2",
@@ -53,5 +53,5 @@
53
53
  "lodash": "^4",
54
54
  "react-hook-form": "^7"
55
55
  },
56
- "gitHead": "50b98666a43a40712a02735f5c19ec69eb8bbce4"
56
+ "gitHead": "4a3654c90bffc9cab1bd764d68ef107033ec47f6"
57
57
  }
@@ -1,423 +1,431 @@
1
1
  import {MapOrgUnit} from "../../../../../interfaces";
2
- // @ts-ignore
3
- import EE from "./api";
4
- // import EE from "@google/earthengine";
5
2
  import {EarthEngineOptions, EarthEngineToken, RefreshToken} from "../interfaces";
6
3
  import {
7
- combineReducers,
8
- getFeatureCollectionProperties,
9
- getHistogramStatistics,
10
- getInfo,
11
- getScale,
12
- hasClasses
4
+ combineReducers,
5
+ getFeatureCollectionProperties,
6
+ getHistogramStatistics,
7
+ getInfo,
8
+ getScale,
9
+ hasClasses
13
10
  } from "../utils";
14
11
  import {find, head, isEmpty} from "lodash";
15
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
+
21
+ const EE = await importEEModule();
22
+
16
23
  // @ts-ignore
17
24
  const ee = EE as any;
18
25
  // @ts-ignore
19
26
  window.ee = ee;
20
27
 
21
- const FEATURE_STYLE = { color: "FFA500", strokeWidth: 2 };
28
+ const FEATURE_STYLE = {color: "FFA500", strokeWidth: 2};
22
29
  const DEFAULT_TILE_SCALE = 1;
23
30
 
24
31
  export class EarthEngine {
25
- token?: EarthEngineToken;
26
- options: EarthEngineOptions;
27
- refresh?: RefreshToken;
28
- orgUnits?: MapOrgUnit[];
29
- initialized = false;
30
- period?: string | string[];
31
- instance: any;
32
- scale?: any;
33
- image: any;
34
- aggregationData: any;
35
-
36
- constructor({ options }: { options: EarthEngineOptions }) {
37
- this.options = options;
38
- this.initialized = true;
39
- this.getInstance();
40
- }
41
-
42
- static async setToken(token: EarthEngineToken, refresh: RefreshToken): Promise<void> {
43
- const tokenType = "Bearer";
44
-
45
- function refreshToken(authArgs: { scope: any }, callback: (props: any) => void) {
46
- refresh().then(({ token }: { token: EarthEngineToken }) => {
47
- callback({
48
- ...token,
49
- token_type: tokenType ?? "Bearer",
50
- state: authArgs?.scope,
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");
51
82
  });
52
- });
53
- }
54
-
55
- await new Promise((resolve, reject) => {
56
- if (ee.data.getAuthToken()) {
57
- ee.initialize(null, null, resolve, reject);
58
- }
59
- if (token) {
60
- const { access_token, client_id, expires_in } = token;
61
- ee.data.setAuthToken(
62
- client_id,
63
- tokenType ?? "Bearer",
64
- access_token,
65
- expires_in,
66
- null,
67
- () => {
68
- ee.initialize(null, null, resolve, reject);
69
- },
70
- false
71
- );
72
- ee.data.setAuthTokenRefresher(refreshToken);
73
- }
74
- resolve("Token not found");
75
- });
76
- }
77
-
78
- setOrgUnits(orgUnits: MapOrgUnit[]): EarthEngine {
79
- this.orgUnits = orgUnits;
80
- return this;
81
- }
82
-
83
- setPeriod(period: string) {
84
- this.period = period;
85
- }
86
-
87
- async getValue(geoJSON: any, type: string) {
88
- return new Promise((resolve, reject) => {
89
- const point = this.getGeometryByType(geoJSON);
90
- const reducer = this.getReducerByType(type);
91
- const image = this.getImage();
92
-
93
- const reducedImage = image.reduceRegion(reducer, point, 1);
94
-
95
- reducedImage.evaluate((data: unknown, error: any) => {
96
- if (error) {
97
- reject(error);
98
- } else {
99
- resolve(data);
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;
100
210
  }
101
- });
102
- });
103
- }
104
-
105
- async getPeriod() {
106
- const { type } = this.options;
107
- if (type !== "ImageCollection") {
108
- return;
109
- }
110
-
111
- const imageCollection = this.instance.distinct("system:time_start").sort("system:time_start", false);
112
- const featureCollection = ee.FeatureCollection(imageCollection).select(["system:time_start", "system:time_end"], null, false);
113
-
114
- return getInfo(featureCollection);
115
- }
116
-
117
- async info() {
118
- return new Promise((resolve) => {
119
- this.instance.getInfo(resolve);
120
- });
121
- }
122
-
123
- async getScale() {
124
- try {
125
- const { type } = this.options;
126
- switch (type) {
127
- case "ImageCollection":
128
- this.scale = await getScale(this.instance.first());
129
- break;
130
- default:
131
- this.scale = await getScale(this.getImage());
132
- }
133
- } catch (e) {}
134
- }
135
-
136
- async getFeatureCollectionAggregation() {
137
- const { datasetId } = this.options;
138
- const dataset = ee.FeatureCollection(datasetId);
139
- const collection = this.getFeatureCollection() as any;
140
- const aggFeatures = collection
141
- ?.map((feature: any) => {
142
- feature = ee.Feature(feature);
143
- const count = dataset.filterBounds(feature.geometry()).size();
144
-
145
- return feature.set("count", count);
146
- })
147
- .select(["count"], null, false);
148
-
149
- return getInfo(aggFeatures).then(getFeatureCollectionProperties);
150
- }
151
-
152
- async getHistogramAggregations() {
153
- try {
154
- const aggregation = head(this.options.aggregations) ?? "";
155
- const reducer = ee.Reducer.frequencyHistogram();
156
- const collection = this.getFeatureCollection();
157
- const legend = this.options.legend?.items;
158
- const scale = this.scale;
159
- const tileScale = this.options.tileScale ?? DEFAULT_TILE_SCALE;
160
- const scaleValue = await getInfo(scale);
161
-
162
- const image = this.getImage();
163
- const features = Object.values(
164
- await getInfo(
165
- image
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
166
225
  .reduceRegions({
167
- collection,
168
- reducer,
169
- scale,
170
- tileScale,
226
+ collection,
227
+ reducer,
228
+ scale,
229
+ tileScale,
171
230
  })
172
- .select(["histogram"], null, false)
173
- ).then((data) =>
174
- getHistogramStatistics({
175
- data,
176
- scale: scaleValue,
177
- aggregationType: aggregation,
178
- legend,
179
- })
180
- )
181
- );
182
-
183
- return features.map((feature: any, index: number) => {
184
- return {
185
- orgUnit: this.orgUnits?.[index],
186
- data: feature,
187
- };
188
- });
189
- } catch (e: any) {
190
- throw Error("Could not get histogram", {
191
- cause: e,
192
- });
193
- }
194
- }
195
-
196
- async getAggregations() {
197
- await this.getScale();
198
- const { type } = this.options;
199
- if (type === "FeatureCollection") {
200
- this.aggregationData = await this.getFeatureCollectionAggregation();
201
- return;
202
- }
203
- const aggregations = this.options.aggregations;
204
- if (!aggregations) return;
205
-
206
- if (hasClasses(head(aggregations) ?? "")) {
207
- this.aggregationData = await this.getHistogramAggregations();
208
- return;
209
- }
210
-
211
- const reducer = combineReducers(ee)(aggregations);
212
- const collection = this.getFeatureCollection();
213
- const image = this.getImage();
214
- const scale = this.scale;
215
- const tileScale = this.options.tileScale ?? DEFAULT_TILE_SCALE;
216
- const aggregatedFeatures = image
217
- .reduceRegions({
218
- collection,
219
- reducer,
220
- scale,
221
- tileScale,
222
- })
223
- .select(aggregations, null, false);
224
-
225
- const features = Object.values(getFeatureCollectionProperties(await getInfo(aggregatedFeatures))) as any[];
226
- if (!isEmpty(features) && features.length === this.orgUnits?.length) {
227
- //Mapping features to orgUnits using index.
228
- this.aggregationData = features.map((feature: any, index: number) => {
229
- return {
230
- orgUnit: this.orgUnits?.[index],
231
- data: feature,
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,
232
324
  };
233
- });
234
- }
235
- }
236
-
237
- getAggregation(orgUnit: MapOrgUnit) {
238
- if (isEmpty(this.aggregationData)) {
239
- return;
240
- }
241
- return find(this.aggregationData, (aggregation) => aggregation.orgUnit.id === orgUnit.id);
242
- }
243
-
244
- async url(): Promise<string> {
245
- if (!this.initialized) throw "You need to call init() first";
246
- return this.visualize(this.getImage());
247
- }
248
-
249
- protected applyPeriod(imageCollection: any) {
250
- const period = this.period;
251
- if (period) {
252
- return imageCollection.filterDate(period);
253
- }
254
- }
255
-
256
- protected applyMask(image: any) {
257
- if (this.options.mask) {
258
- return image.updateMask(image.gt(0));
259
- } else {
260
- return image;
261
- }
262
- }
263
-
264
- protected applyBand(imageCollection: any) {
265
- if (this.options.selectedBands) {
266
- return imageCollection.select(this.options.selectedBands);
267
- } else {
268
- return imageCollection;
269
- }
270
- }
271
-
272
- protected getReducerByType(type: string) {
273
- return ee.Reducer[type].call();
274
- }
275
-
276
- protected getGeometryByType(geoJSON: any) {
277
- return ee.Geometry(geoJSON?.geometry);
278
- }
279
-
280
- protected getFeatureByType(geoJSON: any) {
281
- const featureType = geoJSON.type;
282
- const features = geoJSON.features ?? [];
283
- const geometry = this.getGeometryByType(geoJSON);
284
- switch (featureType) {
285
- case "Feature":
286
- return ee.Feature(geometry);
287
- case "FeatureCollection":
288
- return ee.FeatureCollection([...features.map((feature: any) => ee.Feature(this.getGeometryByType(feature)))]);
289
- }
290
- }
291
-
292
- protected getFeatureCollection(): unknown {
293
- if (this.orgUnits) {
294
- return ee.FeatureCollection(this.orgUnits.map((orgUnit: MapOrgUnit) => this.getFeatureByType(orgUnit.geoJSON)));
295
- } else {
296
- throw "You need to set org units first";
297
- }
298
- }
299
-
300
- protected getParamsFromLegend() {
301
- if (!this.options.legend) return;
302
- const legend = this.options.legend.items;
303
- const keys = legend.map((l) => l.id);
304
- const min = Math.min(...keys);
305
- const max = Math.max(...keys);
306
- const palette = legend.map((l) => l.color).join(",");
307
- return { min, max, palette };
308
- }
309
-
310
- protected async visualize(image: any): Promise<string> {
311
- const { min, max, palette } = this.getParamsFromLegend() ??
312
- this.options.params ?? {
313
- min: null,
314
- max: null,
315
- palette: null,
316
- };
317
- return (
318
- (await new Promise((resolve, reject) => {
319
- image.getMap({ min, max, palette }, resolve);
320
- })) as any
321
- )?.urlFormat;
322
- }
323
-
324
- protected getImageCollectionInstance() {
325
- const { datasetId } = this.options;
326
- let imageCollection = ee.ImageCollection(datasetId);
327
- if (this.period) {
328
- imageCollection = this.applyPeriod(imageCollection);
329
- }
330
- imageCollection = this.applyBand(imageCollection);
331
- return imageCollection;
332
- }
333
-
334
- protected getImageFromImageCollection() {
335
- const { mosaic } = this.options;
336
- const imageCollection = this.instance;
337
- return mosaic
338
- ? imageCollection.mosaic().clipToCollection(this.getFeatureCollection())
339
- : ee.Image(imageCollection.first()).clipToCollection(this.getFeatureCollection());
340
- }
341
-
342
- protected getImageInstance() {
343
- const { datasetId } = this.options;
344
- return ee.Image(datasetId).clipToCollection(this.getFeatureCollection());
345
- }
346
-
347
- protected getImageFromImage() {
348
- return this.instance;
349
- }
350
-
351
- protected getFeatureInstance() {
352
- const { datasetId } = this.options;
353
- const feature = ee.Feature(datasetId);
354
- this.instance = feature;
355
- return feature;
356
- }
357
-
358
- protected getImageFromFeature() {
359
- return this.instance;
360
- }
361
-
362
- protected getFeatureCollectionInstance() {
363
- const { datasetId } = this.options;
364
- let featureCollection = ee.FeatureCollection(datasetId);
365
- if (this.period) {
366
- featureCollection = this.applyPeriod(featureCollection);
367
- }
368
- return featureCollection;
369
- }
370
-
371
- protected getImageFromFeatureCollection() {
372
- let featureCollection = this.instance;
373
- return featureCollection.draw(FEATURE_STYLE).clipToCollection(this.getFeatureCollection());
374
- }
375
-
376
- protected getInstance() {
377
- const { type } = this.options;
378
- switch (type) {
379
- case "Feature":
380
- this.instance = this.getFeatureInstance();
381
- break;
382
- case "FeatureCollection":
383
- this.instance = this.getFeatureCollectionInstance();
384
- break;
385
- case "Image":
386
- this.instance = this.getImageInstance();
387
- break;
388
- case "ImageCollection":
389
- this.instance = this.getImageCollectionInstance();
390
- break;
391
- default:
392
- this.instance = this.getImageFromImage();
393
- }
394
- }
395
-
396
- protected getImage(): any {
397
- if (this.image) {
398
- return this.image;
399
- }
400
- const { type } = this.options;
401
- let image;
402
- switch (type) {
403
- case "Feature":
404
- image = this.getImageFromFeature();
405
- break;
406
- case "FeatureCollection":
407
- image = this.getImageFromFeatureCollection();
408
- break;
409
- case "Image":
410
- image = this.getImageFromImage();
411
- break;
412
- case "ImageCollection":
413
- image = this.getImageFromImageCollection();
414
- break;
415
- default:
416
- image = this.getImageFromImage();
417
- }
418
- image = this.applyMask(image);
419
- image = this.applyBand(image);
420
- this.image = image;
421
- return image;
422
- }
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
+ }
423
431
  }
package/tsconfig.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "baseUrl": ".",
4
- "target": "es5",
4
+ "target": "es2017",
5
5
  "lib": [
6
6
  "dom",
7
7
  "dom.iterable",