@opengeoweb/webmap 15.3.0 → 16.0.0

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/index.esm.js CHANGED
@@ -938,36 +938,6 @@ var getFirstPartOfDimensionValueSet = function getFirstPartOfDimensionValueSet(i
938
938
  return !(inputValue != null && inputValue.indexOf) || !(inputValue != null && inputValue.includes('/')) ? inputValue : inputValue.split('/')[0];
939
939
  };
940
940
 
941
- /* *
942
- * Licensed under the Apache License, Version 2.0 (the "License");
943
- * you may not use this file except in compliance with the License.
944
- * You may obtain a copy of the License at
945
- *
946
- * http://www.apache.org/licenses/LICENSE-2.0
947
- *
948
- * Unless required by applicable law or agreed to in writing, software
949
- * distributed under the License is distributed on an "AS IS" BASIS,
950
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
951
- * See the License for the specific language governing permissions and
952
- * limitations under the License.
953
- *
954
- * Copyright 2024 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
955
- * Copyright 2024 - Finnish Meteorological Institute (FMI)
956
- * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
957
- * */
958
- var fakeMaxAgeResponsesByLayer = {
959
- 'observation:wis2_air_temperature': 600,
960
- 'fmi:observation:lightning': 300,
961
- 'fmi:observation:temperature': 3600,
962
- 'fmi:observation:dewpoint': 3600,
963
- 'fmi:observation:temperature_foreign': 3600,
964
- 'fmi:observation:dewpoint_foreign': 3600,
965
- 'fmi:observation:cloudceiling': 3600,
966
- 'fmi:observation:cloudheight': 3600,
967
- 'fmi:observation:cloudheight_foreign': 3600,
968
- 'fmi:observation:cloudceiling_foreign': 3600
969
- };
970
-
971
941
  /**
972
942
  * Returns the current time in ms
973
943
  * @returns the current time in ms
@@ -1057,6 +1027,8 @@ var WMImage = /*#__PURE__*/function () {
1057
1027
  this._hasError = false;
1058
1028
  this._numFailedAttempts = 0;
1059
1029
  this._imageTimeStampAtError = getCurrentImageTime();
1030
+ this._maxAgeSeconds = undefined;
1031
+ this._loadedAtTime = undefined;
1060
1032
  }
1061
1033
  /**
1062
1034
  * Returns true if the image has been loaded
@@ -1065,7 +1037,10 @@ var WMImage = /*#__PURE__*/function () {
1065
1037
  if (this._isLoading) {
1066
1038
  return false;
1067
1039
  }
1068
- return this._isLoaded;
1040
+ if (!this._isLoaded) {
1041
+ return false;
1042
+ }
1043
+ return !this.isStale();
1069
1044
  };
1070
1045
  _proto.isLoadedWithoutErrors = function isLoadedWithoutErrors() {
1071
1046
  return this.isLoaded() && !this.hasError();
@@ -1074,25 +1049,14 @@ var WMImage = /*#__PURE__*/function () {
1074
1049
  return !this._isLoaded && !this._isLoading;
1075
1050
  };
1076
1051
  _proto.isStale = function isStale() {
1077
- if (this._fakeMaxAge === undefined) {
1078
- try {
1079
- var layerName = new URL(this.getSrc()).searchParams.get('LAYERS');
1080
- if (layerName) {
1081
- var _fakeMaxAgeResponsesB;
1082
- this._fakeMaxAge = (_fakeMaxAgeResponsesB = fakeMaxAgeResponsesByLayer[layerName]) != null ? _fakeMaxAgeResponsesB : null;
1083
- } else {
1084
- this._fakeMaxAge = null;
1085
- }
1086
- } catch (_e) {
1087
- // failed to form URL
1088
- this._fakeMaxAge = null;
1089
- }
1052
+ if (!this._isLoaded || this._loadedAtTime === undefined) {
1053
+ return false;
1090
1054
  }
1091
- if (this._fakeMaxAge === null) {
1055
+ if (this._maxAgeSeconds === null || this._maxAgeSeconds === undefined) {
1092
1056
  return false;
1093
1057
  }
1094
- var imageAge = getCurrentImageTime() - this._loadStartTime;
1095
- var maxAge = this._fakeMaxAge * 1000;
1058
+ var imageAge = getCurrentImageTime() - this._loadedAtTime;
1059
+ var maxAge = this._maxAgeSeconds * 1000;
1096
1060
  return imageAge > maxAge;
1097
1061
  }
1098
1062
  /**
@@ -1202,8 +1166,39 @@ var WMImage = /*#__PURE__*/function () {
1202
1166
  }
1203
1167
  this._load();
1204
1168
  };
1205
- _proto._getImageWithHeaders = function _getImageWithHeaders(url, headers) {
1169
+ WMImage._parseMaxAgeFromCacheControl = function _parseMaxAgeFromCacheControl(cacheControlHeader) {
1170
+ if (!cacheControlHeader) {
1171
+ return null;
1172
+ }
1173
+ var maxAgeMatch = /(?:^|,)\s*max-age=(\d+)/i.exec(cacheControlHeader);
1174
+ if (!maxAgeMatch) {
1175
+ return null;
1176
+ }
1177
+ var parsed = Number(maxAgeMatch[1]);
1178
+ return Number.isFinite(parsed) ? parsed : null;
1179
+ };
1180
+ _proto._setMaxAgeFromResponseHeaders = function _setMaxAgeFromResponseHeaders(response) {
1181
+ this._maxAgeSeconds = WMImage._parseMaxAgeFromCacheControl(response.headers.get('cache-control'));
1182
+ };
1183
+ _proto._updateMaxAgeFromUrl = function _updateMaxAgeFromUrl(url) {
1206
1184
  var _this3 = this;
1185
+ fetch(new Request(url), {
1186
+ method: 'GET',
1187
+ mode: 'cors',
1188
+ cache: 'default',
1189
+ headers: new Headers({
1190
+ Range: 'bytes=0-0'
1191
+ })
1192
+ }).then(function (response) {
1193
+ var _response$body;
1194
+ _this3._setMaxAgeFromResponseHeaders(response);
1195
+ void ((_response$body = response.body) == null ? void 0 : _response$body.cancel());
1196
+ })["catch"](function () {
1197
+ // Keep existing behaviour if headers are not readable.
1198
+ });
1199
+ };
1200
+ _proto._getImageWithHeaders = function _getImageWithHeaders(url, headers) {
1201
+ var _this4 = this;
1207
1202
  var fetchHeaders = new Headers();
1208
1203
  if (headers && headers.length > 0) {
1209
1204
  for (var _iterator = _createForOfIteratorHelperLoose(headers), _step; !(_step = _iterator()).done;) {
@@ -1227,19 +1222,21 @@ var WMImage = /*#__PURE__*/function () {
1227
1222
  return window.btoa(binary);
1228
1223
  };
1229
1224
  fetch(request, options).then(function (response) {
1225
+ _this4._setMaxAgeFromResponseHeaders(response);
1230
1226
  response.arrayBuffer().then(function (buffer) {
1231
1227
  var base64Flag = 'data:image/png;base64,';
1232
1228
  var imageStr = arrayBufferToBase64(buffer);
1233
- _this3.getElement().src = base64Flag + imageStr;
1229
+ _this4.getElement().src = base64Flag + imageStr;
1234
1230
  })["catch"](function () {
1235
1231
  debugLogger(DebugType.Error);
1232
+ _this4._loadEvent(true);
1236
1233
  });
1237
1234
  })["catch"](function () {
1238
1235
  debugLogger(DebugType.Error, "Unable to fetch image " + url + " with headers [" + JSON.stringify(headers) + "]");
1239
1236
  if (url.startsWith('http://')) {
1240
1237
  debugLogger(DebugType.Error);
1241
1238
  }
1242
- _this3._loadEvent(true);
1239
+ _this4._loadEvent(true);
1243
1240
  });
1244
1241
  };
1245
1242
  _proto._load = function _load() {
@@ -1247,8 +1244,12 @@ var WMImage = /*#__PURE__*/function () {
1247
1244
  this._loadStartTime = getCurrentImageTime();
1248
1245
  this._hasError = false;
1249
1246
  if (this._isLoaded) {
1250
- this._loadEvent(false);
1251
- return;
1247
+ if (!this.isStale()) {
1248
+ this._loadEvent(false);
1249
+ return;
1250
+ }
1251
+ this._isLoaded = false;
1252
+ this._srcLoaded = undefined;
1252
1253
  }
1253
1254
  this._isLoading = true;
1254
1255
  if (!this.srcToLoad) {
@@ -1275,6 +1276,7 @@ var WMImage = /*#__PURE__*/function () {
1275
1276
  this._getImageWithHeaders(this.srcToLoad, this.headers);
1276
1277
  } else if (this.randomize) {
1277
1278
  /* Do a standard img.src url request */
1279
+ this._maxAgeSeconds = null;
1278
1280
  var newSrc = this.srcToLoad;
1279
1281
  if (!this.srcToLoad.includes('?')) {
1280
1282
  newSrc += '?';
@@ -1290,8 +1292,9 @@ var WMImage = /*#__PURE__*/function () {
1290
1292
  }
1291
1293
  this.getElement().src = newSrc;
1292
1294
  } else {
1293
- // setting src loads the image and the 'load' callback is called when its finished loading
1295
+ // Keep the browser image loading path for rendering reliability.
1294
1296
  this.getElement().src = this.srcToLoad;
1297
+ this._updateMaxAgeFromUrl(this.srcToLoad);
1295
1298
  }
1296
1299
  };
1297
1300
  _proto._loadEvent = function _loadEvent(hasError) {
@@ -1300,6 +1303,7 @@ var WMImage = /*#__PURE__*/function () {
1300
1303
  this._hasError = hasError;
1301
1304
  this._isLoading = false;
1302
1305
  this._isLoaded = true;
1306
+ this._loadedAtTime = hasError ? undefined : getCurrentImageTime();
1303
1307
  this._srcLoaded = this.srcToLoad;
1304
1308
  this._resolveAll();
1305
1309
  (_this$loadEventCallba = this.loadEventCallback) == null || _this$loadEventCallba.call(this, this);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/webmap",
3
- "version": "15.3.0",
3
+ "version": "16.0.0",
4
4
  "description": "GeoWeb webmap library for the opengeoweb project",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -8,7 +8,7 @@
8
8
  "url": "git@gitlab.com:opengeoweb/opengeoweb.git"
9
9
  },
10
10
  "dependencies": {
11
- "@opengeoweb/shared": "15.3.0",
11
+ "@opengeoweb/shared": "16.0.0",
12
12
  "@tanstack/query-core": "^5.69.2",
13
13
  "lodash": "^4.17.21",
14
14
  "i18next": "^25.0.1",
@@ -34,7 +34,8 @@ export default class WMImage {
34
34
  _numFailedAttempts: number;
35
35
  _loadStartTime: number;
36
36
  _loadDuration?: number;
37
- _fakeMaxAge?: number | null;
37
+ _maxAgeSeconds?: number | null;
38
+ _loadedAtTime?: number;
38
39
  _resolveList: ((i: WMImage) => void)[];
39
40
  geoReference: WMGeoReference | null;
40
41
  hashUrl: string | undefined;
@@ -92,6 +93,9 @@ export default class WMImage {
92
93
  loadAwait(): Promise<WMImage>;
93
94
  load(): void;
94
95
  forceReload(randomize?: boolean): void;
96
+ private static _parseMaxAgeFromCacheControl;
97
+ private _setMaxAgeFromResponseHeaders;
98
+ private _updateMaxAgeFromUrl;
95
99
  private _getImageWithHeaders;
96
100
  _load(): void;
97
101
  _loadEvent(hasError: boolean): void;
@@ -34,6 +34,7 @@ export interface LayerFoundation extends TiledLayerFoundation {
34
34
  type?: string;
35
35
  geojson?: FeatureCollection;
36
36
  options?: EDRFeatureLayerOptions;
37
+ showLayerLegend?: boolean;
37
38
  }
38
39
  export interface LayerOptions extends LayerFoundation {
39
40
  id: string;