@eeacms/volto-arcgis-block 0.1.467 → 0.1.468

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 CHANGED
@@ -4,6 +4,26 @@ 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.468](https://github.com/eea/volto-arcgis-block/compare/0.1.467...0.1.468) - 12 August 2026
8
+
9
+ #### :rocket: New Features
10
+
11
+ - feat: bind processapi endpoint to mapviewer [ana-oprea - [`066c9ea`](https://github.com/eea/volto-arcgis-block/commit/066c9ea8d33a1a1091fbec5e40effd9025d199df)]
12
+
13
+ #### :house: Internal changes
14
+
15
+ - style: Automated code fix [eea-jenkins - [`c670ae0`](https://github.com/eea/volto-arcgis-block/commit/c670ae0acf614ead0662eee6b9c1d747cef97d33)]
16
+ - style: Automated code fix [eea-jenkins - [`8ad01ad`](https://github.com/eea/volto-arcgis-block/commit/8ad01ad521477bb5f7cc2235531a65a37703ce92)]
17
+
18
+ #### :hammer_and_wrench: Others
19
+
20
+ - Merge pull request #1189 from eea/CLMS-304632-REFACTOR [Unai Bolivar - [`ffba286`](https://github.com/eea/volto-arcgis-block/commit/ffba286c6368fae6167ffedf3c89a18d74a31edd)]
21
+ - (task): refactor dual layers support [Unai Bolivar - [`c13aaa0`](https://github.com/eea/volto-arcgis-block/commit/c13aaa089d91f476f1fa02e94673dc4d847704c9)]
22
+ - (task): refactor dual layer support [Unai Bolivar - [`7c3a1cf`](https://github.com/eea/volto-arcgis-block/commit/7c3a1cfe18ed8be53b80fb2205b54cce90f0ad68)]
23
+ - CLMS-303649 (bug): Swipe widget solved [Urkorue - [`9f0aea8`](https://github.com/eea/volto-arcgis-block/commit/9f0aea8855a437b63f57e88cb4bd1446bd8f33df)]
24
+ - (feat): implemented a complete refactor to process hi/lo res dataset based on values from internal api [Unai Bolivar - [`f34e881`](https://github.com/eea/volto-arcgis-block/commit/f34e88157a77f90e4fc3ace6b20ffa287efafc5a)]
25
+ - (chore): port refactor [Unai Bolivar - [`fb98e70`](https://github.com/eea/volto-arcgis-block/commit/fb98e70d1750c3d06b961db887509f542412e080)]
26
+ - CLMS-304632 (feat): 10 metre resolution [Urkorue - [`ce9517c`](https://github.com/eea/volto-arcgis-block/commit/ce9517c47eeea1f5d5e752bde7fe19217f2efcac)]
7
27
  ### [0.1.467](https://github.com/eea/volto-arcgis-block/compare/0.1.466...0.1.467) - 12 August 2026
8
28
 
9
29
  ### [0.1.466](https://github.com/eea/volto-arcgis-block/compare/0.1.465...0.1.466) - 7 August 2026
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-arcgis-block",
3
- "version": "0.1.467",
3
+ "version": "0.1.468",
4
4
  "description": "volto-arcgis-block: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: CodeSyntax",
@@ -22,7 +22,8 @@ var WMSLayer,
22
22
  MapImageLayer,
23
23
  projection,
24
24
  SpatialReference,
25
- WebMercatorUtils;
25
+ WebMercatorUtils,
26
+ GroupLayer;
26
27
 
27
28
  const popupSettings = {
28
29
  basic: true,
@@ -583,6 +584,7 @@ class MenuWidget extends React.Component {
583
584
  'esri/geometry/projection',
584
585
  'esri/geometry/SpatialReference',
585
586
  'esri/geometry/support/webMercatorUtils',
587
+ 'esri/layers/GroupLayer',
586
588
  ]).then(
587
589
  ([
588
590
  _WMSLayer,
@@ -598,6 +600,7 @@ class MenuWidget extends React.Component {
598
600
  _projection,
599
601
  _SpatialReference,
600
602
  _WebMercatorUtils,
603
+ _GroupLayer,
601
604
  ]) => {
602
605
  [
603
606
  WMSLayer,
@@ -613,6 +616,7 @@ class MenuWidget extends React.Component {
613
616
  projection,
614
617
  SpatialReference,
615
618
  WebMercatorUtils,
619
+ GroupLayer,
616
620
  ] = [
617
621
  _WMSLayer,
618
622
  _WMTSLayer,
@@ -627,6 +631,7 @@ class MenuWidget extends React.Component {
627
631
  _projection,
628
632
  _SpatialReference,
629
633
  _WebMercatorUtils,
634
+ _GroupLayer,
630
635
  ];
631
636
  },
632
637
  );
@@ -843,7 +848,7 @@ class MenuWidget extends React.Component {
843
848
 
844
849
  this.props.restorePanelScroll();
845
850
  }
846
-
851
+ //this.pruebasLayer()
847
852
  this.setState({ showMapMenu: true });
848
853
  }
849
854
  // if (this.loadFirst && this.container.current) {
@@ -947,6 +952,216 @@ class MenuWidget extends React.Component {
947
952
  }
948
953
  }
949
954
 
955
+ supportDualLayers(layer, inheritedIndexLayer) {
956
+ const resolutionData = layer.resolution_data || {};
957
+ const thresholdScale = Number(resolutionData.thresholdScale);
958
+ const normalizeScaleValue = (scaleValue, fallbackValue = 0) => {
959
+ const normalizedValue = Number(scaleValue);
960
+ return Number.isFinite(normalizedValue) ? normalizedValue : fallbackValue;
961
+ };
962
+ const lowResSourceData = resolutionData.lowRes || layer.lowRes || {};
963
+ const highResSourceData = resolutionData.highRes || layer.highRes || {};
964
+ const baseLayerTitle = layer.Title || layer.LayerId || '';
965
+ const lowResLayerTitle = lowResSourceData.title || baseLayerTitle;
966
+ const highResLayerTitle = highResSourceData.title || baseLayerTitle;
967
+ const lowResLayerData = {
968
+ collectionId: lowResSourceData.collectionId,
969
+ evalscript: lowResSourceData.evalscript,
970
+ minScale: normalizeScaleValue(lowResSourceData.minScale, 0),
971
+ maxScale: normalizeScaleValue(
972
+ lowResSourceData.maxScale,
973
+ Number.isFinite(thresholdScale) ? thresholdScale : 0,
974
+ ),
975
+ };
976
+ const highResLayerData = {
977
+ collectionId: highResSourceData.collectionId,
978
+ evalscript: highResSourceData.evalscript,
979
+ minScale: normalizeScaleValue(
980
+ highResSourceData.minScale,
981
+ Number.isFinite(thresholdScale) ? thresholdScale + 1 : 0,
982
+ ),
983
+ maxScale: normalizeScaleValue(highResSourceData.maxScale, 0),
984
+ };
985
+ if (!lowResLayerData.collectionId && !highResLayerData.collectionId) {
986
+ return;
987
+ }
988
+ const CDSEProcessTileLayer = BaseTileLayer.createSubclass({
989
+ properties: {
990
+ collectionId: null,
991
+ evalscript: null,
992
+ processUrl: '/++api++/@proxyrunprocessapi',
993
+ },
994
+
995
+ // Computes the tile bounding box in EPSG:3857 (without projections)
996
+ _tileToBBox3857: function (level, row, col) {
997
+ const tileInfo = this.tileInfo;
998
+ const origin = tileInfo.origin;
999
+ const res = tileInfo.lods[level].resolution;
1000
+ const size = tileInfo.size[0];
1001
+
1002
+ const xmin = origin.x + col * size * res;
1003
+ const ymax = origin.y - row * size * res;
1004
+ const xmax = xmin + size * res;
1005
+ const ymin = ymax - size * res;
1006
+
1007
+ return {
1008
+ west: xmin,
1009
+ south: ymin,
1010
+ east: xmax,
1011
+ north: ymax,
1012
+ };
1013
+ },
1014
+
1015
+ // Main method that renders each tile
1016
+ fetchTile: function (level, row, col, options) {
1017
+ // Invert row if it is TMS (south origin)
1018
+ if (this.tms) {
1019
+ var rowmax = 1 << level;
1020
+ row = rowmax - row - 1;
1021
+ }
1022
+
1023
+ const bbox3857 = this._tileToBBox3857(level, row, col);
1024
+ const width = this.tileInfo.size[0];
1025
+ const height = this.tileInfo.size[1];
1026
+
1027
+ const payload = {
1028
+ input: {
1029
+ bounds: {
1030
+ bbox: [
1031
+ bbox3857.west,
1032
+ bbox3857.south,
1033
+ bbox3857.east,
1034
+ bbox3857.north,
1035
+ ],
1036
+ properties: {
1037
+ crs: 'http://www.opengis.net/def/crs/EPSG/0/3857',
1038
+ },
1039
+ },
1040
+ data: [
1041
+ {
1042
+ type: this.collectionId,
1043
+ dataFilter: {
1044
+ timeRange: {
1045
+ from: '2021-01-01T00:00:00Z',
1046
+ to: '2022-01-01T23:59:59Z',
1047
+ },
1048
+ },
1049
+ },
1050
+ ],
1051
+ },
1052
+ output: {
1053
+ width: width,
1054
+ height: height,
1055
+ responses: [
1056
+ {
1057
+ identifier: 'default',
1058
+ format: { type: 'image/png' },
1059
+ },
1060
+ ],
1061
+ },
1062
+ evalscript: this.evalscript,
1063
+ };
1064
+
1065
+ return fetch(this.processUrl, {
1066
+ method: 'POST',
1067
+ headers: {
1068
+ 'Content-Type': 'application/json',
1069
+ Accept: 'image/png',
1070
+ },
1071
+ body: JSON.stringify(payload),
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
+ });
1102
+ },
1103
+ });
1104
+ const tileInfo = {
1105
+ size: [512, 512],
1106
+ origin: { x: -20037508.342787, y: 20037508.342787 },
1107
+ spatialReference: { wkid: 3857 },
1108
+ lods: Array.from({ length: 21 }, (_, i) => ({
1109
+ level: i,
1110
+ resolution: 156543.033928 / Math.pow(2, i),
1111
+ scale: 591657527.591555 / Math.pow(2, i),
1112
+ })),
1113
+ };
1114
+ const fullExtent = new Extent({
1115
+ xmin: -20037508.342787,
1116
+ ymin: -20037508.342787,
1117
+ xmax: 20037508.342787,
1118
+ ymax: 20037508.342787,
1119
+ spatialReference: { wkid: 3857 },
1120
+ });
1121
+ const sharedLayerProps = {
1122
+ tms: false,
1123
+ tileInfo: tileInfo,
1124
+ fullExtent: fullExtent,
1125
+ };
1126
+
1127
+ //const lowResolutionScaleLimit = layer.thresholdScale;
1128
+
1129
+ const dualResolutionLayers = [];
1130
+ if (lowResLayerData.collectionId && lowResLayerData.evalscript) {
1131
+ dualResolutionLayers.push(
1132
+ new CDSEProcessTileLayer({
1133
+ ...sharedLayerProps,
1134
+ collectionId: lowResLayerData.collectionId,
1135
+ evalscript: lowResLayerData.evalscript,
1136
+ minScale: lowResLayerData.minScale,
1137
+ maxScale: lowResLayerData.maxScale,
1138
+ title: lowResLayerTitle,
1139
+ }),
1140
+ );
1141
+ }
1142
+ if (highResLayerData.collectionId && highResLayerData.evalscript) {
1143
+ dualResolutionLayers.push(
1144
+ new CDSEProcessTileLayer({
1145
+ ...sharedLayerProps,
1146
+ collectionId: highResLayerData.collectionId,
1147
+ evalscript: highResLayerData.evalscript,
1148
+ minScale: highResLayerData.minScale,
1149
+ maxScale: highResLayerData.maxScale,
1150
+ title: highResLayerTitle,
1151
+ }),
1152
+ );
1153
+ }
1154
+ if (!dualResolutionLayers.length) {
1155
+ return;
1156
+ }
1157
+
1158
+ this.layers[layer.LayerId + '_' + inheritedIndexLayer] = new GroupLayer({
1159
+ title: baseLayerTitle,
1160
+ visibilityMode: 'independent',
1161
+ layers: dualResolutionLayers,
1162
+ });
1163
+ }
1164
+
950
1165
  /**
951
1166
  * This method is executed after the render method is executed
952
1167
  */
@@ -2060,6 +2275,11 @@ class MenuWidget extends React.Component {
2060
2275
  LayerTitle: layer.Title,
2061
2276
  });
2062
2277
  //iterate sublayers fetching all sublayer data
2278
+ } else if (
2279
+ layer.hasLowRes === true ||
2280
+ (layer.resolution_data?.lowRes && layer.resolution_data?.highRes)
2281
+ ) {
2282
+ this.supportDualLayers(layer, inheritedIndexLayer);
2063
2283
  } else if (viewService?.toLowerCase().includes('wms')) {
2064
2284
  viewService = viewService?.includes('?')
2065
2285
  ? viewService + '&'
@@ -6950,7 +7170,7 @@ class MenuWidget extends React.Component {
6950
7170
 
6951
7171
  getLayerTitle(layer) {
6952
7172
  let title;
6953
- if (layer.url.toLowerCase().includes('wmts')) {
7173
+ if (layer.url?.toLowerCase().includes('wmts')) {
6954
7174
  // CLMS-1105
6955
7175
  title = layer._wmtsTitle;
6956
7176
  } else {