@eeacms/volto-arcgis-block 0.1.468 → 0.1.470
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 +9 -0
- package/package.json +1 -1
- package/src/components/MapViewer/MenuWidget.jsx +164 -72
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,14 @@ 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.470](https://github.com/eea/volto-arcgis-block/compare/0.1.469...0.1.470) - 13 August 2026
|
|
8
|
+
|
|
9
|
+
### [0.1.469](https://github.com/eea/volto-arcgis-block/compare/0.1.468...0.1.469) - 12 August 2026
|
|
10
|
+
|
|
11
|
+
#### :hammer_and_wrench: Others
|
|
12
|
+
|
|
13
|
+
- (chore): fix linting [Unai Bolivar - [`df6b223`](https://github.com/eea/volto-arcgis-block/commit/df6b223aa3b8b2e0bf098e191e210ec4022f059f)]
|
|
14
|
+
- (bug): dynamically pull time range from catalog for hi/lo res tile requests [Unai Bolivar - [`810b22d`](https://github.com/eea/volto-arcgis-block/commit/810b22d9b555fb18d9f8d5a810a5099f6ae29ab6)]
|
|
7
15
|
### [0.1.468](https://github.com/eea/volto-arcgis-block/compare/0.1.467...0.1.468) - 12 August 2026
|
|
8
16
|
|
|
9
17
|
#### :rocket: New Features
|
|
@@ -17,6 +25,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
17
25
|
|
|
18
26
|
#### :hammer_and_wrench: Others
|
|
19
27
|
|
|
28
|
+
- Merge pull request #1190 from eea/develop [Unai Bolivar - [`5d9e33f`](https://github.com/eea/volto-arcgis-block/commit/5d9e33f1470e6776920657aac835360aff91e47c)]
|
|
20
29
|
- Merge pull request #1189 from eea/CLMS-304632-REFACTOR [Unai Bolivar - [`ffba286`](https://github.com/eea/volto-arcgis-block/commit/ffba286c6368fae6167ffedf3c89a18d74a31edd)]
|
|
21
30
|
- (task): refactor dual layers support [Unai Bolivar - [`c13aaa0`](https://github.com/eea/volto-arcgis-block/commit/c13aaa089d91f476f1fa02e94673dc4d847704c9)]
|
|
22
31
|
- (task): refactor dual layer support [Unai Bolivar - [`7c3a1cf`](https://github.com/eea/volto-arcgis-block/commit/7c3a1cfe18ed8be53b80fb2205b54cce90f0ad68)]
|
package/package.json
CHANGED
|
@@ -952,7 +952,7 @@ class MenuWidget extends React.Component {
|
|
|
952
952
|
}
|
|
953
953
|
}
|
|
954
954
|
|
|
955
|
-
supportDualLayers(layer, inheritedIndexLayer) {
|
|
955
|
+
supportDualLayers(layer, inheritedIndexLayer, datasetCollectionId) {
|
|
956
956
|
const resolutionData = layer.resolution_data || {};
|
|
957
957
|
const thresholdScale = Number(resolutionData.thresholdScale);
|
|
958
958
|
const normalizeScaleValue = (scaleValue, fallbackValue = 0) => {
|
|
@@ -988,10 +988,85 @@ class MenuWidget extends React.Component {
|
|
|
988
988
|
const CDSEProcessTileLayer = BaseTileLayer.createSubclass({
|
|
989
989
|
properties: {
|
|
990
990
|
collectionId: null,
|
|
991
|
+
catalogByoc: null,
|
|
991
992
|
evalscript: null,
|
|
992
993
|
processUrl: '/++api++/@proxyrunprocessapi',
|
|
993
994
|
},
|
|
994
995
|
|
|
996
|
+
_resolveCatalogDateRange: function (options) {
|
|
997
|
+
const rawCollectionId = this.catalogByoc || '';
|
|
998
|
+
const normalizedCollectionId = String(rawCollectionId).replace(
|
|
999
|
+
/^byoc-/i,
|
|
1000
|
+
'',
|
|
1001
|
+
);
|
|
1002
|
+
if (!normalizedCollectionId) {
|
|
1003
|
+
return Promise.resolve(null);
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
const cacheByCollection =
|
|
1007
|
+
this.constructor._catalogDateRangeCache ||
|
|
1008
|
+
(this.constructor._catalogDateRangeCache = {});
|
|
1009
|
+
const pendingByCollection =
|
|
1010
|
+
this.constructor._catalogDateRangePending ||
|
|
1011
|
+
(this.constructor._catalogDateRangePending = {});
|
|
1012
|
+
|
|
1013
|
+
if (cacheByCollection[normalizedCollectionId]) {
|
|
1014
|
+
return Promise.resolve(cacheByCollection[normalizedCollectionId]);
|
|
1015
|
+
}
|
|
1016
|
+
if (pendingByCollection[normalizedCollectionId]) {
|
|
1017
|
+
return pendingByCollection[normalizedCollectionId];
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
const requestUrl =
|
|
1021
|
+
'/++api++/@get_catalogapi_dates?byoc=' +
|
|
1022
|
+
encodeURIComponent(normalizedCollectionId) +
|
|
1023
|
+
'&force_refresh=false';
|
|
1024
|
+
|
|
1025
|
+
pendingByCollection[normalizedCollectionId] = fetch(requestUrl, {
|
|
1026
|
+
headers: {
|
|
1027
|
+
Accept: 'application/json',
|
|
1028
|
+
},
|
|
1029
|
+
signal: options && options.signal,
|
|
1030
|
+
})
|
|
1031
|
+
.then((response) => {
|
|
1032
|
+
if (!response.ok) {
|
|
1033
|
+
return null;
|
|
1034
|
+
}
|
|
1035
|
+
return response.json();
|
|
1036
|
+
})
|
|
1037
|
+
.then((payload) => {
|
|
1038
|
+
const dates = Array.isArray(payload?.dates) ? payload.dates : [];
|
|
1039
|
+
const resolveTimeValue = (value, isStart) => {
|
|
1040
|
+
if (!value) {
|
|
1041
|
+
return null;
|
|
1042
|
+
}
|
|
1043
|
+
const stringValue = String(value);
|
|
1044
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(stringValue)) {
|
|
1045
|
+
return isStart
|
|
1046
|
+
? `${stringValue}T00:00:00Z`
|
|
1047
|
+
: `${stringValue}T23:59:59Z`;
|
|
1048
|
+
}
|
|
1049
|
+
return stringValue;
|
|
1050
|
+
};
|
|
1051
|
+
const resolvedDateRange =
|
|
1052
|
+
dates.length > 0
|
|
1053
|
+
? {
|
|
1054
|
+
from: resolveTimeValue(dates[0], true),
|
|
1055
|
+
to: resolveTimeValue(dates[dates.length - 1], false),
|
|
1056
|
+
}
|
|
1057
|
+
: null;
|
|
1058
|
+
cacheByCollection[normalizedCollectionId] = resolvedDateRange;
|
|
1059
|
+
delete pendingByCollection[normalizedCollectionId];
|
|
1060
|
+
return resolvedDateRange;
|
|
1061
|
+
})
|
|
1062
|
+
.catch(() => {
|
|
1063
|
+
delete pendingByCollection[normalizedCollectionId];
|
|
1064
|
+
return null;
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
return pendingByCollection[normalizedCollectionId];
|
|
1068
|
+
},
|
|
1069
|
+
|
|
995
1070
|
// Computes the tile bounding box in EPSG:3857 (without projections)
|
|
996
1071
|
_tileToBBox3857: function (level, row, col) {
|
|
997
1072
|
const tileInfo = this.tileInfo;
|
|
@@ -1024,81 +1099,94 @@ class MenuWidget extends React.Component {
|
|
|
1024
1099
|
const width = this.tileInfo.size[0];
|
|
1025
1100
|
const height = this.tileInfo.size[1];
|
|
1026
1101
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1102
|
+
return this._resolveCatalogDateRange(options).then(
|
|
1103
|
+
(catalogDateRange) => {
|
|
1104
|
+
const resolvedTimeRangeFrom = catalogDateRange?.from || null;
|
|
1105
|
+
const resolvedTimeRangeTo = catalogDateRange?.to || null;
|
|
1106
|
+
const timeRange = {};
|
|
1107
|
+
if (resolvedTimeRangeFrom) {
|
|
1108
|
+
timeRange.from = resolvedTimeRangeFrom;
|
|
1109
|
+
}
|
|
1110
|
+
if (resolvedTimeRangeTo) {
|
|
1111
|
+
timeRange.to = resolvedTimeRangeTo;
|
|
1112
|
+
}
|
|
1113
|
+
const dataFilter = {};
|
|
1114
|
+
if (Object.keys(timeRange).length) {
|
|
1115
|
+
dataFilter.timeRange = timeRange;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
const payload = {
|
|
1119
|
+
input: {
|
|
1120
|
+
bounds: {
|
|
1121
|
+
bbox: [
|
|
1122
|
+
bbox3857.west,
|
|
1123
|
+
bbox3857.south,
|
|
1124
|
+
bbox3857.east,
|
|
1125
|
+
bbox3857.north,
|
|
1126
|
+
],
|
|
1127
|
+
properties: {
|
|
1128
|
+
crs: 'http://www.opengis.net/def/crs/EPSG/0/3857',
|
|
1047
1129
|
},
|
|
1048
1130
|
},
|
|
1131
|
+
data: [
|
|
1132
|
+
{
|
|
1133
|
+
type: this.collectionId,
|
|
1134
|
+
...(Object.keys(dataFilter).length ? { dataFilter } : {}),
|
|
1135
|
+
},
|
|
1136
|
+
],
|
|
1049
1137
|
},
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1138
|
+
output: {
|
|
1139
|
+
width: width,
|
|
1140
|
+
height: height,
|
|
1141
|
+
responses: [
|
|
1142
|
+
{
|
|
1143
|
+
identifier: 'default',
|
|
1144
|
+
format: { type: 'image/png' },
|
|
1145
|
+
},
|
|
1146
|
+
],
|
|
1059
1147
|
},
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1148
|
+
evalscript: this.evalscript,
|
|
1149
|
+
};
|
|
1150
|
+
|
|
1151
|
+
return fetch(this.processUrl, {
|
|
1152
|
+
method: 'POST',
|
|
1153
|
+
headers: {
|
|
1154
|
+
'Content-Type': 'application/json',
|
|
1155
|
+
Accept: 'image/png',
|
|
1156
|
+
},
|
|
1157
|
+
body: JSON.stringify(payload),
|
|
1158
|
+
signal: options && options.signal,
|
|
1159
|
+
})
|
|
1160
|
+
.then((response) => {
|
|
1161
|
+
if (!response.ok) {
|
|
1162
|
+
throw new Error(
|
|
1163
|
+
`Process API error ${response.status}: ${response.statusText}`,
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
return response.blob();
|
|
1167
|
+
})
|
|
1168
|
+
.then((blob) => {
|
|
1169
|
+
return new Promise((resolve, reject) => {
|
|
1170
|
+
const url = URL.createObjectURL(blob);
|
|
1171
|
+
const img = new Image();
|
|
1172
|
+
img.onload = () => {
|
|
1173
|
+
const canvas = document.createElement('canvas');
|
|
1174
|
+
canvas.width = width;
|
|
1175
|
+
canvas.height = height;
|
|
1176
|
+
const ctx = canvas.getContext('2d');
|
|
1177
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
1178
|
+
URL.revokeObjectURL(url);
|
|
1179
|
+
resolve(canvas);
|
|
1180
|
+
};
|
|
1181
|
+
img.onerror = (err) => {
|
|
1182
|
+
URL.revokeObjectURL(url);
|
|
1183
|
+
reject(err);
|
|
1184
|
+
};
|
|
1185
|
+
img.src = url;
|
|
1186
|
+
});
|
|
1187
|
+
});
|
|
1070
1188
|
},
|
|
1071
|
-
|
|
1072
|
-
signal: options && options.signal,
|
|
1073
|
-
})
|
|
1074
|
-
.then((response) => {
|
|
1075
|
-
if (!response.ok) {
|
|
1076
|
-
throw new Error(
|
|
1077
|
-
`Process API error ${response.status}: ${response.statusText}`,
|
|
1078
|
-
);
|
|
1079
|
-
}
|
|
1080
|
-
return response.blob();
|
|
1081
|
-
})
|
|
1082
|
-
.then((blob) => {
|
|
1083
|
-
return new Promise((resolve, reject) => {
|
|
1084
|
-
const url = URL.createObjectURL(blob);
|
|
1085
|
-
const img = new Image();
|
|
1086
|
-
img.onload = () => {
|
|
1087
|
-
const canvas = document.createElement('canvas');
|
|
1088
|
-
canvas.width = width;
|
|
1089
|
-
canvas.height = height;
|
|
1090
|
-
const ctx = canvas.getContext('2d');
|
|
1091
|
-
ctx.drawImage(img, 0, 0, width, height);
|
|
1092
|
-
URL.revokeObjectURL(url);
|
|
1093
|
-
resolve(canvas);
|
|
1094
|
-
};
|
|
1095
|
-
img.onerror = (err) => {
|
|
1096
|
-
URL.revokeObjectURL(url);
|
|
1097
|
-
reject(err);
|
|
1098
|
-
};
|
|
1099
|
-
img.src = url;
|
|
1100
|
-
});
|
|
1101
|
-
});
|
|
1189
|
+
);
|
|
1102
1190
|
},
|
|
1103
1191
|
});
|
|
1104
1192
|
const tileInfo = {
|
|
@@ -1132,6 +1220,7 @@ class MenuWidget extends React.Component {
|
|
|
1132
1220
|
new CDSEProcessTileLayer({
|
|
1133
1221
|
...sharedLayerProps,
|
|
1134
1222
|
collectionId: lowResLayerData.collectionId,
|
|
1223
|
+
catalogByoc: datasetCollectionId || null,
|
|
1135
1224
|
evalscript: lowResLayerData.evalscript,
|
|
1136
1225
|
minScale: lowResLayerData.minScale,
|
|
1137
1226
|
maxScale: lowResLayerData.maxScale,
|
|
@@ -1144,6 +1233,7 @@ class MenuWidget extends React.Component {
|
|
|
1144
1233
|
new CDSEProcessTileLayer({
|
|
1145
1234
|
...sharedLayerProps,
|
|
1146
1235
|
collectionId: highResLayerData.collectionId,
|
|
1236
|
+
catalogByoc: datasetCollectionId || null,
|
|
1147
1237
|
evalscript: highResLayerData.evalscript,
|
|
1148
1238
|
minScale: highResLayerData.minScale,
|
|
1149
1239
|
maxScale: highResLayerData.maxScale,
|
|
@@ -2279,7 +2369,9 @@ class MenuWidget extends React.Component {
|
|
|
2279
2369
|
layer.hasLowRes === true ||
|
|
2280
2370
|
(layer.resolution_data?.lowRes && layer.resolution_data?.highRes)
|
|
2281
2371
|
) {
|
|
2282
|
-
|
|
2372
|
+
const datasetCollectionId =
|
|
2373
|
+
dataset_download_information?.items?.[0]?.byoc_collection || null;
|
|
2374
|
+
this.supportDualLayers(layer, inheritedIndexLayer, datasetCollectionId);
|
|
2283
2375
|
} else if (viewService?.toLowerCase().includes('wms')) {
|
|
2284
2376
|
viewService = viewService?.includes('?')
|
|
2285
2377
|
? viewService + '&'
|