@eeacms/volto-arcgis-block 0.1.477 → 0.1.479

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.
@@ -18,8 +18,10 @@ class HotspotWidget extends React.Component {
18
18
  showMapMenu: false,
19
19
  activeLayers: {},
20
20
  selectedArea: null,
21
+ referenceLcYear: null,
21
22
  lcYear: null,
22
23
  lccYear: null,
24
+ hasMultipleLcDates: false,
23
25
  activeLayersArray: [],
24
26
  };
25
27
  this.menuClass =
@@ -46,8 +48,10 @@ class HotspotWidget extends React.Component {
46
48
  this.handleApplyFilter = this.handleApplyFilter.bind(this);
47
49
  this.filteredLayersToHotspotData =
48
50
  this.filteredLayersToHotspotData.bind(this);
51
+ this.resetHotspotWidgetFilters = this.resetHotspotWidgetFilters.bind(this);
49
52
  this.mapCfg = this.props.mapCfg;
50
53
  this.selectedArea = null;
54
+ this.referenceLcYear = null;
51
55
  this.lcYear = null;
52
56
  this.lccYear = null;
53
57
  this.urls = this.props.urls;
@@ -56,6 +60,235 @@ class HotspotWidget extends React.Component {
56
60
  this._isMounted = false;
57
61
  }
58
62
 
63
+ parseKeymapInfo(rawKeymapInfo) {
64
+ if (typeof rawKeymapInfo === 'string') {
65
+ try {
66
+ return JSON.parse(rawKeymapInfo) || {};
67
+ } catch (e) {
68
+ return {};
69
+ }
70
+ }
71
+ if (rawKeymapInfo && typeof rawKeymapInfo === 'object') {
72
+ return rawKeymapInfo;
73
+ }
74
+ return {};
75
+ }
76
+
77
+ getDateOptionsForNode(node) {
78
+ const keyMapInfoObj = this.parseKeymapInfo(node?.keymap_info);
79
+ let lccDateList = [];
80
+ let lcDateList = [];
81
+ let lccDatesByLcYear = {};
82
+
83
+ if (Array.isArray(keyMapInfoObj.dates)) {
84
+ keyMapInfoObj.dates.forEach((entry) => {
85
+ const lccDate = Number(
86
+ entry && typeof entry === 'object' ? entry?.date : entry,
87
+ );
88
+ const lcDate = Number(
89
+ entry && typeof entry === 'object' ? entry?.lc_date : undefined,
90
+ );
91
+ if (Number.isFinite(lccDate)) {
92
+ lccDateList.push(lccDate);
93
+ }
94
+ if (Number.isFinite(lcDate)) {
95
+ lcDateList.push(lcDate);
96
+ if (!lccDatesByLcYear[lcDate]) {
97
+ lccDatesByLcYear[lcDate] = [];
98
+ }
99
+ if (Number.isFinite(lccDate)) {
100
+ lccDatesByLcYear[lcDate].push(lccDate);
101
+ }
102
+ }
103
+ });
104
+ }
105
+
106
+ if (Array.isArray(keyMapInfoObj.multiple_lc_dates)) {
107
+ lcDateList = lcDateList.concat(
108
+ keyMapInfoObj.multiple_lc_dates
109
+ .map((yearEntry) =>
110
+ Number(
111
+ yearEntry && typeof yearEntry === 'object'
112
+ ? yearEntry?.date
113
+ : yearEntry,
114
+ ),
115
+ )
116
+ .filter((year) => Number.isFinite(year)),
117
+ );
118
+ }
119
+
120
+ const dynamicYearValues = Object.keys(keyMapInfoObj)
121
+ .filter((key) => /^year\d+$/.test(key))
122
+ .map((key) => Number(keyMapInfoObj[key]))
123
+ .filter((year) => Number.isFinite(year));
124
+ if (dynamicYearValues.length) {
125
+ lccDateList = lccDateList.concat(dynamicYearValues);
126
+ }
127
+
128
+ const presentLcYearFromKeymap = Number(keyMapInfoObj.year_present_lc);
129
+ if (Number.isFinite(presentLcYearFromKeymap)) {
130
+ lcDateList.push(presentLcYearFromKeymap);
131
+ }
132
+
133
+ if (!lccDateList.length && Number.isFinite(Number(node?.lcc_year))) {
134
+ lccDateList = [Number(node?.lcc_year)];
135
+ }
136
+ if (!lcDateList.length && Number.isFinite(Number(node?.present_lc_year))) {
137
+ lcDateList = [Number(node?.present_lc_year)];
138
+ }
139
+
140
+ lccDateList = Array.from(new Set(lccDateList)).sort((a, b) => a - b);
141
+ lcDateList = Array.from(new Set(lcDateList)).sort((a, b) => a - b);
142
+
143
+ Object.keys(lccDatesByLcYear).forEach((lcDateKey) => {
144
+ lccDatesByLcYear[lcDateKey] = Array.from(
145
+ new Set(lccDatesByLcYear[lcDateKey]),
146
+ ).sort((a, b) => a - b);
147
+ });
148
+
149
+ return {
150
+ keyMapInfoObj,
151
+ lccDateList,
152
+ lcDateList,
153
+ lccDatesByLcYear,
154
+ };
155
+ }
156
+
157
+ getSelectedNodeByArea(selectedArea) {
158
+ if (!selectedArea || !Array.isArray(this.dataJSONNames)) {
159
+ return null;
160
+ }
161
+
162
+ return this.dataJSONNames.find(
163
+ (entry) => entry?.node?.klc_name === selectedArea,
164
+ )?.node;
165
+ }
166
+
167
+ isReferenceSelectionKlcCode(klcCode) {
168
+ return klcCode === 'CAF_02' || klcCode === 'CAF_05';
169
+ }
170
+
171
+ getReferenceLcYearSelection(lcDateList) {
172
+ const selectedReferenceLcYear = Number(this.state.referenceLcYear);
173
+ if (
174
+ Number.isFinite(selectedReferenceLcYear) &&
175
+ lcDateList.includes(selectedReferenceLcYear)
176
+ ) {
177
+ return selectedReferenceLcYear;
178
+ }
179
+ return null;
180
+ }
181
+
182
+ setPresentLandCoverVisibility(shouldShow) {
183
+ const presentLandCoverContainer = this.container.current?.querySelector(
184
+ '.presentLandCoverContainer',
185
+ );
186
+ if (presentLandCoverContainer) {
187
+ presentLandCoverContainer.style.display = shouldShow ? 'block' : 'none';
188
+ }
189
+ }
190
+
191
+ isHotspotLayerKey(layerKey) {
192
+ if (typeof layerKey !== 'string') return false;
193
+ return (
194
+ layerKey.includes('all_present_lc_') ||
195
+ layerKey.includes('all_lcc_') ||
196
+ layerKey.includes('cop_klc') ||
197
+ layerKey.includes('protected_areas') ||
198
+ layerKey.endsWith('_filter')
199
+ );
200
+ }
201
+
202
+ removeLayerFromMap(layer) {
203
+ if (!layer || !this.props.map) return;
204
+ try {
205
+ this.props.map.remove(layer);
206
+ } catch (e) {}
207
+ if (layer.visible !== undefined) {
208
+ layer.visible = false;
209
+ }
210
+ }
211
+
212
+ clearHotspotLayersFromMap() {
213
+ const layerRefs = [];
214
+ if (this.layers && typeof this.layers === 'object') {
215
+ Object.keys(this.layers).forEach((layerKey) => {
216
+ if (this.isHotspotLayerKey(layerKey) && this.layers[layerKey]) {
217
+ layerRefs.push(this.layers[layerKey]);
218
+ }
219
+ });
220
+ }
221
+
222
+ const hotspotData = this.props.hotspotData || {};
223
+ const activeLayers = hotspotData.activeLayers || {};
224
+ const filteredLayers = hotspotData.filteredLayers || {};
225
+
226
+ Object.keys(activeLayers).forEach((layerKey) => {
227
+ if (this.isHotspotLayerKey(layerKey) && activeLayers[layerKey]) {
228
+ layerRefs.push(activeLayers[layerKey]);
229
+ }
230
+ });
231
+ Object.keys(filteredLayers).forEach((layerKey) => {
232
+ if (this.isHotspotLayerKey(layerKey) && filteredLayers[layerKey]) {
233
+ layerRefs.push(filteredLayers[layerKey]);
234
+ }
235
+ });
236
+
237
+ Array.from(new Set(layerRefs)).forEach((layer) => {
238
+ this.removeLayerFromMap(layer);
239
+ });
240
+ }
241
+
242
+ resetHotspotViewState() {
243
+ if (this.props.view && this.props.view.popup) {
244
+ this.props.view.popup.close();
245
+ }
246
+ if (this.props.view && this.props.view.graphics) {
247
+ this.props.view.graphics.removeAll();
248
+ }
249
+ }
250
+
251
+ resetHotspotWidgetFilters() {
252
+ const selectBox = document.getElementById('select-klc-area');
253
+ const selectBoxLcTime = document.getElementById('select-klc-lcTime');
254
+ const selectBoxLccTime = document.getElementById('select-klc-lccTime');
255
+
256
+ if (selectBox) {
257
+ selectBox.value = 'default';
258
+ }
259
+
260
+ if (selectBoxLcTime) {
261
+ this.removeOptions(selectBoxLcTime);
262
+ selectBoxLcTime.options.add(
263
+ new Option('Select a year', 'default', true, true),
264
+ );
265
+ selectBoxLcTime.options[0].disabled = true;
266
+ }
267
+
268
+ if (selectBoxLccTime) {
269
+ this.removeOptions(selectBoxLccTime);
270
+ selectBoxLccTime.options.add(
271
+ new Option('Select a year', 'default', true, true),
272
+ );
273
+ selectBoxLccTime.options[0].disabled = true;
274
+ }
275
+
276
+ this.setPresentLandCoverVisibility(false);
277
+
278
+ this.selectedArea = null;
279
+ this.referenceLcYear = null;
280
+ this.lcYear = null;
281
+ this.lccYear = null;
282
+
283
+ this.setState({
284
+ selectedArea: null,
285
+ referenceLcYear: null,
286
+ lcYear: null,
287
+ lccYear: null,
288
+ hasMultipleLcDates: false,
289
+ });
290
+ }
291
+
59
292
  loader() {
60
293
  return loadModules([
61
294
  'esri/layers/WMSLayer',
@@ -137,80 +370,166 @@ class HotspotWidget extends React.Component {
137
370
  return legendLinkUrl + legend;
138
371
  }
139
372
 
373
+ getHotspotWmsConfig() {
374
+ return {
375
+ endpoint:
376
+ this.urls.hotspotWmsEndpoint ||
377
+ 'https://geospatial.jrc.ec.europa.eu/geoserver/hsm/wms',
378
+ version: this.urls.hotspotWmsVersion || '1.1.0',
379
+ srs: this.urls.hotspotWmsSrs || 'EPSG:3857',
380
+ layerNames: this.urls.hotspotWmsLayerNames || {
381
+ lcc: {
382
+ a: 'hsm:lcc_a_pols',
383
+ b: 'hsm:lcc_b_pols',
384
+ },
385
+ lc: {
386
+ a: 'hsm:present_lc_a_pols',
387
+ b: 'hsm:present_lc_b_pols',
388
+ },
389
+ klc: 'hsm:cop_klc',
390
+ pa: 'hsm:protected_areas',
391
+ },
392
+ };
393
+ }
394
+
395
+ resolveLayerVariant(activeLayers, type) {
396
+ if (!Array.isArray(activeLayers) || !activeLayers.length) return 'b';
397
+ const hasVariantA = activeLayers.some((layer) =>
398
+ layer.includes(type === 'lcc' ? 'all_lcc_a_pol' : 'all_present_lc_a_pol'),
399
+ );
400
+ return hasVariantA ? 'a' : 'b';
401
+ }
402
+
403
+ resolveWmsLayerName(type, variant) {
404
+ const config = this.getHotspotWmsConfig();
405
+ if (type === 'lcc') {
406
+ return config.layerNames.lcc[variant] || config.layerNames.lcc.b;
407
+ }
408
+ if (type === 'lc') {
409
+ return config.layerNames.lc[variant] || config.layerNames.lc.b;
410
+ }
411
+ if (type === 'klc') {
412
+ return config.layerNames.klc;
413
+ }
414
+ if (type === 'pa') {
415
+ return config.layerNames.pa;
416
+ }
417
+ return null;
418
+ }
419
+
420
+ buildCqlFilter(klcCode, date) {
421
+ const baseFilter = "klc_code='" + klcCode + "' AND in_pa='not_defined'";
422
+ if (!Number.isFinite(Number(date))) {
423
+ return baseFilter;
424
+ }
425
+ return baseFilter + ' AND date=' + Number(date);
426
+ }
427
+
428
+ buildWmsCustomLayerParameters(cqlFilter) {
429
+ const config = this.getHotspotWmsConfig();
430
+ return {
431
+ SERVICE: 'WMS',
432
+ REQUEST: 'GetMap',
433
+ FORMAT: 'image/png',
434
+ TRANSPARENT: 'true',
435
+ tiled: 'true',
436
+ STYLES: '',
437
+ VERSION: config.version,
438
+ SRS: config.srs,
439
+ CQL_FILTER: cqlFilter,
440
+ };
441
+ }
442
+
443
+ getLccDateOptionsFromData(selectedLcYear, lccDatesByLcYear, lccDateList) {
444
+ const mappedByData = Number.isFinite(Number(selectedLcYear))
445
+ ? lccDatesByLcYear[Number(selectedLcYear)]
446
+ : null;
447
+ if (Array.isArray(mappedByData) && mappedByData.length) {
448
+ return mappedByData;
449
+ }
450
+ return lccDateList;
451
+ }
452
+
140
453
  layerModelInit() {
141
- const serviceUrl = this.urls.serviceUrl;
454
+ const serviceUrl = this.getHotspotWmsConfig().endpoint;
142
455
  this.esriLayer_lcc = new WMSLayer({
143
456
  url: serviceUrl,
457
+ version: this.getHotspotWmsConfig().version,
144
458
  title: '',
145
459
  //featureInfoFormat: "application/json",
146
- customLayerParameters: {},
460
+ customLayerParameters: this.buildWmsCustomLayerParameters(''),
147
461
  sublayers: [
148
462
  // LAND COVER CHANGE DATASET ________________________________________________________________________________________________________________
149
463
  {
150
- name: this.addLegendName('all_lcc_a_pol'),
464
+ name: this.addLegendName(this.resolveWmsLayerName('lcc', 'a')),
151
465
  legendUrl: this.addLegendNameToUrl('all_lcc_a_pol'),
152
466
  },
153
467
  ],
154
468
  });
155
469
  this.esriLayer_lcc = new WMSLayer({
156
470
  url: serviceUrl,
471
+ version: this.getHotspotWmsConfig().version,
157
472
  title: '',
158
473
  //featureInfoFormat: "application/json",
159
- customLayerParameters: {},
474
+ customLayerParameters: this.buildWmsCustomLayerParameters(''),
160
475
  sublayers: [
161
476
  // LAND COVER CHANGE DATASET ________________________________________________________________________________________________________________
162
477
  {
163
- name: this.addLegendName('all_lcc_b_pol'),
478
+ name: this.addLegendName(this.resolveWmsLayerName('lcc', 'b')),
164
479
  legendUrl: this.addLegendNameToUrl('all_lcc_b_pol'),
165
480
  },
166
481
  ],
167
482
  });
168
483
  this.esriLayer_lc = new WMSLayer({
169
484
  url: serviceUrl,
485
+ version: this.getHotspotWmsConfig().version,
170
486
  title: '',
171
487
  //featureInfoFormat: "application/json",
172
- customLayerParameters: {},
488
+ customLayerParameters: this.buildWmsCustomLayerParameters(''),
173
489
  sublayers: [
174
490
  // PRESENT LAND COVER DATASET ________________________________________________________________________________________________________________
175
491
  {
176
- name: this.addLegendName('all_present_lc_a_pol'),
492
+ name: this.addLegendName(this.resolveWmsLayerName('lc', 'a')),
177
493
  legendUrl: this.addLegendNameToUrl('all_present_lc_a_pol'),
178
494
  },
179
495
  ],
180
496
  });
181
497
  this.esriLayer_lc = new WMSLayer({
182
498
  url: serviceUrl,
499
+ version: this.getHotspotWmsConfig().version,
183
500
  title: '',
184
501
  //featureInfoFormat: "application/json",
185
- customLayerParameters: {},
502
+ customLayerParameters: this.buildWmsCustomLayerParameters(''),
186
503
  sublayers: [
187
504
  // PRESENT LAND COVER DATASET ________________________________________________________________________________________________________________
188
505
  {
189
- name: this.addLegendName('all_present_lc_b_pol'),
506
+ name: this.addLegendName(this.resolveWmsLayerName('lc', 'b')),
190
507
  legendUrl: this.addLegendNameToUrl('all_present_lc_b_pol'),
191
508
  },
192
509
  ],
193
510
  });
194
511
  this.esriLayer_klc = new WMSLayer({
195
512
  url: serviceUrl,
513
+ version: this.getHotspotWmsConfig().version,
196
514
  title: '',
197
515
  //featureInfoFormat: "application/json",
198
- customLayerParameters: {},
516
+ customLayerParameters: this.buildWmsCustomLayerParameters(''),
199
517
  sublayers: [
200
518
  {
201
- name: this.addLegendName('cop_klc'),
519
+ name: this.addLegendName(this.resolveWmsLayerName('klc')),
202
520
  legendUrl: this.addLegendNameToUrl('cop_klc'),
203
521
  },
204
522
  ],
205
523
  });
206
524
  this.esriLayer_pa = new WMSLayer({
207
525
  url: serviceUrl,
526
+ version: this.getHotspotWmsConfig().version,
208
527
  title: '',
209
528
  //featureInfoFormat: "application/json",
210
- customLayerParameters: {},
529
+ customLayerParameters: this.buildWmsCustomLayerParameters(''),
211
530
  sublayers: [
212
531
  {
213
- name: this.addLegendName('protected_areas'),
532
+ name: this.addLegendName(this.resolveWmsLayerName('pa')),
214
533
  legendUrl: this.addLegendNameToUrl('protected_areas'),
215
534
  },
216
535
  ],
@@ -246,6 +565,11 @@ class HotspotWidget extends React.Component {
246
565
  }
247
566
 
248
567
  async handleApplyFilter(typeFilter) {
568
+ await Promise.all([this.getLayerParameters(), this.getBBoxData()]);
569
+ this.clearHotspotLayersFromMap();
570
+ this.resetHotspotViewState();
571
+ this.layerModelInit();
572
+
249
573
  let typeLegend;
250
574
  let title;
251
575
  let activeLayers =
@@ -277,17 +601,12 @@ class HotspotWidget extends React.Component {
277
601
  .value.match(/\d+/g)
278
602
  .map(Number)[0];
279
603
  }
280
- for (let i = 0; activeLayers[i]; i++) {
281
- let layer = activeLayers[i];
282
- if (layer.includes('all_lcc_a_pol')) {
283
- typeLegend = 'all_lcc_a_pol';
284
- title = 'Dichotomous Land Cover Change in selected Hot Spots';
285
- break;
286
- } else {
287
- typeLegend = 'all_lcc_b_pol';
288
- title = 'Modular Land Cover Change in selected Hot Spots';
289
- }
290
- }
604
+ const layerVariant = this.resolveLayerVariant(activeLayers, 'lcc');
605
+ typeLegend = layerVariant === 'a' ? 'all_lcc_a_pol' : 'all_lcc_b_pol';
606
+ title =
607
+ layerVariant === 'a'
608
+ ? 'Dichotomous Land Cover Change in selected Hot Spots'
609
+ : 'Modular Land Cover Change in selected Hot Spots';
291
610
 
292
611
  this.addFilteredLayersData(
293
612
  filteredLayersData,
@@ -298,7 +617,9 @@ class HotspotWidget extends React.Component {
298
617
 
299
618
  filterLayer = this.esriLayer_lcc;
300
619
 
301
- filterLayer.sublayers.items[0].name = this.addLegendName(typeLegend);
620
+ filterLayer.sublayers.items[0].name = this.addLegendName(
621
+ this.resolveWmsLayerName('lcc', layerVariant),
622
+ );
302
623
  filterLayer.sublayers.items[0].legendUrl =
303
624
  this.addLegendNameToUrl(typeLegend);
304
625
  filterLayer.sublayers.items[0].title = title;
@@ -307,30 +628,27 @@ class HotspotWidget extends React.Component {
307
628
  bookmarkHotspotFilter.filteredLayers &&
308
629
  bookmarkHotspotFilter.filteredLayers['lcc_filter'] !== undefined
309
630
  ) {
310
- filterLayer.customLayerParameters['CQL_FILTER'] =
311
- bookmarkHotspotFilter.filteredLayers['lcc_filter'];
631
+ filterLayer.customLayerParameters =
632
+ this.buildWmsCustomLayerParameters(
633
+ bookmarkHotspotFilter.filteredLayers['lcc_filter'],
634
+ );
312
635
  } else {
313
- filterLayer.customLayerParameters['CQL_FILTER'] =
314
- 'klc_code LIKE ' +
315
- "'" +
316
- this.dataKlc_code +
317
- "'" +
318
- " AND in_pa = 'not_defined' AND date = " +
319
- selectBoxHighlightsLcc;
636
+ filterLayer.customLayerParameters =
637
+ this.buildWmsCustomLayerParameters(
638
+ this.buildCqlFilter(this.dataKlc_code, selectBoxHighlightsLcc),
639
+ );
320
640
  }
321
641
  }
322
642
  if (type === 'lc') {
323
- for (let i = 0; i < activeLayers.length; i++) {
324
- let layer = activeLayers[i];
325
- if (layer.includes('all_present_lc_a_pol')) {
326
- typeLegend = 'all_present_lc_a_pol';
327
- title = 'Dichotomous Present Land Cover in selected Hot Spots';
328
- break;
329
- } else {
330
- typeLegend = 'all_present_lc_b_pol';
331
- title = 'Modular Present Land Cover in selected Hot Spots';
332
- }
333
- }
643
+ const layerVariant = this.resolveLayerVariant(activeLayers, 'lc');
644
+ typeLegend =
645
+ layerVariant === 'a'
646
+ ? 'all_present_lc_a_pol'
647
+ : 'all_present_lc_b_pol';
648
+ title =
649
+ layerVariant === 'a'
650
+ ? 'Dichotomous Present Land Cover in selected Hot Spots'
651
+ : 'Modular Present Land Cover in selected Hot Spots';
334
652
 
335
653
  let selectLcBoxTime =
336
654
  document.getElementById('select-klc-lcTime').value;
@@ -353,7 +671,9 @@ class HotspotWidget extends React.Component {
353
671
 
354
672
  filterLayer = this.esriLayer_lc;
355
673
 
356
- filterLayer.sublayers.items[0].name = this.addLegendName(typeLegend);
674
+ filterLayer.sublayers.items[0].name = this.addLegendName(
675
+ this.resolveWmsLayerName('lc', layerVariant),
676
+ );
357
677
  filterLayer.sublayers.items[0].legendUrl =
358
678
  this.addLegendNameToUrl(typeLegend);
359
679
  filterLayer.sublayers.items[0].title = title;
@@ -362,16 +682,15 @@ class HotspotWidget extends React.Component {
362
682
  bookmarkHotspotFilter.filteredLayers &&
363
683
  bookmarkHotspotFilter.filteredLayers['lc_filter'] !== undefined
364
684
  ) {
365
- filterLayer.customLayerParameters['CQL_FILTER'] =
366
- bookmarkHotspotFilter.filteredLayers['lc_filter'];
685
+ filterLayer.customLayerParameters =
686
+ this.buildWmsCustomLayerParameters(
687
+ bookmarkHotspotFilter.filteredLayers['lc_filter'],
688
+ );
367
689
  } else {
368
- filterLayer.customLayerParameters['CQL_FILTER'] =
369
- 'klc_code LIKE ' +
370
- "'" +
371
- this.dataKlc_code +
372
- "'" +
373
- " AND in_pa = 'not_defined' AND date = " +
374
- selectBoxHighlightsLc;
690
+ filterLayer.customLayerParameters =
691
+ this.buildWmsCustomLayerParameters(
692
+ this.buildCqlFilter(this.dataKlc_code, selectBoxHighlightsLc),
693
+ );
375
694
  }
376
695
  }
377
696
  if (type === 'klc') {
@@ -381,13 +700,20 @@ class HotspotWidget extends React.Component {
381
700
  bookmarkHotspotFilter.filteredLayers &&
382
701
  bookmarkHotspotFilter.filteredLayers['klc_filter'] !== undefined
383
702
  ) {
384
- this.esriLayer_klc.customLayerParameters['CQL_FILTER'] =
385
- bookmarkHotspotFilter.filteredLayers['klc_filter'];
703
+ this.esriLayer_klc.customLayerParameters =
704
+ this.buildWmsCustomLayerParameters(
705
+ bookmarkHotspotFilter.filteredLayers['klc_filter'],
706
+ );
386
707
  } else {
387
- this.esriLayer_klc.customLayerParameters['CQL_FILTER'] =
388
- "klc_code LIKE '" + this.dataKlc_code + "'";
708
+ this.esriLayer_klc.customLayerParameters =
709
+ this.buildWmsCustomLayerParameters(
710
+ "klc_code='" + this.dataKlc_code + "'",
711
+ );
389
712
  }
390
713
  filterLayer = this.esriLayer_klc;
714
+ filterLayer.sublayers.items[0].name = this.addLegendName(
715
+ this.resolveWmsLayerName('klc'),
716
+ );
391
717
  filterLayer.sublayers.items[0].title = title;
392
718
  }
393
719
  if (type === 'pa') {
@@ -398,13 +724,20 @@ class HotspotWidget extends React.Component {
398
724
  bookmarkHotspotFilter.filteredLayers &&
399
725
  bookmarkHotspotFilter.filteredLayers['pa_filter'] !== undefined
400
726
  ) {
401
- this.esriLayer_pa.customLayerParameters['CQL_FILTER'] =
402
- bookmarkHotspotFilter.filteredLayers['pa_filter'];
727
+ this.esriLayer_pa.customLayerParameters =
728
+ this.buildWmsCustomLayerParameters(
729
+ bookmarkHotspotFilter.filteredLayers['pa_filter'],
730
+ );
403
731
  } else {
404
- this.esriLayer_pa.customLayerParameters['CQL_FILTER'] =
405
- "klc_code LIKE '" + this.dataKlc_code + "'";
732
+ this.esriLayer_pa.customLayerParameters =
733
+ this.buildWmsCustomLayerParameters(
734
+ "klc_code='" + this.dataKlc_code + "'",
735
+ );
406
736
  }
407
737
  filterLayer = this.esriLayer_pa;
738
+ filterLayer.sublayers.items[0].name = this.addLegendName(
739
+ this.resolveWmsLayerName('pa'),
740
+ );
408
741
  filterLayer.sublayers.items[0].title = title;
409
742
  }
410
743
  layersToAdd[type + '_filter'] = filterLayer;
@@ -416,8 +749,6 @@ class HotspotWidget extends React.Component {
416
749
  if (layerId !== undefined) this.layers[layerId].visible = false;
417
750
  let layer = this.props.map.findLayerById(layerId);
418
751
  if (layer !== undefined) {
419
- layer.clear();
420
- layer.destroy();
421
752
  this.props.map.remove(layer);
422
753
  }
423
754
  });
@@ -428,8 +759,6 @@ class HotspotWidget extends React.Component {
428
759
  if (layerId !== undefined) this.layers[layerId].visible = false;
429
760
  let layer = this.props.map.findLayerById(layerId);
430
761
  if (layer !== undefined) {
431
- layer.clear();
432
- layer.destroy();
433
762
  this.props.map.remove(layer);
434
763
  }
435
764
  });
@@ -507,6 +836,7 @@ class HotspotWidget extends React.Component {
507
836
 
508
837
  openMenu() {
509
838
  if (this.state.showMapMenu) {
839
+ this.resetHotspotWidgetFilters();
510
840
  this.props.mapViewer.setActiveWidget();
511
841
  this.container.current.querySelector('.right-panel').style.display =
512
842
  'none';
@@ -539,7 +869,7 @@ class HotspotWidget extends React.Component {
539
869
  const url =
540
870
  window.location.href.replace(window.location.pathname.substring(3), '') +
541
871
  this.props.urls.all_geo_klc;
542
- fetch(url)
872
+ return fetch(url)
543
873
  .then((data) => {
544
874
  if (data.status === 200) {
545
875
  return data.json();
@@ -559,18 +889,24 @@ class HotspotWidget extends React.Component {
559
889
  this.props.hotspotData && this.props.hotspotData['activeLayers']
560
890
  ? Object.keys(this.props.hotspotData['activeLayers'])
561
891
  : [];
892
+ const hasActivePresentLcLayer = activeLayers.some(
893
+ (layer) =>
894
+ layer.includes('all_present_lc_a_pol') ||
895
+ layer.includes('all_present_lc_b_pol') ||
896
+ layer.includes('lc_filter'),
897
+ );
898
+ const hasActiveLccLayer = activeLayers.some(
899
+ (layer) =>
900
+ layer.includes('all_lcc_a_pol') ||
901
+ layer.includes('all_lcc_b_pol') ||
902
+ layer.includes('lcc_filter'),
903
+ );
562
904
 
563
- if (
564
- this.container.current.querySelector('.presentLandCoverContainer').style
565
- .display === 'block'
566
- ) {
905
+ if (hasActivePresentLcLayer) {
567
906
  typeFilter.push('lc');
568
907
  }
569
908
 
570
- if (
571
- this.container.current.querySelector('.landCoverChangeContainer').style
572
- .display === 'block'
573
- ) {
909
+ if (hasActiveLccLayer) {
574
910
  typeFilter.push('lcc');
575
911
  }
576
912
  activeLayers.forEach((layer) => {
@@ -668,22 +1004,16 @@ class HotspotWidget extends React.Component {
668
1004
  selectBoxLccTime = document.getElementById('select-klc-lccTime');
669
1005
  selectBoxLcTime = document.getElementById('select-klc-lcTime');
670
1006
 
1007
+ let hasMultipleLcDatesForSelection = false;
1008
+ let hasSelectedAreaOption = false;
1009
+
671
1010
  //this.selectedArea = selectedOption;
672
1011
 
673
1012
  for (let i = 0; i < data.length; i++) {
674
1013
  var option = data[i].node.klc_name;
675
1014
 
676
1015
  let rawKeymapInfo = data[i].node.keymap_info;
677
- let keyMapInfoObj = {};
678
- if (typeof rawKeymapInfo === 'string') {
679
- try {
680
- keyMapInfoObj = JSON.parse(rawKeymapInfo) || {};
681
- } catch (e) {
682
- keyMapInfoObj = {};
683
- }
684
- } else if (rawKeymapInfo && typeof rawKeymapInfo === 'object') {
685
- keyMapInfoObj = rawKeymapInfo;
686
- }
1016
+ let keyMapInfoObj = this.parseKeymapInfo(rawKeymapInfo);
687
1017
 
688
1018
  if (keyMapInfoObj.b_classes === true) {
689
1019
  modularKLCAreas.push(option);
@@ -709,103 +1039,47 @@ class HotspotWidget extends React.Component {
709
1039
  selectBoxLccTime.options[0].disabled = true;
710
1040
  }
711
1041
 
712
- let lccDateList = [];
713
- let lcDateList = [];
714
- let lccDatesByLcYear = {};
715
-
716
- if (Array.isArray(keyMapInfoObj.dates)) {
717
- keyMapInfoObj.dates.forEach((entry) => {
718
- const lccDate = Number(
719
- entry && typeof entry === 'object' ? entry?.date : entry,
720
- );
721
- const lcDate = Number(
722
- entry && typeof entry === 'object' ? entry?.lc_date : undefined,
723
- );
724
- if (Number.isFinite(lccDate)) {
725
- lccDateList.push(lccDate);
726
- }
727
- if (Number.isFinite(lcDate)) {
728
- lcDateList.push(lcDate);
729
- if (!lccDatesByLcYear[lcDate]) {
730
- lccDatesByLcYear[lcDate] = [];
731
- }
732
- if (Number.isFinite(lccDate)) {
733
- lccDatesByLcYear[lcDate].push(lccDate);
734
- }
735
- }
736
- });
737
- }
738
-
739
- if (Array.isArray(keyMapInfoObj.multiple_lc_dates)) {
740
- lcDateList = lcDateList.concat(
741
- keyMapInfoObj.multiple_lc_dates
742
- .map((yearEntry) =>
743
- Number(
744
- yearEntry && typeof yearEntry === 'object'
745
- ? yearEntry?.date
746
- : yearEntry,
747
- ),
748
- )
749
- .filter((year) => Number.isFinite(year)),
750
- );
751
- }
752
-
753
- const dynamicYearValues = Object.keys(keyMapInfoObj)
754
- .filter((key) => /^year\d+$/.test(key))
755
- .map((key) => Number(keyMapInfoObj[key]))
756
- .filter((year) => Number.isFinite(year));
757
- if (dynamicYearValues.length) {
758
- lccDateList = lccDateList.concat(dynamicYearValues);
759
- }
760
-
761
- const presentLcYearFromKeymap = Number(keyMapInfoObj.year_present_lc);
762
- if (Number.isFinite(presentLcYearFromKeymap)) {
763
- lcDateList.push(presentLcYearFromKeymap);
764
- }
1042
+ const { lccDateList, lcDateList, lccDatesByLcYear } =
1043
+ this.getDateOptionsForNode(data[i].node);
765
1044
 
766
- if (
767
- !lccDateList.length &&
768
- Number.isFinite(Number(data[i].node.lcc_year))
769
- ) {
770
- lccDateList = [Number(data[i].node.lcc_year)];
771
- }
772
- if (
773
- !lcDateList.length &&
774
- Number.isFinite(Number(data[i].node.present_lc_year))
775
- ) {
776
- lcDateList = [Number(data[i].node.present_lc_year)];
777
- }
1045
+ const isReferenceSelectionArea = this.isReferenceSelectionKlcCode(
1046
+ data[i].node.klc_code,
1047
+ );
1048
+ const selectedReferenceLcYear = isReferenceSelectionArea
1049
+ ? this.getReferenceLcYearSelection(lcDateList)
1050
+ : null;
778
1051
 
779
- lccDateList = Array.from(new Set(lccDateList)).sort((a, b) => a - b);
780
- lcDateList = Array.from(new Set(lcDateList)).sort((a, b) => a - b);
1052
+ hasMultipleLcDatesForSelection = lcDateList.length > 1;
1053
+ hasSelectedAreaOption = true;
781
1054
 
782
- Object.keys(lccDatesByLcYear).forEach((lcDateKey) => {
783
- lccDatesByLcYear[lcDateKey] = Array.from(
784
- new Set(lccDatesByLcYear[lcDateKey]),
785
- ).sort((a, b) => a - b);
786
- });
1055
+ const lcDateOptionsToUse =
1056
+ isReferenceSelectionArea && Number.isFinite(selectedReferenceLcYear)
1057
+ ? [selectedReferenceLcYear]
1058
+ : isReferenceSelectionArea
1059
+ ? []
1060
+ : lcDateList;
787
1061
 
788
- lcDateList.forEach((element) => {
1062
+ lcDateOptionsToUse.forEach((element) => {
789
1063
  selectBoxLcTime.options.add(new Option(element, element, element));
790
1064
  });
791
1065
 
792
- if (this.state.lcYear !== null) {
793
- const hasLcYearOption = Array.from(selectBoxLcTime.options).some(
794
- (option) => option.value === this.state.lcYear,
795
- );
796
- selectBoxLcTime.value = hasLcYearOption
797
- ? this.state.lcYear
798
- : 'default';
799
- }
800
-
801
- const selectedLcYear = Number(this.state.lcYear);
802
- const mappedLccDateList = Number.isFinite(selectedLcYear)
803
- ? lccDatesByLcYear[selectedLcYear]
804
- : null;
805
- const lccOptionsToUse =
806
- mappedLccDateList && mappedLccDateList.length
807
- ? mappedLccDateList
808
- : lccDateList;
1066
+ const selectedLcYear =
1067
+ isReferenceSelectionArea && Number.isFinite(selectedReferenceLcYear)
1068
+ ? selectedReferenceLcYear
1069
+ : Number(selectBoxLcTime.value);
1070
+ const lccOptionsToUse = hasMultipleLcDatesForSelection
1071
+ ? Number.isFinite(selectedLcYear)
1072
+ ? this.getLccDateOptionsFromData(
1073
+ selectedLcYear,
1074
+ lccDatesByLcYear,
1075
+ lccDateList,
1076
+ )
1077
+ : []
1078
+ : this.getLccDateOptionsFromData(
1079
+ selectedLcYear,
1080
+ lccDatesByLcYear,
1081
+ lccDateList,
1082
+ );
809
1083
 
810
1084
  lccOptionsToUse.forEach((element) => {
811
1085
  selectBoxLccTime.options.add(new Option(element, element, element));
@@ -824,12 +1098,14 @@ class HotspotWidget extends React.Component {
824
1098
  );
825
1099
  selectBox.options[0].disabled = true;
826
1100
  }
1101
+ let hasDatasetSpecificKlcOptions = false;
827
1102
  if (activeLayers.length) {
828
1103
  for (let a = 0; a < activeLayers.length; a++) {
829
1104
  if (
830
1105
  activeLayers[a].includes('all_lcc_b_pol') ||
831
1106
  activeLayers[a].includes('all_present_lc_b_pol')
832
1107
  ) {
1108
+ hasDatasetSpecificKlcOptions = true;
833
1109
  for (let i = 0; i < modularKLCAreas.length; i++) {
834
1110
  let option = modularKLCAreas[i];
835
1111
  selectBox.options.add(new Option(option, option, option));
@@ -840,22 +1116,6 @@ class HotspotWidget extends React.Component {
840
1116
  continue;
841
1117
  } else {
842
1118
  selectBox.value = this.state.selectedArea;
843
- if (this.state.lcYear !== null) {
844
- const hasLcYearOption = Array.from(
845
- selectBoxLcTime.options,
846
- ).some((option) => option.value === this.state.lcYear);
847
- selectBoxLcTime.value = hasLcYearOption
848
- ? this.state.lcYear
849
- : 'default';
850
- }
851
- if (this.state.lccYear !== null) {
852
- const hasLccYearOption = Array.from(
853
- selectBoxLccTime.options,
854
- ).some((option) => option.value === this.state.lccYear);
855
- selectBoxLccTime.value = hasLccYearOption
856
- ? this.state.lccYear
857
- : 'default';
858
- }
859
1119
  break; // move break statement inside the if block
860
1120
  }
861
1121
  }
@@ -864,6 +1124,7 @@ class HotspotWidget extends React.Component {
864
1124
  activeLayers[a].includes('all_lcc_a_pol') ||
865
1125
  activeLayers[a].includes('all_present_lc_a_pol')
866
1126
  ) {
1127
+ hasDatasetSpecificKlcOptions = true;
867
1128
  for (let i = 0; i < dichotomousKLCAreas.length; i++) {
868
1129
  let option = dichotomousKLCAreas[i];
869
1130
  selectBox.options.add(new Option(option, option, option));
@@ -874,29 +1135,15 @@ class HotspotWidget extends React.Component {
874
1135
  continue;
875
1136
  } else {
876
1137
  selectBox.value = this.state.selectedArea;
877
- if (this.state.lcYear !== null) {
878
- const hasLcYearOption = Array.from(
879
- selectBoxLcTime.options,
880
- ).some((option) => option.value === this.state.lcYear);
881
- selectBoxLcTime.value = hasLcYearOption
882
- ? this.state.lcYear
883
- : 'default';
884
- }
885
- if (this.state.lccYear !== null) {
886
- const hasLccYearOption = Array.from(
887
- selectBoxLccTime.options,
888
- ).some((option) => option.value === this.state.lccYear);
889
- selectBoxLccTime.value = hasLccYearOption
890
- ? this.state.lccYear
891
- : 'default';
892
- }
893
1138
  break;
894
1139
  }
895
1140
  }
896
1141
  break;
897
1142
  }
898
1143
  }
899
- } else if (selectBox) {
1144
+ }
1145
+
1146
+ if (!hasDatasetSpecificKlcOptions && selectBox) {
900
1147
  const allKLCAreas = Array.from(
901
1148
  new Set(modularKLCAreas.concat(dichotomousKLCAreas)),
902
1149
  ).sort((a, b) => a.localeCompare(b));
@@ -914,20 +1161,60 @@ class HotspotWidget extends React.Component {
914
1161
  }
915
1162
  }
916
1163
  if (selectBox.value === 'default') {
1164
+ hasMultipleLcDatesForSelection = false;
917
1165
  if (selectBoxLcTime) {
918
1166
  this.removeOptions(selectBoxLcTime);
919
1167
  selectBoxLcTime.options.add(
920
- new Option('Select a region first', 'default', true, true),
1168
+ new Option('Select a year', 'default', true, true),
921
1169
  );
922
1170
  selectBoxLcTime.options[0].disabled = true;
923
1171
  }
924
1172
  if (selectBoxLccTime) {
925
1173
  this.removeOptions(selectBoxLccTime);
926
1174
  selectBoxLccTime.options.add(
927
- new Option('Select a region first', 'default', true, true),
1175
+ new Option('Select a year', 'default', true, true),
928
1176
  );
929
1177
  selectBoxLccTime.options[0].disabled = true;
930
1178
  }
1179
+
1180
+ if (
1181
+ this.state.selectedArea !== null ||
1182
+ this.state.referenceLcYear !== null ||
1183
+ this.state.lcYear !== null ||
1184
+ this.state.lccYear !== null
1185
+ ) {
1186
+ this.setState({
1187
+ selectedArea: null,
1188
+ referenceLcYear: null,
1189
+ lcYear: null,
1190
+ lccYear: null,
1191
+ });
1192
+ }
1193
+ }
1194
+
1195
+ if (
1196
+ selectBox &&
1197
+ this.state.selectedArea !== null &&
1198
+ Array.from(selectBox.options).some(
1199
+ (option) => option.value === this.state.selectedArea,
1200
+ )
1201
+ ) {
1202
+ selectBox.value = this.state.selectedArea;
1203
+ hasSelectedAreaOption = true;
1204
+ }
1205
+
1206
+ const hasActivePresentLcLayer = activeLayers.some(
1207
+ (layer) =>
1208
+ layer.includes('all_present_lc_a_pol') ||
1209
+ layer.includes('all_present_lc_b_pol') ||
1210
+ layer.includes('lc_filter'),
1211
+ );
1212
+
1213
+ const shouldShowPresentLandCoverDropdown =
1214
+ hasSelectedAreaOption && hasActivePresentLcLayer;
1215
+ this.setPresentLandCoverVisibility(shouldShowPresentLandCoverDropdown);
1216
+ if (this.state.hasMultipleLcDates !== hasMultipleLcDatesForSelection) {
1217
+ this.setState({ hasMultipleLcDates: hasMultipleLcDatesForSelection });
931
1218
  }
932
1219
  }
933
1220
 
@@ -959,70 +1246,21 @@ class HotspotWidget extends React.Component {
959
1246
  return;
960
1247
  }
961
1248
 
962
- let rawKeymapInfo = selectedNode.keymap_info;
963
- let keyMapInfoObj = {};
964
- if (typeof rawKeymapInfo === 'string') {
965
- try {
966
- keyMapInfoObj = JSON.parse(rawKeymapInfo) || {};
967
- } catch (e) {
968
- keyMapInfoObj = {};
969
- }
970
- } else if (rawKeymapInfo && typeof rawKeymapInfo === 'object') {
971
- keyMapInfoObj = rawKeymapInfo;
972
- }
973
-
974
- let lccDateList = [];
975
- let lccDatesByLcYear = {};
976
-
977
- if (Array.isArray(keyMapInfoObj.dates)) {
978
- keyMapInfoObj.dates.forEach((entry) => {
979
- const lccDate = Number(
980
- entry && typeof entry === 'object' ? entry?.date : entry,
981
- );
982
- const lcDate = Number(
983
- entry && typeof entry === 'object' ? entry?.lc_date : undefined,
984
- );
985
- if (Number.isFinite(lccDate)) {
986
- lccDateList.push(lccDate);
987
- }
988
- if (Number.isFinite(lcDate)) {
989
- if (!lccDatesByLcYear[lcDate]) {
990
- lccDatesByLcYear[lcDate] = [];
991
- }
992
- if (Number.isFinite(lccDate)) {
993
- lccDatesByLcYear[lcDate].push(lccDate);
994
- }
995
- }
996
- });
997
- }
998
-
999
- const dynamicYearValues = Object.keys(keyMapInfoObj)
1000
- .filter((key) => /^year\d+$/.test(key))
1001
- .map((key) => Number(keyMapInfoObj[key]))
1002
- .filter((year) => Number.isFinite(year));
1003
- if (dynamicYearValues.length) {
1004
- lccDateList = lccDateList.concat(dynamicYearValues);
1005
- }
1006
-
1007
- if (!lccDateList.length && Number.isFinite(Number(selectedNode.lcc_year))) {
1008
- lccDateList = [Number(selectedNode.lcc_year)];
1009
- }
1010
-
1011
- lccDateList = Array.from(new Set(lccDateList)).sort((a, b) => a - b);
1012
- Object.keys(lccDatesByLcYear).forEach((lcDateKey) => {
1013
- lccDatesByLcYear[lcDateKey] = Array.from(
1014
- new Set(lccDatesByLcYear[lcDateKey]),
1015
- ).sort((a, b) => a - b);
1016
- });
1017
-
1018
- const selectedLcYear = Number(this.state.lcYear);
1019
- const mappedLccDateList = Number.isFinite(selectedLcYear)
1020
- ? lccDatesByLcYear[selectedLcYear]
1021
- : null;
1022
- const lccOptionsToUse =
1023
- mappedLccDateList && mappedLccDateList.length
1024
- ? mappedLccDateList
1025
- : lccDateList;
1249
+ const { lccDateList, lcDateList, lccDatesByLcYear } =
1250
+ this.getDateOptionsForNode(selectedNode);
1251
+
1252
+ const selectedLcYear = this.isReferenceSelectionKlcCode(
1253
+ selectedNode?.klc_code,
1254
+ )
1255
+ ? this.getReferenceLcYearSelection(lcDateList)
1256
+ : Number(this.state.lcYear);
1257
+ const lccOptionsToUse = Number.isFinite(Number(selectedLcYear))
1258
+ ? this.getLccDateOptionsFromData(
1259
+ selectedLcYear,
1260
+ lccDatesByLcYear,
1261
+ lccDateList,
1262
+ )
1263
+ : [];
1026
1264
 
1027
1265
  this.removeOptions(selectBoxLccTime);
1028
1266
  selectBoxLccTime.options.add(
@@ -1069,6 +1307,84 @@ class HotspotWidget extends React.Component {
1069
1307
  );
1070
1308
  }
1071
1309
 
1310
+ renderReferenceLandCoverSelection() {
1311
+ const selectedNode = this.getSelectedNodeByArea(this.state.selectedArea);
1312
+ if (
1313
+ !selectedNode ||
1314
+ !this.isReferenceSelectionKlcCode(selectedNode.klc_code)
1315
+ ) {
1316
+ return null;
1317
+ }
1318
+
1319
+ const { lcDateList } = this.getDateOptionsForNode(selectedNode);
1320
+ if (!lcDateList.length) {
1321
+ return null;
1322
+ }
1323
+
1324
+ const selectedReferenceLcYear = this.state.referenceLcYear || 'default';
1325
+
1326
+ return (
1327
+ <div className="measurement-dropdown-container hotspot-reference-selection">
1328
+ <div className="esri-print__form-section-container">
1329
+ <label>
1330
+ Select first the reference land cover date you want to visualize
1331
+ <select
1332
+ id="select-klc-reference-lc-time"
1333
+ className="esri-select"
1334
+ value={selectedReferenceLcYear}
1335
+ onBlur={() => {}}
1336
+ onChange={(e) => {
1337
+ const nextReferenceLcYear = e.target.value;
1338
+ if (nextReferenceLcYear === 'default') {
1339
+ this.setState(
1340
+ {
1341
+ referenceLcYear: null,
1342
+ lcYear: null,
1343
+ lccYear: null,
1344
+ },
1345
+ () => {
1346
+ this.getKLCNames(
1347
+ this.dataJSONNames,
1348
+ this.state.selectedArea,
1349
+ );
1350
+ this.updateLccOptionsForSelectedLc();
1351
+ this.disableButton();
1352
+ },
1353
+ );
1354
+ return;
1355
+ }
1356
+ this.setState(
1357
+ {
1358
+ referenceLcYear: nextReferenceLcYear,
1359
+ lcYear: nextReferenceLcYear,
1360
+ lccYear: null,
1361
+ },
1362
+ () => {
1363
+ this.getKLCNames(
1364
+ this.dataJSONNames,
1365
+ this.state.selectedArea,
1366
+ );
1367
+ this.updateLccOptionsForSelectedLc();
1368
+ this.disableButton();
1369
+ },
1370
+ );
1371
+ }}
1372
+ >
1373
+ <option value="default" disabled>
1374
+ Select a year
1375
+ </option>
1376
+ {lcDateList.map((year) => (
1377
+ <option key={year} value={String(year)}>
1378
+ {year}
1379
+ </option>
1380
+ ))}
1381
+ </select>
1382
+ </label>
1383
+ </div>
1384
+ </div>
1385
+ );
1386
+ }
1387
+
1072
1388
  render() {
1073
1389
  let divs = [
1074
1390
  {
@@ -1151,6 +1467,7 @@ class HotspotWidget extends React.Component {
1151
1467
  onChange={(e) => {
1152
1468
  this.setState({
1153
1469
  selectedArea: e.target.value,
1470
+ referenceLcYear: null,
1154
1471
  lcYear: null,
1155
1472
  lccYear: null,
1156
1473
  });
@@ -1161,6 +1478,7 @@ class HotspotWidget extends React.Component {
1161
1478
  </label>
1162
1479
  </div>
1163
1480
  </div>
1481
+ {this.renderReferenceLandCoverSelection()}
1164
1482
  <div>
1165
1483
  {divs.map((div, i) => (
1166
1484
  <div key={i} className={div.className}>
@@ -1242,7 +1560,12 @@ class HotspotWidget extends React.Component {
1242
1560
  this.lccYear = null;
1243
1561
  this.selectedArea = null;
1244
1562
  if (this._isMounted) {
1245
- this.setState({ lcYear: null, lccYear: null, selectedArea: null });
1563
+ this.setState({
1564
+ lcYear: null,
1565
+ lccYear: null,
1566
+ selectedArea: null,
1567
+ referenceLcYear: null,
1568
+ });
1246
1569
  }
1247
1570
  shouldUpdate = true;
1248
1571
  }
@@ -1279,9 +1602,7 @@ class HotspotWidget extends React.Component {
1279
1602
  return '';
1280
1603
  }
1281
1604
  return Object.keys(activeLayers)
1282
- .filter(
1283
- (key) => key.includes('all_present_lc_') || key.includes('all_lcc_'),
1284
- )
1605
+ .filter((key) => this.isHotspotLayerKey(key))
1285
1606
  .sort()
1286
1607
  .join('|');
1287
1608
  }
@@ -1294,17 +1615,16 @@ class HotspotWidget extends React.Component {
1294
1615
  this.props.hotspotData,
1295
1616
  );
1296
1617
 
1297
- if (
1298
- prevHotspotLayerSignature !== nextHotspotLayerSignature &&
1299
- (this.state.selectedArea !== null ||
1300
- this.state.lcYear !== null ||
1301
- this.state.lccYear !== null)
1302
- ) {
1303
- this.setState({
1304
- selectedArea: null,
1305
- lcYear: null,
1306
- lccYear: null,
1307
- });
1618
+ if (prevHotspotLayerSignature !== nextHotspotLayerSignature) {
1619
+ this.clearHotspotLayersFromMap();
1620
+ this.resetHotspotViewState();
1621
+ const newHotspotData = {
1622
+ ...(this.props.hotspotData || {}),
1623
+ filteredLayers: {},
1624
+ filteredLayersData: {},
1625
+ };
1626
+ this.props.hotspotDataHandler(newHotspotData);
1627
+ this.resetHotspotWidgetFilters();
1308
1628
  return;
1309
1629
  }
1310
1630
 
@@ -1318,6 +1638,9 @@ class HotspotWidget extends React.Component {
1318
1638
  if (prevState.lcYear !== this.state.lcYear) {
1319
1639
  this.disableButton();
1320
1640
  }
1641
+ if (prevState.referenceLcYear !== this.state.referenceLcYear) {
1642
+ this.disableButton();
1643
+ }
1321
1644
  }
1322
1645
  }
1323
1646
  export default HotspotWidget;