From 28bf5e1289446b41a53e8b79c0d46e1e084e0dd5 Mon Sep 17 00:00:00 2001 From: Benjamin Gerber Date: Mon, 7 Oct 2024 20:42:18 +0200 Subject: [PATCH 1/2] Remove ol-cesium --- .github/renovate.json5 | 5 - buildtools/extract-ngeo-dependencies | 1 - package.json | 4 +- src/olcs/Manager.js | 57 ----- src/olcs/Service.js | 164 -------------- src/olcs/constants.js | 55 ----- src/olcs/controls3d.html.js | 35 --- src/olcs/controls3d.js | 315 --------------------------- src/olcs/controls3d.scss | 124 ----------- src/olcs/img/angle.png | Bin 6791 -> 0 bytes src/olcs/img/left.png | Bin 1507 -> 0 bytes src/olcs/img/left_grey.png | Bin 809 -> 0 bytes src/olcs/img/right.png | Bin 1491 -> 0 bytes src/olcs/img/right_grey.png | Bin 792 -> 0 bytes src/olcs/img/rotation.png | Bin 5296 -> 0 bytes src/olcs/img/zoomin.png | Bin 836 -> 0 bytes src/olcs/img/zoomout.png | Bin 877 -> 0 bytes src/olcs/olcsModule.js | 32 --- src/permalink/Permalink.js | 18 +- 19 files changed, 8 insertions(+), 802 deletions(-) delete mode 100644 src/olcs/Manager.js delete mode 100644 src/olcs/Service.js delete mode 100644 src/olcs/constants.js delete mode 100644 src/olcs/controls3d.html.js delete mode 100644 src/olcs/controls3d.js delete mode 100644 src/olcs/controls3d.scss delete mode 100644 src/olcs/img/angle.png delete mode 100644 src/olcs/img/left.png delete mode 100644 src/olcs/img/left_grey.png delete mode 100644 src/olcs/img/right.png delete mode 100644 src/olcs/img/right_grey.png delete mode 100644 src/olcs/img/rotation.png delete mode 100644 src/olcs/img/zoomin.png delete mode 100644 src/olcs/img/zoomout.png delete mode 100644 src/olcs/olcsModule.js diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 6d321eb36dc2..07cc4682beea 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -98,11 +98,6 @@ groupName: 'CI dependencies', automerge: true, }, - /** Disable ol-cesium updates */ - { - enabled: false, - matchDepNames: ['ol-cesium'], - }, /** Packages published very recently are not pushed to stabilization branches for security reasons */ { matchBaseBranches: ['/^[0-9]+\\.[0-9]+$/'], diff --git a/buildtools/extract-ngeo-dependencies b/buildtools/extract-ngeo-dependencies index e148d41fdce4..1aa5c356f6ad 100755 --- a/buildtools/extract-ngeo-dependencies +++ b/buildtools/extract-ngeo-dependencies @@ -51,7 +51,6 @@ all_required_js = {a for a in all_required_js if not a.startswith("./")} all_required_js = {a for a in all_required_js if not a.startswith("ngeo/")} all_required_js = {a for a in all_required_js if not a.startswith("gmf/")} all_required_js = {a for a in all_required_js if not a.startswith("gmfapi/")} -all_required_js = {a for a in all_required_js if not a.startswith("olcs/")} all_required_js = {a for a in all_required_js if not a.startswith("jsts/")} all_required_js = {a for a in all_required_js if not a.startswith("mapillary-js/")} all_required_js = { diff --git a/package.json b/package.json index 09a564e2f20d..a60e1c192f83 100644 --- a/package.json +++ b/package.json @@ -107,9 +107,7 @@ "_optionalDependenciesComment_": "Dep. for plugins", "optionalDependencies": { "jsts": "2.11.3", - "localforage": "1.10.0", - "mapillary-js": "4.1.2", - "ol-cesium": "2.14.0" + "mapillary-js": "4.1.2" }, "devDependencies": { "@chromatic-com/storybook": "2.0.2", diff --git a/src/olcs/Manager.js b/src/olcs/Manager.js deleted file mode 100644 index fb6ff110300b..000000000000 --- a/src/olcs/Manager.js +++ /dev/null @@ -1,57 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2017-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import olcsContribManager from 'olcs/contrib/Manager'; - -/** - * @hidden - */ -class Manager extends olcsContribManager { - /** - * @param {string} url . - * @param {angular.IScope} $rootScope . - * @param {import('olcs/contrib/Manager').ManagerOptions} options . - */ - constructor(url, $rootScope, options) { - super(url, options); - /** - * @type {angular.IScope} - * @private - */ - this.rootScope_ = $rootScope; - } - - /** - * @override - */ - toggle3d() { - // The transition is asynchronous and at the end of it the state of OLCesium is changed. - // In order to have all code dependent on OLCesium state updated, we kick an Angular digest cycle. - const promise = super.toggle3d(); - return /** @type {Promise} */ ( - promise.then(() => { - this.rootScope_.$apply(); - }) - ); - } -} - -export default Manager; diff --git a/src/olcs/Service.js b/src/olcs/Service.js deleted file mode 100644 index 2d766dfa6aa3..000000000000 --- a/src/olcs/Service.js +++ /dev/null @@ -1,164 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2017-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import angular from 'angular'; -import ngeoMiscDebounce from 'ngeo/misc/debounce'; -import ngeoStatemanagerLocation from 'ngeo/statemanager/Location'; -import {Permalink3dParam} from 'ngeo/olcs/constants'; -import ngeoStatemanagerService from 'ngeo/statemanager/Service'; -import {toDegrees} from 'ol/math'; - -/** - * @hidden - */ -export class OlcsService { - /** - * @param {import('ngeo/misc/debounce').miscDebounce} ngeoDebounce ngeo debounce - * service. - * @param {import('ngeo/statemanager/Location').StatemanagerLocation} ngeoLocation ngeo location - * service. - * @param {import('ngeo/statemanager/Service').StatemanagerService} ngeoStateManager The ngeo - * StateManager service. - */ - constructor(ngeoDebounce, ngeoLocation, ngeoStateManager) { - /** - * @private - * @type {?import('olcs/contrib/Manager').default} - */ - this.manager_ = null; - - /** - * @private - * @type {import('ngeo/misc/debounce').miscDebounce} - */ - this.ngeoDebounce_ = ngeoDebounce; - - /** - * @private - * @type {import('ngeo/statemanager/Location').StatemanagerLocation} - */ - this.ngeoLocation_ = ngeoLocation; - - /** - * @private - * @type {import('ngeo/statemanager/Service').StatemanagerService} - */ - this.ngeoStateManager_ = ngeoStateManager; - } - - /** - * @param {import('olcs/contrib/Manager').default} manager Manager. - */ - initialize(manager) { - this.manager_ = manager; - this.manager_.on('load', () => { - this.cameraToState_(); - }); - if (this.ngeoStateManager_.getInitialBooleanValue('3d_enabled')) { - this.initialStateToCamera_(); - } - } - - /** - * @returns {?import('olcs/contrib/Manager').default} the manager. - */ - getManager() { - return this.manager_; - } - - /** - * @private - * @returns {Promise} A promise after load & enabled. - */ - initialStateToCamera_() { - if (!this.manager_) { - throw new Error('Missing manager'); - } - const stateManager = this.ngeoStateManager_; - const lon = stateManager.getInitialNumberValue(Permalink3dParam.LON); - const lat = stateManager.getInitialNumberValue(Permalink3dParam.LAT); - const elevation = stateManager.getInitialNumberValue(Permalink3dParam.ELEVATION); - const heading = stateManager.getInitialNumberValue(Permalink3dParam.HEADING) || 0; - const pitch = stateManager.getInitialNumberValue(Permalink3dParam.PITCH) || 0; - if (!lon) { - throw new Error('Missing lon'); - } - if (!lat) { - throw new Error('Missing lat'); - } - if (!elevation) { - throw new Error('Missing elevation'); - } - return this.manager_.set3dWithView(lon, lat, elevation, heading, pitch); - } - - /** - * @private - */ - cameraToState_() { - if (!this.manager_) { - throw new Error('Missing manager'); - } - const manager = this.manager_; - const scene = manager.getOl3d().getCesiumScene(); - const camera = scene.camera; - camera.moveEnd.addEventListener( - this.ngeoDebounce_( - () => { - const position = camera.positionCartographic; - this.ngeoStateManager_.updateState({ - [Permalink3dParam.ENABLED]: true, - [Permalink3dParam.LON]: toDegrees(position.longitude).toFixed(5), - [Permalink3dParam.LAT]: toDegrees(position.latitude).toFixed(5), - [Permalink3dParam.ELEVATION]: position.height.toFixed(0), - [Permalink3dParam.HEADING]: toDegrees(camera.heading).toFixed(3), - [Permalink3dParam.PITCH]: toDegrees(camera.pitch).toFixed(3), - }); - }, - 1000, - true, - ), - ); - this.manager_.on('toggle', (event) => { - if (!event.target.is3dEnabled()) { - this.remove3dState_(); - } - }); - } - - /** - * @private - */ - remove3dState_() { - this.ngeoLocation_.getParamKeysWithPrefix(Permalink3dParam.PREFIX).forEach((key) => { - this.ngeoStateManager_.deleteParam(key); - }); - } -} -OlcsService.$inject = ['ngeoDebounce', 'ngeoLocation', 'ngeoStateManager']; -/** - * @type {angular.IModule} - * @hidden - */ -const myModule = angular - .module(name, [ngeoMiscDebounce.name, ngeoStatemanagerLocation.name, ngeoStatemanagerService.name]) - .service('ngeoOlcsService', OlcsService); -export default myModule; diff --git a/src/olcs/constants.js b/src/olcs/constants.js deleted file mode 100644 index 3f899f3600b9..000000000000 --- a/src/olcs/constants.js +++ /dev/null @@ -1,55 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -/** - * @enum {string} - * @hidden - */ -export const Permalink3dParam = { - /** - * @type {string} - */ - ENABLED: '3d_enabled', - /** - * @type {string} - */ - LON: '3d_lon', - /** - * @type {string} - */ - LAT: '3d_lat', - /** - * @type {string} - */ - ELEVATION: '3d_elevation', - /** - * @type {string} - */ - HEADING: '3d_heading', - /** - * @type {string} - */ - PITCH: '3d_pitch', - /** - * @type {string} - */ - PREFIX: '3d_', -}; diff --git a/src/olcs/controls3d.html.js b/src/olcs/controls3d.html.js deleted file mode 100644 index 76d92ed9e13f..000000000000 --- a/src/olcs/controls3d.html.js +++ /dev/null @@ -1,35 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -export default `
-
- - -
-
- - -
-
-
- - -
`; diff --git a/src/olcs/controls3d.js b/src/olcs/controls3d.js deleted file mode 100644 index b2222e7cb9a2..000000000000 --- a/src/olcs/controls3d.js +++ /dev/null @@ -1,315 +0,0 @@ -ngeoOlcsControls3dTemplateUrlInjectable.$inject = ['$attrs', 'ngeoOlcsControls3dTemplateUrl']; -// The MIT License (MIT) -// -// Copyright (c) 2017-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -/* global Cesium */ - -import angular from 'angular'; -import * as olEasing from 'ol/easing'; -import {toRadians} from 'ol/math'; -import olcsCore from 'olcs/core'; -import htmlTemplate from './controls3d.html'; - -/** - * @type {angular.IModule} - * @hidden - */ -const myModule = angular.module('ngeoOlcsControls3d', []); - -/** - * @private - * @hidden - * @param {number} older Older - * @param {number} newer Newer - * @returns {boolean} ? - */ -function shouldUpdate(older, newer) { - return Number.isFinite(newer) && (!Number.isFinite(older) || Math.abs(newer - older) > 0.05); -} - -/** - * @hidden - */ -export class Controller { - /** - * @param {JQuery} $element The element - * @param {import('ngeo/olcs/Service').OlcsService} ngeoOlcsService The ol-cesium service. - */ - constructor($element, ngeoOlcsService) { - /** - * @type {JQuery} - * @private - */ - this.element_ = $element; - - /** - * @type {?import('olcs/contrib/Manager').default} - */ - this.ol3dm = null; - - /** - * @type {number} - */ - this.minTilt = -1; - - /** - * @type {number} - * @private - */ - this.maxTilt = -1; - - /** - * @type {?JQuery} - * @private - */ - this.tiltRightEl_ = null; - - /** - * @type {?JQuery} - * @private - */ - this.tiltLeftEl_ = null; - - /** - * @type {?JQuery} - * @private - */ - this.rotation3dEl_ = null; - - /** - * @type {?JQuery} - * @private - */ - this.angle3dEl_ = null; - - /** - * @type {number} - * @private - */ - this.previousRotation_ = -1; - - /** - * @type {?Cesium.Matrix4} - * @private - */ - this.previousViewMatrix_ = null; - - /** - * @type {number} - * @private - */ - this.animationFrameRequestId_ = -1; - - /** - * @type {import('ngeo/olcs/Service').OlcsService} - * @private - */ - this.olcsService_ = ngeoOlcsService; - } - updateWidget_() { - if (!this.ol3dm) { - throw new Error('Missing ol3dm'); - } - if (!this.rotation3dEl_) { - throw new Error('Missing rotation3dEl_'); - } - if (!this.angle3dEl_) { - throw new Error('Missing angle3dEl_'); - } - if (!this.tiltRightEl_) { - throw new Error('Missing tiltRightEl_'); - } - if (!this.tiltLeftEl_) { - throw new Error('Missing tiltLeftEl_'); - } - const newRotation = this.ol3dm.getOl3d().getOlView().getRotation(); - if (shouldUpdate(this.previousRotation_, newRotation)) { - this.rotateElement_(this.rotation3dEl_, newRotation); - this.previousRotation_ = newRotation; - } - const newViewMatrix = this.ol3dm.getCesiumViewMatrix(); - if (!Cesium.Matrix4.equalsEpsilon(this.previousViewMatrix_, newViewMatrix, 1e-5)) { - const newTilt = this.ol3dm.getTiltOnGlobe(); // this is expensive!! - if (newTilt != undefined && Number.isFinite(newTilt || 0)) { - this.rotateElement_(this.angle3dEl_, newTilt); - this.previousViewMatrix_ = Cesium.Matrix4.clone(newViewMatrix); - - // if min or max tilt is reached, disable the tilting buttons - const buffer = 0.01; // rad - if (newTilt - this.minTilt < buffer) { - this.tiltRightEl_.addClass('ngeo-right-inactive'); - } else if (this.tiltRightEl_.hasClass('ngeo-right-inactive')) { - this.tiltRightEl_.removeClass('ngeo-right-inactive'); - } - if (this.maxTilt - newTilt < buffer) { - this.tiltLeftEl_.addClass('ngeo-left-inactive'); - } else if (this.tiltLeftEl_.hasClass('ngeo-left-inactive')) { - this.tiltLeftEl_.removeClass('ngeo-left-inactive'); - } - } - } - this.animationFrameRequestId_ = requestAnimationFrame(() => this.updateWidget_()); - } - $onDestroy() { - if (this.animationFrameRequestId_) { - cancelAnimationFrame(this.animationFrameRequestId_); - } - } - $onInit() { - if (this.minTilt === undefined) { - this.minTilt = 0; - } - if (this.maxTilt === undefined) { - this.maxTilt = (7 * Math.PI) / 16; - } - if (!this.ol3dm) { - this.ol3dm = this.olcsService_.getManager() || null; - } - this.tiltRightEl_ = this.element_.find('.ngeo-tilt-right'); - this.tiltLeftEl_ = this.element_.find('.ngeo-tilt-left'); - this.rotation3dEl_ = this.element_.find('.ngeo-rotation3d'); - this.angle3dEl_ = this.element_.find('.ngeo-angle3d'); - this.updateWidget_(); - } - - /** - * @param {JQuery} element Element to rotate. - * @param {(number|undefined)} angle Angle in radians - * @private - */ - rotateElement_(element, angle) { - const r = `rotate(${angle}rad)`; - element.css({ - '-moz-transform': r, - '-webkit-transform': r, - '-o-transform': r, - '-ms-transform': r, - 'transform': r, - }); - } - - /** - * @param {number} angle Angle in degrees. - */ - rotate(angle) { - if (!this.ol3dm) { - throw new Error('Missing ol3dm'); - } - this.ol3dm.setHeading(toRadians(angle)); - } - - /** - * @param {number} angle Angle in degrees. - */ - tilt(angle) { - if (!this.ol3dm) { - throw new Error('Missing ol3dm'); - } - angle = toRadians(angle); - const tiltOnGlobe = Number(this.ol3dm.getTiltOnGlobe()); - if (tiltOnGlobe + angle < this.minTilt) { - angle = this.minTilt - tiltOnGlobe; - } else if (tiltOnGlobe + angle > this.maxTilt) { - angle = this.maxTilt - tiltOnGlobe; - } - const scene = this.ol3dm.getCesiumScene(); - olcsCore.rotateAroundBottomCenter(scene, angle); - } - - /** - * @param {number} delta 1 to zoom out and 1 to zoom in. - */ - zoom(delta) { - if (!this.ol3dm) { - throw new Error('Missing ol3dm'); - } - const view = this.ol3dm.getOlView(); - const cur = view.getResolution(); - const newResolution = view.constrainResolution(cur, delta); - if (view.getAnimating()) { - view.cancelAnimations(); - } - view.animate({ - resolution: newResolution, - duration: 250, - easing: olEasing.easeOut, - }); - } -} -Controller.$inject = ['$element', 'ngeoOlcsService']; -/** - * @param {angular.IAttributes} $attrs Attributes. - * @param {string} ngeoOlcsControls3dTemplateUrl Template function. - * @returns {string} Template URL. - * @private - * @hidden - */ -function ngeoOlcsControls3dTemplateUrlInjectable($attrs, ngeoOlcsControls3dTemplateUrl) { - if (ngeoOlcsControls3dTemplateUrl) { - return ngeoOlcsControls3dTemplateUrl; - } - const templateUrl = $attrs['ngeoOlcsControls3dTemplateUrl']; - return templateUrl ? templateUrl : 'ngeo/olsc/controls3d'; -} -myModule.run( - /** - * @param {angular.ITemplateCacheService} $templateCache - */ - [ - '$templateCache', - ($templateCache) => { - // @ts-ignore: webpack - $templateCache.put('ngeo/olsc/controls3d', htmlTemplate); - }, - ], -); - -/** - * Provides the "ngeoOlcsControls3d" component, a widget for - * controlling the 3D camera. - * - * Example: - * - * - * - * - * By default the directive uses "controls3d.html" as its templateUrl. This - * can be changed by redefining the "ngeoOlcsControls3dTemplateUrl" value. - * - * See our live example: [../examples/simple3d.html](../examples/simple3d.html) - * - * @htmlAttribute {olcs.contrib.Manager} ngeo-olcs-manager The OL-Cesium manager. - * @type {angular.IComponentOptions} - * @ngdoc component - * @ngname ngeoOlcsControls3d - */ -const olscControls3dComponent = { - bindings: { - 'minTilt': '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 JPDHLkV1mnl&%OWv diff --git a/src/olcs/img/left_grey.png b/src/olcs/img/left_grey.png deleted file mode 100644 index 84917ca06535ccb1195750bede72c80ecbf0992b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 809 zcmV+^1J?YBP)eSad^g zZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00NasL_t(Y$IX??PE%17hQEETiUS+e32~rIyvC?Ch8RVpm~by`PkT;j zORw7j&z)j-*^8ND0U@&jtyZ>lV+EkXy`?J^rloh#iu$ z&<&m^DYtn@v_{xufe3oA*a(5>m+Tm{fuFSpk!W0aUmj=sZ zD$))Ly*QUF-3+Y-7yXRZHSZmJqynXGa0N%mgAY@U_=ETC&mFY6cct2C$CL*z=WFU0 zyyOEBY50nr*M*gSMi|FY*S-awu@#QXLu7m0gerzO$0VZ8;5GO7%(m2K4;#u5wVoxC zvzvEU_{d6~1;98rxQGjf-?nb9bV$^vlqV)P`N=23O}6M6F5zbk6+1R;)7B+%x}pp* zxxp%5S!>APBwRRAxykkFt~&`EZc&zC#>IDXO)YeE;4Bl3xWJA_D6$7TDq*&eEwa$j z8*xyuqX>(%;beeeHrQ)wVPG`Fj|?or=2OFN2JsRh!Y}EO00000NkvXXu0mjfpKDv1 diff --git a/src/olcs/img/right.png b/src/olcs/img/right.png deleted file mode 100644 index f17ce79ee85dc7673330e86c0fac91669a9cc92b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1491 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 diff --git a/src/olcs/img/zoomin.png b/src/olcs/img/zoomin.png deleted file mode 100644 index 77a0d83e8a59ad4587d4bc32ef693ef89ff3df3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 836 zcmV-K1H1f*P)qYe zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00OK@L_t(I%dJ&CPbxtaJ+scP zV1;I^Z80=-*zr-(>>t?5#F&@}2`2WqKfuIfwIIf*4K2ksG^|jeosGd3E!ij)uFkS! zwIlO@_blG6COfm|o;mm4Geii1MbYc^M5oii^Yb%CqY(gLb8{2h+uJCWO33H)WYK@* zPr!$V2T`xr;rl))r3;gVVF<<;Y}-aImm^C7&(F`r<>e)k$s~RgK@ebne;K^jP#E6d-;0BT10)g&dDt)v z)M_=DrU_lw0RWtHxUP${vom~seJM;EjRtbL93esol*?r?9*^aLt*tFIn@y~&tSr^g zvMjv3yvT2LO3`dKVHk$o^L-z^UQcMA=gDeDQG}zT zBZV0u1er_*nM?+R{1lW@idwBEHKmlo^E_yS!9X7R`1pWnnsdx_U6(q}?wO{EAPD65 z!C(M7d)J#_;<33IKS2e@7UG zpp-%gA(>>eSpdM}uB-HJ zI-Lf&ySo#|$H!8;)zwvao~N`;3^2Q%PNygqi&DQZ3~_pT3awBm5XP9y^7;7*%d#+? zPUo1;f?1ZOObcTS`Fx&e08p>jmGTdVLzGG-v|25MVW><F2t*tY#EgFQJp!OqSO`Kx2c(d~BS6A(`mV@y5)g+gKB6YveB@n2XqA;*sZ O0000e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00PxXL_t(I%dJ#BPvbxkee2kJ zS*n1bLKYOHA`$<9NOT4a1tLW{x(HE(HhkDV0ktJWgM_F+A{{bc9lCUsk)c8qKp7OE zNpkVWUUBkX63C&GZYpbL_Icj!n@7+Uhlht`X=#aDmSq4iZ*Ol=tyTd5LqkJIr_lHEK!NCD(G#bYK{{Ch=7^M`2LIJw2Ls687DjdgwZQE$IS{;+-^ZDtrqU??xLxXNF)U9YPI@D zHvcQ+!NEa1KR*KiUSD6~`#xk@2IpK%@)>192t3cj+uIxZ`ufCbN~u&zG{)m`IF2JI z_ll_II1b|RxX7ncDM+5@ZF-)^0YH)@*tU%z2)?8i1OaT@h9pTsHULb*Ij7ld_Gi0D zzY=y31jyxbXkUg%*fCXA!{Om!+}zw`B0avpzvJlW2#G`j$z)PY;rl*LPfwB0=TWQG zI#zFCVd4AY;^Gg|ZVp#hSLt@k3d0c1W)uDW{Q!Vktp>)J_(4Qf(=>N`dwb%8eHDwv z%Guf3KiSvp?5w-9voq1tV0U+S&2qVHJUl%7)nLcQ#>nL4q_wiL(qXV4gv}VUN~O{_ zP16ib)1ay<7-L|JK~+^uPfufJX2vX)N`x_Hb)WwQ)qqL Date: Mon, 7 Oct 2024 20:46:20 +0200 Subject: [PATCH 2/2] Remove offline --- DEVELOPING.md | 2 +- package-lock.json | 385 +------------- src/offline/AbstractLocalforageWrapper.js | 147 ------ src/offline/Configuration.js | 398 --------------- src/offline/Downloader.js | 196 -------- src/offline/LocalforageAndroidWrapper.js | 53 -- src/offline/LocalforageCordovaWrapper.js | 39 -- src/offline/LocalforageIosWrapper.js | 66 --- src/offline/Mask.js | 109 ---- src/offline/Mode.js | 107 ---- src/offline/NetworkStatus.js | 224 --------- src/offline/Restorer.js | 79 --- src/offline/SerializerDeserializer.js | 271 ---------- src/offline/ServiceManager.js | 134 ----- src/offline/TilesDownloader.js | 223 --------- src/offline/component.html.js | 182 ------- src/offline/component.js | 578 ---------------------- src/offline/index.js | 81 --- src/offline/module.js | 44 -- src/offline/utils.js | 53 -- src/options.js | 6 - srcapi/store/config.spec.ts | 10 +- srcapi/store/config.ts | 6 - 23 files changed, 9 insertions(+), 3384 deletions(-) delete mode 100644 src/offline/AbstractLocalforageWrapper.js delete mode 100644 src/offline/Configuration.js delete mode 100644 src/offline/Downloader.js delete mode 100644 src/offline/LocalforageAndroidWrapper.js delete mode 100644 src/offline/LocalforageCordovaWrapper.js delete mode 100644 src/offline/LocalforageIosWrapper.js delete mode 100644 src/offline/Mask.js delete mode 100644 src/offline/Mode.js delete mode 100644 src/offline/NetworkStatus.js delete mode 100644 src/offline/Restorer.js delete mode 100644 src/offline/SerializerDeserializer.js delete mode 100644 src/offline/ServiceManager.js delete mode 100644 src/offline/TilesDownloader.js delete mode 100644 src/offline/component.html.js delete mode 100644 src/offline/component.js delete mode 100644 src/offline/index.js delete mode 100644 src/offline/module.js delete mode 100644 src/offline/utils.js diff --git a/DEVELOPING.md b/DEVELOPING.md index f791ce76b1b7..1e4bb376ed56 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -9,7 +9,7 @@ make serve-ngeo Use the _ONE_EXAMPLE_ environment variable to build (and rebuild on each change) only one example. ``` -ONE_EXAMPLE=offline make serve-ngeo +ONE_EXAMPLE=simple make serve-ngeo ``` The ngeo examples are now available on your https://localhost:3000/examples/. diff --git a/package-lock.json b/package-lock.json index 7801acde744e..554f7afc6797 100644 --- a/package-lock.json +++ b/package-lock.json @@ -155,9 +155,7 @@ }, "optionalDependencies": { "jsts": "2.11.3", - "localforage": "1.10.0", - "mapillary-js": "4.1.2", - "ol-cesium": "2.14.0" + "mapillary-js": "4.1.2" }, "peerDependencies": { "color-rgba": "3.0.0", @@ -1049,53 +1047,6 @@ "node": ">=6.9.0" } }, - "node_modules/@cesium/engine": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@cesium/engine/-/engine-11.1.0.tgz", - "integrity": "sha512-vrEQAbYQuXt2cMYF9BpBu4Kxu+8uje1CrFHfyI5aNp7gCrUK1RYquldyqT7TDr3YKe7oZMHL+Xeb5Vm8ua6gZQ==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "@tweenjs/tween.js": "^25.0.0", - "@zip.js/zip.js": "^2.7.34", - "autolinker": "^4.0.0", - "bitmap-sdf": "^1.0.3", - "dompurify": "^3.0.2", - "draco3d": "^1.5.1", - "earcut": "^3.0.0", - "grapheme-splitter": "^1.0.4", - "jsep": "^1.3.8", - "kdbush": "^4.0.1", - "ktx-parse": "^0.7.0", - "lerc": "^2.0.0", - "mersenne-twister": "^1.1.0", - "meshoptimizer": "^0.21.0", - "pako": "^2.0.4", - "protobufjs": "^7.1.0", - "rbush": "3.0.1", - "topojson-client": "^3.1.0", - "urijs": "^1.19.7" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@cesium/widgets": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@cesium/widgets/-/widgets-8.1.0.tgz", - "integrity": "sha512-WD5eokNfSQmB3oqe97KmdmDefwzooHaMWBm9kE/Af9edyD2j3eQVTrbNhiJ06UIyEjd01U1af2iDOawI9adAgA==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "@cesium/engine": "^11.1.0", - "nosleep.js": "^0.12.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/@chromatic-com/storybook": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-2.0.2.tgz", @@ -2199,90 +2150,6 @@ "url": "https://opencollective.com/popperjs" } }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true - }, "node_modules/@puppeteer/browsers": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.0.tgz", @@ -3906,14 +3773,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@tweenjs/tween.js": { - "version": "25.0.0", - "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-25.0.0.tgz", - "integrity": "sha512-XKLA6syeBUaPzx4j3qwMqzzq+V4uo72BnlbOjmuljLrRqdsd3qnzvZZoxvMHZ23ndsRS4aufU6JOZYpCbU6T1A==", - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/@types/angular": { "version": "1.8.9", "resolved": "https://registry.npmjs.org/@types/angular/-/angular-1.8.9.tgz", @@ -4590,7 +4449,7 @@ "version": "20.16.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz", "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.19.2" @@ -5411,19 +5270,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/@zip.js/zip.js": { - "version": "2.7.52", - "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.52.tgz", - "integrity": "sha512-+5g7FQswvrCHwYKNMd/KFxZSObctLSsQOgqBSi0LzwHo3li9Eh1w5cF5ndjQw9Zbr3ajVnd2+XyiX85gAetx1Q==", - "license": "BSD-3-Clause", - "optional": true, - "peer": true, - "engines": { - "bun": ">=0.7.0", - "deno": ">=1.0.0", - "node": ">=16.5.0" - } - }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -5935,17 +5781,6 @@ "node": ">= 4.0.0" } }, - "node_modules/autolinker": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-4.0.0.tgz", - "integrity": "sha512-fl5Kh6BmEEZx+IWBfEirnRUU5+cOiV0OK7PEt0RBKvJMJ8GaRseIOeDU3FKf4j3CE5HVefcjHmhYPOcaVt0bZw==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.3.0" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -6997,14 +6832,6 @@ "integrity": "sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA==", "license": "CC0-1.0" }, - "node_modules/bitmap-sdf": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/bitmap-sdf/-/bitmap-sdf-1.0.4.tgz", - "integrity": "sha512-1G3U4n5JE6RAiALMxu0p1XmeZkTeCwGKykzsLTCqVzfSDaN6S7fKnkIkfejogz+iwqBWc0UYAIKnKHNN7pSfDg==", - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/bl": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", @@ -7481,25 +7308,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/cesium": { - "version": "1.122.0", - "resolved": "https://registry.npmjs.org/cesium/-/cesium-1.122.0.tgz", - "integrity": "sha512-zHxF4QMVE9/ukhxvV/UULzytZp5uz0JVjegc+qxfhHtvN3crFbpL6/8frkVrcQ0GTjH6/LT1AcMERj/bNdVYng==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "workspaces": [ - "packages/engine", - "packages/widgets" - ], - "dependencies": { - "@cesium/engine": "^11.1.0", - "@cesium/widgets": "^8.1.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, "node_modules/chai": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", @@ -9619,14 +9427,6 @@ "domelementtype": "1" } }, - "node_modules/dompurify": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz", - "integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==", - "license": "(MPL-2.0 OR Apache-2.0)", - "optional": true, - "peer": true - }, "node_modules/domutils": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", @@ -9647,14 +9447,6 @@ "tslib": "^2.0.3" } }, - "node_modules/draco3d": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.7.tgz", - "integrity": "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==", - "license": "Apache-2.0", - "optional": true, - "peer": true - }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -11938,14 +11730,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -12875,13 +12659,6 @@ "node": ">= 4" } }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "license": "MIT", - "optional": true - }, "node_modules/immutable": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", @@ -13717,17 +13494,6 @@ "node": ">=12.0.0" } }, - "node_modules/jsep": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.9.tgz", - "integrity": "sha512-i1rBX5N7VPl0eYb6+mHNp52sEuaS2Wi8CDYx1X5sn9naevL78+265XJqy1qENEk7mRKwS06NHpUqiBwR7qeodw==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 10.16.0" - } - }, "node_modules/jsesc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", @@ -14086,14 +13852,6 @@ "node": ">=0.10.0" } }, - "node_modules/kdbush": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", - "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==", - "license": "ISC", - "optional": true, - "peer": true - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -14114,14 +13872,6 @@ "node": ">=0.10.0" } }, - "node_modules/ktx-parse": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.7.1.tgz", - "integrity": "sha512-FeA3g56ksdFNwjXJJsc1CCc7co+AJYDp6ipIp878zZ2bU8kWROatLYf39TQEd4/XRSUvBXovQ8gaVKWPXsCLEQ==", - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/launch-editor": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", @@ -14152,14 +13902,6 @@ "node": ">=10.13.0" } }, - "node_modules/lerc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lerc/-/lerc-2.0.0.tgz", - "integrity": "sha512-7qo1Mq8ZNmaR4USHHm615nEW2lPeeWJ3bTyoqFbd35DLx0LUH7C6ptt5FDCTAlbIzs3+WKrk5SkJvw8AFDE2hg==", - "license": "Apache-2.0", - "optional": true, - "peer": true - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -14174,16 +13916,6 @@ "node": ">= 0.8.0" } }, - "node_modules/lie": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", - "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", - "license": "MIT", - "optional": true, - "dependencies": { - "immediate": "~3.0.5" - } - }, "node_modules/lilconfig": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", @@ -14329,16 +14061,6 @@ "integrity": "sha512-JKwc6JOsmKxBZTKNA666x+7qiJpdR+XtHpKJhY7s5bR/Q/NJNDpLae/Dgx4EFC/j6YbelR3t0qEw2ZFhCdG/Cw==", "license": "MIT" }, - "node_modules/localforage": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", - "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "lie": "3.1.1" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -14546,14 +14268,6 @@ "node": ">=8.0" } }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "license": "Apache-2.0", - "optional": true, - "peer": true - }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -14931,22 +14645,6 @@ "node": ">= 8" } }, - "node_modules/mersenne-twister": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mersenne-twister/-/mersenne-twister-1.1.0.tgz", - "integrity": "sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/meshoptimizer": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.21.0.tgz", - "integrity": "sha512-WabtlpnK/GgD0GMwYd1fBTfYHf4MIcQPEg6dt7y4GuDcY51RzLSkSNE8ZogD7U3Vs2/fIf4z89TOLpA80EOnhg==", - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -15600,14 +15298,6 @@ "node": ">=0.10.0" } }, - "node_modules/nosleep.js": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/nosleep.js/-/nosleep.js-0.12.0.tgz", - "integrity": "sha512-9d1HbpKLh3sdWlhXMhU6MMH+wQzKkrgfRkYV0EBdvt99YJfj0ilCJrWRDYG2130Tm4GXbEoTCx5b34JSaP+HhA==", - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/now-and-later": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", @@ -15703,17 +15393,6 @@ "url": "https://opencollective.com/openlayers" } }, - "node_modules/ol-cesium": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/ol-cesium/-/ol-cesium-2.14.0.tgz", - "integrity": "sha512-/4bAW2BMSSQUBfnhOEuIZzFamtco9OC4lvzN2lzrdoLhAaatfSW6+AJhHZcVesVWZg09uUbnlWDp3QuP3v9JGg==", - "license": "BSD-2-Clause", - "optional": true, - "peerDependencies": { - "cesium": ">= 1.62.0", - "ol": ">= 6.0.1 || 7" - } - }, "node_modules/ol-layerswitcher": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/ol-layerswitcher/-/ol-layerswitcher-4.1.2.tgz", @@ -16750,32 +16429,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/protobufjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", - "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "optional": true, - "peer": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/protocol-buffers-schema": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", @@ -19915,30 +19568,6 @@ "node": ">=0.6" } }, - "node_modules/topojson-client": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz", - "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", - "license": "ISC", - "optional": true, - "peer": true, - "dependencies": { - "commander": "2" - }, - "bin": { - "topo2geo": "bin/topo2geo", - "topomerge": "bin/topomerge", - "topoquantize": "bin/topoquantize" - } - }, - "node_modules/topojson-client/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/tough-cookie": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", @@ -20406,7 +20035,7 @@ "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/unicorn-magic": { @@ -20573,14 +20202,6 @@ "node": ">=6" } }, - "node_modules/urijs": { - "version": "1.19.11", - "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", - "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/url": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", diff --git a/src/offline/AbstractLocalforageWrapper.js b/src/offline/AbstractLocalforageWrapper.js deleted file mode 100644 index 6082cbd821e8..000000000000 --- a/src/offline/AbstractLocalforageWrapper.js +++ /dev/null @@ -1,147 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2019-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -/** - * @typedef {Object} Action - * @property {number} id - * @property {string} plugin - * @property {string} command - * @property {!*[]} args - * @property {?} context - * @property {string} [msg] - */ - -/** - * @abstract - */ -const exports = class AbstractLocalforageWrapper { - constructor() { - this.waitingPromises_ = new Map(); - this.currentId_ = 0; - } - - /** - * @param {...unknown} args Some arguments. - * @returns {Promise} - */ - setItem(...args) { - return this.createAction('setItem', ...args); - } - - /** - * @param {...unknown} args Some arguments. - * @returns {Promise} - */ - getItem(...args) { - return this.createAction('getItem', ...args); - } - - /** - * @returns {Promise} - */ - clear() { - return this.createAction('clear'); - } - - /** - * @param {...unknown} args Some arguments. - * @returns {Promise} - */ - config(...args) { - return this.createAction('config', ...args); - } - - /** - * @export - * @param {string} command . - * @param {...unknown} args . - * @returns {Promise} . - */ - createAction(command, ...args) { - const id = ++this.currentId_; - /** - * @type {Action} - */ - const action = { - plugin: 'localforage', - command: command, - args: args, - id: id, - context: null, - }; - const waitingPromise = { - /** - * @param {any} _any - */ - resolve(_any) {}, - /** - * @param {any} _any - */ - reject(_any) {}, - }; - const promise = new Promise((resolve, reject) => { - waitingPromise.resolve = resolve; - waitingPromise.reject = reject; - }); - this.waitingPromises_.set(id, waitingPromise); - this.postToBackend(action); - return promise; - } - - /** - * @export - * @param {*} event . - */ - receiveMessage(event) { - /** - * @type {Action} - */ - const action = event.data; - const id = action.id; - const command = action.command; - const args = action.args || []; - const context = action.context; - const msg = action.msg; - - const waitingPromise = this.waitingPromises_.get(id); - if (command === 'error') { - console.error(msg, args, context); - if (waitingPromise) { - waitingPromise.reject(args, context); - this.waitingPromises_.delete(id); - } - } else if (command === 'response') { - waitingPromise.resolve(...args); - this.waitingPromises_.delete(id); - } else { - console.error('Unhandled command', JSON.stringify(action, null, '\t')); - } - } - - /** - * @abstract - * @protected - * @param {Action} action . - */ - postToBackend(action) {} -}; - -export default exports; diff --git a/src/offline/Configuration.js b/src/offline/Configuration.js deleted file mode 100644 index f27709e45805..000000000000 --- a/src/offline/Configuration.js +++ /dev/null @@ -1,398 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import olObservable from 'ol/Observable'; -import olLayerLayer from 'ol/layer/Layer'; -import olLayerVector from 'ol/layer/Vector'; -import olLayerTile from 'ol/layer/WebGLTile'; -import olLayerImage from 'ol/layer/Image'; -import * as olProj from 'ol/proj'; -import {defaultImageLoadFunction} from 'ol/source/Image'; -import olSourceImageWMS from 'ol/source/ImageWMS'; -import olSourceTileWMS from 'ol/source/TileWMS'; -import {createForProjection as createTileGridForProjection} from 'ol/tilegrid'; -import SerializerDeserializer from 'ngeo/offline/SerializerDeserializer'; -import LocalforageCordovaWrapper from 'ngeo/offline/LocalforageCordovaWrapper'; -import LocalforageAndroidWrapper from 'ngeo/offline/LocalforageAndroidWrapper'; -import LocalforageIosWrapper from 'ngeo/offline/LocalforageIosWrapper'; -import ngeoCustomEvent from 'ngeo/CustomEvent'; -import {normalizeURL, traverseLayer} from 'ngeo/offline/utils'; -// @ts-ignore -import localforage from 'localforage/src/localforage'; - -/** - * implements {import('ngeo/offline/index').OfflineOnTileDownload} - */ -export default class _ngInjectAnonymousClass extends olObservable { - /** - * @param {!angular.IScope} $rootScope The rootScope provider. - * @param {!import('ngeo/map/BackgroundLayerMgr').MapBackgroundLayerManager} ngeoBackgroundLayerMgr - * Background layer manager. - * @param {number} ngeoOfflineGutter A gutter around the tiles to download (to avoid cut symbols) - */ - constructor($rootScope, ngeoBackgroundLayerMgr, ngeoOfflineGutter) { - super(); - this.localforage_ = this.createLocalforage(); - this.configureLocalforage(); - - /** - * @private - * @type {!angular.IScope} - */ - this.rootScope_ = $rootScope; - - /** - * @protected - * @type {boolean} - */ - this.hasData = false; - this.initializeHasOfflineData(); - - /** - * @private - * @type {!import('ngeo/map/BackgroundLayerMgr').MapBackgroundLayerManager} - */ - this.ngeoBackgroundLayerMgr_ = ngeoBackgroundLayerMgr; - - /** - * @private - * @type {SerializerDeserializer} - */ - // @ts-ignore - this.serDes_ = new SerializerDeserializer({ - gutter: ngeoOfflineGutter, - }); - - /** - * @private - * @type {number} - */ - this.gutter_ = ngeoOfflineGutter; - } - - /** - * @private - * @param {number} progress new progress. - */ - dispatchProgress_(progress) { - this.dispatchEvent( - new ngeoCustomEvent('progress', { - 'progress': progress, - }), - ); - } - - /** - * @protected - */ - initializeHasOfflineData() { - this.getItem('offline_content').then((value) => this.setHasOfflineData(!!value)); - } - - /** - * @export - * @returns {boolean} whether some offline data is available in the storage - */ - hasOfflineData() { - return this.hasData; - } - - /** - * @param {boolean} value whether there is offline data available in the storage. - */ - setHasOfflineData(value) { - const needDigest = value !== this.hasData; - this.hasData = value; - if (needDigest) { - this.rootScope_.$applyAsync(); // force update of the UI - } - } - - /** - * Hook to allow measuring get/set item performance. - * - * @param {string} msg A message - * @param {string} key The key to work on - * @param {Promise} promise A promise - * @returns {Promise} The promise we passed - */ - traceGetSetItem(msg, key, promise) { - return promise; - } - createLocalforage() { - if (location.search.includes('localforage=cordova')) { - console.log('Using cordova localforage'); - return new LocalforageCordovaWrapper(); - } else if (location.search.includes('localforage=android')) { - console.log('Using android localforage'); - return new LocalforageAndroidWrapper(); - } else if (location.search.includes('localforage=ios')) { - console.log('Using ios localforage'); - return new LocalforageIosWrapper(); - } - return localforage; - } - configureLocalforage() { - this.localforage_.config({ - 'name': 'ngeoOfflineStorage', - 'version': 1.0, - 'storeName': 'offlineStorage', - }); - } - - /** - * @param {string} key The key - * @returns {Promise} A promise - */ - getItem(key) { - const promise = this.localforage_['getItem'](key); - return this.traceGetSetItem('getItem', key, promise); - } - - /** - * @param {string} key . - * @returns {Promise} . - */ - removeItem(key) { - const promise = this.localforage_['removeItem'](key); - return this.traceGetSetItem('removeItem', key, promise); - } - - /** - * @param {string} key The key - * @param {*} value A value - * @returns {Promise} A promise - */ - setItem(key, value) { - const promise = this.localforage_['setItem'](key, value); - return this.traceGetSetItem('setItem', key, promise); - } - - /** - * @returns {Promise} A promise - */ - clear() { - this.setHasOfflineData(false); - const promise = this.localforage_.clear(); - return this.traceGetSetItem('clear', '', promise); - } - - /** - * @param {!import('ol/Map').default} map A map - * @returns {number} An "estimation" of the size of the data to download - */ - estimateLoadDataSize(map) { - return 50; - } - - /** - * @param {import('./index').OfflineLayerMetadata} layerItem The layer metadata - * @returns {string} A key identifying an offline layer and used during restore. - */ - getLayerKey(layerItem) { - return /** @type {string} */ layerItem.layer.get('label'); - } - - /** - * @param {number} progress The download progress - * @param {import('./index').OfflineTile} tile The tile - * @returns {Promise} A promise - */ - onTileDownloadSuccess(progress, tile) { - this.dispatchProgress_(progress); - if (tile.response) { - return this.setItem(normalizeURL(tile.url), tile.response); - } - return Promise.resolve(); - } - - /** - * @param {number} progress The progress - * @returns {Promise} A promise - */ - onTileDownloadError(progress) { - this.dispatchProgress_(progress); - return Promise.resolve(); - } - - /** - * @param {import('ol/Map').default} map A map - * @param {import('ol/layer/Layer').default} layer A layer - * @param {import('ol/layer/Group').default[]} ancestors The ancestors of that layer - * @param {import('ol/extent').Extent} userExtent The extent selected by the user. - * @returns {import('./index').OfflineExtentByZoom[]} The extent to download per zoom level - */ - getExtentByZoom(map, layer, ancestors, userExtent) { - const currentZoom = map.getView().getZoom(); - if (currentZoom === undefined) { - throw new Error('Missing currentZoom'); - } - /** - * @type {import('./index').OfflineExtentByZoom[]} - */ - const results = []; - [0, 1, 2, 3, 4].forEach((dz) => { - results.push({ - zoom: currentZoom + dz, - extent: userExtent, - }); - }); - return results; - } - - /** - * @protected - * @param {import('ol/source/Source').default} source An ImageWMS source - * @param {!import('ol/proj/Projection').default} projection The projection - * @returns {import('ol/source/Source').default} A tiled equivalent source - */ - sourceImageWMSToTileWMS(source, projection) { - if ( - source instanceof olSourceImageWMS && - source.getUrl() && - source.getImageLoadFunction() === defaultImageLoadFunction - ) { - const tileGrid = createTileGridForProjection(source.getProjection() || projection, 42, 256); - const attributions = source.getAttributions() || ''; - const url = source.getUrl(); - if (!url || !attributions) { - throw new Error('Invalid values'); - } - source = new olSourceTileWMS({ - gutter: this.gutter_, - url, - tileGrid, - attributions, - projection: source.getProjection(), - params: source.getParams(), - }); - } - return source; - } - - /** - * @param {import('ol/Map').default} map The map to work on. - * @param {import('ol/extent').Extent} userExtent The extent selected by the user. - * @returns {!import('./index').OfflineLayerMetadata[]} the downloadable layers and metadata. - */ - createLayerMetadatas(map, userExtent) { - /** - * @type {import('./index').OfflineLayerMetadata[]} - */ - const layersItems = []; - - /** - * @param {import('ol/layer/Base').default} layer . - * @param {import('ol/layer/Group').default[]} ancestors . - * @returns {boolean} whether to traverse this layer children. - */ - const visitLayer = (layer, ancestors) => { - if (layer instanceof olLayerLayer) { - const extentByZoom = this.getExtentByZoom(map, layer, ancestors, userExtent); - const projection = olProj.get(map.getView().getProjection()); - const source = this.sourceImageWMSToTileWMS(layer.getSource(), projection); - /** - * @type {string|undefined} - */ - let layerType; - /** - * @type {string|undefined} - */ - let layerSerialization; - if (layer instanceof olLayerTile || layer instanceof olLayerImage) { - layerType = 'tile'; - // @ts-ignore - layerSerialization = this.serDes_.serializeTileLayer(layer, source); - } else if (layer instanceof olLayerVector) { - layerType = 'vector'; - } - const backgroundLayer = this.ngeoBackgroundLayerMgr_.get(map) === layer; - layersItems.push({ - backgroundLayer, - map, - extentByZoom, - layerType, - layerSerialization, - layer, - source, - ancestors, - }); - } - return true; - }; - map.getLayers().forEach((root) => { - traverseLayer(root, [], visitLayer); - }); - return layersItems; - } - - /** - * @private - * @param {import('./index').OfflinePersistentLayer} offlineLayer The offline layer - * @returns {function(import('ol/ImageTile').default, string)} the tile function - */ - createTileLoadFunction_(offlineLayer) { - /** - * Load the tile from persistent storage. - * - * @param {import('ol/ImageTile').default} imageTile The image tile - * @param {string} src The tile URL - */ - const tileLoadFunction = (imageTile, src) => { - this.getItem(normalizeURL(src)).then((content) => { - if (!content) { - // use a transparent 1x1 image to make the map consistent - /* eslint-disable-next-line */ - content = - 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='; - } - /** @type {HTMLImageElement} */ - imageTile.getImage().src = content; - }); - }; - return tileLoadFunction; - } - - /** - * @param {import('./index').OfflinePersistentLayer} offlineLayer The layer to recreate - * @returns {?import('ol/layer/Layer').default} the layer. - */ - recreateOfflineLayer(offlineLayer) { - if (offlineLayer.layerType === 'tile') { - const serialization = offlineLayer.layerSerialization; - if (serialization) { - const tileLoadFunction = this.createTileLoadFunction_(offlineLayer); - // @ts-ignore - const layer = this.serDes_.deserializeTileLayer(serialization, tileLoadFunction); - return layer; - } - } - return null; - } - - /** - * @returns {number} The number - */ - getMaxNumberOfParallelDownloads() { - return 11; - } -} -_ngInjectAnonymousClass.$inject = ['$rootScope', 'ngeoBackgroundLayerMgr', 'ngeoOfflineGutter']; diff --git a/src/offline/Downloader.js b/src/offline/Downloader.js deleted file mode 100644 index c0d01bcbca65..000000000000 --- a/src/offline/Downloader.js +++ /dev/null @@ -1,196 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import {DEVICE_PIXEL_RATIO} from 'ol/has'; -import olSourceTileWMS from 'ol/source/TileWMS'; -import olSourceWMTS from 'ol/source/WMTS'; -import TilesDownloader from 'ngeo/offline/TilesDownloader'; -import angular from 'angular'; - -/** - * @param {import('ol/coordinate').Coordinate} a Some coordinates. - * @param {import('ol/coordinate').Coordinate} b Some other coordinates. - * @returns {number} The squared magnitude. - */ -function magnitude2(a, b) { - let magnitudeSquared = 0; - for (let i = 0; i < a.length; ++i) { - magnitudeSquared += Math.pow(a[i] - b[i], 2); - } - return magnitudeSquared; -} -const Downloader = class { - /** - * @param {import('ngeo/offline/Configuration').default} ngeoOfflineConfiguration - * A service for customizing offline behavior. - */ - constructor(ngeoOfflineConfiguration) { - /** - * @private - * @type {import('ngeo/offline/Configuration').default} - */ - this.configuration_ = ngeoOfflineConfiguration; - - /** - * @type {?TilesDownloader} - * @private - */ - this.tileDownloader_ = null; - } - cancel() { - if (this.tileDownloader_) { - this.tileDownloader_.cancel(); - } - } - - /** - * @param {import('./index').OfflineLayerMetadata} layerMetadata Layers metadata. - * @param {import('./index').OfflineTile[]} queue Queue of tiles to download. - */ - queueLayerTiles_(layerMetadata, queue) { - const source = /** @type {olSourceTileWMS|olSourceWMTS} */ layerMetadata.source; - const {map, extentByZoom} = layerMetadata; - if (!source) { - return; - } - console.assert(source instanceof olSourceTileWMS || source instanceof olSourceWMTS); - const projection = map.getView().getProjection(); - const tileGrid = source.getTileGrid(); - const tileUrlFunction = source.getTileUrlFunction(); - console.assert(extentByZoom); - for (const extentZoom of extentByZoom) { - const z = extentZoom.zoom; - const extent = extentZoom.extent; - /** - * @type {import('./index').OfflineTile[]} - */ - const queueByZ = []; - /** - * @type {number} - */ - let minX; - /** - * @type {number} - */ - let minY; - /** - * @type {number} - */ - let maxX; - /** - * @type {number} - */ - let maxY; - tileGrid.forEachTileCoord(extent, z, (coord) => { - maxX = coord[1]; - maxY = coord[2]; - if (minX === undefined || minY === undefined) { - minX = coord[1]; - minY = coord[2]; - } - const url = tileUrlFunction(coord, DEVICE_PIXEL_RATIO, projection); - console.assert(url); - if (url) { - /** - * @type {import('./index').OfflineTile} - */ - const tile = { - coord, - url, - response: null, - }; - queueByZ.push(tile); - } - }); - const centerTileCoord = [z, (minX + maxX) / 2, (minY + maxY) / 2]; - queueByZ.sort((a, b) => magnitude2(a.coord, centerTileCoord) - magnitude2(b.coord, centerTileCoord)); - queue.push(...queueByZ); - } - } - - /** - * @param {import('ol/extent').Extent} extent The extent to download. - * @param {import('ol/Map').default} map The map to work on. - * @returns {Promise<*>} A promise resolving when save is finished. - */ - save(extent, map) { - /** - * @type {!import('./index').OfflineLayerMetadata[]} - */ - const layersMetadatas = this.configuration_.createLayerMetadatas(map, extent); - - /** - * @type {!import('./index').OfflinePersistentLayer[]} - */ - const persistentLayers = []; - /** - * @type {import('./index').OfflineTile[]} - */ - const queue = []; - /** - * @type {number[]} - */ - const zooms = []; - for (const layerItem of layersMetadatas) { - if (layerItem.layerType === 'tile') { - /** - * @type {import('./index').OfflineTile[]} - */ - const tiles = []; - this.queueLayerTiles_(layerItem, tiles); - queue.push(...tiles); - } - persistentLayers.push({ - backgroundLayer: layerItem.backgroundLayer, - layerType: layerItem.layerType, - layerSerialization: layerItem.layerSerialization, - key: this.configuration_.getLayerKey(layerItem), - }); - layerItem.extentByZoom.forEach((obj) => { - const zoom = obj.zoom; - if (!zooms.includes(zoom)) { - zooms.push(zoom); - } - }); - } - - /** - * @type {import('./index').OfflinePersistentContent} - */ - const persistentObject = { - extent: extent, - layers: persistentLayers, - zooms: zooms.sort((a, b) => (a < b ? -1 : 1)), - }; - const setOfflineContentPromise = this.configuration_.setItem('offline_content', persistentObject); - const maxDownloads = this.configuration_.getMaxNumberOfParallelDownloads(); - this.tileDownloader_ = new TilesDownloader(queue, this.configuration_, maxDownloads); - const tileDownloadPromise = this.tileDownloader_.download(); - const allPromise = Promise.all([setOfflineContentPromise, tileDownloadPromise]); - const setHasOfflineData = () => this.configuration_.setHasOfflineData(true); - allPromise.then(setHasOfflineData, setHasOfflineData); - return allPromise; - } -}; -const name = 'offlineDownloader'; -Downloader.module = angular.module(name, []).service(name, Downloader); -const exports = Downloader; -export default exports; diff --git a/src/offline/LocalforageAndroidWrapper.js b/src/offline/LocalforageAndroidWrapper.js deleted file mode 100644 index 626480c9c95b..000000000000 --- a/src/offline/LocalforageAndroidWrapper.js +++ /dev/null @@ -1,53 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2019-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import AbstractWrapper from 'ngeo/offline/AbstractLocalforageWrapper'; - -const exports = class AndroidWrapper extends AbstractWrapper { - constructor() { - super(); - // @ts-ignore - window.androidWrapper = this; - } - - /** - * @param {unknown} action - * @override - */ - postToBackend(action) { - const stringified = JSON.stringify(action); - // @ts-ignore - window.ngeoHost.postMessageToAndroid(stringified); - } - - /** - * @export - * @param {string} actionString . - */ - receiveFromAndroid(actionString) { - const action = JSON.parse(actionString); - this.receiveMessage({ - 'data': action, - }); - } -}; - -export default exports; diff --git a/src/offline/LocalforageCordovaWrapper.js b/src/offline/LocalforageCordovaWrapper.js deleted file mode 100644 index a4ac026877c2..000000000000 --- a/src/offline/LocalforageCordovaWrapper.js +++ /dev/null @@ -1,39 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2019-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import AbstractWrapper from 'ngeo/offline/AbstractLocalforageWrapper'; - -const exports = class CordovaWrapper extends AbstractWrapper { - constructor() { - super(); - window.addEventListener('message', this.receiveMessage.bind(this), false); - } - - /** - * @param {unknown} action - * @override - */ - postToBackend(action) { - window.parent.postMessage(action, '*'); - } -}; - -export default exports; diff --git a/src/offline/LocalforageIosWrapper.js b/src/offline/LocalforageIosWrapper.js deleted file mode 100644 index 83838bb15a7a..000000000000 --- a/src/offline/LocalforageIosWrapper.js +++ /dev/null @@ -1,66 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2019-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import AbstractWrapper from 'ngeo/offline/AbstractLocalforageWrapper'; - -/** - * @typedef {Object} Action - * @property {string} command - * @property {string[]} args - */ -const exports = class IosWrapper extends AbstractWrapper { - constructor() { - super(); - // @ts-ignore - window.iosWrapper = this; - } - - /** - * @param {Action} action - * @override - */ - postToBackend(action) { - if (action.command === 'setItem') { - action.args[1] = JSON.stringify(action.args[1]); - } - const stringified = JSON.stringify(action); - // @ts-ignore - window.webkit.messageHandlers.ios.postMessage(stringified); - } - - /** - * @export - * @param {string} actionString . - */ - receiveFromIos(actionString) { - const action = JSON.parse(actionString); - /** - * @type {string[]} - */ - const args = action['args'] || []; - action['args'] = args.map((item) => JSON.parse(item)); - this.receiveMessage({ - 'data': action, - }); - } -}; - -export default exports; diff --git a/src/offline/Mask.js b/src/offline/Mask.js deleted file mode 100644 index 4d891dec5fbd..000000000000 --- a/src/offline/Mask.js +++ /dev/null @@ -1,109 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2019-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import Layer from 'ol/layer/Layer'; -import {createCanvasContext2D} from 'ol/dom'; -import {DEVICE_PIXEL_RATIO} from 'ol/has'; - -/** - * @typedef {Object} Options - * @property {number} [margin] - * @property {number} [extentInMeters] - */ - -/** - * @augments {Layer} - */ -export default class Mask extends Layer { - /** - * @param {import('ol/layer/Layer').Options} layerOptions - * @param {Options} maskOptions - */ - constructor(layerOptions = {}, maskOptions = {}) { - super(layerOptions); - - /** - * @private - */ - this.context_ = createCanvasContext2D(); - - this.context_.canvas.style.opacity = '0.5'; - this.context_.canvas.style.position = 'absolute'; - - this.margin_ = maskOptions.margin || 100; - this.extentInMeters_ = maskOptions.extentInMeters || 0; - } - - /** - * @param {import('ol/coordinate').Coordinate} center center, a xy point. - * @param {number} halfLength a half length of a square's side. - * @returns {import('ol/extent').Extent} an extent. - */ - createExtent(center, halfLength) { - const minx = center[0] - halfLength; - const miny = center[1] - halfLength; - const maxx = center[0] + halfLength; - const maxy = center[1] + halfLength; - return [minx, miny, maxx, maxy]; - } - - /** - * @param {import("ol/Map").FrameState} frameState - * @returns {HTMLElement} - */ - render(frameState) { - const context = this.context_; - const cwidth = frameState.size[0]; - context.canvas.width = cwidth; - const cheight = frameState.size[1]; - context.canvas.height = cheight; - - // background (clockwise) - context.beginPath(); - context.moveTo(0, 0); - context.lineTo(cwidth, 0); - context.lineTo(cwidth, cheight); - context.lineTo(0, cheight); - context.lineTo(0, 0); - context.closePath(); - - let extentLength = Math.min(cwidth, cheight) - this.margin_ * 2; - if (this.extentInMeters_) { - extentLength = (DEVICE_PIXEL_RATIO * this.extentInMeters_) / frameState.viewState.resolution; - } - - // Draw the get data zone - const extent = this.createExtent([cwidth / 2, cheight / 2], Math.ceil(extentLength / 2)); - - context.moveTo(extent[0], extent[1]); - context.lineTo(extent[0], extent[3]); - context.lineTo(extent[2], extent[3]); - context.lineTo(extent[2], extent[1]); - context.lineTo(extent[0], extent[1]); - context.closePath(); - - // Fill the mask - context.fillStyle = 'rgba(0, 5, 25, 0.5)'; - context.fill(); - - return context.canvas; - } -} diff --git a/src/offline/Mode.js b/src/offline/Mode.js deleted file mode 100644 index 29f46e5b0229..000000000000 --- a/src/offline/Mode.js +++ /dev/null @@ -1,107 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import angular from 'angular'; -class Mode { - /** - * @param {import('ngeo/offline/Configuration').default} ngeoOfflineConfiguration - * ngeo offline configuration service. - * @ngdoc service - * @ngname ngeoOfflineState - */ - constructor(ngeoOfflineConfiguration) { - /** - * Offline mode is enabled or not. - * - * @type {boolean} - * @private - */ - this.enabled_ = false; - - /** - * Offline component. - * - * @type {?import('ngeo/offline/component').Controller} - * @private - */ - this.component_ = null; - - /** - * @private - * @type {import('ngeo/offline/Configuration').default} - */ - this.ngeoOfflineConfiguration_ = ngeoOfflineConfiguration; - } - - /** - * Return if we are in offline mode. - * - * @returns {boolean} whether offline mode is enabled - * @export - */ - isEnabled() { - return this.enabled_; - } - - /** - * Enable offline mode. ATM we cannot escape from the offline mode. - * - * @export - */ - enable() { - this.enabled_ = true; - } - - /** - * - * @param {import('ngeo/offline/component').Controller} component Offline component. - * @export - */ - registerComponent(component) { - this.component_ = component; - } - - /** - * @export - */ - activateOfflineMode() { - if (!this.component_) { - throw new Error('The component is not registered'); - } - this.component_.activateOfflineMode(); - } - - /** - * @returns {boolean} True if data are accessible offline. - * @export - */ - hasData() { - return this.ngeoOfflineConfiguration_.hasOfflineData(); - } -} -Mode.$inject = ['ngeoOfflineConfiguration']; -/** - * @type {!angular.IModule} - */ -const myModule = angular.module('ngeoOfflineMode', []); -myModule.service('ngeoOfflineMode', Mode); -Mode.module = myModule; -export default Mode; diff --git a/src/offline/NetworkStatus.js b/src/offline/NetworkStatus.js deleted file mode 100644 index 2610409b0eac..000000000000 --- a/src/offline/NetworkStatus.js +++ /dev/null @@ -1,224 +0,0 @@ -configFunction_.$inject = ['$httpProvider']; -// The MIT License (MIT) -// -// Copyright (c) 2018-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import ngeoMiscDebounce from 'ngeo/misc/debounce'; -import angular from 'angular'; -const Service = class { - /** - * This service watches the status of network connection. - * - * Currently it watches every $http and $.ajax requests errors, if an error - * occurs we wait 2 sec then we make an http request on the checker file. - * If the checker responds that means we are online, otherwise we make a - * 2nd request 2 sec later, if the 2nd requests failed that means we - * are offline. - * - * A timeout of 1 sec is set for the checker file, so if we have a bad - * connection, we consider we are offline. - * - * During offline mode we test every 2 sec if we are back online. - * - * @param {!jQuery} $document Angular document service. - * @param {angular.IWindowService} $window Angular window service. - * @param {angular.ITimeoutService} $timeout Angular timeout service. - * @param {angular.IScope} $rootScope The root scope. - * @param {import('ngeo/options').ngeoOfflineTestUrl} ngeoOfflineTestUrl URL of the test page. - */ - constructor($document, $window, $timeout, $rootScope, ngeoOfflineTestUrl) { - /** - * @private - * @type {!jQuery} - */ - this.$document_ = $document; - - /** - * @private - * @type {!Window} - */ - this.$window_ = $window; - - /** - * @private - * @type {!angular.ITimeoutService} - */ - this.$timeout_ = $timeout; - - /** - * @private - * @type {angular.IScope} - */ - this.$rootScope_ = $rootScope; - - /** - * @private - * @type {import('ngeo/options').ngeoOfflineTestUrl} - */ - this.ngeoOfflineTestUrl_ = ngeoOfflineTestUrl; - - /** - * @private - * @type {!number} - */ - this.count_ = 0; - - /** - * @type {!boolean|undefined} - * @private - */ - this.offline_; - - /** - * @private - * @type {angular.IPromise|undefined} - */ - this.promise_; - this.initialize_(); - } - initialize_() { - this.offline_ = !this.$window_.navigator.onLine; - - // airplane mode, works offline(firefox) - this.$window_.addEventListener('offline', () => { - this.triggerChangeStatusEvent_(true); - }); - - // online event doesn't means we have a internet connection, that means we - // have possibly one (connected to a router ...) - this.$window_.addEventListener('online', () => { - this.check(undefined); - }); - - // We catch every $.ajax request errors or (canceled request). - // @ts-ignore - if (this.$document_.ajaxError) { - /** - * @param {unknown} evt - * @param {unknown} jqxhr - * @param {unknown} settings - * @param {string} thrownError - */ - const onAjaxError = (evt, jqxhr, settings, thrownError) => { - // Filter out canceled requests - if (!/^(canceled|abort)$/.test(thrownError)) { - this.check(2000); - } - }; - // @ts-ignore - this.$document_.ajaxError(onAjaxError); - } - } - - /** - * Check fir network status - * - * @param {number} [timeout] Delay for timeout. - */ - check(timeout) { - if (this.promise_) { - this.$timeout_.cancel(this.promise_); - this.promise_ = undefined; - } - if (timeout !== undefined) { - this.count_++; - this.promise_ = this.$timeout_(() => this.check(), timeout); - return; - } - $.ajax({ - method: 'GET', - url: this.ngeoOfflineTestUrl_, - timeout: 1000, - success: () => { - this.count_ = 0; - if (this.offline_) { - this.triggerChangeStatusEvent_(false); - } - }, - error: () => { - this.count_++; - // We consider we are offline after 3 requests failed - if (this.count_ > 2 && !this.offline_) { - this.triggerChangeStatusEvent_(true); - } - }, - }); - } - - /** - * @param {boolean} offline whether it's offline or not. - * @private - */ - triggerChangeStatusEvent_(offline) { - this.offline_ = offline; - // this.$rootScope_.$broadcast('ngeoNetworkStatusChange', net.offline); - this.$rootScope_.$digest(); - } - - /** - * @returns {boolean} True if we are disconnected. - * @export - */ - isDisconnected() { - return !!this.offline_; - } -}; -const name = 'ngeoNetworkStatus'; -Service.module = angular.module(name, [ngeoMiscDebounce.name]); -Service.module.service(name, Service); - -/** - * @param {angular.IQService} $q The Angular $q service. - * @param {import('ngeo/misc/debounce').miscDebounce} ngeoDebounce ngeo debounce service. - * @param {Service} ngeoNetworkStatus ngeo network status service. - * @returns {angular.IHttpInterceptor} the interceptor - */ -const httpInterceptor = function ($q, ngeoDebounce, ngeoNetworkStatus) { - const debouncedCheck = ngeoDebounce(() => ngeoNetworkStatus.check(undefined), 2000, false); - return { - request(config) { - return config; - }, - requestError(rejection) { - return $q.reject(rejection); - }, - response(response) { - return response; - }, - responseError(rejection) { - debouncedCheck(); - return $q.reject(rejection); - }, - }; -}; -httpInterceptor.$inject = ['$q', 'ngeoDebounce', 'ngeoNetworkStatus']; -httpInterceptor.$inject = ['$q', 'ngeoDebounce', 'ngeoNetworkStatus']; -Service.module.factory('httpInterceptor', httpInterceptor); - -/** - * @private - * @param {angular.IHttpProvider} $httpProvider . - */ -function configFunction_($httpProvider) { - $httpProvider.interceptors.push('httpInterceptor'); -} -Service.module.config(configFunction_); -const exports = Service; -export default exports; diff --git a/src/offline/Restorer.js b/src/offline/Restorer.js deleted file mode 100644 index e93aa2124b18..000000000000 --- a/src/offline/Restorer.js +++ /dev/null @@ -1,79 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import ngeoMapBackgroundLayerMgr from 'ngeo/map/BackgroundLayerMgr'; -import angular from 'angular'; -class Restorer { - /** - * @param {import('ngeo/offline/Configuration').default} ngeoOfflineConfiguration - * A service for customizing offline behavior. - * @param {import('ngeo/map/BackgroundLayerMgr').MapBackgroundLayerManager} ngeoBackgroundLayerMgr - * The background layer manager. - */ - constructor(ngeoOfflineConfiguration, ngeoBackgroundLayerMgr) { - /** - * @private - * @type {import('ngeo/offline/Configuration').default} - */ - this.configuration_ = ngeoOfflineConfiguration; - - /** - * @private - * @type {import('ngeo/map/BackgroundLayerMgr').MapBackgroundLayerManager} - */ - this.ngeoBackgroundLayerMgr_ = ngeoBackgroundLayerMgr; - } - - /** - * @param {import('ol/Map').default} map The map to work on. - * @returns {Promise} A promise to the extent of the restored area. - */ - restore(map) { - return this.configuration_ - .getItem('offline_content') - .then((offlineContent) => this.doRestore(map, offlineContent)); - } - - /** - * @protected - * @param {import('ol/Map').default} map A map - * @param {import('./index').OfflinePersistentContent} offlineContent The offline content - * @returns {import('ol/extent').Extent} The extent of the restored area - */ - doRestore(map, offlineContent) { - map.getLayerGroup().getLayers().clear(); - for (const offlineLayer of offlineContent.layers) { - const layer = this.configuration_.recreateOfflineLayer(offlineLayer); - if (layer) { - map.addLayer(layer); - if (offlineLayer.backgroundLayer) { - this.ngeoBackgroundLayerMgr_.set(map, layer); - } - } - } - return offlineContent.extent; - } -} -Restorer.$inject = ['ngeoOfflineConfiguration', 'ngeoBackgroundLayerMgr']; -const name = 'ngeoOfflineRestorer'; -Restorer.module = angular.module(name, [ngeoMapBackgroundLayerMgr.name]).service(name, Restorer); -const exports = Restorer; -export default exports; diff --git a/src/offline/SerializerDeserializer.js b/src/offline/SerializerDeserializer.js deleted file mode 100644 index 0ef2927c3525..000000000000 --- a/src/offline/SerializerDeserializer.js +++ /dev/null @@ -1,271 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import OlTilegridTileGrid from 'ol/tilegrid/TileGrid'; -import OlTilegridWMTS from 'ol/tilegrid/WMTS'; -import * as olProj from 'ol/proj'; -import OlSourceTileWMS from 'ol/source/TileWMS'; -import OlSourceWMTS from 'ol/source/WMTS'; -import OlLayerTile from 'ol/layer/WebGLTile'; - -const SerDes = class { - /** - * @param {unknown} options The options - */ - // @ts-ignore - constructor({gutter}) { - /** - * @private - */ - this.gutter_ = gutter; - } - - /** - * @private - * @param {import('ol/Object').default} olObject An OL object - * @returns {Object} The serializable properties of the object - */ - createBaseObject_(olObject) { - const properties = olObject.getProperties(); - /** - * @type {Object} - */ - const obj = {}; - for (const key in properties) { - const value = properties[key]; - const typeOf = typeof value; - if (typeOf === 'string' || typeOf === 'number') { - obj[key] = value; - } - } - return obj; - } - - /** - * @param {OlTilegridTileGrid} tilegrid . - * @returns {string} . - */ - serializeTilegrid(tilegrid) { - /** - * @type {Object} - */ - const obj = {}; - obj.extent = tilegrid.getExtent(); - obj.minZoom = tilegrid.getMinZoom(); - obj.origin = tilegrid.getOrigin(0); // hack - obj.resolutions = tilegrid.getResolutions(); - obj.tileSize = tilegrid.getTileSize(tilegrid.getMinZoom()); - return JSON.stringify(obj); - } - - /** - * @param {string} serialization . - * @returns {OlTilegridTileGrid} tilegrid - */ - deserializeTilegrid(serialization) { - /** - * @type {import ("ol/tilegrid/WMTS").Options} - */ - const options = JSON.parse(serialization); - return new OlTilegridTileGrid(options); - } - - /** - * @param {OlTilegridWMTS} tilegrid . - * @returns {string|undefined} . - */ - serializeTilegridWMTS(tilegrid) { - if (!tilegrid) { - return undefined; - } - /** - * @type {{ - * 'extent': import('ol/extent').Extent, - * 'minZoom': number, - * 'matrixIds': string[], - * 'resolutions': number[], - * 'origins': import('ol/coordinate').Coordinate[], - * }} - */ - const obj = {}; - const resolutions = tilegrid.getResolutions(); - obj.extent = tilegrid.getExtent(); - obj.minZoom = tilegrid.getMinZoom(); - obj.matrixIds = tilegrid.getMatrixIds(); - obj.resolutions = resolutions; - - obj.origins = []; - for (let z = 0; z < resolutions.length; ++z) { - obj.origins.push(tilegrid.getOrigin(z)); - } - return JSON.stringify(obj); - } - - /** - * @param {string} serialization . - * @returns {OlTilegridWMTS} tilegrid . - */ - deserializeTilegridWMTS(serialization) { - /** - * @type {import ("ol/tilegrid/WMTS").Options} - */ - const options = JSON.parse(serialization); - return new OlTilegridWMTS(options); - } - - /** - * @param {OlSourceTileWMS} source . - * @returns {string} . - */ - serializeSourceTileWMS(source) { - const obj = this.createBaseObject_(source); - obj.params = source.getParams(); - obj.urls = source.getUrls(); - obj.tileGrid = this.serializeTilegrid(source.getTileGrid()); - const projection = source.getProjection(); - if (projection) { - obj.projection = olProj.get(source.getProjection()).getCode(); - } - - return JSON.stringify(obj); - } - - /** - * @param {string} serialization . - * @param {function(import('ol/ImageTile').default, string): void} [tileLoadFunction] . - * @returns {OlSourceTileWMS} source . - */ - deserializeSourceTileWMS(serialization, tileLoadFunction) { - /** - * @type {import ("ol/source/TileWMS").Options} - */ - const options = JSON.parse(serialization); - // @ts-ignore - options.tileLoadFunction = tileLoadFunction; - if (options.tileGrid) { - options.tileGrid = this.deserializeTilegrid(/** @type {any} */ (options).tileGrid); - } - options.gutter = this.gutter_; - return new OlSourceTileWMS(options); - } - - /** - * @param {OlSourceWMTS} source . - * @returns {string} . - */ - serializeSourceWMTS(source) { - const obj = this.createBaseObject_(source); - obj.dimensions = source.getDimensions(); - obj.format = source.getFormat(); - obj.urls = source.getUrls(); - obj.version = source.getVersion(); - obj.layer = source.getLayer(); - obj.style = source.getStyle(); - obj.matrixSet = source.getMatrixSet(); - // The OL getTileGrid method is expected to return a WMTS tilegrid so it is OK to cast here. - const tileGridWMTS = /** @type {OlTilegridWMTS} */ (source.getTileGrid()); - obj.tileGrid = this.serializeTilegridWMTS(tileGridWMTS); - obj.requestEncoding = source.getRequestEncoding(); - const projection = source.getProjection(); - if (projection) { - obj.projection = olProj.get(source.getProjection()).getCode(); - } - - return JSON.stringify(obj); - } - - /** - * @param {string} serialization . - * @param {function(import('ol/ImageTile').default, string): void} [tileLoadFunction] . - * @returns {OlSourceWMTS} . - */ - deserializeSourceWMTS(serialization, tileLoadFunction) { - /** - * @type {import("ol/source/WMTS").Options} - */ - const options = JSON.parse(serialization); - // @ts-ignore - options.tileLoadFunction = tileLoadFunction; - if (options.tileGrid) { - options.tileGrid = this.deserializeTilegridWMTS(/** @type {any} */ (options).tileGrid); - } - return new OlSourceWMTS(options); - } - - /** - * @private - * @param {number} number Some number which may be Infinity - * @returns {number} The same number or an arbitrary big number instead of Infinity - */ - makeInfinitySerializable_(number) { - if (number === Infinity) { - return 1000; - } - return number; - } - - /** - * @param {!import('ol/layer/WebGLTile').default|import('ol/layer/Image').default} layer . - * @param {import('ol/source/Source').default} [source] . - * @returns {string} . - */ - serializeTileLayer(layer, source) { - const obj = this.createBaseObject_(layer); - obj.opacity = layer.getOpacity(); - obj.visible = layer.getVisible(); - obj.minResolution = layer.getMinResolution(); - obj.maxResolution = this.makeInfinitySerializable_(layer.getMaxResolution()); - obj.zIndex = layer.getZIndex(); - source = source || layer.getSource(); - if (source instanceof OlSourceTileWMS) { - obj.source = this.serializeSourceTileWMS(source); - obj.sourceType = 'tileWMS'; - } else if (source instanceof OlSourceWMTS) { - obj.source = this.serializeSourceWMTS(source); - obj.sourceType = 'WMTS'; - } - return JSON.stringify(obj); - } - - /** - * @param {string} serialization . - * @param {function(import('ol/ImageTile').default, string): void} [tileLoadFunction] . - * @returns {!import('ol/layer/WebGLTile').default} . - */ - deserializeTileLayer(serialization, tileLoadFunction) { - /** - * @type {import('ol/layer/BaseTile').Options} - */ - const options = JSON.parse(serialization); - // @ts-ignore - const sourceType = options.sourceType; - if (sourceType === 'tileWMS') { - options.source = this.deserializeSourceTileWMS(/** @type {any} */ (options).source, tileLoadFunction); - } else if (sourceType === 'WMTS') { - options.source = this.deserializeSourceWMTS(/** @type {any} */ (options).source, tileLoadFunction); - } - return new OlLayerTile(options); - } -}; - -const exports = SerDes; - -export default exports; diff --git a/src/offline/ServiceManager.js b/src/offline/ServiceManager.js deleted file mode 100644 index c21d45d6b05a..000000000000 --- a/src/offline/ServiceManager.js +++ /dev/null @@ -1,134 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import angular from 'angular'; -class ServiceManager { - /** - * @param {angular.auto.IInjectorService} $injector Main injector. - * @struct - * @ngdoc service - * @ngname ngeoOfflineServiceManager - */ - constructor($injector) { - /** - * @type {angular.auto.IInjectorService} - * @private - */ - this.$injector_ = $injector; - - /** - * @type {*} - * @private - */ - this.saveService_ = null; - - /** - * @type {*} - * @private - */ - this.restoreService_ = null; - } - - /** - * @param {string|unknown} serviceLike A service like. - * @param {string} method A method. - * @returns {unknown} A returned object. - */ - getOfflineService_(serviceLike, method) { - if (typeof serviceLike === 'string') { - if (!this.$injector_.has(serviceLike)) { - console.error(`The offline ${method} service could not be found`); - return; - } - const service = this.$injector_.get(serviceLike); - if (!service[method]) { - console.error(`The offline service ${serviceLike} does not have a ${method} method`); - return; - } - return service; - } - // @ts-ignore - if (!serviceLike[method]) { - console.error(`The provided offline service does not have a ${method} method`); - return; - } - return serviceLike; - } - - /** - * Set the service to call on 'save'. - * - * @param {string|{save: Function}} saveLikeService - * A service name that can be injected or an object that have a 'save' method. - */ - setSaveService(saveLikeService) { - this.saveService_ = this.getOfflineService_(saveLikeService, 'save'); - } - - /** - * Set the service to call on 'restore' - * - * @param {string|{restore: Function}} restoreLikeService - * A service name that can be injected or an object that have a 'restore' method. - */ - setRestoreService(restoreLikeService) { - this.restoreService_ = this.getOfflineService_(restoreLikeService, 'restore'); - } - cancel() { - if (!this.saveService_) { - console.warn('You must register a saveService first'); - return; - } - this.saveService_.cancel(); - } - - /** - * Ask the provided service to save the data to an offline purpose - * - * @param {import('ol/extent').Extent} extent The extent to download. - * @param {import("ol/Map").default} map The map to work on. - */ - save(extent, map) { - if (!this.saveService_) { - console.warn('You must register a saveService first'); - return; - } - this.saveService_.save(extent, map); - } - - /** - * Ask the provided service to restore the saved data on the map - * - * @param {import('ol/Map').default} map The map to work on. - * @returns {Promise} A promise to the extent of the downloaded area - */ - restore(map) { - if (!this.restoreService_) { - console.warn('You must register a restoreService first'); - return Promise.reject(); - } - return this.restoreService_.restore(map); - } -} -ServiceManager.$inject = ['$injector']; -ServiceManager.module = angular.module('ngeoOfflineServiceManager', []); -ServiceManager.module.service('ngeoOfflineServiceManager', ServiceManager); -export default ServiceManager; diff --git a/src/offline/TilesDownloader.js b/src/offline/TilesDownloader.js deleted file mode 100644 index 850716a22adc..000000000000 --- a/src/offline/TilesDownloader.js +++ /dev/null @@ -1,223 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -/** - * @param {!Blob} blob A blob - * @returns {Promise} data URL - */ -function blobToDataUrl(blob) { - return new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.onload = function () { - resolve(/** @type {string} */ (reader.result)); - }; - reader.onerror = reject; - reader.readAsDataURL(blob); - }); -} - -export default class TileDownloader { - /** - * @param {import('./index').OfflineTile[]} tiles An array of tiles to download. - * @param {import('./index').OfflineOnTileDownload} callbacks The callbacks. - * @param {number} workers The maximum number of workers. - */ - constructor(tiles, callbacks, workers) { - /** - * @private - * @type {number} - */ - this.maxNumberOfWorkers_ = workers; - - /** - * @private - */ - this.wasStarted_ = false; - - /** - * @type {import('./index').OfflineTile[]} - * @private - */ - this.tiles_ = tiles; - - /** - * @private - * @type {import('./index').OfflineOnTileDownload} - */ - this.callbacks_ = callbacks; - - /** - * @private - */ - this.allCount_ = 0; - - /** - * @private - */ - this.okCount_ = 0; - - /** - * @private - */ - this.koCount_ = 0; - - /** - * @private - */ - this.requestedCount_ = 0; - - /** - * @private - * @type {?function(): unknown} - */ - this.resolvePromise_ = null; - - /** - * @private - * @type {?Promise} - */ - this.promise_ = null; - - /** - * @type {number} - * @private - */ - this.tileIndex_ = 0; - - /** - * @type {boolean} - * @private - */ - this.cancel_ = false; - } - - cancel() { - this.cancel_ = true; - } - - /** - * @returns {Promise} A promise that resolves when the downloads are complete (failing or not) - */ - download() { - if (this.promise_) { - return this.promise_; - } - - this.promise_ = new Promise((resolve, reject) => { - this.resolvePromise_ = resolve; - }); - - console.assert(this.tiles_); - if (this.tiles_.length === 0) { - this.callbacks_.onTileDownloadError(1); // forcing progress update - if (this.resolvePromise_) { - this.resolvePromise_(); - } - } else { - for (let i = 0; i < this.maxNumberOfWorkers_; ++i) { - this.downloadTile_(); - } - } - - return this.promise_; - } - - /** - * @private - */ - downloadTile_() { - if (this.cancel_ || this.tileIndex_ >= this.tiles_.length) { - return; - } - const tile = this.tiles_[this.tileIndex_++]; - const tileUrl = tile.url; - const xhr = new XMLHttpRequest(); - xhr.open('GET', tileUrl, true); - xhr.responseType = 'blob'; - const onTileDownloaded = () => { - if (this.allCount_ === this.tiles_.length && this.resolvePromise_) { - this.resolvePromise_(); - } - this.downloadTile_(); - }; - - /** - * @param {unknown} _ Unused. - */ - const errorCallback = (_) => { - if (this.cancel_) { - return; - } - ++this.allCount_; - ++this.koCount_; - const progress = this.allCount_ / this.tiles_.length; - this.callbacks_.onTileDownloadError(progress).then(onTileDownloaded, onTileDownloaded); - }; - - /** - * - * @param {!ProgressEvent} e The load event. - */ - const onloadCallback = (e) => { - /** - * @type {?Blob} - */ - const response = xhr.response; - if (response && response.size !== 0) { - // non-empty tile - blobToDataUrl(response).then( - (dataUrl) => { - if (this.cancel_) { - return; - } - ++this.allCount_; - ++this.okCount_; - tile.response = dataUrl; - const progress = this.allCount_ / this.tiles_.length; - this.callbacks_.onTileDownloadSuccess(progress, tile).then(onTileDownloaded, onTileDownloaded); - }, - () => { - if (this.cancel_) { - return; - } - errorCallback(e); - }, - ); - } else { - if (this.cancel_) { - return; - } - ++this.allCount_; - ++this.okCount_; - this.callbacks_ - .onTileDownloadSuccess(this.allCount_ / this.tiles_.length, tile) - .then(onTileDownloaded, onTileDownloaded); - } - }; - - xhr.onload = onloadCallback; - xhr.onerror = errorCallback; - xhr.onabort = errorCallback; - xhr.ontimeout = errorCallback; - xhr.send(); - ++this.requestedCount_; - } -} diff --git a/src/offline/component.html.js b/src/offline/component.html.js deleted file mode 100644 index 6ef1f175da22..000000000000 --- a/src/offline/component.html.js +++ /dev/null @@ -1,182 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -export default `
- -
-
- -
-
-
- -
-
- Save map -
-
Abort
-
- -
-
{{$ctrl.progressPercents}}%
-
- - - - - - - - - - - - - - - - - - - - - - - - -`; diff --git a/src/offline/component.js b/src/offline/component.js deleted file mode 100644 index 3828567d7769..000000000000 --- a/src/offline/component.js +++ /dev/null @@ -1,578 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import ngeoMapFeatureOverlayMgr from 'ngeo/map/FeatureOverlayMgr'; -import ngeoMessageModalComponent from 'ngeo/message/modalComponent'; -import {extentToRectangle} from 'ngeo/utils'; -import olCollection from 'ol/Collection'; -import Feature from 'ol/Feature'; -import Polygon from 'ol/geom/Polygon'; -import {DEVICE_PIXEL_RATIO} from 'ol/has'; -import angular from 'angular'; -import MaskLayer from './Mask'; -import htmlTemplate from './component.html'; - -/** - * @type {!angular.IModule} - */ -const myModule = angular.module('ngeoOffline', [ngeoMessageModalComponent.name]); -myModule.value( - 'ngeoOfflineTemplateUrl', - /** - * @param {JQuery} element Element. - * @param {angular.IAttributes} attrs Attributes. - * @returns {string} Template URL. - */ - (element, attrs) => { - const templateUrl = attrs['ngeoOfflineTemplateurl']; - return templateUrl !== undefined ? templateUrl : 'ngeo/offline/component.html'; - }, -); -myModule.run( - /** - * @param {angular.ITemplateCacheService} $templateCache - */ - [ - '$templateCache', - ($templateCache) => { - // @ts-ignore: webpack - $templateCache.put('ngeo/offline/component.html', htmlTemplate); - }, - ], -); - -/** - * @param {!JQuery} $element Element. - * @param {!angular.IAttributes} $attrs Attributes. - * @param {!function(!JQuery, !angular.IAttributes): string} ngeoOfflineTemplateUrl Template function. - * @returns {string} Template URL. - */ -ngeoOfflineTemplateUrl.$inject = ['$element', '$attrs', 'ngeoOfflineTemplateUrl']; -function ngeoOfflineTemplateUrl($element, $attrs, ngeoOfflineTemplateUrl) { - return ngeoOfflineTemplateUrl($element, $attrs); -} - -/** - * Provides the "offline" component. - * - * Example: - * - * - * ngeo-offline-mask-margin="::100" - * ngeo-offline-min_zoom="::11" - * ngeo-offline-max_zoom="::15" - * - * - * See our live example: [../examples/offline.html](../examples/offline.html) - * - * @htmlAttribute {import('ol/Map').default} ngeo-offline-map The map. - * @htmlAttribute {number} ngeo-offline-extentsize The size, in map units, of a side of the extent. - * @private - * @ngdoc component - * @ngname ngeoOffline - */ -const component = { - bindings: { - 'map': '>} - * @private - */ - this.overlayCollection_ = new olCollection(); - this.featuresOverlay_.setFeatures(this.overlayCollection_); - - /** - * @type {?Polygon} - * @private - */ - this.dataPolygon_ = null; - - /** - * Whether the current view is the extent selection. - * - * @type {boolean} - * @export - */ - this.selectingExtent = false; - - /** - * Whether the current view is downloading one. - * - * @type {boolean} - * @export - */ - this.downloading = false; - - /** - * The progression of the data loading (0-100%). - * - * @type {number} - * @export - */ - this.progressPercents = 0; - - /** - * Whether the menu is currently displayed. - * - * @type {boolean} - * @export - */ - this.menuDisplayed = false; - - /** - * Whether the cancel download modal is displayed. - * - * @type {boolean} - * @export - */ - this.displayAlertAbortDownload = false; - - /** - * Whether the load data modal is displayed. - * - * @type {boolean} - * @export - */ - this.displayAlertLoadData = false; - - /** - * Whether the "no layer" modal is displayed. - * - * @type {boolean} - * @export - */ - this.displayAlertNoLayer = false; - - /** - * Offline mask minimum margin in pixels. - * - * @type {number} - * @export - */ - this.maskMargin = 0; - - /** - * Minimum zoom where offline is enable. - * - * @type {number} - * @export - */ - this.minZoom; - - /** - * Maximum zoom where offline is enable. - * - * @type {number} - * @export - */ - this.maxZoom; - - /** - * Map view max zoom constraint. - * - * @type {number} - * @export - */ - this.originalMinZoom; - - /** - * Map view min zoom constraint. - * - * @type {number} - * @export - */ - this.originalMaxZoom; - - /** - * @type {number} - * @export - */ - this.estimatedLoadDataSize = 0; - - /** - * @type {boolean} - */ - this.rotateMask = false; - - /** - * @private - * @param {import("ngeo/CustomEvent").default<{'progress': number}>} event the progress event. - */ - this.progressCallback_ = (event) => { - const progress = event.detail.progress; - this.progressPercents = Math.floor(progress * 100); - if (progress === 1) { - this.finishDownload_(); - } - this.$timeout_(() => {}, 0); // FIXME: force redraw - }; - } - $onInit() { - this.offlineMode.registerComponent(this); - this.ngeoOfflineConfiguration_.on( - /** @type {import('ol/Observable').EventTypes} */ 'progress', - /** @type {function(?): ?} */ this.progressCallback_, - ); - this.maskMargin = this.maskMargin || 100; - this.minZoom = this.minZoom || 10; - this.maxZoom = this.maxZoom || 15; - // @ts-ignore: extentInMeters does not exists... - this.maskLayer_ = new MaskLayer( - { - extentInMeters: this.extentSize, - }, - { - margin: this.maskMargin, - }, - ); - } - $onDestroy() { - this.ngeoOfflineConfiguration_.un( - /** @type {import('ol/Observable').EventTypes} */ 'progress', - /** @type {function(?): ?} */ this.progressCallback_, - ); - } - - /** - * @returns {boolean} True if data are accessible offline. - * @export - */ - hasData() { - return this.ngeoOfflineConfiguration_.hasOfflineData(); - } - - /** - * @export - */ - computeSizeAndDisplayAlertLoadData() { - this.estimatedLoadDataSize = this.ngeoOfflineConfiguration_.estimateLoadDataSize(this.map); - if (this.estimatedLoadDataSize > 0) { - this.displayAlertLoadData = true; - } else { - this.displayAlertNoLayer = true; - } - } - /** - * Toggle the selecting extent view. - * - * @param {boolean} [finished] If just finished downloading. - * @export - */ - toggleViewExtentSelection(finished) { - this.menuDisplayed = false; - this.selectingExtent = !this.selectingExtent; - this.map.removeLayer(this.maskLayer_); - this.removeZoomConstraints_(); - if (this.selectingExtent && !this.map.getLayers().getArray().includes(this.maskLayer_)) { - this.addZoomConstraints_(); - this.map.addLayer(this.maskLayer_); - } - this.map.render(); - } - - /** - * Validate the current extent and download data. - * - * @export - */ - validateExtent() { - this.progressPercents = 0; - const extent = this.getDowloadExtent_(); - this.downloading = true; - this.ngeoOfflineServiceManager_.save(extent, this.map); - } - - /** - * @private - */ - finishDownload_() { - this.downloading = false; - this.toggleViewExtentSelection(true); - } - - /** - * Ask to abort the download of data. - * - * @export - */ - askAbortDownload() { - this.displayAlertAbortDownload = true; - } - - /** - * Abort the download of data. - * - * @export - */ - abortDownload() { - this.downloading = false; - this.ngeoOfflineServiceManager_.cancel(); - this.deleteData(); - } - - /** - * Show the main menu. - * - * @export - */ - showMenu() { - this.menuDisplayed = true; - } - - /** - * Activate offline mode. - * Zoom to the extent of that data and restore the data. - * - * @export - */ - activateOfflineMode() { - this.ngeoOfflineServiceManager_.restore(this.map).then((extent) => { - this.dataPolygon_ = this.createPolygonFromExtent_(extent); - const size = this.map.getSize(); - if (size === undefined) { - throw new Error('Missing size'); - } - this.map.getView().fit(extent, { - size, - }); - this.menuDisplayed = false; - this.displayExtent_(); - this.offlineMode.enable(); - }); - } - - /** - * - * Deactivate offline mode. - * Reload the page. - * - * @export - */ - deactivateOfflineMode() { - window.location.reload(); - } - - /** - * Toggle the visibility of the data's extent. - * - * @export - */ - toggleExtentVisibility() { - if (this.isExtentVisible()) { - this.overlayCollection_.clear(); - } else { - this.displayExtent_(); - } - } - - /** - * @returns {boolean} True if the extent is currently visible. False otherwise. - * @export - */ - isExtentVisible() { - return this.overlayCollection_.getLength() > 0; - } - - /** - * Delete the saved data. - * - * @export - */ - deleteData() { - this.overlayCollection_.clear(); - this.dataPolygon_ = null; - if (this.networkStatus.isDisconnected()) { - this.menuDisplayed = false; - } - const reloadIfInOfflineMode = () => { - if (this.offlineMode.isEnabled()) { - this.deactivateOfflineMode(); - } - }; - this.ngeoOfflineConfiguration_.clear().then(reloadIfInOfflineMode); - } - - /** - * @private - */ - displayExtent_() { - if (!this.isExtentVisible() && this.dataPolygon_) { - const feature = new Feature(this.dataPolygon_); - this.overlayCollection_.push(feature); - } - } - - /** - * When enabling mask extent, zoom the view to the defined zoom range and - * add constraints to the view to not allow user to move out of this range. - * - * @private - */ - addZoomConstraints_() { - const view = this.map.getView(); - const zoom = view.getZoom() || 0; - this.originalMinZoom = view.getMinZoom(); - this.originalMaxZoom = view.getMaxZoom(); - if (zoom < this.minZoom) { - view.setZoom(this.minZoom); - } else if (zoom > this.maxZoom) { - view.setZoom(this.maxZoom); - } - view.setMaxZoom(this.maxZoom); - view.setMinZoom(this.minZoom); - } - - /** - * @private - */ - removeZoomConstraints_() { - const view = this.map.getView(); - if (this.originalMaxZoom !== undefined && this.originalMinZoom !== undefined) { - view.setMaxZoom(this.originalMaxZoom); - view.setMinZoom(this.originalMinZoom); - } - } - - /** - * A polygon on the whole extent of the projection, with a hole for the offline extent. - * - * @param {import('ol/extent').Extent} extent An extent - * @returns {Polygon} Polygon to save, based on the projection extent, the center of the map and - * the extentSize property. - * @private - */ - createPolygonFromExtent_(extent) { - const projExtent = this.map.getView().getProjection().getExtent(); - return new Polygon([extentToRectangle(projExtent), extentToRectangle(extent)], 'XY'); - } - - /** - * @returns {import('ol/extent').Extent} the download extent. - * @private - */ - getDowloadExtent_() { - const center = this.map.getView().getCenter(); - const halfLength = Math.ceil(this.extentSize || this.getExtentSize_()) / 2; - return this.maskLayer_.createExtent(center, halfLength); - } - getExtentSize_() { - const mapSize = this.map.getSize() || [150, 150]; - const maskSizePixel = DEVICE_PIXEL_RATIO * Math.min(mapSize[0], mapSize[1]) - this.maskMargin * 2; - const maskSizeMeter = (maskSizePixel * (this.map.getView().getResolution() || 1)) / DEVICE_PIXEL_RATIO; - return maskSizeMeter; - } -} -Controller.$inject = [ - '$timeout', - 'ngeoOfflineServiceManager', - 'ngeoOfflineConfiguration', - 'ngeoOfflineMode', - 'ngeoNetworkStatus', -]; -myModule.controller('ngeoOfflineController', Controller); -export default myModule; diff --git a/src/offline/index.js b/src/offline/index.js deleted file mode 100644 index 91b6b54e4098..000000000000 --- a/src/offline/index.js +++ /dev/null @@ -1,81 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2019-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -/** - * @typedef {Object} OfflineExtentByZoom - * @property {number} zoom - * @property {import('ol/extent').Extent} extent - */ - -/** - * @typedef {Object} OfflineLayerMetadata - * @property {import('ol/Map').default} map - * @property {OfflineExtentByZoom[]} extentByZoom - * @property {import('ol/layer/Layer').default} layer - * @property {import('ol/source/Source').default} source - * @property {string|undefined} layerType - * @property {string|undefined} layerSerialization - * @property {boolean} backgroundLayer - * @property {import('ol/layer/Group').default[]} ancestors - */ - -/** - * @typedef {Object} OfflinePersistentLayer - * @property {string|undefined} layerType - * @property {string|undefined} layerSerialization - * @property {boolean} backgroundLayer - * @property {string} key - */ - -/** - * @typedef {Object} OfflinePersistentContent - * @property {import('ol/extent').Extent} extent - * @property {!OfflinePersistentLayer[]} layers - * @property {!number[]} zooms - */ - -/** - * @typedef {Object} OfflineTile - * @property {import('ol/coordinate').Coordinate} coord - * @property {string} url - * @property {?string} response - */ - -/** - * @callback onTileDownloadSuccess - * @param {number} progress - * @param {OfflineTile} tile - * @returns {Promise} - */ - -/** - * @callback onTileDownloadError - * @param {number} progress - * @returns {Promise} - */ - -/** - * @typedef {Object} OfflineOnTileDownload - * @property {onTileDownloadSuccess} onTileDownloadSuccess - * @property {onTileDownloadError} onTileDownloadError - */ - -export default {}; diff --git a/src/offline/module.js b/src/offline/module.js deleted file mode 100644 index f14a4e6d14cd..000000000000 --- a/src/offline/module.js +++ /dev/null @@ -1,44 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import ngeoOfflineComponent from 'ngeo/offline/component'; -import ngeoOfflineNetworkStatus from 'ngeo/offline/NetworkStatus'; -import ngeoOfflineServiceManager from 'ngeo/offline/ServiceManager'; -import downloader from 'ngeo/offline/Downloader'; -import restorer from 'ngeo/offline/Restorer'; -import mode from 'ngeo/offline/Mode'; -import angular from 'angular'; - -/** - * @type {!angular.IModule} - */ -const exports = angular.module('ngeoOfflineModule', [ - ngeoOfflineComponent.name, - ngeoOfflineNetworkStatus.module.name, - ngeoOfflineServiceManager.module.name, - downloader.module.name, - restorer.module.name, - mode.module.name, -]); - -exports.value('ngeoOfflineGutter', 96); - -export default exports; diff --git a/src/offline/utils.js b/src/offline/utils.js deleted file mode 100644 index 8a16b732b986..000000000000 --- a/src/offline/utils.js +++ /dev/null @@ -1,53 +0,0 @@ -// The MIT License (MIT) -// -// Copyright (c) 2018-2024 Camptocamp SA -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import olLayerGroup from 'ol/layer/Group'; - -/** - * @param {import('ol/layer/Base').default} layer A layer tree. - * @param {!import('ol/layer/Group').default[]} ancestors The groups to which the layer belongs to. - * @param {function(import('ol/layer/Base').default, import('ol/layer/Group').default[]): boolean} visitor - * A function which will return false if descend must stop. - */ -export function traverseLayer(layer, ancestors, visitor) { - const descend = visitor(layer, ancestors); - if (descend && layer instanceof olLayerGroup) { - layer.getLayers().forEach((childLayer) => { - traverseLayer(childLayer, [...ancestors, layer], visitor); - }); - } -} - -const extractor = new RegExp('[^/]*//[^/]+/(.*)'); - -/** - * Extract the part after the URL authority. - * - * @param {string} url A URL to normalize - * @returns {string} The normalized string. - */ -export function normalizeURL(url) { - const matches = extractor.exec(url); - if (!matches) { - throw new Error('Could not normalize url ' + url); - } - return matches[1]; -} diff --git a/src/options.js b/src/options.js index d1924c16dad8..7a678e4ef89a 100644 --- a/src/options.js +++ b/src/options.js @@ -153,12 +153,6 @@ export function buildStyle(styleDescriptor) { * @typedef {import('ol/style/Style').StyleLike|Style[]|Style} StyleLike */ -/** - * URL of the test page to detect online/offline. - * - * @typedef {string} ngeoOfflineTestUrl - */ - /** * URL to the WFS server. * diff --git a/srcapi/store/config.spec.ts b/srcapi/store/config.spec.ts index e9e13210a274..808579a49d93 100644 --- a/srcapi/store/config.spec.ts +++ b/srcapi/store/config.spec.ts @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) 2021 Camptocamp SA +// Copyright (c) 2021-2024 Camptocamp SA // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in @@ -30,9 +30,9 @@ describe('Test store config', () => { }, }); - configuration.setConfig({ngeoOfflineTestUrl: 'test'} as Configuration); - expect(config.ngeoOfflineTestUrl).to.equal('test'); - configuration.setConfig({ngeoOfflineTestUrl: 'test2'} as Configuration); - expect(config.ngeoOfflineTestUrl).to.equal('test2'); + configuration.setConfig({authenticationBaseUrl: 'test'} as Configuration); + expect(config.authenticationBaseUrl).to.equal('test'); + configuration.setConfig({authenticationBaseUrl: 'test2'} as Configuration); + expect(config.authenticationBaseUrl).to.equal('test2'); }); }); diff --git a/srcapi/store/config.ts b/srcapi/store/config.ts index 285cd0e02571..3e0b462cfb87 100644 --- a/srcapi/store/config.ts +++ b/srcapi/store/config.ts @@ -250,11 +250,6 @@ export function buildStyle(styleDescriptor: StyleLike): OlStyleStyleStyleLike { } } -/** - * URL of the test page to detect online/offline. - */ -export type ngeoOfflineTestUrl = string; - /** * URL to the WFS server. */ @@ -1405,7 +1400,6 @@ export type gmfDatasourceOptions = { */ export type Configuration = { authenticationBaseUrl: authenticationBaseUrl; - ngeoOfflineTestUrl: ngeoOfflineTestUrl; ngeoPermalinkOgcserverUrl: ngeoPermalinkOgcserverUrl; ngeoNominatimSearchDefaultParams: ngeoNominatimSearchDefaultParams; ngeoQueryOptions: ngeoQueryOptions;