@eeacms/volto-arcgis-block 0.1.402 → 0.1.403
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/CHANGELOG.md +2 -0
- package/package.json +1 -1
- package/src/components/MapViewer/InfoWidget.jsx +133 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
### [0.1.403](https://github.com/eea/volto-arcgis-block/compare/0.1.402...0.1.403) - 4 November 2025
|
|
8
|
+
|
|
7
9
|
### [0.1.402](https://github.com/eea/volto-arcgis-block/compare/0.1.401...0.1.402) - 3 November 2025
|
|
8
10
|
|
|
9
11
|
#### :hammer_and_wrench: Others
|
package/package.json
CHANGED
|
@@ -142,7 +142,24 @@ class InfoWidget extends React.Component {
|
|
|
142
142
|
title = this.getLayerTitle(layer);
|
|
143
143
|
}
|
|
144
144
|
if (layer?.isTimeSeries) {
|
|
145
|
-
if (
|
|
145
|
+
if (
|
|
146
|
+
!!layer.ViewService &&
|
|
147
|
+
['/ogc/', '/cdse/'].some((s) =>
|
|
148
|
+
layer.ViewService.toLowerCase().includes(s),
|
|
149
|
+
)
|
|
150
|
+
) {
|
|
151
|
+
layerTypes.push({
|
|
152
|
+
isTimeSeries: true,
|
|
153
|
+
type: 'wmts',
|
|
154
|
+
title: title,
|
|
155
|
+
fields: layer.fields,
|
|
156
|
+
});
|
|
157
|
+
promises.push(
|
|
158
|
+
this.cdseCapabilities(layer.ViewService, layer).then((xml) =>
|
|
159
|
+
this.identifyCDSE(xml, layer),
|
|
160
|
+
),
|
|
161
|
+
);
|
|
162
|
+
} else if (layer.url.toLowerCase().includes('wms')) {
|
|
146
163
|
layerTypes.push({
|
|
147
164
|
isTimeSeries: true,
|
|
148
165
|
type: 'wms',
|
|
@@ -293,6 +310,15 @@ class InfoWidget extends React.Component {
|
|
|
293
310
|
};
|
|
294
311
|
break;
|
|
295
312
|
case 'wmts':
|
|
313
|
+
if (
|
|
314
|
+
layers[index]?.ViewService &&
|
|
315
|
+
layers[index].ViewService.toLowerCase().includes(
|
|
316
|
+
'cdse',
|
|
317
|
+
)
|
|
318
|
+
) {
|
|
319
|
+
properties = data;
|
|
320
|
+
}
|
|
321
|
+
properties = data;
|
|
296
322
|
this.infoData[index] = {
|
|
297
323
|
title: layer.title,
|
|
298
324
|
data: properties,
|
|
@@ -444,7 +470,9 @@ class InfoWidget extends React.Component {
|
|
|
444
470
|
|
|
445
471
|
getLayerTitle(layer) {
|
|
446
472
|
let title;
|
|
447
|
-
if (layer.
|
|
473
|
+
if (layer.ViewService && layer.ViewService.toLowerCase().includes('cdse')) {
|
|
474
|
+
title = layer.title;
|
|
475
|
+
} else if (layer.url.toLowerCase().includes('wmts')) {
|
|
448
476
|
// CLMS-1105
|
|
449
477
|
title = layer._wmtsTitle;
|
|
450
478
|
} else if (layer.url.toLowerCase().toLowerCase().endsWith('mapserver')) {
|
|
@@ -562,6 +590,109 @@ class InfoWidget extends React.Component {
|
|
|
562
590
|
});
|
|
563
591
|
}
|
|
564
592
|
|
|
593
|
+
async cdseCapabilities(url, layer) {
|
|
594
|
+
if (!url) return {};
|
|
595
|
+
try {
|
|
596
|
+
const res = await fetch(url);
|
|
597
|
+
const text = await res.text();
|
|
598
|
+
let parser = new DOMParser();
|
|
599
|
+
let xml = parser.parseFromString(text, 'text/html');
|
|
600
|
+
return xml;
|
|
601
|
+
} catch (e) {
|
|
602
|
+
return {};
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
identifyCDSE(xml, layer) {
|
|
607
|
+
let values = { timeFields: {}, data: {}, variables: {}, tableData: {} };
|
|
608
|
+
if (!xml || !xml.querySelector) {
|
|
609
|
+
values.timeFields['start'] = 'time';
|
|
610
|
+
values.variables = { options: ['value'], selected: 'value' };
|
|
611
|
+
values.tableData['fields'] = ['time', 'value'];
|
|
612
|
+
values.timeFields['values'] = [];
|
|
613
|
+
values.data['outFields'] = 'value';
|
|
614
|
+
values.data['values'] = [];
|
|
615
|
+
values.tableData['values'] = [];
|
|
616
|
+
return values;
|
|
617
|
+
}
|
|
618
|
+
let layerId = this.getLayerName(layer);
|
|
619
|
+
let layers = Array.from(xml.querySelectorAll('Layer'));
|
|
620
|
+
let lyr =
|
|
621
|
+
layers.find((l) => {
|
|
622
|
+
let id =
|
|
623
|
+
l.querySelector('ows\\:Identifier') || l.querySelector('Identifier');
|
|
624
|
+
return id && id.textContent === layerId;
|
|
625
|
+
}) || layers[0];
|
|
626
|
+
let timeValues = [];
|
|
627
|
+
if (lyr) {
|
|
628
|
+
let dimNodes = Array.from(lyr.querySelectorAll('Dimension'));
|
|
629
|
+
let timeDim =
|
|
630
|
+
dimNodes.find((d) => {
|
|
631
|
+
let n = d.getAttribute('name') || d.getAttribute('identifier') || '';
|
|
632
|
+
return n.toLowerCase() === 'time';
|
|
633
|
+
}) ||
|
|
634
|
+
dimNodes.find((d) => {
|
|
635
|
+
let idn =
|
|
636
|
+
d.querySelector('ows\\:Identifier') ||
|
|
637
|
+
d.querySelector('Identifier');
|
|
638
|
+
return idn && idn.textContent.toLowerCase() === 'time';
|
|
639
|
+
});
|
|
640
|
+
if (timeDim) {
|
|
641
|
+
let valNodes = Array.from(timeDim.querySelectorAll('Value'));
|
|
642
|
+
if (valNodes.length) {
|
|
643
|
+
timeValues = valNodes
|
|
644
|
+
.map((v) => v.textContent.trim())
|
|
645
|
+
.filter((t) => t);
|
|
646
|
+
} else {
|
|
647
|
+
let txt = (timeDim.textContent || '').trim();
|
|
648
|
+
if (txt) {
|
|
649
|
+
if (txt.includes(',')) {
|
|
650
|
+
timeValues = txt.split(',').map((s) => s.trim());
|
|
651
|
+
} else if (txt.includes('/')) {
|
|
652
|
+
timeValues = this.expandTimeRange(txt);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
let def = timeDim.getAttribute('default') || '';
|
|
656
|
+
if (!timeValues.length && def) timeValues = [def];
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
values.timeFields['start'] = 'time';
|
|
661
|
+
values.variables = { options: ['value'], selected: 'value' };
|
|
662
|
+
values.tableData['fields'] = ['time', 'value'];
|
|
663
|
+
values.timeFields['values'] = timeValues.map((t) => {
|
|
664
|
+
let obj = {};
|
|
665
|
+
obj['time'] = t;
|
|
666
|
+
return obj;
|
|
667
|
+
});
|
|
668
|
+
values.data['outFields'] = 'value';
|
|
669
|
+
values.data['values'] = [];
|
|
670
|
+
values.tableData['values'] = timeValues.map((t) => {
|
|
671
|
+
return [
|
|
672
|
+
['time', t],
|
|
673
|
+
['value', ''],
|
|
674
|
+
];
|
|
675
|
+
});
|
|
676
|
+
return values;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
expandTimeRange(range) {
|
|
680
|
+
let parts = range.split('/');
|
|
681
|
+
if (parts.length !== 3) return parts.filter((p) => p);
|
|
682
|
+
let start = new Date(parts[0]);
|
|
683
|
+
let end = new Date(parts[1]);
|
|
684
|
+
let step = parts[2];
|
|
685
|
+
let out = [];
|
|
686
|
+
if (step === 'P1D') {
|
|
687
|
+
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
|
|
688
|
+
out.push(new Date(d).toISOString().split('T')[0]);
|
|
689
|
+
}
|
|
690
|
+
return out;
|
|
691
|
+
} else {
|
|
692
|
+
return [parts[0], parts[1]];
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
565
696
|
parseCapabilities(xml, tag) {
|
|
566
697
|
let result = xml.getElementsByTagName(tag);
|
|
567
698
|
|