diff --git a/build/webpack/bundle.webpack.config.js b/build/webpack/bundle.webpack.config.js index ffc3805bd..a2b9bfbe9 100644 --- a/build/webpack/bundle.webpack.config.js +++ b/build/webpack/bundle.webpack.config.js @@ -88,14 +88,19 @@ module.exports = (env, argv) => { server : "https", open : ["samples/index-bundle.html"], static : { - directory : path.join(rootdir) + directory : path.join(rootdir), + watch : { + usePolling : false, + ignored : [ + path.join(rootdir, "samples-src/**/*"), + path.join(rootdir, "demos/**/*"), + path.join(rootdir, "node_modules/**/*"), + path.join(rootdir, "samples/resources/vendor/modules/**/*") + ] + } }, watchFiles : { - paths : ["src/**/*"], - options : { - usePolling : false, - ignored : ["demos/**", "node_modules/**"] - }, + paths : ["src/**/*"] }, devMiddleware : { index : true, diff --git a/build/webpack/modules.webpack.config.js b/build/webpack/modules.webpack.config.js index 3dce29b81..79d0c9fe9 100644 --- a/build/webpack/modules.webpack.config.js +++ b/build/webpack/modules.webpack.config.js @@ -118,14 +118,19 @@ module.exports = (env, argv) => { server : "https", open : ["samples/index-modules.html"], static : { - directory : path.join(rootdir) + directory : path.join(rootdir), + watch : { + usePolling : false, + ignored : [ + path.join(rootdir, "samples-src/**/*"), + path.join(rootdir, "demos/**/*"), + path.join(rootdir, "node_modules/**/*"), + path.join(rootdir, "samples/resources/vendor/modules/**/*") + ] + } }, watchFiles : { - paths : ["src/**/*"], - options : { - usePolling : false, - ignored : ["demos/**", "node_modules/**"] - }, + paths : ["src/**/*"] }, devMiddleware : { index : true, diff --git a/demos/esmodule-project/.gitignore b/demos/esmodule-project/.gitignore new file mode 100644 index 000000000..8ee54e8d3 --- /dev/null +++ b/demos/esmodule-project/.gitignore @@ -0,0 +1,30 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +*.tsbuildinfo diff --git a/demos/esmodule-project/esmodule.png b/demos/esmodule-project/esmodule.png new file mode 100644 index 000000000..b206b4c0e Binary files /dev/null and b/demos/esmodule-project/esmodule.png differ diff --git a/demos/esmodule-project/index.html b/demos/esmodule-project/index.html new file mode 100644 index 000000000..f08018607 --- /dev/null +++ b/demos/esmodule-project/index.html @@ -0,0 +1,18 @@ + + + + + + + Using OpenLayers with Vite + + +
+ +
+
+
+ +
+ + diff --git a/demos/esmodule-project/main.js b/demos/esmodule-project/main.js new file mode 100644 index 000000000..615843256 --- /dev/null +++ b/demos/esmodule-project/main.js @@ -0,0 +1,131 @@ +import "./style.css"; +import { + Map, + View +} from "ol"; +import TileLayer from "ol/layer/Tile"; +import OSM from "ol/source/OSM"; + +import { + Drawing, + Isocurve, + Route, + LayerImport, + GeoportalAttribution, + ElevationPath, + MeasureArea, + MeasureAzimuth, + MeasureLength, + LayerSwitcher, + MousePosition as GeoportalMousePosition, + ReverseGeocode, + SearchEngine, + GetFeatureInfo, + CRS, + LayerMapBox as GeoportalLayerMapBox, + LayerWMTS as GeoportalLayerWMTS +} from "geoportal-extensions-openlayers"; + +import Gp from "geoportal-access-lib"; + +var cfg = new Gp.Services.Config({ + customConfigFile : "https://raw.githubusercontent.com/IGNF/geoportal-configuration/new-url/dist/fullConfig.json", + onSuccess : () => { + CRS.load(); + + const map = new Map({ + target : "map", + layers : [ + new TileLayer({ + source : new OSM() + }), + new GeoportalLayerMapBox({ + layer : "PLAN.IGN" + }), + new GeoportalLayerWMTS({ + layer : "ORTHOIMAGERY.ORTHOPHOTOS" + }) + ], + view : new View({ + center : [288074.8449901076, 6247982.515792289], + zoom : 8, + }) + }); + + var drawing = new Drawing({ + position : "bottom-right" + }); + map.addControl(drawing); + + var iso = new Isocurve({ + position : "bottom-left" + }); + map.addControl(iso); + + var layerImport = new LayerImport({ + position : "bottom-left" + }); + map.addControl(layerImport); + + var layerSwitcher = new LayerSwitcher({ + options : { + position : "top-right" + } + }); + map.addControl(layerSwitcher); + + var mp = new GeoportalMousePosition({ + position : "top-right" + }); + map.addControl(mp); + + var route = new Route({ + position : "top-right" + }); + map.addControl(route); + + var reverse = new ReverseGeocode({ + position : "top-right" + }); + map.addControl(reverse); + + var search = new SearchEngine({ + position : "top-right" + }); + map.addControl(search); + + var feature = new GetFeatureInfo({ + options : { + position : "top-right" + } + }); + map.addControl(feature); + + var measureLength = new MeasureLength({ + position : "bottom-left" + }); + map.addControl(measureLength); + + var measureArea = new MeasureArea({ + position : "bottom-left" + }); + map.addControl(measureArea); + + var measureAzimuth = new MeasureAzimuth({ + position : "bottom-left" + }); + map.addControl(measureAzimuth); + + var measureProfil = new ElevationPath({ + position : "bottom-left" + }); + map.addControl(measureProfil); + + var attributions = new GeoportalAttribution(); + map.addControl(attributions); + }, + onFailure : (e) => { + console.error(e); + } +}); +cfg.call(); \ No newline at end of file diff --git a/demos/esmodule-project/package.json b/demos/esmodule-project/package.json new file mode 100644 index 000000000..929ec00a1 --- /dev/null +++ b/demos/esmodule-project/package.json @@ -0,0 +1,16 @@ +{ + "name": "my-app", + "version": "1.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "serve": "vite preview" + }, + "devDependencies": { + "vite": "^5.2.11" + }, + "dependencies": { + "geoportal-extensions-openlayers": "../../dist/package/geoportal-extensions-openlayers.tgz", + "ol": "latest" + } +} diff --git a/demos/esmodule-project/readme.md b/demos/esmodule-project/readme.md new file mode 100644 index 000000000..8c8c69a62 --- /dev/null +++ b/demos/esmodule-project/readme.md @@ -0,0 +1,18 @@ +# OpenLayers + Vite + +This example demonstrates how the `ol` package can be used with [Vite](https://vitejs.dev/). + +To get started, run the following (requires Node 14+): + + npx create-ol-app my-app --template vite + +Then change into your new `my-app` directory and start a development server (available at http://localhost:5173): + + cd my-app + npm run dev + +To generate a build ready for production: + + npm run build + +Then deploy the contents of the `dist` directory to your server. You can also run `npm run serve` to serve the results of the `dist` directory for preview. diff --git a/demos/esmodule-project/style.css b/demos/esmodule-project/style.css new file mode 100644 index 000000000..a2e7c21cd --- /dev/null +++ b/demos/esmodule-project/style.css @@ -0,0 +1,28 @@ +@import "node_modules/ol/ol.css"; +@import "node_modules/geoportal-extensions-openlayers/css/Classic.css"; + +html, body { + margin: 0; + height: 100%; +} +header { + display: flex; + place-items: center; + justify-content: center; +} + +.logo { + margin: 0 2rem 0 0; +} + +header .wrapper { + display: flex; + place-items: flex-start; + flex-wrap: wrap; +} + +#map { + position: absolute; + height: 500px; + width: 100%; +} diff --git a/demos/esmodule-project/vite.config.js b/demos/esmodule-project/vite.config.js new file mode 100644 index 000000000..9d365f5fb --- /dev/null +++ b/demos/esmodule-project/vite.config.js @@ -0,0 +1,5 @@ +export default { + build : { + sourcemap : true, + } +}; diff --git a/package.json b/package.json index 8b6b1915c..a03471582 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "geoportal-extensions-openlayers", "description": "French Geoportal Extensions for OpenLayers libraries", - "version": "1.0.0-beta.52", + "version": "1.0.0-beta.32-52", "date": "24/05/2024", "module": "src/index.js", "directories": {}, diff --git a/samples-src/pages/tests/Default/pages-ol-bundle-default.html b/samples-src/pages/tests/Default/pages-ol-bundle-default.html index 28d92fdb8..afa596b47 100644 --- a/samples-src/pages/tests/Default/pages-ol-bundle-default.html +++ b/samples-src/pages/tests/Default/pages-ol-bundle-default.html @@ -77,7 +77,7 @@

Ajout de tous les widgets

}); map.addControl(reverse); var search = new ol.control.SearchEngine({ - position : "top-right" + position : "top-left" }); map.addControl(search); var feature = new ol.control.GetFeatureInfo({ diff --git a/samples-src/pages/tests/Default/pages-ol-bundle-dsfr-default.html b/samples-src/pages/tests/Default/pages-ol-bundle-dsfr-default.html index eb8c2dd6f..777127338 100644 --- a/samples-src/pages/tests/Default/pages-ol-bundle-dsfr-default.html +++ b/samples-src/pages/tests/Default/pages-ol-bundle-dsfr-default.html @@ -77,7 +77,7 @@

Ajout de tous les widgets

}); map.addControl(reverse); var search = new ol.control.SearchEngine({ - position : "top-right" + position : "top-left" }); map.addControl(search); var feature = new ol.control.GetFeatureInfo({ diff --git a/samples-src/pages/tests/Default/pages-ol-modules-default.html b/samples-src/pages/tests/Default/pages-ol-modules-default.html index fb5c59b5a..4bca96510 100644 --- a/samples-src/pages/tests/Default/pages-ol-modules-default.html +++ b/samples-src/pages/tests/Default/pages-ol-modules-default.html @@ -101,20 +101,20 @@

Ajout de tous les widgets

position : "bottom-right" }); map.addControl(route); + var feature = new ol.control.GetFeatureInfo({ + options :{ + position : "top-right" + } + }); + map.addControl(feature); var reverse = new ol.control.ReverseGeocode({ position : "top-right" }); map.addControl(reverse); var search = new ol.control.SearchEngine({ - position : "top-right" + position : "top-left" }); map.addControl(search); - var feature = new ol.control.GetFeatureInfo({ - options :{ - position : "top-right" - } - }); - map.addControl(feature); var measureLength = new ol.control.MeasureLength({ position : "top-left" diff --git a/samples-src/pages/tests/Default/pages-ol-modules-dsrf-default.html b/samples-src/pages/tests/Default/pages-ol-modules-dsrf-default.html index aca4be526..0f2793112 100644 --- a/samples-src/pages/tests/Default/pages-ol-modules-dsrf-default.html +++ b/samples-src/pages/tests/Default/pages-ol-modules-dsrf-default.html @@ -102,21 +102,20 @@

Ajout de tous les widgets

position : "bottom-right" }); map.addControl(route); + var feature = new ol.control.GetFeatureInfo({ + options :{ + position : "top-right" + } + }); + map.addControl(feature); var reverse = new ol.control.ReverseGeocode({ position : "top-right" }); map.addControl(reverse); var search = new ol.control.SearchEngine({ - position : "top-right", - displayButtonGeolocate : true + position : "top-left" }); map.addControl(search); - var feature = new ol.control.GetFeatureInfo({ - options :{ - position : "top-right" - } - }); - map.addControl(feature); var measureLength = new ol.control.MeasureLength({ position : "top-left" diff --git a/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-addlayers.html b/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-addlayers.html index d0ba371c9..90643ec47 100644 --- a/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-addlayers.html +++ b/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-addlayers.html @@ -17,6 +17,13 @@ width: 100%; height: 500px; } + .wrapper { + display: flex; + flex-direction: row; + align-items: flex-start; + align-content: flex-start; + justify-content: flex-start; + } {{/content}} @@ -25,14 +32,18 @@

Ajout du gestionnaire de couches avec formulaire d'ajout de couche

-
- - -
- - - - +
+
+ + +
+ + + + +
+
+
{{/content}} @@ -41,12 +52,20 @@

Ajout du gestionnaire de couches avec formulaire d'ajout de couche

var map; var layerSwitcher; var addMapsLayer, addOSMLayer; - var osm, maps; + var osm, ortho, maps; var createMap = function() { // on cache l'image de chargement du Géoportail. document.getElementById('map').style.backgroundImage = 'none'; + osm = new ol.layer.Tile({ + source : new ol.source.OSM(), + opacity : 0.8 + }); + ortho = new ol.layer.GeoportalWMTS({ + layer : "ORTHOIMAGERY.ORTHOPHOTOS" + }); + // Création de la map map = new ol.Map({ target : "map", @@ -55,18 +74,71 @@

Ajout du gestionnaire de couches avec formulaire d'ajout de couche

zoom : 6 }), layers : [ - new ol.layer.Tile({ - source : new ol.source.OSM(), - opacity : 0.8 - }) + osm, + ortho ] }); + // Appel du LayerSwitcher - layerSwitcher = new ol.control.LayerSwitcher({}); + layerSwitcher = new ol.control.LayerSwitcher({ + options : { + position : "bottom-right", + collapsed : false, + panel : true, + counter : true + } + }); // Ajout du LayerSwitcher à la carte map.addControl(layerSwitcher); + + // Evenement + layerSwitcher.on("layerswitcher:add", function (e) { + console.warn("layer", e, e.layer); + }); + layerSwitcher.on("layerswitcher:remove", function (e) { + console.warn("layer", e, e.layer); + }); + layerSwitcher.on("layerswitcher:change:opacity", function (e) { + console.warn("layer", e, e.layer, e.opacity); + }); + layerSwitcher.on("layerswitcher:change:visibility", function (e) { + console.warn("layer", e, e.layer, e.visibility); + }); + + // // Appel du LayerSwitcher + // var layerSwitcher1 = new ol.control.LayerSwitcher({ + // options : { + // position : "bottom-left", + // collapsed : false + // } + // }); + + // // Ajout du LayerSwitcher à la carte + // map.addControl(layerSwitcher1); + + // // Appel du LayerSwitcher + // var layerSwitcher2 = new ol.control.LayerSwitcher({ + // options : { + // position : "top-left", + // collapsed : false + // } + // }); + + // // Ajout du LayerSwitcher à la carte + // map.addControl(layerSwitcher2); + + // // Appel du LayerSwitcher + // var layerSwitcher3 = new ol.control.LayerSwitcher({ + // options : { + // // position : "top-right", + // collapsed : false + // } + // }); + + // // Ajout du LayerSwitcher à la carte + // map.addControl(layerSwitcher3); }; Gp.Services.getConfig({ @@ -74,7 +146,8 @@

Ajout du gestionnaire de couches avec formulaire d'ajout de couche

callbackSuffix : "", // apiKey: "{{ apikey }}", timeOut : 20000, - onSuccess : createMap + onSuccess : createMap, + onFailure : (e) => { console.error(e); } }); addMapsLayer = function() { diff --git a/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-dsfr-addlayers.html b/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-dsfr-addlayers.html index 157694a57..b3b2de9ef 100644 --- a/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-dsfr-addlayers.html +++ b/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-dsfr-addlayers.html @@ -41,12 +41,20 @@

Ajout du gestionnaire de couches avec formulaire d'ajout de couche

var map; var layerSwitcher; var addMapsLayer, addOSMLayer; - var osm, maps; + var osm, maps, ortho; var createMap = function() { // on cache l'image de chargement du Géoportail. document.getElementById('map').style.backgroundImage = 'none'; + osm = new ol.layer.Tile({ + source : new ol.source.OSM(), + opacity : 0.8 + }); + ortho = new ol.layer.GeoportalWMTS({ + layer : "ORTHOIMAGERY.ORTHOPHOTOS" + }); + // Création de la map map = new ol.Map({ target : "map", @@ -55,18 +63,73 @@

Ajout du gestionnaire de couches avec formulaire d'ajout de couche

zoom : 6 }), layers : [ - new ol.layer.Tile({ - source : new ol.source.OSM(), - opacity : 0.8 - }) + osm, + ortho ] }); // Appel du LayerSwitcher - layerSwitcher = new ol.control.LayerSwitcher({}); + layerSwitcher = new ol.control.LayerSwitcher({ + options : { + position : "bottom-right", + collapsed : false, + panel : true, + counter : true + } + }); + + // Evenement + layerSwitcher.on("layerswitcher:add", function (e) { + console.warn("layer", e, e.layer); + }); + layerSwitcher.on("layerswitcher:remove", function (e) { + console.warn("layer", e, e.layer); + }); + layerSwitcher.on("layerswitcher:change:opacity", function (e) { + console.warn("layer", e, e.layer, e.opacity); + }); + layerSwitcher.on("layerswitcher:change:visibility", function (e) { + console.warn("layer", e, e.layer, e.visibility); + }); + layerSwitcher.on("layerswitcher:extent", function (e) { + console.warn("layer", e); + }); // Ajout du LayerSwitcher à la carte map.addControl(layerSwitcher); + + // // Appel du LayerSwitcher + // var layerSwitcher1 = new ol.control.LayerSwitcher({ + // options : { + // position : "bottom-left", + // collapsed : false + // } + // }); + + // // Ajout du LayerSwitcher à la carte + // map.addControl(layerSwitcher1); + + // // Appel du LayerSwitcher + // var layerSwitcher2 = new ol.control.LayerSwitcher({ + // options : { + // position : "top-left", + // collapsed : false + // } + // }); + + // // Ajout du LayerSwitcher à la carte + // map.addControl(layerSwitcher2); + + // // Appel du LayerSwitcher + // var layerSwitcher3 = new ol.control.LayerSwitcher({ + // options : { + // // position : "top-right", + // collapsed : false + // } + // }); + + // // Ajout du LayerSwitcher à la carte + // map.addControl(layerSwitcher3); }; Gp.Services.getConfig({ diff --git a/samples-src/pages/tests/Layers/pages-ol-layermapbox-modules-conf.html b/samples-src/pages/tests/Layers/pages-ol-layermapbox-modules-conf.html new file mode 100644 index 000000000..04363ed92 --- /dev/null +++ b/samples-src/pages/tests/Layers/pages-ol-layermapbox-modules-conf.html @@ -0,0 +1,142 @@ +{{#extend "ol-sample-modules-layout"}} + +{{#content "vendor"}} + + + +{{/content}} + +{{#content "head"}} + Sample openlayers +{{/content}} + +{{#content "style"}} + +{{/content}} + +{{#content "body"}} +

Ajout d'une couche MapBox

+ +
+
+{{/content}} + +{{#content "js"}} + +{{/content}} + +{{/extend}} diff --git a/samples-src/pages/tests/Layers/pages-ol-layermapbox-modules-default.html b/samples-src/pages/tests/Layers/pages-ol-layermapbox-modules-default.html index c2c310ee8..c6f433662 100644 --- a/samples-src/pages/tests/Layers/pages-ol-layermapbox-modules-default.html +++ b/samples-src/pages/tests/Layers/pages-ol-layermapbox-modules-default.html @@ -1,6 +1,8 @@ {{#extend "ol-sample-modules-layout"}} {{#content "vendor"}} + + {{/content}} @@ -44,6 +46,12 @@

Ajout d'une couche MapBox

}) ] }); + + // Appel du LayerSwitcher + var layerSwitcher = new ol.control.LayerSwitcher(); + + // Ajout du LayerSwitcher à la carte + map.addControl(layerSwitcher); }; Gp.Services.getConfig({ customConfigFile : "{{ configurl }}", diff --git a/samples-src/pages/tests/Layers/pages-ol-layerwmts-modules-conf.html b/samples-src/pages/tests/Layers/pages-ol-layerwmts-modules-conf.html new file mode 100644 index 000000000..140b09dd1 --- /dev/null +++ b/samples-src/pages/tests/Layers/pages-ol-layerwmts-modules-conf.html @@ -0,0 +1,651 @@ +{{#extend "ol-sample-modules-layout"}} + +{{#content "vendor"}} + + + +{{/content}} + +{{#content "head"}} + Sample openlayers +{{/content}} + +{{#content "style"}} + +{{/content}} + +{{#content "body"}} +

Ajout d'une couche WMTS

+ +
+
+{{/content}} + +{{#content "js"}} + +{{/content}} + +{{/extend}} diff --git a/samples-src/pages/tests/Services/pages-ol-searchservice-modules-default.html b/samples-src/pages/tests/Services/pages-ol-searchservice-modules-default.html index d2dbd720a..eeecc503b 100644 --- a/samples-src/pages/tests/Services/pages-ol-searchservice-modules-default.html +++ b/samples-src/pages/tests/Services/pages-ol-searchservice-modules-default.html @@ -1,4 +1,4 @@ -{{#extend "ol-sample-modules-layout"}} +{{#extend "ol-sample-sources-layout"}} {{#content "vendor"}} diff --git a/samples-src/templates/packages/ol-sample-sources-layout.hbs b/samples-src/templates/packages/ol-sample-sources-layout.hbs new file mode 100644 index 000000000..bcde888b9 --- /dev/null +++ b/samples-src/templates/packages/ol-sample-sources-layout.hbs @@ -0,0 +1,25 @@ + + + + {{#extend "partials-common-head"}} + {{/extend}} + + {{#block "vendor"}} + {{/block}} + + {{#block "head"}} + {{/block}} + {{#block "style"}} + {{/block}} + + + +

Extension Géoportail pour OpenLayers

+ + {{#block "body"}} + {{/block}} + + {{#block "js"}} + {{/block}} + + diff --git a/src/packages/CSS/Controls/ElevationPath/GPFelevationPath.css b/src/packages/CSS/Controls/ElevationPath/GPFelevationPath.css index 0900df9c1..8b87c5c55 100644 --- a/src/packages/CSS/Controls/ElevationPath/GPFelevationPath.css +++ b/src/packages/CSS/Controls/ElevationPath/GPFelevationPath.css @@ -1,5 +1,5 @@ div[id^=GPelevationPath-] { - height: 36px; + /* height: 36px; */ } /* Showing/hiding elevationPath panel */ @@ -21,12 +21,6 @@ button[id^="GPshowElevationPathPicto-"][aria-pressed="true"] + dialog { /* Panel */ -[id^=GPelevationPathPanelClose] { - background-image: url("img/GPshowElevationPath.png"); - background-repeat: no-repeat; - background-position: -27px center; -} - [id^=GPelevationPathPanelReduce] { background-image: url("img/GPshowElevationPath.png"); background-repeat: no-repeat; diff --git a/src/packages/CSS/Controls/ElevationPath/GPFelevationPathStyle.css b/src/packages/CSS/Controls/ElevationPath/GPFelevationPathStyle.css index de58f3b5c..099d346ff 100644 --- a/src/packages/CSS/Controls/ElevationPath/GPFelevationPathStyle.css +++ b/src/packages/CSS/Controls/ElevationPath/GPFelevationPathStyle.css @@ -2,6 +2,13 @@ padding: unset; } + +[id^=GPelevationPathPanelClose] { + background-image: url("img/GPshowElevationPath.png"); + background-repeat: no-repeat; + background-position: -27px center; +} + /* CSS : Raw */ #profileElevationRaw { diff --git a/src/packages/CSS/Controls/LayerSwitcher/DSFRlayerSwitcherStyle.css b/src/packages/CSS/Controls/LayerSwitcher/DSFRlayerSwitcherStyle.css index e69de29bb..aab6cc2ce 100644 --- a/src/packages/CSS/Controls/LayerSwitcher/DSFRlayerSwitcherStyle.css +++ b/src/packages/CSS/Controls/LayerSwitcher/DSFRlayerSwitcherStyle.css @@ -0,0 +1,139 @@ +div[id^=GPlayerSwitcher-] { + height: 44px; +} + +button[id^=GPshowLayersListPicto] { + width: 40px; +} + +button[id^=GPshowLayersListPicto][aria-pressed="true"] + dialog[id^=GPlayersList] { + width: 350px; +} + +.gpf-btn-icon-layerswitcher { + background-image: url("img/dsfr/layerswitcher.svg"); + background-repeat: no-repeat; + background-size: auto auto; + background-position: center center; +} + +.gpf-btn-icon-ls-visibility { + background-image: url("img/dsfr/visible-open.svg"); + background-repeat: no-repeat; + background-size: auto auto; + background-position: center center; + box-shadow: none; +} + +button[id^=GPvisibilityPicto_ID_][aria-pressed="false"] { + background-image: url("img/dsfr/visible-close-blanc.svg"); + background-repeat: no-repeat; + background-size: auto auto; + background-position: center center; + box-shadow: none; +} + +.gpf-btn-icon-ls-remove { + background-image: url("img/dsfr/remove.svg"); + background-repeat: no-repeat; + background-size: auto auto; + background-position: center center; + box-shadow: none; +} + +.gpf-btn-icon-ls-collapse { + background-image: url("img/dsfr/collapse.svg"); + background-repeat: no-repeat; + background-size: auto auto; + background-position: center center; + box-shadow: none; +} + +.gpf-btn-icon-ls-dragndrop { + background-image: url("img/dsfr/dragndrop-blanc.svg"); + background-repeat: no-repeat; + background-size: auto auto; + background-position: center center; + box-shadow: none; +} + +button[id^=GPshowAdvancedTools_ID_][aria-pressed="false"] { + background-image: url("img/dsfr/collapse.svg"); + background-repeat: no-repeat; + background-size: auto auto; + background-position: center center; + box-shadow: none; +} +button[id^=GPshowAdvancedTools_ID_] { + position: absolute; + top: 0; + right: 0; +} + +div[id^=GPbasicTools_ID_] { + display: flex; + align-items: center; + justify-content: flex-end; + flex-wrap: nowrap; + flex-direction: row-reverse; +} + +div[id^=GPadvancedTools_ID_] { + display: flex; + align-content: center; + align-items: center; + flex-direction: row; + flex-wrap: nowrap; + justify-content: space-around; +} + +.gpf-btn-header { + z-index: 2; + position: absolute; + width: 26px; + height: 26px; +} + +.gpf-btn-icon-layers { + background-image: url("img/dsfr/layers.svg"); + background-repeat: no-repeat; + background-size: auto auto; + background-position: center center; +} +.gpf-panel__title_ls { + color: #101092; + padding: 12px 15px; + position: relative; + font-size: 1rem; + font-weight: normal; + margin: 0; + right: -16px; +} +.gpf-panel__header_ls { + display: flex; + flex-direction: row; + align-items: center; + align-content: center; + background: #E3E3FD; +} + +.gpf-btn-icon-ls-info { + background-image: url("img/dsfr/info.svg"); + background-repeat: no-repeat; + background-size: auto auto; + background-position: center center; + box-shadow: none; +} + +.gpf-btn-icon-ls-extent { + background-image: url("img/dsfr/extent.svg"); + background-repeat: no-repeat; + background-size: auto auto; + background-position: center center; + box-shadow: none; +} + +div[id^=GPlayerInfoPanel] { + position: absolute; + height: initial; +} \ No newline at end of file diff --git a/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcher.css b/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcher.css index c23dee320..c40608a9f 100644 --- a/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcher.css +++ b/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcher.css @@ -5,12 +5,6 @@ div[id^=GPlayerSwitcher-] { right: 8px; } -div[id^=GPlayerSwitcher-] { - /* dsfr */ - flex-direction: row-reverse; - align-items: flex-start; -} - div[id^=GPlayerSwitcher-] [draggable] { -moz-user-select: none; -khtml-user-select: none; @@ -33,14 +27,6 @@ input[id^=GPshowLayersList-] { /* Showing/hiding layers list */ -button[id^=GPshowLayersListPicto] { - float: right; - /* transition: opacity 0.5s ease-out 0s, box-shadow 0.5s ease-out 0s, border 0.5s ease-out 0s, border-radius 0.5s ease-out 0s; */ - background-position: -2px center; - background-repeat: no-repeat; - background-image: url("img/GPshowLayersList.png"); -} - button[id^=GPshowLayersListPicto][aria-pressed="false"] + dialog { display: none; visibility: hidden; @@ -54,17 +40,24 @@ button[id^="GPshowLayersListPicto-"][aria-pressed="true"] + dialog { opacity: 100%; } -button[id^=GPshowLayersListPicto][aria-pressed="true"] { - border-top-right-radius: 0; - border-top-left-radius: 0; - background-position: -35px center; - /* transition: border-radius 0.5s ease-out 0s, opacity 0.5s ease-out 0s; */ +/* Layers list */ +/* positionnement actif */ +.position > div[id^=GPlayerSwitcher-] > dialog[id^=GPlayersList] { + position: absolute; +} +.position > div[id^=GPlayerSwitcher-] > button[id^=GPshowLayersListPicto-] { + float: unset; } -/* Layers list */ +/* positionnement inactif */ +dialog[id^=GPlayersList] { + position: relative; +} +button[id^=GPshowLayersListPicto-] { + float: right; +} dialog[id^=GPlayersList] { - position: relative; border-bottom-right-radius: 0; opacity: 0; overflow: auto; @@ -72,15 +65,29 @@ dialog[id^=GPlayersList] { } button[id^=GPshowLayersListPicto][aria-pressed="true"] + dialog[id^=GPlayersList] { + height: initial; max-height: 232px; - width: 180px; opacity: 1; } button[id^=GPshowLayersListPicto][aria-pressed="false"] + dialog[id^=GPlayersList] { /* transition: max-height 0.5s ease-in 0s, opacity 0.25s ease-in 0s; */ +} +.GPlayerCounter { + position: absolute; + background: #fff; + color: #000; + padding: 2px 0px 1px; + border-radius: 100px; + min-width: 15px; + text-align: center; + font-size: 12px; + line-height: 1; + top: -6px; + left: -8px; } + /* Layer : general */ .GPlayerSwitcher_layer { @@ -95,3 +102,42 @@ dialog[id^=GPlayersList] .GPlayerSwitcher_layer:last-child { border-bottom: none; } +/* Showing layer advanced tools */ + + +.GPlayerAdvancedTools { + display: block; + max-height: 0; + opacity: 0; + transition: max-height 0.5s ease-out 0s, opacity 0.5s ease-out 0s; +} + +button[id^=GPshowAdvancedTools_ID_][aria-pressed="true"] + .GPlayerAdvancedTools { + max-height: 28px; + opacity: 1; +} + +.GPlayerName { + left: 28px; + width: calc(100% - 56px); + line-height: 28px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + padding-left: 4px; + cursor: move; +} + +.outOfRange .GPlayerName { + color: #AAA; +} + +div[id^=GPlayerInfoContent] { + position: relative; + width: 280px; + max-height: 200px; + overflow-y: auto; + padding-left: 10px; + padding-right: 10px; +} + diff --git a/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcherStyle.css b/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcherStyle.css index 2c5e517f0..a0bb9b853 100644 --- a/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcherStyle.css +++ b/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcherStyle.css @@ -1,12 +1,46 @@ -/* LAYER SWITCHER OL3 */ +/* LAYER SWITCHER */ +div[id^=GPlayerSwitcher-] { + height: 32px; +} +button[id^=GPshowLayersListPicto][aria-pressed="true"] + dialog[id^=GPlayersList] { + width: 190px; +} +button[id^=GPshowLayersListPicto] { + /* transition: opacity 0.5s ease-out 0s, box-shadow 0.5s ease-out 0s, border 0.5s ease-out 0s, border-radius 0.5s ease-out 0s; */ + background-position: -2px center; + background-repeat: no-repeat; + background-image: url("img/GPshowLayersList.png"); +} +button[id^=GPshowLayersListPicto][aria-pressed="true"] { + border-top-right-radius: 0; + border-top-left-radius: 0; + background-position: -35px center; + /* transition: border-radius 0.5s ease-out 0s, opacity 0.5s ease-out 0s; */ +} /* Layers list */ +button[id^=GPlayerInfoClose] { + background-position: -2px center; + background-repeat: no-repeat; + background-image: url("img/GPlayerInfoClose.png"); + background-color: unset; +} +button[id^=GPlayersPanelClose] { + background-position: -2px center; + background-repeat: no-repeat; + background-image: url("img/GPlayerClose.png"); +} - +.GPpanelIcon { + background-image: url("img/layers.svg"); + background-repeat: no-repeat; + background-size: auto auto; + background-position: center center; +} /* Layer info panel */ div[id^=GPlayerInfoPanel] { @@ -26,6 +60,7 @@ div[id^=GPlayerInfoTitle] { height: 28px; } +.GPlayerExtent, .GPlayerVisibility, .GPlayerInfo, .GPlayerInfoOpened, @@ -35,6 +70,7 @@ div[id^=GPlayerInfoTitle] { cursor: pointer; } +.GPlayerExtent, .GPlayerVisibility, .GPlayerName, .GPlayerInfo, @@ -57,40 +93,9 @@ div[id^=GPlayerInfoTitle] { } - -.GPlayerName { - left: 28px; - width: calc(100% - 56px); - line-height: 28px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - padding-left: 4px; - cursor: move; -} - -.outOfRange .GPlayerName { - color: #AAA; -} - -/* Showing layer advanced tools */ - - -.GPlayerAdvancedTools { - display: block; - max-height: 0; - opacity: 0; - transition: max-height 0.5s ease-out 0s, opacity 0.5s ease-out 0s; -} - -div[id^=GPlayerSwitcher-] input[type="checkbox"]:checked + label + .GPlayerAdvancedTools { - max-height: 28px; - opacity: 1; -} - /* Layer advanced tools */ - +.GPlayerExtent, .GPlayerVisibility, .GPshowLayerAdvancedTools, .GPlayerInfo, @@ -131,12 +136,19 @@ div[id^=GPlayerInfoClose] { background-image: url("img/GPlayerInfo.png"); } -.GPlayerVisibility { +button[id^=GPinfo_ID_], +button[id^=GPremove_ID_], +button[id^=GPvisibilityPicto_ID_] { + border: none; + background-color: transparent; +} + +button[id^=GPvisibilityPicto_ID_][aria-pressed="false"] { left: 0; background-position: -28px 0; } -input[type="checkbox"]:checked + .GPlayerVisibility { +button[id^=GPvisibilityPicto_ID_][aria-pressed="true"] { background-position: 0 0; } @@ -287,14 +299,14 @@ div[id^=GPlayerInfoPanel] { display: none; } -div[id^=GPlayerInfoContent] { +/* div[id^=GPlayerInfoContent] { position: relative; width: 280px; max-height: 200px; overflow-y: auto; padding-left: 10px; padding-right: 10px; -} +} */ div[id^=GPlayerInfoTitle] { width: calc(100% - 52px); diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/GPlayerClose.png b/src/packages/CSS/Controls/LayerSwitcher/img/GPlayerClose.png new file mode 100644 index 000000000..d0e50506b Binary files /dev/null and b/src/packages/CSS/Controls/LayerSwitcher/img/GPlayerClose.png differ diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/collapse.svg b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/collapse.svg new file mode 100644 index 000000000..1e3679d82 --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/collapse.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/dragndrop-blanc.svg b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/dragndrop-blanc.svg new file mode 100644 index 000000000..0f838b125 --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/dragndrop-blanc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/dragndrop.svg b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/dragndrop.svg new file mode 100644 index 000000000..cca9812be --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/dragndrop.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/extent.svg b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/extent.svg new file mode 100644 index 000000000..468b696fc --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/extent.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/info.svg b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/info.svg new file mode 100644 index 000000000..fea5756d7 --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/info.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/layers.svg b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/layers.svg new file mode 100644 index 000000000..7942d36f5 --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/layers.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/layerswitcher.svg b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/layerswitcher.svg new file mode 100644 index 000000000..5eff46c10 --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/layerswitcher.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/remove.svg b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/remove.svg new file mode 100644 index 000000000..1b6909984 --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/remove.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/visible-close-blanc.svg b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/visible-close-blanc.svg new file mode 100644 index 000000000..d86381002 --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/visible-close-blanc.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/visible-close.svg b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/visible-close.svg new file mode 100644 index 000000000..a406f9bc8 --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/visible-close.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/visible-open.svg b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/visible-open.svg new file mode 100644 index 000000000..534314b11 --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/visible-open.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/layers.svg b/src/packages/CSS/Controls/LayerSwitcher/img/layers.svg new file mode 100644 index 000000000..0040f3955 --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/layers.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/packages/CSS/Controls/MousePosition/GPFmousePosition.css b/src/packages/CSS/Controls/MousePosition/GPFmousePosition.css index 7eb624d17..438a7f666 100644 --- a/src/packages/CSS/Controls/MousePosition/GPFmousePosition.css +++ b/src/packages/CSS/Controls/MousePosition/GPFmousePosition.css @@ -29,10 +29,6 @@ dialog[id^=GPmousePositionPanel-] { bottom: 0px; } -button[id^=GPmousePositionPanelClose] { - background-image: url("img/GPmousePositionOpen.png"); -} - [id^=GPmousePositionPanel-] { overflow: hidden; left: 34px; diff --git a/src/packages/CSS/Controls/MousePosition/GPFmousePositionStyle.css b/src/packages/CSS/Controls/MousePosition/GPFmousePositionStyle.css index ed2941cc5..5c322a542 100644 --- a/src/packages/CSS/Controls/MousePosition/GPFmousePositionStyle.css +++ b/src/packages/CSS/Controls/MousePosition/GPFmousePositionStyle.css @@ -14,6 +14,10 @@ button[id^="GPshowMousePositionPicto-"] { background-image: url("img/GPmousePositionEditCoordinates.png"); } +button[id^=GPmousePositionPanelClose] { + background-image: url("img/GPmousePositionOpen.png"); +} + /* Map center localisation */ .GPmousePositionLabel, diff --git a/src/packages/CSS/DSFRgeneralWidget.css b/src/packages/CSS/DSFRgeneralWidget.css index a3c0ad699..c62695c3d 100644 --- a/src/packages/CSS/DSFRgeneralWidget.css +++ b/src/packages/CSS/DSFRgeneralWidget.css @@ -226,9 +226,9 @@ justify-content: center; /* crée un décalage sur le searchEngine */ /* align-items: center; */ - min-width: var(--size-per-row); + width: var(--size-per-row); min-height: var(--size-per-row); - padding: 5px; + /* padding: 5px; */ } .position-container-top-left, diff --git a/src/packages/CSS/GPFgeneralWidget.css b/src/packages/CSS/GPFgeneralWidget.css index aadb67bde..78f0d7f89 100644 --- a/src/packages/CSS/GPFgeneralWidget.css +++ b/src/packages/CSS/GPFgeneralWidget.css @@ -39,7 +39,7 @@ /* position */ /************/ :root { - --size-per-row: 50px; + --size-per-row: 44px; } #position-container-top-left, #position-container-top-right, @@ -52,9 +52,9 @@ justify-content: center; /* crée un décalage sur le searchEngine */ /* align-items: center; */ - min-width: var(--size-per-row); + width: var(--size-per-row); min-height: var(--size-per-row); - padding: 5px; + /* padding: 5px; */ } #position-container-top-left, @@ -124,6 +124,7 @@ .GPpanelFooter {} +.GPpanelIcon, .GPresetPicto, .GPreturnPicto, .GPpanelClose, diff --git a/src/packages/Controls/Control.js b/src/packages/Controls/Control.js index ecf12b68f..d06add612 100644 --- a/src/packages/Controls/Control.js +++ b/src/packages/Controls/Control.js @@ -28,7 +28,6 @@ const ANCHORS = [ /** * Position * @private - * @todo revoir les css des widgets car les panneaux sont en position:absolute */ class PositionFactory { @@ -74,7 +73,7 @@ class PositionFactory { // ex. { position:relative; height:50px; width:100%; } var div = document.createElement("div"); div.id = "position-container-" + name; - div.className = "position-container-" + name ; + div.className = "position position-container-" + name ; var container = this.caller.getMap().getOverlayContainerStopEvent(); container.appendChild(div); @@ -83,9 +82,13 @@ class PositionFactory { /** * ... * @param {*} pos - ... - * @todo + * @todo fonctionnement à tester ! */ #setAnchor (pos) { + const position = (pos) => { + var element = document.getElementById("position-container-" + pos); + return element.children.length; + }; const sizeW = (pos) => { var element = document.getElementById("position-container-" + pos); var width = element.offsetWidth; @@ -115,33 +118,33 @@ class PositionFactory { if (panels.length === 0) { return; } - panels.forEach((e) => { - clear(e); + panels.forEach((panel) => { + clear(panel); + + // on modifie le positionnement du menu (dialog ou div : panel) + // en fonction du bouton + // ex. bouton : bottom-left, menu : bottom:0px; left:50px + switch (pos.toLowerCase()) { + case "top-left": + panel.style.top = position(pos) ? sizeH(pos) + "px" : "0px"; + panel.style.left = sizeW(pos) + "px"; + break; + case "bottom-left": + panel.style.bottom = position(pos) ? sizeH(pos) + "px" : "0px"; + panel.style.left = sizeW(pos) + "px"; + break; + case "top-right": + panel.style.top = position(pos) ? sizeH(pos) + "px" : "0px"; + panel.style.right = sizeW(pos) + "px"; + break; + case "bottom-right": + panel.style.bottom = position(pos) ? sizeH(pos) + "px" : "0px"; + panel.style.right = sizeW(pos) + "px"; + break; + default: + break; + } }); - var panel = panels[0]; - // on modifie le positionnement du menu (dialog ou div : panel) - // en fonction du bouton - // ex. bouton : bottom-left, menu : bottom:0px; left:50px - switch (pos.toLowerCase()) { - case "top-left": - panel.style.top = "0px"; - panel.style.left = sizeW(pos) + "px"; // container 50px + padding de 5px - break; - case "bottom-left": - panel.style.bottom = "0px"; - panel.style.left = sizeW(pos) + "px"; - break; - case "top-right": - panel.style.top = "0px"; - panel.style.right = sizeW(pos) + "px"; - break; - case "bottom-right": - panel.style.bottom = "0px"; - panel.style.right = sizeW(pos) + "px"; - break; - default: - break; - } } /** @@ -156,7 +159,11 @@ class PositionFactory { // positionnement de l'element this.#setAnchor(pos); - document.getElementById("position-container-" + pos).appendChild(this.caller.element); + if (pos.includes("bottom")) { + document.getElementById("position-container-" + pos).prepend(this.caller.element); + } else { + document.getElementById("position-container-" + pos).appendChild(this.caller.element); + } } }; \ No newline at end of file diff --git a/src/packages/Controls/LayerSwitcher/LayerSwitcher.js b/src/packages/Controls/LayerSwitcher/LayerSwitcher.js index 61b3aa942..48808755e 100644 --- a/src/packages/Controls/LayerSwitcher/LayerSwitcher.js +++ b/src/packages/Controls/LayerSwitcher/LayerSwitcher.js @@ -6,9 +6,13 @@ import "../../CSS/Controls/LayerSwitcher/GPFlayerSwitcher.css"; import Control from "../Control"; import { unByKey as olObservableUnByKey } from "ol/Observable"; import { intersects as olIntersects } from "ol/extent"; +import { + transformExtent as olTransformExtentProj +} from "ol/proj"; // import local import SelectorID from "../../Utils/SelectorID"; import Logger from "../../Utils/LoggerByDefault"; +import Config from "../../Utils/Config"; // DOM import LayerSwitcherDOM from "./LayerSwitcherDOM"; @@ -35,6 +39,15 @@ var logger = Logger.getLogger("layerswitcher"); * @param {Array} [options.layers.config.metadata] - array of layer metadata. Each array element is an object, with property url (String, mandatory) : link to a metadata * @param {Object} [options.options] - ol.control.Control options (see {@link http://openlayers.org/en/latest/apidoc/ol.control.Control.html ol.control.Control}) * @param {Boolean} [options.options.collapsed = true] - Specify if widget has to be collapsed (true) or not (false) on map loading. Default is true. + * @param {Boolean} [options.options.panel = false] - Specify if widget has to have a panel header. Default is false. + * @param {Boolean} [options.options.counter = false] - Specify if widget has to have a counter. Default is false. + * @fires layerswitcher:add + * @fires layerswitcher:remove + * @fires layerswitcher:extent + * @fires layerswitcher:change:opacity + * @fires layerswitcher:change:visibility + * @fires layerswitcher:start:dragndrop (todo) + * @fires layerswitcher:end:dragndrop (todo) * @example * map.addControl(new ol.control.LayerSwitcher( * [ @@ -47,9 +60,25 @@ var logger = Logger.getLogger("layerswitcher"); * } * ], * { - * collapsed : true + * collapsed : true, + * panel : false, + * counter : false, + * position : "top-left" * } * )); + * + * LayerSwitcher.on("layerswitcher:add", function (e) { + * console.warn("layer", e.layer); + * }); + * LayerSwitcher.on("layerswitcher:remove", function (e) { + * console.warn("layer", e.layer); + * }); + * LayerSwitcher.on("layerswitcher:change:opacity", function (e) { + * console.warn("layer", e.layer, e.opacity); + * }); + * LayerSwitcher.on("layerswitcher:change:visibility", function (e) { + * console.warn("layer", e.layer, e.visibility); + * }); */ var LayerSwitcher = class LayerSwitcher extends Control { @@ -113,6 +142,11 @@ var LayerSwitcher = class LayerSwitcher extends Control { // on ajoute les couches this._addMapLayers(map); + // mode "collapsed" + if (!this.collapsed) { + this._showLayerSwitcherButton.setAttribute("aria-pressed", true); + } + // At every map movement, layer switcher may be updated, // according to layers on map, and their range. this._listeners.onMoveListener = map.on( @@ -185,6 +219,7 @@ var LayerSwitcher = class LayerSwitcher extends Control { * @param {Object} [config.legends] - layer legends (default is an empty array) * @param {Object} [config.metadata] - layer metadata (default is an empty array) * @param {Object} [config.quicklookUrl] - layer quicklookUrl (default is null) + * @fires layerswitcher:add * @example * layerSwitcher.addLayer( * gpParcels, @@ -234,6 +269,8 @@ var LayerSwitcher = class LayerSwitcher extends Control { var layerOptions = { layer : layer, id : id, + name : layer.name, // only geoportal layers + service : layer.service, // only geoportal layers opacity : opacity != null ? opacity : 1, visibility : visibility != null ? visibility : true, inRange : isInRange != null ? isInRange : true, @@ -263,7 +300,9 @@ var LayerSwitcher = class LayerSwitcher extends Control { this._layersOrder.unshift(layerOptions); this._lastZIndex++; layer.setZIndex(this._lastZIndex); - this._layerListContainer.insertBefore(layerDiv, this._layerListContainer.firstChild); + this._layerListContainer.insertBefore(layerDiv, + (this.options.panel) ? + this._layerListContainer.childNodes[1] : this._layerListContainer.firstChild); } // 3. Add listeners for opacity and visibility changes @@ -313,16 +352,35 @@ var LayerSwitcher = class LayerSwitcher extends Control { } // close layer info element if open, to update information. if (infodiv && infodiv.className === "GPlayerInfoOpened") { - document.getElementById(this._addUID("GPlayerInfoPanel")).className = "GPlayerInfoPanelClosed"; - infodiv.className = "GPlayerInfo"; + document.getElementById(this._addUID("GPlayerInfoPanel")).classList.add("GPlayerInfoPanelClosed", "gpf-hidden"); + // infodiv.className = "GPlayerInfo"; } } + // on met à jour le compteur + this._updateLayerCounter(); + /** + * event triggered when a layer is added + * + * @event layerswitcher:add + * @property {Object} type - event + * @property {Object} layer - layer + * @property {Object} target - instance LayerSwitcher + * @example + * LayerSwitcher.on("layerswitcher:add", function (e) { + * console.log(e.layer); + * }) + */ + this.dispatchEvent({ + type : "layerswitcher:add", + layer : this._layers[id] + }); }; /** * Remove a layer from control * * @param {ol.layer.Layer} layer - layer. + * @fires layerswitcher:remove * @deprecated on the future version ... */ removeLayer (layer) { @@ -341,8 +399,8 @@ var LayerSwitcher = class LayerSwitcher extends Control { // close layer info element if open. var infodiv = document.getElementById(this._addUID("GPinfo_ID_" + layerID)); if (infodiv && infodiv.className === "GPlayerInfoOpened") { - document.getElementById(this._addUID("GPlayerInfoPanel")).className = "GPlayerInfoPanelClosed"; - infodiv.className = "GPlayerInfo"; + document.getElementById(this._addUID("GPlayerInfoPanel")).classList.add("GPlayerInfoPanelClosed", "gpf-hidden"); + // infodiv.className = "GPlayerInfo"; } // remove layer div var layerDiv = document.getElementById(this._addUID("GPlayerSwitcher_ID_" + layerID)); @@ -359,8 +417,29 @@ var LayerSwitcher = class LayerSwitcher extends Control { for (var i = 0; i < layerOrderTemp.length; i++) { layerOrderTemp[i].layer.setZIndex(this._lastZIndex - i); } + + /** + * event triggered when a layer is removed + * + * @event layerswitcher:add + * @property {Object} type - event + * @property {Object} layer - layer + * @property {Object} target - instance LayerSwitcher + * @example + * LayerSwitcher.on("layerswitcher:remove", function (e) { + * console.log(e.layer); + * }) + */ + this.dispatchEvent({ + type : "layerswitcher:remove", + layer : this._layers[layerID] + }); + // on retire la couche de la liste des layers delete this._layers[layerID]; + + // on met à jour le compteur + this._updateLayerCounter(); } /** @@ -379,11 +458,11 @@ var LayerSwitcher = class LayerSwitcher extends Control { } // on simule l'ouverture du panneau après un click if (!isCollapsed) { - var layers = document.getElementsByClassName("GPlayerInfoOpened"); - for (var i = 0; i < layers.length; i++) { - layers[i].className = "GPlayerInfo"; - } - document.getElementById(this._addUID("GPlayerInfoPanel")).className = "GPlayerInfoPanelClosed"; + // var layers = document.getElementsByClassName("GPlayerInfoOpened"); + // for (var i = 0; i < layers.length; i++) { + // layers[i].className = "GPlayerInfo"; + // } + document.getElementById(this._addUID("GPlayerInfoPanel")).classList.add("GPlayerInfoPanelClosed", "gpf-hidden"); } document.getElementById(this._addUID("GPshowLayersList")).checked = !collapsed; } @@ -482,6 +561,8 @@ var LayerSwitcher = class LayerSwitcher extends Control { var layerOptions = { layer : layer, // la couche ol.layer concernée id : id, + name : layer.name, // only geoportal layers + service : layer.service, // only geoportal layers opacity : opacity != null ? opacity : 1, visibility : visibility != null ? visibility : true, title : conf.title != null ? conf.title : conf.id ? conf.id : id, @@ -535,9 +616,15 @@ var LayerSwitcher = class LayerSwitcher extends Control { ); // ajout dans le container principal du picto du controle - var picto = this._createMainPictoElement(); + var picto = this._showLayerSwitcherButton = this._createMainPictoElement(); container.appendChild(picto); + // ajout du compteur de couches + if (this.options.counter) { + var counter = this._layerSwitcherCounter = this._createMainCounterLayersElement(); + picto.appendChild(counter); + } + // ajout dans le container principal de la liste des layers var divL = this._createMainLayersElement(); container.appendChild(divL); @@ -545,11 +632,29 @@ var LayerSwitcher = class LayerSwitcher extends Control { var div = this._layerListContainer = this._createMainLayersDivElement(); divL.appendChild(div); + // header ? + if (this.options.panel) { + // header + var panelHeader = this._createLayersPanelHeaderElement(); + div.appendChild(panelHeader); + // icon + var panelIcon = this._createLayersPanelIconElement(); + panelHeader.appendChild(panelIcon); + // title + var panelTitle = this._createLayersPanelTitleElement(); + panelHeader.appendChild(panelTitle); + // close picto + var panelClose = this._createLayersPanelCloseElement(); + panelHeader.appendChild(panelClose); + } + // creation du mode draggable this._createDraggableElement(div, this); // ajout dans le container principal du panneau d'information var divI = this._createMainInfoElement(); + var divD = this._createMainInfoDivElement(); + divI.appendChild(divD); container.appendChild(divI); return container; @@ -568,7 +673,7 @@ var LayerSwitcher = class LayerSwitcher extends Control { // idée : le layerSwitcher doit représenter l'ensemble des couches de la carte. map.getLayers().forEach((layer) => { // ajout des couches de la carte à la liste - var id; + var id = null; // si elles ont déjà un identifiant (gpLayerId), on le récupère, sinon on en crée un nouveau, en incrémentant this_layerId. if (!layer.hasOwnProperty("gpLayerId")) { id = this._layerId; @@ -587,6 +692,8 @@ var LayerSwitcher = class LayerSwitcher extends Control { var layerOptions = { layer : layer, id : id, + name : layer.name, // only geoportal layers + service : layer.service, // only geoportal layers opacity : opacity != null ? opacity : 1, visibility : visibility != null ? visibility : true, inRange : isInRange != null ? isInRange : true, @@ -603,6 +710,8 @@ var LayerSwitcher = class LayerSwitcher extends Control { this._layers[id].visibility = layer.getVisible(); this._layers[id].inRange = this.isInRange(layer, map); } + // on met à jour le compteur + this._updateLayerCounter(); // Ajout de listeners sur les changements d'opacité, visibilité this._listeners.updateLayerOpacity = layer.on( @@ -686,6 +795,15 @@ var LayerSwitcher = class LayerSwitcher extends Control { // ######################### DOM events ############################## // // ################################################################### // + /** + * update layer counter + */ + _updateLayerCounter () { + if (this._layerSwitcherCounter) { + this._layerSwitcherCounter.innerHTML = Object.keys(this._layers).length; + } + } + /** * Change layer opacity on layer opacity picto click * @@ -708,6 +826,7 @@ var LayerSwitcher = class LayerSwitcher extends Control { * Update picto opacity value on layer opacity change * * @param {Object} e - event + * @fires layerswitcher:change:opacity * @private */ _updateLayerOpacity (e) { @@ -729,6 +848,25 @@ var LayerSwitcher = class LayerSwitcher extends Control { if (layerOpacitySpan) { layerOpacitySpan.innerHTML = Math.round(opacity * 100) + "%"; } + + /** + * event triggered when an opacity layer is changed + * + * @event layerswitcher:change:opacity + * @property {Object} type - event + * @property {Object} opacity - opacity + * @property {Object} layer - layer + * @property {Object} target - instance LayerSwitcher + * @example + * LayerSwitcher.on("layerswitcher:change", function (e) { + * console.log(e.opacity); + * }) + */ + this.dispatchEvent({ + type : "layerswitcher:change:opacity", + opacity : opacity, + layer : this._layers[id] + }); } /** @@ -741,28 +879,47 @@ var LayerSwitcher = class LayerSwitcher extends Control { var divId = e.target.id; // ex GPvisibilityPicto_ID_26 var layerID = SelectorID.index(divId); // ex. 26 var layer = this._layers[layerID].layer; - - layer.setVisible(e.target.checked); + layer.setVisible((e.target.ariaPressed === "true")); } /** * Change picto visibility on layer visibility change * * @param {Object} e - event + * @fires layerswitcher:change:visibility * @private */ _updateLayerVisibility (e) { var visible = e.target.getVisible(); var id = e.target.gpLayerId; - var layerVisibilityInput = document.getElementById(this._addUID("GPvisibility_ID_" + id)); - if (layerVisibilityInput) { - layerVisibilityInput.checked = visible; + var layerVisibility = document.getElementById(this._addUID("GPvisibilityPicto_ID_" + id)); + if (layerVisibility) { + layerVisibility.ariaPressed = visible; } + + /** + * event triggered when an visibility layer is changed + * + * @event layerswitcher:change:visibility + * @property {Object} type - event + * @property {Object} visibility - visibility + * @property {Object} layer - layer + * @property {Object} target - instance LayerSwitcher + * @example + * LayerSwitcher.on("layerswitcher:change:visibility", function (e) { + * console.log(e.visibility); + * }) + */ + this.dispatchEvent({ + type : "layerswitcher:change:visibility", + visibility : visible, + layer : this._layers[id] + }); } /** * Change layers order in layerswitcher (control container) on a layer index change (on map) or when a layer is added to a specific zindex - * + * @todo fires layerswitcher:change:zindex * @private */ _updateLayersOrder () { @@ -826,8 +983,12 @@ var LayerSwitcher = class LayerSwitcher extends Control { if (this._layerListContainer) { // on vide le container précédent - while (this._layerListContainer.firstChild) { - this._layerListContainer.removeChild(this._layerListContainer.firstChild); + for (let index = 0; index < this._layerListContainer.childNodes.length; index++) { + const element = this._layerListContainer.childNodes[index]; + if (element.id === "") { + continue; + } + element.remove(); } // et on rajoute les div correspondantes aux différentes couches, dans l'ordre décroissant des zindex for (var j = 0; j < this._layersOrder.length; j++) { @@ -846,58 +1007,48 @@ var LayerSwitcher = class LayerSwitcher extends Control { * @private */ _onOpenLayerInfoClick (e) { - var divId = e.target.id; // ex GPvisibilityPicto_ID_26 - var layerID = SelectorID.index(divId); // ex. 26 + var id = e.target.id; // ex GPvisibilityPicto_ID_26 + var layerID = SelectorID.index(id); // ex. 26 var layerOptions = this._layers[layerID]; var panel; var info; // Close layer info panel - divId = document.getElementById(e.target.id); - if (divId.className === "GPlayerInfoOpened") { - if (divId.classList !== undefined) { - divId.classList.remove("GPlayerInfoOpened"); - divId.classList.add("GPlayerInfo"); - } + var divId = document.getElementById(e.target.id); + if (divId.classList.contains("GPlayerInfoOpened")) { + divId.classList.remove("GPlayerInfoOpened"); + divId.classList.add("GPlayerInfoClosed"); panel = document.getElementById(this._addUID("GPlayerInfoPanel")); - if (panel.classList !== undefined) { - panel.classList.remove("GPpanel"); - panel.classList.remove("GPlayerInfoPanelOpened"); - panel.classList.add("GPlayerInfoPanelClosed"); - } + panel.classList.remove("GPlayerInfoPanelOpened", "gpf-visible"); + panel.classList.add("GPlayerInfoPanelClosed", "gpf-hidden"); info = document.getElementById(this._addUID("GPlayerInfoContent")); - panel.removeChild(info); + if (info) { + info.parentNode.remove(); + } return; } - var layers = document.getElementsByClassName("GPlayerInfoOpened"); - for (var i = 0; i < layers.length; i++) { - layers[i].className = "GPlayerInfo"; - } - // Open layer info panel - if (divId.classList !== undefined) { - divId.classList.remove("GPlayerInfo"); + if (divId.classList.contains("GPlayerInfoClosed")) { + divId.classList.remove("GPlayerInfoClosed"); divId.classList.add("GPlayerInfoOpened"); } panel = document.getElementById(this._addUID("GPlayerInfoPanel")); - if (panel.classList !== undefined) { - panel.classList.add("GPpanel"); - panel.classList.remove("GPlayerInfoPanelClosed"); - panel.classList.add("GPlayerInfoPanelOpened"); - } + panel.classList.remove("GPlayerInfoPanelClosed", "gpf-hidden"); + panel.classList.add("GPlayerInfoPanelOpened", "gpf-visible"); info = document.getElementById(this._addUID("GPlayerInfoContent")); if (info) { - panel.removeChild(info); + info.parentNode.remove(); } // on récupère les infos associées au layer pour mettre dynamiquement le contenu du panel d'informations var obj = { + id : id, title : layerOptions.title, description : layerOptions.description, quicklookUrl : layerOptions.quicklookUrl, @@ -912,7 +1063,7 @@ var LayerSwitcher = class LayerSwitcher extends Control { obj._maxScaleDenominator = Math.round(maxResolution / 0.00028); } var infoLayer = this._createContainerLayerInfoElement(obj); - panel.appendChild(infoLayer); + panel.firstChild.appendChild(infoLayer); } /** @@ -933,10 +1084,10 @@ var LayerSwitcher = class LayerSwitcher extends Control { /** * change layers order (on map) on drag and drop (on control container) - * + * * @private */ - _onDragAndDropLayerClick () { + _onEndDragAndDropLayerClick () { // INFO : e.oldIndex et e.newIndex marchent en mode AMD mais pas Bundle. var map = this.getMap(); @@ -974,6 +1125,107 @@ var LayerSwitcher = class LayerSwitcher extends Control { map.updateSize(); } + /** + * change layers order (on map) on drag and drop (on control container) + * + * @param {Event} e - DragNDrop Event + * @private + */ + _onStartDragAndDropLayerClick (e) { + logger.debug(e); + } + + /** + * zoom to extent + * @fixme dot it for other user data + * @param {PointerEvent} e - Event + */ + _onZoomToExtentClick (e) { + logger.debug(e); + + // FIXME + // le zoom to extent fonctionne par defaut pour les couches raster TMS/WMS/WMTS issues du catalogue + // mais doit aussi le faire pour les données utilisateurs du type : + // * vecteurs (imports) + // * raster par moissonnage (imports) + + var domIDShort = e.target.id; // ex GPvisibilityPicto_ID_26 + var domIDLong = SelectorID.index(domIDShort); // ex. 26 + var data = this._layers[domIDLong]; + + var extent = null; + var error = null; + try { + // Check if configuration is loaded + if (!Config.isConfigLoaded()) { + throw "ERROR : contract key configuration has to be loaded to load Geoportal layers."; + } + + if (!data.layer.hasOwnProperty("gpLayerId")) { + throw "WARN : User data not yet implemented !"; + } + + var layerName = data.layer.name || data.layer.getSource().name; + var layerService = data.layer.service || data.layer.getSource().service; + var layerId = Config.configuration.getLayerId(layerName, layerService); + if (!layerId) { + throw "ERROR : Layer ID not found into the catalogue !?"; + } + + var globalConstraints = Config.configuration.getGlobalConstraints(layerId); + if (globalConstraints) { + var map = this.getMap(); + if (!map || !map.getView()) { + return; + } + var view = map.getView(); + var crsTarget = view.getProjection(); + + // récupération de l'étendue (en EPSG:4326 par défaut), + // et reprojection dans la projection de la couche + var bbox = [ + globalConstraints.extent.left, + globalConstraints.extent.bottom, + globalConstraints.extent.right, + globalConstraints.extent.top + ]; + var crsSource = globalConstraints.crs; + // projection par defaut + if (!crsSource) { + crsSource = "EPSG:4326"; + } + + extent = olTransformExtentProj(bbox, crsSource, crsTarget); + if (extent) { + view.fit(extent); + } + } + } catch (e) { + error = e; + } + + /** + * event triggered when an zoom extent is done + * + * @event layerswitcher:zoom + * @property {Object} type - event + * @property {Object} extent - extent (map projection) + * @property {Object} layer - layer + * @property {String} error - error + * @property {Object} target - instance LayerSwitcher + * @example + * LayerSwitcher.on("layerswitcher:extent", function (e) { + * console.log(e.extent); + * }) + */ + this.dispatchEvent({ + type : "layerswitcher:extent", + extent : extent, + layer : data, + error : error + }); + } + /** * check layers range on map movement * diff --git a/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js b/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js index 2e87705fe..dff72e33f 100644 --- a/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js +++ b/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js @@ -22,7 +22,7 @@ var LayerSwitcherDOM = { // Call event function on drag and drop onEnd : function (e) { // FIXME pas terrrible, mais il faut bien passer ce contexte... - context._onDragAndDropLayerClick(e); + context._onEndDragAndDropLayerClick(e); } }); } else { @@ -34,7 +34,7 @@ var LayerSwitcherDOM = { // Call event function on drag and drop onEnd : function (e) { // FIXME pas terrrible, mais il faut bien passer ce contexte... - context._onDragAndDropLayerClick(e); + context._onEndDragAndDropLayerClick(e); } }); } @@ -62,7 +62,7 @@ var LayerSwitcherDOM = { _createMainContainerElement : function () { var container = document.createElement("div"); container.id = this._addUID("GPlayerSwitcher"); - container.className = "GPwidget gpf-widget gpf-widget-button"; + container.className = "GPwidget gpf-widget"; // gpf-widget-button return container; }, @@ -111,7 +111,7 @@ var LayerSwitcherDOM = { var button = document.createElement("button"); button.id = this._addUID("GPshowLayersListPicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto gpf-btn gpf-btn-icon-layerswitcher fr-btn"; + button.className = "GPshowOpen GPshowAdvancedToolPicto GPshowLayersListPicto gpf-btn gpf-btn-icon gpf-btn-icon-layerswitcher fr-btn"; button.htmlFor = this._addUID("GPshowLayersList"); button.title = "Afficher/masquer le gestionnaire de couches"; button.setAttribute("tabindex", "0"); @@ -123,11 +123,8 @@ var LayerSwitcherDOM = { e.target.setAttribute("aria-pressed", !status); document.getElementById(self._addUID("GPshowLayersList")).checked = status; if (document.getElementById(self._addUID("GPshowLayersList")).checked) { - var layers = document.getElementsByClassName("GPlayerInfoOpened"); - for (var i = 0; i < layers.length; i++) { - layers[i].className = "GPlayerInfo"; - } - document.getElementById(self._addUID("GPlayerInfoPanel")).className = "GPlayerInfoPanelClosed"; + document.getElementById(self._addUID("GPlayerInfoPanel")).classList.remove("GPlayerInfoPanelOpened", "gpf-visible"); + document.getElementById(self._addUID("GPlayerInfoPanel")).classList.add("GPlayerInfoPanelClosed", "gpf-hidden"); } }); } else if (button.attachEvent) { @@ -135,11 +132,8 @@ var LayerSwitcherDOM = { var status = (e.target.ariaPressed === "true"); e.target.setAttribute("aria-pressed", !status); if (document.getElementById(self._addUID("GPshowLayersList")).checked) { - var layers = document.getElementsByClassName("GPlayerInfoOpened"); - for (var i = 0; i < layers.length; i++) { - layers[i].className = "GPlayerInfo"; - } - document.getElementById(self._addUID("GPlayerInfoPanel")).className = "GPlayerInfoPanelClosed"; + document.getElementById(self._addUID("GPlayerInfoPanel")).classList.remove("GPlayerInfoPanelOpened", "gpf-visible"); + document.getElementById(self._addUID("GPlayerInfoPanel")).classList.add("GPlayerInfoPanelClosed", "gpf-hidden"); } }); } @@ -147,6 +141,14 @@ var LayerSwitcherDOM = { return button; }, + _createMainCounterLayersElement : function () { + var span = document.createElement("span"); + span.id = this._addUID("GPlayerCounter"); + span.className = "GPlayerCounter"; + span.innerHTML = "0"; + return span; + }, + /** * Creation du container du panneau d"information (DOM) * @@ -155,9 +157,15 @@ var LayerSwitcherDOM = { _createMainInfoElement : function () { // gestion du panneau d"information dans le container principal //
...
+ var divP = document.createElement("div"); + divP.id = this._addUID("GPlayerInfoPanel"); + divP.className = "GPpanel GPlayerInfoPanelClosed gpf-panel fr-modal"; + return divP; + }, + + _createMainInfoDivElement : function () { var div = document.createElement("div"); - div.id = this._addUID("GPlayerInfoPanel"); - div.className = "GPpanel GPlayerInfoPanelClosed gpf-panel fr-modal"; + div.className = "gpf-panel__body fr-modal__body"; return div; }, @@ -165,6 +173,49 @@ var LayerSwitcherDOM = { // ######################### Layer container ######################### // // ################################################################### // + _createLayersPanelHeaderElement : function () { + var container = document.createElement("div"); + // FIXME on n'utilise pas le dsfr ! + // container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; + container.className = "GPpanelHeader gpf-panel__header_ls"; + return container; + }, + _createLayersPanelIconElement : function () { + var label = document.createElement("label"); + label.className = "GPpanelIcon gpf-btn-header gpf-btn-icon-layers"; + label.title = "Couches de données"; + return label; + }, + _createLayersPanelTitleElement : function () { + var div = document.createElement("div"); + div.className = "GPpanelTitle gpf-panel__title_ls"; + div.id = this._addUID("GPlayersHeaderTitle"); + div.innerHTML = "Couches de données"; + return div; + }, + _createLayersPanelCloseElement : function () { + // contexte + var self = this; + + var btnClose = document.createElement("button"); + btnClose.id = this._addUID("GPlayersPanelClose"); + btnClose.className = "GPpanelClose GPlayersPanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--tertiary-no-outline fr-m-1w"; + btnClose.title = "Fermer le panneau"; + + // Link panel close / visibility checkbox + if (btnClose.addEventListener) { + btnClose.addEventListener("click", function () { + document.getElementById(self._addUID("GPshowLayersListPicto")).click(); + }, false); + } else if (btnClose.attachEvent) { + btnClose.attachEvent("onclick", function () { + document.getElementById(self._addUID("GPshowLayersListPicto")).click(); + }); + } + + return btnClose; + }, + /** * Creation du container du layer (DOM) * @@ -205,14 +256,11 @@ var LayerSwitcherDOM = { // ajout des outils basiques (visibility / layer name) container.appendChild(this._createBasicToolElement(obj)); + + // ajout bouton des outils avancés + container.appendChild(this._createAdvancedToolShowElement(obj)); // liste des outils avancés (layer info / opacity slider / opacity value / removal) - var array = this._createAdvancedToolShowElement(obj); - for (var i = 0; i < array.length; i++) { - container.appendChild(array[i]); - } - - // ajout des outils avancés container.appendChild(this._createAdvancedToolElement(obj)); return container; @@ -241,13 +289,37 @@ var LayerSwitcherDOM = { div.className = "GPlayerBasicTools"; div.appendChild(this._createBasicToolNameElement(obj)); + div.appendChild(this._createBasicToolVisibilityElement(obj)); + div.appendChild(this._createBasicToolDragNDropElement(obj)); - var array = this._createBasicToolVisibilityElement(obj); - for (var i = 0; i < array.length; i++) { - div.appendChild(array[i]); + return div; + }, + + _createBasicToolDragNDropElement : function (obj) { + // INFO inactif en mode classique ! + var button = document.createElement("button"); + button.id = this._addUID("GPdragndropPicto_ID_" + obj.id); + button.className = "GPelementHidden GPlayerDragNDrop gpf-btn gpf-btn-icon gpf-btn-icon-ls-dragndrop fr-btn fr-btn--tertiary-no-outline fr-m-1w"; + button.title = "Deplacer la couche"; + button.setAttribute("tabindex", "0"); + button.setAttribute("aria-pressed", true); + + var self = this; + if (button.addEventListener) { + button.addEventListener("click", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); + self._onStartDragAndDropLayerClick(e); + }); + } else if (button.attachEvent) { + button.attachEvent("onclick", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); + self._onStartDragAndDropLayerClick(e); + }); } - return div; + return button; }, /** @@ -277,49 +349,31 @@ var LayerSwitcherDOM = { * @returns {DOMElement[]} array containing input and label elements */ _createBasicToolVisibilityElement : function (obj) { - // exemple : - // - // - - var list = []; - - var checked = (typeof obj.visibility !== "undefined") ? obj.visibility : true; - var id = this._addUID("GPvisibility_ID_" + obj.id); + var visible = (typeof obj.visibility !== "undefined") ? obj.visibility : true; - var input = document.createElement("input"); - input.id = id; - input.type = "checkbox"; - input.checked = checked; - - var label = document.createElement("label"); - label.htmlFor = id; - label.id = this._addUID("GPvisibilityPicto_ID_" + obj.id); - label.className = "GPlayerVisibility gpf-label fr-label"; - label.title = "Afficher/masquer la couche"; - - // add event for visibility change + var button = document.createElement("button"); + button.id = this._addUID("GPvisibilityPicto_ID_" + obj.id); + button.className = "GPlayerVisibility gpf-btn gpf-btn-icon gpf-btn-icon-ls-visibility fr-btn fr-btn--tertiary"; + button.title = "Afficher/masquer la couche"; + button.setAttribute("tabindex", "0"); + button.setAttribute("aria-pressed", visible); + var context = this; - if (input.addEventListener) { - input.addEventListener( - "click", - function (e) { - context._onVisibilityLayerClick(e); - } - ); - } else if (input.attachEvent) { - // internet explorer - input.attachEvent( - "onclick", - function (e) { - context._onVisibilityLayerClick(e); - } - ); + if (button.addEventListener) { + button.addEventListener("click", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); + context._onVisibilityLayerClick(e); + }); + } else if (button.attachEvent) { + button.attachEvent("onclick", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); + context._onVisibilityLayerClick(e); + }); } - list.push(input); - list.push(label); - - return list; + return button; }, /** @@ -330,25 +384,38 @@ var LayerSwitcherDOM = { * @returns {DOMElement[]} array containing input and label elements */ _createAdvancedToolShowElement : function (obj) { - // - // - - var list = []; - - var label = document.createElement("label"); - label.id = this._addUID("GPshowAdvancedToolsPicto_ID_" + obj.id); - label.htmlFor = this._addUID("GPshowAdvancedTools_ID_" + obj.id); - label.title = "Plus d'outils"; - label.className = "GPshowMoreOptions GPshowLayerAdvancedTools gpf-label fr-label"; + var button = document.createElement("button"); + button.id = this._addUID("GPshowAdvancedTools_ID_" + obj.id); - var input = document.createElement("input"); - input.type = "checkbox"; - input.id = this._addUID("GPshowAdvancedTools_ID_" + obj.id); + button.className = "GPshowAdvancedToolPicto GPshowMoreOptionsImage GPshowMoreOptions GPshowLayerAdvancedTools gpf-btn gpf-btn-icon gpf-btn-icon-ls-collapse fr-btn--sm fr-btn--tertiary"; + button.title = "Plus d'outils"; + button.setAttribute("tabindex", "0"); + button.setAttribute("aria-pressed", false); - list.push(input); - list.push(label); + var self = this; + if (button.addEventListener) { + button.addEventListener("click", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); + var element = document.getElementById(self._addUID("GPadvancedTools_ID_" + obj.id)); + if (status) { + element.classList.replace("GPelementVisible", "GPelementHidden"); + element.classList.replace("gpf-visible", "gpf-hidden"); + } else { + element.classList.replace("GPelementHidden", "GPelementVisible"); + element.classList.replace("gpf-hidden", "gpf-visible"); + } + }); + } else if (button.attachEvent) { + button.attachEvent("onclick", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); + element.classList.replace("GPelementVisible", "GPelementHidden"); + element.classList.replace("gpf-visible", "gpf-hidden"); + }); + } - return list; + return button; }, /** @@ -368,7 +435,7 @@ var LayerSwitcherDOM = { var container = document.createElement("div"); container.id = this._addUID("GPadvancedTools_ID_" + obj.id); - container.className = "GPlayerAdvancedTools"; + container.className = "GPelementHidden GPlayerAdvancedTools gpf-hidden"; container.appendChild(this._createAdvancedToolDeleteElement(obj)); @@ -383,6 +450,7 @@ var LayerSwitcherDOM = { } } + container.appendChild(this._createAdvancedToolExtentElement(obj)); return container; }, @@ -394,34 +462,30 @@ var LayerSwitcherDOM = { * @returns {DOMElement} container */ _createAdvancedToolDeleteElement : function (obj) { - // exemple : - //
- - var div = document.createElement("div"); - div.id = this._addUID("GPremove_ID_" + obj.id); - div.className = "GPlayerRemove"; - div.title = "Supprimer la couche"; - div.layerId = obj.id; - + var button = document.createElement("button"); + button.id = this._addUID("GPremove_ID_" + obj.id); + button.className = "GPlayerRemove gpf-btn gpf-btn-icon gpf-btn-icon-ls-remove fr-btn fr-btn--tertiary"; + button.title = "Supprimer la couche"; + button.layerId = obj.id; + button.setAttribute("tabindex", "0"); + button.setAttribute("aria-pressed", true); + var context = this; - if (div.addEventListener) { - div.addEventListener( - "click", - function (e) { - context._onDropLayerClick(e); - } - ); - } else if (div.attachEvent) { - // internet explorer - div.attachEvent( - "onclick", - function (e) { - context._onDropLayerClick(e); - } - ); + if (button.addEventListener) { + button.addEventListener("click", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); + context._onDropLayerClick(e); + }); + } else if (button.attachEvent) { + button.attachEvent("onclick", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); + context._onDropLayerClick(e); + }); } - return div; + return button; }, /** @@ -435,31 +499,37 @@ var LayerSwitcherDOM = { // exemple : //
- var div = document.createElement("div"); - div.id = this._addUID("GPinfo_ID_" + obj.id); - div.className = "GPlayerInfo"; - div.title = "Informations/légende"; - div.layerId = obj.id; + var btnInfo = document.createElement("button"); + btnInfo.id = this._addUID("GPinfo_ID_" + obj.id); + btnInfo.className = "GPlayerInfo GPlayerInfoClosed gpf-btn gpf-btn-icon gpf-btn-icon-ls-info fr-btn fr-btn--tertiary"; + btnInfo.title = "Informations/légende"; + btnInfo.layerId = obj.id; + btnInfo.setAttribute("tabindex", "0"); + btnInfo.setAttribute("aria-pressed", true); // add event on click var context = this; - if (div.addEventListener) { - div.addEventListener( + if (btnInfo.addEventListener) { + btnInfo.addEventListener( "click", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); context._onOpenLayerInfoClick(e); } ); - } else if (div.attachEvent) { + } else if (btnInfo.attachEvent) { // internet explorer - div.attachEvent( + btnInfo.attachEvent( "onclick", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); context._onOpenLayerInfoClick(e); } ); } - return div; + return btnInfo; }, /** @@ -484,7 +554,7 @@ var LayerSwitcherDOM = { // curseur pour changer l'opacité var divO = document.createElement("div"); divO.id = this._addUID("GPopacity_ID_" + obj.id); - divO.className = "GPlayerOpacity"; + divO.className = "GPlayerOpacity fr-range fr-range--sm"; divO.title = "Opacité"; var opacity = (typeof obj.opacity !== "undefined") ? obj.opacity : 1; @@ -541,6 +611,7 @@ var LayerSwitcherDOM = { var span = document.createElement("span"); span.id = this._addUID("GPopacityValue_ID_" + obj.id); + span.className = "fr-range__output gpf-visible"; span.innerHTML = opacity + "%"; divC.appendChild(span); @@ -551,6 +622,34 @@ var LayerSwitcherDOM = { return list; }, + _createAdvancedToolExtentElement : function (obj) { + // FIXME inactif en mode classique ! + var button = document.createElement("button"); + button.id = this._addUID("GPextent_ID_" + obj.id); + button.className = "GPelementHidden GPlayerExtent gpf-btn gpf-btn-icon gpf-btn-icon-ls-extent fr-btn fr-btn--tertiary"; + button.title = "Zoomer dans l'étendue"; + button.layerId = obj.id; + button.setAttribute("tabindex", "0"); + button.setAttribute("aria-pressed", true); + + var context = this; + if (button.addEventListener) { + button.addEventListener("click", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); + context._onZoomToExtentClick(e); + }); + } else if (button.attachEvent) { + button.attachEvent("onclick", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); + context._onZoomToExtentClick(e); + }); + } + + return button; + }, + // ################################################################### // // ############################ Layer info ########################### // // ################################################################### // @@ -567,12 +666,50 @@ var LayerSwitcherDOM = { */ _createContainerLayerInfoElement : function (obj) { var container = document.createElement("div"); - container.id = this._addUID("GPlayerInfoContent"); + + var header = document.createElement("div"); + // FIXME on n'utilise pas le dsfr ! + // container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; + header.className = "gpf-panel__header_ls"; + container.appendChild(header); + + var label = document.createElement("label"); + label.className = "GPlayerInfo gpf-btn-header gpf-btn-icon-ls-info"; + label.title = "Informations"; + header.appendChild(label); var title = document.createElement("div"); title.id = this._addUID("GPlayerInfoTitle"); title.innerHTML = obj.title; - container.appendChild(title); + title.className = "gpf-panel__title_ls"; + header.appendChild(title); + + var btnClose = document.createElement("button"); + btnClose.id = this._addUID("GPlayerInfoClose"); + btnClose.className = "GPpanelClose GPlayersPanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--tertiary-no-outline fr-m-1w"; + btnClose.title = "Fermer la fenêtre"; + + var self = this; + /** Call event function on close click */ + var onCloseClick = function () { + document.getElementById(self._addUID("GPlayerInfoPanel")).classList.add("GPlayerInfoPanelClosed", "gpf-hidden"); + document.getElementById(self._addUID("GPlayerInfoPanel")).classList.remove("GPlayerInfoPanelOpened", "gpf-visible"); + document.getElementById(obj.id).classList.add("GPlayerInfoClosed"); + document.getElementById(obj.id).classList.remove("GPlayerInfoOpened"); + }; + if (btnClose.addEventListener) { + btnClose.addEventListener("click", onCloseClick); + } else if (btnClose.attachEvent) { + // internet explorer + btnClose.attachEvent("onclick", onCloseClick); + } + header.appendChild(btnClose); + container.appendChild(header); + + var content = document.createElement("div"); + content.id = this._addUID("GPlayerInfoContent"); + content.className = "gpf-panel__content fr-modal__content"; + container.appendChild(content); if (obj.quicklookUrl) { var quick = document.createElement("div"); @@ -581,34 +718,13 @@ var LayerSwitcherDOM = { var refquick = document.createElement("a"); refquick.href = obj.quicklookUrl; refquick.appendChild(quick); - container.appendChild(refquick); - } - - var close = document.createElement("div"); - close.id = this._addUID("GPlayerInfoClose"); - close.title = "Fermer la fenêtre"; - - var self = this; - /** Call event function on close click */ - var onCloseClick = function () { - document.getElementById(self._addUID("GPlayerInfoPanel")).className = "GPlayerInfoPanelClosed"; - var layers = document.getElementsByClassName("GPlayerInfoOpened"); - for (var i = 0; i < layers.length; i++) { - layers[i].className = "GPlayerInfo"; - } - }; - if (close.addEventListener) { - close.addEventListener("click", onCloseClick); - } else if (close.attachEvent) { - // internet explorer - close.attachEvent("onclick", onCloseClick); + content.appendChild(refquick); } - container.appendChild(close); var desc = document.createElement("div"); desc.id = this._addUID("GPlayerInfoDescription"); desc.innerHTML = obj.description; - container.appendChild(desc); + content.appendChild(desc); if (obj.metadata) { var mtd = document.createElement("div"); @@ -633,7 +749,7 @@ var LayerSwitcherDOM = { } if (obj.metadata.length !== 0) { - container.appendChild(mtd); + content.appendChild(mtd); } } @@ -684,7 +800,7 @@ var LayerSwitcherDOM = { } if (Object.keys(legends).length !== 0) { - container.appendChild(lgd); + content.appendChild(lgd); } } diff --git a/src/packages/Controls/ReverseGeocode/ReverseGeocode.js b/src/packages/Controls/ReverseGeocode/ReverseGeocode.js index b279cd946..4ca33b0db 100644 --- a/src/packages/Controls/ReverseGeocode/ReverseGeocode.js +++ b/src/packages/Controls/ReverseGeocode/ReverseGeocode.js @@ -503,7 +503,7 @@ var ReverseGeocode = class ReverseGeocode extends Control { // return picto (hidden at start) var returnPicto = this._returnPictoContainer = this._createReverseGeocodingPanelReturnPictoElement(); panelHeader.appendChild(returnPicto); - // pane title + // title var panelTitle = this._panelTitleContainer = this._createReverseGeocodingPanelTitleElement(); panelHeader.appendChild(panelTitle); // close picto diff --git a/src/packages/Controls/SearchEngine/SearchEngine.js b/src/packages/Controls/SearchEngine/SearchEngine.js index e5060a38f..fc043903a 100644 --- a/src/packages/Controls/SearchEngine/SearchEngine.js +++ b/src/packages/Controls/SearchEngine/SearchEngine.js @@ -13,6 +13,7 @@ import { // import geoportal library access import Gp from "geoportal-access-lib"; // import local +import Config from "../../Utils/Config"; import Logger from "../../Utils/LoggerByDefault"; import Utils from "../../Utils/Helper"; import Markers from "../Utils/Markers"; @@ -1802,11 +1803,49 @@ var SearchEngine = class SearchEngine extends Control { onSearchedResultsItemClick (e) { var idx = SelectorID.index(e.target.id); - var message = null; - var suggest = Search.getSuggestions()[idx]; - if (!suggest) { - message = "No suggestions found !"; + var error = null; + try { + var suggest = Search.getSuggestions()[idx]; + if (!suggest) { + throw "No suggestions found !"; + } + + // Ajout de la couche sur la carte si l'option le permet + if (this.options.searchOptions.addToMap) { + // Check if configuration is loaded + if (!Config.isConfigLoaded()) { + throw "ERROR : contract key configuration has to be loaded to load Geoportal layers."; + } + var service = suggest.service; + var name = suggest.name; + var layer = null; + switch (service) { + case "WMS": + layer = new GeoportalWMS({ + layer : name + }); + break; + case "WMTS": + layer = new GeoportalWMTS({ + layer : name + }); + break; + case "TMS": + layer = new GeoportalMapBox({ + layer : name + }); + default: + break; + } + if (layer) { + var map = this.getMap(); + map.addLayer(layer); + } + } + } catch (e) { + error = e; } + /** * event triggered when an element of the results is clicked for search service * @@ -1823,37 +1862,8 @@ var SearchEngine = class SearchEngine extends Control { this.dispatchEvent({ type : "searchengine:search:click", suggest : suggest, - error : new Error(message) + error : error }); - - // Ajout de la couche sur la carte si l'option le permet - if (this.options.searchOptions.addToMap) { - var service = suggest.service; - var name = suggest.name; - var layer = null; - switch (service) { - case "WMS": - layer = new GeoportalWMS({ - layer : name - }); - break; - case "WMTS": - layer = new GeoportalWMTS({ - layer : name - }); - break; - case "TMS": - layer = new GeoportalMapBox({ - layer : name - }); - default: - break; - } - if (layer) { - var map = this.getMap(); - map.addLayer(layer); - } - } } // ################################################################### // diff --git a/src/packages/Layers/LayerMapBox.js b/src/packages/Layers/LayerMapBox.js index f0a82e3b1..ba5a48ab6 100644 --- a/src/packages/Layers/LayerMapBox.js +++ b/src/packages/Layers/LayerMapBox.js @@ -11,35 +11,123 @@ import Utils from "../Utils/Helper"; import Config from "../Utils/Config"; /** - * @classdesc - * Geoportal Layer Mapbox creation - * - * @constructor - * @extends {ol.layer.VectorTile} - * @alias ol.layer.GeoportalMapBox - * @type {ol.layer.GeoportalMapBox} - * @param {Object} options - options for function call. - * @param {String} options.layer - Layer name (e.g. "PLAN.IGN") - * @param {String} [options.style] - Style name (e.g. "classique") - * @param {String} [options.source] - Source name (e.g. "plan_ign") - * @param {Boolean} [options.ssl] - if set true, enforce protocol https (only for nodejs) - * @param {Object} [settings] - other options for ol.layer.VectorTile function (see {@link https://openlayers.org/en/latest/apidoc/module-ol_layer_VectorTile-VectorTileLayer.html ol.layer.VectorTile}) - * @example - * var LayerMapBox = new ol.layer.GeoportalMapBox({ - * layer : "PLAN.IGN", - * [style : "classique",] - * [source : "plan_ign",] - * [ssl: true] - * }, { - * opacity - * visible - * extent - * declutter - * ... - * }); - */ +* @classdesc +* Geoportal Layer Mapbox creation +* +* @constructor +* @extends {ol.layer.VectorTile} +* @alias ol.layer.GeoportalMapBox +* @type {ol.layer.GeoportalMapBox} +* @param {Object} options - options for function call. +* @param {String} options.layer - Layer name (e.g. "PLAN.IGN") +* @param {Object} [options.configuration] - configuration (cf. example) +* @param {String} [options.style] - Style name (e.g. "classique") +* @param {String} [options.source] - Source name (e.g. "plan_ign") +* @param {Boolean} [options.ssl] - if set true, enforce protocol https (only for nodejs) +* @param {Object} [settings] - other options for ol.layer.VectorTile function (see {@link https://openlayers.org/en/latest/apidoc/module-ol_layer_VectorTile-VectorTileLayer.html ol.layer.VectorTile}) +* @example +* var LayerMapBox = new ol.layer.GeoportalMapBox({ +* layer : "PLAN.IGN", +* [style : "classique",] +* [source : "plan_ign",] +* [ssl: true] +* }, { +* opacity +* visible +* extent +* declutter +* ... +* }); +* +* // Ex. configuration object for TMS Layer +* "PLAN.IGN$GEOPORTAIL:GPP:TMS": { +* "hidden": true, +* "queryable": false, +* "serviceParams": { +* "id": "GPP:TMS", +* "version": "1.0.0", +* "serverUrl": { +* "cartes": "https://wxs.ign.fr/cartes/geoportail/tms/1.0.0/" +* } +* }, +* "name": "PLAN.IGN", +* "title": "Plan IGN", +* "description": "BDUni tuilée", +* "formats": [ +* { +* "current": true, +* "name": "application/x-protobuf" +* } +* ], +* "styles": [ +* { +* "name": "standard", +* "title": "Style standard", +* "current": true, +* "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/standard.json" +* }, +* { +* "name": "classique", +* "title": "Style classique", +* "current": true, +* "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/classique.json" +* }, +* { +* "name": "transparent", +* "title": "Style transparent", +* "current": true, +* "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/transparent.json" +* }, +* { +* "name": "accentue", +* "title": "Style accentue", +* "current": true, +* "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/accentue.json" +* }, +* { +* "name": "attenue", +* "title": "Style attenue", +* "current": true, +* "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/attenue.json" +* }, +* { +* "name": "gris", +* "title": "Style en noir et blanc", +* "current": false, +* "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/gris.json" +* }, +* { +* "name": "epure", +* "title": "Style epure", +* "current": true, +* "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/epure.json" +* }, +* { +* "name": "sans_toponymes", +* "title": "Style sans toponymes", +* "current": false, +* "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/sans_toponymes.json" +* } +* ], +* "globalConstraint": { +* "crs": null, +* "bbox": { +* "left": -724011.531917197, +* "right": 1095801.237496279, +* "top": 6672646.821182753, +* "bottom": 5009377.0856973175 +* }, +* "minScaleDenominator": null, +* "maxScaleDenominator": null +* }, +* "quicklookUrl": "https://wxs.ign.fr/static/pictures/ign_carte2.jpg", +* "layerId": "PLAN.IGN$GEOPORTAIL:GPP:TMS", +* "defaultProjection": "EPSG:3857" +* } +* +*/ var LayerMapBox = class LayerMapBox extends VectorTileLayer { - + /** * See {@link ol.layer.GeoportalMapBox} * @module LayerMapBox @@ -50,133 +138,54 @@ var LayerMapBox = class LayerMapBox extends VectorTileLayer { * import LayerMapBox from "gpf-ext-ol/layers/LayerMapBox" * ou * import { LayerMapBox } from "gpf-ext-ol" - */ + */ constructor (options, settings) { // if (!(this instanceof LayerMapBox)) { // throw new TypeError("ERROR CLASS_CONSTRUCTOR"); // } - + if (!options.layer) { throw new Error("ERROR PARAM_MISSING : layer"); } - + if (typeof options.layer !== "string") { throw new Error("ERROR WRONG TYPE : layer"); } - + // par defaut if (typeof options.ssl === "undefined") { options.ssl = true; } - + // si ssl = false on fait du http // par défaut, ssl = true, on fait du https var protocol = options.ssl === false ? "http://" : "https://"; - + // WARNING : - // on fait le choix de ne pas utiliser la clef apiKey pour checker les droits sur la ressource + // on fait le choix de ne pas utiliser la clef apiKey pour checker + // les droits sur la ressource // car le service n'est pas securisé... + + // configuration de la ressource + var layerCfg = options.configuration; - // Check if configuration is loaded - if (!Config.isConfigLoaded()) { - throw new Error("ERROR : contract key configuration has to be loaded to load Geoportal layers."); - } - - /** - * Ex. configuration object for TMS Layer - * (only for jsdoc) - * @example - * "PLAN.IGN$GEOPORTAIL:GPP:TMS": { - * "hidden": true, - * "queryable": false, - * "serviceParams": { - * "id": "GPP:TMS", - * "version": "1.0.0", - * "serverUrl": { - * "cartes": "https://wxs.ign.fr/cartes/geoportail/tms/1.0.0/" - * } - * }, - * "name": "PLAN.IGN", - * "title": "Plan IGN", - * "description": "BDUni tuilée", - * "formats": [ - * { - * "current": true, - * "name": "application/x-protobuf" - * } - * ], - * "styles": [ - * { - * "name": "standard", - * "title": "Style standard", - * "current": true, - * "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/standard.json" - * }, - * { - * "name": "classique", - * "title": "Style classique", - * "current": true, - * "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/classique.json" - * }, - * { - * "name": "transparent", - * "title": "Style transparent", - * "current": true, - * "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/transparent.json" - * }, - * { - * "name": "accentue", - * "title": "Style accentue", - * "current": true, - * "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/accentue.json" - * }, - * { - * "name": "attenue", - * "title": "Style attenue", - * "current": true, - * "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/attenue.json" - * }, - * { - * "name": "gris", - * "title": "Style en noir et blanc", - * "current": false, - * "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/gris.json" - * }, - * { - * "name": "epure", - * "title": "Style epure", - * "current": true, - * "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/epure.json" - * }, - * { - * "name": "sans_toponymes", - * "title": "Style sans toponymes", - * "current": false, - * "url": "https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/essentiels/sans_toponymes.json" - * } - * ], - * "globalConstraint": { - * "crs": null, - * "bbox": { - * "left": -724011.531917197, - * "right": 1095801.237496279, - * "top": 6672646.821182753, - * "bottom": 5009377.0856973175 - * }, - * "minScaleDenominator": null, - * "maxScaleDenominator": null - * }, - * "quicklookUrl": "https://wxs.ign.fr/static/pictures/ign_carte2.jpg", - * "layerId": "PLAN.IGN$GEOPORTAIL:GPP:TMS", - * "defaultProjection": "EPSG:3857" - * } - */ - // récupération des ressources utiles depuis la configuration - var layerId = options.layer + "$GEOPORTAIL:GPP:TMS"; - - var layerCfg = Config.configuration.getLayerConf(layerId); + // 2 solutions pour la récupération des ressources utiles + // * soit depuis la configuration en option + // * soit via la variable globale Gp.Config chargée if (!layerCfg) { - throw new Error("ERROR : Layer ID not found into the catalogue !?"); + // Check if configuration is loaded + if (!Config.isConfigLoaded()) { + throw new Error("ERROR : contract key configuration has to be loaded to load Geoportal layers."); + } + + // id de la ressource + var layerId = options.layer + "$GEOPORTAIL:GPP:TMS"; + + // récupération des ressources utiles depuis la configuration + layerCfg = Config.configuration.getLayerConf(layerId); + if (!layerCfg) { + throw new Error("ERROR : Layer ID not found into the catalogue !?"); + } } var styleUrl = null; @@ -199,52 +208,54 @@ var LayerMapBox = class LayerMapBox extends VectorTileLayer { } } } - + if (!styleUrl) { throw new Error("ERROR : Style URL not found !?"); } - + styleUrl.replace(/(http|https):\/\//, protocol); - + // création de la source var source = new VectorTileSource({ state : "loading", // statut format : new MVT() }); - + source._originators = layerCfg.originators; source._legends = layerCfg.legends; source._metadata = layerCfg.metadata; source._description = layerCfg.description; source._title = layerCfg.title + " (" + styleTitle + ")"; source._quicklookUrl = layerCfg.quicklookUrl; - + // options definies sur ol.layer.VectorTile var layerVectorTileOptions = { source : source }; - + // récupération des autres paramètres passés par l'utilisateur Utils.mergeParams(layerVectorTileOptions, settings); - + // on surcharge les originators (non récupérés depuis configuration de la couche) if (options.olParams && !layerCfg.originators) { source._originators = options.olParams.attributions; } - + // création d'une ol.layer.VectorTile avec les options récupérées ci-dessus. super(layerVectorTileOptions); - + + this.name = options.layer; + this.service = "TMS"; this.protocol = protocol; this.sourceId = options.source; this.styleUrl = styleUrl; - + // récuperation du style this.setStyleMapBox(); - + return this; } - + /** * Get Style MapBox * @private @@ -253,19 +264,17 @@ var LayerMapBox = class LayerMapBox extends VectorTileLayer { var self = this; fetch(this.styleUrl, { credentials : "same-origin" - }) - .then(function (response) { - if (response.ok) { - response.json().then(function (style) { - self.onStyleMapBoxLoad(style); - }); - } - }) - .catch(function (e) { - self.onStyleMapBoxError(e); - }); + }).then(function (response) { + if (response.ok) { + response.json().then(function (style) { + self.onStyleMapBoxLoad(style); + }); + } + }).catch(function (e) { + self.onStyleMapBoxError(e); + }); }; - + /** * Add Style * @param {*} style - json style @@ -275,7 +284,7 @@ var LayerMapBox = class LayerMapBox extends VectorTileLayer { if (!this.sourceId) { this.sourceId = Object.keys(style.sources)[0]; } - + var styleSource = style.sources[this.sourceId]; if (!styleSource) { this.onStyleMapBoxError({ @@ -283,23 +292,23 @@ var LayerMapBox = class LayerMapBox extends VectorTileLayer { }); return; } - + if (styleSource.type !== "vector") { this.onStyleMapBoxError({ message : "ERROR : Source TYPE not permitted !" }); return; } - + var source = this.getSource(); - + // WARNING : // la clef renseignée dans les urls n'est pas forcement la bonne // car la substitution avec la clef utilisateur n'est pas faite par le service... if (styleSource.url) { // protocole : http ou https styleSource.url.replace(/(http|https):\/\//, this.protocol); - + var vectorTileJson = new TileJSONSource({ url : styleSource.url }); @@ -321,7 +330,7 @@ var LayerMapBox = class LayerMapBox extends VectorTileLayer { } }); } - + if (styleSource.tiles) { // protocole : http ou https for (var j = 0; j < styleSource.tiles.length; j++) { @@ -329,17 +338,15 @@ var LayerMapBox = class LayerMapBox extends VectorTileLayer { } source.setUrls(styleSource.tiles); } - - applyStyle(this, style, this.sourceId) - .then(() => { - source.setState("ready"); - this.set("mapbox-styles", style); - }) - .catch((error) => { - this.onStyleMapBoxError(error); - }); + + applyStyle(this, style, this.sourceId).then(() => { + source.setState("ready"); + this.set("mapbox-styles", style); + }).catch((error) => { + this.onStyleMapBoxError(error); + }); }; - + /** * Error * @param {*} error - message @@ -350,7 +357,7 @@ var LayerMapBox = class LayerMapBox extends VectorTileLayer { // eslint-disable-next-line no-console console.error(error.message); }; - + }; export default LayerMapBox; diff --git a/src/packages/Layers/LayerWMS.js b/src/packages/Layers/LayerWMS.js index 444712779..03bfb95bd 100644 --- a/src/packages/Layers/LayerWMS.js +++ b/src/packages/Layers/LayerWMS.js @@ -18,8 +18,9 @@ import SourceWMS from "./SourceWMS"; * @extends {ol.layer.Tile} * @alias ol.layer.GeoportalWMS * @type {ol.layer.GeoportalWMS} - * @param {Object} GeoportalWMSoptions - options for function call. + * @param {Object} options - options for function call. * @param {String} options.layer - Layer name (e.g. "ORTHOIMAGERY.ORTHOPHOTOS") + * @param {Object} [options.configuration] - configuration (cf. example) * @param {Boolean} [options.ssl] - if set true, enforce protocol https (only for nodejs) * @param {String} [options.apiKey] - Access key to Geoportal platform * @param {Object} [options.olParams] - other options for ol.layer.Tile function (see {@link http://openlayers.org/en/latest/apidoc/ol.layer.Tile.html ol.layer.Tile}) @@ -59,9 +60,23 @@ var LayerWMS = class LayerWMS extends TileLayer { options.ssl = true; } - // Check if configuration is loaded - if (!Config.isConfigLoaded()) { - throw new Error("ERROR : contract key configuration has to be loaded to load Geoportal layers."); + // configuration de la ressource + var layerCfg = options.configuration; + + // 2 solutions pour la récupération des ressources utiles + // * soit depuis la configuration en option + // * soit via la variable globale Gp.Config chargée + if (!layerCfg) { + // Check if configuration is loaded + if (!Config.isConfigLoaded()) { + throw new Error("ERROR : contract key configuration has to be loaded to load Geoportal layers."); + } + // récupération des autres paramètres nécessaires à la création de la layer + var layerId = Config.configuration.getLayerId(options.layer, "WMS"); + layerCfg = Config.configuration.getLayerConf(layerId); + if (!layerCfg) { + throw new Error("ERROR : Layer ID not found into the catalogue !?"); + } } // création de la source WMS @@ -71,6 +86,7 @@ var LayerWMS = class LayerWMS extends TileLayer { } var wmsSource = new SourceWMS({ layer : options.layer, + configuration : options.configuration, ssl : options.ssl, apiKey : options.apiKey, olParams : olSourceParams @@ -83,10 +99,6 @@ var LayerWMS = class LayerWMS extends TileLayer { // si le param LAYERS n'a pas été renseigné lors de la création de la source, // c'est que l'identifiant de la couche n'a pas été trouvé. on passe donc la recherche des paramètres. if (wmsSource.getParams().LAYERS !== undefined) { - // récupération des autres paramètres nécessaires à la création de la layer - var layerId = Config.configuration.getLayerId(options.layer, "WMS"); - var globalConstraints = Config.configuration.getGlobalConstraints(layerId); - /* INFO : on ne récupère l'emprise de la couche que lorsque que l'utilisateur spécifie la projection. Si aucune projection n'est spécifiée, il faudrait spécifier l'emprise dans la projection de la carte (car OpenLayers reprojette), mais on ne peut pas la récupérer à ce niveau. On ne spécifie donc aucune emprise. @@ -95,10 +107,10 @@ var LayerWMS = class LayerWMS extends TileLayer { if (olSourceParams && olSourceParams.projection) { // récupération de l'étendue (en EPSG:4326), et reprojection dans la proj spécifiée var geobbox = [ - globalConstraints.extent.left, - globalConstraints.extent.bottom, - globalConstraints.extent.right, - globalConstraints.extent.top + layerCfg.globalConstraints.extent.left, + layerCfg.globalConstraints.extent.bottom, + layerCfg.globalConstraints.extent.right, + layerCfg.globalConstraints.extent.top ]; layerTileOptions.extent = olTransformExtentProj(geobbox, "EPSG:4326", olSourceParams.projection); @@ -117,15 +129,15 @@ var LayerWMS = class LayerWMS extends TileLayer { * on les arrondit respectivement à l'unité inférieure et supérieure * pour que les couches soient bien disponibles aux niveaux de zoom correspondants */ // info : 1 pixel = 0.00028 m - layerTileOptions.minResolution = (globalConstraints.minScale - 1) * 0.00028; - layerTileOptions.maxResolution = (globalConstraints.maxScale + 1) * 0.00028; + layerTileOptions.minResolution = (layerCfg.globalConstraints.minScale - 1) * 0.00028; + layerTileOptions.maxResolution = (layerCfg.globalConstraints.maxScale + 1) * 0.00028; } else if (p.getUnits() === "degrees") { /* fixme : fix temporaire pour gérer les min/max scaledenominator qui sont arrondis dans la configuration ! * on les arrondit respectivement à l'unité inférieure et supérieure * pour que les couches soient bien disponibles aux niveaux de zoom correspondants */ // info : 6378137 * 2 * pi / 360 = rayon de la terre (ellipsoide WGS84) - layerTileOptions.minResolution = (globalConstraints.minScale - 1) * 0.00028 * 180 / (Math.PI * 6378137); - layerTileOptions.maxResolution = (globalConstraints.maxScale + 1) * 0.00028 * 180 / (Math.PI * 6378137); + layerTileOptions.minResolution = (layerCfg.globalConstraints.minScale - 1) * 0.00028 * 180 / (Math.PI * 6378137); + layerTileOptions.maxResolution = (layerCfg.globalConstraints.maxScale + 1) * 0.00028 * 180 / (Math.PI * 6378137); } } } @@ -136,6 +148,9 @@ var LayerWMS = class LayerWMS extends TileLayer { // création d'une ol.layer.Tile avec les options récupérées ci-dessus. super(layerTileOptions); + this.name = options.layer; + this.service = "WMS"; + return this; } diff --git a/src/packages/Layers/LayerWMTS.js b/src/packages/Layers/LayerWMTS.js index 0dd03d5c5..c2af4b899 100644 --- a/src/packages/Layers/LayerWMTS.js +++ b/src/packages/Layers/LayerWMTS.js @@ -17,6 +17,7 @@ import SourceWMTS from "./SourceWMTS"; * @type {ol.layer.GeoportalWMTS} * @param {Object} options - options for function call. * @param {String} options.layer - Layer name (e.g. "ORTHOIMAGERY.ORTHOPHOTOS") + * @param {Object} [options.configuration] - configuration (cf. example) * @param {Boolean} [options.ssl] - if set true, enforce protocol https (only for nodejs) * @param {String} [options.apiKey] - Access key to Geoportal platform * @param {Object} [options.olParams] - other options for ol.layer.Tile function (see {@link http://openlayers.org/en/latest/apidoc/ol.layer.Tile.html ol.layer.Tile}) @@ -25,6 +26,52 @@ import SourceWMTS from "./SourceWMTS"; * var layerWMTS = new ol.layer.GeoportalWMTS({ * layer : "ORTHOIMAGERY.ORTHOPHOTOS" * }); + * + * // Ex. configuration object for WMTS Layer + * { +* name: "ORTHOIMAGERY.ORTHOPHOTOS", +* title: "Photographies aériennes", +* description: "Photographies aériennes", +* globalConstraint: { +* maxScaleDenominator: 559082264.0287179, +* minScaleDenominator: 266.5911979812229, +* bbox: { +* left: -180, +* right: 180, +* top: 89, +* bottom: -89 +* } +* }, +* serviceParams: { +* id: "OGC:WMTS", +* version: "1.0.0", +* serverUrl: { +* full: "https://data.geopf.fr/wmts" +* } +* }, +* defaultProjection: "EPSG:3857", +* wmtsOptions: { +* tileMatrixSetLink: "PM", +* tileMatrixSetLimits: { +* (...) +* } +* }, +* styles: [{ +* name: "normal", +* title: "Légende générique", +* current: true, +* url: null +* }], +* legends: [{ +* format: "image/jpeg", +* url: "https://data.geopf.fr/annexes/ressources/legendes/LEGEND.jpg", +* minScaleDenominator: "200" +* }], +* formats: [{ +* name: "image/jpeg", +* current: true +* }] +* } */ var LayerWMTS = class LayerWMTS extends TileLayer { @@ -56,9 +103,23 @@ var LayerWMTS = class LayerWMTS extends TileLayer { options.ssl = true; } - // Check if configuration is loaded - if (!Config.isConfigLoaded()) { - throw new Error("ERROR : contract key configuration has to be loaded to load Geoportal layers."); + // configuration de la ressource + var layerCfg = options.configuration; + + // 2 solutions pour la récupération des ressources utiles + // * soit depuis la configuration en option + // * soit via la variable globale Gp.Config chargée + if (!layerCfg) { + // Check if configuration is loaded + if (!Config.isConfigLoaded()) { + throw new Error("ERROR : contract key configuration has to be loaded to load Geoportal layers."); + } + // récupération des autres paramètres nécessaires à la création de la layer + var layerId = Config.configuration.getLayerId(options.layer, "WMTS"); + layerCfg = Config.configuration.getLayerConf(layerId); + if (!layerCfg) { + throw new Error("ERROR : Layer ID not found into the catalogue !?"); + } } // création de la source WMTS @@ -68,6 +129,7 @@ var LayerWMTS = class LayerWMTS extends TileLayer { } var wmtsSource = new SourceWMTS({ layer : options.layer, + configuration : options.configuration, ssl : options.ssl, apiKey : options.apiKey, olParams : olSourceParams @@ -80,26 +142,23 @@ var LayerWMTS = class LayerWMTS extends TileLayer { // si le param layer n'a pas été renseigné lors de la création de la source, // c'est que l'identifiant de la couche n'a pas été trouvé. on passe donc la recherche des paramètres. if (wmtsSource.getLayer() !== undefined) { - // récupération des autres paramètres nécessaires à la création de la layer - var layerId = Config.configuration.getLayerId(options.layer, "WMTS"); - var globalConstraints = Config.configuration.getGlobalConstraints(layerId); - if (globalConstraints && globalConstraints.projection) { + if (layerCfg.globalConstraints && layerCfg.globalConstraints.projection) { /* INFO : désactivation temporaire de l'étendue, car certaines étendues (trop grandes ?) provoquent quelques bugs d'affichage (zoom > 16 par exemple) */ // récupération de l'étendue (en EPSG:4326), et reprojection dans la proj de la couche // var geobbox = [ - // globalConstraints.extent.left, - // globalConstraints.extent.bottom, - // globalConstraints.extent.right, - // globalConstraints.extent.top + // layerCfg.globalConstraints.extent.left, + // layerCfg.globalConstraints.extent.bottom, + // layerCfg.globalConstraints.extent.right, + // layerCfg.globalConstraints.extent.top // ]; - // layerTileOptions.extent = ol.proj.transformExtent(geobbox, "EPSG:4326", globalConstraints.projection); + // layerTileOptions.extent = ol.proj.transformExtent(geobbox, "EPSG:4326", layerCfg.globalConstraints.projection); // récupération des résolutions min et max var p; // on récupère tout d'abord la projection - if (typeof globalConstraints.projection === "string") { - p = olGetProj(globalConstraints.projection); + if (typeof layerCfg.globalConstraints.projection === "string") { + p = olGetProj(layerCfg.globalConstraints.projection); } // puis, selon l'unité de la projection, on calcule la résolution correspondante if (p && p.getUnits()) { @@ -108,15 +167,15 @@ var LayerWMTS = class LayerWMTS extends TileLayer { * on les arrondit respectivement à l'unité inférieure et supérieure * pour que les couches soient bien disponibles aux niveaux de zoom correspondants */ // info : 1 pixel = 0.00028 m - layerTileOptions.minResolution = (globalConstraints.minScale - 1) * 0.00028; - layerTileOptions.maxResolution = (globalConstraints.maxScale + 1) * 0.00028; + layerTileOptions.minResolution = (layerCfg.globalConstraints.minScale - 1) * 0.00028; + layerTileOptions.maxResolution = (layerCfg.globalConstraints.maxScale + 1) * 0.00028; } else if (p.getUnits() === "degrees") { /* fixme : fix temporaire pour gérer les min/max scaledenominator qui sont arrondis dans la configuration ! * on les arrondit respectivement à l'unité inférieure et supérieure * pour que les couches soient bien disponibles aux niveaux de zoom correspondants */ // info : 6378137 * 2 * pi / 360 = rayon de la terre (ellipsoide WGS84) - layerTileOptions.minResolution = (globalConstraints.minScale - 1) * 0.00028 * 180 / (Math.PI * 6378137); - layerTileOptions.maxResolution = (globalConstraints.maxScale + 1) * 0.00028 * 180 / (Math.PI * 6378137); + layerTileOptions.minResolution = (layerCfg.globalConstraints.minScale - 1) * 0.00028 * 180 / (Math.PI * 6378137); + layerTileOptions.maxResolution = (layerCfg.globalConstraints.maxScale + 1) * 0.00028 * 180 / (Math.PI * 6378137); } } } @@ -128,6 +187,9 @@ var LayerWMTS = class LayerWMTS extends TileLayer { // création d'une ol.layer.Tile avec les options récupérées ci-dessus. super(layerTileOptions); + this.name = options.layer; + this.service = "WMTS"; + return this; } diff --git a/src/packages/Layers/SourceWMS.js b/src/packages/Layers/SourceWMS.js index d222b5f6e..8536d0bd6 100644 --- a/src/packages/Layers/SourceWMS.js +++ b/src/packages/Layers/SourceWMS.js @@ -20,6 +20,7 @@ var logger = Logger.getLogger("sourcewms"); * @extends {ol.source.TileWMS} * @param {Object} options - options for function call. * @param {String} options.layer - Layer name (e.g. "ORTHOIMAGERY.ORTHOPHOTOS") + * @param {Object} [options.configuration] - configuration (cf. example) * @param {Boolean} [options.ssl] - if set true, enforce protocol https (only for nodejs) * @param {String} [options.apiKey] - Access key to Geoportal platform * @param {Array} [options.legends] - Legends objects associated to the layer @@ -53,23 +54,34 @@ var SourceWMS = class SourceWMS extends TileWMSSource { options.ssl = true; } - // Check if configuration is loaded - if (!Config.isConfigLoaded()) { - throw new Error("ERROR : contract key configuration has to be loaded to load Geoportal layers."); - } + // configuration de la ressource + var layerCfg = options.configuration; + var wmsParams = (layerCfg) ? layerCfg.params : null; + var apiKey = options.apiKey; + + // 2 solutions pour la récupération des ressources utiles + // * soit depuis la configuration en option + // * soit via la variable globale Gp.Config + if (!layerCfg) { + // Check if configuration is loaded + if (!Config.isConfigLoaded()) { + throw new Error("ERROR : contract key configuration has to be loaded to load Geoportal layers."); + } - var layerId = Config.configuration.getLayerId(options.layer, "WMS"); + var layerId = Config.configuration.getLayerId(options.layer, "WMS"); + if (!layerId) { + throw new Error(`ERROR : WMS Layer ID ${options.layer} cannot be found in Geoportal Configuration. Make sure that this resource is included in your contract key.`); + } - if (!layerId) { - throw new Error(`ERROR : WMS Layer ID ${options.layer} cannot be found in Geoportal Configuration. Make sure that this resource is included in your contract key.`); - } + layerCfg = Config.configuration.getLayerConf(layerId); + if (!layerCfg) { + throw new Error("ERROR : WMS Layer configuration cannot be found in Geoportal."); + } - if (!Config.configuration.getLayerConf(layerId)) { - throw new Error("ERROR : WMS Layer configuration cannot be found in Geoportal...."); + apiKey = Config.configuration.getLayerKey(layerId)[0]; + wmsParams = Config.configuration.getLayerParams(options.layer, "WMS"); } - var wmsParams = Config.configuration.getLayerParams(options.layer, "WMS"); - // si ssl = false on fait du http // par défaut, ssl = true, on fait du https var protocol = options.ssl === false ? "http://" : "https://"; @@ -81,7 +93,11 @@ var SourceWMS = class SourceWMS extends TileWMSSource { // si l'url est privée // Ajout de la clef d'API fournie par l'utilisateur en prioritée // ou récupérée depuis la configuration - urlParams["apikey"] = options.apiKey || Config.configuration.getLayerKey(layerId)[0]; + var key = options.apiKey || apiKey; + if (!key) { + throw new Error("ERROR : WMS Layer apiKey cannot be found in Geoportal Configuration."); + } + urlParams["apikey"] = key; } var wmsSourceOptions = { @@ -124,6 +140,9 @@ var SourceWMS = class SourceWMS extends TileWMSSource { this._description = options.description || wmsParams.description; this._quicklookUrl = options.quicklookUrl || wmsParams.quicklookUrl; + this.name = options.layer; + this.service = "WMS"; + return this; } diff --git a/src/packages/Layers/SourceWMTS.js b/src/packages/Layers/SourceWMTS.js index 4566650a9..6fa6d1ce2 100644 --- a/src/packages/Layers/SourceWMTS.js +++ b/src/packages/Layers/SourceWMTS.js @@ -23,6 +23,7 @@ var logger = Logger.getLogger("sourcewmts"); * @extends {WMTSExtended} * @param {Object} options - options for function call. * @param {String} options.layer - Layer name (e.g. "ORTHOIMAGERY.ORTHOPHOTOS") + * @param {Object} [options.configuration] - configuration (cf. example) * @param {Boolean} [options.ssl] - if set true, enforce protocol https (only for nodejs) * @param {String} [options.apiKey] - Access key to Geoportal platform * @param {Array} [options.legends] - Legends objects associated to the layer @@ -56,23 +57,34 @@ var SourceWMTS = class SourceWMTS extends WMTSExtended { options.ssl = true; } - // Check if configuration is loaded - if (!Config.isConfigLoaded()) { - throw new Error("ERROR : contract key configuration has to be loaded to load Geoportal layers."); - } - - var layerId = Config.configuration.getLayerId(options.layer, "WMTS"); - - if (!layerId) { - throw new Error(`ERROR : WMTS Layer ID ${options.layer} cannot be found in Geoportal Configuration. Make sure that this resource is included in your contract key.`); - } - - if (!Config.configuration.getLayerConf(layerId)) { - throw new Error("ERROR : WMTS Layer configuration cannot be found in Geoportal...."); + // configuration de la ressource + var layerCfg = options.configuration; + var wmtsParams = (layerCfg) ? layerCfg.params : null; + var apiKey = options.apiKey; + + // 2 solutions pour la récupération des ressources utiles + // * soit depuis la configuration en option + // * soit via la variable globale Gp.Config + if (!layerCfg) { + // Check if configuration is loaded + if (!Config.isConfigLoaded()) { + throw new Error("ERROR : contract key configuration has to be loaded to load Geoportal layers."); + } + + var layerId = Config.configuration.getLayerId(options.layer, "WMTS"); + if (!layerId) { + throw new Error(`ERROR : WMTS Layer ID ${options.layer} cannot be found in Geoportal Configuration. Make sure that this resource is included in your contract key.`); + } + + layerCfg = Config.configuration.getLayerConf(layerId); + if (!layerCfg) { + throw new Error("ERROR : WMTS Layer configuration cannot be found in Geoportal."); + } + + apiKey = Config.configuration.getLayerKey(layerId)[0]; + wmtsParams = Config.configuration.getLayerParams(options.layer, "WMTS"); } - var wmtsParams = Config.configuration.getLayerParams(options.layer, "WMTS"); - // si ssl = false on fait du http // par défaut, ssl = true, on fait du https var protocol = options.ssl === false ? "http://" : "https://"; @@ -84,7 +96,11 @@ var SourceWMTS = class SourceWMTS extends WMTSExtended { // si l'url est privée // Ajout de la clef d'API fournie par l'utilisateur en prioritée // ou récupérée depuis la configuration - urlParams["apikey"] = options.apiKey || Config.configuration.getLayerKey(layerId)[0]; + var key = options.apiKey || apiKey; + if (!key) { + throw new Error("ERROR : WMS Layer apiKey cannot be found in Geoportal Configuration."); + } + urlParams["apikey"] = key; } var wmtsSourceOptions = { @@ -125,6 +141,9 @@ var SourceWMTS = class SourceWMTS extends WMTSExtended { this._description = options.description || wmtsParams.description; this._title = options.title || wmtsParams.title; this._quicklookUrl = options.quicklookUrl || wmtsParams.quicklookUrl; + + this.name = options.layer; + this.service = "WMTS"; return this; }