From 760758362cabd8e9862a7ccedf5d7b0b08366a21 Mon Sep 17 00:00:00 2001 From: jean-philippe bazonnais Date: Mon, 6 May 2024 23:20:03 +0200 Subject: [PATCH] Build des binaires et des sources du projet (#13) * Ajout de la documentation * Ajout de la licence * Build des binaires et des sources du projet * Github actions build et deploy * Nouvelle nomenclature des bundles (GpfExtOl) --- .github/workflow/build-site.yml | 75 + .github/workflow/release.yml | 141 + CHANGELOG.md | 12 + CONTRIBUTORS.md | 19 + DRAFT_CHANGELOG.md | 26 + LICENCE.md | 137 + README.md | 31 + build/jsdoc/README.md | 4 +- build/jsdoc/jaguarjs-jsdoc/tmpl/layout.tmpl | 2 +- build/jsdoc/jsdoc.json | 4 +- build/licences/licence-es6promise.txt | 7 - build/licences/licence-fetch.tmpl | 7 - build/licences/licence-sortablejs.tmpl | 29 +- build/release/README.md | 50 + build/release/changelog.js | 2 + .../.npmignore | 1 - .../css/Dsfr.css | 88 - .../css/Portail.css | 90 - ...al-extensions-openlayers-1.0.0-beta.15.tgz | Bin 637546 -> 0 bytes .../package.json | 40 - .../src/index.d.ts | 48 - .../src/index.d.ts.map | 1 - .../src/index.js | 67 - .../src/packages/CRS/AutoLoadCRS.d.ts | 2 - .../src/packages/CRS/AutoLoadCRS.d.ts.map | 1 - .../src/packages/CRS/AutoLoadCRS.js | 19 - .../src/packages/CRS/CRS.d.ts | 22 - .../src/packages/CRS/CRS.d.ts.map | 1 - .../src/packages/CRS/CRS.js | 166 - .../src/packages/CRS/Proj4.d.ts | 2 - .../src/packages/CRS/Proj4.d.ts.map | 1 - .../src/packages/CRS/Proj4.js | 50 - .../Attribution/DSFRattributionStyle.css | 0 .../Controls/Attribution/GPFattribution.css | 0 .../Attribution/GPFattributionStyle.css | 7 - .../CSS/Controls/Drawing/DSFRdrawingStyle.css | 8 - .../CSS/Controls/Drawing/GPFdrawing.css | 168 - .../CSS/Controls/Drawing/GPFdrawingStyle.css | 370 -- .../Controls/Drawing/img/GPdrawingOpen.png | Bin 517 -> 0 bytes .../CSS/Controls/Drawing/img/drawing-save.svg | 1 - .../Controls/Drawing/img/drawing-tools.svg | 452 --- .../CSS/Controls/Drawing/img/modifier.svg | 3 - .../CSS/Controls/Editor/DSFReditorStyle.css | 0 .../CSS/Controls/Editor/GPFeditor.css | 0 .../CSS/Controls/Editor/GPFeditorStyle.css | 505 --- .../Editor/img/GPEditorLayerTools.png | Bin 2151 -> 0 bytes .../Editor/img/GPEditorLayerTypeIcon.png | Bin 4022 -> 0 bytes .../Editor/img/GPEditorLayerTypeIcon.svg | 241 -- .../ElevationPath/DSFRelevationPathStyle.css | 16 - .../ElevationPath/GPFelevationPath.css | 66 - .../ElevationPath/GPFelevationPathStyle.css | 173 - .../ElevationPath/img/GPshowElevationPath.png | Bin 1237 -> 0 bytes .../Controls/ElevationPath/img/altipath.svg | 62 - .../CSS/Controls/Export/DSFRexportStyle.css | 0 .../CSS/Controls/Export/GPFexport.css | 0 .../CSS/Controls/Export/GPFexportStyle.css | 102 - .../CSS/Controls/Export/img/GPexportSave.svg | 28 - .../DSFRgetFeatureInfoStyle.css | 15 - .../GetFeatureInfo/GPFgetFeatureInfo.css | 10 - .../GetFeatureInfo/GPFgetFeatureInfoStyle.css | 11 - .../CSS/Controls/GetFeatureInfo/img/GFI.svg | 56 - .../GetFeatureInfo/img/GPactivateGfi.png | Bin 9904 -> 0 bytes .../CSS/Controls/GetFeatureInfo/img/NoGFI.svg | 61 - .../Controls/Isochron/DSFRisochronStyle.css | 16 - .../CSS/Controls/Isochron/GPFisochron.css | 147 - .../Controls/Isochron/GPFisochronStyle.css | 190 - .../Controls/Isochron/img/GPisochronCheck.png | Bin 1316 -> 0 bytes .../Controls/Isochron/img/GPisochronOpen.png | Bin 660 -> 0 bytes .../Isochron/img/GPisochronOptions.png | Bin 5658 -> 0 bytes .../CSS/Controls/Isochron/img/isochrone.svg | 33 - .../LayerImport/DSFRlayerImportStyle.css | 14 - .../Controls/LayerImport/GPFlayerImport.css | 115 - .../LayerImport/GPFlayerImportStyle.css | 201 -- .../LayerImport/img/GPimportMapBoxReturn.png | Bin 421 -> 0 bytes .../Controls/LayerImport/img/GPimportOpen.png | Bin 638 -> 0 bytes .../Controls/LayerImport/img/layerimport.svg | 44 - .../LayerSwitcher/DSFRlayerSwitcherStyle.css | 0 .../LayerSwitcher/GPFlayerSwitcher.css | 97 - .../LayerSwitcher/GPFlayerSwitcherStyle.css | 374 -- .../LayerSwitcher/img/GPlayerInfo.png | Bin 726 -> 0 bytes .../LayerSwitcher/img/GPlayerInfoClose.png | Bin 535 -> 0 bytes .../LayerSwitcher/img/GPlayerTools.png | Bin 2233 -> 0 bytes .../LayerSwitcher/img/GPopacitySlider.png | Bin 179 -> 0 bytes .../LayerSwitcher/img/GPshowLayersList.png | Bin 7054 -> 0 bytes .../LocationSelector/DSFRlocationStyle.css | 18 - .../Controls/LocationSelector/GPFlocation.css | 48 - .../LocationSelector/GPFlocationStyle.css | 40 - .../img/GPlocationOptions.png | Bin 3381 -> 0 bytes .../LocationSelector/img/GProuteMarker.png | Bin 1733 -> 0 bytes .../Measures/DSFRmeasureAreaStyle.css | 6 - .../Measures/DSFRmeasureAzimuthStyle.css | 6 - .../Measures/DSFRmeasureLengthStyle.css | 6 - .../CSS/Controls/Measures/GPFmeasureArea.css | 9 - .../Controls/Measures/GPFmeasureAreaStyle.css | 18 - .../Controls/Measures/GPFmeasureAzimuth.css | 8 - .../Measures/GPFmeasureAzimuthStyle.css | 17 - .../Controls/Measures/GPFmeasureLength.css | 6 - .../Measures/GPFmeasureLengthStyle.css | 17 - .../Controls/Measures/GPFmeasureToolTip.css | 46 - .../Measures/img/DSFRmeasuresOpen.png | Bin 1668 -> 0 bytes .../Controls/Measures/img/GPmeasuresOpen.png | Bin 1668 -> 0 bytes .../Measures/img/mesurer-distance.svg | 8 - .../Controls/Measures/img/mesurer-surface.svg | 11 - .../Measures/img/modifier-geometrie-old.svg | 8 - .../MousePosition/DSFRmousePositionStyle.css | 6 - .../MousePosition/GPFmousePosition.css | 129 - .../MousePosition/GPFmousePositionStyle.css | 122 - .../MousePosition/img/GPmapCenter.png | Bin 1975 -> 0 bytes .../img/GPmousePositionEditCoordinates.png | Bin 540 -> 0 bytes .../MousePosition/img/GPmousePositionOpen.png | Bin 377 -> 0 bytes .../Controls/MousePosition/img/position.svg | 44 - .../DSFRreverseGeocodingStyle.css | 28 - .../ReverseGeocoding/GPFreverseGeocoding.css | 55 - .../GPFreverseGeocodingStyle.css | 27 - .../img/GPreverseGeocodingOpen.png | Bin 631 -> 0 bytes .../img/GPreverseGeocodingReturn.png | Bin 421 -> 0 bytes .../ReverseGeocoding/img/reversegeocode.svg | 44 - .../CSS/Controls/Route/DSFRrouteStyle.css | 9 - .../packages/CSS/Controls/Route/GPFroute.css | 231 -- .../CSS/Controls/Route/GPFrouteStyle.css | 249 -- .../CSS/Controls/Route/img/GProuteCheck.png | Bin 1316 -> 0 bytes .../CSS/Controls/Route/img/GProuteOpen.png | Bin 442 -> 0 bytes .../CSS/Controls/Route/img/GProuteOptions.png | Bin 3381 -> 0 bytes .../packages/CSS/Controls/Route/img/route.svg | 69 - .../SearchEngine/DSFRsearchEngineStyle.css | 87 - .../Controls/SearchEngine/GPFsearchEngine.css | 200 -- .../SearchEngine/GPFsearchEngineStyle.css | 146 - .../SearchEngine/img/GPsearchEngineClose.png | Bin 7787 -> 0 bytes .../SearchEngine/img/GPsearchEngineOpen.png | Bin 9851 -> 0 bytes .../SearchEngine/img/dsfr/coordonnees.svg | 3 - .../SearchEngine/img/dsfr/localiser.svg | 8 - .../SearchEngine/img/dsfr/search-line.svg | 3 - .../DSFRtoolBoxMeasureStyle.css | 5 - .../ToolBoxMeasure/GPFtoolBoxMeasure.css | 47 - .../ToolBoxMeasure/GPFtoolBoxMeasureStyle.css | 4 - .../img/GPtoolBoxMeasureOpen.png | Bin 896 -> 0 bytes .../src/packages/CSS/DSFRgeneralWidget.css | 371 -- .../src/packages/CSS/GPFgeneralWidget.css | 548 --- .../src/packages/CSS/GPFwaiting.css | 37 - .../src/packages/CSS/img/GPclose.png | Bin 7787 -> 0 bytes .../src/packages/CSS/img/GPinfo.svg | 56 - .../src/packages/CSS/img/GPinfo_secondary.svg | 57 - .../packages/CSS/img/GPshowMoreOptions.png | Bin 293 -> 0 bytes .../src/packages/CSS/img/close-blue.svg | 1 - .../src/packages/CSS/img/close-emeraud.svg | 1 - .../src/packages/CSS/img/lightOrange.svg | 82 - .../src/packages/CSS/img/waiting.gif | Bin 1333 -> 0 bytes .../Controls/Attribution/AttributionDOM.d.ts | 10 - .../Attribution/AttributionDOM.d.ts.map | 1 - .../Controls/Attribution/AttributionDOM.js | 96 - .../Attribution/GeoportalAttribution.d.ts | 21 - .../Attribution/GeoportalAttribution.d.ts.map | 1 - .../Attribution/GeoportalAttribution.js | 243 -- .../src/packages/Controls/Control.d.ts | 7 - .../src/packages/Controls/Control.d.ts.map | 1 - .../src/packages/Controls/Control.js | 161 - .../packages/Controls/Drawing/Drawing.d.ts | 110 - .../Controls/Drawing/Drawing.d.ts.map | 1 - .../src/packages/Controls/Drawing/Drawing.js | 1998 ----------- .../packages/Controls/Drawing/DrawingDOM.d.ts | 3 - .../Controls/Drawing/DrawingDOM.d.ts.map | 1 - .../packages/Controls/Drawing/DrawingDOM.js | 732 ---- .../src/packages/Controls/Editor/Editor.d.ts | 257 -- .../packages/Controls/Editor/Editor.d.ts.map | 1 - .../src/packages/Controls/Editor/Editor.js | 1008 ------ .../packages/Controls/Editor/EditorDOM.d.ts | 5 - .../Controls/Editor/EditorDOM.d.ts.map | 1 - .../src/packages/Controls/Editor/EditorDOM.js | 14 - .../src/packages/Controls/Editor/Event.d.ts | 36 - .../packages/Controls/Editor/Event.d.ts.map | 1 - .../src/packages/Controls/Editor/Event.js | 83 - .../src/packages/Controls/Editor/Filter.d.ts | 91 - .../packages/Controls/Editor/Filter.d.ts.map | 1 - .../src/packages/Controls/Editor/Filter.js | 252 -- .../src/packages/Controls/Editor/Group.d.ts | 72 - .../packages/Controls/Editor/Group.d.ts.map | 1 - .../src/packages/Controls/Editor/Group.js | 174 - .../src/packages/Controls/Editor/Layer.d.ts | 211 -- .../packages/Controls/Editor/Layer.d.ts.map | 1 - .../src/packages/Controls/Editor/Layer.js | 638 ---- .../src/packages/Controls/Editor/Legend.d.ts | 330 -- .../packages/Controls/Editor/Legend.d.ts.map | 1 - .../src/packages/Controls/Editor/Legend.js | 1038 ------ .../src/packages/Controls/Editor/Search.d.ts | 92 - .../packages/Controls/Editor/Search.d.ts.map | 1 - .../src/packages/Controls/Editor/Search.js | 217 -- .../src/packages/Controls/Editor/Style.d.ts | 154 - .../packages/Controls/Editor/Style.d.ts.map | 1 - .../src/packages/Controls/Editor/Style.js | 458 --- .../src/packages/Controls/Editor/Themes.d.ts | 120 - .../packages/Controls/Editor/Themes.d.ts.map | 1 - .../src/packages/Controls/Editor/Themes.js | 382 --- .../Controls/ElevationPath/ElevationPath.d.ts | 73 - .../ElevationPath/ElevationPath.d.ts.map | 1 - .../Controls/ElevationPath/ElevationPath.js | 1743 ---------- .../ElevationPath/ElevationPathDOM.d.ts | 14 - .../ElevationPath/ElevationPathDOM.d.ts.map | 1 - .../ElevationPath/ElevationPathDOM.js | 252 -- .../ProfileElevationPathDOM.d.ts | 14 - .../ProfileElevationPathDOM.d.ts.map | 1 - .../ElevationPath/ProfileElevationPathDOM.js | 1113 ------ .../src/packages/Controls/Export/Export.d.ts | 266 -- .../packages/Controls/Export/Export.d.ts.map | 1 - .../src/packages/Controls/Export/Export.js | 700 ---- .../packages/Controls/Export/ExportDOM.d.ts | 5 - .../Controls/Export/ExportDOM.d.ts.map | 1 - .../src/packages/Controls/Export/ExportDOM.js | 14 - .../GetFeatureInfo/GetFeatureInfo.d.ts | 31 - .../GetFeatureInfo/GetFeatureInfo.d.ts.map | 1 - .../Controls/GetFeatureInfo/GetFeatureInfo.js | 681 ---- .../GetFeatureInfo/GetFeatureInfoDOM.d.ts | 7 - .../GetFeatureInfo/GetFeatureInfoDOM.d.ts.map | 1 - .../GetFeatureInfo/GetFeatureInfoDOM.js | 60 - .../packages/Controls/Isocurve/Isocurve.d.ts | 65 - .../Controls/Isocurve/Isocurve.d.ts.map | 1 - .../packages/Controls/Isocurve/Isocurve.js | 1637 --------- .../Controls/Isocurve/IsocurveDOM.d.ts | 26 - .../Controls/Isocurve/IsocurveDOM.d.ts.map | 1 - .../packages/Controls/Isocurve/IsocurveDOM.js | 886 ----- .../Controls/LayerImport/LayerImport.d.ts | 84 - .../Controls/LayerImport/LayerImport.d.ts.map | 1 - .../Controls/LayerImport/LayerImport.js | 3041 ----------------- .../Controls/LayerImport/LayerImportDOM.d.ts | 42 - .../LayerImport/LayerImportDOM.d.ts.map | 1 - .../Controls/LayerImport/LayerImportDOM.js | 1057 ------ .../Controls/LayerSwitcher/LayerSwitcher.d.ts | 40 - .../LayerSwitcher/LayerSwitcher.d.ts.map | 1 - .../Controls/LayerSwitcher/LayerSwitcher.js | 1087 ------ .../LayerSwitcher/LayerSwitcherDOM.d.ts | 29 - .../LayerSwitcher/LayerSwitcherDOM.d.ts.map | 1 - .../LayerSwitcher/LayerSwitcherDOM.js | 695 ---- .../LocationSelector/LocationSelector.d.ts | 39 - .../LocationSelector.d.ts.map | 1 - .../LocationSelector/LocationSelector.js | 814 ----- .../LocationSelector/LocationSelectorDOM.d.ts | 18 - .../LocationSelectorDOM.d.ts.map | 1 - .../LocationSelector/LocationSelectorDOM.js | 511 --- .../Controls/Measures/MeasureArea.d.ts | 27 - .../Controls/Measures/MeasureArea.d.ts.map | 1 - .../packages/Controls/Measures/MeasureArea.js | 302 -- .../Controls/Measures/MeasureAreaDOM.d.ts | 7 - .../Controls/Measures/MeasureAreaDOM.d.ts.map | 1 - .../Controls/Measures/MeasureAreaDOM.js | 69 - .../Controls/Measures/MeasureAzimuth.d.ts | 27 - .../Controls/Measures/MeasureAzimuth.d.ts.map | 1 - .../Controls/Measures/MeasureAzimuth.js | 357 -- .../Controls/Measures/MeasureAzimuthDOM.d.ts | 7 - .../Measures/MeasureAzimuthDOM.d.ts.map | 1 - .../Controls/Measures/MeasureAzimuthDOM.js | 69 - .../Controls/Measures/MeasureLength.d.ts | 27 - .../Controls/Measures/MeasureLength.d.ts.map | 1 - .../Controls/Measures/MeasureLength.js | 299 -- .../Controls/Measures/MeasureLengthDOM.d.ts | 7 - .../Measures/MeasureLengthDOM.d.ts.map | 1 - .../Controls/Measures/MeasureLengthDOM.js | 68 - .../packages/Controls/Measures/Measures.d.ts | 11 - .../Controls/Measures/Measures.d.ts.map | 1 - .../packages/Controls/Measures/Measures.js | 536 --- .../Controls/MousePosition/MousePosition.d.ts | 87 - .../MousePosition/MousePosition.d.ts.map | 1 - .../Controls/MousePosition/MousePosition.js | 1719 ---------- .../MousePosition/MousePositionDOM.d.ts | 32 - .../MousePosition/MousePositionDOM.d.ts.map | 1 - .../MousePosition/MousePositionDOM.js | 893 ----- .../ReverseGeocode/ReverseGeocode.d.ts | 34 - .../ReverseGeocode/ReverseGeocode.d.ts.map | 1 - .../Controls/ReverseGeocode/ReverseGeocode.js | 1789 ---------- .../ReverseGeocode/ReverseGeocodeDOM.d.ts | 21 - .../ReverseGeocode/ReverseGeocodeDOM.d.ts.map | 1 - .../ReverseGeocode/ReverseGeocodeDOM.js | 485 --- .../src/packages/Controls/Route/Route.d.ts | 71 - .../packages/Controls/Route/Route.d.ts.map | 1 - .../src/packages/Controls/Route/Route.js | 2265 ------------ .../src/packages/Controls/Route/RouteDOM.d.ts | 34 - .../packages/Controls/Route/RouteDOM.d.ts.map | 1 - .../src/packages/Controls/Route/RouteDOM.js | 1233 ------- .../Controls/SearchEngine/SearchEngine.d.ts | 115 - .../SearchEngine/SearchEngine.d.ts.map | 1 - .../Controls/SearchEngine/SearchEngine.js | 2315 ------------- .../SearchEngine/SearchEngineDOM.d.ts | 82 - .../SearchEngine/SearchEngineDOM.d.ts.map | 1 - .../Controls/SearchEngine/SearchEngineDOM.js | 1384 -------- .../ToolBoxMeasure/MeasureToolBox.d.ts | 10 - .../ToolBoxMeasure/MeasureToolBox.d.ts.map | 1 - .../Controls/ToolBoxMeasure/MeasureToolBox.js | 92 - .../ToolBoxMeasure/MeasureToolBoxDOM.d.ts | 11 - .../ToolBoxMeasure/MeasureToolBoxDOM.d.ts.map | 1 - .../ToolBoxMeasure/MeasureToolBoxDOM.js | 108 - .../src/packages/Controls/Utils/Gfi.d.ts | 23 - .../src/packages/Controls/Utils/Gfi.d.ts.map | 1 - .../src/packages/Controls/Utils/Gfi.js | 636 ---- .../packages/Controls/Utils/Interactions.d.ts | 10 - .../Controls/Utils/Interactions.d.ts.map | 1 - .../packages/Controls/Utils/Interactions.js | 123 - .../src/packages/Controls/Utils/Markers.d.ts | 9 - .../packages/Controls/Utils/Markers.d.ts.map | 1 - .../src/packages/Controls/Utils/Markers.js | 9 - .../packages/Controls/Utils/MarkersOther.d.ts | 12 - .../Controls/Utils/MarkersOther.d.ts.map | 1 - .../packages/Controls/Utils/MarkersOther.js | 214 -- .../src/packages/Formats/GPX.d.ts | 22 - .../src/packages/Formats/GPX.d.ts.map | 1 - .../src/packages/Formats/GPX.js | 511 --- .../src/packages/Formats/GeoJSON.d.ts | 21 - .../src/packages/Formats/GeoJSON.d.ts.map | 1 - .../src/packages/Formats/GeoJSON.js | 150 - .../src/packages/Formats/KML.d.ts | 30 - .../src/packages/Formats/KML.d.ts.map | 1 - .../src/packages/Formats/KML.js | 1316 ------- .../src/packages/Formats/Styling.d.ts | 63 - .../src/packages/Formats/Styling.d.ts.map | 1 - .../src/packages/Formats/Styling.js | 878 ----- .../src/packages/Layers/LayerMapBox.d.ts | 31 - .../src/packages/Layers/LayerMapBox.d.ts.map | 1 - .../src/packages/Layers/LayerMapBox.js | 359 -- .../src/packages/Layers/LayerWMS.d.ts | 22 - .../src/packages/Layers/LayerWMS.d.ts.map | 1 - .../src/packages/Layers/LayerWMS.js | 147 - .../src/packages/Layers/LayerWMTS.d.ts | 22 - .../src/packages/Layers/LayerWMTS.d.ts.map | 1 - .../src/packages/Layers/LayerWMTS.js | 140 - .../src/packages/Layers/SourceWMS.d.ts | 26 - .../src/packages/Layers/SourceWMS.d.ts.map | 1 - .../src/packages/Layers/SourceWMS.js | 137 - .../src/packages/Layers/SourceWMTS.d.ts | 26 - .../src/packages/Layers/SourceWMTS.d.ts.map | 1 - .../src/packages/Layers/SourceWMTS.js | 139 - .../src/packages/Layers/WFS.d.ts | 3 - .../src/packages/Layers/WFS.d.ts.map | 1 - .../src/packages/Layers/WFS.js | 3 - .../src/packages/Services/Search.d.ts | 40 - .../src/packages/Services/Search.d.ts.map | 1 - .../src/packages/Services/Search.js | 191 -- .../src/packages/Sources/WMTS.d.ts | 14 - .../src/packages/Sources/WMTS.d.ts.map | 1 - .../src/packages/Sources/WMTS.js | 135 - .../src/packages/Utils/AutoLoadConfig.d.ts | 2 - .../packages/Utils/AutoLoadConfig.d.ts.map | 1 - .../src/packages/Utils/AutoLoadConfig.js | 48 - .../src/packages/Utils/ColorUtils.d.ts | 12 - .../src/packages/Utils/ColorUtils.d.ts.map | 1 - .../src/packages/Utils/ColorUtils.js | 180 - .../src/packages/Utils/Config.d.ts | 6 - .../src/packages/Utils/Config.d.ts.map | 1 - .../src/packages/Utils/Config.js | 40 - .../src/packages/Utils/Draggable.d.ts | 5 - .../src/packages/Utils/Draggable.d.ts.map | 1 - .../src/packages/Utils/Draggable.js | 133 - .../src/packages/Utils/GeocodeUtils.d.ts | 6 - .../src/packages/Utils/GeocodeUtils.d.ts.map | 1 - .../src/packages/Utils/GeocodeUtils.js | 60 - .../src/packages/Utils/Helper.d.ts | 7 - .../src/packages/Utils/Helper.d.ts.map | 1 - .../src/packages/Utils/Helper.js | 101 - .../src/packages/Utils/LayerUtils.d.ts | 13 - .../src/packages/Utils/LayerUtils.d.ts.map | 1 - .../src/packages/Utils/LayerUtils.js | 315 -- .../src/packages/Utils/LoggerByDefault.d.ts | 7 - .../packages/Utils/LoggerByDefault.d.ts.map | 1 - .../src/packages/Utils/LoggerByDefault.js | 62 - .../src/packages/Utils/MathUtils.d.ts | 68 - .../src/packages/Utils/MathUtils.d.ts.map | 1 - .../src/packages/Utils/MathUtils.js | 234 -- .../src/packages/Utils/Parser.d.ts | 7 - .../src/packages/Utils/Parser.d.ts.map | 1 - .../src/packages/Utils/Parser.js | 137 - .../src/packages/Utils/ProxyUtils.d.ts | 8 - .../src/packages/Utils/ProxyUtils.d.ts.map | 1 - .../src/packages/Utils/ProxyUtils.js | 51 - .../src/packages/Utils/Register.d.ts | 441 --- .../src/packages/Utils/Register.d.ts.map | 1 - .../src/packages/Utils/Register.js | 657 ---- .../src/packages/Utils/SearchEngineUtils.d.ts | 25 - .../packages/Utils/SearchEngineUtils.d.ts.map | 1 - .../src/packages/Utils/SearchEngineUtils.js | 152 - .../src/packages/Utils/SelectorID.d.ts | 8 - .../src/packages/Utils/SelectorID.d.ts.map | 1 - .../src/packages/Utils/SelectorID.js | 87 - .../src/packages/bundle.d.ts | 105 - .../src/packages/bundle.d.ts.map | 1 - build/release/package.js | 96 + build/webpack/README.md | 66 + build/webpack/bundle.webpack.config.js | 209 ++ build/webpack/controls.webpack.config.js | 106 + build/webpack/crs.webpack.config.js | 23 + build/webpack/extend.banners.webpack.js | 42 + build/webpack/extend.base.webpack.js | 148 + build/webpack/extend.samples.webpack.js | 83 + build/webpack/extend.themes.webpack.js | 58 + build/webpack/formats.webpack.config.js | 27 + build/webpack/layers.webpack.config.js | 30 + build/webpack/modules.webpack.config.js | 237 ++ build/webpack/webpack.config.modules.js | 448 --- build/webpack/webpack.config.packages.js | 423 --- doc/CHANGELOG.md | 2035 ----------- doc/README.md | 228 +- doc/capture-carte.png | Bin 0 -> 159652 bytes doc/openlayers.svg | 1 + package.json | 33 +- ...pages-ol-attributions-modules-default.html | 10 +- .../pages-ol-attributions-modules-osm.html | 10 +- ...ault.html => pages-ol-bundle-default.html} | 62 +- ...html => pages-ol-bundle-dsfr-default.html} | 62 +- .../Default/pages-ol-modules-default.html | 62 +- .../pages-ol-modules-dsrf-default.html | 62 +- .../pages-ol-drawing-modules-default.html | 7 +- ...es-ol-drawing-modules-display-measure.html | 4 +- ...pages-ol-drawing-modules-dsfr-default.html | 4 +- .../pages-ol-drawing-modules-export.html | 4 +- ...pages-ol-editor-modules-multi-editor.html} | 7 +- ...pages-ol-editor-modules-options-icon.html} | 7 +- ...pages-ol-editor-modules-options-sort.html} | 7 +- ...ges-ol-editor-modules-options-themes.html} | 7 +- ...l => pages-ol-editor-modules-sprites.html} | 7 +- .../Editor/pages-ol-editor-modules-test.html | 5 +- ...tml => pages-ol-filters-modules-test.html} | 7 +- ...html => pages-ol-layers-modules-test.html} | 7 +- ...tml => pages-ol-legends-modules-test.html} | 7 +- ...html => pages-ol-styles-modules-test.html} | 7 +- ...html => pages-ol-themes-modules-test.html} | 7 +- ...-ol-elevationpath-modules-all-options.html | 8 +- ...ges-ol-elevationpath-modules-amcharts.html | 4 +- .../pages-ol-elevationpath-modules-d3.html | 4 +- ...l-elevationpath-modules-dsfr-amcharts.html | 4 +- ...ages-ol-elevationpath-modules-dsfr-d3.html | 4 +- ...ges-ol-elevationpath-modules-dsfr-raw.html | 4 +- ...s-ol-elevationpath-modules-raw-target.html | 4 +- .../pages-ol-elevationpath-modules-raw.html | 4 +- .../pages-ol-export-modules-default.html | 28 +- .../pages-ol-export-modules-dsfr-default.html | 28 +- ...es-ol-geojsonextended-modules-default.html | 4 +- .../pages-ol-gpxextended-modules-default.html | 4 +- .../pages-ol-kmlextended-modules-default.html | 4 +- ...ges-ol-getfeatureinfo-modules-default.html | 8 +- ...ges-ol-getfeatureinfo-modules-options.html | 12 +- .../pages-ol-isocurve-modules-default.html | 8 +- ...ages-ol-isocurve-modules-dsfr-default.html | 4 +- .../pages-ol-layerimport-modules-default.html | 8 +- ...s-ol-layerimport-modules-dsfr-default.html | 8 +- ...es-ol-layerswitcher-modules-addlayers.html | 6 +- ...ages-ol-layerswitcher-modules-default.html | 4 +- ...-layerswitcher-modules-dsfr-addlayers.html | 6 +- ...ol-layerswitcher-modules-dsfr-default.html | 4 +- ...ol-layerswitcher-modules-removelayers.html | 6 +- .../pages-ol-layermapbox-modules-default.html | 2 +- .../pages-ol-layermapbox-modules-editor.html | 4 +- .../pages-ol-layerwms-modules-default.html | 2 +- ...ges-ol-layerwms-modules-without-right.html | 2 +- .../pages-ol-layerwmts-modules-default.html | 2 +- .../pages-ol-sourcewms-modules-L93.html | 4 +- .../pages-ol-sourcewms-modules-default.html | 2 +- .../pages-ol-sourcewmts-modules-L93.html | 4 +- .../pages-ol-sourcewmts-modules-default.html | 2 +- .../pages-ol-location-modules-default.html | 8 +- ...ages-ol-location-modules-dsfr-default.html | 8 +- .../pages-ol-measures-modules-default.html | 16 +- ...ages-ol-measures-modules-dsfr-default.html | 16 +- .../pages-ol-measures-modules-target.html | 16 +- ...ages-ol-mouseposition-modules-default.html | 10 +- ...ol-mouseposition-modules-dsfr-default.html | 6 +- ...position-modules-opts-editcoordinates.html | 6 +- ...ges-ol-reversegeocode-modules-default.html | 8 +- ...l-reversegeocode-modules-dsfr-default.html | 8 +- .../Route/pages-ol-route-modules-default.html | 10 +- .../pages-ol-route-modules-dsfr-default.html | 10 +- ...pages-ol-searchengine-modules-default.html | 4 +- ...-ol-searchengine-modules-dsfr-default.html | 4 +- ...pages-ol-searchengine-modules-options.html | 12 +- ...pages-ol-searchengine-modules-trigger.html | 4 +- .../packages/ol-sample-bundle-dsfr-layout.hbs | 26 + .../packages/ol-sample-bundle-layout.hbs | 26 + .../packages/partials-ol-bundle-dsfr-head.hbs | 10 + .../packages/partials-ol-bundle-head.hbs | 8 + .../partials-ol-modules-dsfr-head.hbs | 4 +- .../packages/partials-ol-modules-head.hbs | 4 +- .../Attribution/GeoportalAttribution.js | 6 +- src/packages/Controls/Control.js | 1 + src/packages/Controls/Drawing/Drawing.js | 6 +- src/packages/Controls/Editor/Filter.js | 8 + src/packages/Controls/Editor/Layer.js | 8 + src/packages/Controls/Editor/Legend.js | 8 + src/packages/Controls/Editor/Style.js | 9 + src/packages/Controls/Editor/Themes.js | 9 + .../Controls/ElevationPath/ElevationPath.js | 6 +- .../ElevationPath/ProfileElevationPathDOM.js | 7 - src/packages/Controls/Export/Export.js | 6 +- .../Controls/GetFeatureInfo/GetFeatureInfo.js | 6 +- src/packages/Controls/Isocurve/Isocurve.js | 6 +- .../Controls/LayerImport/LayerImport.js | 6 +- .../Controls/LayerSwitcher/LayerSwitcher.js | 6 +- .../LocationSelector/LocationSelector.js | 9 +- .../Controls/MousePosition/MousePosition.js | 6 +- .../Controls/ReverseGeocode/ReverseGeocode.js | 6 +- src/packages/Controls/Route/Route.js | 6 +- .../Controls/SearchEngine/SearchEngine.js | 6 +- src/packages/Formats/GPX.js | 6 +- src/packages/Formats/GeoJSON.js | 6 +- src/packages/Formats/KML.js | 6 +- src/packages/Formats/Styling.js | 1 + src/packages/Layers/LayerMapBox.js | 6 +- src/packages/Layers/LayerWMS.js | 6 +- src/packages/Layers/LayerWMTS.js | 6 +- src/packages/Utils/ColorUtils.js | 20 +- src/packages/Utils/Config.js | 3 +- src/packages/Utils/Draggable.js | 3 +- src/packages/Utils/GeocodeUtils.js | 11 + src/packages/Utils/Helper.js | 12 +- src/packages/Utils/LayerUtils.js | 12 +- src/packages/Utils/LoggerByDefault.js | 12 +- src/packages/Utils/MathUtils.js | 2 +- src/packages/Utils/Parser.js | 2 +- src/packages/Utils/ProxyUtils.js | 2 +- src/packages/Utils/Register.js | 2 +- src/packages/Utils/SearchEngineUtils.js | 3 +- src/packages/Utils/SelectorID.js | 3 +- src/packages/bundle.js | 62 +- build/types/tsconfig.json => tsconfig.json | 4 +- 517 files changed, 2493 insertions(+), 57748 deletions(-) create mode 100644 .github/workflow/build-site.yml create mode 100644 .github/workflow/release.yml create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTORS.md create mode 100644 DRAFT_CHANGELOG.md create mode 100644 LICENCE.md create mode 100644 README.md delete mode 100644 build/licences/licence-es6promise.txt delete mode 100644 build/licences/licence-fetch.tmpl create mode 100644 build/release/README.md create mode 100644 build/release/changelog.js delete mode 100644 build/release/geoportal-extensions-openlayers/.npmignore delete mode 100644 build/release/geoportal-extensions-openlayers/css/Dsfr.css delete mode 100644 build/release/geoportal-extensions-openlayers/css/Portail.css delete mode 100644 build/release/geoportal-extensions-openlayers/geoportal-extensions-openlayers-1.0.0-beta.15.tgz delete mode 100644 build/release/geoportal-extensions-openlayers/package.json delete mode 100644 build/release/geoportal-extensions-openlayers/src/index.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/index.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/index.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CRS/AutoLoadCRS.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CRS/AutoLoadCRS.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CRS/AutoLoadCRS.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CRS/CRS.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CRS/CRS.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CRS/CRS.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CRS/Proj4.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CRS/Proj4.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CRS/Proj4.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Attribution/DSFRattributionStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Attribution/GPFattribution.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Attribution/GPFattributionStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/DSFRdrawingStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/GPFdrawing.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/GPFdrawingStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/GPdrawingOpen.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/drawing-save.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/drawing-tools.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/modifier.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/DSFReditorStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/GPFeditor.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/GPFeditorStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/img/GPEditorLayerTools.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/img/GPEditorLayerTypeIcon.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/img/GPEditorLayerTypeIcon.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/DSFRelevationPathStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/GPFelevationPath.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/GPFelevationPathStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/img/GPshowElevationPath.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/img/altipath.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/DSFRexportStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/GPFexport.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/GPFexportStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/img/GPexportSave.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/DSFRgetFeatureInfoStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/GPFgetFeatureInfo.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/GPFgetFeatureInfoStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/img/GFI.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/img/GPactivateGfi.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/img/NoGFI.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/DSFRisochronStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/GPFisochron.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/GPFisochronStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/img/GPisochronCheck.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/img/GPisochronOpen.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/img/GPisochronOptions.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/img/isochrone.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/DSFRlayerImportStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/GPFlayerImport.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/GPFlayerImportStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/img/GPimportMapBoxReturn.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/img/GPimportOpen.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/img/layerimport.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/DSFRlayerSwitcherStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcher.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcherStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/img/GPlayerInfo.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/img/GPlayerInfoClose.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/img/GPlayerTools.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/img/GPopacitySlider.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/img/GPshowLayersList.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LocationSelector/DSFRlocationStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LocationSelector/GPFlocation.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LocationSelector/GPFlocationStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LocationSelector/img/GPlocationOptions.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LocationSelector/img/GProuteMarker.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/DSFRmeasureAreaStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/DSFRmeasureAzimuthStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/DSFRmeasureLengthStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/GPFmeasureArea.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/GPFmeasureAreaStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/GPFmeasureAzimuth.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/GPFmeasureAzimuthStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/GPFmeasureLength.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/GPFmeasureLengthStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/GPFmeasureToolTip.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/img/DSFRmeasuresOpen.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/img/GPmeasuresOpen.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/img/mesurer-distance.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/img/mesurer-surface.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/img/modifier-geometrie-old.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/DSFRmousePositionStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/GPFmousePosition.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/GPFmousePositionStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/img/GPmapCenter.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/img/GPmousePositionEditCoordinates.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/img/GPmousePositionOpen.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/img/position.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/DSFRreverseGeocodingStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/GPFreverseGeocoding.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/GPFreverseGeocodingStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/img/GPreverseGeocodingOpen.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/img/GPreverseGeocodingReturn.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/img/reversegeocode.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/DSFRrouteStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/GPFroute.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/GPFrouteStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/img/GProuteCheck.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/img/GProuteOpen.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/img/GProuteOptions.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/img/route.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/DSFRsearchEngineStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/GPFsearchEngine.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/GPFsearchEngineStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/GPsearchEngineClose.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/GPsearchEngineOpen.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/dsfr/coordonnees.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/dsfr/localiser.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/dsfr/search-line.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/DSFRtoolBoxMeasureStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/GPFtoolBoxMeasure.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/GPFtoolBoxMeasureStyle.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/img/GPtoolBoxMeasureOpen.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/DSFRgeneralWidget.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/GPFgeneralWidget.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/GPFwaiting.css delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPclose.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPinfo.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPinfo_secondary.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPshowMoreOptions.png delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/img/close-blue.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/img/close-emeraud.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/img/lightOrange.svg delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/CSS/img/waiting.gif delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/AttributionDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/AttributionDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/AttributionDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/GeoportalAttribution.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/GeoportalAttribution.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/GeoportalAttribution.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Control.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Control.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Control.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/Drawing.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/Drawing.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/Drawing.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/DrawingDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/DrawingDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/DrawingDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Editor.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Editor.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Editor.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/EditorDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/EditorDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/EditorDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Event.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Event.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Event.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Filter.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Filter.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Filter.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Group.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Group.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Group.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Layer.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Layer.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Layer.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Legend.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Legend.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Legend.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Search.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Search.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Search.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Style.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Style.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Style.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Themes.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Themes.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Themes.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPath.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPath.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPath.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPathDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPathDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPathDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ProfileElevationPathDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ProfileElevationPathDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ProfileElevationPathDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/Export.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/Export.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/Export.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/ExportDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/ExportDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/ExportDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfo.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfo.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfo.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/Isocurve.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/Isocurve.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/Isocurve.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/IsocurveDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/IsocurveDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/IsocurveDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImport.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImport.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImport.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImportDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImportDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImportDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcher.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcher.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcher.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelector.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelector.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelector.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelectorDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelectorDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelectorDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureArea.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureArea.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureArea.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAreaDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAreaDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAreaDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuth.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuth.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuth.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuthDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuthDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuthDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLength.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLength.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLength.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLengthDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLengthDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLengthDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/Measures.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/Measures.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/Measures.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePosition.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePosition.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePosition.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePositionDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePositionDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePositionDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocode.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocode.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocode.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/Route.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/Route.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/Route.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/RouteDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/RouteDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/RouteDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngine.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngine.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngine.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngineDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngineDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngineDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBox.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBox.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBox.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Gfi.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Gfi.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Gfi.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Interactions.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Interactions.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Interactions.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Markers.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Markers.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Markers.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/MarkersOther.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/MarkersOther.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/MarkersOther.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Formats/GPX.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Formats/GPX.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Formats/GPX.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Formats/GeoJSON.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Formats/GeoJSON.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Formats/GeoJSON.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Formats/KML.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Formats/KML.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Formats/KML.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Formats/Styling.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Formats/Styling.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Formats/Styling.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerMapBox.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerMapBox.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerMapBox.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMS.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMS.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMS.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMTS.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMTS.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMTS.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMS.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMS.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMS.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMTS.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMTS.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMTS.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/WFS.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/WFS.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Layers/WFS.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Services/Search.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Services/Search.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Services/Search.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Sources/WMTS.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Sources/WMTS.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Sources/WMTS.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/AutoLoadConfig.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/AutoLoadConfig.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/AutoLoadConfig.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/ColorUtils.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/ColorUtils.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/ColorUtils.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Config.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Config.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Config.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Draggable.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Draggable.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Draggable.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/GeocodeUtils.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/GeocodeUtils.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/GeocodeUtils.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Helper.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Helper.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Helper.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/LayerUtils.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/LayerUtils.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/LayerUtils.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/LoggerByDefault.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/LoggerByDefault.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/LoggerByDefault.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/MathUtils.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/MathUtils.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/MathUtils.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Parser.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Parser.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Parser.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/ProxyUtils.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/ProxyUtils.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/ProxyUtils.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Register.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Register.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/Register.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/SearchEngineUtils.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/SearchEngineUtils.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/SearchEngineUtils.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/SelectorID.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/SelectorID.d.ts.map delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/Utils/SelectorID.js delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/bundle.d.ts delete mode 100644 build/release/geoportal-extensions-openlayers/src/packages/bundle.d.ts.map create mode 100644 build/release/package.js create mode 100644 build/webpack/README.md create mode 100644 build/webpack/bundle.webpack.config.js create mode 100644 build/webpack/controls.webpack.config.js create mode 100644 build/webpack/crs.webpack.config.js create mode 100644 build/webpack/extend.banners.webpack.js create mode 100644 build/webpack/extend.base.webpack.js create mode 100644 build/webpack/extend.samples.webpack.js create mode 100644 build/webpack/extend.themes.webpack.js create mode 100644 build/webpack/formats.webpack.config.js create mode 100644 build/webpack/layers.webpack.config.js create mode 100644 build/webpack/modules.webpack.config.js delete mode 100644 build/webpack/webpack.config.modules.js delete mode 100644 build/webpack/webpack.config.packages.js delete mode 100644 doc/CHANGELOG.md create mode 100644 doc/capture-carte.png create mode 100644 doc/openlayers.svg rename samples-src/pages/tests/Default/{pages-ol-packages-default.html => pages-ol-bundle-default.html} (60%) rename samples-src/pages/tests/Default/{pages-ol-packages-dsfr-default.html => pages-ol-bundle-dsfr-default.html} (59%) rename samples-src/pages/tests/Editor/{pages-ol-editor-bundle-multi-editor.html => pages-ol-editor-modules-multi-editor.html} (97%) rename samples-src/pages/tests/Editor/{pages-ol-editor-bundle-options-icon.html => pages-ol-editor-modules-options-icon.html} (90%) rename samples-src/pages/tests/Editor/{pages-ol-editor-bundle-options-sort.html => pages-ol-editor-modules-options-sort.html} (95%) rename samples-src/pages/tests/Editor/{pages-ol-editor-bundle-options-themes.html => pages-ol-editor-modules-options-themes.html} (91%) rename samples-src/pages/tests/Editor/{pages-ol-editor-bundle-sprites.html => pages-ol-editor-modules-sprites.html} (95%) rename samples-src/pages/tests/Editor/{pages-ol-filters-bundle-test.html => pages-ol-filters-modules-test.html} (91%) rename samples-src/pages/tests/Editor/{pages-ol-layers-bundle-test.html => pages-ol-layers-modules-test.html} (97%) rename samples-src/pages/tests/Editor/{pages-ol-legends-bundle-test.html => pages-ol-legends-modules-test.html} (99%) rename samples-src/pages/tests/Editor/{pages-ol-styles-bundle-test.html => pages-ol-styles-modules-test.html} (95%) rename samples-src/pages/tests/Editor/{pages-ol-themes-bundle-test.html => pages-ol-themes-modules-test.html} (96%) create mode 100644 samples-src/templates/packages/ol-sample-bundle-dsfr-layout.hbs create mode 100644 samples-src/templates/packages/ol-sample-bundle-layout.hbs create mode 100644 samples-src/templates/partials/packages/partials-ol-bundle-dsfr-head.hbs create mode 100644 samples-src/templates/partials/packages/partials-ol-bundle-head.hbs rename build/types/tsconfig.json => tsconfig.json (88%) diff --git a/.github/workflow/build-site.yml b/.github/workflow/build-site.yml new file mode 100644 index 000000000..123a0fe68 --- /dev/null +++ b/.github/workflow/build-site.yml @@ -0,0 +1,75 @@ +name: Publication du site ... + +on: + push: + branches: + - main + +jobs: + + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Use nodejs + uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - name: Install dependencies + run: npm install + + - name: Build bundle + run: npm run build + + - name: Build package + run: npm run publish + + - name: Upload Binary artifacts + uses: actions/upload-artifact@v4 + with: + name: dist + path: dist + + - name: Upload JSDoc artifacts + uses: actions/upload-artifact@v4 + with: + name: jsdoc + path: jsdoc + + deploy: + runs-on: ubuntu-latest + needs: build + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + repository: IGNF/geoportal-extensions-openlayers + ref: gh-pages + + - name: Download Binary artifacts + uses: actions/download-artifact@v4 + with: + name: dist + path: . + + - name: Download JSDoc artifacts + uses: actions/download-artifact@v4 + with: + name: jsdoc + path: . + + - name: Build 404 + run: | + cp index.html 404.html + + - name: Publish + run: | + git config user.name github-actions + git config user.email github-actions@github.com + git add -A + git commit -m "build project gh-pages" + git push + diff --git a/.github/workflow/release.yml b/.github/workflow/release.yml new file mode 100644 index 000000000..4703bb445 --- /dev/null +++ b/.github/workflow/release.yml @@ -0,0 +1,141 @@ +name: Creation des releases + +on: + push: + tags: + - '*' + +jobs: + + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Use nodejs + uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - name: Install dependencies + run: npm install + + - name: Build bundle + run: npm run build + + - name: Build package + run: npm run publish + + - name: Create Zip Modules + run: | + zip --junk-paths modules dist/modules/* + + - name: Create Zip Bundle + run: | + zip --junk-paths bundle dist/bundle/* + + - name: Upload JSDoc artifacts + uses: actions/upload-artifact@v4 + with: + name: jsdoc + path: jsdoc + + - name: Upload Binary artifacts + uses: actions/upload-artifact@v4 + with: + name: dist + path: dist + + - name: Upload Bundle artifacts + uses: actions/upload-artifact@v4 + with: + name: bundle + path: bundle.zip + + - name: Upload Modules artifacts + uses: actions/upload-artifact@v4 + with: + name: modules + path: modules.zip + + deploy: + needs: build + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + repository: IGNF/geoportal-extensions-openlayers + ref: gh-pages + + - name: Download Binary artifacts + uses: actions/download-artifact@v4 + with: + name: dist + path: . + + - name: Download JSDoc artifacts + uses: actions/download-artifact@v4 + with: + name: jsdoc + path: . + + - name: Build 404 + run: | + cp index.html 404.html + + - name: Publish + run: | + git config user.name github-actions + git config user.email github-actions@github.com + git add -A + git commit -m "build project gh-pages" + git push + + # not yet implemented ! + release: + if: false # always skip job ! + + # not yet implemented ! + publish: + if: false # always skip job ! + + # not yet implemented ! + changelog: + if: false # always skip job ! + + # not yet implemented ! + samples: + if: false # always skip job ! + + # not yet implemented ! + rollback: + if: false # always skip job ! + # if: failure() + # if: github.event_name == 'push' && contains(github.ref, '/tags/') # Only for tags ! + needs: [release, publish, changelog] + runs-on: ubuntu-latest + steps: + - name: Get the tagname + id: get_tagname + run: echo ::set-output name=TAGNAME::$(echo ${GITHUB_REF##*/}) + + - name: Rollback jsdoc (gh-pages) + run: | + echo "not yet implemented !" + + - name: Rollback changelog (develop) + run: | + echo "not yet implemented !" + + - name: Rollback Release + if: job.create_release.steps.create_release.outputs.id != '' + uses: author/action-rollback@stable + with: + # Using a known release ID + id: ${{ job.create_release.steps.create_release.id }} + # Using a tag name + tag: ${{ steps.get_tagname.outputs.TAGNAME }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..03c7c23a0 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,12 @@ +# CHANGELOG EXTENSION GEOPORTAL + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + + + + +--- diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 000000000..d5c0cc803 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,19 @@ + +Le fichier [CONTRIBUTING.md](CONTRIBUTING.md) définit les règles et pratiques pour contribuer au projet geoportal-extensions. Les personnes suivantes ont contribué à ce projet : + +# Equipe de développement + +* [lboulanger](https://github.com/lboulanger) +* [lowzonenose](https://github.com/lowzonenose) +* [elias75015](https://github.com/elias75015) +* [pjjmunier](https://github.com/pjjmunier) +* [gcebelieu](https://github.com/gcebelieu) +* [azarz](https://github.com/azarz) + +# Autre contributeurs + +* [ojathelonius](https://github.com/ojathelonius) +* [vcoindet](https://github.com/vcoindet) +* [pprev94](https://github.com/pprev94) +* [sylvainpolletvillard](https://github.com/sylvainpolletvillard) +* [ThomasG77](https://github.com/ThomasG77) diff --git a/DRAFT_CHANGELOG.md b/DRAFT_CHANGELOG.md new file mode 100644 index 000000000..c39250003 --- /dev/null +++ b/DRAFT_CHANGELOG.md @@ -0,0 +1,26 @@ +# Extension Geoplateforme OpenLayers, 🔖 version __VERSION__ + +**__DATE__** +> Release Extension Geoplateforme openlayers + +## 🎉 Summary + +## 💥 Breaking changes + +## 📖 Changelog + +* ✨ [Added] + +* 🔨 [Changed] + +* 🔥 [Deprecated] + +* 🔥 [Removed] + +* 🐛 [Fixed] + +* 🔒 [Security] + +## 🚀 Unreleased + +--- diff --git a/LICENCE.md b/LICENCE.md new file mode 100644 index 000000000..f79c3a303 --- /dev/null +++ b/LICENCE.md @@ -0,0 +1,137 @@ + +# Geoplatform Extensions + +This software is released under the licence CeCILL-B (Free BSD compatible) + +You may obtain a copy of the License at : + + (english) + + (french) + +see + +Copyright (c) 2016 IGN + +## Third party code + +The Geoplatform Extensions include the following third party code : + +### Geoplatform resources access library + +This software is released under the licence CeCILL-B (Free BSD compatible) + +You may obtain a copy of the License at : + + (english) + + (french) + +see + +Copyright (c) 2016 IGN + +### Sortable - is a JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices + +Released under MIT LICENCE + +Copyright 2013-2016 Lebedev Konstantin + + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +_THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ + +### Proj4js -- Javascript reprojection library + +Authors: + +- Mike Adair madairATdmsolutions.ca +- Richard Greenwood richATgreenwoodmap.com +- Didier Richard didier.richardATign.fr +- Stephen Irons stephen.ironsATclear.net.nz +- Olivier Terral oterralATgmail.com +- Calvin Metcalf cmetcalfATappgeo.com + +Copyright (c) 2014, Mike Adair, Richard Greenwood, Didier Richard, Stephen Irons, Olivier Terral and Calvin Metcalf + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE._ + +### ol-mapbox-style -- Create OpenLayers maps from Mapbox Style objects + +Copyright 2016-present Boundless Spatial + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +_THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE._ + +### eventbusjs - Simple JavaScript class for managing events + +The MIT License (MIT) + +Copyright (c) 2014 Krasimir Tsonev + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +_THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE._ diff --git a/README.md b/README.md new file mode 100644 index 000000000..df0bc4c7f --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# Extensions Géoplateforme + +![image](doc/capture-carte.png) + +--- +[![Build](https://github.com/IGNF/geoportal-extensions-openlayers/actions/workflows/build.yml/badge.svg)](https://github.com/IGNF/geoportal-extensions-openlayers/actions/workflows/build.yml) +[![CeCILL License](https://img.shields.io/badge/licence-CeCILL--B-blue.svg)](https://raw.githubusercontent.com/IGNF/geoportal-extensions-openlayers/main/LICENCE.md) + +--- + +Ce projet a pour but de fournir des extensions facilitant l'accès aux ressources de la [Géoplateforme](https://www.geoportail.gouv.fr/) pour la bibliothèque cartographique [OpenLayers](https://openlayers.org/) (versions 8 et supérieures). + +Ces extensions proposent des classes et widgets utilisables en complément de la bibliothèque cartographique qu'elles étendent, permettant notamment : + +* d'afficher simplement les couches WMTS et WMS délivrées par la Géoplateforme ; + +* d'intégrer un widget de gestion d'empilement des couches ; + +* d'intégrer une barre de recherche utilisant le service de géocodage IGN ; + +* de faire des calculs d'itinéraires à partir du service de la Géoplateforme ; + +* de faire des calculs d'isochrones / isodistances à partir du service de la Géoplateforme ; + +* d'afficher l'altitude en un point de la carte à l'aide du service d'altimétrie de la Géoplateforme. + +* ... + +## OPENLAYERS + +Voir le détail des [fonctionnalités proposées par l'extension Géoplateforme pour OpenLayers](doc/README.md) diff --git a/build/jsdoc/README.md b/build/jsdoc/README.md index bc742ee22..272106aa2 100644 --- a/build/jsdoc/README.md +++ b/build/jsdoc/README.md @@ -11,8 +11,8 @@ This extension is not standalone and has to be used **together with OpenLayers** - - + + ``` NB : to have complete access to this extension functionnalities, you need to freely provide a geoportal access key among the one available here : . Use it either when loading extension script (using the data-key attribute) or by conditinning their use to the onSuccess callback function of a Gp.Services.GetConfig() call with that key. Otherwhise some functionalities may not work as announced. diff --git a/build/jsdoc/jaguarjs-jsdoc/tmpl/layout.tmpl b/build/jsdoc/jaguarjs-jsdoc/tmpl/layout.tmpl index d02ab1df1..9dc2ea934 100644 --- a/build/jsdoc/jaguarjs-jsdoc/tmpl/layout.tmpl +++ b/build/jsdoc/jaguarjs-jsdoc/tmpl/layout.tmpl @@ -66,7 +66,7 @@

-

API Reference

+

diff --git a/build/jsdoc/jsdoc.json b/build/jsdoc/jsdoc.json index 6b6ef462d..60475f37b 100644 --- a/build/jsdoc/jsdoc.json +++ b/build/jsdoc/jsdoc.json @@ -11,13 +11,13 @@ }, "templates": { "cleverLinks" : false, - "applicationName" : "Geoportal Extension for OpenLayers", + "applicationName" : "Geoportal Extension for OpenLayers
API Reference", "monospaceLinks" : false, "dateFormat" : "ddd MMM Do YYYY", "outputSourceFiles" : true, "outputSourcePath" : true, "systemName" : "Geoportal Extension for OpenLayers", - "footer" : "API Reference", + "footer" : "", "copyright" : "Geoportail - Copyright (c) IGN, released under the CECILL-B license", "navType" : "inline", "theme" : "darkly", diff --git a/build/licences/licence-es6promise.txt b/build/licences/licence-es6promise.txt deleted file mode 100644 index f646a89e0..000000000 --- a/build/licences/licence-es6promise.txt +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * @overview es6-promise - a tiny implementation of Promises/A+. - * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE - * @version v4.2.4 - */ diff --git a/build/licences/licence-fetch.tmpl b/build/licences/licence-fetch.tmpl deleted file mode 100644 index 738ee1def..000000000 --- a/build/licences/licence-fetch.tmpl +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * @overview Fetch - window.fetch polyfill - * @copyright Copyright (c) 2014-2016 GitHub, Inc. - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/github/fetch/master/LICENSE - * @version {__VERSION__} - */ diff --git a/build/licences/licence-sortablejs.tmpl b/build/licences/licence-sortablejs.tmpl index 47106bb33..ee7827e44 100644 --- a/build/licences/licence-sortablejs.tmpl +++ b/build/licences/licence-sortablejs.tmpl @@ -1,31 +1,10 @@ /*! - * Sortable -- JavaScript library for reorderable drag-and-drop lists on modern + * @overview Sortable -- JavaScript library for reorderable drag-and-drop lists on modern * browsers and touch devices. No jQuery required. Supports Meteor, AngularJS, * React, Polymer, Vue, Knockout and any CSS library, e.g. Bootstrap. * - * Released under MIT LICENSE - * - * Copyright Lebedev Konstantin - * https://github.com/SortableJS/Sortable - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * @copyright Copyright (c) 2019 All contributors to Sortable + * https://github.com/SortableJS/Sortable + * @license Licensed under MIT license * @version {__VERSION__} */ diff --git a/build/release/README.md b/build/release/README.md new file mode 100644 index 000000000..2aaf1cfff --- /dev/null +++ b/build/release/README.md @@ -0,0 +1,50 @@ +# Information + +> construction du package des sources + +## remise à plat des paths + +```js +import Drawing from "geoportal-extensions-openlayers/controls/Drawing" +import { + Drawing, + Route +} from "geoportal-extensions-openlayers/controls" + +import LayerWMTS from "geoportal-extensions-openlayers/layers/LayerWMTS"; +import { + LayerWMTS as GeoportalWMTS, + LayerWMS as GeoportalWMS +} from "geoportal-extensions-openlayers/layers"; +``` + +utilisation standard : + +```js + import { + version, + date, + LoggerUtils as Logger, + LayerWMTS as GeoportalWMTS, + LayerWMS as GeoportalWMS, + Drawing, + Isocurve, + Route, + LayerImport, + GeoportalAttribution, + ElevationPath, + MeasureArea, + MeasureAzimuth, + MeasureLength, + LayerSwitcher, + MousePosition as GeoportalMousePosition, + ReverseGeocode, + SearchEngine, + GetFeatureInfo + } from "geoportal-extensions-openlayers"; +``` + +## creation du changelog + +> workflow de creation / mise à jour du changelog lors d'une publication d'une release + diff --git a/build/release/changelog.js b/build/release/changelog.js new file mode 100644 index 000000000..b516aaa4f --- /dev/null +++ b/build/release/changelog.js @@ -0,0 +1,2 @@ +// TODO +// mise à jour des changelog \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/.npmignore b/build/release/geoportal-extensions-openlayers/.npmignore deleted file mode 100644 index aa1ec1ea0..000000000 --- a/build/release/geoportal-extensions-openlayers/.npmignore +++ /dev/null @@ -1 +0,0 @@ -*.tgz diff --git a/build/release/geoportal-extensions-openlayers/css/Dsfr.css b/build/release/geoportal-extensions-openlayers/css/Dsfr.css deleted file mode 100644 index 1fab48ea5..000000000 --- a/build/release/geoportal-extensions-openlayers/css/Dsfr.css +++ /dev/null @@ -1,88 +0,0 @@ -/*! - * @brief geoportal-extensions-openlayers - * - * This software is released under the licence CeCILL-B (Free BSD compatible) - * @see http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt - * @see http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt - * @see http://www.cecill.info/ - * - * @copyright copyright (c) IGN - * @license CeCILL-B - * @author IGN - * @version 3.0.0 - * @date 01/02/2024 - * - */ - -/*! - * @overview ol-mapbox-style - Use Mapbox Style objects with OpenLayers - * @copyright Copyright (c) 2016 openlayers - * @license BSD 2-Clause "Simplified" License - * See https://raw.githubusercontent.com/openlayers/ol-mapbox-style/master/LICENSE - * @version 12.2.0 - */ - -/*! - * Sortable -- JavaScript library for reorderable drag-and-drop lists on modern - * browsers and touch devices. No jQuery required. Supports Meteor, AngularJS, - * React, Polymer, Vue, Knockout and any CSS library, e.g. Bootstrap. - * - * Released under MIT LICENSE - * - * Copyright Lebedev Konstantin - * https://github.com/SortableJS/Sortable - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * @version 1.15.2 - */ - -/*! - * @overview EventBus - Simple JavaScript class for managing events in JavaScript - * @copyright Copyright (c) 2014 Krasimir Tsonev - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/krasimir/EventBus/master/LICENSE - * @version 0.2.0 - */ - -/*! - * @overview es6-promise - a tiny implementation of Promises/A+. - * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE - * @version v4.2.4 - */ - -/*! - * @overview Proj4js - Javascript reprojection library. - * - * @authors - * - Mike Adair madairATdmsolutions.ca - * - Richard Greenwood richATgreenwoodmap.com - * - Didier Richard didier.richardATign.fr - * - Stephen Irons stephen.ironsATclear.net.nz - * - Olivier Terral oterralATgmail.com - * - Calvin Metcalf cmetcalfATappgeo.com - * - * @copyright Copyright (c) 2014, Mike Adair, Richard Greenwood, Didier Richard, Stephen Irons, Olivier Terral and Calvin Metcalf - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/proj4js/proj4js/master/LICENSE.md - * @version 2.10.0 - */.gpf-widget{padding:2px;pointer-events:auto;position:absolute}.gpf-widget-button{width:40px}.gpf-panel{background-color:unset;position:relative;width:fit-content}.gpf-panel--hidden{display:none}.gpf-panel__body{overflow:unset}.gpf-panel__title{text-align:center}.gpf-panel__footer{background-color:transparent;margin-top:0;padding:0}.gpf-panel__content{margin-bottom:unset;padding:unset}.gpf-panel--close,.gpf-panel--info,.gpf-panel--reduce{cursor:pointer;position:relative}.gpf-flex{align-items:center;flex-direction:row}.gpf-flex,.gpf-flex-column{display:flex;justify-content:space-evenly}.gpf-flex-column{flex-direction:column}.gpf-flex-padding{padding:5px}.gpf-hidden{display:none;opacity:0;visibility:hidden}.gpf-visible{display:block;opacity:100%;visibility:visible}.gpf-waiting{background-color:hsla(0,0%,100%,.9);border-radius:4px;bottom:0;font-size:1.5em;font-weight:700;height:inherit;left:0;overflow:hidden;position:absolute;right:0;top:80px}.gpf-waiting--hidden{display:none}.gpf-waiting--visible{display:-webkit-flex;display:-ms-flexbox;display:-webkit-box;display:flex}.gpf-waiting_info{margin:auto}.gpf-btn-icon{width:inherit}.gpf-btn-icon-reset{background-image:url(data:image/png;base64,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IHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDo4ZDc5MTIyYy0xNDNiLTQwMDItOGExOS02ODEyYTA4ZmRiMzgiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6N2FlNWZmMzEtNzVlYS00NWQ0LWI5MzktOWVkYmE3N2M0YjQ3IgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NDU3NDBkYTQtYmZlMS00YWFlLThjMDEtZDliZDVhOWY0ZTBiIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iTGludXgiCiAgIEdJTVA6VGltZVN0YW1wPSIxNzEzNTM5MDc3OTM4NDkxIgogICBHSU1QOlZlcnNpb249IjIuMTAuMzAiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiCiAgIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ZjJmYTMwMGMtZWRlMy00YWNhLTkyODQtYmRiMTI4NDFiMWIxIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKExpbnV4KSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyNC0wNC0xOVQxNzowNDozNyswMjowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz69OJaNAAAABmJLR0QAAAAAAJF+SxitAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH6AQTDwQlpds7gAAAAYdJREFUWMPtl11OwkAURs8tK2AZvrknNVJB3EK3wE/9gz355jZ4N6GfDxSc1DJMaUs0mfPU0Ena03uZ7w5EIpFIJBKJ/CUk3Ul6k5R41pikhaRJd0+eCWYiyxLP29lhXQAWIgu8AgmwBu7NrKjKAgtgDAiYmtmyvaxDthmQZcVv2XnltyevUxLw5Gtn3S2wLAVd2byU3X/Eq87bLBtud4I+2dOECE8At1op8C4pcSqbOvdXwGN7w2nNu82LXXsfkc02g9Yt7VRxXsrvWQNfwENFdlRt+Ra7R3gVa1v+TGGPNP3JNpAOlG0kfEK6djO7iHQD2dD/cMhHMv4JScPqLpzd2OUG8OZ0by2dDbf+nD5D+IjsqowjnMjqWDpw02ognbSQHZXxs+xH2hc9NZEVKB0yaeWV6HkBxmamyuDhZvGzmY07nbQO2WzyV7/9pPUBFE5lJ3tZgPJ67FRawGf3k9Zm8CMLu+tp0svOJimVlLsj5ZHDQy4p7fzwgKyrw0MkEolEIpHIxfgGwh3Z0ws3xlMAAAAASUVORK5CYII=)}.gpf-btn-icon-info{height:40px;width:40px}.gpf-input{padding-left:5px}.gpf-panel__advancedlist,.gpf-panel__list{background-color:#fff;border:1px solid #999;max-height:140px;overflow-y:hidden;position:absolute;width:inherit;z-index:2}.gpf-panel__advancedlist{border-top:none;font-size:.9em;width:calc(100% - 28px)}.gpf-panel__items:hover{background-color:#cedbef;color:#000}.gpf-panel__items{color:#5e5e5e;cursor:pointer;font-size:1em;height:28px;line-height:16px;overflow:hidden;padding:6px 10px;text-overflow:ellipsis;white-space:nowrap;width:100%}.gpf-panel:after,.gpf-panel:before{height:unset}:root{--size-per-row:50px}.position-container-bottom-left,.position-container-bottom-right,.position-container-top-left,.position-container-top-right{border-style:solid;display:flex;flex-direction:column;justify-content:center;min-height:var(--size-per-row);min-width:var(--size-per-row);padding:5px;position:absolute}.position-container-top-left,.position-container-top-right{top:0}.position-container-top-left{float:left;left:0}.position-container-top-right{float:right;right:0}.position-container-bottom-left,.position-container-bottom-right{bottom:0}.position-container-bottom-right{float:right;right:0}.position-container-bottom-left{float:left;left:0}.gp-feature-info-div{background-color:#fff;bottom:17px;box-shadow:0 0 5px #000;font-size:.75em;max-width:calc(100vw - 80px);padding:10px;position:relative}.gp-feature-info-div:before{border-left:14px solid transparent;border-right:14px solid transparent;border-top:15px solid #fff;bottom:-15px;content:"";left:50%;margin-left:-14px;position:absolute}.gp-feature-info-div .closer{background-color:#fff;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+PGRlZnM+PGNsaXBQYXRoIGlkPSJhIj48cGF0aCBkPSJNMCA4NDEuOWg1OTUuM1YwSDB6Ii8+PC9jbGlwUGF0aD48L2RlZnM+PGcgZmlsbD0iIzAwMDA5MSIgY2xpcC1wYXRoPSJ1cmwoI2EpIiB0cmFuc2Zvcm09Im1hdHJpeCguMDIzNTIgMCAwIC0uMDIzNTIgMSAxOCkiPjxwYXRoIGQ9Im0zNjguNCA0MjAuOSAyMTIuMiAyMTIuMmMxOS41NCAxOS41NCAxOS41NCA1MS4yMSAwIDcwLjc1cy01MS4yMSAxOS41NC03MC43NSAwbC0yMTIuMi0yMTIuMy0yMTIuMiAyMTIuM2MtMTkuNTQgMTkuNTQtNTEuMjEgMTkuNTQtNzAuNzUgMC0xOS41My0xOS41NC0xOS41My01MS4yMSAwLTcwLjc1TDIyNyA0MjAuOSAxNC44IDIwOC43Yy0xOS41My0xOS41NC0xOS41My01MS4yMSAwLTcwLjc1IDE5LjU0LTE5LjU0IDUxLjIxLTE5LjU0IDcwLjc1IDBsMjEyLjIgMjEyLjIgMjEyLjItMjEyLjJjMTkuNTMtMTkuNTQgNTEuMjEtMTkuNTQgNzAuNzUgMHMxOS41NCA1MS4yMSAwIDcwLjc1TDM2OC41IDQyMC45eiIvPjwvZz48L3N2Zz4=);background-position:50%;background-repeat:no-repeat;background-size:14px 14px;border:none;border-bottom-right-radius:10px;border-top-right-radius:10px;cursor:pointer;display:block;height:30px;position:absolute;right:0;top:0;width:30px}.gp-features-content-div{max-height:340px;max-width:420px;min-width:260px;overflow:auto}.gp-features-content-div h5,.gp-features-content-div h6,.gp-features-content-div p,.gp-features-content-div ul{margin:0}.gp-features-content-div ul{list-style-type:none;padding:0}.geoportail-popup-content h5,.geoportail-popup-content h6,.geoportail-popup-content p,.gp-att-description-div,.gp-att-name-div,.gp-att-others-div{padding:0 10px}.geoportail-popup-content h5:not(:last-child),.geoportail-popup-content h6:not(:last-child),.geoportail-popup-content p:not(:last-child),.gp-att-description-div:not(:last-child),.gp-att-others-div:not(:last-child){margin-bottom:15px}.geoportail-popup-content h5:last-child,.geoportail-popup-content h6:last-child,.geoportail-popup-content p:last-child,.gp-att-description-div:last-child,.gp-att-name-div,.gp-att-others-div:last-child{margin-bottom:10px}.geoportail-popup-content h5:first-child,.geoportail-popup-content h6:first-child,.geoportail-popup-content p:first-child,.gp-att-description-div:first-child,.gp-att-name-div:first-child,.gp-att-others-div:first-child{margin-top:10px}.gp-att-name-div,.gp-features-content-div h5{color:#0b6ba7;font-size:1.2em;font-weight:700;padding-right:35px;text-transform:uppercase}.gp-features-content-div h6{font-size:1.1em}.gp-att-description-div:not(:last-child),.gp-att-others-div:not(:last-child){border-bottom:1px dotted #666;padding-bottom:10px}.gpf-btn-icon-drawing{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNSIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE1LjA0IDkuNDM3IDEzLjcwNCA4LjFsLTguODExIDguODF2MS4zMzlINi4yM3pNMTYuMzc4IDguMWwxLjMzOC0xLjMzOC0xLjMzOC0xLjMzN0wxNS4wNCA2Ljc2ek03LjAxNCAyMC4xNEgzdi00LjAxM2wxMi43MS0xMi43MWEuOTQ2Ljk0NiAwIDAgMSAxLjMzNyAwbDIuNjc2IDIuNjc2Yy4zNy4zNy4zNy45NjkgMCAxLjMzOHoiLz48L3N2Zz4=)}.gpf-btn-icon-drawing,.gpf-btn-icon-elevation{background-position:50%;background-repeat:no-repeat;background-size:auto auto}.gpf-btn-icon-elevation{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIxNy41MyIgaGVpZ2h0PSIxMS42IiB2aWV3Qm94PSIwIDAgNC42MzggMy4wNjkiPjxnIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjM5NyI+PHBhdGggZD0iTTEwMi4zNTQgMzkxLjEzOWMuNTMgMCAuNTMtLjU0NSAxLjA2LS41NDVzLjUzLjU0NSAxLjA2LjU0NS41My0uNTQ1IDEuMDYtLjU0NWMuNTMyIDAgLjUzLjU0NSAxLjA2Mi41NDVNMTAyLjM1NCAzOTIuMjAyYy41MyAwIC41My0uNTQ1IDEuMDYtLjU0NXMuNTMuNTQ1IDEuMDYuNTQ1LjUzLS41NDUgMS4wNi0uNTQ1Yy41MzIgMCAuNTMuNTQ1IDEuMDYyLjU0NU0xMDIuMzU0IDM5My4yNjZjLjUzIDAgLjUzLS41NDUgMS4wNi0uNTQ1cy41My41NDUgMS4wNi41NDUuNTMtLjU0NSAxLjA2LS41NDVjLjUzMiAwIC41My41NDUgMS4wNjIuNTQ1IiBzdHlsZT0iZmlsbDpub25lIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTAyLjE1NiAtMzkwLjM5NSkiLz48L2c+PC9zdmc+)}#profileElevationByDefaultSvg{height:80%}[id^=GPelevationPathPanelInfo]{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgdmlld0JveD0iMCAwIDUuMjkyIDUuMjkyIj48ZyBzdHlsZT0ic3Ryb2tlOiMwMDAxOTE7c3Ryb2tlLW9wYWNpdHk6MSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwMS44MjUgLTQwLjAyKSI+PGNpcmNsZSBjeD0iMTA0LjQ3MSIgY3k9IjQyLjY2NyIgcj0iMi40NDciIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4zOTciIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDAxOTE7c3Ryb2tlLW9wYWNpdHk6MSIvPjwvZz48cGF0aCBmaWxsPSIjMDAwMDkxIiBkPSJNMTA0Ljk3NiA0My45OWgtMS4wMzR2LS4xNzZoLjA1NWEuMzMuMzMgMCAwIDAgLjE2MS0uMDMuMTMuMTMgMCAwIDAgLjA2Mi0uMDg2IDEgMSAwIDAgMCAuMDEyLS4xNjJ2LS41NjVhLjcuNyAwIDAgMC0uMDE1LS4xNjhxLS4wMTQtLjA1LS4wNzQtLjA3M2EuNy43IDAgMCAwLS4yMDEtLjAyNXYtLjE3NWwuNzgtLjE2NHYxLjE3cTAgLjE2LjA0LjIyLjA0MS4wNTkuMjE0LjA1OXptLS4yMTUtMi4zNjlhLjI3LjI3IDAgMCAxLS4wOC4xOTYuMjcuMjcgMCAwIDEtLjE5Ni4wOC4yNy4yNyAwIDAgMS0uMTk1LS4wODIuMjcyLjI3MiAwIDAgMS0uMDAxLS4zOS4yNy4yNyAwIDAgMSAuMTk2LS4wODFxLjExNiAwIC4xOTcuMDguMDguMDguMDguMTk4eiIgc3R5bGU9ImZpbGw6IzAwMDE5MTtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6LjI2NDU4MyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwMS44MjUgLTQwLjAyKSIvPjwvc3ZnPg==);background-position:50%;background-repeat:no-repeat}.gpf-btn-icon-getfeatureinfo{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgdmlld0JveD0iMCAwIDUuMjkyIDUuMjkyIj48Y2lyY2xlIGN4PSIxMDQuNDcxIiBjeT0iNDIuNjY3IiByPSIyLjQ0NyIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjM5NyIgc3R5bGU9ImZpbGw6bm9uZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwMS44MjUgLTQwLjAyKSIvPjxwYXRoIGZpbGw9IiMwMDAwOTEiIGQ9Ik0xMDQuOTc2IDQzLjk5aC0xLjAzNHYtLjE3NmguMDU1YS4zMy4zMyAwIDAgMCAuMTYxLS4wMy4xMy4xMyAwIDAgMCAuMDYyLS4wODYgMSAxIDAgMCAwIC4wMTItLjE2MnYtLjU2NWEuNy43IDAgMCAwLS4wMTUtLjE2OHEtLjAxNC0uMDUtLjA3NC0uMDczYS43LjcgMCAwIDAtLjIwMS0uMDI1di0uMTc1bC43OC0uMTY0djEuMTdxMCAuMTYuMDQuMjIuMDQxLjA1OS4yMTQuMDU5em0tLjIxNS0yLjM2OWEuMjcuMjcgMCAwIDEtLjA4LjE5Ni4yNy4yNyAwIDAgMS0uMTk2LjA4LjI3LjI3IDAgMCAxLS4xOTUtLjA4Mi4yNzIuMjcyIDAgMCAxLS4wMDEtLjM5LjI3LjI3IDAgMCAxIC4xOTYtLjA4MXEuMTE2IDAgLjE5Ny4wOC4wOC4wOC4wOC4xOTh6IiBzdHlsZT0iZmlsbDojZmZmO3N0cm9rZS13aWR0aDouMjY0NTgzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTAxLjgyNSAtNDAuMDIpIi8+PC9zdmc+);background-position:50%;background-repeat:no-repeat;background-size:auto auto}button[id^=GPgetFeatureInfoPicto-][aria-pressed=true]{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIyMC45ODciIGhlaWdodD0iMjAuOTg3IiB2aWV3Qm94PSIwIDAgNS41NTMgNS41NTMiPjxjaXJjbGUgY3g9IjEwNC40NzEiIGN5PSI0Mi42NjciIHI9IjIuNDQ3IiBmaWxsPSIjZmZmIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMzk3IiBzdHlsZT0iZmlsbDpub25lIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTAxLjY5NCAtMzkuODkpIi8+PHBhdGggZmlsbD0iIzAwMDA5MSIgZD0iTTEwNC45NzYgNDMuOTloLTEuMDM0di0uMTc2aC4wNTVhLjMzLjMzIDAgMCAwIC4xNjEtLjAzLjEzLjEzIDAgMCAwIC4wNjItLjA4NiAxIDEgMCAwIDAgLjAxMi0uMTYydi0uNTY1YS43LjcgMCAwIDAtLjAxNS0uMTY4cS0uMDE0LS4wNS0uMDc0LS4wNzNhLjcuNyAwIDAgMC0uMjAxLS4wMjV2LS4xNzVsLjc4LS4xNjR2MS4xN3EwIC4xNi4wNC4yMi4wNDEuMDU5LjIxNC4wNTl6bS0uMjE1LTIuMzY5YS4yNy4yNyAwIDAgMS0uMDguMTk2LjI3LjI3IDAgMCAxLS4xOTYuMDguMjcuMjcgMCAwIDEtLjE5NS0uMDgyLjI3Mi4yNzIgMCAwIDEtLjAwMS0uMzkuMjcuMjcgMCAwIDEgLjE5Ni0uMDgxcS4xMTYgMCAuMTk3LjA4LjA4LjA4LjA4LjE5OHoiIHN0eWxlPSJmaWxsOiNmZmY7c3Ryb2tlLXdpZHRoOi4yNjQ1ODMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMDEuNjk0IC0zOS44OSkiLz48cGF0aCBkPSJtODkuNDc1IDQwLjA2NyA1LjIgNS4yIiBzdHlsZT0iZmlsbDpub25lO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTojZmZmO3N0cm9rZS13aWR0aDouNTtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTg5LjI5OSAtMzkuODkpIi8+PC9zdmc+)}.gpf-btn-icon-isocurve,button[id^=GPgetFeatureInfoPicto-][aria-pressed=true]{background-position:50%;background-repeat:no-repeat;background-size:auto auto}.gpf-btn-icon-isocurve{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIxNC45MTIiIGhlaWdodD0iMTguMDAzIiB2aWV3Qm94PSIwIDAgMy45NDUgNC43NjMiPjxwYXRoIGZpbGw9IiMwMDAwOTEiIGQ9Ik0xMDUuNjc2IDIyMy4yNmExLjUzNCAxLjUzNCAwIDEgMC0yLjE3IDBsMS4wODUgMS4wODV6bS0xLjA4NSAxLjcwNS0xLjM5NC0xLjM5NWExLjk3NCAxLjk3NCAwIDEgMSAyLjc5IDB6bS4yMi0yLjc5aC44NzZ2LjQzN2gtMS4zMTV2LTEuNTM0aC40Mzl6IiBzdHlsZT0iZmlsbDojZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDouMjY0NTgzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTAyLjYxOSAtMjIwLjIwMSkiLz48L3N2Zz4=)}.gpf-flex-isocurve{justify-content:unset}.gpf-btn-icon-isocurve-reset{background-position:-29px}.gpf-btn-icon-import{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIxOCIgaGVpZ2h0PSIyMCIgdmlld0JveD0iMCAwIDQuNzYyIDUuMjkyIj48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTA1LjI2NSAzMDUuMTMzaC0yLjY0NnY0LjIzNGgzLjcwNHYtMy4xNzVoLTEuMDU4em0tMy4xNzUtLjI2N2MwLS4xNDUuMTE4LS4yNjIuMjY0LS4yNjJoMy4xNzVsMS4zMjMgMS4zMjN2My43MDJhLjI2NS4yNjUgMCAwIDEtLjI2My4yNjdoLTQuMjM3YS4yNjUuMjY1IDAgMCAxLS4yNjItLjI2MnptMi42NDUgMi4zODR2MS4wNThoLS41Mjl2LTEuMDU4aC0uNzkzbDEuMDU4LTEuMDU4IDEuMDU4IDEuMDU4eiIgc3R5bGU9InN0cm9rZS13aWR0aDouMjY0NTgzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTAyLjA5IC0zMDQuNjA0KSIvPjwvc3ZnPg==);background-position:50%;background-repeat:no-repeat;background-size:auto auto}.gpf-btn-icon-return{background-color:#366291;background-position:3px}.gpf-btn-icon-pointer{background-image:url(data:image/png;base64,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);background-position:1px;background-repeat:no-repeat}.gpf-btn-icon-remove{background-position:-82px}.gpf-btn-icon-add,.gpf-btn-icon-remove{background-image:url(data:image/png;base64,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);background-repeat:no-repeat}.gpf-btn-icon-add{background-position:-54px}.gpf-btn-icon-area{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE3Ljk5MiAxNi4zOTJhLjc1Ljc1IDAgMCAwLTEuMDYgMS4wNnptMS40NzcgMy41OTguNTMuNTMgMS4wNjItMS4wNi0uNTMtLjUzem0tMi41MzctMi41MzggMi41MzggMi41MzggMS4wNi0xLjA2LTIuNTM4LTIuNTM4eiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0yMC41MyAxOS45OS41My0uNTNMMjAgMTguNGwtLjUzLjUzem0tMy41OTggMS40NzdhLjc1Ljc1IDAgMCAwIDEuMDYgMS4wNjF6bTIuNTM4LTIuNTM3LTIuNTM4IDIuNTM3IDEuMDYgMS4wNjEgMi41MzgtMi41Mzh6TTEuNDcgNS42NzhhLjc1Ljc1IDAgMCAwIDEuMDYgMS4wNnpNNC43MzkgNC41M2wuNTMtLjUzLTEuMDYtMS4wNi0uNTMxLjUzek0yLjUzIDYuNzQgNC43NCA0LjUzIDMuNjc4IDMuNDcgMS40NyA1LjY3OHoiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJtNC43MzkgMy40Ny0uNTMtLjUzTDMuMTQ4IDRsLjUzLjUzMXptMS4xNDcgMy4yN2EuNzUuNzUgMCAwIDAgMS4wNjEtMS4wNjF6TTMuNjc4IDQuNTMgNS44ODYgNi43NGwxLjA2MS0xLjA2MUw0Ljc0IDMuNDd6Ii8+PHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIxLjUiIGQ9Ik00LjIwOSA1LjEwNXYxMS44OGMwIDEuMzkzLjk0NiAyLjQ3NyAyLjE2MSAyLjQ3N0gxOS4xMiIvPjxwYXRoIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIGQ9Ik0xOS42NyAxMi44MzZWNi4wNjVjMC0xLjE2Mi0uNzg3LTIuMDY1LTEuOC0yLjA2NWgtNy4wMzUiLz48cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgZD0ibTE2LjM1NyAxMS45ODQtNC4xMjMgNC4wODZNMTYuMjc3IDcuMzkzIDcuNTIyIDE2LjA3TTExLjY0NSA3LjMxNCA3LjUyMiAxMS40Ii8+PC9zdmc+)}.gpf-btn-icon-area,.gpf-btn-icon-length{background-position:50%;background-repeat:no-repeat;background-size:auto auto}.gpf-btn-icon-length{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMSIgaGVpZ2h0PSIyMSIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTYuODk0IDYuMTg3YS41LjUgMCAwIDAgLjcwNy43MDd6bTEuNDE0LTEuNDE0TDYuODk0IDYuMTg3bC43MDcuNzA3TDkuMDE1IDUuNDh6TTguOTc0IDguMjY2YS41LjUgMCAxIDAgLjcwNy43MDh6bTEuNDE0LTEuNDE0TDguOTc0IDguMjY2bC43MDcuNzA4IDEuNDE0LTEuNDE1ek0xMS4wNTMgMTAuMzQ2YS41LjUgMCAxIDAgLjcwNy43MDd6bTEuNDE0LTEuNDE0LTEuNDE0IDEuNDE0LjcwNy43MDcgMS40MTUtMS40MTR6TTEzLjEzMyAxMi40MjZhLjUuNSAwIDEgMCAuNzA3LjcwN3ptMS40MTQtMS40MTQtMS40MTQgMS40MTQuNzA3LjcwNyAxLjQxNC0xLjQxNHoiLz48cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBkPSJtMTYuOTggMTMuNDQ1LTEuNDE0IDEuNDE0Ii8+PHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iMS41IiBkPSJtNS41MzYgMiAxNC4xNDIgMTQuMTQyLTMuNTM2IDMuNTM2TDIgNS41MzZ6Ii8+PC9zdmc+)}.gpf-btn-icon-azimuth{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNMy4wNzYgMTkuNDU4SDE5LjA0Ii8+PHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2UtZGFzaGFycmF5PSIxIDQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik0xOS44MjUgMTkuNTA1IDguNTIgNi4xMjkiLz48cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik04LjQ1IDYuMDc2IDIuOTk4IDE5LjUxIi8+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTQuNTQ4IDIxLjA2YTIuMTc3IDIuMTc3IDAgMSAwLTIuOTQ1LTMuMjA1IDIuMTc3IDIuMTc3IDAgMCAwIDIuOTQ1IDMuMjA2TTkuOTIzIDcuNjc5YTIuMTc3IDIuMTc3IDAgMSAwLTIuOTQ2LTMuMjA2IDIuMTc3IDIuMTc3IDAgMCAwIDIuOTQ2IDMuMjA2TTIxLjM5NyAyMS4wNmEyLjE3NyAyLjE3NyAwIDEgMC0yLjk0NS0zLjIwNSAyLjE3NyAyLjE3NyAwIDAgMCAyLjk0NSAzLjIwNiIvPjwvc3ZnPg==)}.gpf-btn-icon-azimuth,.gpf-btn-icon-position{background-position:50%;background-repeat:no-repeat;background-size:auto auto}.gpf-btn-icon-position{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIxOS45OTgiIGhlaWdodD0iMTguNjY1IiB2aWV3Qm94PSIwIDAgNS4yOTEgNC45MzgiPjxwYXRoIGZpbGw9IiMwMDAwOTEiIGQ9Ik0xMDQuMjYgMTI1LjkzMWgtLjI3OWMtLjEzIDAtLjE4Mi0uMDkzLS4xMi0uMjA0cS4yMzYtLjQxNi40NzktLjgyOGMuMDYyLS4xMDYuMTY3LS4xMDYuMjI5LjAwM3EuMjM1LjQwNC40NjcuODA3Yy4wNzcuMTM1LjAyNC4yMi0uMTMzLjIyMmgtLjI1N2MwIC4wMzctLjAwMy4wNjEtLjAwMy4wOXYxLjYyNWMwIC4wMzcuMDIyLjA5LjA1LjExMXEuNzk3LjU2NCAxLjYwMiAxLjEyNWwuMDI3LjAxMy4xNjctLjIyYy4wODctLjExMS4xODktLjEwMy4yNDIuMDI3LjEyMy4yODUuMjQ0LjU3NC4zNjUuODU3LjA1NS4xMy0uMDA0LjIxMi0uMTQ2LjE5NmwtLjkxOC0uMTA2Yy0uMTU1LS4wMTktLjE5Mi0uMTE0LS4wOTYtLjIzOGwuMTMtLjE3OGMuMDAzLS4wMDMuMDAzLS4wMDguMDEyLS4wMjZsLS4yOTQtLjIxMnEtLjYzMi0uNDQzLTEuMjY1LS44ODZjLS4wNTItLjAzNy0uMDktLjA0Mi0uMTQ1IDAtLjQ5OC4zNTItMSAuNzA0LTEuNDk3IDEuMDU2LS4wMTIuMDA4LS4wMjIuMDEzLS4wMzcuMDI2cS4wOS4xMTguMTc2LjIzNWMuMDc3LjEwOS4wNC4yMDQtLjA5Ni4yMnEtLjQ3NC4wNi0uOTUuMTExYy0uMTE3LjAxMy0uMTc1LS4wNzEtLjEzLS4xODUuMTAzLS4yNDMuMjA4LS40OS4zMTMtLjczM3EuMDMxLS4wNzYuMDYyLS4xNDVjLjA1My0uMTEyLjE1Mi0uMTI1LjIzMi0uMDNsLjE0OS4xOTYuMDIxLjAxNC41MzItLjM3NnEuNTE0LS4zNjMgMS4wMzMtLjcyM2MuMDU5LS4wNC4wNzctLjA4NC4wNzctLjE1M3YtMS42OTN6IiBzdHlsZT0iZmlsbDojZmZmO3N0cm9rZS13aWR0aDouMjY0NTgzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTAxLjgyNSAtMTI0LjgyKSIvPjwvc3ZnPg==)}.gpf-btn-icon-reverse{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgdmlld0JveD0iMCAwIDQuNzYyIDQuNzYzIj48cGF0aCBmaWxsPSIjMDAwMDkxIiBkPSJNMTA0LjQ3IDE2MS40NjVhMi4zODEgMi4zODEgMCAxIDEgLjAwMS00Ljc2MyAyLjM4MSAyLjM4MSAwIDAgMSAwIDQuNzYzbTAtLjQ3N2ExLjkwNCAxLjkwNCAwIDEgMCAuMDAyLTMuODA4IDEuOTA0IDEuOTA0IDAgMCAwLS4wMDEgMy44MDhtLS4yMzctMS4xOWguNDc2di40NzZoLS40NzZ6bS40NzYtLjM5MnYuMTU0aC0uNDc2di0uMzU4YzAtLjEzMi4xMDYtLjIzOC4yMzgtLjIzOGEuMzU2LjM1NiAwIDEgMC0uMzUtLjQyNmwtLjQ2OC0uMDk1YS44MzQuODM0IDAgMSAxIDEuMDU2Ljk2MyIgc3R5bGU9ImZpbGw6I2ZmZjtzdHJva2Utd2lkdGg6LjI2NDU4MyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwMi4wOSAtMTU2LjcwMikiLz48L3N2Zz4=);background-position:50%;background-repeat:no-repeat;background-size:auto auto}.gpf-btn-icon-return{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4AUXDwQyeFmCzQAAATJJREFUSMftliFLBFEURs/dVUQURJvYLCaLGESz1T9gUJsoWARBEBRM/obFIFgMKxtsNhG2aTUIBqOCySLsHssuTNiVGZ47aU8aZr5537vz3TfvwZAhg0K9UL/U5bLMuuyljFXJYXYOHGVuxcAM1VPg5D+/1sgfZsfAWY9HG+ok0AY+gFfgJSI+UzI7tBht9UHdUqtFzQ5M41GdKZLhQmJMa0A9d6VqqDXT2e41fvQxrQCXQK+X7oGnzvUoMA3MAyvAWEbXjIjVIllW1eseM9/vo59SrzK6ljpXtIGq6k0ew0wcdxntTqGFHxEtYBO4zTPBiBDYBX6SGlAdVRud9baeQ99tunrKz6CizubULnYMn8vczprqW+HdIoEaMF5mhRPqe2kVRsQ30Cj7WLI0PJwNnF82zKAINyZs+wAAAABJRU5ErkJggg==);background-position:0;background-repeat:no-repeat}.gpf-flex-reverse{align-items:flex-start;display:flex;flex-direction:column;justify-content:space-evenly}.gpf-panel-reverse{width:100%}.gpf-btn-icon-route{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIxNy43NSIgaGVpZ2h0PSIxNC4zNSIgdmlld0JveD0iMCAwIDQuNjk2IDMuNzk3Ij48ZyBzdHJva2U9IiMwMDAwOTEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCI+PHBhdGggc3Ryb2tlLXdpZHRoPSIuNTI5IiBkPSJNMTAyLjgwNCAyMDAuNzI5YS40NS40NSAwIDEgMSAwLS45LjQ1LjQ1IDAgMCAxIDAgLjl6IiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojZmZmO3N0cm9rZS1vcGFjaXR5OjEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMDIuMDkgLTE5OS41NjUpIi8+PHBhdGggc3Ryb2tlLXdpZHRoPSIuMzk3IiBkPSJNMTAyLjgwNCAyMDAuODc3djEuNWEuNzg3Ljc4NyAwIDAgMCAxLjU3NCAwdi0xLjU0YS43OS43OSAwIDAgMSAuNzg3LS43ODguNzkuNzkgMCAwIDEgLjc4Ni43ODh2MS40MjYiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiNmZmY7c3Ryb2tlLW9wYWNpdHk6MSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwMi4wOSAtMTk5LjU2NSkiLz48cGF0aCBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iLjM5NyIgZD0ibTEwNS4zMTUgMjAxLjkzMy42MzYuNjM1TTEwNS45NTIgMjAyLjU2OGwuNjM2LS42MzUiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiNmZmY7c3Ryb2tlLW9wYWNpdHk6MSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwMi4wOSAtMTk5LjU2NSkiLz48L2c+PC9zdmc+);background-position:50%;background-repeat:no-repeat;background-size:auto auto}.gpf-widget-padding{padding-bottom:5px;padding-left:15px;padding-top:5px}.gpf-widget-color{background-color:#fff}.gpf-panel__items{height:unset}input[name^=inputSex].gpf-input,select[name^=inputSex].gpf-select{padding:unset}button[id^=GPsearchInputReset]{height:40px;width:40px}.gpf-btn-icon-search{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCI+PHBhdGggZmlsbD0iI2Y1ZjVmZSIgZD0ibTE4LjAzMSAxNi42MTcgNC4yODMgNC4yODItMS40MTUgMS40MTUtNC4yODItNC4yODNBOC45NiA4Ljk2IDAgMCAxIDExIDIwYy00Ljk2OCAwLTktNC4wMzItOS05czQuMDMyLTkgOS05IDkgNC4wMzIgOSA5YTguOTYgOC45NiAwIDAgMS0xLjk2OSA1LjYxN20tMi4wMDYtLjc0MkE2Ljk4IDYuOTggMCAwIDAgMTggMTFjMC0zLjg2OC0zLjEzMy03LTctN3MtNyAzLjEzMi03IDcgMy4xMzIgNyA3IDdhNi45OCA2Ljk4IDAgMCAwIDQuODc1LTEuOTc1eiIvPjwvc3ZnPg==);background-position:50%;background-repeat:no-repeat;width:40px}.gpf-btn-icon-search:disabled{background-color:#000091}.gpf-btn-icon-search-advanced{background-image:url(data:image/png;base64,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YWMxMWEiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ZDIyMjI3NzYtNzg5YS00NzdiLTgxNWEtYjMyMTgwMTQ1NTQwIgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MDVmZGI3NTYtYjAzNi00NDZmLTkwNGYtOTIwZTg5NTUzNjZlIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iTGludXgiCiAgIEdJTVA6VGltZVN0YW1wPSIxNzEzNTM5NTY4NjIxOTY4IgogICBHSU1QOlZlcnNpb249IjIuMTAuMzAiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiCiAgIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6NTlmNGRjNGYtYmM1My00YjcyLTkxOTktYWU4ZDM1YThjNTBjIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKExpbnV4KSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyNC0wNC0xNVQxOToxNjo1MyswMjowMCIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozZmQ3MGZkYi0yMDBhLTQ3YjYtOGI3Yi05M2Q5NGZkZjI4OWMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTGludXgpIgogICAgICBzdEV2dDp3aGVuPSIyMDI0LTA0LTE5VDE3OjEyOjQ4KzAyOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Plysf0sAAAAGYktHRAAAAAAAkX5LGK0AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfoBBMPDDAA31VjAAAI9klEQVR42u2bf2xVZxnHP0/DKFsBIaXLcCPImNMmduLUlSrMDFAzN0WXYXCTkDpDR3AcRWIHMxH+WMZ+oDtGaF2M+xHd0HUzusURl7rgxhioBIJmXUC21TF/QAeza8eK7vGP85z2vefe295z7mm5ac6T3Nx73vO+57nnOc/3+fkeyCijjDLKKKOMKoRU9WOqOj2TREYZxQfPJFV9VVXfUNX6TCIZZRQPQK0a0AFVrUrxuptUdeUY/P9mVW0eP0/E3wT+yjHg0xx80n8gV6rqL1T1dVUdUNVjqrpDVReOguVvU9U9qlrrjNfaWJuqTkqBzzmqeqMBpcYZrzEl7zUALUnx3maqap/JrnqUAaSqquMEPDPB7wP/GPjVo8xLg088kuEUDfghcPMw69uBW0Tkv2kACHjbDv8B/Nx+3wjMtN/VIjJQLoCAH9nhm8Be+90IXA18CHhKRD6XolI/BKywwztEZOMogeccIJTPRBE5k6KCTQJ+AMwDrgWvx8ZrgSeBA8C3wDudIs8cuYG3cZTAkyM38M6kAaB2oMUO/wU8ArwGXATcAJxv57aLyJoUHv4S4OkRpi0Rkc4y+dQD3yxwaiqwDKgClorIEykp9SXAYWfof8B0EelNETjXAxuAyyOn9gNbROTRlAA0ooEDbyAlpS4oN/B6UwTOsHID79FEAFLVK4Fddvg0cL2I/Mc5/x6gAwjDnIUi8lwZCtAIPAZc6Ay/Zf+vxhk7BlwnIvsS8pljHnWa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);background-position:-126px;background-repeat:no-repeat}.gpf-btn-icon-search-geolocate{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOSIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggc3Ryb2tlPSIjMTAxMDkyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iMiIgZD0iTTkuNSAxNi4yOTJhNi4yOTIgNi4yOTIgMCAxIDAgMC0xMi41ODQgNi4yOTIgNi4yOTIgMCAwIDAgMCAxMi41ODRaIi8+PHBhdGggc3Ryb2tlPSIjMTAxMDkyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNMSAxMGgyLjIwOE0xNS43OTIgMTBIMThNOS41IDEuNXYyLjIwOE05LjUgMTYuMjkyVjE4LjUiLz48cGF0aCBmaWxsPSIjMTAxMDkyIiBkPSJNOS41IDExLjEwNGExLjEwNCAxLjEwNCAwIDEgMCAwLTIuMjA4IDEuMTA0IDEuMTA0IDAgMCAwIDAgMi4yMDgiLz48L3N2Zz4=);background-position:50%;background-repeat:no-repeat}.gpf-btn-icon-search-coordinate{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMSIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEwMTA5MiIgZD0iTTkuNzAyIDQuODY4SDguNjVjLS40OTEgMC0uNjktLjM1LS40NTYtLjc3MUEyNzMgMjczIDAgMCAxIDEwLjAwNi45NjRjLjIzNC0uMzk3LjYzMS0uMzk3Ljg2NS4wMTJhNDA5IDQwOSAwIDAgMSAxLjc2NSAzLjA1Yy4yOTIuNTE1LjA5My44My0uNTAzLjg0MmgtLjk3YzAgLjE0LS4wMTIuMjM0LS4wMTIuMzR2Ni4xMzZjMCAuMTQuMDgyLjMzOS4xODcuNDIgMi4wMSAxLjQyNyA0LjAzMyAyLjg0MSA2LjA1NSA0LjI1Ni4wMjQuMDExLjA1OS4wMjMuMTA1LjA0Ni4yMS0uMjguNDIxLS41Ni42MzItLjgzLjMyNy0uNDIuNzEzLS4zODUuOTExLjEwNi40NjggMS4wNzUuOTI0IDIuMTYyIDEuMzggMy4yMzcuMjEuNDkxLS4wMTIuNzk1LS41NS43MzdhMzQ3IDM0NyAwIDAgMS0zLjQ3MS0uMzk3Yy0uNTg1LS4wNy0uNzI1LS40MzMtLjM2My0uOWwuNDkxLS42NjdjLjAxMi0uMDEyLjAxMi0uMDM1LjA0Ny0uMTA1YTIyNSAyMjUgMCAwIDEtMS4xMS0uNzk1Yy0xLjU5LTEuMTIyLTMuMTkxLTIuMjMzLTQuNzgxLTMuMzU1LS4xOTktLjE0LS4zNC0uMTYzLS41NSAwYTE2NzIgMTY3MiAwIDAgMS01LjY1NyAzLjk4NmMtLjA0Ny4wMzUtLjA4Mi4wNTktLjE0LjEwNi4yMjIuMzAzLjQ1NS41ODQuNjY2Ljg4OC4yOTIuNDA5LjE1Mi43NzEtLjM2Mi44My0xLjE5My4xNTItMi4zOTcuMjkyLTMuNTg5LjQyLS40NDQuMDQ3LS42NjYtLjI2OC0uNDkxLS43LjM4Ni0uOTI0Ljc4My0xLjg0OCAxLjE4LTIuNzcxLjA4Mi0uMTg3LjE1My0uMzc0LjIzNC0uNTUuMi0uNDIuNTczLS40NjcuODc3LS4xMDVsLjU2MS43MzdjLjAxMi4wMTEuMDM1LjAyMy4wODIuMDQ3LjY2Ni0uNDY4IDEuMzMzLS45MzYgMi4wMS0xLjQxNSAxLjI5OC0uOTEyIDIuNTk1LTEuODM1IDMuOTA1LTIuNzM1LjIyMi0uMTUyLjI5Mi0uMzE2LjI5Mi0uNTczVjQuODU3eiIvPjwvc3ZnPg==);background-position:50%;background-repeat:no-repeat}.gpf-btn-icon-search-reset{background-position:-25px}dialog[id^=GPgeocodeResultsList],div[id^=GPautoCompleteList]{background-color:#fff;height:fit-content;position:absolute;width:300px}div[id^=GPautoCompleteList]{top:55px}dialog[id^=GPgeocodeResultsList]{border-radius:4px;overflow:hidden;position:absolute;top:55px}div[id^=GPgeocodeResults-]{background-color:#fff;max-height:240px;overflow-y:auto;position:relative;width:100%}.gpf-btn-icon-toolbox{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAlqAAAJagFGUcfpAAAAB3RJTUUH4AsKDCgkqrnTSAAAAw1JREFUSMe9ll2IlVUUhp9vnEintH+FulAyI+uihClKjSZtQJAJrRnDoKt+oCIIjSIrDCokKXQiCqkuTMFAJtQLCwItMsQbURmjiRIK+pmSoSjJ/JmnC98je6ZzjmVMCzbnO/vstd691nrf9R0YA1NRn2SsTX1E/UM9vVc1OdwC3A7cBLQD1wE/Al8AA0BfVVXf1vFbAmwCjgPjq+oUREsDkBuA3UBfwL4EXgS2AgJLgIPqw2pV+HUCG4B9/yTtF9Rj6pvqBeo4db7apU5N/VGXqofVHeo09Ub1N3Wdeo/6Z1m60SAL1KPqrQnWqR5Qt6pvqYfU1WqbWqnvqt+p89Sf1T61pSmQOkH9Wl2ZLDaru9T2gLapH6mvB6RXHVRvU79Rd6rnqteoH6vHGwEtV7/K4ZXq+qJME9VP1JfzfZU6lMwPqnvVSfltkvpMyl8X6L3ccmIyayuAdqjP5flZ9deA7M7lpqjjC5+eZkAH1AfT5LVxaFUfV39JoGXq72qHul39Qb0ypX5fvaIRUEnv6dHIZGAwe28Ac4DngQeAl4DFeZ4NLAAOAb3ZP1nEG6HREmgAmAEcBmYCTwFTgaXAEPAK0AMsBO4G7gT2A08Aj9YKM+qzbul61Q0hQ7+6L43tCVW71RXqCXVRUaJhdaOnbHIY2d2Mdd3q96F5e0TYFV3dl/4Nq/cHZE7m2avqLQXQeTlzohFQm/q5+k4C3ZFAD6mL4/h0frs6U2FzMpgdoEujq371ZCMg1GvDqjXqkTCuI1mtyZnLQv9dYWItO9VLwsC7GgIVYPfGaYU6K5rZmJtPUPeoAwla85lbALWcEagA61Svyoj5QD0nAbaoP0U71AJFvKoX50J/A2odDVRVFWo/8Fk00p13y2tAJzAv+6cvVmjGYo3QUWudjC4EPgSORjNHgGXAY3kfzcoqbcaZ9NM6eoID24CLMhGGgA5geabFzVn1bBAYBs4HLm/Wm3HqttB2ZtHof7va1U/Ts7oZvQ10AWuB67PO1vYAc+tls9qxsZETtinf/6PV/gX9b/YXjLd1o+WqCcMAAAAASUVORK5CYII=);background-position:3px;background-repeat:no-repeat} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/css/Portail.css b/build/release/geoportal-extensions-openlayers/css/Portail.css deleted file mode 100644 index ac33f52e2..000000000 --- a/build/release/geoportal-extensions-openlayers/css/Portail.css +++ /dev/null @@ -1,90 +0,0 @@ -/*! - * @brief geoportal-extensions-openlayers - * - * This software is released under the licence CeCILL-B (Free BSD compatible) - * @see http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt - * @see http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt - * @see http://www.cecill.info/ - * - * @copyright copyright (c) IGN - * @license CeCILL-B - * @author IGN - * @version 3.0.0 - * @date 01/02/2024 - * - */ - -/*! - * @overview ol-mapbox-style - Use Mapbox Style objects with OpenLayers - * @copyright Copyright (c) 2016 openlayers - * @license BSD 2-Clause "Simplified" License - * See https://raw.githubusercontent.com/openlayers/ol-mapbox-style/master/LICENSE - * @version 12.2.0 - */ - -/*! - * Sortable -- JavaScript library for reorderable drag-and-drop lists on modern - * browsers and touch devices. No jQuery required. Supports Meteor, AngularJS, - * React, Polymer, Vue, Knockout and any CSS library, e.g. Bootstrap. - * - * Released under MIT LICENSE - * - * Copyright Lebedev Konstantin - * https://github.com/SortableJS/Sortable - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * @version 1.15.2 - */ - -/*! - * @overview EventBus - Simple JavaScript class for managing events in JavaScript - * @copyright Copyright (c) 2014 Krasimir Tsonev - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/krasimir/EventBus/master/LICENSE - * @version 0.2.0 - */ - -/*! - * @overview es6-promise - a tiny implementation of Promises/A+. - * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE - * @version v4.2.4 - */ - -/*! - * @overview Proj4js - Javascript reprojection library. - * - * @authors - * - Mike Adair madairATdmsolutions.ca - * - Richard Greenwood richATgreenwoodmap.com - * - Didier Richard didier.richardATign.fr - * - Stephen Irons stephen.ironsATclear.net.nz - * - Olivier Terral oterralATgmail.com - * - Calvin Metcalf cmetcalfATappgeo.com - * - * @copyright Copyright (c) 2014, Mike Adair, Richard Greenwood, Didier Richard, Stephen Irons, Olivier Terral and Calvin Metcalf - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/proj4js/proj4js/master/LICENSE.md - * @version 2.10.0 - */#GPmapLoading{display:none;height:50px;left:50%;margin-left:-25px;margin-top:-25px;position:absolute;top:50%;width:50px;z-index:50}#GPmapLoading.GPmapLoadingVisible{display:block}#GPmapLoading{background-image:url(data:image/gif;base64,R0lGODlhNAA0AIQSAAFkpSZ5sAGV3k2Ruiao3kOj1/GUBk225pe/B4S83XrK75HH3qrS5szMzNbW1sHe797e3ubm5v///////////////////////////////////////////////////////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQFAQAfACwAAAAANAA0AAAF5uAnjmRpnmiqrmzrvnAsz3T9FXhh72Ke8zWfDzgT/ogxIw55cjgiJ6XOhKjaII1sNio8Vb8ImnbMXVLBVhl2vI2hvzIHOwt9veGxyLwhu4dlcw59bzVjgjNoPHU2f0yOj5CRkpMocg2HjwaaBitzmZuaKWuGTKCgKHt8SKabqHulrJwno1qYQLGyJ56OrCuWtrChlMPExcbHH4s1ymK1NJZtM4Fxu3mvMXvMLdBj2ip60zG0WoBzENLVJL+66TDj7GQmbOc1EE9N4SURDvSRqcgj/gH8wC0LsGPtAK7pN7Chw4cQSYQAACH5BAUBAB8ALBYABAAaACcAAAVw4PdBTQOJaKquX+k2bJw6b+nIcu3isV7yLFrttioYczWWcVmICYkq5hKolB6pKOsUm9Vyu9JvKiyOls/otHqNQ7gR6ff7LJeX63Mx3n3f0+txeWyDhIVlBmsGiopoi45njo9fkZKTlIhil42RaYsxIQAh+QQFAQAfACwWAAkAGgAnAAAFdOAnjmQZOVCprmTjuikrf289y/Ub32SUuw6e6teICEuO31GVfC1Zxqd0Sq1arYVsAavNUrvdKVgrHm+l5jMazPVe3/C4/IN4I+73Kn5P3fOffn+AgXUqBocGK4QriIiKfoaNjip4LJKTT5eHU5qJnJJWjVUhACH5BAUBAB8ALAkAFgAnABoAAAV04CeOZGmepdM0Duq+5yo3cO2qcwPZPJnLveBvFezhZrsi76cM4lrNqHRKrVpPhmoBZuh2o4VwGOUtK8VoU9lcRKdJazbP/R7Fv236tnQ/If4IJ3pYa36Af4JuLl6Gh4gmYlKOgFclk4+VIpeBmSOTnZaUTSEAIfkEBQEAHwAsBAAWACcAGgAABXfg9xmkIZ5oqq5rWbJwnLqubLP0e+9nTvJAnwnIyxGJtaNyyWw6n1Ao4hmRIa7XpaPBbbCw4OO2y1WBw0Ryt4o6o3cRNdeRcmfTcojZvSr4CytyXntvKH9/gWR6X3cph4crEQ6LSo+IUYaWgJgnmpucIpagjpc3IQAh+QQFAQAfACwEAAkAGgAnAAAFb+AnjqJhkmiamqyhvmjLwrA806p946Tu8isbMNca1ozIpHLJTCKeiCYUupxOlVaqMxvdZqtWqbZJLpvPyEK5wGYz23AlPJ6c0412t9yucjQaDi98KX+FDTBtfYZ/gUmLhUqPf0p+i42Oi00QfxAiIQAh+QQFAQAfACwEAAQAGgAnAAAFc+AnjmRZGqhhrmyasrDounE7o/V64yvi6zuTb4gA0oTEn+lYSg5zSGcROpJOqVUntknc9rzgsHhMLhXOhTEaHV6vwW62N36G09tutbzM7/v/JhFlDYQNDmKFhYdeEYmFYA6OhIJbEJINYZdhlolkEA6UUCEAIfkEAQEAHwAsBAAEACcAGgAABXXgJ45kWSIoYq5sS6apK8swPN9mHeP8p6O9UmG4+qlMhmRryCwUa6uk1LBqMp9A5FQptBKDW2nX6+SFxSRyuXemjpvBz5lljYu2srX9vu/7/4CBgh8NhQ6DK4WKDYgkEIuGjSKQipKElIySj5CHlpSWIw6RoCEAOw==)}.GPwidget{color:#333;font-family:Helvetica Neue,Arial,Helvetica,sans-serif;font-size:13px;pointer-events:auto;position:absolute}.GPwidget input[type=button],.GPwidget input[type=text]{-webkit-appearance:none;appearance:none;color:#333}.GPwidget input[type=checkbox]{display:none}.GPwidget select{border-radius:3px;padding-left:3px}.GPwidget form{margin-bottom:0}.GPwidget *{background-repeat:no-repeat;box-sizing:border-box}:root{--size-per-row:50px}#position-container-bottom-left,#position-container-bottom-right,#position-container-top-left,#position-container-top-right{border-style:solid;display:flex;flex-direction:column;justify-content:center;min-height:var(--size-per-row);min-width:var(--size-per-row);padding:5px;position:absolute}#position-container-top-left,#position-container-top-right{top:0}#position-container-top-left{float:left;left:0}#position-container-top-right{float:right;right:0}#position-container-bottom-left,#position-container-bottom-right{bottom:0}#position-container-bottom-right{float:right;right:0}#position-container-bottom-left{float:left;left:0}.GPpanel{background-color:#fff;border:unset;border-radius:4px;box-shadow:0 0 6px #000;padding:unset}.GPpanelHeader{background-color:#9db1bd;border-top-left-radius:4px;border-top-right-radius:4px;height:32px;padding:3px;position:relative;width:100%}.GPpanelTitle{background-color:#366291;border-top-left-radius:2px;border-top-right-radius:2px;color:#fff;font-weight:700;height:100%;line-height:26px;text-align:center;width:100%}.GPpanelClose,.GPpanelInfo,.GPpanelReduce,.GPresetPicto,.GPreturnPicto{background-color:#366291;border:none;cursor:pointer;height:26px;position:absolute;width:26px}.GPpanelClose{background-position:-27px 0;right:3px;top:3px}.GPpanelInfo{left:3px;top:3px}.GPpanelReduce{right:32px;top:3px}.GPresetPicto,.GPreturnPicto{border-radius:3px;opacity:1}.GPshowAdvancedToolPicto{background-color:hsla(0,0%,100%,.4);border:2px solid hsla(0,0%,100%,.4);border-radius:4px;box-sizing:border-box;cursor:pointer;height:32px;padding:2px;position:relative;width:32px}.GPshowAdvancedToolPicto:hover{background-color:hsla(0,0%,100%,.6)}.GPshowAdvancedToolOpen{background-color:rgba(0,60,136,.5);border-radius:2px;box-sizing:border-box;display:block;height:26px;position:absolute;width:26px}.GPshowAdvancedToolPicto:hover .GPshowAdvancedToolOpen{background-color:rgba(0,60,136,.7)}.GPshowOpen{background-color:rgba(0,60,136,.5)}.GPshowOpen:hover{background-color:rgba(0,60,136,.7)}.GPwaitingContainer{background-color:hsla(0,0%,100%,.9);border-radius:4px;bottom:0;font-size:1.5em;font-weight:700;left:0;overflow:hidden;position:absolute;right:0;top:32px}.GPwaitingContainerVisible{display:-webkit-flex;display:-ms-flexbox;display:-webkit-box;display:flex}.GPwaitingContainerHidden{display:none}.GPwaitingContainerInfo{margin:auto}.GPflexInput{display:-webkit-flex;display:-ms-flexbox;display:-webkit-box;display:flex;transition:max-height .3s ease-out,opacity .3s ease-out}.GPflexInput>*{border:1px solid #999;border-radius:0;display:block;height:28px;line-height:26px}.GPflexInput :not(:last-child){border-right:none}.GPflexInput :first-child{border-radius:3px 0 0 3px}.GPflexInput :last-child{border-radius:0 3px 3px 0}.GPflexInput>:not(input){overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.GPflexInput>input{min-width:0;padding:0 5px}.GPflexInput>input,.GPflexInput>select{-webkit-flex:1;-webkit-box-flex:1;-ms-flex:1;flex:1}.GPflexInput>select{padding-right:7px}.GPflexInput>label{background-color:#f2f2f2;color:#666;cursor:pointer;padding-left:7px;padding-right:9px}input.GPsubmit{background:none;background-color:#366291;border:none;border-radius:3px;color:#fff;cursor:pointer;display:block;font-family:Helvetica Neue,Arial,Helvetica,sans-serif;font-weight:700;height:28px;line-height:26px;margin:auto;opacity:.8;padding:0;transition:opacity .2s ease-out;width:80px}input.GPsubmit:hover{opacity:1}.GPselect{border:1px solid #999;color:#333;cursor:pointer;display:block;height:28px;line-height:26px;margin:auto}.GPform{padding:15px}.GPelementHidden,.GPelementInvisible{display:none}.GPelementShow,.GPelementVisible{display:block}.GPadvancedAutoCompleteList,.GPautoCompleteList{z-index:2}.GPadvancedAutoCompleteList{border-top:none;font-size:.9em;width:calc(100% - 28px)}.GPautoCompleteProposal{color:#5e5e5e;cursor:pointer;font-size:1em;height:28px;line-height:16px;overflow:hidden;padding:6px 10px;text-overflow:ellipsis;white-space:nowrap;width:100%}.GPautoCompleteProposal:hover{background-color:#cedbef;color:#000}.GPshowMoreOptionsImage{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAA7ElEQVRIx+3UvUoDQRSG4ffMLhbaLIEFvQSxtN1ALiGymkswpZVoupS6Vt6BYBMWf+s0Kaa1FG9BEBYbDQRnj4UKqTRgtjtPeWaYb4YPBowxpmmyyKbs6PpJVCfVan3wOOzN5te2huVK692dq0jHn+abf53lFrqWMlKRfjKNxu1Bmf6M24MyTabRWEX6KKOlvRAgO77ZQ/UCqBDXdSqzmnAPbKDs+yK/XGrgV+jtNlrfAcn36BVxXX+y89BYh+kbrQ+JrgBiDbsva1SNdhhigi/yzBd5FmKCdfivQIDOYbk+3+HkrPds35kx5lef+y50/JHC/FoAAAAASUVORK5CYII=)}.GPshowMoreOptions{cursor:pointer;display:block;height:28px;position:absolute;transition:all .5s ease-out 0s;width:28px}button[aria-pressed=true].GPshowMoreOptions,input[type=checkbox]:checked+.GPshowMoreOptions{-webkit-transform:rotateX(180deg);transform:rotateX(180deg)}.gp-feature-info-div{background-color:#fff;border-radius:10px;bottom:17px;box-shadow:0 0 5px #000;color:#002a50;font-family:Open Sans,sans-serif;font-size:.75em;max-width:calc(100vw - 80px);padding:10px;position:relative}.gp-feature-info-div:before{border-left:14px solid transparent;border-right:14px solid transparent;border-top:15px solid #fff;bottom:-15px;content:"";left:50%;margin-left:-14px;position:absolute}.gp-feature-info-div .closer{background-color:#fff;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+PGRlZnM+PGNsaXBQYXRoIGlkPSJhIj48cGF0aCBkPSJNMCA4NDEuOWg1OTUuM1YwSDB6Ii8+PC9jbGlwUGF0aD48L2RlZnM+PGcgZmlsbD0iIzAwYjc5OCIgY2xpcC1wYXRoPSJ1cmwoI2EpIiB0cmFuc2Zvcm09Im1hdHJpeCguMDIzNTIgMCAwIC0uMDIzNTIgMSAxOCkiPjxwYXRoIGQ9Im0zNjguNCA0MjAuOSAyMTIuMiAyMTIuMmMxOS41NCAxOS41NCAxOS41NCA1MS4yMSAwIDcwLjc1cy01MS4yMSAxOS41NC03MC43NSAwbC0yMTIuMi0yMTIuMy0yMTIuMiAyMTIuM2MtMTkuNTQgMTkuNTQtNTEuMjEgMTkuNTQtNzAuNzUgMC0xOS41My0xOS41NC0xOS41My01MS4yMSAwLTcwLjc1TDIyNyA0MjAuOSAxNC44IDIwOC43Yy0xOS41My0xOS41NC0xOS41My01MS4yMSAwLTcwLjc1IDE5LjU0LTE5LjU0IDUxLjIxLTE5LjU0IDcwLjc1IDBsMjEyLjIgMjEyLjIgMjEyLjItMjEyLjJjMTkuNTMtMTkuNTQgNTEuMjEtMTkuNTQgNzAuNzUgMHMxOS41NCA1MS4yMSAwIDcwLjc1TDM2OC41IDQyMC45eiIvPjwvZz48L3N2Zz4=);background-position:50%;background-repeat:no-repeat;background-size:14px 14px;border:none;border-bottom-right-radius:10px;border-top-right-radius:10px;cursor:pointer;display:block;height:30px;position:absolute;right:0;top:0;width:30px}.gp-features-content-div{max-height:340px;max-width:420px;min-width:260px;overflow:auto}.gp-features-content-div h5,.gp-features-content-div h6,.gp-features-content-div p,.gp-features-content-div ul{margin:0}.gp-features-content-div ul{list-style-type:none;padding:0}.geoportail-popup-content h5,.geoportail-popup-content h6,.geoportail-popup-content p,.gp-att-description-div,.gp-att-name-div,.gp-att-others-div{padding:0 10px}.geoportail-popup-content h5:not(:last-child),.geoportail-popup-content h6:not(:last-child),.geoportail-popup-content p:not(:last-child),.gp-att-description-div:not(:last-child),.gp-att-others-div:not(:last-child){margin-bottom:15px}.geoportail-popup-content h5:last-child,.geoportail-popup-content h6:last-child,.geoportail-popup-content p:last-child,.gp-att-description-div:last-child,.gp-att-name-div,.gp-att-others-div:last-child{margin-bottom:10px}.geoportail-popup-content h5:first-child,.geoportail-popup-content h6:first-child,.geoportail-popup-content p:first-child,.gp-att-description-div:first-child,.gp-att-name-div:first-child,.gp-att-others-div:first-child{margin-top:10px}.gp-att-name-div,.gp-features-content-div h5{color:#0b6ba7;font-size:1.2em;font-weight:700;padding-right:35px;text-transform:uppercase}.gp-features-content-div h6{font-size:1.1em}.gp-att-description-div:not(:last-child),.gp-att-others-div:not(:last-child){border-bottom:1px dotted #666;padding-bottom:10px}[id^=GPdrawingPanel-]{width:240px}.GPshowDrawingPicto{background-position:1px;background-repeat:no-repeat}.GPdrawingPanelClose,.GPshowDrawingPicto{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAAaCAYAAAD43n+tAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGCSURBVFiF7da/Sh1BFMfxuXZa2AuWgkoa0SqP4StoUoi2PklyBZXUNlpZWGmq5AmiYghpAv5pAoKW+rFwFq/D3NXdu5fb7K9ahjPnd757Zs9OCK1atWrVlDCHvzjB5KjrGVg49aKfdaHwGdsYK4np4As26lf8diF7XqsyVIR5iPt3c1AR5muMeWwUCrM4wwEmcZhAHVfM1032b6GTwGwlMd0mYS57Eh9loP5UzFkcpV7tYizpTKGdXBebgEmh9vALczVy94NKuzd0mEL7DXjkoEYCA+cDG4VSqOywyKk0CLMhhO8hhKmSsOsQwvL7y35TnXeuVRMm8Bu3JZ25UuOb6eOXGwC1utTPYBXfsIT/GYMbfBgizE5mrT6U5+vMYnz+mHTqCvNDhinGdnakVzWZxj1metYKqMZgYt7h/1ixGTf+wwwWPB+/iyZhotcnL1ef7GhOOvWI9aomP3rexl08fisYb4zktd9a7FTfaRahulirY3AZoTYxPVC1rVq1ajVKPQEmCKhvk/LblAAAAABJRU5ErkJggg==)}.GPdrawingCoords,.GPdrawingLabel{display:inline-block;line-height:20px}.GPdrawingLabel{font-weight:700;width:80px}.GPdrawingCoords{width:110px}.marker-input-radio{display:none}input.marker-input-radio:checked+label{border:1px solid red}div.drawing-tools-flex-display{justify-content:space-between}button[id^=drawing-export-]{background-position:2px 0}.drawing-button{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAxMjAiPjxnIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwYjc5OCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjMiPjxwYXRoIGQ9Ik02ODggMzI2LjR2OGgyMHYtOG0tMTAtMTR2MTQiIHRyYW5zZm9ybT0ibWF0cml4KC42MDg2IDAgMCAuNTU5NSAtNDA5LjggLTEzNikiLz48cGF0aCBkPSJtNjkzIDMyMS40IDUgNSA1LTUiIHRyYW5zZm9ybT0ibWF0cml4KC42MDg2IDAgMCAuNTU5NSAtNDA5LjggLTEzNikiLz48L2c+PGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTUwNSAtODU3LjQpIj48cmVjdCB3aWR0aD0iMSIgaGVpZ2h0PSIxNCIgeD0iNTEzIiB5PSI5MjUuNCIgcng9IjAiIHJ5PSIwIi8+PHJlY3Qgd2lkdGg9IjEiIGhlaWdodD0iOCIgeD0iNTE0IiB5PSI5MjUuNCIgcng9IjAiIHJ5PSIwIi8+PHBhdGggZD0iTTUxNSA5MzAuNGgxdjNoLTF6bTEgMWg4djJoLTh6Ii8+PHJlY3Qgd2lkdGg9IjEiIGhlaWdodD0iMTQiIHg9IjUyNiIgeT0iOTI1LjQiIHJ4PSIwIiByeT0iMCIvPjxwYXRoIGQ9Ik01MjUgOTI1LjRoMXY4aC0xem0tMSA1aDF2M2gtMXptLTkgNGgxMHYyaC0xMHptNSAyaDV2M2gtNXptLTMgMWgydjJoLTJ6bS0yLTFoMXYzaC0xem00LTExaDV2NWgtNXptLTMgM2gzdjJoLTN6bTAtM2gxdjNoLTF6bTEgMGgydjFoLTJ6Ii8+PC9nPjxnIGZpbGw9IiMwMGI3OTgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01NDAgLTgyNy40KSI+PHJlY3Qgd2lkdGg9IjEiIGhlaWdodD0iMTQiIHg9IjU0OCIgeT0iOTI1LjQiIHJ4PSIwIiByeT0iMCIvPjxyZWN0IHdpZHRoPSIxIiBoZWlnaHQ9IjgiIHg9IjU0OSIgeT0iOTI1LjQiIHJ4PSIwIiByeT0iMCIvPjxwYXRoIGQ9Ik01NTAgOTMwLjRoMXYzaC0xem0xIDFoOHYyaC04eiIvPjxyZWN0IHdpZHRoPSIxIiBoZWlnaHQ9IjE0IiB4PSI1NjEiIHk9IjkyNS40IiByeD0iMCIgcnk9IjAiLz48cGF0aCBkPSJNNTYwIDkyNS40aDF2OGgtMXptLTEgNWgxdjNoLTF6bS05IDRoMTB2MmgtMTB6bTUgMmg1djNoLTV6bS0zIDFoMnYyaC0yem0tMi0xaDF2M2gtMXptNC0xMWg1djVoLTV6bS0zIDNoM3YyaC0zem0wLTNoMXYzaC0xem0xIDBoMnYxaC0yeiIvPjwvZz48ZyBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIzIj48cGF0aCBkPSJNNjg4IDMyNi40djhoMjB2LThtLTEwLTE0djE0IiB0cmFuc2Zvcm09Im1hdHJpeCguNjA4NiAwIDAgLjU1OTUgLTQwOS44IC0xNjYpIi8+PHBhdGggZD0ibTY5MyAzMjEuNCA1IDUgNS01IiB0cmFuc2Zvcm09Im1hdHJpeCguNjA4NiAwIDAgLjU1OTUgLTQwOS44IC0xNjYpIi8+PC9nPjwvc3ZnPg==);background-size:30px 120px;font-size:.7em;height:30px;line-height:30px;margin:auto;padding-left:30px;padding-right:15px}.tool-form-submit{background-color:#00b798;border:none;border-radius:20px;color:#fff;font-family:Helvetica Neue,Arial,Helvetica,sans-serif;font-size:.9em;text-align:center;text-transform:uppercase}.gp-label-div,.gp-styling-div{background-color:#fff;border-radius:10px;box-shadow:0 0 5px #000;box-sizing:border-box;font-size:.75em;position:relative;top:17px}.gp-label-div:before,.gp-styling-div:before{border-bottom:15px solid #fff;border-left:10px solid transparent;border-right:9px solid transparent;content:"";left:50%;margin-left:-10px;position:absolute;top:-15px}.gp-input-label-style,.gp-textarea-att-label-style{border:none}.gp-textarea-att-label-style{height:80px;resize:none;width:240px}.gp-input-measure-style{background-color:#fff;border-radius:10px;font-size:.75em;text-align:center;width:240px}.gp-textarea-att-label-style{display:block}.gp-label-div .closer{background-color:#fff;border-top-right-radius:10px}.gp-input-label-style{width:180px}.gp-label-div{padding:10px}.gp-styling-div{padding:50px 20px 20px;width:340px}.gp-styling-div:after{border-bottom:1px solid #bbb;content:"Modifier le style";display:block;font-size:1.2em;font-variant:small-caps;font-weight:700;height:30px;left:30px;line-height:30px;position:absolute;text-align:center;top:0;width:280px}.gp-label-div .gp-styling-button:not([class*=closer]){display:block;margin:10px auto auto}.gp-styling-button:not([class*=closer]){background-color:#00b798;border:none;border-radius:12px;color:#fff;display:inline-block;font-size:.9em;font-weight:700;height:24px;line-height:24px;margin-top:20px;text-align:center;text-transform:uppercase;width:140px}.gp-styling-button:not([class*=closer]):hover{background-color:#eef2f5;color:#00b798}.gp-styling-button:not([class*=closer])+.gp-styling-button:not([class*=closer]){margin-left:20px}.gp-label-div .closer,.gp-styling-div .closer{background-color:transparent;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+PGRlZnM+PGNsaXBQYXRoIGlkPSJhIj48cGF0aCBkPSJNMCA4NDEuOWg1OTUuM1YwSDB6Ii8+PC9jbGlwUGF0aD48L2RlZnM+PGcgZmlsbD0iIzAwYjc5OCIgY2xpcC1wYXRoPSJ1cmwoI2EpIiB0cmFuc2Zvcm09Im1hdHJpeCguMDIzNTIgMCAwIC0uMDIzNTIgMSAxOCkiPjxwYXRoIGQ9Im0zNjguNCA0MjAuOSAyMTIuMiAyMTIuMmMxOS41NCAxOS41NCAxOS41NCA1MS4yMSAwIDcwLjc1cy01MS4yMSAxOS41NC03MC43NSAwbC0yMTIuMi0yMTIuMy0yMTIuMiAyMTIuM2MtMTkuNTQgMTkuNTQtNTEuMjEgMTkuNTQtNzAuNzUgMC0xOS41My0xOS41NC0xOS41My01MS4yMSAwLTcwLjc1TDIyNyA0MjAuOSAxNC44IDIwOC43Yy0xOS41My0xOS41NC0xOS41My01MS4yMSAwLTcwLjc1IDE5LjU0LTE5LjU0IDUxLjIxLTE5LjU0IDcwLjc1IDBsMjEyLjIgMjEyLjIgMjEyLjItMjEyLjJjMTkuNTMtMTkuNTQgNTEuMjEtMTkuNTQgNzAuNzUgMHMxOS41NCA1MS4yMSAwIDcwLjc1TDM2OC41IDQyMC45eiIvPjwvZz48L3N2Zz4=);background-position:50%;background-repeat:no-repeat;background-size:14px 14px;border:none;cursor:pointer;display:block;height:30px;position:absolute;right:0;top:0;width:30px}.gp-styling-div ul{list-style-type:none;margin:0;padding:0}.gp-styling-option{font-size:11px;line-height:30px;padding:0 20px;position:relative}.gp-styling-option input{cursor:pointer;display:block;height:20px;padding:0;position:absolute;top:6px}.gp-styling-option input[type=checkbox]{background:none;border:none;height:10px;padding:0;right:70px}.gp-styling-option input[type=color]{background:none;border:none;padding:0;right:70px;width:30px}.gp-styling-option input[type=text]{background:none;border:1px solid grey;color:#0b6ba7;margin:none;padding:0 5px;right:40px;width:80px}.gp-styling-option input[type=range]{margin:0;right:40px;width:80px}.gp-styling-option input[type=range]:focus{box-shadow:none;outline:none}.gp-styling-option input[type=range]::-webkit-slider-runnable-track{-webkit-appearance:none;background-color:grey;height:1px}.gp-styling-option input[type=range]::-webkit-slider-thumb:before{height:1px;left:-200px;pointer-events:none;position:absolute;right:50%;top:0}.gp-styling-option input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background-color:#0b6ba7;border:none;border-radius:50%;height:13px;position:relative;top:-6px;width:13px}.gp-styling-option input[type=range]::-moz-range-track{background-color:grey;height:1px;width:70px}.gp-styling-option input[type=range]::-moz-range-thumb{background-color:#0b6ba7;border:none;border-radius:50%;box-shadow:0;height:13px;position:relative;width:13px}.gp-styling-option input[type=range]::-ms-track{background-color:grey;border:0;border-color:transparent;border-radius:0;border-width:0;color:transparent;height:1px;width:70px}.gp-styling-option input[type=range]::-ms-fill-lower,.gp-styling-option input[type=range]::-ms-fill-upper{background:transparent;border-radius:0}.gp-styling-option input[type=range]::-ms-thumb{background-color:#0b6ba7;border:none;border-radius:50%;height:13px;width:13px}.gp-styling-option input[type=range]::-ms-tooltip{display:none}.gp-styling-option .marker-input-radio{display:none}.gp-styling-option .marker-label{cursor:pointer;display:inline-block;height:32px;margin-bottom:5px;margin-right:5px;padding:3px}.gp-styling-option .marker-input-radio:checked+.marker-label{background-color:rgba(0,183,152,.5);border:1px solid #002a50;padding:2px}.gp-styling-option .marker-label img{height:24px}.ol-attribution .gp-control-attribution-image{max-height:30px;max-width:inherit;vertical-align:middle}.GPimportMapBoxpRoot{padding:5px}.GPEditorMapBoxContainer{border:1px solid #87cefa;border-radius:5px;-webkit-box-shadow:0 0 5px #000;box-shadow:0 0 5px #000;-webkit-box-sizing:border-box;box-sizing:border-box;height:auto;padding:5px;position:relative;width:100%}.GPEditorMapBoxSep{border:4px double #87cefa;display:block;width:50%}.GPEditorMapBoxLayersTitle,.GPEditorMapBoxThemesTitle{font-style:italic;font-weight:700;padding:5px}.disabled{opacity:.5;pointer-events:none}.GPEditorMapBoxGroupDetails{border:1px dotted #87cefa;border-radius:5px}.GPEditorMapBoxLayerContainer{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;width:100%;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.GPEditorMapBoxLayerContainer,.GPEditorMapBoxLayerTitleContainer{min-height:28px;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.GPEditorMapBoxLayerTitleContainer{display:-webkit-box;display:-ms-flexbox;display:flex;width:inherit;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.GPEditorMapBoxLayerImageInput{display:none}.GPEditorMapBoxLayerImageLabel{background-image:url(data:image/png;base64,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);background-position:-56px 0;cursor:pointer;min-height:28px;min-width:24px}input[type=checkbox]:checked+.GPEditorMapBoxLayerImageLabel{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.GPEditorMapBoxLayerTypeImage{background-image:url(data:image/png;base64,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);background-position:0 0;background-repeat:no-repeat;border:1px solid gray;border-radius:5px;-webkit-box-shadow:2px 2px 1px #d3d3d3;box-shadow:2px 2px 1px #d3d3d3;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer;margin-right:5px;min-height:30px;min-width:30px}.GPEditorMapBoxLayerTitleInput{display:none}.GPEditorMapBoxLayerTitleLabel{border:1px solid gray;border-radius:5px;-webkit-box-shadow:2px 2px 1px #d3d3d3;box-shadow:2px 2px 1px #d3d3d3;cursor:pointer;margin-left:5px;padding:5px;width:inherit;word-break:break-word}input[type=checkbox]:checked+.GPEditorMapBoxLayerTitleLabel{background-color:#d3d3d3}.GPEditorMapBoxToolsContainer{display:-webkit-box;display:-ms-flexbox;display:flex;height:28px;min-width:28px;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.GPEditorMapBoxToolsVisibilityInput{display:none}.GPEditorMapBoxToolsVisibilityInputDisable{display:"block"}.GPEditorMapBoxToolsVisibilityLabel{background-image:url(data:image/png;base64,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);background-position:-28px 0;cursor:pointer;height:28px;width:28px}.GPEditorMapBoxToolsVisibilityLabelDisable{cursor:pointer}input[type=checkbox]:checked+.GPEditorMapBoxToolsVisibilityLabel{background-position:0 0}.GPEditorMapBoxFilterContainer{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;margin-left:28px}.GPEditorMapBoxFilterJsonContainer{border-radius:5px;border-style:solid;border-width:1px;padding:5px}.GPEditorMapBoxFilterDisplayJson{cursor:pointer;height:125px;overflow:scroll;resize:vertical;width:175px}.GPEditorMapBoxThemesContainer{display:-webkit-box;display:-ms-flexbox;display:flex;width:175px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.GPEditorMapBoxThemeContainer{border-radius:5px;border-style:solid;border-width:1px;margin:5px;padding:5px;text-align:center;width:inherit}.GPEditorMapBoxThemeContainer:focus{background-color:#d3d3d3}.GPEditorMapBoxThemeImage{cursor:pointer;height:60px;width:120px}.GPEditorMapBoxThemeTitle{cursor:pointer;padding:5px}.GPEditorMapBoxThemeMessage{color:red;font-style:italic}.GPEditorMapBoxStyleContainer{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;margin-left:28px}.GPEditorMapBoxStyleJsonContainer{border-radius:5px;border-style:solid;border-width:1px;padding:5px}.GPEditorMapBoxStyleJsonDisplay{cursor:pointer;height:125px;overflow:scroll;resize:vertical;width:175px}.GPEditorMapBoxStyleToolsScaleContainer{border-radius:5px;border-style:solid;border-width:1px;padding:5px;width:-webkit-min-content;width:-moz-min-content;width:min-content}.GPEditorMapBoxStyleToolsScaleMaxContainer,.GPEditorMapBoxStyleToolsScaleMinContainer{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;width:175px;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.GPEditorMapBoxLegendContainer{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-ms-flex-wrap:nowrap;flex-wrap:nowrap;margin-left:28px}.GPEditorMapBoxLegendRenderContainer{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border-radius:5px;border-style:solid;border-width:1px;overflow-y:auto;padding:5px;width:175px}.GPEditorMapBoxLegendRender{border:1px solid transparent;border-radius:5px;-webkit-box-shadow:2px 2px 1px grey;box-shadow:2px 2px 1px grey;cursor:pointer;min-height:28px;min-width:28px}.GPEditorMapBoxLegendEditable{border-color:#000}.GPEditorMapBoxLegendTitle{margin-left:10px}.GPEditorMapBoxLegendToolsContainer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding:5px;width:230px}.legend-not-implemented,.legend-unknow{background-color:#fff}.legend-unknow:before{color:red;content:"\2753";font-size:15px}.legend-not-implemented:before{color:red;content:"\2718";font-size:15px}.legend-circle-not-editable,.legend-line-not-editable{border-color:#fff}.legend-styling-div{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.legend-styling{width:50px}.GPpanelHeader{padding:unset}#profileElevationRaw{padding:unset;resize:none}#profileElevationByDefault{display:-webkit-flex;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;height:100%}.altiPathValue{font-weight:700;fill:#5e5e5e}.altiPathCoords{font-style:italic;fill:#5e5e5e}.tooltipInit{opacity:0}.tooltipFadeIn{opacity:1;transition:opacity .3s ease 0ms,transform 50ms ease 0s,top 50ms ease 0s,left 50ms ease 0s}.tooltipFadeOut{opacity:0;transition:opacity .5s ease 0ms}.axis-d3>text{fill:#5e5e5e;font-family:Verdana;font-size:10px;opacity:1;text-anchor:end}.axis-d3{fill:none;stroke:#5e5e5e;stroke-width:1;shape-rendering:crispEdges}.area-d3{fill:#c77a04;stroke:#5e5e5e;stroke-width:0;fill-opacity:.4}.line-d3{fill:none;stroke:#c77a04;stroke-width:1px}.grid-d3 .tick{stroke:#d3d3d3;opacity:.7}.grid-d3 path{stroke-width:0}.overlay-d3{fill:none;pointer-events:all}.focusLine-d3{fill:none;stroke:#c77a04;stroke-width:.5px}.focusCircle-d3{fill:#c77a04}div.tooltip-d3{background:#fff;border:0;border-radius:8px;font:8px sans-serif;height:45px;padding:5px;pointer-events:none;position:inherit;text-align:left;width:80px}[id^=GPelevationPathPanel-]{width:280px}[id^=GPelevationPathPanelInfo]{background-position:-75px}[id^=GPelevationPathPanelInfo],button[id^=GPshowElevationPathPicto-]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGgAAAAaCAYAAABb9hlrAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH4gEQEjITjE0MtwAABGJJREFUaN7tmU1oHGUYx//PZEvSLjHVBLVaerCXSgo5tAqxiqBSxcSLWqknFaNdaYjiwUMOVVGi2EORJg0xtgbx0FKVgmirRU17SUpjPsCVUhQtVOr6ES8mmpqdnwffhekw2dndbMK23T8MzMzzzsz7PP/3+ZjnlaqooooqrlhY7gSol3Rr7tLMTlfNs3gAJqnGncvMJMk3M7+Q5xOB8zsl9Ui6XtI/ktZXzVs6MpmMNTU1rZa0SdJNknLkSNI0MCrpTzPLFkSQmR0FspIGJb1UNXHpHjM3N9dUW1t7u6QHJW2V9KukPyQhqcEt/i8lHctms8Oe5/0WR5SAW4AfgWGgC1ixjEo9AwwAXj7Fgb1AZ6WSMzk56QGbgQPA98AUsBvYAKwCVgJrgV3AKeAccAi4f3x8vCbOSA8AB91xGEguIzlZ/sdgFEmOnF43xq9UkoBrgD7gZ+B13/c3u/uPAG8AbwEdkpTNZjcCLwJngE+AtYV8YEW+VbxESvVxKfa5xBokZ19oTF+lkTMzM+MB9wJngT0hHT8KzP2bkGwHcB54Ktb2wNtAb5EGbgAaFhOzXegKYhDwQp6TwzvLvYgK1CPpwtkZYEtI9iowCowBAyHZeuCEi1pr4j4yBBwscmK7gZ7FJtYFSOq7TMgx4A7gB6AvnU5bSF4H1LtjVVCWSqUMeN550eN59SuWIMf+HDAL3LwEJC0bOSPdCRvpTljwOiT3RroTdQvM3QPanYfcFiHvAj4GjgCvLWDHT4EX8hZnUQQBCRf6tkWMD8bW/WVaiVEkDZZKDmWCI6kmD0FtwNfAugXsetG96qsIeSPwfhRBXoxy10n6XFKXpEPAy7kEDtwl6eHA8CeA5nJ2N2LuxXrEEjiaX2a9YpHvv2ODpFOS7gl84BVHVFLSntAjNZLeXGRLZK+knRHipyUNFONFrT3zlDsExhjZJNVLuqGE16+W1BjX6rmk3JY06v56w9gmaUuufRFCO3C3mZ0oAzmDki4G7nXkytJC+lgj3Qlr7ZnHzIK5JW4V09ozz0h3Yo0zdJOk3yVlHOELkY6kaUnXSnoynU6PNTc3F7RAUqmUSWqX1CLpA0nZ2Bzkqo5ScbKEvBNZSucrwS+zMnsI+DcqB8WV2Uuh6Loix/eGPKdf0g4z880Ml//6A/IO520VhdnZ2b8lHXM2fTQkrg1Eq3AleJ/rzX0mKVNQiFtmTLjk67mw1umIyTVxAXY61+904eS7SiMomUz6wGlJxyU9BswARzzPG5P0oaSfXJ4+m2v1eJ63VdKzzgbHo0J3Ik9MPVfiXM8XVdqYvety3sYwOSGSuhyJ35pZfyX24qampv5qaWl5T9JKSdvN7CHgC0n7JR11dm0Edklqk3Sjy/UHJiYmLsSWfsCQpDoz264qSq5Gi9lu8H0/73ZDmKCTrpq4UI65SnrOzIavRqJyG3ae522KqHinnefEbtiFCWpzJXSmTD91h83sl6vdo7SILe8qqqiiiisY/wFFCbN/sRPwgwAAAABJRU5ErkJggg==);background-repeat:no-repeat}button[id^=GPshowElevationPathPicto-]{background-position:1px}div[id^=GPexportContainer-]{padding:5px}div[id^=GPexportContainer-]>input.GPsubmit{color:#fff}input[id^=GPexportButton-]{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHdpZHRoPSIxMy45OTkiIGhlaWdodD0iMTMuOTg4IiB2aWV3Qm94PSItMSAtMSA1LjcwNSA1LjciPjxnIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjMiPjxwYXRoIGQ9Ik02ODggMzI2LjR2OGgyMHYtOG0tMTAtMTR2MTQiIHRyYW5zZm9ybT0ibWF0cml4KC4xNjEwMyAwIDAgLjE0ODAzIC0xMTAuNTQ0IC00Ni4wMjQpIi8+PHBhdGggZD0ibTY5MyAzMjEuNCA1IDUgNS01IiB0cmFuc2Zvcm09Im1hdHJpeCguMTYxMDMgMCAwIC4xNDgwMyAtMTEwLjU0NCAtNDYuMDI0KSIvPjwvZz48L3N2Zz4=);background-repeat:no-repeat;background-size:25px 25px;min-width:fit-content;padding-left:25px;padding-right:5px}.GPexportMenuHidden{visibility:hidden}.GPexportMenuContainer{display:inline-block;position:relative}.GPexportMenuContent{border-radius:10px;box-shadow:0 8px 16px 0 rgba(0,0,0,.2);display:none;min-width:80px;padding:8px;position:absolute;z-index:1}.GPexportMenuContent,.GPexportMenuContent a:hover{background-color:#f1f1f1}.GPexportMenuContainer:hover .GPexportMenuContent{display:block}.GPexportMenuContent .container{cursor:pointer;display:block;font-size:14px;margin-bottom:5px;padding-left:15px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.GPexportMenuContent .container input{cursor:pointer;height:0;opacity:0;position:absolute;width:0}.GPexportMenuContent .checkmark{background-color:#eee;border-radius:50%;height:12px;left:0;position:absolute;top:0;width:12px}.GPexportMenuContent .container:hover input~.checkmark{background-color:#ccc}.GPexportMenuContent .container input:checked~.checkmark{background-color:#366291}.GPexportMenuContent .checkmark:after{content:"";display:none;position:absolute}.GPexportMenuContent .container input:checked~.checkmark:after{display:block}.GPexportMenuContent .container .checkmark:after{background:#fff;border-radius:50%;height:4px;left:4px;top:4px;width:4px}.GPgetFeatureInfoPicto{background-image:url(data:image/png;base64,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cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczpHSU1QPSJodHRwOi8vd3d3LmdpbXAub3JnL3htcC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgeG1wTU06RG9jdW1lbnRJRD0iZ2ltcDpkb2NpZDpnaW1wOjliYzYwZTdiLTQ2YTQtNDBmYi1iNTdlLWM2MGY5ZWYzNTc2YSIKICAgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDphMDE5ZDJjNS02YmZkLTQ5YzQtYTczYS0zMGQ3OGE0Y2MyZDUiCiAgIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpkN2U0OWVjNi0wZjQyLTQ5YTEtODQ3NS0zN2Y5N2Y3MGJjZWIiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICBHSU1QOkFQST0iMi4wIgogICBHSU1QOlBsYXRmb3JtPSJMaW51eCIKICAgR0lNUDpUaW1lU3RhbXA9IjE3MTAwODA3MjUxNDU4NjUiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zMCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoxNTAxZWQwNS0xMmQ3LTQzNGMtODY3YS0yYjMyMzIxYTYwYjgiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTGludXgpIgogICAgICBzdEV2dDp3aGVuPSIyMDI0LTAzLTEwVDE1OjI1OjI1KzAxOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PnuaV+YAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAHdElNRQfoAwoOGRnrK4UpAAAB+UlEQVRYw+3YsWoUURTG8TNrikAECYJYiVjFLBhS2GktpPEV8gg+gr2IhbWQRhMQG0stIxaCaNKIjQTExqgBUYOJyc/mLkxmZ3d2dmciSA4sy+58c/73u+fMvXc34iROorXAPFaHCdY1F+vHxIG1Xu6sANLkDGZZlg0wpOFiLWRZtlkKmhSGLKU5HKIZm4M57Oaqc4TTGSPhNO7iHmZafD76OJiLiDcRMR0Re6MkqZw5XMZn7OB6WxUqcgqV+Y2FKs7IrYALuNh2y/U4JWauDOJM1WiB0xFxLiJm0/v3iNgqWwt6t4zZakXObEQ8yLXZ1SzLNtGp5AybOdzHFvZwiNsDdJ2U5qAhzn6+MnU4la2AG/iBDzjThqEc51cy1GemSUPPk+TJEE0Thl7mluU+M40Ywnl8xFcsYqqllruWq8weFsflVIHupMuvcAmfcKtEdyrp/tTlpNWs98wcYmkSTpWhF+nyBrbxCFlThkpOAO8n5VQZuonHeIilITlqGyqY2cezJjhNneXO1jFUtmlOwukMA+ZiA90SXRev88KI+FLDvIh4lzbNSBv1QWOcit8pP7Gc0y6n74qxg294+q85g+AzWMklWin5PFMzZ9nZrHFO1SCKM3VkJicx0wZn1MF08Ta9umPmWEsD3cV8W5zj/nNjdZCZk/jf4y94DaUx429cawAAAABJRU5ErkJggg==);background-position:1px;background-repeat:no-repeat}button[id^=GPgetFeatureInfoPicto-][aria-pressed=true]{background-position:-25px}[id^=GPisochronPanel-]{width:280px}.GPshowIsochronPicto{background-position:1px;background-repeat:no-repeat}.GPisochronPanelClose,.GPshowIsochronPicto{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAAaCAYAAAD43n+tAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIRSURBVFiF7ZbRS1RBFMbPbLq9ldjaY88Zkv1JQRqt+Wf0aCrYBuY/UkRQRFQvQQax+JipEUIoQdHq/nrYb3K8zl33zl20h/vBwnLOmfPNN+fMmWtWoUKFMwPwjiO8Pu/9xOAGDQRqZnYYmLrOuQvD31I51AYJAqbNbNnMfgXm38AyMFV2E8AssKpDy4txwAowX4booogO1WYdYEu/jmwHIqqXEOPzr8VEScwjxXSTREnMSyXZBGaAscA/DtyTOIDnKaKAFsfxGHCB38kWopUiaNVffmC8T9wE8FaxKwk8vpVCrAG1TGU8nsSqeBrJLbXBl5gY4C7wOSNqW+13Y4iistUrLkYE/lTu5PhfAR8ytjmteViYMF9UeTFK3qZ36S9HfJeAP8CDjL2hqq4nkVpfUdFhEcNIjv2ame045/aA22Z2PeMbNbOn4QLn3C6wK38ZxN7Ggd/LKICfwKb+tyMntgGcOAzgO/AjkTM2AJKqFEvuW27s9Oh/aybUch8T+PKmWdaWJiro49kCa+a1ZmFIYvzYjo70ooJu6rS/Ao0B4q8C31TVyYJcZ/aw+iRv+omSmPeKXUrgmeHo0yc6mjOV6gL3i/IYUAdeKMkW0ASuBP6G2mxHMc+A0cJEvVxNVSp3mklUC2imcPgkdSU5CE5nWyK6snXofXUniTkXAFPAIvAJ2Af2gHVgoeidqVChwv+NvxOT737B3Fc7AAAAAElFTkSuQmCC)}button[id^=GPisochronReset]{opacity:.8;transition:opacity .2s ease-out}button[id^=GPisochronReset]:hover{opacity:1}.GPisochronReset{background-color:#366291;background-image:url(data:image/png;base64,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);background-position:-281px}div[id^=GPisochronChoice]{margin:15px auto 5px;width:160px}.GPisochronChoiceAlt input:checked+label+span{color:#366291}input[id^=GPisochronChoiceAltChron]+.GPisochronChoiceAltImg{background-position:-56px 0}input[id^=GPisochronChoiceAltChron]:checked+.GPisochronChoiceAltImg{background-position:-84px 0}input[id^=GPisochronChoiceAltDist]+.GPisochronChoiceAltImg{background-position:-112px 0}input[id^=GPisochronChoiceAltDist]:checked+.GPisochronChoiceAltImg{background-position:-140px 0}.GPisochronChoiceAltImg,.GPisochronOriginPointerImg,.GPisochronTransportImg,input[id^=GPisochronChoiceAltChron]{background-image:url(data:image/png;base64,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)}.GPisochronChoiceAltImg,.GPisochronOriginPointerImg,.GPisochronTransportImg{font-size:0}.GPisoExclusionsOption{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAA4CAYAAADuMJi0AAAE60lEQVRYw+2YWWxUZRTHz/fd7y4zzAzTbaAdpgtQWsBiYVxYGpcEMCwRQkx48KHGhKg0WhESNYglwSUgWCKGTaMRBF4MwShpECUshlJqay2U0LCUwrRAp+0Ms997v8UnEl8Gp9Ppg2Z+bzfnn+/knHvud865AFmy/GfZVVZW/vvb9eduNn7Wc+ixGQ3/pm+UcO735VP3/rpsyc39TudHyXQ4maF61cqfZi97ocbjmVi6YGHNxoOeor3JtDskae606uqzFfPmvRqLxFg4EetIpiXJDJqqOHBwEEjIDyXjiVw4t/S1XD34TKs/MX+z4EEAgK0SwhPtjh+qq6tXBjGOtTY11a31D371qEygRxn3F3vWPVE1deN0G82T+m5BbCAIF+8lBttifLoFQeV0Wf7R7XbndsXird19/TUfAhgZeZ8H7eoXHYVWwzdBFTedsmhScfg0wfQPTRF7FfLdmBRRo4Q9RzTS8aeKRaeERAsC8TmRto30HJKqMCrhIcMUMuMcmADQJAQ5GJ4fqUMpFdE2mXgqOe+ewXhJFCHoJNJxu4omz7bhScVMyj/BeFPGUrlZIROOYRT4C0C0S0h8qUhHAAC2yGTFpUka7Skfx9/DZFZGnH2gEHxYwnc6EIguBYnDqtTzT3uDTFb3VdrEcZfWk5GUrgZxaI4QCyyaBAME04sUzTvL+dBD+xnOu8qiwrIgV1leEuf9JxhvTzu6Bgm5ThXkmNcciriaS8R2lXySTHvUqXb/lqsNp3Ju0qstx2Z7sfTZGuKsLAFkV4RK0J5k2s4wXYqYsO6WyYq0HUYN06c9XgX5SxcBuIt4gvJ40sJi7MaVONtVhGHmqIrmyLPzm29tqqf7ilwHUtHvVAjO9tksWbJkyQzehd7xo5ppUqW2tlbzLp380rhxitdB8q/4fD6acnsaKfX19c7Ji+QNJU/at7mmWaaZpklHNSY+irq6urzSxbBBy1PqEoJZfFdYoK2tjY2Jw4aGBpurJvKOmme8xWTTmgjq1DApAwAxoo6fIkieEnoF2+NvUDVqCekRiNIY4ip1eb1ekvEI39/65nOyO7hWtyWc0biOogkDooYOBhhujLEDAIZG4xADAH/4sH796y42ZWBNxBGrCEZMlNBNER1k8fBtdixwwzzY2toaTCtCr9drLXzKthgSiv7ztycfjvQo4O5fpWqR5eGojg2DCX1IBHUf3n2nSey5cOpCXzrfIXp6WZXXMtdYh8pi74JTL3WTijO913tDq2qXVxplA5vijgdTIvE4RO6zYOwO3t5/GhpbTrYMjnh78nq9VlwRfRmVRdewArM6rgJBTLbxErYEAL4J5vetwFJ4jghQxMNSSAyoO42Ttl0Xz58PpzXqS5JE7G5tqrAbM6lMiyljkimoQg1m8VhK7xrFwTpdixcbAaGz2/I+ekba0dzc/iDt3SIUCtH+Lv+lArWwjWPOOeMVJjI1imgRsyXKDas+mxoc83vKUfOC/dO2lst3M7LM3L816LdLBedlTIKU05lUNfJM2ZzEBZORXzuHrtk+vnSu63JGF9LhvmH9/uVAu8s9MUQFnWUSIweHFJ90z7qlq+n6L2OyAQMA918NdLrcrqgwoQrHyAHWqX49PDzMxsohAIAUuZ0YsHJHSO+G5t7eXj+k8ZsEjfCmsQGABgAmAMQBIJEdN7L8//gb3FshBGMt81oAAAAASUVORK5CYII=)}.GPisochronOriginPointerImg{background-color:#f2f2f2;cursor:pointer;width:28px}.GPisochronChoiceAlt input{display:none}.GPisochronChoiceAltImg{cursor:pointer;display:block;height:28px;margin:auto;width:28px}.GPisochronChoiceAlt span{color:#999;cursor:pointer;display:block}.GPisochronModeLabel{display:block;margin-bottom:5px;text-align:center}input[id^=GPisochronTransportCar]+.GPisochronTransportImg{background-position:-168px 0}input[id^=GPisochronTransportCar]+.GPisochronTransportImg,input[id^=GPisochronTransportCar]:checked+.GPisochronTransportImg{background-image:url(data:image/png;base64,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)}input[id^=GPisochronTransportCar]:checked+.GPisochronTransportImg{background-position:-196px 0}input[id^=GPisochronTransportPedestrian]+.GPisochronTransportImg{background-position:-224px 0}input[id^=GPisochronTransportPedestrian]+.GPisochronTransportImg,input[id^=GPisochronTransportPedestrian]:checked+.GPisochronTransportImg{background-image:url(data:image/png;base64,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)}input[id^=GPisochronTransportPedestrian]:checked+.GPisochronTransportImg{background-position:-252px 0}.GPisochronTransportChoice input{display:none}.GPisochronTransportImg{cursor:pointer;display:inline-block;height:28px;width:28px}.GPisochronTransportImg:first-of-type{margin-left:18px;margin-right:10px}select[id^=GPisochronDirectionSelect]{width:80px}.GPshowIsoExclusionsPicto{right:0;top:250px;transition:all .5s ease-out 0s}.GPisoExclusionsLabel{display:block;font-weight:700;line-height:16px;margin-bottom:10px;text-align:center}.GPisoExclusionsOptions{display:-webkit-flex;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-justify-content:space-around;-ms-flex-pack:distribute;justify-content:space-around}.GPisoExclusionsOption{background-color:#fee;border:1px solid #a77;border-radius:3px;color:#a77;cursor:pointer;display:block;height:28px;line-height:26px;padding-left:28px;padding-right:5px}input:checked+.GPisoExclusionsOption{background-color:#efe;background-position:0 -28px;border:1px solid #797;color:#797}[id^=GPimportPanel-]{width:280px}[id^=GPimportGetCapPanel-],[id^=GPimportMapBoxPanel-]{width:340px}div[id^=GPimportTypeLine-]{border-bottom:1px solid #999;margin-bottom:15px;padding-bottom:15px}div[id^=GPimportChoice-]{margin-bottom:5px;margin-top:5px}.GPshowImportPicto{background-position:1px;background-repeat:no-repeat}.GPimportGetCapPanelClose,.GPimportMapBoxPanelClose,.GPimportPanelClose,.GPshowImportPicto{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAAaCAYAAAD43n+tAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAH7SURBVFiF7dY/aBRhEAXwvcN/sRBBkUNsA8JhoZ1gJaIIamV91SUSFCxtU1oJQS9i0lnZWShYpE5pIYFUNoJIsLGIYhC9n8XOcZt175Ldu2CzD7bYmfne+97O7nybJDVq1KhRFZjFWlyz/3s/lYFDeIjvhviJRRyZAv8cXqA5pqaBp3gwqdglvA8TW+jgNj5HbAOXJ+Cfw5/gWi0yFWaeRU2/kikcx2P8DpKXOJXJn8RSbKYfT/hEBZ2e3VhGI2dmOVfTKytyC59i8Udcy+RA5v4KNiP8BXdLag1epSxW0cx1ZoCVoi6OIm9FJ+BXdOhYrmaXoYgdxiPsRPoNzk3BVL57pcx08C0WrqM9ou4fQ5lcO9YKrs6EpqqZCcLtWPgkv3CMSFG3msEB2/vewHhThcOiCNmi50mSSJLkXpIk3TIbyaEbHIKzLBr7jO0N3JB+2PAapwtqCl856dR7FemvuFNSu2gAVOpSnvgM3gbJFm7uZQhXDc+lNZydgpmVglhlUw3M44f0jFnC0bwh6XRblJ5FO9JJV0pwjJnB2C4c6aVNhVgbH4JoAxcyufOGfxCbuFhR4+AP1pzgTIj2o2Pzue71MDMBf9fw16dwNOc61cf9yoYypNcNBwYVPvwx3AvxYEZOszDVw8I0NAekLbyLqzU14ho1atQ4KPwF7C8m4Xa+2v4AAAAASUVORK5CYII=)}.GPimportMapBoxPanelReturnPicto{background-color:#366291;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4AUXDwQyeFmCzQAAATJJREFUSMftliFLBFEURs/dVUQURJvYLCaLGESz1T9gUJsoWARBEBRM/obFIFgMKxtsNhG2aTUIBqOCySLsHssuTNiVGZ47aU8aZr5537vz3TfvwZAhg0K9UL/U5bLMuuyljFXJYXYOHGVuxcAM1VPg5D+/1sgfZsfAWY9HG+ok0AY+gFfgJSI+UzI7tBht9UHdUqtFzQ5M41GdKZLhQmJMa0A9d6VqqDXT2e41fvQxrQCXQK+X7oGnzvUoMA3MAyvAWEbXjIjVIllW1eseM9/vo59SrzK6ljpXtIGq6k0ew0wcdxntTqGFHxEtYBO4zTPBiBDYBX6SGlAdVRud9baeQ99tunrKz6CizubULnYMn8vczprqW+HdIoEaMF5mhRPqe2kVRsQ30Cj7WLI0PJwNnF82zKAINyZs+wAAAABJRU5ErkJggg==)}.GPimportChoiceAlt input[type=radio]{display:none}.GPimportChoiceAltTxt{color:#bbb;cursor:pointer;display:block;font-weight:700;line-height:28px}input[type=radio]:checked+.GPimportChoiceAltTxt{color:#366291}.GPimportInputLine{display:-ms-flexbox;display:-webkit-box;display:flex;margin-bottom:10px}.GPimportInputLine>*{border:1px solid #999;border-radius:0;display:block;height:28px;line-height:26px}.GPimportInputLine :not(:last-child){border-right:none}.GPimportInputLine :first-child{border-radius:3px 0 0 3px}.GPimportInputLine :last-child{border-radius:0 3px 3px 0}.GPimportInputLine>:not(input){overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap}.GPimportInputLine>input{-webkit-box-flex:1;-ms-flex:1;flex:1;min-width:0;padding:0 5px}.GPimportInputLine>select{-webkit-box-flex:1;-ms-flex:1;flex:1;padding-right:7px}.GPimportInputLine>label{background-color:#f2f2f2;color:#666;cursor:pointer;padding-left:7px;padding-right:9px}.GPimportGetCapProposal{color:#5e5e5e;cursor:pointer;font-size:1em;height:28px;line-height:16px;list-style-type:none;overflow:hidden;padding:6px 10px;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;width:100%}.GPimportGetCapRubriqueTitle,.GPimportMapBoxListSourceTitle,.GPimportMapBoxSourceTitle{color:#5e5e5e}.GPimportGetCapListRubrique,.GPimportGetCapRubrique,.GPimportMapBoxListSource,.GPimportMapBoxSource{list-style-type:none}li.GPimportGetCapListRubrique:before,li.GPimportGetCapRubrique:before,li.GPimportMapBoxListSource:before,li.GPimportMapBoxSource:before{content:"» "}.GPimportGetCapProposal:hover,.GPimportGetCapRubriqueTitle:hover,.GPimportMapBoxSourceTitle:hover{color:#000}.GPimportMapBoxSourceFilter,.GPimportMapBoxSourceScale,.GPimportMapBoxSourceStyle,.GPimportMapBoxSourceVisibility{display:inline-block;margin-left:15px}.GPimportMapBoxJsonEdit{margin:5px;outline:1px solid #ccc;padding:5px}.GPimportMapBoxJsonEdithidden{display:none}.gp-json-string{color:green}.gp-json-number{color:#ff8c00}.gp-json-boolean{color:blue}.gp-json-null{color:#f0f}.gp-json-key{color:red}.GPimportMapBoxSourceVisibilityInput{display:block!important}div[id^=GPlayerInfoPanel]{right:190px}div[id^=GPlayerInfoTitle]{border-bottom:1px solid #366291;color:#366291}.GPlayerAdvancedTools,.GPlayerBasicTools{height:28px;position:relative;width:100%}.GPlayerInfo,.GPlayerInfoOpened,.GPlayerRemove,.GPlayerVisibility{cursor:pointer;height:28px;width:28px}.GPlayerInfo,.GPlayerInfoOpened,.GPlayerName,.GPlayerOpacity,.GPlayerOpacityValue,.GPlayerRemove,.GPlayerVisibility{position:absolute;top:0}.GPghostLayer{opacity:0}.GPlayerBasicTools{background-color:#fff}.GPlayerName{cursor:move;left:28px;line-height:28px;overflow:hidden;padding-left:4px;text-overflow:ellipsis;white-space:nowrap;width:calc(100% - 56px)}.outOfRange .GPlayerName{color:#aaa}.GPlayerAdvancedTools{display:block;max-height:0;opacity:0;transition:max-height .5s ease-out 0s,opacity .5s ease-out 0s}div[id^=GPlayerSwitcher-] input[type=checkbox]:checked+label+.GPlayerAdvancedTools{max-height:28px;opacity:1}.GPlayerInfo,.GPlayerInfoOpened,.GPlayerRemove,.GPlayerVisibility,.GPshowLayerAdvancedTools{background-image:url(data:image/png;base64,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)}.GPlayerOpacity input[type=range]::-webkit-slider-runnable-track{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAECAYAAAAZDrhMAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAwSURBVDiNY/z379//v3//Mvz9+5fh379/DITYxKobKWYxMYwCisBoAFIIRgOQQgAADrTuhXfc36kAAAAASUVORK5CYII=)}.GPlayerOpacity input[type=range]::-moz-range-track{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAECAYAAAAZDrhMAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAwSURBVDiNY/z379//v3//Mvz9+5fh379/DITYxKobKWYxMYwCisBoAFIIRgOQQgAADrTuhXfc36kAAAAASUVORK5CYII=)}.GPlayerOpacity input[type=range]::-ms-track{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAECAYAAAAZDrhMAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAwSURBVDiNY/z379//v3//Mvz9+5fh379/DITYxKobKWYxMYwCisBoAFIIRgOQQgAADrTuhXfc36kAAAAASUVORK5CYII=)}div[id^=GPlayerInfoQuicklook]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAoCAYAAAD+MdrbAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJTSURBVEiJ7ZZdSJNRGMd/59Vo9m6jQYKWRV/MQYGBXSStC2/S27YmXYfQZRexZiBhdNE2ke68qq5rY3rRjRFE1Du0KKIcwQYtaGpCH+r01ZrsPV2lc853c0IE+r87z3P+Px7OOc85B7adROFgcHDQAbRWYtR1fdTv9+vF8do1dCFanE7nU6vVagpbWFgglUq1A89NgQB2ux2Hw2EKVBRl45ypswqtq7BYM/oyD8emSE7rgMTVaKPTtac64E99mZtDKRZzeZobVABef55lPDPH6b2W+k0DH72aYjGX51rnEU4csAGQmJhnYCTNmx/qFSBa7DFdw+RXneYGdQUGcLLJxvF6C78M5VQpT5lNkebpzQJdjTaS0zqJifmVWGJynk/fflNXa7wr5Vm3htlsFsMwADjvtDCeEQyMpDm2bzcA6e85LLWwvy434vNFaqLRrnyhf03r9ff3q6qqthXGJhct9W9nrN1LeaUFoK7GeH/YujScmLWGhRCRl5YPl+nrM0oCNyN3INYL3AbxQAtd6AYhAWqqBX6JR14cOndpF8irB90f7Zl45AlssfW0oKdXIu8qQslshbOjba+SneIOxFavGSG6tKAn6u4ZCiBlsHCeFvKu85sd7AkgKg2ZAdCCnpCU3CtXodmNPaqFvF0rVfcMtyINbzlgRa139nrsDDL/DHCAzAL3twQE2kHYQWalFB1ayNuN4FbVwHjYewfkDSlFRzzsHXP3xI6C8rjU3LLv8l9poYurOywJguGjxCn5pz+HNncgFtkoVw2wCfBVUtWO/nP9AYuuwXn+Xm/WAAAAAElFTkSuQmCC)}div[id^=GPlayerInfoClose]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAgCAYAAAAFQMh/AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGUSURBVEiJ7ZQxT8JQEMf/hxOsDg6GOGtiYgyy0I4Ormj8BBqpZW9HFhNxRKom8AU0tHFRRx1KYlwcQIkrzM4mGnoOtlJKsa/q2N/4ernfu97dAxISEhJ+CYkEyZq1y8w5O9NRUKk44VFMsm7VHIdf2kdb9aicM0JS8BkIuezH3PxgfekKd3cclEqaeQxQmYg2soXt10H74uGnvKkoMROveHFE2JHelusAkz9C0iwDINU9IErRYlTeyIr79vnNgtybBZB3j9ayhZ5b+S3cSvd9F2nY6a46+VfGEeqx1z9mlL9PmJqE4TsoFZSWps9BbHG4PPBdWBpT7Mkva8zOmJzZabYzT3uiUkBguCbUPAy5LMUsQGC4fEpvZdTgFyJanb5qfxKHSbkB4B6g/JccseQC4nCpne6W+gfKtX/V4sgjeyPppgGGb2VwaleLKkA8uphlAFB8WU/sw82JlviJHC4CHgG408oNO90pj6QAQGxXiyoRvPeZwfQclVcIWWspkm4a409lECZJNw1ZaynTYxISEhL+gU/lu7XSwAzyjAAAAABJRU5ErkJggg==)}.GPlayerInfoLink,.GPlayerInfoPopup{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAoCAYAAAD+MdrbAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJTSURBVEiJ7ZZdSJNRGMd/59Vo9m6jQYKWRV/MQYGBXSStC2/S27YmXYfQZRexZiBhdNE2ke68qq5rY3rRjRFE1Du0KKIcwQYtaGpCH+r01ZrsPV2lc853c0IE+r87z3P+Px7OOc85B7adROFgcHDQAbRWYtR1fdTv9+vF8do1dCFanE7nU6vVagpbWFgglUq1A89NgQB2ux2Hw2EKVBRl45ypswqtq7BYM/oyD8emSE7rgMTVaKPTtac64E99mZtDKRZzeZobVABef55lPDPH6b2W+k0DH72aYjGX51rnEU4csAGQmJhnYCTNmx/qFSBa7DFdw+RXneYGdQUGcLLJxvF6C78M5VQpT5lNkebpzQJdjTaS0zqJifmVWGJynk/fflNXa7wr5Vm3htlsFsMwADjvtDCeEQyMpDm2bzcA6e85LLWwvy434vNFaqLRrnyhf03r9ff3q6qqthXGJhct9W9nrN1LeaUFoK7GeH/YujScmLWGhRCRl5YPl+nrM0oCNyN3INYL3AbxQAtd6AYhAWqqBX6JR14cOndpF8irB90f7Zl45AlssfW0oKdXIu8qQslshbOjba+SneIOxFavGSG6tKAn6u4ZCiBlsHCeFvKu85sd7AkgKg2ZAdCCnpCU3CtXodmNPaqFvF0rVfcMtyINbzlgRa139nrsDDL/DHCAzAL3twQE2kHYQWalFB1ayNuN4FbVwHjYewfkDSlFRzzsHXP3xI6C8rjU3LLv8l9poYurOywJguGjxCn5pz+HNncgFtkoVw2wCfBVUtWO/nP9AYuuwXn+Xm/WAAAAAElFTkSuQmCC)}.GPlayerVisibility{background-position:-28px 0;left:0}input[type=checkbox]:checked+.GPlayerVisibility{background-position:0 0}.GPshowLayerAdvancedTools{background-position:-112px 0;right:0;top:0}.GPlayerInfo{background-position:-55px 0;left:0}.GPlayerInfoOpened{background-position:-83px 0;left:0}.GPlayerOpacity{height:28px;left:28px;padding-left:8px;width:calc(100% - 100px)}.GPlayerOpacityValue{cursor:default;font-size:10px;font-style:italic;left:calc(100% - 60px);line-height:28px;width:32px}.GPlayerRemove{background-position:-140px 0;right:0}.GPlayerOpacity input{-webkit-appearance:none;-moz-appearance:none;background:none;cursor:pointer;display:block;height:100%;margin:0;overflow:hidden;padding:0;width:100%}.GPlayerOpacity input[type=range]:focus{box-shadow:none;outline:none}.GPlayerOpacity input[type=range]::-webkit-slider-runnable-track{-webkit-appearance:none;height:3px}.GPlayerOpacity input[type=range]::-webkit-slider-thumb:before{height:3px;left:-200px;pointer-events:none;position:absolute;right:50%;top:0}.GPlayerOpacity input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background-color:#505050;border:2px solid #fff;height:17px;position:relative;top:-7px;width:9px}.GPlayerOpacity input[type=range]::-moz-range-track{height:3px;width:80px}.GPlayerOpacity input[type=range]::-moz-range-thumb{background-color:#505050;border:2px solid #fff;border-radius:0;box-shadow:0;height:13px;position:relative;width:5px}.GPlayerOpacity input[type=range]::-ms-track{border:0;border-color:transparent;border-radius:0;border-width:0;color:transparent;height:3px;width:80px}.GPlayerOpacity input[type=range]::-ms-fill-lower,.GPlayerOpacity input[type=range]::-ms-fill-upper{background:transparent;border-radius:0}.GPlayerOpacity input[type=range]::-ms-thumb{background-color:#505050;border:2px solid #fff;height:13px;width:5px}.GPlayerOpacity input[type=range]::-ms-tooltip{display:none}div[id^=GPlayerInfoPanel]{overflow-y:hidden;padding-bottom:10px;padding-top:10px;position:absolute;top:0}.GPlayerInfoPanelOpened{display:block}.GPlayerInfoPanelClosed{display:none}div[id^=GPlayerInfoContent]{max-height:200px;overflow-y:auto;padding-left:10px;padding-right:10px;position:relative;width:280px}div[id^=GPlayerInfoTitle]{font-size:1.1em;font-weight:700;margin:auto auto 10px;padding-bottom:5px;text-align:center;width:calc(100% - 52px)}div[id^=GPlayerInfoQuicklook]{cursor:pointer;height:20px;left:10px;position:absolute;top:-2px;width:20px}div[id^=GPlayerInfoClose]{cursor:pointer;height:28px;position:absolute;right:10px;top:-8px;width:28px}div[id^=GPlayerInfoDescription]{font-size:.9em}.GPlayerInfoSubtitle{font-weight:700;margin-bottom:4px;margin-top:10px;padding-left:35px}.GPlayerInfoLink,.GPlayerInfoPopup{background-repeat:no-repeat;color:#999;cursor:pointer;line-height:20px;overflow-x:hidden;padding-left:23px;text-overflow:ellipsis;white-space:nowrap}.GPlayerInfoLink{background-position:0 -20px}.GPlayerInfoLink:hover,.GPlayerInfoPopup:hover{color:#333}.GPlayerInfoLink a,.GPlayerInfoLink a:visited -.GPlayerInfoLink a:focus -.GPlayerInfoLink a:hover{color:inherit;text-decoration:none}.GPlocationOpen{background-color:unset}.GPlocationStageRemove{background-position:-84px}.GPlocationStageAdd{background-position:-56px}[id*=GPlocationOriginPointer]+.GPlocationOriginPointerImg{background-position:-1px}[id*=GPlocationOriginPointer]:checked+.GPlocationOriginPointerImg{background-position:-29px}.GPlocationStageFlexInput{max-height:28px;opacity:1}button.GPlocationOriginPointerImg[id*=GPlocationOriginPointerImg]{border-bottom-right-radius:3px;border-right:1px solid #999;border-top-right-radius:3px;width:28px}.GPlocationStageFlexInput{margin-bottom:5px}button[id^=GPshowMeasureAreaPicto-]{background-image:url(data:image/png;base64,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);background-position:-78px;background-repeat:no-repeat}button[id^=GPshowMeasureAreaPicto-][aria-pressed=false]{background-color:rgba(0,60,136,.5)}button[id^=GPshowMeasureAreaPicto-][aria-pressed=true]{background-color:rgba(0,60,136,.7)}button[id^=GPshowMeasureLengthPicto-]{background-image:url(data:image/png;base64,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);background-position:-24px;background-repeat:no-repeat}button[id^=GPshowMeasureLengthPicto-][aria-pressed=false]{background-color:rgba(0,60,136,.5)}button[id^=GPshowMeasureLengthPicto-][aria-pressed=true]{background-color:rgba(0,60,136,.7)}button[id^=GPshowMeasureAzimuthPicto-]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGgAAAAaCAYAAABb9hlrAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4AsJDhwxbX+/1AAABhFJREFUaN7tmn2wVlUVxn+HLyHU4k4KaApCQuXtYxQtU/zAmCBjqGaKKUljajJMKkcyE8mKorCyD83RgoaQLCuxUQNNtMAyHWFEKbIcFSNSRstKlCi8v/557nS6c997z/sBVxrWzJ7zvmevs87e69n7WeuscwqVfVK/FEWxR+7Tb5+rd7+oqBPU+9Xp/88AHQIcuLeBA7weuBV4CFiqTq4X3a7tKPUm9Xj1WvWUGnp7sp2lPq8+ph5WQf8A9bi0Y1s9njp8e6L6V/UM9VB1Rv6f0AxAp6r/VH+mblJn9TE4Hwg4y9SN6h/UEb1cM1W9T92qPrynAYreKer2gDJOfShjP0v9i3p0MxT3FDAceEkfs8Q5wNXA+cCZwGTgGeA2oK2H61YBnwB2ARf0Aa29CfgpcCfwrlDzs0AHcAewBLi5GYAGAJcHpL6Sj2YMH85xDfAIsAwwvF4rJo0JsI8ChwID9yA4U4GbsoiGA1uADwFnB6ydwFuB6xuluMHq+Pwerw7tRudidbW6PPzaalr7eGhtm/ryZEGb1OnqXerBoa61av9urp+i/iDtRzXm0FKKS9+00Noa9Zfq+9WXqkenf2TmcVkzMQi1TZ2nDuumb7S6Qx2r7gq/thKceQFnS4B6RB2VST+bSZOYpLp/DTsD1X67Iy7W8OM71KfVdeq31IvUtlL/yxKDFjWbxaFekMl/pJu+w+KoN6gdyU5aNfnPBPSH1flJCs5NwEcdkuOcgHhuD7a+rl5R5/1fnFYZoJybkUV7r3qJukAdUOoflTkt6AGHofUAdGEAurBG/2fVe9Qr1fNaBM4X4vQH1c9nx0xI35ElvfOjd3Yv9paG4uoZw5fUhVUByv+ZWVS3qN9W7+7M0NI/Rt2szi+da1NPC0N8X/19FvtBjQD0OfXxTHZ2Ddprtn0lTn8gK//W7NCuep+MXpXUv16Axqo71ed6Y4WS72ZlPD9U71A/ph6iTiwtrC3x48XqioC1S/2tek2umaj+Tp3SCEAjQikrShw7pEXAFOrlmeSv1avUn5QmWG6XZGIzK9ruDqABWQDv7Eb/ev8rSyrY/2DGc0Oo7d3q4JJfX6n+OQwzKhQ4R31jjaTlu+q8ZinucPWJBqijFjhX5T5r1MUBZ3I3ugvVf4fraRCgNvX23K8jgBfpm+j/yq5UVHqyvy7jvlY9U92/5NP2+KkzRp6uru/F3hz1hmZrcX8E3pbWWfg7Drgrzyj71VEHXJJng9XAtpzfnmeEsnwZmAvMAK5r8BHlFcA9wKTOgjTw6dgbCny1i35/4Iu92DwDGJ8Hz+8VRbE99Pe6nPtUURRXRLcd2NiLvfXAMa1KEsZk2y7LalTdoO5XYWX3D/eq3hyK+KZ6cijoVSXdbyQuTGtgh3buoIHq36wtW3voO7mXGPQa9Un1PaWq9ZPqrC4+vkad28t4X5Sde3CzAA1JwNsenb8nLR9UwWn94jQT025TF6kn1aC/HXnopAmABtu4rK2QxR2bAuiS1NhmdrMJNlScx0Z1ajMUNwN4EFgADAEWA+OAS4F/Vbh+RGysAg4C7gZWAmu70N9i4L3ANOCWPiw3HV7hxd29oftJwOyiKJZ3Kf30D8VurHC/dWWaG1DHQI8BvgacmP9rgPOA++qc8BPAjcDxcf7g2Cpz/1Lg7cDpwC/2krerdwJH1FA5EtgBbK1gbn0KrZUBOgD4DvC+BNZHUx3+cYPz6UjB8EZgBXBSlwLtcuAtwJuBX7Wqhgk81uC1f2rB/duB31TUXZ8qfK8Adb50nwsMSna1ELgs1dhmZGd2yCrgdmBidtZ1oYnJybhaJTuB0X24ydor0hvABmCkOrwoim09ATQ+x4GhnIuAx1s46OeSTq8Ohz8FjAROyypqhYwBXpuY2YpdOLtBym1P2l1FdgCbElJW9gTQpcBYYP5ujAPPAFOAn+edzSTg/hbaXwScUHrGakY6mgD61Vl844DNCROdx3/0kCisLF4gn10Vydye31s+Bqn62VX8OyWJwuhSOwIYBjzdBbDNwARgWFEU018oAO110ux3cfH7gV0AKwM4qCiKo/YB1EcAVZX/AEA6wl77lvn1AAAAAElFTkSuQmCC);background-position:2px;background-repeat:no-repeat}button[id^=GPshowMeasureAzimuthPicto-][aria-pressed=false]{background-color:rgba(0,60,136,.5)}button[id^=GPshowMeasureAzimuthPicto-][aria-pressed=true]{background-color:rgba(0,60,136,.7)}.GPmeasureTooltip{background:rgba(0,0,0,.5);border-radius:4px;color:#fff;padding:4px 8px;position:relative;white-space:nowrap}.GPmeasureTooltip-measure{font-weight:700}.GPmeasureTooltip-info{font-size:.75em;text-align:center}.GPmeasureTooltip-static{background-color:#fc3;border:1px solid #fff;color:#000}.GPmeasureTooltip-hidden{display:none}.GPmeasureTooltip-info:before,.GPmeasureTooltip-measure:before,.GPmeasureTooltip-static:before{border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid rgba(0,0,0,.5);bottom:-6px;content:"";left:50%;margin-left:-7px;position:absolute}.GPmeasureTooltip-static:before{border-top-color:#fc3}[id^=GPmousePositionPanel-]{width:280px}button[id^=GPshowMousePositionPicto-]{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAAaCAYAAAD43n+tAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAD2SURBVFiF7ZbRDoIwDEUZ36oPRP9GMVF+k1c5vpQ4l24CFkfITsIDY2l70+6yqirsDITcdcSocxdQKHxhjTMEHIE7ED0CgAMuwNkyt7kgEfOUsJ0mSsRcZc9gLsoSoOWTG+C8707WfNqcNSfxRsmnA+qgMyOP1GjOSaxioCklKuyejRhJOtLLYyZI4muilosJC4y89957P2H/LMEJUapZaGzxpuAmrv3Gn0YuNIBFXZqaUMUodszNwjVbUWuQEDPatmrpueuOQu4fq+WoSbwD76uPas1BpwbgZJV/rctpI52KupmIaoHGMndh86wxcpZs1/4KO+UFLQ+rEigj9BAAAAAASUVORK5CYII=);background-position:1px;background-repeat:no-repeat}.GPmousePositionEditTool{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAASCAYAAAAzI3woAAAB40lEQVR42tWWy07CQBSGi8+gPoJLE4SitqC+AioLF9qLuDC6bKuuSNS4QTo1ConWF4AWgz6IlzdB94A9pVNunZluiDjJJA3MdD7+/z9n4DjGyKh3PZjcrIyZAFrOlxfTKrrmVesDA/nPknmVLNwssPbnNPdI0JxHrlSaoyxL5Az3fl1rnFJflpIrhYxi/WCQ8ckr6Hv1AO3SYETD6WTPmj1Bd2wCVELUnQdYIxpulwgFMLxidfsHWy9J6XYjBNk3N3kVtYLvuiQowXCqcBCeou7WAGAUxq0Nr4E9kTZhZdISMkgZSsnmOVaKYJ9vxciBA6VCZQbAjadIFSEzWBlWRtKy9eqDepmi5WMUqmkLWr0aC8ZXQrG+4BCwiQUE9uGgs0I7DBALhhRekmWs9ZNQzQkoQa/bZGWmDDSeGZheVT0zWoJng4I+41q2Vixv+ZbJ6J1mWRRMRNAJHdkLaD8XqMXMkIzeAqDLuDCQmfHPqFBQ9lDKcBCUNskyXkIXQdm3SWVPKW1aS5gc0OzCxugphasJJtgUKqNYHV4x81NtjGGPkSo7WCnC1dFeOUTbpP2eOkV8dVD6TKgUXB1Z3T2hZgSsgExBaEMQ7xkys7RXmmdfro3j4FcnaKGHNbD2//39+EugX0KgD3FX5kMVAAAAAElFTkSuQmCC)}.GPmousePositionCoords,.GPmousePositionLabel{display:inline-block;line-height:20px}.GPmousePositionLabel{font-weight:700;width:100px}.GPmousePositionCoords{width:110px}.GPshowMousePositionSettingsPicto{bottom:5px;right:0;transition:all .5s ease-out 0s}.GPmousePositionSettingsLabel{display:block;font-weight:700;line-height:16px;margin:auto;text-align:center}.GPmousePositionSettingsSelect{margin-top:5px;margin-inline:auto;width:180px}.GPSexagesimal,.GPSexagesimalsec{border:1px solid #ccc;border-radius:4px;margin:0}input:read-only.GPSexagesimal,input:read-only.GPSexagesimalsec{text-align:right}.GPSexagesimal{width:30px}.GPSexagesimalsec{width:45px}.GPmousePositionSexagesimalLabel{font-size:1.2em;padding:0;vertical-align:middle}select.GPmousePositionDirection{border:1px solid #999;margin-left:2px}select.GPmousePositionDirection:disabled{-webkit-appearance:none;-moz-appearance:none;background:transparent;border:none;color:#000}select.GPmousePositionDirection:disabled::-ms-expand{display:none}select.GPmousePositionDirection:disabled::-ms-value{color:#000}.GPmousePositionAltitudeUnits,.GPmousePositionUnits{margin-left:5px}.GPmousePositionPanelEditTools{position:absolute;right:5px;top:20px}.GPmousePositionEditTool{cursor:pointer;display:inline-block;height:18px;width:18px}[id^=GPreverseGeocodingPanel-]{width:280px}.GPshowReverseGeocodingPicto{background-position:1px;background-repeat:no-repeat}.GPreverseGeocodingPanelClose,.GPshowReverseGeocodingPicto{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAAaCAYAAAD43n+tAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAH0SURBVFiF7dY/bE1xFAfwvlZMhFSim0i6mdnNnUWiOqGShqlsSPyJ0VQV+jqUDsQgNrFIECxi0MmmibRTWRph0I/hncfPde9z7/Uakdzv9ju/c77nfN/33vPuwECDBg0a9AsYwUW8wTo+4QUO/evZfgGOYQlfsYpbGM7Je6sY4xX6TUaPwR45LczgdBUhLdyNgdbxEstxXsFoJv8sNvAYV3ENnyP/dQUx36KmnScq5roeORulReF4FD3B7oRsOuLP0Eryd2BfhmOm+4OU7DmbcfZGpkcrYilmywpaCmdGcu7uB9n+P3A8jLzlkj27j1KKNgYzznQxl+diEfkXvCq4mwzCoz3qzyeNr5Rq2ltU1r3yYoJ4Fe9Ty5O7y0E6VlB7IWn8CFtLNy4WVV9MkN6M4ulMfK/OSl7D9py6gzovKzyoKqaEqNxlUYZwWGeb0XlnTuJSiIHxAve6z/m7umISQdl3BuZrCQrSUTzPEK7hCM7gHrZkaubxEe1NEPN3LiXkBzCBMWyL2GKQL2Ko7vAlxczlxOqLKmg8hNtB/sMp7MJh7OmjmO7azl3p/RbVdWohYk/jvFLVOZv5x1pR1AIm4vwhabazItcJPz99cldzxqkNnOqXlqKhzul8YdypWT8VTv22QZOcVuRM1Z+0QYMGDf53fAdKmTphX0Bz5wAAAABJRU5ErkJggg==)}.GPreverseGeocodingReturnPicto{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4AUXDwQyeFmCzQAAATJJREFUSMftliFLBFEURs/dVUQURJvYLCaLGESz1T9gUJsoWARBEBRM/obFIFgMKxtsNhG2aTUIBqOCySLsHssuTNiVGZ47aU8aZr5537vz3TfvwZAhg0K9UL/U5bLMuuyljFXJYXYOHGVuxcAM1VPg5D+/1sgfZsfAWY9HG+ok0AY+gFfgJSI+UzI7tBht9UHdUqtFzQ5M41GdKZLhQmJMa0A9d6VqqDXT2e41fvQxrQCXQK+X7oGnzvUoMA3MAyvAWEbXjIjVIllW1eseM9/vo59SrzK6ljpXtIGq6k0ew0wcdxntTqGFHxEtYBO4zTPBiBDYBX6SGlAdVRud9baeQ99tunrKz6CizubULnYMn8vczprqW+HdIoEaMF5mhRPqe2kVRsQ30Cj7WLI0PJwNnF82zKAINyZs+wAAAABJRU5ErkJggg==);background-position:0;background-repeat:no-repeat}.GPlocationHighlight{background-color:rgba(255,200,0,.25);color:#222}[id^=GProutePanel-]{width:320px}.GPshowRoutePicto{background-position:1px;background-repeat:no-repeat}.GProutePanelClose,.GPshowRoutePicto{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAAaCAYAAAD43n+tAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAE3SURBVFiF7ZZBTkJBDEDnE125MhyHHV5FF0RvI58EOIYuTIw79S5wB3lu+vU7tp8Z6IiLectJp+1L/xRCqFQqfwawATan7sMNhFP3McQoPgAugEcilDiLJXCe0wRwI/d+9dOLaYB74C4n8Rh417rsS+wRAngGLjNkPuTeWpMSmbnE7JKlgCerw0whgIfEmm10bwE0kcwiimlThcbAm4NQzoS6T6nPGhjxczIdKwY+Ta2A+YYShQ55Q5ZUPL08mYTCX0LeGFLlZKSoNaFXYOqQ35JSl4WGl/EkhPDilKtJPDuePRO6OjK3tgAOmlJO0SJvyJBZKWe+UiWEBmS6ta2udK/iJYTK/bAmFC8hdM33Xx91NUeT2gG3XsXdhSTvTCZlbjORaoGZZ+EiQp6cZcZvi3RRqVT+DZ/jc6+cH/zb+QAAAABJRU5ErkJggg==)}.GProuteStageFlexInput{max-height:28px;opacity:1}.GProuteStageFlexInputHidden{max-height:0;opacity:0;overflow:hidden}.GProuteOriginPointerImg,.GProuteStageRemove,.GProuteTransportImg,div[id^=GProuteStageAdd]{background-image:url(data:image/png;base64,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);font-size:0}.GProuteExclusionsOption{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAA4CAYAAADuMJi0AAAE60lEQVRYw+2YWWxUZRTHz/fd7y4zzAzTbaAdpgtQWsBiYVxYGpcEMCwRQkx48KHGhKg0WhESNYglwSUgWCKGTaMRBF4MwShpECUshlJqay2U0LCUwrRAp+0Ms997v8UnEl8Gp9Ppg2Z+bzfnn+/knHvud865AFmy/GfZVVZW/vvb9eduNn7Wc+ixGQ3/pm+UcO735VP3/rpsyc39TudHyXQ4maF61cqfZi97ocbjmVi6YGHNxoOeor3JtDskae606uqzFfPmvRqLxFg4EetIpiXJDJqqOHBwEEjIDyXjiVw4t/S1XD34TKs/MX+z4EEAgK0SwhPtjh+qq6tXBjGOtTY11a31D371qEygRxn3F3vWPVE1deN0G82T+m5BbCAIF+8lBttifLoFQeV0Wf7R7XbndsXird19/TUfAhgZeZ8H7eoXHYVWwzdBFTedsmhScfg0wfQPTRF7FfLdmBRRo4Q9RzTS8aeKRaeERAsC8TmRto30HJKqMCrhIcMUMuMcmADQJAQ5GJ4fqUMpFdE2mXgqOe+ewXhJFCHoJNJxu4omz7bhScVMyj/BeFPGUrlZIROOYRT4C0C0S0h8qUhHAAC2yGTFpUka7Skfx9/DZFZGnH2gEHxYwnc6EIguBYnDqtTzT3uDTFb3VdrEcZfWk5GUrgZxaI4QCyyaBAME04sUzTvL+dBD+xnOu8qiwrIgV1leEuf9JxhvTzu6Bgm5ThXkmNcciriaS8R2lXySTHvUqXb/lqsNp3Ju0qstx2Z7sfTZGuKsLAFkV4RK0J5k2s4wXYqYsO6WyYq0HUYN06c9XgX5SxcBuIt4gvJ40sJi7MaVONtVhGHmqIrmyLPzm29tqqf7ilwHUtHvVAjO9tksWbJkyQzehd7xo5ppUqW2tlbzLp380rhxitdB8q/4fD6acnsaKfX19c7Ji+QNJU/at7mmWaaZpklHNSY+irq6urzSxbBBy1PqEoJZfFdYoK2tjY2Jw4aGBpurJvKOmme8xWTTmgjq1DApAwAxoo6fIkieEnoF2+NvUDVqCekRiNIY4ip1eb1ekvEI39/65nOyO7hWtyWc0biOogkDooYOBhhujLEDAIZG4xADAH/4sH796y42ZWBNxBGrCEZMlNBNER1k8fBtdixwwzzY2toaTCtCr9drLXzKthgSiv7ztycfjvQo4O5fpWqR5eGojg2DCX1IBHUf3n2nSey5cOpCXzrfIXp6WZXXMtdYh8pi74JTL3WTijO913tDq2qXVxplA5vijgdTIvE4RO6zYOwO3t5/GhpbTrYMjnh78nq9VlwRfRmVRdewArM6rgJBTLbxErYEAL4J5vetwFJ4jghQxMNSSAyoO42Ttl0Xz58PpzXqS5JE7G5tqrAbM6lMiyljkimoQg1m8VhK7xrFwTpdixcbAaGz2/I+ekba0dzc/iDt3SIUCtH+Lv+lArWwjWPOOeMVJjI1imgRsyXKDas+mxoc83vKUfOC/dO2lst3M7LM3L816LdLBedlTIKU05lUNfJM2ZzEBZORXzuHrtk+vnSu63JGF9LhvmH9/uVAu8s9MUQFnWUSIweHFJ90z7qlq+n6L2OyAQMA918NdLrcrqgwoQrHyAHWqX49PDzMxsohAIAUuZ0YsHJHSO+G5t7eXj+k8ZsEjfCmsQGABgAmAMQBIJEdN7L8//gb3FshBGMt81oAAAAASUVORK5CYII=)}.GProuteModeLabel{display:block;margin-bottom:5px;text-align:center}.GProuteTransportImg{cursor:pointer;display:inline-block;height:28px;width:28px;content-visibility:hidden}.GProuteTransportImg:first-of-type{margin-left:18px;margin-right:10px}input[id^=GProuteTransportCar]+.GProuteTransportImg{background-position:-112px 0}input[id^=GProuteTransportCar]:checked+.GProuteTransportImg{background-position:-140px 0}input[id^=GProuteTransportPedestrian]+.GProuteTransportImg{background-position:-168px 0}input[id^=GProuteTransportPedestrian]:checked+.GProuteTransportImg{background-position:-196px 0}div[id^=GProuteTransportChoice] input{display:none}select[id^=GProuteComputationSelect]{width:100px}.GProuteResultsDetailsInstructionHighlight{background-color:rgba(255,200,0,.25);color:#222}.GProuteResultStage{display:-webkit-flex;display:-ms-flexbox;display:-webkit-box;display:flex}.GProuteResultStageLabel,.GProuteResultStageValue,.GProuteResultsValueLabel{display:inline-block;line-height:18px}.GProuteResultStageLabel,.GProuteResultsValueLabel{color:#666}.GProuteResultStageLabel{width:60px}.GProuteResultsValueLabel{width:65px}.GProuteResultStageValue{-webkit-flex:1;-webkit-box-flex:1;-ms-flex:1;flex:1;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.GPshowRouteExclusionsPicto{right:0;transition:all .3s ease-out 0s}.GProuteExclusionsLabel{display:block;font-weight:700;line-height:16px;margin-bottom:10px;text-align:center}.GProuteExclusionsOptions{display:-webkit-flex;display:-ms-flexbox;display:-webkit-box;display:flex;-webkit-justify-content:space-around;-ms-flex-pack:distribute;justify-content:space-around}.GProuteExclusionsOption{background-color:#fee;border:1px solid #a77;border-radius:3px;color:#a77;cursor:pointer;display:block;height:28px;line-height:26px;padding-left:28px;padding-right:5px}input:checked+.GProuteExclusionsOption{background-color:#efe;background-position:0 -28px;border:1px solid #797;color:#797}.GPfakeBorder{border-bottom:1px solid #999;display:inline-block;height:14px;width:60px}.GPfakeBorderLeft{margin-left:15px}input[id^=GProuteResultsShowDetails]+label,input[id^=GProuteResultsShowDetails]+label+label{cursor:pointer;font-weight:700;line-height:28px;text-align:center;transition:color .2s ease-out;vertical-align:top;width:130px}input[id^=GProuteResultsShowDetails]+label,input[id^=GProuteResultsShowDetails]:checked+label+label{display:inline-block}input[id^=GProuteResultsShowDetails]+label+label,input[id^=GProuteResultsShowDetails]:checked+label{display:none}input[id^=GProuteResultsShowDetails]+label+label+div+div[id^=GProuteResultsDetails]{max-height:0;opacity:0}input[id^=GProuteResultsShowDetails]:checked+label+label+div+div[id^=GProuteResultsDetails]{max-height:200px;opacity:1}div[id^=GProuteResultsDetails]{overflow-y:auto;transition:max-height .5s ease-in-out .25s,opacity .5s ease-in-out .25s}.GProuteResultsDetailsInstruction,.GProuteResultsDetailsNumber{color:#666;display:inline-block;line-height:16px;margin-top:4px}.GProuteResultsDetailsNumber{font-weight:700;text-align:right;vertical-align:top;width:22px}.GProuteResultsDetailsInstruction{padding-left:5px;width:calc(100% - 30px)}.GPshowSearchEnginePicto{background-image:url(data:image/png;base64,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YWMxMWEiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ZDIyMjI3NzYtNzg5YS00NzdiLTgxNWEtYjMyMTgwMTQ1NTQwIgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MDVmZGI3NTYtYjAzNi00NDZmLTkwNGYtOTIwZTg5NTUzNjZlIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iTGludXgiCiAgIEdJTVA6VGltZVN0YW1wPSIxNzEzNTM5NTY4NjIxOTY4IgogICBHSU1QOlZlcnNpb249IjIuMTAuMzAiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiCiAgIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6NTlmNGRjNGYtYmM1My00YjcyLTkxOTktYWU4ZDM1YThjNTBjIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKExpbnV4KSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyNC0wNC0xNVQxOToxNjo1MyswMjowMCIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozZmQ3MGZkYi0yMDBhLTQ3YjYtOGI3Yi05M2Q5NGZkZjI4OWMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTGludXgpIgogICAgICBzdEV2dDp3aGVuPSIyMDI0LTA0LTE5VDE3OjEyOjQ4KzAyOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Plysf0sAAAAGYktHRAAAAAAAkX5LGK0AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfoBBMPDDAA31VjAAAI9klEQVR42u2bf2xVZxnHP0/DKFsBIaXLcCPImNMmduLUlSrMDFAzN0WXYXCTkDpDR3AcRWIHMxH+WMZ+oDtGaF2M+xHd0HUzusURl7rgxhioBIJmXUC21TF/QAeza8eK7vGP85z2vefe295z7mm5ac6T3Nx73vO+57nnOc/3+fkeyCijjDLKKKOMKoRU9WOqOj2TREYZxQfPJFV9VVXfUNX6TCIZZRQPQK0a0AFVrUrxuptUdeUY/P9mVW0eP0/E3wT+yjHg0xx80n8gV6rqL1T1dVUdUNVjqrpDVReOguVvU9U9qlrrjNfaWJuqTkqBzzmqeqMBpcYZrzEl7zUALUnx3maqap/JrnqUAaSqquMEPDPB7wP/GPjVo8xLg088kuEUDfghcPMw69uBW0Tkv2kACHjbDv8B/Nx+3wjMtN/VIjJQLoCAH9nhm8Be+90IXA18CHhKRD6XolI/BKywwztEZOMogeccIJTPRBE5k6KCTQJ+AMwDrgWvx8ZrgSeBA8C3wDudIs8cuYG3cZTAkyM38M6kAaB2oMUO/wU8ArwGXATcAJxv57aLyJoUHv4S4OkRpi0Rkc4y+dQD3yxwaiqwDKgClorIEykp9SXAYWfof8B0EelNETjXAxuAyyOn9gNbROTRlAA0ooEDbyAlpS4oN/B6UwTOsHID79FEAFLVK4Fddvg0cL2I/Mc5/x6gAwjDnIUi8lwZCtAIPAZc6Ay/Zf+vxhk7BlwnIvsS8pljHnWa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);background-position:0;background-repeat:no-repeat}.GPshowAdvancedSearch{background-position:-26px}.GPshowAdvancedSearch,.GPshowGeolocate{background-image:url(data:image/png;base64,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YWMxMWEiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ZDIyMjI3NzYtNzg5YS00NzdiLTgxNWEtYjMyMTgwMTQ1NTQwIgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MDVmZGI3NTYtYjAzNi00NDZmLTkwNGYtOTIwZTg5NTUzNjZlIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iTGludXgiCiAgIEdJTVA6VGltZVN0YW1wPSIxNzEzNTM5NTY4NjIxOTY4IgogICBHSU1QOlZlcnNpb249IjIuMTAuMzAiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiCiAgIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6NTlmNGRjNGYtYmM1My00YjcyLTkxOTktYWU4ZDM1YThjNTBjIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKExpbnV4KSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyNC0wNC0xNVQxOToxNjo1MyswMjowMCIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozZmQ3MGZkYi0yMDBhLTQ3YjYtOGI3Yi05M2Q5NGZkZjI4OWMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTGludXgpIgogICAgICBzdEV2dDp3aGVuPSIyMDI0LTA0LTE5VDE3OjEyOjQ4KzAyOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Plysf0sAAAAGYktHRAAAAAAAkX5LGK0AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfoBBMPDDAA31VjAAAI9klEQVR42u2bf2xVZxnHP0/DKFsBIaXLcCPImNMmduLUlSrMDFAzN0WXYXCTkDpDR3AcRWIHMxH+WMZ+oDtGaF2M+xHd0HUzusURl7rgxhioBIJmXUC21TF/QAeza8eK7vGP85z2vefe295z7mm5ac6T3Nx73vO+57nnOc/3+fkeyCijjDLKKKOMKoRU9WOqOj2TREYZxQfPJFV9VVXfUNX6TCIZZRQPQK0a0AFVrUrxuptUdeUY/P9mVW0eP0/E3wT+yjHg0xx80n8gV6rqL1T1dVUdUNVjqrpDVReOguVvU9U9qlrrjNfaWJuqTkqBzzmqeqMBpcYZrzEl7zUALUnx3maqap/JrnqUAaSqquMEPDPB7wP/GPjVo8xLg088kuEUDfghcPMw69uBW0Tkv2kACHjbDv8B/Nx+3wjMtN/VIjJQLoCAH9nhm8Be+90IXA18CHhKRD6XolI/BKywwztEZOMogeccIJTPRBE5k6KCTQJ+AMwDrgWvx8ZrgSeBA8C3wDudIs8cuYG3cZTAkyM38M6kAaB2oMUO/wU8ArwGXATcAJxv57aLyJoUHv4S4OkRpi0Rkc4y+dQD3yxwaiqwDKgClorIEykp9SXAYWfof8B0EelNETjXAxuAyyOn9gNbROTRlAA0ooEDbyAlpS4oN/B6UwTOsHID79FEAFLVK4Fddvg0cL2I/Mc5/x6gAwjDnIUi8lwZCtAIPAZc6Ay/Zf+vxhk7BlwnIvsS8pljHnWa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);background-repeat:no-repeat;transition:border-radius .5s ease-out 0s}.GPshowGeolocate{background-position:-102px}.GPshowSearchByCoordinate{background-image:url(data:image/png;base64,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YWMxMWEiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ZDIyMjI3NzYtNzg5YS00NzdiLTgxNWEtYjMyMTgwMTQ1NTQwIgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MDVmZGI3NTYtYjAzNi00NDZmLTkwNGYtOTIwZTg5NTUzNjZlIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iTGludXgiCiAgIEdJTVA6VGltZVN0YW1wPSIxNzEzNTM5NTY4NjIxOTY4IgogICBHSU1QOlZlcnNpb249IjIuMTAuMzAiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiCiAgIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6NTlmNGRjNGYtYmM1My00YjcyLTkxOTktYWU4ZDM1YThjNTBjIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKExpbnV4KSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyNC0wNC0xNVQxOToxNjo1MyswMjowMCIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozZmQ3MGZkYi0yMDBhLTQ3YjYtOGI3Yi05M2Q5NGZkZjI4OWMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTGludXgpIgogICAgICBzdEV2dDp3aGVuPSIyMDI0LTA0LTE5VDE3OjEyOjQ4KzAyOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Plysf0sAAAAGYktHRAAAAAAAkX5LGK0AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfoBBMPDDAA31VjAAAI9klEQVR42u2bf2xVZxnHP0/DKFsBIaXLcCPImNMmduLUlSrMDFAzN0WXYXCTkDpDR3AcRWIHMxH+WMZ+oDtGaF2M+xHd0HUzusURl7rgxhioBIJmXUC21TF/QAeza8eK7vGP85z2vefe295z7mm5ac6T3Nx73vO+57nnOc/3+fkeyCijjDLKKKOMKoRU9WOqOj2TREYZxQfPJFV9VVXfUNX6TCIZZRQPQK0a0AFVrUrxuptUdeUY/P9mVW0eP0/E3wT+yjHg0xx80n8gV6rqL1T1dVUdUNVjqrpDVReOguVvU9U9qlrrjNfaWJuqTkqBzzmqeqMBpcYZrzEl7zUALUnx3maqap/JrnqUAaSqquMEPDPB7wP/GPjVo8xLg088kuEUDfghcPMw69uBW0Tkv2kACHjbDv8B/Nx+3wjMtN/VIjJQLoCAH9nhm8Be+90IXA18CHhKRD6XolI/BKywwztEZOMogeccIJTPRBE5k6KCTQJ+AMwDrgWvx8ZrgSeBA8C3wDudIs8cuYG3cZTAkyM38M6kAaB2oMUO/wU8ArwGXATcAJxv57aLyJoUHv4S4OkRpi0Rkc4y+dQD3yxwaiqwDKgClorIEykp9SXAYWfof8B0EelNETjXAxuAyyOn9gNbROTRlAA0ooEDbyAlpS4oN/B6UwTOsHID79FEAFLVK4Fddvg0cL2I/Mc5/x6gAwjDnIUi8lwZCtAIPAZc6Ay/Zf+vxhk7BlwnIvsS8pljHnWa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);background-position:-76px;background-repeat:no-repeat;transition:border-radius .5s ease-out 0s}.GPsearchInputReset{background-image:url(data:image/png;base64,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IHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDo4ZDc5MTIyYy0xNDNiLTQwMDItOGExOS02ODEyYTA4ZmRiMzgiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6N2FlNWZmMzEtNzVlYS00NWQ0LWI5MzktOWVkYmE3N2M0YjQ3IgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NDU3NDBkYTQtYmZlMS00YWFlLThjMDEtZDliZDVhOWY0ZTBiIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iTGludXgiCiAgIEdJTVA6VGltZVN0YW1wPSIxNzEzNTM5MDc3OTM4NDkxIgogICBHSU1QOlZlcnNpb249IjIuMTAuMzAiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiCiAgIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ZjJmYTMwMGMtZWRlMy00YWNhLTkyODQtYmRiMTI4NDFiMWIxIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKExpbnV4KSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyNC0wNC0xOVQxNzowNDozNyswMjowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz69OJaNAAAABmJLR0QAAAAAAJF+SxitAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH6AQTDwQlpds7gAAAAYdJREFUWMPtl11OwkAURs8tK2AZvrknNVJB3EK3wE/9gz355jZ4N6GfDxSc1DJMaUs0mfPU0Ena03uZ7w5EIpFIJBKJ/CUk3Ul6k5R41pikhaRJd0+eCWYiyxLP29lhXQAWIgu8AgmwBu7NrKjKAgtgDAiYmtmyvaxDthmQZcVv2XnltyevUxLw5Gtn3S2wLAVd2byU3X/Eq87bLBtud4I+2dOECE8At1op8C4pcSqbOvdXwGN7w2nNu82LXXsfkc02g9Yt7VRxXsrvWQNfwENFdlRt+Ra7R3gVa1v+TGGPNP3JNpAOlG0kfEK6djO7iHQD2dD/cMhHMv4JScPqLpzd2OUG8OZ0by2dDbf+nD5D+IjsqowjnMjqWDpw02ognbSQHZXxs+xH2hc9NZEVKB0yaeWV6HkBxmamyuDhZvGzmY07nbQO2WzyV7/9pPUBFE5lJ3tZgPJ67FRawGf3k9Zm8CMLu+tp0svOJimVlLsj5ZHDQy4p7fzwgKyrw0MkEolEIpHIxfgGwh3Z0ws3xlMAAAAASUVORK5CYII=);background-position:0}button[id^=GPsearchInputReset]{border-bottom-right-radius:5px;border-top-right-radius:5px;height:32px;width:32px}button[id^=GPadvancedSearchClose],button[id^=GPcoordinateSearchClose],button[id^=GPgeocodeResultsClose]{height:32px;right:0;top:0;width:30px}button[id^=GPcoordinateSearchClose],button[id^=GPgeocodeResultsClose]{background-position:0 0}button[id^=GPadvancedSearchClose]{background-repeat:no-repeat}button[id^=GPcoordinateSearchClose],button[id^=GPgeocodeResultsClose]{background-image:url(data:image/png;base64,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IHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDo4ZDc5MTIyYy0xNDNiLTQwMDItOGExOS02ODEyYTA4ZmRiMzgiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6N2FlNWZmMzEtNzVlYS00NWQ0LWI5MzktOWVkYmE3N2M0YjQ3IgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NDU3NDBkYTQtYmZlMS00YWFlLThjMDEtZDliZDVhOWY0ZTBiIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iTGludXgiCiAgIEdJTVA6VGltZVN0YW1wPSIxNzEzNTM5MDc3OTM4NDkxIgogICBHSU1QOlZlcnNpb249IjIuMTAuMzAiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiCiAgIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6ZjJmYTMwMGMtZWRlMy00YWNhLTkyODQtYmRiMTI4NDFiMWIxIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKExpbnV4KSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyNC0wNC0xOVQxNzowNDozNyswMjowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz69OJaNAAAABmJLR0QAAAAAAJF+SxitAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH6AQTDwQlpds7gAAAAYdJREFUWMPtl11OwkAURs8tK2AZvrknNVJB3EK3wE/9gz355jZ4N6GfDxSc1DJMaUs0mfPU0Ena03uZ7w5EIpFIJBKJ/CUk3Ul6k5R41pikhaRJd0+eCWYiyxLP29lhXQAWIgu8AgmwBu7NrKjKAgtgDAiYmtmyvaxDthmQZcVv2XnltyevUxLw5Gtn3S2wLAVd2byU3X/Eq87bLBtud4I+2dOECE8At1op8C4pcSqbOvdXwGN7w2nNu82LXXsfkc02g9Yt7VRxXsrvWQNfwENFdlRt+Ra7R3gVa1v+TGGPNP3JNpAOlG0kfEK6djO7iHQD2dD/cMhHMv4JScPqLpzd2OUG8OZ0by2dDbf+nD5D+IjsqowjnMjqWDpw02ognbSQHZXxs+xH2hc9NZEVKB0yaeWV6HkBxmamyuDhZvGzmY07nbQO2WzyV7/9pPUBFE5lJ3tZgPJ67FRawGf3k9Zm8CMLu+tp0svOJimVlLsj5ZHDQy4p7fzwgKyrw0MkEolEIpHIxfgGwh3Z0ws3xlMAAAAASUVORK5CYII=)}button[id^=GPadvancedSearchClose]{background-image:url(data:image/png;base64,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YWMxMWEiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ZDIyMjI3NzYtNzg5YS00NzdiLTgxNWEtYjMyMTgwMTQ1NTQwIgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MDVmZGI3NTYtYjAzNi00NDZmLTkwNGYtOTIwZTg5NTUzNjZlIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iTGludXgiCiAgIEdJTVA6VGltZVN0YW1wPSIxNzEzNTM5NTY4NjIxOTY4IgogICBHSU1QOlZlcnNpb249IjIuMTAuMzAiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiCiAgIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6NTlmNGRjNGYtYmM1My00YjcyLTkxOTktYWU4ZDM1YThjNTBjIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKExpbnV4KSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyNC0wNC0xNVQxOToxNjo1MyswMjowMCIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozZmQ3MGZkYi0yMDBhLTQ3YjYtOGI3Yi05M2Q5NGZkZjI4OWMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTGludXgpIgogICAgICBzdEV2dDp3aGVuPSIyMDI0LTA0LTE5VDE3OjEyOjQ4KzAyOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Plysf0sAAAAGYktHRAAAAAAAkX5LGK0AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfoBBMPDDAA31VjAAAI9klEQVR42u2bf2xVZxnHP0/DKFsBIaXLcCPImNMmduLUlSrMDFAzN0WXYXCTkDpDR3AcRWIHMxH+WMZ+oDtGaF2M+xHd0HUzusURl7rgxhioBIJmXUC21TF/QAeza8eK7vGP85z2vefe295z7mm5ac6T3Nx73vO+57nnOc/3+fkeyCijjDLKKKOMKoRU9WOqOj2TREYZxQfPJFV9VVXfUNX6TCIZZRQPQK0a0AFVrUrxuptUdeUY/P9mVW0eP0/E3wT+yjHg0xx80n8gV6rqL1T1dVUdUNVjqrpDVReOguVvU9U9qlrrjNfaWJuqTkqBzzmqeqMBpcYZrzEl7zUALUnx3maqap/JrnqUAaSqquMEPDPB7wP/GPjVo8xLg088kuEUDfghcPMw69uBW0Tkv2kACHjbDv8B/Nx+3wjMtN/VIjJQLoCAH9nhm8Be+90IXA18CHhKRD6XolI/BKywwztEZOMogeccIJTPRBE5k6KCTQJ+AMwDrgWvx8ZrgSeBA8C3wDudIs8cuYG3cZTAkyM38M6kAaB2oMUO/wU8ArwGXATcAJxv57aLyJoUHv4S4OkRpi0Rkc4y+dQD3yxwaiqwDKgClorIEykp9SXAYWfof8B0EelNETjXAxuAyyOn9gNbROTRlAA0ooEDbyAlpS4oN/B6UwTOsHID79FEAFLVK4Fddvg0cL2I/Mc5/x6gAwjDnIUi8lwZCtAIPAZc6Ay/Zf+vxhk7BlwnIvsS8pljHnWa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);background-position:-50px 3px}form[id^=GPsearchInput-] input{border:1px solid #999;border-bottom-right-radius:5px;border-top-right-radius:5px;color:#333;display:block;font-size:1em;padding:0 30px 0 5px;width:100%}form[id^=GPsearchInput-] input:disabled{background-color:#ddd;color:#999}.GPsearchInputText{height:32px}dialog[id^=GPgeocodeResultsList],div[id^=GPautoCompleteList]{background-color:#fff;max-height:140px;position:absolute;width:280px}div[id^=GPautoCompleteList]{top:35px}dialog[id^=GPgeocodeResultsList]{border-radius:4px;overflow:hidden;position:absolute;top:35px}div[id^=GPgeocodeResults-]{background-color:#fff;max-height:140px;overflow-y:auto;position:relative;width:100%}.GPadvancedSearchCodeLabel,.GPadvancedSearchFilterLabel,.GPcoordinateSearchLabel{max-width:105px}.GPadvancedSearchCode,.GPadvancedSearchCodeLabel,.GPcoordinateSearchSystemsLabel,.GPcoordinateSearchSystemsSelect,div[id^=GPadvancedSearchFilters]{margin-top:15px}.GPadvancedSearchFilterInput,.GPadvancedSearchFilterLabel,.GPcoordinateSearchInput,.GPcoordinateSearchLabel,.GPcoordinateSearchSystemsLabel,.GPcoordinateSearchSystemsSelect,.GPcoordinateSearchUnitsLabel,.GPcoordinateSearchUnitsSelect{margin-bottom:5px}.GPshowToolBoxPicto{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAlqAAAJagFGUcfpAAAAB3RJTUUH4AsKDCgkqrnTSAAAAw1JREFUSMe9ll2IlVUUhp9vnEintH+FulAyI+uihClKjSZtQJAJrRnDoKt+oCIIjSIrDCokKXQiCqkuTMFAJtQLCwItMsQbURmjiRIK+pmSoSjJ/JmnC98je6ZzjmVMCzbnO/vstd691nrf9R0YA1NRn2SsTX1E/UM9vVc1OdwC3A7cBLQD1wE/Al8AA0BfVVXf1vFbAmwCjgPjq+oUREsDkBuA3UBfwL4EXgS2AgJLgIPqw2pV+HUCG4B9/yTtF9Rj6pvqBeo4db7apU5N/VGXqofVHeo09Ub1N3Wdeo/6Z1m60SAL1KPqrQnWqR5Qt6pvqYfU1WqbWqnvqt+p89Sf1T61pSmQOkH9Wl2ZLDaru9T2gLapH6mvB6RXHVRvU79Rd6rnqteoH6vHGwEtV7/K4ZXq+qJME9VP1JfzfZU6lMwPqnvVSfltkvpMyl8X6L3ccmIyayuAdqjP5flZ9deA7M7lpqjjC5+eZkAH1AfT5LVxaFUfV39JoGXq72qHul39Qb0ypX5fvaIRUEnv6dHIZGAwe28Ac4DngQeAl4DFeZ4NLAAOAb3ZP1nEG6HREmgAmAEcBmYCTwFTgaXAEPAK0AMsBO4G7gT2A08Aj9YKM+qzbul61Q0hQ7+6L43tCVW71RXqCXVRUaJhdaOnbHIY2d2Mdd3q96F5e0TYFV3dl/4Nq/cHZE7m2avqLQXQeTlzohFQm/q5+k4C3ZFAD6mL4/h0frs6U2FzMpgdoEujq371ZCMg1GvDqjXqkTCuI1mtyZnLQv9dYWItO9VLwsC7GgIVYPfGaYU6K5rZmJtPUPeoAwla85lbALWcEagA61Svyoj5QD0nAbaoP0U71AJFvKoX50J/A2odDVRVFWo/8Fk00p13y2tAJzAv+6cvVmjGYo3QUWudjC4EPgSORjNHgGXAY3kfzcoqbcaZ9NM6eoID24CLMhGGgA5geabFzVn1bBAYBs4HLm/Wm3HqttB2ZtHof7va1U/Ts7oZvQ10AWuB67PO1vYAc+tls9qxsZETtinf/6PV/gX9b/YXjLd1o+WqCcMAAAAASUVORK5CYII=);background-repeat:no-repeat} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/geoportal-extensions-openlayers-1.0.0-beta.15.tgz b/build/release/geoportal-extensions-openlayers/geoportal-extensions-openlayers-1.0.0-beta.15.tgz deleted file mode 100644 index 2a95d55613baff0d6b57837564841ccce944ecd8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 637546 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∾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

#&I=l4YB;sP2CzGLT7;P^V3EIWL{xjkStHD3 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�aE;I9ALCzh<+qP$_E$f%#`zza13r?K{dQ#e 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

K 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νBRcW{Ns^VIT+t3tOtt-oO^yMpB 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Ψ&70vmXN*e@#l?{IL}JDkhVq)^uD3AZ47 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

87U>8#6J^+~OUyda0L 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�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%0Ds(po)H1nCx(Ul^?PtPtyps*X7_?tb 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

hR$H$|6U2m6K+s(OWbLGkK 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 diff --git a/build/release/geoportal-extensions-openlayers/package.json b/build/release/geoportal-extensions-openlayers/package.json deleted file mode 100644 index 74f9046d2..000000000 --- a/build/release/geoportal-extensions-openlayers/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "geoportal-extensions-openlayers", - "description": "French Geoportal Extensions for OpenLayers libraries", - "version": "1.0.0-beta.15", - "date": "29/04/2024", - "main": "src/index.js", - "type": "module", - "directories": {}, - "engines": { - "node": ">=20" - }, - "scripts": {}, - "repository": { - "type": "git", - "url": "https://github.com/IGNF/geoportal-extensions-openlayers.git" - }, - "author": "IGNF", - "keywords": [ - "geoportail", - "geoplateforme", - "javascript", - "OpenLayers 8" - ], - "license": "CECILL-B", - "bugs": { - "url": "https://github.com/IGNF/geoportal-extensions-openlayers/issues" - }, - "homepage": "https://github.com/IGNF/geoportal-extensions-openlayers#readme", - "dependencies": { - "@gouvfr/dsfr": "^1.11.0", - "eventbusjs": "0.2.0", - "geoportal-access-lib": "3.4.1", - "loglevel": "^1.9.1", - "ol": "8.2.0", - "ol-mapbox-style": "12.2.0", - "proj4": "2.10.0", - "sortablejs": "1.15.2" - }, - "devDependencies": {} -} diff --git a/build/release/geoportal-extensions-openlayers/src/index.d.ts b/build/release/geoportal-extensions-openlayers/src/index.d.ts deleted file mode 100644 index b84118843..000000000 --- a/build/release/geoportal-extensions-openlayers/src/index.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -export { default as GfiUtils } from "./packages/Controls/Utils/Gfi"; -export { default as InteractionsUtils } from "./packages/Controls/Utils/Interactions"; -export { default as KML } from "./packages/Formats/KML"; -export { default as GPX } from "./packages/Formats/GPX"; -export { default as GeoJSON } from "./packages/Formats/GeoJSON"; -export { default as WMTS } from "./packages/Sources/WMTS"; -export { default as SourceWMTS } from "./packages/Layers/SourceWMTS"; -export { default as SourceWMS } from "./packages/Layers/SourceWMS"; -export { default as LayerWMTS } from "./packages/Layers/LayerWMTS"; -export { default as LayerWMS } from "./packages/Layers/LayerWMS"; -export { default as LayerMapBox } from "./packages/Layers/LayerMapBox"; -export { default as LayerSwitcher } from "./packages/Controls/LayerSwitcher/LayerSwitcher"; -export { default as GetFeatureInfo } from "./packages/Controls/GetFeatureInfo/GetFeatureInfo"; -export { default as SearchEngine } from "./packages/Controls/SearchEngine/SearchEngine"; -export { default as MousePosition } from "./packages/Controls/MousePosition/MousePosition"; -export { default as Drawing } from "./packages/Controls/Drawing/Drawing"; -export { default as Route } from "./packages/Controls/Route/Route"; -export { default as Isocurve } from "./packages/Controls/Isocurve/Isocurve"; -export { default as ReverseGeocode } from "./packages/Controls/ReverseGeocode/ReverseGeocode"; -export { default as LocationSelector } from "./packages/Controls/LocationSelector/LocationSelector"; -export { default as LayerImport } from "./packages/Controls/LayerImport/LayerImport"; -export { default as GeoportalAttribution } from "./packages/Controls/Attribution/GeoportalAttribution"; -export { default as ElevationPath } from "./packages/Controls/ElevationPath/ElevationPath"; -export { default as MeasureLength } from "./packages/Controls/Measures/MeasureLength"; -export { default as MeasureArea } from "./packages/Controls/Measures/MeasureArea"; -export { default as MeasureAzimuth } from "./packages/Controls/Measures/MeasureAzimuth"; -export { default as ButtonExport } from "./packages/Controls/Export/Export"; -export { default as EditorStyle } from "./packages/Controls/Editor/Style"; -export { default as EditorFilter } from "./packages/Controls/Editor/Filter"; -export { default as EditorLayer } from "./packages/Controls/Editor/Layer"; -export { default as EditorThemes } from "./packages/Controls/Editor/Themes"; -export { default as EditorLegend } from "./packages/Controls/Editor/Legend"; -export { default as EditorGroup } from "./packages/Controls/Editor/Group"; -export { default as EditorSearch } from "./packages/Controls/Editor/Search"; -export { default as Editor } from "./packages/Controls/Editor/Editor"; -export { default as HelperUtils } from "./packages/Utils/Helper"; -export { default as LayerUtils } from "./packages/Utils/LayerUtils"; -export { default as ProxyUtils } from "./packages/Utils/ProxyUtils"; -export { default as ColorUtils } from "./packages/Utils/ColorUtils"; -export { default as MathUtils } from "./packages/Utils/MathUtils"; -export { default as LoggerUtils } from "./packages/Utils/LoggerByDefault"; -export { default as CRS } from "./packages/CRS/CRS"; -/** Version */ -export const version: any; -/** Publication date */ -export const date: any; -export { default as MarkersUtils, default as Markers } from "./packages/Controls/Utils/Markers"; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/index.d.ts.map b/build/release/geoportal-extensions-openlayers/src/index.d.ts.map deleted file mode 100644 index 70186a797..000000000 --- a/build/release/geoportal-extensions-openlayers/src/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA,cAAc;AACd,0BAAmC;AACnC,uBAAuB;AACvB,uBAA6B"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/index.js b/build/release/geoportal-extensions-openlayers/src/index.js deleted file mode 100644 index 08cb10f8e..000000000 --- a/build/release/geoportal-extensions-openlayers/src/index.js +++ /dev/null @@ -1,67 +0,0 @@ -import Pkg from "../package.json"; - -// utilitaires liés à OpenLayers -export {default as GfiUtils} from "./packages/Controls/Utils/Gfi"; -export {default as InteractionsUtils} from "./packages/Controls/Utils/Interactions"; -export {default as MarkersUtils} from "./packages/Controls/Utils/Markers"; - -// formats -export { default as KML } from "./packages/Formats/KML"; -export { default as GPX } from "./packages/Formats/GPX"; -export { default as GeoJSON } from "./packages/Formats/GeoJSON"; - -// couches -export { default as WMTS } from "./packages/Sources/WMTS"; -export { default as SourceWMTS } from "./packages/Layers/SourceWMTS"; -export { default as SourceWMS } from "./packages/Layers/SourceWMS"; -export { default as LayerWMTS } from "./packages/Layers/LayerWMTS"; -export { default as LayerWMS } from "./packages/Layers/LayerWMS"; -export { default as LayerMapBox } from "./packages/Layers/LayerMapBox"; - -// controles -export { default as LayerSwitcher } from "./packages/Controls/LayerSwitcher/LayerSwitcher"; -export { default as GetFeatureInfo } from "./packages/Controls/GetFeatureInfo/GetFeatureInfo"; -export { default as SearchEngine } from "./packages/Controls/SearchEngine/SearchEngine"; -export { default as MousePosition } from "./packages/Controls/MousePosition/MousePosition"; -export { default as Drawing } from "./packages/Controls/Drawing/Drawing"; -export { default as Route } from "./packages/Controls/Route/Route"; -export { default as Isocurve } from "./packages/Controls/Isocurve/Isocurve"; -export { default as ReverseGeocode } from "./packages/Controls/ReverseGeocode/ReverseGeocode"; -export { default as LocationSelector } from "./packages/Controls/LocationSelector/LocationSelector"; -export { default as LayerImport } from "./packages/Controls/LayerImport/LayerImport"; -export { default as GeoportalAttribution } from "./packages/Controls/Attribution/GeoportalAttribution"; -export { default as Markers } from "./packages/Controls/Utils/Markers"; -export { default as ElevationPath } from "./packages/Controls/ElevationPath/ElevationPath"; -export { default as MeasureLength } from "./packages/Controls/Measures/MeasureLength"; -export { default as MeasureArea } from "./packages/Controls/Measures/MeasureArea"; -export { default as MeasureAzimuth } from "./packages/Controls/Measures/MeasureAzimuth"; -export { default as ButtonExport } from "./packages/Controls/Export/Export"; - -// proj4 -export { default as Proj4 } from "proj4"; - -// Editeur de style -export { default as EditorStyle } from "./packages/Controls/Editor/Style"; -export { default as EditorFilter } from "./packages/Controls/Editor/Filter"; -export { default as EditorLayer } from "./packages/Controls/Editor/Layer"; -export { default as EditorThemes } from "./packages/Controls/Editor/Themes"; -export { default as EditorLegend } from "./packages/Controls/Editor/Legend"; -export { default as EditorGroup } from "./packages/Controls/Editor/Group"; -export { default as EditorSearch } from "./packages/Controls/Editor/Search"; -export { default as Editor } from "./packages/Controls/Editor/Editor"; - -// utilitaires -export { default as HelperUtils } from "./packages/Utils/Helper"; -export { default as LayerUtils } from "./packages/Utils/LayerUtils"; -export { default as ProxyUtils } from "./packages/Utils/ProxyUtils"; -export { default as ColorUtils } from "./packages/Utils/ColorUtils"; -export { default as MathUtils } from "./packages/Utils/MathUtils"; -export { default as LoggerUtils } from "./packages/Utils/LoggerByDefault"; - -// projections -export { default as CRS } from "./packages/CRS/CRS"; - -/** Version */ -export const version = Pkg.version; -/** Publication date */ -export const date = Pkg.date; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CRS/AutoLoadCRS.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/CRS/AutoLoadCRS.d.ts deleted file mode 100644 index d62f954ba..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CRS/AutoLoadCRS.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=AutoLoadCRS.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CRS/AutoLoadCRS.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/CRS/AutoLoadCRS.d.ts.map deleted file mode 100644 index c5586bf85..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CRS/AutoLoadCRS.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"AutoLoadCRS.d.ts","sourceRoot":"","sources":["../../../../src/packages/CRS/AutoLoadCRS.js"],"names":[],"mappings":""} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CRS/AutoLoadCRS.js b/build/release/geoportal-extensions-openlayers/src/packages/CRS/AutoLoadCRS.js deleted file mode 100644 index 697f3acdd..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CRS/AutoLoadCRS.js +++ /dev/null @@ -1,19 +0,0 @@ -import CRS from "./CRS"; - -/** - * Autoload function that loads defs into proj4 - * and adds proj4 defs into ol. - */ -(function () { - // if you want to load all defs into proj4 - // you can call : - // inside code, CRS.load() - // or - // outside code, Gp.olExtended.includeProjections() - // but you can call only once... - - // load default defs into proj4 - CRS.loadByDefault(); - // and register defs into openlayers - CRS.overload(); -})(); diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CRS/CRS.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/CRS/CRS.d.ts deleted file mode 100644 index 86ea7b5b4..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CRS/CRS.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -export default CRS; -declare namespace CRS { - let projectionsExtent: { - "EPSG:2154": { - left: number; - bottom: number; - right: number; - top: number; - }; - "EPSG:27572": { - left: number; - bottom: number; - right: number; - top: number; - }; - }; - function load(): void; - function loadByDefault(): void; - function loadByName(name: string): void; - function overload(): void; -} -//# sourceMappingURL=CRS.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CRS/CRS.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/CRS/CRS.d.ts.map deleted file mode 100644 index db34b30cd..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CRS/CRS.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"CRS.d.ts","sourceRoot":"","sources":["../../../../src/packages/CRS/CRS.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;IAgDW,sBAoBN;IAiBe,+BAqBf;IAMY,wCAoBZ;IAMU,0BAmBV"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CRS/CRS.js b/build/release/geoportal-extensions-openlayers/src/packages/CRS/CRS.js deleted file mode 100644 index 7c9ab73f1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CRS/CRS.js +++ /dev/null @@ -1,166 +0,0 @@ -/* - * FIXME - * en mode bundle, l'action register des methodes de chargement est executée 2 fois. - * mais aucun impact sur performance, car le register teste si la projection a été déjà - * chargé... - */ - -// import external -import Proj4 from "proj4"; -// import OpenLayers -// import { register } from "ol/proj/proj4"; -import { register } from "./Proj4"; -import { - getTransform, - addProjection, - get as getProjection -} from "ol/proj"; -// import { clear as clearProj } from "ol/proj/transforms"; -import { applyTransform } from "ol/extent"; -// import local -import Register from "../Utils/Register"; -import Logger from "../Utils/LoggerByDefault"; - -var logger = Logger.getLogger("CRS"); - -var CRS = { - - /** - * List of extent projections - */ - projectionsExtent : { - "EPSG:2154" : { - left : -9.62, - bottom : 41.18, - right : 10.3, - top : 51.54 - }, - "EPSG:27572" : { - left : -4.87, - bottom : 42.33, - right : 8.23, - top : 51.14 - } - }, - - /** - * Load all custom definition projection - */ - load : function () { - logger.trace("Loading custom definitions projections"); - // loading except if it's already loaded... - if (!Register.isLoaded) { - // load all defs into proj4 - Register.load(Proj4); - try { - // register all defs - register(Proj4); - // Expose proj4 with custom defs into OpenLayers global variable - if (window.ol && window.ol.proj && window.ol.proj.proj4) { - window.ol.proj.proj4.register = register; - window.ol.proj.proj4.register(Proj4); - } - } catch (e) { - // FIXME ? - logger.error(e); - // clearProj(); - } - } - }, - - /** - * Load definition projection by default - * - * include into proj4 : - * - WGS84 - * - ['EPSG:4326'] - * - ['EPSG:3785'], ['EPSG:3857'], GOOGLE, ['EPSG:900913'], ['EPSG:102113'] - * + - * - ["EPSG:2154"], ["EPSG:27571"], ["EPSG:27572"], ["EPSG:27573"], ["EPSG:2757"], - * - ["CRS:84"], - * - ["IGNF:LAMB93"], - * - ["IGNF:LAMBE"], ["IGNF:LAMB1"], ["IGNF:LAMB2"], ["IGNF:LAMB3"], ["IGNF:LAMB4"], - * - ["IGNF:RGF93G"], - * - ["IGNF:WGS84G"] - */ - loadByDefault : function () { - logger.trace("Loading custom definitions projections by default"); - // loading except if it's already loaded... - if (!Register.isLoaded) { - // load defs by default into proj4 - Register.loadByDefault(Proj4); - try { - // register all defs - register(Proj4); - // Expose proj4 with custom defs into OpenLayers global variable - if (window.ol && window.ol.proj && window.ol.proj.proj4) { - window.ol.proj.proj4.register = register; - window.ol.proj.proj4.register(Proj4); - } - } catch (e) { - // FIXME une projection ne passe pas avec ol.proj/proj4.register()... - // on fait quoi ? - logger.error(e); - // clearProj(); - } - } - }, - - /** - * Load a custom definition projection - * @param {String} name - ie. EPSG:2154 (Lambert) - */ - loadByName : function (name) { - logger.trace("Loading a custom definition projection : ", name); - // loading except if it's already loaded... - if (!Register.isLoaded) { - // load defs by default into proj4 - Register.loadByName(Proj4, name); - try { - // register all defs - register(Proj4); - // Expose proj4 with custom defs into OpenLayers global variable - if (window.ol && window.ol.proj && window.ol.proj.proj4) { - window.ol.proj.proj4.register = register; - window.ol.proj.proj4.register(Proj4); - } - } catch (e) { - // FIXME ? - logger.error(e); - // clearProj(); - } - } - }, - - /** - * Overload OpenLayers ol.proj parameters, - * to manage EPSG:2154 extent restriction - */ - overload : function () { - logger.trace("Loading projections aera (extent)"); - for (var code in this.projectionsExtent) { - if (this.projectionsExtent.hasOwnProperty(code)) { - var extent = this.projectionsExtent[code]; - var proj = getProjection(code); - var fromLonLat = getTransform("EPSG:4326", proj); - - // very approximate calculation of projection extent - var _extent = applyTransform([extent.bottom, extent.right, extent.top, extent.left], fromLonLat); - proj.setExtent(_extent); - addProjection(proj); - - // Expose projection extent with custom defs into OpenLayers global variable - if (window.ol && window.ol.proj && window.ol.proj.addProjection) { - window.ol.proj.addProjection(proj); - } - } - } - } -}; - -export default CRS; - -// Expose proj4 with custom defs into OpenLayers global variable -if (window.ol && window.ol.proj && window.ol.proj.proj4) { - window.ol.proj.proj4.register = register; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CRS/Proj4.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/CRS/Proj4.d.ts deleted file mode 100644 index 893529046..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CRS/Proj4.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export function register(proj4: any): void; -//# sourceMappingURL=Proj4.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CRS/Proj4.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/CRS/Proj4.d.ts.map deleted file mode 100644 index 206b30c7d..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CRS/Proj4.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Proj4.d.ts","sourceRoot":"","sources":["../../../../src/packages/CRS/Proj4.js"],"names":[],"mappings":"AAaA,2CAoCC"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CRS/Proj4.js b/build/release/geoportal-extensions-openlayers/src/packages/CRS/Proj4.js deleted file mode 100644 index d81044490..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CRS/Proj4.js +++ /dev/null @@ -1,50 +0,0 @@ -import { - addCoordinateTransforms, - addProjection, - addEquivalentProjections, - get -} from "ol/proj"; -import { get as getTransform } from "ol/proj/transforms"; -import Projection from "ol/proj/Projection"; - -import Logger from "../Utils/LoggerByDefault"; - -var logger = Logger.getLogger("CRS"); - -export function register (proj4) { - const projCodes = Object.keys(proj4.defs); - logger.trace("proj. codes :", projCodes); - - const len = projCodes.length; - let i, j; - for (i = 0; i < len; ++i) { - const code = projCodes[i]; - if (!get(code)) { - const def = proj4.defs(code); - addProjection(new Projection({ - code : code, - axisOrientation : def.axis, - metersPerUnit : def.to_meter, - units : def.units - })); - } - } - for (i = 0; i < len; ++i) { - const code1 = projCodes[i]; - const proj1 = get(code1); - - for (j = 0; j < len; ++j) { - const code2 = projCodes[j]; - const proj2 = get(code2); - - if (!getTransform(code1, code2)) { - if (proj4.defs[code1] === proj4.defs[code2]) { - addEquivalentProjections([proj1, proj2]); - } else { - const transform = proj4(code1, code2); - addCoordinateTransforms(proj1, proj2, transform.forward, transform.inverse); - } - } - } - } -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Attribution/DSFRattributionStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Attribution/DSFRattributionStyle.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Attribution/GPFattribution.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Attribution/GPFattribution.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Attribution/GPFattributionStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Attribution/GPFattributionStyle.css deleted file mode 100644 index c13b6f2ae..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Attribution/GPFattributionStyle.css +++ /dev/null @@ -1,7 +0,0 @@ -/* Geoportal Attribution */ - -.ol-attribution .gp-control-attribution-image { - max-height: 30px; - max-width: inherit; - vertical-align: middle; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/DSFRdrawingStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/DSFRdrawingStyle.css deleted file mode 100644 index 9d3f44edd..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/DSFRdrawingStyle.css +++ /dev/null @@ -1,8 +0,0 @@ -.gpf-btn-icon-drawing { - background-image: url("img/modifier.svg"); - background-repeat: no-repeat; - background-size: auto auto; - background-position: center center; -} - -.gpf-btn-icon-close {} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/GPFdrawing.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/GPFdrawing.css deleted file mode 100644 index b13e94f0a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/GPFdrawing.css +++ /dev/null @@ -1,168 +0,0 @@ -/* MOUSE POSITION */ - -div[id^=GPdrawing-] { - top: 48px; - right: 8px; -} - -/* Showing/hiding drawing panel */ - -button[id^="GPshowDrawingPicto-"] {} - -button[id^="GPshowDrawingPicto-"][aria-pressed="false"] + dialog { - display: none; - visibility: hidden; - opacity: 0%; -} - -button[id^="GPshowDrawingPicto-"][aria-pressed="true"] + dialog { - display: block; - visibility: visible; - opacity: 100%; -} - -/* General panels */ - -[id^=GPdrawingPanel-] { - top: 0px; - left: -276px; - position: absolute; - height: inherit; - overflow: hidden; - bottom: unset; /* fix dsfr */ -} - -/* Basic infos */ - -div[id^=GPdrawingBasicPanel-] { - padding: 10px 15px; -} - -.drawing-tool-section:not(:last-child) { - border-bottom: 1px solid #ddd; -} - -.drawing-tool-section { - padding: 2px 5px 5px; -} - -.drawing-tool-section-title { - /* font-family: OpenSansExtraBold,"Open Sans",Arial,sans-serif; */ - font-size: 0.75em; - margin-bottom: 0; - margin-top: 0; - text-transform: uppercase; -} - -ul.drawing-tools-flex-display { - justify-content: center; - padding : 0; -} -.drawing-tools-flex-display { - align-items: center; - display: flex; -} - -.drawing-tool:not(:last-child) { - margin-right: 10px; -} - -.drawing-tool { - border-radius: 10px; - cursor: pointer; - display: block; - height: 40px; - width: 40px; -} - -.drawing-tool { - background-image: url("img/drawing-tools.svg"); - background-size: 720px 40px; -} - -.drawing-tool { - background-color: #e9edf0; -} - -.drawing-tool-active { - background-color: #002a50; -} - - -/* -* Drawing tools -*/ -li[id^=drawing-tool-point-] { - background-position: 0 0; -} - -li[id^=drawing-tool-point-].drawing-tool-active { - background-position: -40px 0; -} - -li[id^=drawing-tool-line-].drawing-tool-active { - background-position: -120px 0; -} - -li[id^=drawing-tool-line-] { - background-position: -80px 0; -} - -li[id^=drawing-tool-holes-] { - background-position: -640px 0; -} - -li[id^=drawing-tool-holes-].drawing-tool-active { - background-position: -680px 0; -} - -li[id^=drawing-tool-polygon-] { - background-position: -160px 0; -} - -li[id^=drawing-tool-polygon-].drawing-tool-active { - background-position: -200px 0; -} - -li[id^=drawing-tool-text-] { - background-position: -240px 0; -} - -li[id^=drawing-tool-text-].drawing-tool-active { - background-position: -280px 0; -} - -/* -* Editing tools -*/ -li[id^=drawing-tool-edit-] { - background-position: -320px 0; -} - -li[id^=drawing-tool-edit-].drawing-tool-active { - background-position: -360px 0; -} - -li[id^=drawing-tool-display] { - background-position: -400px 0; -} - -li[id^=drawing-tool-display-].drawing-tool-active { - background-position: -440px 0; -} - -li[id^=drawing-tool-tooltip] { - background-position: -480px 0; -} - -li[id^=drawing-tool-tooltip-].drawing-tool-active { - background-position: -520px 0; -} - -li[id^=drawing-tool-remove] { - background-position: -560px 0; -} - -li[id^=drawing-tool-remove-].drawing-tool-active { - background-position: -600px 0; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/GPFdrawingStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/GPFdrawingStyle.css deleted file mode 100644 index 4611b65d3..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/GPFdrawingStyle.css +++ /dev/null @@ -1,370 +0,0 @@ -[id^=GPdrawingPanel-] { - width: 240px; -} - -.GPshowDrawingPicto { - background-image: url("img/GPdrawingOpen.png"); - background-repeat: no-repeat; - background-position: 1px center; -} -.GPdrawingPanelClose { - background-image: url("img/GPdrawingOpen.png"); -} - -.GPdrawingLabel, -.GPdrawingCoords { - display: inline-block; - line-height: 20px; -} - -.GPdrawingLabel { - width: 80px; - font-weight: bold; -} - -.GPdrawingCoords { - width: 110px; -} - -/* markers selector */ -.marker-input-radio { - display : none ; -} - -input.marker-input-radio:checked + label { - border: 1px solid red; -} - - - -/* section d'export */ - -div.drawing-tools-flex-display { - justify-content: space-between; -} - -button[id^=drawing-export-] { - background-position: 2px 0; -} - -.drawing-button { - margin: auto; - font-size: 0.7em; - height: 30px; - line-height: 30px; - padding-left: 30px; - padding-right: 15px; - /* from site colors-chart */ - background-image: url("img/drawing-save.svg"); - background-size: 30px 120px; -} - -.tool-form-submit { - border: medium none; - border-radius: 20px; - font-family: "Helvetica Neue",Arial,Helvetica,sans-serif; - font-size: 0.9em; - text-align: center; - text-transform: uppercase; - /* from site colors-chart */ - background-color: #00b798; - color: #fff; -} - -/* - * popups - */ -.gp-label-div, -.gp-styling-div { - position: relative; - top: 17px; - border-radius: 10px; - font-size: 0.75em; - background-color: #FFF; - box-shadow: 0 0 5px #000; - box-sizing: border-box; -} - -.gp-label-div::before, -.gp-styling-div::before { - content: ""; - position: absolute; - border-bottom: 15px solid #FFF; - border-right: 9px solid transparent; - border-left: 10px solid transparent; - top: -15px; - margin-left: -10px; - left: 50%; -} - -.gp-textarea-att-label-style, -.gp-input-label-style { - border: none; -} - -.gp-textarea-att-label-style { - width: 240px; - height: 80px; - resize: none; -} - -.gp-input-measure-style { - width: 240px; - font-size: 0.75em; - background-color: #FFF; - text-align: center; - border-radius: 10px; -} - -.gp-textarea-att-label-style { - display: block; -} - -.gp-label-div .closer { - border-top-right-radius: 10px; - background-color: #FFF; -} - -.gp-input-label-style { - width: 180px; -} - -/* Label popups */ - -.gp-label-div { - padding: 10px; -} - -/* Styling popup */ - -.gp-styling-div { - width: 340px; - padding: 20px; - padding-top: 50px; -} - -.gp-styling-div::after { - content: "Modifier le style"; - position: absolute; - display: block; - width: 280px; - height: 30px; - line-height: 30px; - text-align: center; - left: 30px; - top: 0; - border-bottom: 1px solid #BBB; - font-variant: small-caps; - font-size: 1.2em; - font-weight: bold; -} - -.gp-label-div .gp-styling-button:not([class*="closer"]) { - display: block; - margin: auto; - margin-top: 10px; -} - -.gp-styling-button:not([class*="closer"]) { - display: inline-block; - width: 140px; - height: 24px; - line-height: 24px; - margin-top: 20px; - border-radius: 12px; - text-align: center; - color: #FFF; - background-color: #00B798; - font-weight: bold; - font-size: 0.9em; - text-transform: uppercase; - border: none; -} - -.gp-styling-button:not([class*="closer"]):hover { - color: #00B798; - background-color: #EEF2F5; -} - -.gp-styling-button:not([class*="closer"]) + .gp-styling-button:not([class*="closer"]) { - margin-left: 20px; -} - -.gp-label-div .closer, -.gp-styling-div .closer { - cursor: pointer; - position: absolute; - display: block; - width: 30px; - height: 30px; - top: 0; - right: 0; - border: none; - background-color: transparent; - background-repeat: no-repeat; - background-image: url("../../img/close-emeraud.svg"); - background-size: 14px 14px; - background-position: center; -} - -.gp-styling-div ul { - list-style-type: none; - padding: 0; - margin: 0; -} - -.gp-styling-option { - font-size: 11px; - position: relative; - line-height: 30px; - padding: 0 20px; -} - -.gp-styling-option input { - display: block; - position: absolute; - height: 20px; - top: 6px; - cursor: pointer; - padding: 0; -} - -.gp-styling-option input[type="checkbox"] { - height: 10px; - right: 70px; - padding: 0; - border: none; - background: none; -} - -.gp-styling-option input[type="color"] { - width: 30px; - right: 70px; - padding: 0; - border: none; - background: none; -} - -.gp-styling-option input[type="text"] { - width: 80px; - right: 40px; - padding: 0 5px; - margin: none; - background: none; - border: 1px solid #808080; - color: #0B6BA7; -} - - -/* Styling slider : general */ -.gp-styling-option input[type="range"] { - margin: 0; - width: 80px; - right: 40px; -} - -.gp-styling-option input[type="range"]:focus { - box-shadow: none; - outline: none; -} - -/* Styling slider : Chrome, Safari, Opera */ - -.gp-styling-option input[type="range"]::-webkit-slider-runnable-track { - -webkit-appearance: none; - height: 1px; - background-color: #808080; -} - -.gp-styling-option input[type="range"]::-webkit-slider-thumb:before { - position: absolute; - top: 0; - right: 50%; - left: -200px; - height: 1px; - pointer-events: none; -} - -.gp-styling-option input[type="range"]::-webkit-slider-thumb { - width: 13px; - height: 13px; - -webkit-appearance: none; - background-color: #0B6BA7; - border: none; - border-radius: 50%; - position: relative; - top: -6px; -} - -/* Styling slider : Firefox */ - -.gp-styling-option input[type="range"]::-moz-range-track { - width: 70px; - height: 1px; - background-color: #808080; -} - -.gp-styling-option input[type="range"]::-moz-range-thumb { - width: 13px; - height: 13px; - background-color: #0B6BA7; - border: none; - border-radius: 50%; - box-shadow: 0; - position: relative; -} - -/* Styling slider : IE */ - -.gp-styling-option input[type="range"]::-ms-track { - border: 0; - border-color: transparent; - border-radius: 0; - border-width: 0; - color: transparent; - height: 1px; - width: 70px; - background-color: #808080; -} - -.gp-styling-option input[type="range"]::-ms-fill-lower, -.gp-styling-option input[type="range"]::-ms-fill-upper { - background: transparent; - border-radius: 0; -} - -.gp-styling-option input[type="range"]::-ms-thumb { - width: 13px; - height: 13px; - background-color: #0B6BA7; - border: none; - border-radius: 50%; -} - -.gp-styling-option input[type="range"]::-ms-tooltip { - display: none; -} - - -.gp-styling-option .marker-input-radio { - display: none; -} - -.gp-styling-option .marker-label { - display: inline-block; - height: 32px; - padding: 3px; - margin-right: 5px; - margin-bottom: 5px; - cursor: pointer; -} - -.gp-styling-option .marker-input-radio:checked + .marker-label { - padding: 2px; - background-color: rgba(0,183,152,0.5); - border: 1px solid #002A50; -} - -.gp-styling-option .marker-label img { - height: 24px; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/GPdrawingOpen.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/GPdrawingOpen.png deleted file mode 100644 index f23a92c20315eef5f64ffdb99c2518ebcd8d4fdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 517 zcmV+g0{Z=lP)MX#)Of0)m$Mv2Yfz!`#)~yO-PSuUdvP=Xbt)X3tItty;Be)s!%Y zzc|6EH`C>R0@BA$wk{GE{_li2HYQP!Z;9jCpJn3bQ!F z0VZ*nKpj`i*G=|sp_9ODB{AJ5VJ>?TA7!BaRLof%rC#k~Ea^<4om>~2fJveD@C$P_ za`%HuyEk;0Li-JPOu*j)22(uxC?;(V#lCbL#!t(peep8)yu2mBz z@Ef-!ow-uuo9W}18vwPs)X!iQ->`)L8G{>q7$VG0X01My=j+U3eEyhp>I(BihAGB& zcBEG|nZ`Y4de#c4#$aOJ;s02%88`mJ3>G{ezl$beqSq%cSD)-?PCE67^{OU6dfvue zJbo(}Z;a%%-&*Wc-)R=1x>&1Ya2cUCF+EVVty;BeHA+1JCJ3l+lk(e?00000NkvXX Hu0mjf@Y&%T diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/drawing-save.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/drawing-save.svg deleted file mode 100644 index ecbd7a813..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/drawing-save.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/drawing-tools.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/drawing-tools.svg deleted file mode 100644 index f5c331b99..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/drawing-tools.svg +++ /dev/null @@ -1,452 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/modifier.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/modifier.svg deleted file mode 100644 index ce5901a61..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Drawing/img/modifier.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/DSFReditorStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/DSFReditorStyle.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/GPFeditor.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/GPFeditor.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/GPFeditorStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/GPFeditorStyle.css deleted file mode 100644 index e52ed2202..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/GPFeditorStyle.css +++ /dev/null @@ -1,505 +0,0 @@ -.GPimportMapBoxpRoot { - padding: 5px; -} - -.GPEditorMapBoxContainer { - width: 100%; - height: auto; - position: relative; - padding: 5px; - -webkit-box-sizing: border-box; - box-sizing: border-box; - -webkit-box-shadow: 0 0 5px #000000; - box-shadow: 0 0 5px #000000; - border-style: solid; - border-width: 1px; - border-color: lightskyblue; - border-radius: 5px; -} - -.GPEditorMapBoxSep { - display: block; - width: 50%; - border-style: double; - border-width: 4px; - border-color: lightskyblue; -} - -.GPEditorMapBoxLayersTitle, -.GPEditorMapBoxThemesTitle { - padding: 5px; - font-style: italic; - font-weight: bold; -} - -/* desactive un composant */ -.disabled { - pointer-events: none; - opacity: 0.5; -} - -/******************************************************************************* -GROUPS -*******************************************************************************/ -.GPEditorMapBoxGroupContainer {} - -/* FIXME : modifier la couleur de la puce ? */ -.GPEditorMapBoxGroupDetails { - border-style: dotted; - border-width: 1px; - border-radius: 5px; - border-color: lightskyblue -} - -.GPEditorMapBoxGroupSummary {} - -/******************************************************************************* -LAYERS -*******************************************************************************/ - -/* - container principal */ -.GPEditorMapBoxLayersContainer { - -} -/* - container layers */ -.GPEditorMapBoxLayerContainer { - width: 100%; - min-height: 28px; - display: -webkit-inline-box; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-box-orient: horizontal; - -webkit-box-direction: normal; - -ms-flex-direction: row; - flex-direction: row; - -ms-flex-wrap: nowrap; - flex-wrap: nowrap; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - /* background-color: red; */ -} -/* - container titre */ -.GPEditorMapBoxLayerTitleContainer { - width: inherit; - min-height: 28px; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: start; - -ms-flex-pack: start; - justify-content: flex-start; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - /* background-color: grey; */ -} -.GPEditorMapBoxLayerImageInput { - display: none; -} -.GPEditorMapBoxLayerImageLabel { - min-width: 24px; - min-height: 28px; - cursor: pointer; - /* position: absolute; */ - background-image: url("img/GPEditorLayerTools.png"); - background-position: -56px 0; - /* background-color: green; */ -} -input[type="checkbox"]:checked + .GPEditorMapBoxLayerImageLabel { - -webkit-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); -} -.GPEditorMapBoxLayerTypeImage { - min-width: 30px; - min-height: 30px; - margin-right: 5px; - background-repeat: no-repeat; - cursor: pointer; - /* position: absolute; */ - /* background-image: url("img/GPEditorLayerTypeIcon.svg"); */ - background-image: url("img/GPEditorLayerTypeIcon.png"); - background-position: 0px 0; - -webkit-box-sizing: border-box; - box-sizing: border-box; - -webkit-box-shadow: 2px 2px 1px lightgrey; - box-shadow: 2px 2px 1px lightgrey; - border-style: solid; - border-width: 1px; - border-radius: 5px; - border-color: gray; - /* background-color: blue; */ -} -.GPEditorMapBoxLayerTitleInput { - display: none; -} -.GPEditorMapBoxLayerTitleLabel { - width: inherit; - /* margin-inline-start: 28px; */ - cursor: pointer; - /* background-color: yellow; */ - border-style: solid; - border-width: 1px; - border-radius: 5px; - border-color: gray; - -webkit-box-shadow: 2px 2px 1px lightgrey; - box-shadow: 2px 2px 1px lightgrey; - padding: 5px; - margin-left: 5px; - word-break: break-word; -} -input[type="checkbox"]:checked + .GPEditorMapBoxLayerTitleLabel { - background-color: lightgrey; -} - -/* - container legend */ -.GPEditorMapBoxLayerLegendContainer { - -} - -/* - container outils */ -.GPEditorMapBoxToolsContainer { - min-width: 28px; - height: 28px; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: end; - -ms-flex-pack: end; - justify-content: flex-end; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - /* background-color: pink; */ -} -.GPEditorMapBoxToolsVisibilityInput { - display: none; -} -.GPEditorMapBoxToolsVisibilityInputDisable { - display: "block"; -} - -.GPEditorMapBoxToolsVisibilityLabel { - width: 28px; - height: 28px; - cursor: pointer; - /* position: absolute; */ - background-image: url("img/GPEditorLayerTools.png"); - background-position: -28px 0; - /* background-color: white; */ -} -.GPEditorMapBoxToolsVisibilityLabelDisable { - cursor: pointer; -} - -input[type="checkbox"]:checked + .GPEditorMapBoxToolsVisibilityLabel { - background-position: 0 0; -} - -/******************************************************************************* - FILTERS -*******************************************************************************/ - -/* - container principal */ -.GPEditorMapBoxFilterContainer { - width: 100%; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - -ms-flex-wrap: nowrap; - flex-wrap: nowrap; - -webkit-box-align: start; - -ms-flex-align: start; - align-items: flex-start; - /* background-color: red; */ - margin-left: 28px; -} -/* - container titre + editeur json */ -.GPEditorMapBoxFilterJsonContainer { - border-style: solid; - border-radius: 5px; - border-width: 1px; - padding: 5px; -} -.GPEditorMapBoxFilterTitleJson { - -} -.GPEditorMapBoxFilterDisplayJson { - width: 175px; - height: 125px; - cursor: pointer; - overflow: scroll; - resize: vertical; -} - -/* - container outils editions */ -.GPEditorMapBoxFilterToolsEditionContainer { - /* border-style: solid; - border-radius: 5px; - padding: 5px; */ -} -/* - container outils boutons enregister/annuler */ -.GPEditorMapBoxFilterToolsButtonsContainer { - /* border-style: solid; - border-radius: 5px; - padding: 5px; */ -} - -/******************************************************************************* - THEMES -*******************************************************************************/ - -/* - container principal */ -.GPEditorMapBoxThemesContainer { - width: 175px; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - -ms-flex-wrap: nowrap; - flex-wrap: nowrap; - -webkit-box-align: start; - -ms-flex-align: start; - align-items: flex-start; - /* background-color: red; */ -} - -/* - container d'un theme */ -.GPEditorMapBoxThemeContainer { - width: inherit; - border-style: solid; - border-radius: 5px; - border-width: 1px; - padding: 5px; - margin: 5px; - text-align: center; -} - -.GPEditorMapBoxThemeContainer:focus { - background-color: lightgrey; -} - -.GPEditorMapBoxThemeImage { - width: 120px; - height: 60px; - cursor:pointer; -} -.GPEditorMapBoxThemeTitle { - padding: 5px; - cursor:pointer; -} - -.GPEditorMapBoxThemeMessage { - font-style: italic; - color: red; -} -/******************************************************************************* - STYLES -*******************************************************************************/ - -/* - container principal */ -.GPEditorMapBoxStyleContainer { - width: 100%; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - -ms-flex-wrap: nowrap; - flex-wrap: nowrap; - -webkit-box-align: start; - -ms-flex-align: start; - align-items: flex-start; - /* background-color: red; */ - margin-left: 28px; -} -/* - container titre + editeur json */ -.GPEditorMapBoxStyleJsonContainer { - border-style: solid; - border-radius: 5px; - border-width: 1px; - padding: 5px; -} -.GPEditorMapBoxStyleTitleJson { - -} -.GPEditorMapBoxStyleJsonDisplay { - width: 175px; - height: 125px; - cursor: pointer; - overflow: scroll; - resize: vertical; -} -/* - container outils Scale */ -.GPEditorMapBoxStyleToolsScaleContainer { - width: -webkit-min-content; - width: -moz-min-content; - width: min-content; /* FIXME */ - border-style: solid; - border-radius: 5px; - border-width: 1px; - padding: 5px; -} -.GPEditorMapBoxStyleScaleTitle {} -.GPEditorMapBoxStyleToolsScaleMaxContainer, -.GPEditorMapBoxStyleToolsScaleMinContainer { - width: 175px; - display: -webkit-inline-box; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-box-orient: horizontal; - -webkit-box-direction: normal; - -ms-flex-direction: row; - flex-direction: row; - -ms-flex-wrap: nowrap; - flex-wrap: nowrap; -} -.GPEditorMapBoxStyleScaleLabelMin {} -.GPEditorMapBoxStyleScaleInputMin {} -.GPEditorMapBoxStyleScaleLabelMax {} -.GPEditorMapBoxStyleScaleInputMax {} - -/* - container outils editions */ -.GPEditorMapBoxStyleToolsEditionContainer { - /* border-style: solid; - border-radius: 5px; - padding: 5px; */ -} - /* - container outils boutons enregister/annuler */ -.GPEditorMapBoxStyleToolsButtonsContainer { - /* border-style: solid; - border-radius: 5px; - padding: 5px; */ -} - -/******************************************************************************* -JSON display Editor -*******************************************************************************/ -.gp-json-string { color: green; } -.gp-json-number { color: darkorange; } -.gp-json-boolean { color: blue; } -.gp-json-null { color: magenta; } -.gp-json-key { color: red; } - - -/******************************************************************************* -LEGEND -*******************************************************************************/ - -.GPEditorMapBoxLegendContainer { - width: 100%; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - -webkit-box-align: start; - -ms-flex-align: start; - align-items: flex-start; - -ms-flex-wrap: nowrap; - flex-wrap: nowrap; - margin-left: 28px; -} - -.GPEditorMapBoxLegendRenderContainer { - display: -webkit-inline-box; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - width: 175px; - padding: 5px; - border-style: solid; - border-radius: 5px; - border-width: 1px; - overflow-y: auto; -} - -.GPEditorMapBoxLegendInput { - -} -.GPEditorMapBoxLegendRender { - min-width: 28px; - min-height: 28px; - border-color: transparent; - border-style: solid; - border-width: 1px; - border-radius: 5px; - -webkit-box-shadow: 2px 2px 1px grey; - box-shadow: 2px 2px 1px grey; - cursor: pointer; -} -.GPEditorMapBoxLegendEditable { - border-color: black; -} -.GPEditorMapBoxLegendTitle { - margin-left: 10px; -} - -.GPEditorMapBoxLegendToolsContainer { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - width: 230px; - padding: 5px; -} - -.legend-background {} -.legend-fill , -.legend-line { - /* margin: auto; - padding: 5px; */ -} -.legend-icon {} -.legend-text {} -.legend-circle {} -.legend-unknow, -.legend-not-implemented { - background-color: #FFFFFF; -} -.legend-unknow:before { - content: '\2753'; - color: red; - font-size: 15px; -} -.legend-not-implemented:before { - content: '\2718'; - color: red; - font-size: 15px; -} -.legend-fill-not-editable { - -} -.legend-circle-not-editable, -.legend-line-not-editable { - border-color: white; -} - -.legend-styling-div { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; -} -.legend-styling { - width: 50px; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/img/GPEditorLayerTools.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/img/GPEditorLayerTools.png deleted file mode 100644 index 123e390198cbf3fc600e69d14fee6b7a7054af99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2151 zcmV-t2$=VYP)&RM{EFe}@5t85_5ln~b=CF`?9Hh=!G@4Tu_y)z}o)iD@d;ekCyiqQzIN zCK{EJVQ~|a`bh)CxVVf7Au%CDx}?Mmz7Wl{d?*12uVb#&RWk#2n0xvG?(N{)!p!Wh zw)0O&<~h${o_o&upXdC~a|aSgAb|uDNZ^BjNKC>156X{SmUI1|j^n>ga3n#P==&!p zrt!x^ZEfw(Ef&k#$hL4e{MW|D#(#XM&zzK4wjU1`i)F2pve>Ytl*O+T=tILtmtnfP zy5!@>k6F5ODJ3N(aXVid8X8DVO-0H#vvw#HV*mdAF~@MZTuYOZl1inNrNFO%pG>um%mKXzHZt3B=-#^rL!9XobNfcpCS89qf(04OUflPxVR zG9F~<>FJTZy}baGl#~GA_xl0J&dvs)yStm4H*ZEAuc4vAAPYju8wifIt69IVs;Zh{ zUsXSy>LUcr&COAd>6iPy#%X`>+_}gnXZ5#u?AzjlS7M&aqPnXT|FQk8zF++5irFVF zgz@=&^3b6}Qqwd}pFT}RMTN-9$`a?!ox|;Ri~9O{bN8P)bB2L|0S+BH6!jwd{eIcm z*(rm;Af=_HtXj27*zI<)dGluMb~^wI7cK;#w6qjeRq5>Pj4EDgYU;Gwgr`=$O2Rh? z{!)C<{aK_flPsSh&09?LH;k!#J_fLE-8!>9J3EK$>>SfJd{W9Wq$T#5J@0IOH8W@Kc9l#~?KtXV@K5a9at>vN8$>pB3= zOdmg;Nd9+HQrHPRLh5cMKt`mUEW>u=Xo`N}*>Y}i)kkQdmva+(ou3fwEcsz4n#M`%TOI1}_xpJkMZG1kT1Slvd5XO;|mX^li z#fy3V{5f{JU94EK0##MHckkYu;zcgL)BXS{Q?w*3zX3j(6qa_WTV~jCsbeH1jRB00 zk7Ko3-|$h6b4}R8>V$6pT!!X&S1k($Uc&+uGVBKt@IeFJHdI zYPAvw1OUj(%M(_smC@1Bs3x=hQ5IL#PkELWLKiaCybKl8C ziPSL3dU)z9<<#eAX`%ROn8LzByk0N2Z{L=$i`@41c9ReehXYO1O!3>-*C#biGsWs` zk(rr^rfCch56jml@y?w)0NCwz6h$Ez3}Um{02mq?lEGk*oSdAP&iIU1C`jE6e48x8 z&T#TfJ04;}2=Ne@@%)iUPfurjeB8)@4`n=F_eE%!aPrjg(|2|o;bh{gVam(PMPXqf z=g*(V=krO2!-3c9#p!giWXTefEL*m0!Rz&slaqtb=aUyNUZk+FkWHI5&1tj+1qC8A zGZT-;gWvC$M%HpT96WjQ1b`(=mXMp9i>7HTSg-)U-!Jdpy-Q|hCi(gKQO&M1)5o*) zaH_6b+JOv2QkiDsX{24YSoO!gaspk~9~wtedV2aBJ#03cnK`G(6+2;mFbxB+bLUPJ zMWL~=kzg>0!{OlK#fwx{R^oQMh12Qe{Q2`Z91Z{)8yis+g~NvrM>W#r%a>!b+34@@ zClm^yC<=pvgFJio41kRrH!?6VU}m%a{(fvW+nmX1RB#Ps1e3lHP>c|NKCm9dSrKZHx7q`7cX8A2n3ive?A_M2SrgxNlBr*yPMqH zTvn}G6;-_b`}gB=xe!7ig;tLysMjmBTcwNkF6h2&hT!%T;}=-kO>kTrL;RMZRUPxt2xVrgUA8`PBfx?%lip)zs7!oS2xf z8a17Xi3!s`IXTIzSFZqqd-v{r8c(vktNj123UFLr4ZJIRT)1$7c*7vW(W6Ht!20#; z*}i>y+<(whQ&U58b2H&^_^ox8P$(2rW_b%90=YMC+yLOgga6*{j5Z;}7#|=$ikFY~ z?%e|*KR^F_i?L_Vo*!&H)z#HM<0HjKK^V8&EdZ7+TSfv2!X)rLAe!IrCXhe^2_%p} d0tx)D;y?Ou!7j<~m}dY0002ovPDHLkV1lYFBhUZ< diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/img/GPEditorLayerTypeIcon.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/img/GPEditorLayerTypeIcon.png deleted file mode 100644 index f016cdb737ea0b91ad8c75092faf76180122193d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4022 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 diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/img/GPEditorLayerTypeIcon.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/img/GPEditorLayerTypeIcon.svg deleted file mode 100644 index e0e436e5f..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Editor/img/GPEditorLayerTypeIcon.svg +++ /dev/null @@ -1,241 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - T - ... - - - - - - T - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/DSFRelevationPathStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/DSFRelevationPathStyle.css deleted file mode 100644 index 82ae4de9a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/DSFRelevationPathStyle.css +++ /dev/null @@ -1,16 +0,0 @@ -.gpf-btn-icon-elevation { - background-image: url("img/altipath.svg"); - background-repeat: no-repeat; - background-size: auto auto; - background-position: center center; - } - -#profileElevationByDefaultSvg { - height: 80%; -} - -[id^=GPelevationPathPanelInfo] { - background-image: url("../../img/GPinfo_secondary.svg"); - background-repeat: no-repeat; - background-position: center center; -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/GPFelevationPath.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/GPFelevationPath.css deleted file mode 100644 index 0900df9c1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/GPFelevationPath.css +++ /dev/null @@ -1,66 +0,0 @@ -div[id^=GPelevationPath-] { - height: 36px; -} - -/* Showing/hiding elevationPath panel */ - - -button[id^="GPshowElevationPathPicto-"] {} - -button[id^="GPshowElevationPathPicto-"][aria-pressed="false"] + dialog { - display: none; - visibility: hidden; - opacity: 0%; -} - -button[id^="GPshowElevationPathPicto-"][aria-pressed="true"] + dialog { - display: block; - visibility: visible; - opacity: 100%; -} - -/* 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; - background-position: -50px center; -} - -[id^=GPelevationPathPanel-] { - position : relative; - top : 6px; - left: 32px; -} - -/* ELEVATION PATH DISPLAY */ - -[id^=GPelevationPathProfil] { - height: 150px; - width: inherit; -} - -button[id^=GPelevationPathPanelReduce] { - display: none; /* on n'affiche pas le bouton d'information par defaut */ -} - -button[id^=GPelevationPathPanelInfo] { - display: none; /* on n'affiche pas le bouton d'information par defaut */ -} - -div[id^=GPelevationPathInformationsContainer] { - position: absolute; - top: 32px; - bottom: 0; - left: 0; - right: 0; - background-color: rgba(255, 255, 255, 0.9); - border-radius: 4px; - overflow: hidden; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/GPFelevationPathStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/GPFelevationPathStyle.css deleted file mode 100644 index de58f3b5c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/GPFelevationPathStyle.css +++ /dev/null @@ -1,173 +0,0 @@ -.GPpanelHeader { - padding: unset; -} - -/* CSS : Raw */ - -#profileElevationRaw { - resize: none; - padding: unset; -} - -/* CSS : default */ - -#profileElevationByDefault { - display:-webkit-flex; - display:-webkit-box; - display:-ms-flexbox; - display:flex; - -webkit-box-orient:vertical; - -webkit-box-direction:normal; - -webkit-flex-direction:column; - -ms-flex-direction:column; - flex-direction:column; - height:100%; -} - -.altiPathValue { - font-weight: 700; - fill: #5E5E5E; -} - -.altiPathCoords { - font-style: italic; - fill: #5E5E5E; -} - -.tooltipInit { - opacity: 0; -} - -.tooltipFadeIn { - transition: opacity 300ms ease 0ms, transform 50ms ease 0s, top 50ms ease 0s, left 50ms ease 0s; - opacity: 1; -} - -.tooltipFadeOut { - transition: opacity 500ms ease 0ms; - opacity: 0; -} - - - -/* CSS : D3 */ - -.axis-d3 > text { - fill: rgb(94, 94, 94); - font-family: Verdana; - font-size: 10px; - opacity: 1; - text-anchor: end; -} - -.axis-d3 { - fill: none; - stroke: #5E5E5E; - stroke-width: 1; - shape-rendering: crispEdges; -} - -.area-d3 { - fill: #C77A04; - stroke: #5E5E5E; - stroke-width: 0; - fill-opacity: 0.4; -} - -.line-d3 { - fill: none; - stroke: #C77A04; - stroke-width: 1px; -} - -.grid-d3 .tick { - stroke: lightgrey; - opacity: 0.7; -} - -.grid-d3 path { - stroke-width: 0; -} - -.grid-d3 .tick { - stroke: lightgrey; - opacity: 0.7; -} - -.grid-d3 path { - stroke-width: 0; -} - -.overlay-d3 { - fill: none; - pointer-events: all; -} - -.focusLine-d3 { - fill: none; - stroke: #C77A04; - stroke-width: 0.5px; -} - -.focusCircle-d3 { - fill: #C77A04; -} - -div.tooltip-d3 { - position: inherit;; - text-align: left; - width: 80px; - height: 45px; - padding: 5px; - font: 8px sans-serif; - background: white; - border: 0px; - border-radius: 8px; - pointer-events: none; -} - -[id^=GPelevationPathPanel-] { - width: 280px; -} - -[id^=GPelevationPathPanelInfo] { - background-image: url("img/GPshowElevationPath.png"); - background-repeat: no-repeat; - background-position: -75px center; -} - -button[id^="GPshowElevationPathPicto-"] { - background-image: url("img/GPshowElevationPath.png"); - background-repeat: no-repeat; - background-position: 1px center; -} -/* -@media (min-width:720px) and (min-height:720px) { - -[id^=GPelevationPathPanel] { -top: 15px; -left: 15px; -} - -} - -@media (min-width:720px) and (min-height:520px) { - -[id^=GPelevationPathPanel] { -width: 460px; -} - -[id^=GPelevationPathProfil] { -height: 220px; -} - -} - -@media (max-width:560px), (max-height:340px) { - -[id^=GPelevationPathPanel] { -display: none !important; -} - -} -*/ diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/img/GPshowElevationPath.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/img/GPshowElevationPath.png deleted file mode 100644 index e07744ae6a2a90992b9bee6c53c27996bc194090..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1237 zcmV;`1SVGd000McNliru;sFp6G82qV47UIP1Y$`< zK~!ko?U_wz9Ay~C|IcJg(k?O81hravu$M{-IkXC~il9=(#EV*~Cl#YzX^7&%Lk?9@ zqS!-`CJiyR2Jz5Rm4axiMNNB2N@G62l~NQfROFD9Crou3Eah3PQa+1+fyw%tDr z%*^x7%=R!Gs_l4keM9?vXTZRy;L=E z=^isTH`i2KTYI~t2PJKl^sA&lBq6E6E&eYh9m{63!=C5;7DtqTTYw*dVW10Gv5ZPR z0}KFOKE;8(Kxd_rGdVfw0h@sX!1uruup8I_tO8a7Yk^(BDc~G%2)KWIe7q*kNDlx9 z-EkO5E+aWv{>NYxNsgReH^#42l7MS~KHz8Ib>H_lyZes-Zvbxr9g>vIW;X&a0%w3v zfVG8uU`4)FyhKX%aVhq>#2O@LUuaBUrI9l;GvfjG0%w6eAss&o%>A2?YzJ^2cq-QR zz}rA?kp^x68Wt0?UFZs85b#2tlfyg9y@(3bBk97~8DL9D_9`$6i~$27*?QoFi&|^q zJ~9LxEOKJIfu6-C)&)rFyG+P2;11vipf8X4hujt+?*cvsjsUMMV8>5^7xETo zQ3L@A7y7nEj1R`v{bgE-Q6vqPN)Ba$BdI12L2ba-z`6zOdeOb=s|a}`@O~6QUW{_r zN%~w;m!w0$%ee#&+$HJZ!0;!4=5ls7V(!Iy#1c4~UuL~xk?+4_gQQcE?g@P06-QK3 z(w@*GHIm+3WJ_ePq@5AsrzH&(<3+7K^OQRT#u(Wo)l0gegx9Z@)EL+5xuo2dH0u6( z!`LQiORjwpLOXD`nVl#DIfIfe2JUs_%F;smSR>sDYwelG%!0WkZWYtoGtWqOVvRF& zlce7zWgOuPk&dKkN!LnxGM!G3H8(dGv_Mj+lu2rr)FSBvN!i#O&<;8DN|60TV_nS8)CMGV#mVUsH zq&hR(t}05dMvK{Q@O?k;c0-t;ldhV$P>#7udd|#-uSTMB8+M-OZHlOPr=91-ZrFth zYI7xYrc6I|ht2GltKFlth%N6bs;HuhD;WO)MG3Qiu@mrv00000NkvXXu0mjf5^6O^ diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/img/altipath.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/img/altipath.svg deleted file mode 100644 index 1ac34b414..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ElevationPath/img/altipath.svg +++ /dev/null @@ -1,62 +0,0 @@ - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/DSFRexportStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/DSFRexportStyle.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/GPFexport.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/GPFexport.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/GPFexportStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/GPFexportStyle.css deleted file mode 100644 index d464924ad..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/GPFexportStyle.css +++ /dev/null @@ -1,102 +0,0 @@ -/* main container */ -div[id^=GPexportContainer-] { - padding: 5px; -} - -div[id^=GPexportContainer-] > input.GPsubmit { - color: white; -} - -/* bouton */ -input[id^=GPexportButton-] { - min-width: fit-content; - padding-left: 25px; - padding-right: 5px; - background-image: url("img/GPexportSave.svg"); - background-size: 25px 25px; - background-repeat: no-repeat; -} - -/* menu */ -.GPexportMenuHidden { - visibility: hidden; -} - -.GPexportMenuContainer { - position: relative; - display: inline-block; -} - -.GPexportMenuContent { - display: none; - position: absolute; - background-color: #f1f1f1; - min-width: 80px; - padding: 8px; - border-radius: 10px; - box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); - z-index: 1; -} - -.GPexportMenuContent a:hover { background-color: #f1f1f1; } - -.GPexportMenuContainer:hover .GPexportMenuContent { display: block; } - -/* menu des formats */ -.GPexportMenuContent .container { - display: block; - position: relative; - padding-left: 15px; - margin-bottom: 5px; - cursor: pointer; - font-size: 14px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.GPexportMenuContent .container input { - position: absolute; - opacity: 0; - cursor: pointer; - height: 0; - width: 0; -} - -.GPexportMenuContent .checkmark { - position: absolute; - top: 0; - left: 0; - height: 12px; - width: 12px; - background-color: #eee; - border-radius: 50%; -} - -.GPexportMenuContent .container:hover input ~ .checkmark { - background-color: #ccc; -} - -.GPexportMenuContent .container input:checked ~ .checkmark { - background-color: #366291; -} - -.GPexportMenuContent .checkmark:after { - content: ""; - position: absolute; - display: none; -} - -.GPexportMenuContent .container input:checked ~ .checkmark:after { - display: block; -} - -.GPexportMenuContent .container .checkmark:after { - top: 4px; - left: 4px; - width: 4px; - height: 4px; - border-radius: 50%; - background: white; -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/img/GPexportSave.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/img/GPexportSave.svg deleted file mode 100644 index 8f5d0b8ac..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Export/img/GPexportSave.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/DSFRgetFeatureInfoStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/DSFRgetFeatureInfoStyle.css deleted file mode 100644 index 0aed2d7a5..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/DSFRgetFeatureInfoStyle.css +++ /dev/null @@ -1,15 +0,0 @@ -/* GET FEATURE INFO */ - -.gpf-btn-icon-getfeatureinfo { - background-image: url("img/GFI.svg"); - background-repeat: no-repeat; - background-size: auto auto; - background-position: center center; -} - -button[id^="GPgetFeatureInfoPicto-"][aria-pressed="true"] { - background-image: url("img/NoGFI.svg"); - background-repeat: no-repeat; - background-size: auto auto; - background-position: center center; -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/GPFgetFeatureInfo.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/GPFgetFeatureInfo.css deleted file mode 100644 index 2bf4b1d72..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/GPFgetFeatureInfo.css +++ /dev/null @@ -1,10 +0,0 @@ -/* GET FEATURE INFO */ - -div[id^=GPgetFeatureInfo-] { - top: 260px; - left: 10px; -} - -button[id^="GPgetFeatureInfoPicto-"][aria-pressed="false"] {} - -button[id^="GPgetFeatureInfoPicto-"][aria-pressed="true"] {} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/GPFgetFeatureInfoStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/GPFgetFeatureInfoStyle.css deleted file mode 100644 index b45770a8a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/GPFgetFeatureInfoStyle.css +++ /dev/null @@ -1,11 +0,0 @@ -/* GET FEATURE INFO */ - -.GPgetFeatureInfoPicto { - background-position: 1px center; - background-image: url("img/GPactivateGfi.png"); - background-repeat: no-repeat; -} - -button[id^="GPgetFeatureInfoPicto-"][aria-pressed="true"] { - background-position: -25px center; -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/img/GFI.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/img/GFI.svg deleted file mode 100644 index fdab95333..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/img/GFI.svg +++ /dev/null @@ -1,56 +0,0 @@ - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/img/GPactivateGfi.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/GetFeatureInfo/img/GPactivateGfi.png deleted file mode 100644 index 81397bee113df35fbd460ff5fb4481da1b70782f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9904 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 - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/DSFRisochronStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/DSFRisochronStyle.css deleted file mode 100644 index 1fa4f76df..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/DSFRisochronStyle.css +++ /dev/null @@ -1,16 +0,0 @@ -.gpf-btn-icon-isocurve { - background-image: url("img/isochrone.svg"); - background-repeat: no-repeat; - background-size: auto auto; - background-position: center center; -} - -.gpf-btn-icon-close {} - -.gpf-flex-isocurve { - justify-content: unset; -} - -.gpf-btn-icon-isocurve-reset { - background-position: -29px center; -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/GPFisochron.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/GPFisochron.css deleted file mode 100644 index ef62b7a0a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/GPFisochron.css +++ /dev/null @@ -1,147 +0,0 @@ -/* ISOCHRON */ - -div[id^=GPisochron-] { - top: 140px; - left: 10px; -} - -/* Showing/hiding mouse position panel */ - -button[id^="GPshowIsochronPicto-"][aria-pressed="false"] + dialog { - display: none; - visibility: hidden; - opacity: 0%; -} - -button[id^="GPshowIsochronPicto-"][aria-pressed="true"] + dialog { - display: block; - visibility: visible; - opacity: 100%; -} - -/* General panels */ - -[id^=GPisochronPanel-] { - position: absolute; - height: inherit; - top: 0px; - left: 34px; - z-index:2; -} - -/* Isochron form */ - -form[id^=GPisochronForm] { - padding: 15px; -} - - -input[id^="GPisochronOriginPointer"] + .GPisochronOriginPointerImg { - background-position: -1px -1px; -} - -input[id^="GPisochronOriginPointer"]:checked + .GPisochronOriginPointerImg { - background-position: -29px -1px; -} - -/* Alternative choice */ - -div[id^=GPisochronChoice] { - display: -webkit-flex; - display: -ms-flexbox; - display: -webkit-box; - display: flex; - -webkit-justify-content: space-between; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; -} - -/* -input[id^=GPisochronChoiceAltChron] + .GPisochronChoiceAltImg { - background-position: -56px 0; -} - -input[id^=GPisochronChoiceAltChron]:checked + .GPisochronChoiceAltImg { - background-position: -84px 0; -} - -input[id^=GPisochronChoiceAltDist] + .GPisochronChoiceAltImg { - background-position: -112px 0; -} - -input[id^=GPisochronChoiceAltDist]:checked + .GPisochronChoiceAltImg { - background-position: -140px 0; -}*/ - -div[id^=GPisochronValueChron], -div[id^=GPisochronValueDist] { - width: 220px; - margin: auto; -} - -/* Mode choice */ - -.GPisochronFormMini { - max-height: 58px; - overflow: hidden; -} - -.GPisochronFormMini .GPpanelFooter button[id^="GPisochronReset-"], -.GPisochronFormMini .GPpanelFooter input[id^="GPisochronSubmit-"], -.GPisochronFormMini button[id^="GPshowIsoExclusionsPicto-"] { - display: none; -} - -div[id^=GPisochronModeChoice] { - display: -webkit-flex; - display: -ms-flexbox; - display: -webkit-box; - display: flex; - -webkit-justify-content: space-between; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; - margin: 15px 0; -} - -div[id^=GPisochronTransportChoice] > .GPisochronTransportChoice { - display: inline-flex; -} - -/* Showing/hiding exclusions */ - -button[id^="GPshowIsoExclusions"] { - position: absolute; - border: unset; - bottom: 0; - right: 0; - transition: all 0.5s ease-out 0s; -} - -button[id^=GPshowIsoExclusions][aria-pressed="false"] + div[id^=GPisoExclusions] { - max-height: 0; - opacity: 0; - margin-bottom: 0; -} - -button[id^=GPshowIsoExclusions][aria-pressed="true"] + div[id^=GPisoExclusions] { - display: block; - max-height: 76px; - opacity: 1; - margin-bottom: 15px; -} - -div[id^=GPisoExclusions] { - transition: max-height 0.5s ease-in-out 0.25s, opacity 0.5s ease-in-out 0.25s, margin 0.3s ease-in-out 0.25s; - overflow: hidden; -} - -/* Reset picto */ - -button[id^=GPisochronReset] { - -} - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/GPFisochronStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/GPFisochronStyle.css deleted file mode 100644 index 9d514bda2..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/GPFisochronStyle.css +++ /dev/null @@ -1,190 +0,0 @@ -/* ISOCHRON */ -[id^=GPisochronPanel-] { - width: 280px; -} - -.GPshowIsochronPicto { - background-image: url("img/GPisochronOpen.png"); - background-repeat: no-repeat; - background-position: 1px center; -} - -.GPisochronPanelClose { - background-image: url("img/GPisochronOpen.png"); -} - -/* Reset picto */ - -button[id^=GPisochronReset] { - opacity: 0.8; - transition: opacity 0.2s ease-out; -} - -button[id^=GPisochronReset]:hover { - opacity: 1; -} - -.GPisochronReset { - background-color: #366291; - background-image: url("img/GPisochronOptions.png"); - background-position: -281px center; -} - -/* Isochron form */ - -div[id^=GPisochronChoice] { - margin: auto; - margin-top: 15px; - margin-bottom: 5px; - width: 160px; -} - -.GPisochronChoiceAlt input:checked + label + span { - color: #366291; -} - -input[id^=GPisochronChoiceAltChron] + .GPisochronChoiceAltImg { - background-position: -56px 0; -} - -input[id^=GPisochronChoiceAltChron]:checked + .GPisochronChoiceAltImg { - background-position: -84px 0; -} - -input[id^=GPisochronChoiceAltDist] + .GPisochronChoiceAltImg { - background-position: -112px 0; -} - -input[id^=GPisochronChoiceAltDist]:checked + .GPisochronChoiceAltImg { - background-position: -140px 0; -} - -input[id^=GPisochronChoiceAltChron] { - background-image: url("img/GPisochronOptions.png"); -} - -.GPisochronOriginPointerImg, -.GPisochronChoiceAltImg, -.GPisochronTransportImg { - background-image: url("img/GPisochronOptions.png"); - font-size: 0; -} - -.GPisoExclusionsOption { - background-image: url("img/GPisochronCheck.png"); -} - -.GPisochronOriginPointerImg { - width: 28px; - background-color: #F2F2F2; - cursor: pointer; -} - -.GPisochronChoiceAlt input { - display: none; -} - -.GPisochronChoiceAltImg { - display: block; - width: 28px; - height: 28px; - margin: auto; - cursor: pointer; -} - -.GPisochronChoiceAlt span { - cursor: pointer; - display:block; - color: #999; -} - -.GPisochronModeLabel { - display: block; - text-align: center; - margin-bottom: 5px; -} - -input[id^=GPisochronTransportCar] + .GPisochronTransportImg { - background-image: url("img/GPisochronOptions.png"); - background-position: -168px 0; -} - -input[id^=GPisochronTransportCar]:checked + .GPisochronTransportImg { - background-image: url("img/GPisochronOptions.png"); - background-position: -196px 0; -} - -input[id^=GPisochronTransportPedestrian] + .GPisochronTransportImg { - background-image: url("img/GPisochronOptions.png"); - background-position: -224px 0; -} - -input[id^=GPisochronTransportPedestrian]:checked + .GPisochronTransportImg { - background-image: url("img/GPisochronOptions.png"); - background-position: -252px 0; -} - -.GPisochronTransportChoice input { - display: none; -} - -.GPisochronTransportImg { - display: inline-block; - width: 28px; - height: 28px; - cursor: pointer; -} - -.GPisochronTransportImg:first-of-type { - margin-left: 18px; - margin-right: 10px; -} - -select[id^=GPisochronDirectionSelect] { - width: 80px; -} - -.GPshowIsoExclusionsPicto { - top: 250px; - right: 0; - transition: all 0.5s ease-out 0s; -} - - -.GPisoExclusionsLabel { - display: block; - text-align: center; - margin-bottom: 10px; - font-weight: bold; - line-height: 16px; -} - -.GPisoExclusionsOptions { - display: -webkit-flex; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; -} - -.GPisoExclusionsOption { - display: block; - height: 28px; - line-height: 26px; - color: #A77; - background-color: #FEE; - padding-left: 28px; - padding-right: 5px; - border: 1px solid #A77; - border-radius: 3px; - cursor: pointer; -} - -input:checked + .GPisoExclusionsOption { - background-color: #EFE; - background-position: 0 -28px; - color: #797; - border: 1px solid #797; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/img/GPisochronCheck.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Isochron/img/GPisochronCheck.png deleted file mode 100644 index 6f14444ec74e706414d170c2ad11f6761051ccab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1316 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 - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/DSFRlayerImportStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/DSFRlayerImportStyle.css deleted file mode 100644 index ccbc2647d..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/DSFRlayerImportStyle.css +++ /dev/null @@ -1,14 +0,0 @@ -.gpf-btn-icon-import { - background-image: url("img/layerimport.svg"); - background-repeat: no-repeat; - background-size: auto auto; - background-position: center center; -} - -.gpf-btn-icon-return { - background-color: #366291; - background-image: url("img/GPimportMapBoxReturn.png"); - background-position: 3px center; -} - -.gpf-btn-icon-close {} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/GPFlayerImport.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/GPFlayerImport.css deleted file mode 100644 index 83a7e9e0a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/GPFlayerImport.css +++ /dev/null @@ -1,115 +0,0 @@ -/****************/ -/* Layer Import */ -/****************/ - -div[id^="GPimport-"] { - top: 220px; - left: 10px; -} - -/*******************************/ -/* Showing/hiding import panel */ -/******************************/ - -button[id^="GPshowImportPicto-"][aria-pressed="false"] + dialog { - display: none; - visibility: hidden; - opacity: 0%; -} - -button[id^="GPshowImportPicto-"][aria-pressed="true"] + dialog { - display: block; - visibility: visible; - opacity: 100%; -} - -/******************/ -/* General panels */ -/******************/ - -[id^="GPimportPanel-"], -[id^="GPimportGetCapPanel-"], -[id^="GPimportMapBoxPanel-"] { - left: 34px; - top: 0px; - height: inherit; -} - -[id^="GPimportPanel-"] { - position: absolute; -} - -[id^="GPimportGetCapPanel-"], -[id^="GPimportMapBoxPanel-"] { - position: absolute; -} - -[id^="GPimportGetCapPanel-"], -[id^="GPimportMapBoxPanel-"] { - display: none; -} - -[id^="GPimportMapBoxPanelReturnPicto-"] { - position: absolute; - width: 26px; - height: 26px; - border-radius: 3px; - opacity: 1; - background-position: 0 0; - cursor: pointer; -} - -/***************/ -/* Import form */ -/***************/ -form[id^=GPimportForm-] { - padding: 15px; -} - -div[id^="GPimportChoice-"] { - display: -ms-flexbox; - display: -webkit-box; - display: flex; - -ms-flex-pack: distribute; - justify-content: space-around; -} - -input[id^="GPimportSubmit-"] { - margin-top: 20px; -} - -/*******************/ -/* Get cap results */ -/*******************/ - -div[id^="GPimportGetCapResults-"], -div[id^="GPimportMapBoxResults-"] { - background-color: #FFF; - height: 140px; - overflow-y: auto; - resize: vertical; -} - -input[id^="GPimportGetCapRubrique-"], -input[id^="GPimportMapBoxSource-"] { - display: none; -} - -input[id^="GPimportGetCapRubrique-"]~li, -input[id^="GPimportMapBoxSource-"]~div { - display: none; -} - -input[id^="GPimportGetCapRubrique-"]:checked~li, -input[id^="GPimportMapBoxSource-"]:checked~div { - display: block; -} - -input[id^="GPimportGetCapRubrique-"]~ul { - display: block; -} - -input[id^="GPimportGetCapRubrique-"]:checked~ul { - display: none; -} - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/GPFlayerImportStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/GPFlayerImportStyle.css deleted file mode 100644 index 82ebfc4b6..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/GPFlayerImportStyle.css +++ /dev/null @@ -1,201 +0,0 @@ - -/* Import form */ -[id^="GPimportPanel-"] { - width: 280px; -} - -[id^="GPimportGetCapPanel-"], -[id^="GPimportMapBoxPanel-"] { - width: 340px; -} - -div[id^="GPimportTypeLine-"] { - border-bottom: 1px solid #999; - padding-bottom: 15px; - margin-bottom: 15px; -} - -div[id^="GPimportChoice-"] { - margin-top: 5px; - margin-bottom: 5px; -} - -.GPshowImportPicto { - background-image: url("img/GPimportOpen.png"); - background-repeat: no-repeat; - background-position: 1px center; -} - -.GPimportPanelClose, -.GPimportGetCapPanelClose, -.GPimportMapBoxPanelClose { - background-image: url("img/GPimportOpen.png"); -} - -.GPimportMapBoxPanelReturnPicto { - background-color: #366291; - background-image: url("img/GPimportMapBoxReturn.png"); - /* background-position: 3px center; */ -} - -.GPimportChoiceAlt input[type="radio"] { - display: none; -} - -.GPimportChoiceAltTxt { - display: block; - line-height: 28px; - color: #BBB; - font-weight: bold; - cursor: pointer; -} - -input[type="radio"]:checked + .GPimportChoiceAltTxt { - color: #366291; -} - -/* Line inputs */ - -.GPimportInputLine { - display: -ms-flexbox; - display: -webkit-box; - display: flex; - margin-bottom: 10px; -} - -.GPimportInputLine > * { - display: block; - height: 28px; - line-height: 26px; - border: 1px solid #999; - border-radius: 0; -} - -.GPimportInputLine *:not(:last-child) { - border-right:none; -} - -.GPimportInputLine *:first-child { - border-radius: 3px 0 0 3px; -} - -.GPimportInputLine *:last-child { - border-radius: 0 3px 3px 0; -} - -.GPimportInputLine > *:not(input) { - overflow: hidden; - white-space: nowrap; - -o-text-overflow: ellipsis; - text-overflow: ellipsis; -} - -.GPimportInputLine > input { - -webkit-box-flex: 1; - -ms-flex: 1; - flex: 1; - padding: 0 5px; - min-width: 0; -} - -.GPimportInputLine > select { - -webkit-box-flex: 1; - -ms-flex: 1; - flex: 1; - padding-right: 7px; -} - -.GPimportInputLine > label { - background-color: #F2F2F2; - color: #666; - padding-left: 7px; - padding-right: 9px; - cursor: pointer; -} - - - -.GPimportGetCapProposal { - width: 100%; - height: 28px; - line-height: 16px; - padding: 6px 10px; - color: #5E5E5E; - font-size: 1.0em; - overflow: hidden; - white-space: nowrap; - -o-text-overflow:ellipsis; - text-overflow:ellipsis; - cursor: pointer; - list-style-type: none; -} - -.GPimportGetCapRubriqueTitle, -.GPimportMapBoxSourceTitle, -.GPimportMapBoxListSourceTitle { - color: #5E5E5E; -} - -.GPimportGetCapRubrique, -.GPimportGetCapListRubrique, -.GPimportMapBoxSource, -.GPimportMapBoxListSource { - list-style-type: none; -} - -li.GPimportGetCapRubrique:before, -li.GPimportGetCapListRubrique:before, -li.GPimportMapBoxSource:before, -li.GPimportMapBoxListSource:before { - /* content: "→ "; caractère UTF-8 */ - content: "» "; -} - -.GPimportGetCapProposal:hover, -.GPimportGetCapRubrique:hover, -.GPimportMapBoxSource { - -} - -.GPimportGetCapRubriqueTitle:hover, -.GPimportMapBoxSourceTitle:hover { - color: #000000; -} - -.GPimportGetCapProposal:hover { - color: #000000; -} - -.GPimportMapBoxSourceVisibility, -.GPimportMapBoxSourceStyle, -.GPimportMapBoxSourceFilter, -.GPimportMapBoxSourceScale { - display: inline-block; - margin-left: 15px; -} - -.GPimportMapBoxJsonEdit { - outline: 1px solid #ccc; - padding: 5px; - margin: 5px; -} -.GPimportMapBoxJsonEdithidden { - display: none; -} - -.gp-json-string { color: green; } -.gp-json-number { color: darkorange; } -.gp-json-boolean { color: blue; } -.gp-json-null { color: magenta; } -.gp-json-key { color: red; } - -.GPimportMapBoxSourceVisibilityInput { - display: block !important; -} - -.GPimportMapBoxSourceVisibilityLabel { - -} - -.GPimportMapBoxSourceScale { -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/img/GPimportMapBoxReturn.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/img/GPimportMapBoxReturn.png deleted file mode 100644 index 7b4eaff9fde9c255dfcfe37e0afd1e153a8fc298..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 421 zcmV;W0b2fvP)M6=aDU{ISVSOh^36iohx#UNM=D;sP!5w>YH z2nM5q$s+6?%PvgVl^LEpX-^tvzIorf^W8V^!H^+?LcLJG)aA0wy6mNlRmov?4jg4} z#lQ^JQ{d!3zt+efX2-x;k4GEoB+v#vfLGupB0f_xJG2;W^+DZIt3}NYOyg0VDU#tr zVoYm5J$I#Qs5R5s?lpe&F|7cXK(CkXfv3*(C@>Ao11rE-M%Rpp)goC|)$1NJ-|wTJ zQm-<)mO59ofvW0F9>Yu=cNy(Yp@kn2EnpM4%`?G>5ZDENk{VDQRU4i4ww^=ZZMu5O z&!D2t=F~2B44=!~&YJ35;oTyE8ZcgFg%j#~X%$AqH_#~iSh6%coDG~`Hq4+1HzsWR P00000NkvXXu0mjf7)Pts diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/img/GPimportOpen.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/img/GPimportOpen.png deleted file mode 100644 index 518cc2a133a2dab4f476eddbba580d1c38f2b54b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 638 zcmV-^0)hRBP)=WVWFL1C87vwWqs8p z5)>?LQ(6f@FJjVJ*;y!9q)urefmAkvNU*VpVi3Kb#m;e?b?=hhyI`{qw%D2Z-uvFp z?tGghHEPtTQ5BfQT3oaLdq0(dLwJbqhWLp^9GL?D9A2O~rlx_XcrdBhCA<$4Tj=06 zK1XZ=mnYz#!=K<`-3!h@~M_kL~K<54mHY5B6cS~vwUZpHn(ad#bfR&;yjv{YGC*W6f=vc01m!XIq z#v|-R`VG!a!BoC`rOb5jEf%h$J)-U(Lz!GV)(Wo9gr=&Q3Bv7I_$0q@j7U+pn!y3v z``*BKQ-#B#2-%|NNs>sCjO`8FkbcQbKg4BiIG7H;lk2v-fyr8S(Lf|-?qSY=ZU%;Sgjj9J3bydmjyTa=zf zJJLy4N^p#s!PqVw>7`ADSQ{ULXag5Ax$}m95SzGIQRCnb)|}u>i1wpn^SSQzFf##v z*YMY;a5U#S)yMtHhBBnr4F?7lKKwD<3-Mq^PO~u8!@@K)2c#{$i>oy?;uo Y1?(>-;dZ{-{r~^~07*qoM6N<$f|C^+C;$Ke diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/img/layerimport.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/img/layerimport.svg deleted file mode 100644 index 697017bd9..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerImport/img/layerimport.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/DSFRlayerSwitcherStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/DSFRlayerSwitcherStyle.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcher.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcher.css deleted file mode 100644 index c23dee320..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcher.css +++ /dev/null @@ -1,97 +0,0 @@ -/* LAYER SWITCHER */ - -div[id^=GPlayerSwitcher-] { - top: 8px; - 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; - -webkit-user-select: none; - user-select: none; - /* Required to make elements draggable in old WebKit */ - -khtml-user-drag: element; - -webkit-user-drag: element; -} - -/* Manage opening of the components through hiden checkboxes */ - -div[id^=GPlayerSwitcher-] input[type="checkbox"] + button + dialog { - max-height: 0px; -} - -input[id^=GPshowLayersList-] { - display: none; -} - -/* 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; - opacity: 0%; -} - - -button[id^="GPshowLayersListPicto-"][aria-pressed="true"] + dialog { - display: block; - visibility: visible; - 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 */ - -dialog[id^=GPlayersList] { - position: relative; - border-bottom-right-radius: 0; - opacity: 0; - overflow: auto; - /* transition: max-height 0.5s ease-out 0s, opacity 0.5s ease-out 0.25s; */ -} - -button[id^=GPshowLayersListPicto][aria-pressed="true"] + dialog[id^=GPlayersList] { - 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; */ - -} -/* Layer : general */ - -.GPlayerSwitcher_layer { - position: relative; - top: 0; - background-color: #FFF; - border-bottom: 1px dotted #CCC; - overflow: hidden; -} - -dialog[id^=GPlayersList] .GPlayerSwitcher_layer:last-child { - border-bottom: none; -} - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcherStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcherStyle.css deleted file mode 100644 index 2c5e517f0..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/GPFlayerSwitcherStyle.css +++ /dev/null @@ -1,374 +0,0 @@ -/* LAYER SWITCHER OL3 */ - - - - - -/* Layers list */ - - -/* Layer info panel */ - -div[id^=GPlayerInfoPanel] { - right: 190px; -} - -div[id^=GPlayerInfoTitle] { - color: #366291; - border-bottom: 1px solid #366291; -} - - -.GPlayerBasicTools, -.GPlayerAdvancedTools { - position: relative; - width: 100%; - height: 28px; -} - -.GPlayerVisibility, -.GPlayerInfo, -.GPlayerInfoOpened, -.GPlayerRemove { - width: 28px; - height: 28px; - cursor: pointer; -} - -.GPlayerVisibility, -.GPlayerName, -.GPlayerInfo, -.GPlayerInfoOpened, -.GPlayerRemove, -.GPlayerOpacity, -.GPlayerOpacityValue { - position: absolute; - top: 0; -} - -.GPghostLayer { - opacity: 0; -} - -/* Layer basic tools */ - -.GPlayerBasicTools { - background-color: #FFF; -} - - - -.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 */ - - -.GPlayerVisibility, -.GPshowLayerAdvancedTools, -.GPlayerInfo, -.GPlayerInfoOpened, -.GPlayerRemove { - background-image: url("img/GPlayerTools.png"); -} - -/* Opacity slider : Chrome, Safari, Opera */ - -.GPlayerOpacity input[type="range"]::-webkit-slider-runnable-track { - background: url("img/GPopacitySlider.png"); -} - -/* Opacity slider : Firefox */ - -.GPlayerOpacity input[type="range"]::-moz-range-track { - background: url("img/GPopacitySlider.png"); -} - -/* Opacity slider : IE */ - -.GPlayerOpacity input[type="range"]::-ms-track { - background: url("img/GPopacitySlider.png"); -} - - -div[id^=GPlayerInfoQuicklook] { - background-image: url("img/GPlayerInfo.png"); -} - -div[id^=GPlayerInfoClose] { - background-image: url("img/GPlayerInfoClose.png"); -} - -.GPlayerInfoLink, -.GPlayerInfoPopup { - background-image: url("img/GPlayerInfo.png"); -} - -.GPlayerVisibility { - left: 0; - background-position: -28px 0; -} - -input[type="checkbox"]:checked + .GPlayerVisibility { - background-position: 0 0; -} - -.GPshowLayerAdvancedTools { - top: 0; - right: 0; - background-position: -112px 0; -} - -.GPlayerInfo { - left: 0; - background-position: -55px 0; -} - -.GPlayerInfoOpened { - left: 0; - background-position: -83px 0; -} - -.GPlayerOpacity { - left: 28px; - width: calc(100% - 100px); - height: 28px; - padding-left: 8px; -} - -.GPlayerOpacityValue { - width: 32px; - left: calc(100% - 60px); - line-height: 28px; - font-size: 10px; - font-style: italic; - cursor: default; -} - -.GPlayerRemove { - right: 0; - background-position: -140px 0; -} - -/* Opacity slider : general */ - -.GPlayerOpacity input { - -webkit-appearance: none; - -moz-appearance: none; - background: none; - display: block; - width: 100%; - height: 100%; - margin: 0; - padding: 0; - overflow: hidden; - cursor: pointer; -} - -.GPlayerOpacity input[type="range"]:focus { - box-shadow: none; - outline: none; -} - -/* Opacity slider : Chrome, Safari, Opera */ - -.GPlayerOpacity input[type="range"]::-webkit-slider-runnable-track { - -webkit-appearance: none; - height: 3px; -} - -.GPlayerOpacity input[type="range"]::-webkit-slider-thumb:before { - position: absolute; - top: 0; - right: 50%; - left: -200px; - height: 3px; - pointer-events: none; -} - -.GPlayerOpacity input[type="range"]::-webkit-slider-thumb { - width: 9px; - height: 17px; - -webkit-appearance: none; - border: 2px solid #FFF; - background-color: #505050; - position: relative; - top: -7px; -} - -/* Opacity slider : Firefox */ - -.GPlayerOpacity input[type="range"]::-moz-range-track { - width: 80px; - height: 3px; -} - -.GPlayerOpacity input[type="range"]::-moz-range-thumb { - width: 5px; - height: 13px; - border: 2px solid #FFF; - border-radius: 0; - box-shadow: 0; - background-color: #505050; - position: relative; -} - -/* Opacity slider : IE */ - -.GPlayerOpacity input[type="range"]::-ms-track { - border: 0; - border-color: transparent; - border-radius: 0; - border-width: 0; - color: transparent; - height: 3px; - width: 80px; -} - -.GPlayerOpacity input[type="range"]::-ms-fill-lower, -.GPlayerOpacity input[type="range"]::-ms-fill-upper { - background: transparent; - border-radius: 0; -} - -.GPlayerOpacity input[type="range"]::-ms-thumb { - width: 5px; - height: 13px; - border: 2px solid #FFF; - background-color: #505050; -} - -.GPlayerOpacity input[type="range"]::-ms-tooltip { - display: none; -} - -/* Layer info panel */ - -div[id^=GPlayerInfoPanel] { - position: absolute; - top: 0; - overflow-y: hidden; - padding-top: 10px; - padding-bottom: 10px; -} - -.GPlayerInfoPanelOpened { - display: block; -} - -.GPlayerInfoPanelClosed { - display: none; -} - -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); - margin: auto; - margin-bottom: 10px; - padding-bottom: 5px; - text-align: center; - font-size: 1.1em; - font-weight: bold; -} - -div[id^=GPlayerInfoQuicklook] { - position: absolute; - top: -2px; - left: 10px; - width: 20px; - height: 20px; - cursor: pointer; -} - -div[id^=GPlayerInfoClose] { - position: absolute; - top: -8px; - right: 10px; - width: 28px; - height: 28px; - cursor: pointer; -} - -div[id^=GPlayerInfoDescription] { - font-size: 0.9em; -} - -div[id^=GPlayerInfoLegend] { - -} - -div[id^=GPlayerInfoMetadata] { - -} - -.GPlayerInfoSubtitle { - padding-left: 35px; - font-weight: bold; - margin-top: 10px; - margin-bottom: 4px; -} - -.GPlayerInfoLink, -.GPlayerInfoPopup { - line-height: 20px; - padding-left: 23px; - white-space: nowrap; - overflow-x: hidden; - text-overflow: ellipsis; - color: #999999; - background-repeat: no-repeat; - cursor: pointer; -} - -.GPlayerInfoLink { - background-position: 0 -20px; -} - -.GPlayerInfoLink:hover, -.GPlayerInfoPopup:hover { - color: #333; -} - -.GPlayerInfoLink a, -.GPlayerInfoLink a:visited -.GPlayerInfoLink a:focus -.GPlayerInfoLink a:hover { - text-decoration: none; - color: inherit; -} - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/img/GPlayerInfo.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/img/GPlayerInfo.png deleted file mode 100644 index b7d5a0be86eb538881ed366cc2d6cbd564bc8ad3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 726 zcmV;{0xA88P)rGGHj>jiiHZ4@SYmRXPv3r1S8Kd0F+r#wXnY~H{$a}YNFAue4&3$>-G2dtE#HD6~-nP zE%k3_tldj_r3Ij_#(00&x-^`awT6Wdk(ZVam+9*>N&+_{cOcda+y?PL3ti|2ApvTt z1%8P~UK~1iX&1<=2i+g-nRw(0Y_avUpr=o^<34-CH#3}iwKZiDVAQssuR}HWU@KsXPj{bA~0gJA|dH!B+)&Kwi07*qo IM6N<$g3o3~Pyhe` diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/img/GPlayerInfoClose.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/img/GPlayerInfoClose.png deleted file mode 100644 index 1d61d5dec4a4151c77e2122983e60772c059515f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 535 zcmV+y0_gpTP)j0BKLeeY)Ak{q}O3`9e-pGpk_W8|%+?xfE zcaPSxg`QjaE!;}?eHUri>8?8YSH=4~Jrq4laakxD2U051Z z?8z@{%+8pc*=e>jPkW+LKw!8g)I1EiEX6E9V7PorZ)Mcr7b04nzG{CGhe^2s;2xm- zmmIO=0^)F~o$i+U2g7Gl@BmT z7KJ1q{0Si#AetG1R7!+eMajq-CVMFvoms+yNKGxb7Y(Jz&NRpO>;tjOOMv)=uBqo^sF$4y0ik&-m&NZ9OE1qtPMx%eO zt*!m%XrGZW)||d}?V9}Nn{SvkYZgUCMQK}LH8nNwj2ky@hm>+1kU!kq3w#oZL>hPR z-u-Pl{aC*1@;jysb|Ce2Ao2ku^a}VykBY|6|FG%Xu`W=v*}OtZX%|A=0FYAJ&1N&e zs0BLaBIvel+vL4__c(OuP}&4~^5n^Pfm6Vwmt68#O1ZVFs>+=XdxiThzl)Twv?nB6 zZ&a7L$I{%?)z!^1nM@^8$`asLuki0bLWmA2gvi<73r`zUu#ban(TWnm5(Kn3L*NWl%u&cYgoi3!`F+HBWPV+o%DLWtXZ>$qM{)@7S?JOL|*3%NOk3IKBx0`@YN1 z-66jdCVlpe-m7 zC1hu3i&%S0OA7#Rzx_4zs>Hh~G^aG^_UgO^%r0?faV)ebDTd0y~l;X-by{fVV~&aR;1E=ag5D z+3Oy1_Uu{0;V{RJ9TQJ)r(Um@4I4H{x7$rcMFs8c?N}@pcJADXrfD2KdQ>LkV0U*n zkw}En(ozuAc-uP1Cz*Y(no+Ux7_a~Dd;@_C@wCJH{|B#k(-+r{~qg;Qa*U?qJC9pb91xwcsx{8RK%lcPfw2o*tl_{ zuv)G7d_JySyN1nXqrbnO88c>xEnBwW@puvzO;=Z!3&~e?pj^lzgP#rW5@f$V8Y5JF3h6n6523COWg(%=q!+p+{|xvLd(bd)%(Vy_fE!L!c&;=>fpt;2;)@ z<%NEW#S%a8rYumK&4$nCqpPdynL$z%1-IKB7oe)DXqtwiC{I>vM~BojjiREWgq+LC z$wAXJ?%lg5pLgnuFTMaEJ3AXiQ3!{_Sglq7dU|?fI2`P(}`clwmU*d`u zeW`~vE=nP`O&K(Q8qFZuQC(KpQC(IT%^*5u(EO5QPEQ0TP+O?ivoxN)Pf z*=)F6F8qGKR8*H{CqS`WAfz51cO0&>((uDa&nkIe}19|rK?HI z!N(~SVv?{YK2B9MKV%Lng!meGCV)K6gb5QE92|V++LR7S@4fdPilR_kTT3_`MpaeL zoH;{9MFm%`ToDe31DDH%s;U6g*4CmZ3I`7!OzITBV8H^cRx6#IokSuL6h)!CyPHRk z9s#gw)hfJRZ#-Iec6MU5S`%Ij0Fg+f5qO-y;13K94K*e^d3sbNWDgj~9Lj7=hj4zV z98}l!uVY*Mgb5Q~=(k#}@ziWI0!^q6+TPxd!{I>Fv}f|mSRJ&brG+(X)}*Zt+TY)g zs;cz$^>O<2X(mpb$olo`Q4|G5QMh~eF8TTSN!LM#{c;E)nnp1eQcCHls;au2ieL6U zmmE?sN_)cbm+DQINh8I(o3e+5*$t2(qmH(k@?bij-_X#oK-cwKQ>RX4?%cU_c6Ksn zP5}VDy*(^nzMMOE?!*Glg38Luzo%3OjZsxqB>)@_hxGY;&-BF(N9WI<7w6BPPm7}~ zSFRMXH%VW9`DHx+jO916w^ymYNvf)l?x$Gy{vvGgc#6ueQT=X1h`RM=C<#- zR4#=)1>$A(!T~A8)^v*#U|5iaydg{`(*s@CM|DWjb^SrwBIy5TOr{`>D! zUS9r2ese=ZgA$EKw+kWG0dt0%dx5J%LqmiM0XY%F0UXPePy@Hf)fgP>6c!3HEH`F8k#IK@t$Asj$Z!;#Vf2?p zUk71ECym(^Ahji~5hcO-X(i=}MX3zs<>h*rdD+Fui3O>8`9N=3Y5X9leJi&>9fp5#Z*77^| RR|54ic)I$ztaD0e0sssXISv2- diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/img/GPshowLayersList.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/LayerSwitcher/img/GPshowLayersList.png deleted file mode 100644 index 60daaa8faf852134f5a8b5001115c00dc97261dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7054 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 O0000EmQo!m>^@QW{N3EV`?%?Dn~LC$%>+| zvJcJCf`*VRE3r`nO|-x=9brT%vK$p7Qbx;4lqkHv{(0_nx^v%q&-(#a8rIC7^S)=V zv(Db@+51`RtaA#LeNw*^MX^Wj({G=vcfY8p6V&_F>Hp6F9ReJfC}TfM{fl~Z zGZgm}FdTSEAG5?cz}3L{z?r~g;2GdHpsk1NRso*?b^#ak0j<3W_$hEF@UBqvvp@%M z2e1UVxfy^40G9`(zLJk-3?I&M4e$uC3^2T2D<+Kzu#WP6x>iGN~uMX`-=VEoWx;*^aYFhhvXlcOF|wQB!v zuAid*Anivr=Fn1#OW(B6+8Xtj>igA~sz;}PWae>MGcgFYO`WF>>!xqCx-k$KbuLDn54RY4LbwXe!C+s*6`yy)Th;T>bKO3)V5Op%MybYHJinu zUXaOuq?^9O;;1*M9m!5wHTlm3^oP~?Nea$Qz(*aD6`8K9h- zkwts2dWpI~9Z>2Yl{qcw0f(XW0CZshy0Aw7XVrVuE7kK_1kM-Y^as_?XU9xP-;pJ~ z^P_imFZPy(;_4a0m(+z-0m}cGSyZ>E-&XJL%+S(5M%}E=FP&>sPYXkQU;TX+`$3HW z^f~qMOm=n++H1CbB~E`JEC1H)(5`x)j9!)0zg~dGsyo%^dSiu>?`CB@KUD8fKc*g{ zPAn~~E%D>U>WYB1OZ}~SO|F@!{!X3J2tXr3DJx1GJETRx6zb)ffn-JU#b2%3^OVeI7fYBjilwf>bzzt z?r`;q2B@PJI9KI9Yt+R7XL2{X3)O#z>uC_6Hud)0uOomL>6_^P%C1yYda}PR!`_&W}`E6*tV)lmmrl4pa}z_y&NPv%mA)y@Db$|z&*gE&Vn@X>DU_ze6@>yf8dL~*gOLmp9jzH6-BW<^!K`)`&3aB zS46iR*w~A`^}sQ$N)pCo+b+v$RNbKNS7BxM5BI9x9E$j+dU7b}RVCeTBrZ&AV25_@ zpn>Y&tSwu6=sUTW81x$TN%cLYs`ZoVtS&yjMxEQscwdyAdvLP=4N1V;9-Y4@Egw|D zY5n3f6Vq-}7pW)JpuZh?=%fjN2HUu-t&qhXn*!*P)YxWrvk5j-oX19WYBLl!19%Wv z01N>Z1LJ^8fqzxFenf1n0uBQ1237)VyU^ca;Jv^!;FdltHyvK##ofK3`$@p;q9~Sk zDgE>h#cr%{zjbAr8&JnUj{&|0oS6S>fb)R+>YVTsz>UE1asJ@gDs%r*;O)Taz%TZa zx2tyoN7PU`64(K3tzd3_3aym^Iso_%@V*4rM^hdCaf9>eNWt(%U0Cm1}p9>61cC`?=EY;X%WM_8BD&TftVs_Sb zp^3@KxLPGUfzf@q$=WN@8^8u&q&mDPifugsG(N|Hp`43=$6Gk)=aNpZ4u?Mlj08^0 zDr$v{0bZM!*@|5_yFtorPug8Yb^x0aQdaf^(51jwVE%551J3|cfS>1`%_QLd7TR9~ zoKSkkYDPMm0Q%KgeB*%42@{>ifAo+jtSnw2pIsHn+@9ZCJ_f1!*;V{IC5gi5Qab_| z20Yybu+6{(U|3NU(_bh6?RC=ZcX9Fifn5MA130KCilg=c)JFhSmHz-hI>KK2mihGn O0000 - - - - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/img/mesurer-surface.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/img/mesurer-surface.svg deleted file mode 100644 index 6f7e69b90..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/img/mesurer-surface.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/img/modifier-geometrie-old.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/img/modifier-geometrie-old.svg deleted file mode 100644 index 1a8d313df..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Measures/img/modifier-geometrie-old.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/DSFRmousePositionStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/DSFRmousePositionStyle.css deleted file mode 100644 index e867d100c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/DSFRmousePositionStyle.css +++ /dev/null @@ -1,6 +0,0 @@ -.gpf-btn-icon-position { - background-image: url("img/position.svg"); - background-repeat: no-repeat; - background-size: auto auto; - background-position: center center; -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/GPFmousePosition.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/GPFmousePosition.css deleted file mode 100644 index 7eb624d17..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/GPFmousePosition.css +++ /dev/null @@ -1,129 +0,0 @@ -/****************/ -/* MOUSE POSITION */ -/****************/ - -div[id^="GPmousePosition-"] { - bottom: 8px; - left: 10px; -} - -/* Showing/hiding mousePosition panel */ - -button[id^="GPshowMousePositionPicto-"] {} - -button[id^="GPshowMousePositionPicto-"][aria-pressed="false"] + dialog { - display: none; - visibility: hidden; - opacity: 0%; -} - -button[id^="GPshowMousePositionPicto-"][aria-pressed="true"] + dialog { - display: block; - visibility: visible; - opacity: 100%; -} - -/* General panels */ - -dialog[id^=GPmousePositionPanel-] { - bottom: 0px; -} - -button[id^=GPmousePositionPanelClose] { - background-image: url("img/GPmousePositionOpen.png"); -} - -[id^=GPmousePositionPanel-] { - overflow: hidden; - left: 34px; - top: inherit; - position: absolute; - height: inherit; -} - -/* Basic infos */ - -div[id^=GPmousePositionBasicPanel] { - padding: 10px 15px; - position: relative; -} - -/* Settings */ - -div[id^=GPmousePositionSettings-] { - display: block; - max-height: 0; - opacity: 0; - padding-left: 20px; - padding-right: 20px; - /* transition: max-height 0.5s ease-out 0s, opacity 0.5s ease-out 0s; */ -} - -button[id^="GPshowMousePositionSettings"] { - border: unset; -} - -div[id^=GPmousePosition-] button[id^="GPshowMousePositionSettings"][aria-pressed="true"] + div[id^=GPmousePositionSettings-] { - opacity: 1; - padding-bottom: 20px; - max-height: inherit; -} - -button[id^=GPmousePositionSettings-] { - padding-left: 0 15px; - overflow: hidden; -} - -/* General panels */ - -div[id^=GPmousePositionCoordinate-] input.error { - border: 1px solid rgb(255, 0, 0); -} -div[id^=GPmousePositionCoordinate-] input[readonly] { - border: 1px solid transparent; - padding: 2px; - text-align: right; -} - -input[id^=GPmousePositionLat-], input[id^=GPmousePositionLon-] { - width: 120px; -} - -span[id^=GPmousePositionAlt-] { - display: inline-block; - padding: 2px; - width: 120px; - line-height: 20px; - text-align: right; -} - -span[id^=GPmousePositionCloseEdit] { - background-position: -18px 0; - margin-left: 5px; -} - -img[id^=GPmousePositionMarker]:hover { - cursor: pointer; - opacity: 0.7; -} - -/* Map center localisation */ - -#GPmapCenter { - background-image: url("img/GPmapCenter.png"); -} - -#GPmapCenter { - display: none; - position: absolute; - top: 50%; - left: 50%; - width: 50px; - height: 50px; - margin-top: -25px; - margin-left: -25px; -} - -#GPmapCenter.GPmapCenterVisible { - display: block; -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/GPFmousePositionStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/GPFmousePositionStyle.css deleted file mode 100644 index ed2941cc5..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/GPFmousePositionStyle.css +++ /dev/null @@ -1,122 +0,0 @@ - -/* General panels */ -[id^=GPmousePositionPanel-] { - width: 280px; -} - -button[id^="GPshowMousePositionPicto-"] { - background-image: url("img/GPmousePositionOpen.png"); - background-repeat: no-repeat; - background-position: 1px center; -} - -.GPmousePositionEditTool { - background-image: url("img/GPmousePositionEditCoordinates.png"); -} - -/* Map center localisation */ - -.GPmousePositionLabel, -.GPmousePositionCoords { - display: inline-block; - line-height: 20px; -} - -.GPmousePositionLabel { - width: 100px; - font-weight: bold; -} - -.GPmousePositionCoords { - width: 110px; -} - -/* Showing settings */ - -.GPshowMousePositionSettingsPicto { - bottom: 5px; - right: 0; - transition: all 0.5s ease-out 0s; -} - -.GPmousePositionSettingsLabel { - display: block; - margin: auto; - text-align: center; - font-weight: bold; - line-height: 16px; -} - -.GPmousePositionSettingsSelect { - width: 180px; - margin-top: 5px; - margin-inline: auto; -} - -/* sexagesimal coordinates */ - -.GPSexagesimal, .GPSexagesimalsec { - margin:0; - border: 1px solid rgb(204, 204, 204); - border-radius: 4px; -} - -input:read-only.GPSexagesimal, input:read-only.GPSexagesimalsec { - text-align: right; -} - -.GPSexagesimal { - width: 30px; -} - -.GPSexagesimalsec { - width: 45px; -} -.GPmousePositionSexagesimalLabel { - font-size: 1.2em; - vertical-align: middle; - padding: 0; -} - -/* direction N/S ou E/O */ -select.GPmousePositionDirection { - border: 1px solid #999; - margin-left: 2px; -} - -select.GPmousePositionDirection:disabled{ - border: none; - background: transparent; - color: black; - /*For FireFox*/ - -webkit-appearance: none; - /*For Chrome*/ - -moz-appearance: none; -} - -/*For IE10+*/ -select.GPmousePositionDirection:disabled::-ms-expand { - display: none; -} -select.GPmousePositionDirection:disabled::-ms-value { - color: black; -} - -.GPmousePositionUnits, -.GPmousePositionAltitudeUnits { - margin-left: 5px; -} - -/* EDIT COORDINATES TOOLS */ -.GPmousePositionPanelEditTools { - position: absolute; - top: 20px; - right: 5px; -} - -.GPmousePositionEditTool { - width: 18px; - height: 18px; - display: inline-block; - cursor: pointer; -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/img/GPmapCenter.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/img/GPmapCenter.png deleted file mode 100644 index a10837a90df7b82cb7010cfc6bc22a7840f9b2d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1975 zcmV;o2T1sdP)eyvCgwn-7XH#mww0=t9VzOEAU6mOr&5A(OI=0As%0xRRehw56l(hn z*j6a0sd+IC25$Gb7q4$;rXP4I5MFM{!6iTGKHR)L|Nrgo?99!BIOh-xrWzcHfLRGg zBo`4O6*#1D&XR$%t%x(kvG6%UcoYzfaHPP>8O%l2CTL@eT?FJnY$u%u%|NK4D9~!T^9h^vYE2m-*CvnFU6jbn;Fr4-91i61qXx zE-+5p<=XK54K?Cxwx$ub`7JYXyN@Dm*12-)^*r={?nYuNG4u+gAP5_n(^{jIu4f6!To z0N$lxbXu}f zm?eGP6t9G)3W4^b3a0d1gGkx4oEf}ae=C>IVQEK5EdS^GaWeq`V3u_8<*xUzoDmX1 zJ`aGc3!Qs=;;ukg3*Ia?u^v zE3p`}q}xg^x)By!YNP$fi>ntH@iiw%oS1%REv(=02Rj;YQoi3(__iA%(x}us$-Xz>E<>$pP%l=mw*!*LWgs(}?ri-58NlfEgo*m=2m!U%V4vWyTRwU+4wF{1N~F znshrQ!sxK$r~m#1m=h!M7H0@;!sLJNTfad%PsfBsijjT$y|0}K0047h1c|A40kaYe zfOnIGoS}GYS}PT=|v;gVzw3I)WM=V88PJf=uBbGi-OL;^KkXXhdQij4gOU8)lPv9;2F*VZFdNSWB zVn~$!zm!XqFgQgFv$tBTz+3Va#PlaHN0=|WyZRb{0btq#!ejbFue@px1MIFi<@E&^ zOsH(GY(iz=3ov-*(CJ&TjHN&H%7E~gfDj&~%BM~Ne)xH;1~-{Snps%c_E%3!xl^3} zPrw&okXcyS7VDXdDxW$L!lMEp7~z3oDVBo+0PL+f`|9eoY-&l{aXJLU+C#U)#24G!uqIX@4Yy@niidEE0(7GUAFz1Ba0 z0RT9Se4yX|FgxDDjG_--%K=@x05G$$qJ&e^|PKh=8*iDH(_(uW7 zk6xcGn=@jm4vioL&01$&aeU-OkJedNi~!EgKcZW(Uep11QZ~!`GZ33BZnX4pl<(p3cqte%le#6priF z&+8+dg$Th}9q^mZs>!H-tTiRogqy4>Ix?T)h?f#6qen=8@s4@d(Ys*X`qw$ diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/img/GPmousePositionEditCoordinates.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/MousePosition/img/GPmousePositionEditCoordinates.png deleted file mode 100644 index ae806457ae98bcdf904321861f49086b35528e76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 540 zcmV+%0^|LOP)pgw|26NI9+puPes3m4jpxG=hGtFB1YxIsEK3W?SifEI&3h?h4(_kca6 zQ*ND^ZiqO^Bn`}TKK}ndXW%%-$f$QcnB1(4nE+bOmlxA2y5?2u0|WWbl6jRZ+$^y6 z=QQ_7(40rERGOnKOXLjqeqC#vQeT#mD}{_={a}#s$t&o4^#JYCU_`^|WY3yCL3eBd zR6^992UsH-ZkGrJFuY=Q`v+SuN$GYY1lcz?c@?#S@46%?!EmZ@5T2s$)&O7>#;pyn zfjyBnVP(=1GDsOp$>up$ieR5_#mIpJr9x!}z>TL!6(KWN8CFKpvi0hNdYPi-V-%`s z3tGJz3&vMMvA*CCu!#i(_TiwjLOTo)3x*V4l4Y#*lTghGC_%5=WM!rdG@colUR6Ca zT7qYTfT1%K5(Cos-=qZJ(2`1PSDx+8(UNQ4iZH!@$kt#b_DZcMSOKo`b?-4Tpd~6J)vd9gP2NC6dn^K@|x ziD-R0?IK^30gtQX{Z;%f|J@7&>n4X=?wevUJ&#Gu{e<5k=H$%k%kMU=(t5+wa;Nmj ziem8qjhe(>V-}f4YXMuP24=kjH;uOMR1o|;Wy4%GuOl(3=M(f!2`zX!S^B}A_kP!E zZp|@O|LAsdIrFOp#>)LyGR}FfNm`((s`X}GuY{-7rPIl39*?pYP3z|5?%DJGUbTJV zf1QJzfvX}jay~A5ptkPsvH5O#CJnB!vt|Vx)hIi2_K<0GVD - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/DSFRreverseGeocodingStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/DSFRreverseGeocodingStyle.css deleted file mode 100644 index 09b4ad6c3..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/DSFRreverseGeocodingStyle.css +++ /dev/null @@ -1,28 +0,0 @@ -.gpf-btn-icon-reverse { - background-image: url("img/reversegeocode.svg"); - background-repeat: no-repeat; - background-size: auto auto; - background-position: center center; -} - -.gpf-btn-icon-close {} - -.gpf-btn-icon-return { - /* INFO : utiliser l'icone DSFR "fr-icon-arrow-go-back-fill fr-btn--sm fr-btn--icon" */ - background-image: url("img/GPreverseGeocodingReturn.png"); - background-repeat: no-repeat; - background-position: 0 center; -} - -.gpf-flex-reverse { - /* INFO : surcharge de .gpf-flex par defaut */ - display: flex; - align-items: flex-start; - flex-direction: column; - justify-content: space-evenly; -} - -.gpf-panel-reverse { - /* INFO : surcharge de .gpf-panel par defaut */ - width: 100%; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/GPFreverseGeocoding.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/GPFreverseGeocoding.css deleted file mode 100644 index 292669483..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/GPFreverseGeocoding.css +++ /dev/null @@ -1,55 +0,0 @@ -/* REVERSE GEOCODING */ - -div[id^="GPreverseGeocoding-"] { - top: 180px; - left: 10px; -} - -/* Showing/hiding reverse geocoding panel */ - -button[id^="GPshowReverseGeocodingPicto-"][aria-pressed="false"] + dialog { - display: none; - visibility: hidden; - opacity: 0%; -} - -button[id^="GPshowReverseGeocodingPicto-"][aria-pressed="true"] + dialog { - display: block; - visibility: visible; - opacity: 100%; -} - -/* General panels */ - -[id^="GPreverseGeocodingPanel-"] { - position: absolute; - left: 34px; - top: 0px; - height: inherit; -} - -/* Search panel */ - -[id^="GPreverseGeocodingForm-"] { - position: relative; - max-height: 270px; - overflow-y: auto; - padding-left: 15px; - padding-right: 15px; - padding-top: 10px; -} - - -input[id^="GPreverseGeocodingSubmit-"] { - margin-top: 5px; - margin-bottom: 15px; - /* width: 100px; */ -} - -/* Result panel */ - -div[id^=GPreverseGeocodingResultsList-] { - position: relative; - max-height: 210px; - overflow-y: auto; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/GPFreverseGeocodingStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/GPFreverseGeocodingStyle.css deleted file mode 100644 index 81aeae201..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/GPFreverseGeocodingStyle.css +++ /dev/null @@ -1,27 +0,0 @@ -/* REVERSE GEOCODING */ -[id^="GPreverseGeocodingPanel-"] { - width: 280px; -} - -.GPshowReverseGeocodingPicto { - background-image: url("img/GPreverseGeocodingOpen.png"); - background-repeat: no-repeat; - background-position: 1px center; -} - -.GPreverseGeocodingPanelClose { - background-image: url("img/GPreverseGeocodingOpen.png"); -} - -.GPreverseGeocodingReturnPicto { - background-image: url("img/GPreverseGeocodingReturn.png"); - background-repeat: no-repeat; - background-position: 0 center; -} - -/* Results panel */ - -.GPlocationHighlight { - background-color: rgba(255,200,0,0.25); - color: #222; -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/img/GPreverseGeocodingOpen.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/img/GPreverseGeocodingOpen.png deleted file mode 100644 index 09402c2c3c4f735a2356793c8725bfc6d4a85737..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 631 zcmV--0*L*IP)qL?O@e<2%UcqQ4|137}7*}x(pCkWu1u@^Erky7$=DHp^8>L0zcoaRs?u2YQ;?K}Z z@^@fghGVAtgOuz!n{oC=rbjDcDQ3$GS_)@Ia_;U2+5SIpJdC{Ml0CbRQi?VPGtP7| zm*-*;`4_w@xSI^Zqdn@+CylR^YT8>=*1hs#f_N40Q_GXP%RxF;PgBx`R3|D?F$wri7^6Wl@H3SZABjd1p@IQiy@^0{6Pl`MbJe z5<%H_2IgxC3er(L&k(NR2+rUhwq$DN@e%D!5c78~CFBP%fiY~0*kX_`VyN!$CB@9; z#OjMGXgq}5LH@%j?80H}>7$tL+Rk0+{T9`AY9V4z z*9kvAeR5ZG#;FaQ>X(+Hq0Z@iVce-%KNU{>wn3AeR^&|8pR_@P1`YmqdWx RbLRj6002ovPDHLkV1f^hB1!-N diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/img/GPreverseGeocodingReturn.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/img/GPreverseGeocodingReturn.png deleted file mode 100644 index 7b4eaff9fde9c255dfcfe37e0afd1e153a8fc298..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 421 zcmV;W0b2fvP)M6=aDU{ISVSOh^36iohx#UNM=D;sP!5w>YH z2nM5q$s+6?%PvgVl^LEpX-^tvzIorf^W8V^!H^+?LcLJG)aA0wy6mNlRmov?4jg4} z#lQ^JQ{d!3zt+efX2-x;k4GEoB+v#vfLGupB0f_xJG2;W^+DZIt3}NYOyg0VDU#tr zVoYm5J$I#Qs5R5s?lpe&F|7cXK(CkXfv3*(C@>Ao11rE-M%Rpp)goC|)$1NJ-|wTJ zQm-<)mO59ofvW0F9>Yu=cNy(Yp@kn2EnpM4%`?G>5ZDENk{VDQRU4i4ww^=ZZMu5O z&!D2t=F~2B44=!~&YJ35;oTyE8ZcgFg%j#~X%$AqH_#~iSh6%coDG~`Hq4+1HzsWR P00000NkvXXu0mjf7)Pts diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/img/reversegeocode.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/img/reversegeocode.svg deleted file mode 100644 index 9a51bedb7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ReverseGeocoding/img/reversegeocode.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/DSFRrouteStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/DSFRrouteStyle.css deleted file mode 100644 index 667d34c71..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/DSFRrouteStyle.css +++ /dev/null @@ -1,9 +0,0 @@ -.gpf-btn-icon-route { - background-image: url("img/route.svg"); - background-repeat: no-repeat; - background-size: auto auto; - background-position: center center; -} - -.gpf-btn-icon-close {} - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/GPFroute.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/GPFroute.css deleted file mode 100644 index 82b542057..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/GPFroute.css +++ /dev/null @@ -1,231 +0,0 @@ -/* ROUTE */ - -div[id^=GProute-] { - top: 100px; - left: 10px; -} - -/* Showing/hiding panel */ - -button[id^="GPshowRoutePicto-"][aria-pressed="false"] + dialog { - display: none; - visibility: hidden; - opacity: 0%; -} - -button[id^="GPshowRoutePicto-"][aria-pressed="true"] + dialog { - display: block; - visibility: visible; - opacity: 100%; -} - -/* General panels */ - -[id^=GProutePanel-] { - position: absolute; - height: inherit; - top: 0px; - left: 34px; -} - -/* Reset picto */ - -button[id^=GProuteReset] { - /* background-color: #366291; */ - background-image: url("img/GProuteOptions.png"); - background-position: -224px center; -} - -button[id^=GProuteReset] { - opacity: 0.8; - transition: opacity 0.2s ease-out; -} - -button[id^=GProuteReset]:hover { - opacity: 1; -} - -/* Route form */ - -form[id^=GProuteForm] { - padding: 15px; -} - - -form[id^=GProuteForm] > .GPlocationStageFlexInput { - margin-top: 5px; -} - -form[id^=GProuteForm] > .GPlocationStageFlexInputHidden { - margin-top: 0; -} - -form[id^=GProuteForm].GProuteFormMini .GPlocationStageFlexInput:first-child { - margin-top: 5px; -} - -label.GProuteOriginPointerImg[id*="GProuteOriginPointerImg"] { - width: 28px; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; - border-right: 1px solid #999; -} - -input[id*="GProuteOriginPointer"] + .GProuteOriginPointerImg { - background-position: -1px -1px; -} - -input[id*="GProuteOriginPointer"]:checked + .GProuteOriginPointerImg { - background-position: -29px -1px; -} - -.GProuteStageRemove, -div[id^=GProuteStageAdd] { - width: 28px; - border: none; - cursor: pointer; -} - -.GProuteFormMini { - max-height: 58px; - overflow: hidden; - -webkit-transform: translateY(-5px); - transform: translateY(-5px); -} - -.GProuteFormMini button[id^=GPshowRouteExclusionsPicto], -.GProuteFormMini .GProuteStageRemove, -.GProuteFormMini div[id^=GProuteStageAdd], -.GProuteFormMini .GPpanelFooter { - display: none; -} - -.GProuteStageRemove { - background-position: -84px 0; -} - -div[id^=GProuteStageAdd] { - background-position: -56px 0; -} - -[class*="GPlocationPoint"] { - position: relative; -} - -/* Mode choice */ - -div[id^=GProuteModeChoice] { - display: -webkit-flex; - display: -ms-flexbox; - display: -webkit-box; - display: flex; - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; - margin: 15px 0; -} - -div[id^=GProuteTransportChoice] > .GProuteTransportChoice { - display: inline-flex; -} - -/* Showing/hiding exclusions */ - -button[id^="GPshowRouteExclusions"] { - position: absolute; - border: unset; - bottom: 0; - right: 0; - transition: all 0.5s ease-out 0s; -} - -button[id^=GPshowRouteExclusions][aria-pressed="false"] + div[id^=GProuteExclusions] { - max-height: 0; - opacity: 0; - margin-bottom: 0; -} - -button[id^=GPshowRouteExclusions][aria-pressed="true"] + div[id^=GProuteExclusions] { - display: block; - max-height: 76px; - opacity: 1; - margin-bottom: 15px; -} - -div[id^=GProuteExclusions] { - transition: max-height 0.5s ease-in-out 0.25s, opacity 0.5s ease-in-out 0.25s, margin 0.3s ease-in-out 0.25s; - overflow: hidden; -} - -/* Result panel */ - -div[id^=GProuteResultsPanel] { - padding: 15px; -} - -div[id^=GProuteResultsValueDist], -div[id^=GProuteResultsValueTime] { - color: #366291; -} - -div[id^=GProuteResultsNew] { - background-color: #366291; - background-image: url("img/GProuteOptions.png"); -} - -input[id^=GProuteResultsShowDetails] + label:hover, -input[id^=GProuteResultsShowDetails] + label + label:hover { - color: #366291; -} - -div[id^=GProuteResultsStages] { - margin-bottom: 15px; -} - -div[id^=GProuteResultsValueDist], -div[id^=GProuteResultsValueTime] { - display: inline-block; - line-height: 18px; -} - -div[id^=GProuteResultsValueDist], -div[id^=GProuteResultsValueTime] { - width: 80px; - font-weight: bold; -} - -div[id^=GProuteResults-] { - display: -webkit-flex; - display: -ms-flexbox; - display: -webkit-box; - display: flex; - -webkit-justify-content: space-between; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - margin-bottom: 10px; -} - -select[id^=GProuteResultsComputationSelect] { - width: 100px; -} - -div[id^=GProuteResultsNew] { - width: 28px; - height: 28px; - border-radius: 3px; - opacity: 0.8; - background-position: -224px 0; - transition: opacity 0.2s ease-out; - cursor: pointer; -} - -div[id^=GProuteResultsNew]:hover { - opacity: 1; -} - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/GPFrouteStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/GPFrouteStyle.css deleted file mode 100644 index a3816a4b3..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/GPFrouteStyle.css +++ /dev/null @@ -1,249 +0,0 @@ -/* ROUTE */ -[id^=GProutePanel-] { - width: 320px; -} - -.GPshowRoutePicto { - background-image: url("img/GProuteOpen.png"); - background-repeat: no-repeat; - background-position: 1px center; -} - -.GProutePanelClose { - background-image: url("img/GProuteOpen.png"); -} - -/* Route form */ - - -.GProuteStageFlexInput { - max-height: 28px; - opacity: 1; -} - -.GProuteStageFlexInputHidden { - max-height: 0; - opacity: 0; - overflow: hidden; -} - -.GProuteOriginPointerImg, -.GProuteStageRemove, -div[id^=GProuteStageAdd], -.GProuteTransportImg { - background-image: url("img/GProuteOptions.png"); - font-size: 0; -} - -.GProuteExclusionsOption { - background-image: url("img/GProuteCheck.png"); -} - -.GProuteModeLabel { - display: block; - text-align: center; - margin-bottom: 5px; -} - -.GProuteTransportImg { - display: inline-block; - width: 28px; - height: 28px; - cursor: pointer; - content-visibility: hidden; -} - -.GProuteTransportImg:first-of-type { - margin-left: 18px; - margin-right: 10px; -} - -input[id^=GProuteTransportCar] + .GProuteTransportImg { - background-position: -112px 0; -} - -input[id^=GProuteTransportCar]:checked + .GProuteTransportImg { - background-position: -140px 0; -} - -input[id^=GProuteTransportPedestrian] + .GProuteTransportImg { - background-position: -168px 0; -} - -input[id^=GProuteTransportPedestrian]:checked + .GProuteTransportImg { - background-position: -196px 0; -} - -div[id^=GProuteTransportChoice] input { - display: none; -} - -select[id^=GProuteComputationSelect] { - width: 100px; -} -/* Result panel */ - -.GProuteResultsDetailsInstructionHighlight { - background-color: rgba(255,200,0,0.25); - color: #222; -} - -.GProuteResultStage { - display: -webkit-flex; - display: -ms-flexbox; - display: -webkit-box; - display: flex; -} - - -.GProuteResultStageLabel, -.GProuteResultStageValue, -.GProuteResultsValueLabel { - display: inline-block; - line-height: 18px; -} - -.GProuteResultStageLabel, -.GProuteResultsValueLabel { - color: #666; -} - -.GProuteResultStageLabel { - width: 60px; -} - -.GProuteResultsValueLabel { - width: 65px; -} - -.GProuteResultStageValue { - -webkit-flex: 1; - -webkit-box-flex: 1; - -ms-flex: 1; - flex: 1; - overflow-x: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -/* Exclusions */ - - -.GPshowRouteExclusionsPicto { - right: 0; - transition: all 0.3s ease-out 0s; -} - -.GProuteExclusionsLabel { - display: block; - text-align: center; - margin-bottom: 10px; - font-weight: bold; - line-height: 16px; -} - -.GProuteExclusionsOptions { - display: -webkit-flex; - display: -ms-flexbox; - display: -webkit-box; - display: flex; - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; -} - -.GProuteExclusionsOption { - display: block; - height: 28px; - line-height: 26px; - color: #A77; - background-color: #FEE; - padding-left: 28px; - padding-right: 5px; - border: 1px solid #A77; - border-radius: 3px; - cursor: pointer; -} - -input:checked + .GProuteExclusionsOption { - background-color: #EFE; - background-position: 0 -28px; - color: #797; - border: 1px solid #797; -} - -/* Results popup */ - -.gp-features-content-div { - /* min-width: 240px; */ -} - -/* Results details header */ - -.GPfakeBorder { - display: inline-block; - height: 14px; - width: 60px; - border-bottom: 1px solid #999; -} - -.GPfakeBorderLeft { - margin-left:15px; -} - -input[id^=GProuteResultsShowDetails] + label, -input[id^=GProuteResultsShowDetails] + label + label { - width: 130px; - line-height: 28px; - vertical-align: top; - text-align: center; - font-weight: bold; - cursor: pointer; - transition: color 0.2s ease-out; -} - -input[id^=GProuteResultsShowDetails] + label, -input[id^=GProuteResultsShowDetails]:checked + label + label { - display: inline-block; -} - -input[id^=GProuteResultsShowDetails]:checked + label, -input[id^=GProuteResultsShowDetails] + label + label { - display: none; -} - -input[id^=GProuteResultsShowDetails] + label + label + div + div[id^=GProuteResultsDetails] { - max-height: 0; - opacity: 0; -} - -input[id^=GProuteResultsShowDetails]:checked + label + label + div + div[id^=GProuteResultsDetails] { - max-height: 200px; - opacity: 1; -} - -div[id^=GProuteResultsDetails] { - overflow-y: auto; - transition: max-height 0.5s ease-in-out 0.25s, opacity 0.5s ease-in-out 0.25s; -} - -.GProuteResultsDetailsNumber, -.GProuteResultsDetailsInstruction { - display: inline-block; - margin-top: 4px; - line-height: 16px; - color: #666; -} - -.GProuteResultsDetailsNumber { - font-weight: bold; - width: 22px; - text-align: right; - vertical-align: top; -} - -.GProuteResultsDetailsInstruction { - width: calc(100% - 30px); - padding-left: 5px; -} - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/img/GProuteCheck.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/Route/img/GProuteCheck.png deleted file mode 100644 index 6f14444ec74e706414d170c2ad11f6761051ccab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1316 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 - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/DSFRsearchEngineStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/DSFRsearchEngineStyle.css deleted file mode 100644 index 1c7f30046..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/DSFRsearchEngineStyle.css +++ /dev/null @@ -1,87 +0,0 @@ -.gpf-widget-padding { - padding-left: 15px; - padding-top: 5px; - padding-bottom: 5px; -} -.gpf-widget-color { - background-color: #ffffff; -} - -.gpf-panel__items { - height: unset; -} - -select[name^="inputSex"].gpf-select { - padding: unset; -} -input[name^="inputSex"].gpf-input { - padding: unset; -} - -button[id^=GPsearchInputReset] { - width: 40px; - height: 40px; -} - - -.gpf-btn-icon-search { - background-image: url("img/dsfr/search-line.svg"); - background-repeat: no-repeat; - background-position: center center; - /* cas particulier ou on n'utilise pas la class gpf-icon-button pour la largeur à cause du DOM du control*/ - width: 40px; -} -/* hack pour forcer la couleur d'un element desactivé */ -.gpf-btn-icon-search:disabled { - background-color: #000091; -} -.gpf-btn-icon-search-advanced { - background-image: url("img/GPsearchEngineOpen.png"); - background-position: -126px center; - background-repeat: no-repeat; -} -.gpf-btn-icon-search-geolocate { - background-image: url("img/dsfr/localiser.svg"); - background-position: center center; - background-repeat: no-repeat; -} -.gpf-btn-icon-search-coordinate { - background-image: url("img/dsfr/coordonnees.svg"); - background-position: center center; - background-repeat: no-repeat; -} - -.gpf-btn-icon-search-reset { - background-position: -25px center; -} -.gpf-btn-icon-close {} - -/* Autocomplete list / geocode results */ - -div[id^=GPautoCompleteList], -dialog[id^=GPgeocodeResultsList] { - width: 300px; - position: absolute; - height: fit-content; - background-color: #FFF -} - -div[id^=GPautoCompleteList] { - top: 55px; - -} - -dialog[id^=GPgeocodeResultsList] { - position: absolute; - top: 55px; - border-radius: 4px; - overflow: hidden; -} - -div[id^=GPgeocodeResults-] { - width: 100%; - position: relative; - background-color: #FFF; - max-height: 240px; - overflow-y: auto; -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/GPFsearchEngine.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/GPFsearchEngine.css deleted file mode 100644 index 42e2b7209..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/GPFsearchEngine.css +++ /dev/null @@ -1,200 +0,0 @@ -/* SEARCH ENGINE */ - -[id^="GPsearchEngine-"] { - top: 8px; - left: 46px; -} - -[id^="GPsearchEngine-"] { - /* dsfr */ - display: flex; - flex-direction: row; - align-items: center; -} -/* Showing/hiding search engine input */ - -button[id^=GPshowSearchEnginePicto] { - display: inline-block; - transition: border-radius 0s ease-out 0s; - transition-delay: 0.5s; -} - -button[id^=GPshowSearchEnginePicto][aria-pressed="true"] { - transition: border-radius 0.5s ease-out 0s; -} - -button[id^="GPshowSearchEnginePicto-"][aria-pressed="true"] { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - transition-delay: 0s; -} - -button[id^="GPshowSearchEnginePicto-"][aria-pressed="false"] + form[id^=GPsearchInput-] { - max-width: 0px; - border: none; - transition: max-width 0.5s ease-out 0s; -} - -button[id^="GPshowSearchEnginePicto-"][aria-pressed="true"] + form[id^=GPsearchInput-] { - max-width: 280px; -} -button[id^="GPshowSearchEnginePicto-"][aria-pressed="false"] + form[id^=GPsearchInput-] ~ div button[id^=GPshowAdvancedSearch], -button[id^="GPshowSearchEnginePicto-"][aria-pressed="false"] + form[id^=GPsearchInput-] ~ div button[id^=GPshowGeolocate], -button[id^="GPshowSearchEnginePicto-"][aria-pressed="false"] + form[id^=GPsearchInput-] ~ div button[id^=GPshowSearchByCoordinate] { - display: none; -} - -button[id^="GPshowSearchEnginePicto-"][aria-pressed="true"] + form[id^=GPsearchInput-] ~ div button[id^=GPshowAdvancedSearch], -button[id^="GPshowSearchEnginePicto-"][aria-pressed="true"] + form[id^=GPsearchInput-] ~ div button[id^=GPshowGeolocate], -button[id^="GPshowSearchEnginePicto-"][aria-pressed="true"] + form[id^=GPsearchInput-] ~ div button[id^=GPshowSearchByCoordinate] { - display: inline-block; -} - -[id^=GPshowSearchEngine-] + button + form[id^=GPsearchInput-] { - max-width: 0px; -} - -/* div[id^=GPautoCompleteList] { - display: none; -} */ - -/* button[id^="GPshowSearchEnginePicto-"][aria-pressed="true"] + form[id^=GPsearchInput-] + div[id^=GPautoCompleteList] { - display: block; -} */ - -/* Simple search input */ - -form[id^=GPsearchInput-] { - display: inline-block; - position: relative; - /* left: -3px; */ - width: 280px; - overflow: hidden; -} - -button[id^=GPsearchInputReset] { - position: absolute; - top: 0px; - right: 0px; - border: unset; - cursor: pointer; -} - -/* General panels */ - - -/* Advanced search picto */ - -button[id^=GPshowAdvancedSearch] { - transition: border-radius 0s ease-out 0s; - transition-delay: 0.5s; -} - -/* Advanced search panel */ - -/* button[id^=GPshowAdvancedSearch][aria-pressed="true"] + div[id^=GPadvancedSearchPanel] { - display: inline-block; - visibility: visible; - opacity: 100%; -} - -button[id^=GPshowAdvancedSearch][aria-pressed="false"] + div[id^=GPadvancedSearchPanel] { - display: none; - visibility: hidden; - opacity: 0%; -} */ - -dialog[id^=GPcoordinateSearchPanel], -dialog[id^=GPadvancedSearchPanel] { - position: absolute; - top: 35px; - margin-left: 33px;; - width: 310px; - height: inherit; - vertical-align: top; - overflow: hidden; - bottom: unset; /* fix dsfr */ -} - -form[id^=GPcoordinateSearchForm], -form[id^=GPadvancedSearchForm] { - max-height: 250px; - overflow-y: auto; - padding-left: 15px; - padding-right: 15px; -} - -input[id^=GPcoordinateSearchSubmit], -input[id^=GPadvancedSearchSubmit] { - margin-top: 10px; - margin-bottom: 15px; -} - - - -/* Simple search input */ - -[id^="GPsearchInput"] {} - - -[id^="GPshowSearchDiv"]{ - display: flex; -} - -/* General panels */ - - - -/* Advanced search picto */ - -.GPbuttonsContainer { - padding-left: 5px; - padding-right: 5px; -} - - - -/* Autocomplete list / geocode results */ - -.GPlabelTitle { - font-weight: bold; -} - -[id^="GPautocompleteResults"] { - display: flex; - flex-direction: column; - width: 100%; - box-shadow: 0 0 6px #000; -} - -[id^="GPautoCompleteList"], -dialog[id^="GPgeocodeResultsList"] { - margin-left: 33px; -} - -[id^="GPautoCompleteList"] { - /* overflow-y: auto; */ -} - -dialog[id^="GPgeocodeResultsList"] { - top: 35px; - border-radius: 4px; - height: inherit; - bottom: unset; /* fix dsfr */ -} - -[id^="GPautocompleteResultsSuggest"], -[id^="GPautocompleteResultsLocation"] { - width: inherit; -} - -/* Mode Mobile */ - -@media (max-width: 576px) { - - button[id^="GPshowSearchEnginePicto-"][aria-pressed="true"] + form[id^=GPsearchInput-] { - /* 56px: widget de gauche, 40px: bouton loupe, 58px: bouton géoloc, 16px: padding + border des boutons droite, 10px: padding du bouton géoloc*/ - max-width: calc(100vw - 56px - 40px - 58px - 16px - 10px); - } - -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/GPFsearchEngineStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/GPFsearchEngineStyle.css deleted file mode 100644 index f2a51164b..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/GPFsearchEngineStyle.css +++ /dev/null @@ -1,146 +0,0 @@ -/* SEARCH ENGINE */ - -.GPshowSearchEnginePicto { - background-image: url("img/GPsearchEngineOpen.png"); - background-repeat: no-repeat; - background-position: 0 center; -} - -.GPshowAdvancedSearch { - background-image: url("img/GPsearchEngineOpen.png"); - background-position: -26px center; - background-repeat: no-repeat; - transition: border-radius 0.5s ease-out 0s; -} - -.GPshowGeolocate { - background-image: url("img/GPsearchEngineOpen.png"); - background-position: -102px center; - background-repeat: no-repeat; - transition: border-radius 0.5s ease-out 0s; -} - -.GPshowSearchByCoordinate { - background-image: url("img/GPsearchEngineOpen.png"); - background-position: -76px center; - background-repeat: no-repeat; - transition: border-radius 0.5s ease-out 0s; -} - -.GPsearchInputReset { - background-image: url("img/GPsearchEngineClose.png"); - background-position: 0 center; -} - -button[id^=GPsearchInputReset] { - border-top-right-radius: 5px; - border-bottom-right-radius: 5px; - width: 32px; - height: 32px; -} - -button[id^=GPcoordinateSearchClose], -button[id^=GPgeocodeResultsClose], -button[id^=GPadvancedSearchClose] { - top: 0; - right: 0; - width: 30px; - height: 32px; -} - -button[id^=GPcoordinateSearchClose], -button[id^=GPgeocodeResultsClose] { - background-position: 0 0; -} - -button[id^=GPadvancedSearchClose] { - background-repeat: no-repeat; -} - -button[id^=GPcoordinateSearchClose], -button[id^="GPgeocodeResultsClose"] { - background-image: url("img/GPsearchEngineClose.png"); -} - -button[id^="GPadvancedSearchClose"] { - background-image: url("img/GPsearchEngineOpen.png"); - background-position: -50px 3px; -} - -form[id^=GPsearchInput-] input { - display: block; - width: 100%; - /* height: 100%; */ - border: 1px solid #999; - border-top-right-radius: 5px; - border-bottom-right-radius: 5px; - padding: 0; - padding-right: 30px; - padding-left: 5px; - color: #333; - font-size: 1.0em; -} - -form[id^=GPsearchInput-] input:disabled { - background-color: #DDD; - color: #999; -} - -.GPsearchInputText { - height: 32px; -} - -/* Autocomplete list / geocode results */ - -div[id^=GPautoCompleteList], -dialog[id^=GPgeocodeResultsList] { - width: 280px; - position: absolute; - max-height: 140px; - background-color: #FFF -} - -div[id^=GPautoCompleteList] { - top: 35px; -} - -dialog[id^=GPgeocodeResultsList] { - position: absolute; - top: 35px; - border-radius: 4px; - overflow: hidden; -} - -div[id^=GPgeocodeResults-] { - width: 100%; - position: relative; - background-color: #FFF; - max-height: 140px; - overflow-y: auto; -} - -.GPcoordinateSearchLabel, -.GPadvancedSearchCodeLabel, -.GPadvancedSearchFilterLabel { - max-width: 105px; -} - -.GPcoordinateSearchSystemsSelect, -.GPcoordinateSearchSystemsLabel, -.GPadvancedSearchCodeLabel, -.GPadvancedSearchCode, - div[id^=GPadvancedSearchFilters] { - margin-top: 15px; -} - -.GPcoordinateSearchSystemsLabel, -.GPcoordinateSearchSystemsSelect, -.GPcoordinateSearchUnitsLabel, -.GPcoordinateSearchUnitsSelect, -.GPcoordinateSearchLabel, -.GPcoordinateSearchInput, -.GPadvancedSearchFilterLabel, -.GPadvancedSearchFilterInput { - margin-bottom: 5px; -} - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/GPsearchEngineClose.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/GPsearchEngineClose.png deleted file mode 100644 index cb2aaeadb9da306d2aecb8f529b0397d53b40505..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7787 zcmeHrc{r49*#3yfzC`v+B1^`MLChd)mKZx@iJFzM%#1PiwUkgqAtWkG$QB|(wvw!6 z3#F1>mO_>+-%#&%{JwwQ9p`o+IVT8wH?(G2rffi=uQHY7f> z_kC2%Uj4$KRo}XJo-wfdT=1Eljanw5#fxV{LlQ>mI|eJ!!cNaWHkA#23;vq@JT&5Y z|IU}PuuaG4QSM0@n4^*8cjwnZbT7i(rEhU2tywej=RU}EIs0bq0>e1cYjaDmaC*~n z4h-Hrb}}=w9{cDyQmh{TXmU+*!Z?0p>f7xp-J9U^iQOB^Yl?$AJBeZH=SRIbzZtJ= zuZ{LDmb>^WxF7GEugkvyI-U8HsBp#X1HG}k#Rgww&y=#iPeGs+i`2qX|9K_L6HY4q z)VC%oL*DNREHVLdKTpyXo^;_n)xOlRp>{hVf%;K9Nvc7tq(n1gP>1nF z)>ke;2H(0!yPNe2+5tRHPt8^9At@`hOh7#oklYDAsMdgGLZ4+{y0YYfA)_Ab3_uzT zjo15*N~lhL`wG#0TDi(KP`>jfOjMOKHGx@%J>3VYWMo^Uv+X+H*OMr2qnDOP6@)qx zo*20!?%W#dd!U@>YSmw?>jJLxohfo(3|WDFmyXZ9eu}!H@G`vvCKy0j8@~iYI^+5! zQBQInl{}uz4fg#|HZt&G?cMUY6~~s>@SEOl)!v&HXKfLMsSZ`BWlOiJ%Z?@QeOG^| zEo^lRs}*V1?Eu|p?mpSVz6SSo7kb&QVxq>W;u(rO$+`&aIgNw7)F0_DGTb^dVBPj2 zg4TxkgfW;}o1#ABqZ~Pvka78Oq`roC*h!N19A`lLuIJ>XhYOsFYu=-wNl(5&D>ARw znNMrS9$fiWx0?Es`uOLJK87ZULT&Dd_J_~91Cl$KhG_XqjsNW!{kQ0Jzbur%sqG(J{I`J4W-};f0D#^V=}~(Gl@+})Eb~U}XYCeNw?vB$5)pHkqpj;8h2PR*LW+f8p)+@)z?|u{= ziM!WLkc~lll-N`{9m#1ExV_}O;OWr7{pw~eFa66?2jXqto({mp#tZO_sVieaoqu^^P&3AWE+4g&wZtm0EQ%B5} zY`W98OI~D+ArJp0pILluUj#tf+!-S=|}=?Mf7U^VZz>IM70xN2=?_tC+&uV(wPywZYn(QuRcrm`UMY4mn&Y;Jl`fyoKvS=3k z!bYd3WOu!hZ!9ocppT>CBsb?#3TH40f z5EA1ueh`1O?m?mkB%(q-ZX{HX>un1q*fi!ES3fgL&vCUmR7T*Eo_F3Uy@j@wrm(YY z=gW4z86ViX5!wg z?Fa1f%7)p~v#5iIYvo&G80NBs2JHpxRdyZ=%zB>7KH8ylWKdhPy2ke^zZ}m;NgG#< z=+8+=AB$A3D`gkU3yPX7^9q7pRwPJ{>)fuIcJmy$>PW@L;UkL?6{?xq%=t6KYaVO< zelI;bqEALIt;ht;TxNq=vnY31OPLpcwYx`6`8FK*X7he%7q)Bc>wzjoJj~bk3?JdV z!&jbT0ZIz7@%b1C@_hQv+=ERy`AHK3ImlU~+zU76STN{&?+TGayyHTqve0~RB%c3c z;{rpLGB_s^GIl*``O;v1GWDLoI7SK4v~VeU>f6!qUKW!pQXbQsKX$~0IUJEl=v|w&dUB9C&b6UY%6r0EWa?f~k7UGMxwp`m>}!ebxQ(n5 zcJ0;Hrl-p-PX+6Qs3`>NQZvXcQZjU;*RXj#jUiIeu|iL4~>0kHy&Qo_OvfXy#{A+iLmg&Gu3hh46N_J0m~<< zXSa)?j=)XZAQGVyT&PBGzRi!SIG`}g(tU2No?^%H5wFSobGDq>;h)$=@5CHG*1_g? z4=r*RXDucd_xMeOo=bQ{2O)2+#)3R8m>i<6L;w6Hft@)gt*uTs^;TrW>pMm4GvwZP z3RxP~^>+e6hHzPOkY(-VAYQn0P6@e4pNTq*x|MUnfedhK1#uVBFo$v@so zS*Fm*Hff=A>(q@MbRIROq!ditbqY!a2rvkLdf~kp;t?)ktwJw%c?Sm)LP9q2x%c!PSHEI@s6KVoYOPo z1}Bp5rI>vohn<}Le5Zi_YUi@nmc?qU>-ym%=LJ&qd%OgVYeOV<{X=9s)HrHO48#i) z3ntn&A@vL_yO$rJq6JHBc==ciA8#~QpV+x@!|kv?AR>%!0?WFhr*9@4q968E+}U!S z5nF*~Un-}@{G3#DyQ})?5?Ph0q1ih5=_|po@z|1T#p`2*7B@?>=?-mr!Wq&GuOEC# z+9X_xy7BM~`F30^>~YqP`B{fUvUhMJ+7c`=Gb~MgaE-!gsdeFL&6j2)N%MIrIlbBb z#c zkIPNa1Gz*jmE+NE<|(B!WStM6+zPF2n$!%OO?KAs30>{$5h99A ze~M5mx>1!!7WSWs*L*C|uEb}OVORYg;S#bI|pn+L$~k|{u= z7(?IpdF}AGLy3zS^c|#by7+abgHkoz$L>7S>FQH|)VWeIMR)-8j};KQ5`4lZR?Hk} zsmjPIOU1Pg$xELruOBoUT<4S_o z*8};d>_?||L?W&{Xai&#s<%^{#Yce|qZQPypDh-)39KzsEngU&;@1=AV%kaR?HsJ? zif&lNaHPfhcE}~k|;Q!lDv{U1a!uq;0qN$%>q=XVDWHEJ^kMlv?~p9S1OeZ2ZR0m z{N()<RLX&)` z8sg%#dEg)Md6E%`Kk13yzg3{=0rp3c!3y#au%{>Z?-t(FGrlyE-vRxv7T(shHxgh= zoHxmbg2A2f#Sy8;|4xC${Ao}2p?K`4gT;Vx9ym`L)SKp2;U6vyj1cC3TI@;SLhvN- zThYY+2a-y_|0UKxV%wY9Pv`G}(9Hkj{RjGw-1osW6aoR)BVl~@!ZXs-5a06;$C5Av zEPVe|6{`YMfI=}K1tmo^NC^Ugf>cooFwiMg1tX$BhNCIq67|6dc<1W%k56}6|Pf{KEovLXzkq5@M? zRe~w}1+v9aylIuV$Eg63SNz4hw=8g4GBjaPdv!`9*tekN0@tPBP*f7dnnd!@5Z?<4 zxM#Uv-az$Vi(*LdrXd3MD*kuPTj9KZUH!TRJP7+!K;VAa!cmxCPP|dRIPAV7n%%D{ zj4O)hf}`EvzYFS*al-$ySa>KNr3iswKsYQ;k)|*P1%g3UX@X z^+Qo`+Ag$AY1z;UXg?dE^uClb|3v$_;`VfcK$SocC6EHlT0sR4QGzR~oP~EKpSMD8X?XwO*0(kWRT1mQ46QFyH}0$w5{!$ z=WjciHfizdcY{t|5Uj73Qnu87uT#}vwjH6dF?q^g<$fk7Z+aipgkY?cy4=@eG~64M zy2zm?o?s}!6TKxV@xdtYR-*qvO7@j(BR{hYX1sViPxr_W$_a2poVE4vkXSqUF|^9{OZe62k< zjyyB)=W}=5F+tr>+HN})&ynaU5v)_=tN1L6N(H|x0b>SA2sXJ#G`5W>cu)^lju+{tIA8Oy+t%SW2#rIbK%ne0M2g%a{vGU diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/GPsearchEngineOpen.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/GPsearchEngineOpen.png deleted file mode 100644 index 5bde0849d8ded88880841eaa160e5f24a1d3b463..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9851 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 N85@}ESL$B6@;}~JhIjw~ diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/dsfr/coordonnees.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/dsfr/coordonnees.svg deleted file mode 100644 index 50affc1bc..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/dsfr/coordonnees.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/dsfr/localiser.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/dsfr/localiser.svg deleted file mode 100644 index 91510d721..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/dsfr/localiser.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/dsfr/search-line.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/dsfr/search-line.svg deleted file mode 100644 index 7d8a3fe66..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/SearchEngine/img/dsfr/search-line.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/DSFRtoolBoxMeasureStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/DSFRtoolBoxMeasureStyle.css deleted file mode 100644 index 7632f2ce0..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/DSFRtoolBoxMeasureStyle.css +++ /dev/null @@ -1,5 +0,0 @@ -.gpf-btn-icon-toolbox { - background-repeat: no-repeat; - background-image: url("img/GPtoolBoxMeasureOpen.png"); - background-position: 3px center; -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/GPFtoolBoxMeasure.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/GPFtoolBoxMeasure.css deleted file mode 100644 index 65ffe1a08..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/GPFtoolBoxMeasure.css +++ /dev/null @@ -1,47 +0,0 @@ -/* TODO coller un peu plus à la charte -- liseret blanc transparent 32x32 autour du pictogramme -- pictogramme 26x26 -- ... -*/ -div[id^=GPtoolbox-measure-main] { - float: left; - left: 78px; - top: 8px; - position: absolute; - display: inline-block; - z-index: 1; -} - -div[id^=GPtoolbox-measure-widget] { - left: auto; - display: none; - /*visibility: hidden;*/ - /*position: absolute;*/ - /*right: 0;*/ - border-radius: 2px; - /*background-color: #f9f9f9;*/ - /*box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);*/ -} - -div[id^=GPtoolbox-measure-widget]>div { - display: block; - /*visibility: visible;*/ - position: relative; - top: auto; - left: auto; - bottom: auto; - right: auto; -} - -div[id^=GPtoolbox-measure-main]:hover { - /*display: block;*/ - /*visibility: visible;*/ -} - -div[id^=GPtoolbox-measure-main]:hover:not(.active) { - /*background-color: rgba(0,60,136,0.3);*/ -} - -div[id^=GPtoolbox-measure-main]:hover button[id^=GPtoolbox-measure-button] { - background-color: rgba(0, 60, 136, 0.7); -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/GPFtoolBoxMeasureStyle.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/GPFtoolBoxMeasureStyle.css deleted file mode 100644 index afd71e103..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/GPFtoolBoxMeasureStyle.css +++ /dev/null @@ -1,4 +0,0 @@ -.GPshowToolBoxPicto { - background-repeat: no-repeat; - background-image: url("img/GPtoolBoxMeasureOpen.png"); -} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/img/GPtoolBoxMeasureOpen.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/Controls/ToolBoxMeasure/img/GPtoolBoxMeasureOpen.png deleted file mode 100644 index c493063d223ef14ca6dee8dcecc793d40f096bd8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 896 zcmV-`1AqL9P)2C?u-6(?|dS0}V+; zK~zY`y_Q{wl~ojmpKqK!O4yN{uFMK#&Qo8N;BfexM=Gns^_ZLs2{7x8v!j>zslj2>iVKg6V*@D zm-BsVlrzhfOe?Q<@s6l*MRKK<)*0P3!k25KnK(Z z)8w^rXjLCqe@UQa>hEfYx?TN2y)vbKU%jFcP)YCU(a2MaG(c{y{U5m1}@x%y55-H|{Ksf*+Ibbh-!Q(<#5m>r-?qpN=PWFsKdYs0EF>X9(6 zBU!Dr}7G zi1|Q0CjqvoKSev#0!6&47w1BM18N-&R8}Bz+-tI&B`im#+mffI(mWw+klHQ5r%*cV0os+%~|zq5Eur|2QF{c zn{n#4&~|3g=zqJ~)lbv2x*5F$A?*_5gG1WwY9`v5^zDDc}F2)&2$jZ}u0A Ww{@fCstLmY0000 *:not(.GPlocationOriginHidden) */ -.GPflexInput > * { - display: block; - height: 28px; - line-height: 26px; - border: 1px solid #999; - border-radius: 0; -} - -.GPflexInput *:not(:last-child) { - border-right:none; -} - -.GPflexInput *:first-child { - border-radius: 3px 0 0 3px; -} - -.GPflexInput *:last-child { - border-radius: 0 3px 3px 0; -} - -.GPflexInput > *:not(input) { - /* width: 28px; */ - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -.GPflexInput > input { - -webkit-flex: 1; - -webkit-box-flex: 1; - -ms-flex: 1; - flex: 1; - padding: 0 5px; - min-width: 0; -} - -.GPflexInput > select { - -webkit-flex: 1; - -webkit-box-flex: 1; - -ms-flex: 1; - flex: 1; - padding-right: 7px; -} - -.GPflexInput > label { - background-color: #F2F2F2; - color: #666; - padding-left: 7px; - padding-right: 9px; - cursor: pointer; -} - -/****************/ -/* Submit input */ -/****************/ - -input.GPsubmit { - display: block; - width: 80px; - margin: auto; - height: 28px; - line-height: 26px; - padding: 0; - background: none; - border: none; - border-radius: 3px; - font-family: "Helvetica Neue",Arial,Helvetica,sans-serif; - color: #FFF; - background-color: #366291; - font-weight: bold; - opacity: 0.8; - transition: opacity 0.2s ease-out; - cursor: pointer; -} - -input.GPsubmit:hover { - opacity: 1; -} - -/************/ -/* elements */ -/************/ - -.GPselect { - display: block; - height: 28px; - line-height: 26px; - margin: auto; - border: 1px solid #999; - color: #333; - cursor: pointer; -} - -.GPlabel { - -} - -.GPinput { - -} - -.GPform { - padding: 15px; -} - -.GPelementInvisible, -.GPelementHidden { - display: none; -} - -.GPelementVisible, -.GPelementShow { - display: block; -} - -/********************************/ -/* Autocomplete/geocode results */ -/********************************/ - -.GPautoCompleteList, -.GPadvancedAutoCompleteList { - z-index: 2; - /* display: none; */ - /* position: absolute; - max-height: 140px; - background-color: #FFF; - border: 1px solid #999; - overflow-y: hidden; */ -} - -.GPadvancedAutoCompleteList { - width: calc(100% - 28px); - border-top: none; - font-size: 0.9em; -} - -.GPautoCompleteProposal { - width: 100%; - height: 28px; - line-height: 16px; - padding: 6px 10px; - color: #5E5E5E; - font-size: 1.0em; - overflow: hidden; - white-space: nowrap; - text-overflow:ellipsis; - cursor: pointer; -} - -.GPautoCompleteProposal:hover { - color: #000000; - background-color: #CEDBEF -} - -/*************************************/ -/* Showing additional hidden options */ -/*************************************/ - -.GPshowMoreOptionsImage { - background-image: url("img/GPshowMoreOptions.png"); -} - -.GPshowMoreOptions { - display: block; - position: absolute; - width: 28px; - height: 28px; - cursor: pointer; - transition: all 0.5s ease-out 0s; -} - -button[aria-pressed="true"].GPshowMoreOptions, -input[type="checkbox"]:checked + .GPshowMoreOptions { - -webkit-transform: rotateX(180deg); - transform: rotateX(180deg); - /* bottom: 90px; */ -} - -/**********************/ -/* Feature info popup */ -/**********************/ - -.gp-feature-info-div { - bottom: 17px ; - position: relative; - max-width: calc(100vw - 80px); - padding: 10px; - border-radius: 10px; - font-size: 0.75em; - font-family: "Open Sans", sans-serif; - color: #002A50; - background-color: #FFF; - box-shadow: 0 0 5px #000; -} - -.gp-feature-info-div::before { - content: ""; - position: absolute; - border-top: 15px solid #FFF; - border-right: 14px solid transparent; - border-left: 14px solid transparent; - bottom: -15px; - margin-left: -14px; - left: 50%; -} - -.gp-feature-info-div .closer { - position: absolute; - display: block; - width: 30px; - height: 30px; - top: 0; - right: 0; - border: none; - cursor: pointer; - border-top-right-radius: 10px; - border-bottom-right-radius: 10px; - background-color: #FFF; - background-repeat: no-repeat; - background-image: url("img/close-emeraud.svg"); - background-size: 14px 14px; - background-position: center; -} - -.gp-features-content-div { - max-width: 420px; - min-width: 260px; - max-height: 340px; - overflow: auto; -} - -.gp-features-content-div h5, -.gp-features-content-div h6, -.gp-features-content-div p, -.gp-features-content-div ul { - margin: 0; -} - -.gp-features-content-div ul { - padding: 0; - list-style-type: none; -} - -.geoportail-popup-content h5, -.geoportail-popup-content h6, -.geoportail-popup-content p, -.gp-att-name-div, -.gp-att-description-div, -.gp-att-others-div { - padding: 0 10px; -} - -.geoportail-popup-content h5:not(:last-child), -.geoportail-popup-content h6:not(:last-child), -.geoportail-popup-content p:not(:last-child), -.gp-att-description-div:not(:last-child), -.gp-att-others-div:not(:last-child) { - margin-bottom: 15px; -} - -.geoportail-popup-content h5:last-child, -.geoportail-popup-content h6:last-child, -.geoportail-popup-content p:last-child, -.gp-att-description-div:last-child, -.gp-att-others-div:last-child, -.gp-att-name-div { - margin-bottom: 10px; -} - -.geoportail-popup-content h5:first-child, -.geoportail-popup-content h6:first-child, -.geoportail-popup-content p:first-child, -.gp-att-name-div:first-child, -.gp-att-description-div:first-child, -.gp-att-others-div:first-child { - margin-top: 10px; -} - -.gp-att-name-div, -.gp-features-content-div h5 { - padding-right: 35px; - font-weight: bold; - font-size: 1.2em; - text-transform: uppercase; - color: #0B6BA7; -} - -.gp-features-content-div h6 { - font-size: 1.1em; -} - -.gp-att-description-div:not(:last-child), -.gp-att-others-div:not(:last-child) { - padding-bottom: 10px; - border-bottom: 1px dotted #666; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/GPFwaiting.css b/build/release/geoportal-extensions-openlayers/src/packages/CSS/GPFwaiting.css deleted file mode 100644 index ec093cb27..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/GPFwaiting.css +++ /dev/null @@ -1,37 +0,0 @@ -/** -* Map loading -* @sample -* function setMap(map) { -* var center = this._createLoadingElement(); -* map.getViewport().appendChild(center); -* center.className = ""; // invisible ! -* center.className = "GPmapLoadingVisible"; // visible ! -* } -* -* function _createLoadingElement() { -* var div = document.createElement("div"); -* div.id = "GPmapLoading"; -* div.className = ""; -* return div; -* } -*/ - -#GPmapLoading { - display: none; - position: absolute; - z-index: 50; - top: 50%; - left: 50%; - width: 50px; - height: 50px; - margin-top: -25px; - margin-left: -25px; -} - -#GPmapLoading.GPmapLoadingVisible { - display: block; -} - -#GPmapLoading { - background-image: url("img/waiting.gif"); -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPclose.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPclose.png deleted file mode 100644 index cb2aaeadb9da306d2aecb8f529b0397d53b40505..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7787 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 diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPinfo.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPinfo.svg deleted file mode 100644 index fdab95333..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPinfo.svg +++ /dev/null @@ -1,56 +0,0 @@ - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPinfo_secondary.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPinfo_secondary.svg deleted file mode 100644 index 0f2d8d979..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPinfo_secondary.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPshowMoreOptions.png b/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/GPshowMoreOptions.png deleted file mode 100644 index fc109295c7de2c035f712f8b1c271173cba224b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 293 zcmV+=0owkFP)nwSU=tR9>oh5*wG?kb5EdH^ z1ZR(h3aK<;wmVOGW|(h=4+e}erfIUsrtIkYNmM7*YJKoH?9Jxawua?O>)oBJNXMV% zn}40<7P^))QjvZ#jmGUknf{F1gECE~(O5(jEvh&bbhv^%w4~eb-Vhy`5YgCPP7-E7i^2`@`7Gi>R r_^&{K&SAMe-{It}_iW#pG3HmF`!00+k;43100000NkvXXu0mjfAd!Vo diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/close-blue.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/close-blue.svg deleted file mode 100644 index 652653d96..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/close-blue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/close-emeraud.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/close-emeraud.svg deleted file mode 100644 index 3bf3a0696..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/close-emeraud.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/lightOrange.svg b/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/lightOrange.svg deleted file mode 100644 index 913f9d24f..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/lightOrange.svg +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/waiting.gif b/build/release/geoportal-extensions-openlayers/src/packages/CSS/img/waiting.gif deleted file mode 100644 index c7ceaea45827eebcb1d951c26bdb465127063550..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1333 zcmZ?wbhEHbG+{7dXc1yyOj)W{xq)%&J>QAD)K=VcUVQ!I6gJ;&&!+EZZ`pIV>eTy* z$M3DW^z6);GuN(NJ9zK?y?ghbJ$v?_XrTC?+s`#5*x50_)kx2PnUR5kLGdRGDU}Ah^D}p)#7UDiig?@m*=Dh67tfqMOEbI8XTbuE>Kcz_vsY9vT{B00anuZljhocx z^{vsKwr#`0DTj|7J$78a+w@e@R+DMD#*Kx$E7u!VpV7ULd`qk9vf-AfhGKzBS5@}! zdTH?ZO^RC1b5j9---oJ#d|xK6JfZxL@y`KW?hVOr8P>ft->~p-yMSj4lGnu;SQw-j z)PY_vc<|lPm$?(@_4t=&IdiP?U!Ev>`)Fg_C!MIb+q5K#O{Wz`c5rrTJri0nMQ)|W zYmwPki*{ei*V5^mcK*eds$SZQXcQp)UMCBJ^fYse#(^HeDhvi z@8Iz6yB|2UMmO@<@)EDLQEOXs7+0SS+I?3uLR&6>=`&-gGhgHGf7tP-xkCBfcda`A zyPxOR)i*SjYO%GmX}4&1bad6V_4a91=uDdIKfOJ8R_B~aVZEV94&h`F1BQhZFf_mp z$(*a`J!(grtMaGznte$)Y%mvhxoT;F{ZsJTijY8 z@l;p)Xh!hO7?~8hyulK6!?(OUL6{r_b zLU98unHGamNTk$?#C18dHf?yZtI&G!*Q&?bk6v3(&hKEj)N*A0%Lp&NVvlq|t4V$< zL)Eu=-ubrY!G;PSJ<)TmhElR|>ksB_Gp}pAd^>OJo-^-%|5p=CnE*8Rf=|&FYB9q@chiw z-tKLiw*K7*bVoyDlRR%LU$b^=7jK7(KzCcO(uA%_EmL|X^-pM@Hf5SJ-^2xq4AuY< CkYarR diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/AttributionDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/AttributionDOM.d.ts deleted file mode 100644 index c52c8b503..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/AttributionDOM.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export default AttributionDOM; -declare namespace AttributionDOM { - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createMainAttributionsShowElement(): DOMElement; - function _createAttributionsList(): DOMElement; - function _createMainAttributionsListContainer(): DOMElement; - function _createMainPictoElement(collapsed: boolean): DOMElement; -} -//# sourceMappingURL=AttributionDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/AttributionDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/AttributionDOM.d.ts.map deleted file mode 100644 index ffa95494a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/AttributionDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"AttributionDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Attribution/AttributionDOM.js"],"names":[],"mappings":";;IAYc,qCAGT;IAO6B,mDAM7B;IAOoC,0DAKpC;IAOyB,+CAIzB;IAOsC,4DAKtC;IAOyB,iEAqBzB"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/AttributionDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/AttributionDOM.js deleted file mode 100644 index 80f55f305..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/AttributionDOM.js +++ /dev/null @@ -1,96 +0,0 @@ -// FIXME not use !? -var AttributionDOM = { - - // ################################################################### // - // ######################### Main container ########################## // - // ################################################################### // - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Creation du container principal (DOM) - * - * @returns {DOMElement} div DOM - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPAttribution"); - container.className = "GPwidget"; - - return container; - }, - - /** - * Creation du selecteur (caché) pour l'affichage/masquage des attributions (DOM) - * - * @returns {DOMElement} checkbox DOM - */ - _createMainAttributionsShowElement : function () { - var input = document.createElement("input"); - input.id = this._addUID("GPshowAttributionsList"); - input.type = "checkbox"; - return input; - }, - - /** - * Création de l'élément liste des attributions (DOM) - * - * @returns {DOMElement} liste DOM - */ - _createAttributionsList : function () { - var ul = document.createElement("ul"); - ul.id = this._addUID("GPAttributionsList"); - return ul; - }, - - /** - * Création du conteneur principal des attributions (DOM) - * - * @returns {DOMElement} div DOM - */ - _createMainAttributionsListContainer : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPAttributionsListContainer"); - - return div; - }, - - /** - * Création du container du picto du controle (DOM) - * @param {Boolean} collapsed - collapsed - * @returns {DOMElement} label DOM - */ - _createMainPictoElement : function (collapsed) { - var self = this; - - var label = document.createElement("label"); - label.id = this._addUID("GPshowAttributionsListPicto"); - label.className = "GPshowAdvancedToolPicto"; - label.htmlFor = this._addUID("GPshowAttributionsList"); - label.title = "Afficher/masquer les attributions"; - - var spanOpen = document.createElement("span"); - spanOpen.id = this._addUID("GPshowAttributionsListOpenClose"); - spanOpen.className = "GPshowAdvancedToolOpen"; - spanOpen.innerHTML = collapsed ? "i" : "»"; - /** Evenement de type 'click' sur le picto du controle */ - spanOpen.addEventListener("click", function () { - spanOpen.innerHTML = (document.getElementById(self._addUID("GPshowAttributionsList")).checked) ? "i" : "»"; - }); - - label.appendChild(spanOpen); - - return label; - } - -}; - -export default AttributionDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/GeoportalAttribution.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/GeoportalAttribution.d.ts deleted file mode 100644 index bb44a003e..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/GeoportalAttribution.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -export default GeoportalAttribution; -/** - * @classdesc - * OpenLayers Control to manage Originators for layer resources - * - * @constructor - * @extends {ol.control.Attribution} - * @alias ol.control.GeoportalAttribution - * @type {ol.control.GeoportalAttribution} - * @param {Object} options - ol.control.Attribution options (see {@link http://openlayers.org/en/latest/apidoc/ol.control.Attribution.html ol.Control.Attribution}) - * @fires attributions:update - * @example - * var attribution = new ol.control.GeoportalAttribution({ - * collapsed : false - * }); - * map.addControl(attribution); - * // listeners for attributions update : - * attribution.on("attributions:update", function (e) {}); - */ -declare var GeoportalAttribution: ol.control.GeoportalAttribution; -//# sourceMappingURL=GeoportalAttribution.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/GeoportalAttribution.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/GeoportalAttribution.d.ts.map deleted file mode 100644 index 019043bf1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/GeoportalAttribution.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"GeoportalAttribution.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Attribution/GeoportalAttribution.js"],"names":[],"mappings":";AAYA;;;;;;;;;;;;;;;;;GAiBG;AACH,kEA6ME"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/GeoportalAttribution.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/GeoportalAttribution.js deleted file mode 100644 index 70d4003d1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Attribution/GeoportalAttribution.js +++ /dev/null @@ -1,243 +0,0 @@ -// import CSS -import "../../CSS/Controls/Attribution/GPFattribution.css"; -// import "../../CSS/Controls/Attribution/GPFattributionStyle.css"; -// import OpenLayers -import Attribution from "ol/control/Attribution"; -import { transformExtent as olTransformExtentProj } from "ol/proj"; -// import local -import LayerUtils from "../../Utils/LayerUtils"; -import Logger from "../../Utils/LoggerByDefault"; - -var logger = Logger.getLogger("geoportalattribution"); - -/** - * @classdesc - * OpenLayers Control to manage Originators for layer resources - * - * @constructor - * @extends {ol.control.Attribution} - * @alias ol.control.GeoportalAttribution - * @type {ol.control.GeoportalAttribution} - * @param {Object} options - ol.control.Attribution options (see {@link http://openlayers.org/en/latest/apidoc/ol.control.Attribution.html ol.Control.Attribution}) - * @fires attributions:update - * @example - * var attribution = new ol.control.GeoportalAttribution({ - * collapsed : false - * }); - * map.addControl(attribution); - * // listeners for attributions update : - * attribution.on("attributions:update", function (e) {}); - */ -var GeoportalAttribution = class GeoportalAttribution extends Attribution { - - /** - * See {@link ol.control.GeoportalAttribution} - * @module GeoportalAttribution - * @alias module:~Controls/GeoportalAttribution - * @param {*} options - options - * @example - * import GeoportalAttribution from "src/OpenLayers/Controls/GeoportalAttribution" - */ - constructor (options) { - options = options || {}; - - // Attributions are not collapsible for ol/source/OSM except if ... - options.collapsible = true; - options.collapsed = true; - - super(options); - - if (!(this instanceof GeoportalAttribution)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - - return this; - } - - /** - * Overload setMap function, that enables to catch map events, such as movend events. - * - * @param {ol.Map} map - Map. - */ - setMap (map) { - if (map != null) { - // Remove default ol.control.Attribution - var ctrls = map.getControls(); - ctrls.forEach( - (ctrl) => { - if (ctrl instanceof GeoportalAttribution) { - return; - } - if (ctrl) { - var classList = ctrl.element.classList; - for (var i = 0; i < classList.length; i++) { - if (classList[i] === "ol-attribution") { - ctrls.remove(ctrl); - break; - } - } - } - } - ); - - // on récupère les attributions des couches déjà ajoutées à la carte. - this._updateAttributions(map); - - // At every map movement, layers attributions have to be updated, - // according to map and originators zoom and extent. - map.on( - "moveend", - () => { - this._updateAttributions(map); - } - ); - map.getLayers().on( - "add", - () => { - this._updateAttributions(map); - } - ); - map.getLayers().on( - "remove", - () => { - this._updateAttributions(map); - } - ); - } - - super.setMap(map); - } - - /** - * Update map layers attributions - * - * @param {ol.Map} map - Map. - * @private - */ - _updateAttributions (map) { - // get map parameters - var mapAttributions = {}; - - var view = map.getView(); - // extent, then convert to geographical coordinates - var extent = view.calculateExtent(map.getSize()); - var mapProjection = view.getProjection().getCode(); - var geoExtent = olTransformExtentProj(extent, mapProjection, "EPSG:4326"); - // transform extent from [minx, miny, maxx, maxy] to [maxy, minx, miny, maxx] - var standardExtent = [geoExtent[3], geoExtent[0], geoExtent[1], geoExtent[2]]; - // zoom - var zoom = view.getZoom(); - // layers - var layers = map.getLayers().getArray(); - - // info : This option suppresses warnings about functions inside of loops. - /* jshint loopfunc: true */ - - // loop on layers to get their originators, if there is at least one originator, and if layer is visible. - for (var i = 0; i < layers.length; i++) { - // distinguish case of ol.layer.Group (which is made up of layers with their own source) - // and other ol.layer (with their own source) - if (layers[i].getSource) { - // single ol.layer - this._updateLayerAttributions(layers[i], mapAttributions, standardExtent, mapProjection, zoom); - } else if (layers[i].getLayers) { - // ol.layer.Group - var lyrs = layers[i].getLayers(); - lyrs.forEach( - (lyr) => { - if (lyr.getSource) { - this._updateLayerAttributions(lyr, mapAttributions, standardExtent, mapProjection, zoom); - } else { - logger.log("cannot find layer source in layergroup ", layers[i]); - } - } - ); - } - } - } - - /** - * Update a layer attributions - * - * @param {ol.layer} layer - layer - * @param {Object} mapAttributions - object recensing attributions already added, to prevent displaying twice the same producer - * @param {Array} mapExtent - map current extent - * @param {String} mapCrs - map current crs - * @param {Number} mapZoom - map current zoom - * @private - */ - _updateLayerAttributions (layer, mapAttributions, mapExtent, mapCrs, mapZoom) { - if (!layer) { - logger.trace("layer is null !?"); - return; - } - - var src = layer.getSource(); - if (!src) { - logger.trace("source is not yet loaded !"); - return; - } - - if (!mapAttributions) { - mapAttributions = {}; - } - - var attributions = []; - - var visibility = layer.getVisible(); - var originators = src._originators; - - // info : clean previous attributions ONLY for Geoportal Layers (when src._originators is defined) - if (typeof originators !== "undefined") { - src.setAttributions(); // clean - } - - if (originators && visibility) { - // get layer's attributions array - var layerAttributions = LayerUtils.getAttributions({ - extent : mapExtent, - crs : mapCrs, - zoom : mapZoom, - visibility : visibility, - originators : originators - }); - - for (var j = 0; j < layerAttributions.length; j++) { - var attributionj = layerAttributions[j]; - // check that this attribution hasn't been added yet for another layer - if (!mapAttributions.hasOwnProperty(attributionj)) { - // add attribution html - attributions.push(attributionj); - - // add attribution to mapAttributions, to manage all layers attributions - mapAttributions[attributionj] = true; - } - }; - - // update source attribution - if (attributions.length !== 0) { - src.setAttributions(attributions); - /** - * event triggered when the attributions are updated - * - * @event attributions:update - * @type Object - * @property {Array} attributions - list of attributions - */ - this.dispatchEvent({ - type : "attributions:update", - attributions : attributions - }); - } - } - } - -}; - -export default GeoportalAttribution; - -// Expose GeoportalAttribution as ol.control.GeoportalAttribution (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.GeoportalAttribution = GeoportalAttribution; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Control.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Control.d.ts deleted file mode 100644 index 7660c7b55..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Control.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default ControlExtended; -declare var ControlExtended: { - new (options: any): { - setPosition(pos: any): void; - }; -}; -//# sourceMappingURL=Control.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Control.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Control.d.ts.map deleted file mode 100644 index 8963c21a4..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Control.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Control.d.ts","sourceRoot":"","sources":["../../../../src/packages/Controls/Control.js"],"names":[],"mappings":";AAEA;;;;EAWE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Control.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Control.js deleted file mode 100644 index f461dcfcb..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Control.js +++ /dev/null @@ -1,161 +0,0 @@ -import Control from "ol/control/Control"; - -var ControlExtended = class ControlExtended extends Control { - - constructor (options) { - super(options); - } - - setPosition (pos) { - var instance = new PositionFactory(this); - instance.set(pos); - } - -}; - -export default ControlExtended; - -/** - * gestion des anchors - */ -const ANCHORS = [ - "top-left", - "top-right", - "bottom-left", - "bottom-right" -]; - -/** - * Position - * @todo revoir les css des widgets car les panneaux sont en position:absolute - */ -class PositionFactory { - - /** - * constructor - * @param {*} caller - ... - */ - constructor (caller) { - this.caller = caller; - - this.#createContainer("top-left"); - this.#createContainer("top-right"); - this.#createContainer("bottom-left"); - this.#createContainer("bottom-right"); - - return this; - } - - /** - * ... - * @param {*} name - ... - * @returns {Boolean} ... - */ - #existContainer (name) { - var div = document.getElementById("position-container-" + name); - if (div) { - return true; - } - return false; - } - - /** - * ... - * @param {*} name - ... - * @private - */ - #createContainer (name) { - if (this.#existContainer(name)) { - return; - } - // INFO - // positionner les classes position-container-[left|right|top|bottom] - // ex. { position:relative; height:50px; width:100%; } - var div = document.createElement("div"); - div.id = "position-container-" + name; - div.className = "position-container-" + name ; - - var container = this.caller.getMap().getOverlayContainerStopEvent(); - container.appendChild(div); - } - - /** - * ... - * @param {*} pos - ... - * @todo - */ - #setAnchor (pos) { - const sizeW = (pos) => { - var element = document.getElementById("position-container-" + pos); - var width = element.offsetWidth; - return width; - }; - const sizeH = (pos) => { - var element = document.getElementById("position-container-" + pos); - var height = element.offsetHeight; - return height; - }; - const clear = (element) => { - element.style.top = "unset"; - element.style.bottom = "unset"; - element.style.left = "unset"; - element.style.right = "unset"; - }; - - // on supprime le style de positionnement (top, left...) - // car on souhaite une nouvelle position - clear(this.caller.element); - this.caller.element.style.position = "unset"; // div.GPwidget - - // on recherche les panneaux (panel) : - // * panel de formulaire - // * panel de resultats - var panels = Array.from(this.caller.element.getElementsByClassName("GPpanel")); - if (panels.length === 0) { - return; - } - panels.forEach((e) => { - clear(e); - }); - 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; - } - } - - /** - * ... - * @param {*} pos - ... - * @public - */ - set (pos) { - if (!ANCHORS.includes(pos.toLowerCase())) { - return; - } - // positionnement de l'element - this.#setAnchor(pos); - - document.getElementById("position-container-" + pos).appendChild(this.caller.element); - } - -}; \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/Drawing.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/Drawing.d.ts deleted file mode 100644 index 193caaf53..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/Drawing.d.ts +++ /dev/null @@ -1,110 +0,0 @@ -export default Drawing; -/** - * @classdesc - * - * Drawing Control. - * - * @constructor - * @alias ol.control.Drawing - * @type {ol.control.Drawing} - * @extends {ol.control.Control} - * @param {Object} options - options for function call. - * @param {Boolean} [options.collapsed = true] - Specify if Drawing control should be collapsed at startup. Default is true. - * @param {Boolean} [options.draggable = false] - Specify if widget is draggable - * @param {Object} [options.layer = {}] - Openlayers layer that will hosts created features. If none, an empty vector layer will be created. - * @param {Object} [options.popup = {}] - Popup informations - * @param {Boolean} [options.popup.display = true] - Specify if popup is displayed when create a drawing - * @param {Function} [options.popup.function] - Function to display popup informations if you want to cutomise it. You may also provide your own function with params : {geomType / feature / saveFunc(message) / closeFunc()}. This function must return the DOM object of the popup content. - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Croquis"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Mon croquis"] - Layer description to be displayed in LayerSwitcher - * @param {Object} options.tools - Tools to display in the drawing toolbox. All by default. - * @param {Boolean} [options.tools.points = true] - Display points drawing tool - * @param {Boolean} [options.tools.lines = true] - Display lines drawing tool - * @param {Boolean} [options.tools.polygons = true] - Display polygons drawing tool - * @param {Boolean} [options.tools.holes = false] - Display polygons with holes drawing tool - * @param {Boolean} [options.tools.text = true] - Display text drawing tool - * @param {Boolean} [options.tools.remove = true] - Display feature removing tool - * @param {Boolean} [options.tools.display = true] - Display style editing tool - * @param {Boolean} [options.tools.tooltip = true] - Display text editing tool - * @param {Boolean} [options.tools.edit = true] - Display editing tool - * @param {Boolean} [options.tools.export = true] - Display exporting tool - * @param {Boolean} [options.tools.measure = false] - Display measure drawing into popup info - * @param {String} [options.labels] - Labels for Control - * @param {String} [options.labels.control] - Label for Control - * @param {String} [options.labels.points] - Label for points drawing tool - * @param {String} [options.labels.lines] - Label for lines drawing tool - * @param {String} [options.labels.polygons] - Label for polygons drawing tool - * @param {String} [options.labels.holes] - Label for polygons with holes drawing tool - * @param {String} [options.labels.text] - Label for text drawing tool - * @param {String} [options.labels.edit] - Label for editing tool - * @param {String} [options.labels.display] - Label for style editing tool - * @param {String} [options.labels.tooltip] - Label for text editing tool - * @param {String} [options.labels.remove] - Label for feature removing tool - * @param {String} [options.labels.export] - Label for exporting tool. - * @param {String} [options.labels.exportTitle] - Title for exporting tool. - * @param {String} [options.labels.applyToObject] - Label for apply to object button. - * @param {String} [options.labels.saveDescription] - Label for save description button. - * @param {String} [options.labels.setAsDefault] - Label for set as default style button. - * @param {String} [options.labels.strokeColor] - Label for stroke color. - * @param {String} [options.labels.strokeWidth] - Label for stroke width. - * @param {String} [options.labels.fillColor] - Label for fill color. - * @param {String} [options.labels.fillOpacity] - Label for fillOpacity. - * @param {String} [options.labels.markerSize] - Label for markerSize. - * @param {Array.} [options.markersList = [{"src" : "data:image/png;base64,xxxx", "anchor" : [0.5,1]}]] - List of markers src to be used for points with their anchor offsets See {@link http://openlayers.org/en/latest/apidoc/ol.style.Icon.html OpenLayers params} for anchor offset options. - * @param {Object} options.defaultStyles - Default styles applying to geometries (labels, lines and polygons). - * @param {String} [options.defaultStyles.textFillColor = "#000000"] - Text fill color for labels (RGB hex value). - * @param {String} [options.defaultStyles.textStrokeColor = "#FFFFFF"] - Text surrounding color for labels (RGB hex value). - * @param {String} [options.defaultStyles.strokeColor = "#ffcc33"] - Stroke color (RGB hex value). - * @param {Number} [options.defaultStyles.strokeWidth = 2] - Stroke width in pixels. - * @param {String} [options.defaultStyles.polyStrokeColor = "#ffcc33"] - Stroke color (RGB hex value) for polygons. - * @param {Number} [options.defaultStyles.polyStrokeWidth = 2] - Stroke width in pixels for polygons. - * @param {String} [options.defaultStyles.polyFillColor = "#ffffff"] - Polygons fill color (RGB hex value). - * @param {Number} [options.defaultStyles.polyFillOpacity = 0.2] - Polygon fill opacity (alpha value between 0:transparent and 1:opaque). - * @param {Object} options.cursorStyle - cursor (circle) style when drawing or editing. - * @param {String} [options.cursorStyle.fillColor = "rgba(0, 153, 255, 1)"] - Cursor fill color. - * @param {String} [options.cursorStyle.strokeColor = "#FFF"] - Cursor stroke color. - * @param {String} [options.cursorStyle.strokeWidth = 1] - Cursor surrounding stroke width. - * @param {String} [options.cursorStyle.radius = 6] - Cursor radius. - * @example - * var drawing = new ol.control.Drawing({ - * collapsed : false, - * draggable : true, - * layerswitcher : { - * title : "Dessins", - * description : "Mes dessins..." - * }, - * markersList : [{ - * src : "http://api.ign.fr/api/images/api/markers/marker_01.png", - * anchor : [0.5, 1] - * }], - * defaultStyles : {}, - * cursorStyle : {}, - * tools : { - * points : true, - * lines : true, - * polygons :true, - * holes : true, - * text : false, - * remove : true, - * display : true, - * tooltip : true, - * export : true, - * measure : true - * }, - * popup : { - * display : true, - * function : function (params) { - * var container = document.createElement("div"); - * // - params.geomType; - * // - params.feature; - * // Les 2 fonctions ferment la popup avec ou sans sauvegarde des informations - * // dans les properties de la feature (key : description) - * // - params.saveFunc(message); - * // - params.closeFunc(); - * return container; - * } - * }); - */ -declare var Drawing: ol.control.Drawing; -//# sourceMappingURL=Drawing.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/Drawing.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/Drawing.d.ts.map deleted file mode 100644 index ae6327cf1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/Drawing.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Drawing.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Drawing/Drawing.js"],"names":[],"mappings":";AA2DA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0GG;AACH,wCA6xDE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/Drawing.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/Drawing.js deleted file mode 100644 index 18c8d02be..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/Drawing.js +++ /dev/null @@ -1,1998 +0,0 @@ -// import CSS -import "../../CSS/Controls/Drawing/GPFdrawing.css"; -// import "../../CSS/Controls/Drawing/GPFdrawingStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -import { unByKey as olObservableUnByKey } from "ol/Observable"; -import Collection from "ol/Collection"; -import Overlay from "ol/Overlay"; -import { transform as olTransformProj } from "ol/proj"; -import VectorSource from "ol/source/Vector"; -import VectorLayer from "ol/layer/Vector"; -import { - Fill, - Icon, - Stroke, - Style, - Text, - Circle -} from "ol/style"; -import { - LineString, - LinearRing, - Point, - Polygon, - MultiLineString, - MultiPoint, - MultiPolygon -} from "ol/geom"; -import { - Select as SelectInteraction, - Modify as ModifyInteraction, - Draw as DrawInteraction -} from "ol/interaction"; -import { - singleClick as eventSingleClick, - pointerMove as eventPointerMove -} from "ol/events/condition"; -import { - getArea as olGetAreaSphere, - getDistance as olGetDistanceSphere -} from "ol/sphere"; -// import local -import Logger from "../../Utils/LoggerByDefault"; -import Interactions from "../Utils/Interactions"; -import MarkersOther from "../Utils/MarkersOther"; -import Draggable from "../../Utils/Draggable"; -import SelectorID from "../../Utils/SelectorID"; -import Color from "../../Utils/ColorUtils"; -// DOM -import DrawingDOM from "./DrawingDOM"; -// import local with ol dependencies -import KMLExtended from "../../Formats/KML"; -import GeoJSONExtended from "../../Formats/GeoJSON"; -import GPXExtended from "../../Formats/GPX"; -import LayerSwitcher from "../LayerSwitcher/LayerSwitcher"; - -var logger = Logger.getLogger("Drawing"); - -/** - * @classdesc - * - * Drawing Control. - * - * @constructor - * @alias ol.control.Drawing - * @type {ol.control.Drawing} - * @extends {ol.control.Control} - * @param {Object} options - options for function call. - * @param {Boolean} [options.collapsed = true] - Specify if Drawing control should be collapsed at startup. Default is true. - * @param {Boolean} [options.draggable = false] - Specify if widget is draggable - * @param {Object} [options.layer = {}] - Openlayers layer that will hosts created features. If none, an empty vector layer will be created. - * @param {Object} [options.popup = {}] - Popup informations - * @param {Boolean} [options.popup.display = true] - Specify if popup is displayed when create a drawing - * @param {Function} [options.popup.function] - Function to display popup informations if you want to cutomise it. You may also provide your own function with params : {geomType / feature / saveFunc(message) / closeFunc()}. This function must return the DOM object of the popup content. - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Croquis"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Mon croquis"] - Layer description to be displayed in LayerSwitcher - * @param {Object} options.tools - Tools to display in the drawing toolbox. All by default. - * @param {Boolean} [options.tools.points = true] - Display points drawing tool - * @param {Boolean} [options.tools.lines = true] - Display lines drawing tool - * @param {Boolean} [options.tools.polygons = true] - Display polygons drawing tool - * @param {Boolean} [options.tools.holes = false] - Display polygons with holes drawing tool - * @param {Boolean} [options.tools.text = true] - Display text drawing tool - * @param {Boolean} [options.tools.remove = true] - Display feature removing tool - * @param {Boolean} [options.tools.display = true] - Display style editing tool - * @param {Boolean} [options.tools.tooltip = true] - Display text editing tool - * @param {Boolean} [options.tools.edit = true] - Display editing tool - * @param {Boolean} [options.tools.export = true] - Display exporting tool - * @param {Boolean} [options.tools.measure = false] - Display measure drawing into popup info - * @param {String} [options.labels] - Labels for Control - * @param {String} [options.labels.control] - Label for Control - * @param {String} [options.labels.points] - Label for points drawing tool - * @param {String} [options.labels.lines] - Label for lines drawing tool - * @param {String} [options.labels.polygons] - Label for polygons drawing tool - * @param {String} [options.labels.holes] - Label for polygons with holes drawing tool - * @param {String} [options.labels.text] - Label for text drawing tool - * @param {String} [options.labels.edit] - Label for editing tool - * @param {String} [options.labels.display] - Label for style editing tool - * @param {String} [options.labels.tooltip] - Label for text editing tool - * @param {String} [options.labels.remove] - Label for feature removing tool - * @param {String} [options.labels.export] - Label for exporting tool. - * @param {String} [options.labels.exportTitle] - Title for exporting tool. - * @param {String} [options.labels.applyToObject] - Label for apply to object button. - * @param {String} [options.labels.saveDescription] - Label for save description button. - * @param {String} [options.labels.setAsDefault] - Label for set as default style button. - * @param {String} [options.labels.strokeColor] - Label for stroke color. - * @param {String} [options.labels.strokeWidth] - Label for stroke width. - * @param {String} [options.labels.fillColor] - Label for fill color. - * @param {String} [options.labels.fillOpacity] - Label for fillOpacity. - * @param {String} [options.labels.markerSize] - Label for markerSize. - * @param {Array.} [options.markersList = [{"src" : "data:image/png;base64,xxxx", "anchor" : [0.5,1]}]] - List of markers src to be used for points with their anchor offsets See {@link http://openlayers.org/en/latest/apidoc/ol.style.Icon.html OpenLayers params} for anchor offset options. - * @param {Object} options.defaultStyles - Default styles applying to geometries (labels, lines and polygons). - * @param {String} [options.defaultStyles.textFillColor = "#000000"] - Text fill color for labels (RGB hex value). - * @param {String} [options.defaultStyles.textStrokeColor = "#FFFFFF"] - Text surrounding color for labels (RGB hex value). - * @param {String} [options.defaultStyles.strokeColor = "#ffcc33"] - Stroke color (RGB hex value). - * @param {Number} [options.defaultStyles.strokeWidth = 2] - Stroke width in pixels. - * @param {String} [options.defaultStyles.polyStrokeColor = "#ffcc33"] - Stroke color (RGB hex value) for polygons. - * @param {Number} [options.defaultStyles.polyStrokeWidth = 2] - Stroke width in pixels for polygons. - * @param {String} [options.defaultStyles.polyFillColor = "#ffffff"] - Polygons fill color (RGB hex value). - * @param {Number} [options.defaultStyles.polyFillOpacity = 0.2] - Polygon fill opacity (alpha value between 0:transparent and 1:opaque). - * @param {Object} options.cursorStyle - cursor (circle) style when drawing or editing. - * @param {String} [options.cursorStyle.fillColor = "rgba(0, 153, 255, 1)"] - Cursor fill color. - * @param {String} [options.cursorStyle.strokeColor = "#FFF"] - Cursor stroke color. - * @param {String} [options.cursorStyle.strokeWidth = 1] - Cursor surrounding stroke width. - * @param {String} [options.cursorStyle.radius = 6] - Cursor radius. - * @example - * var drawing = new ol.control.Drawing({ - * collapsed : false, - * draggable : true, - * layerswitcher : { - * title : "Dessins", - * description : "Mes dessins..." - * }, - * markersList : [{ - * src : "http://api.ign.fr/api/images/api/markers/marker_01.png", - * anchor : [0.5, 1] - * }], - * defaultStyles : {}, - * cursorStyle : {}, - * tools : { - * points : true, - * lines : true, - * polygons :true, - * holes : true, - * text : false, - * remove : true, - * display : true, - * tooltip : true, - * export : true, - * measure : true - * }, - * popup : { - * display : true, - * function : function (params) { - * var container = document.createElement("div"); - * // - params.geomType; - * // - params.feature; - * // Les 2 fonctions ferment la popup avec ou sans sauvegarde des informations - * // dans les properties de la feature (key : description) - * // - params.saveFunc(message); - * // - params.closeFunc(); - * return container; - * } - * }); - */ -var Drawing = class Drawing extends Control { - - /** - * See {@link ol.control.Drawing} - * @module Drawing - * @alias module:~Controls/Drawing - * @param {*} options - options - * @example - * import Drawing from "src/packages/Controls/Drawing" - */ - constructor (options) { - options = options || {}; - - // call ol.control.Control constructor - super({ - element : options.element, - target : options.target, - render : options.render - }); - - if (!(this instanceof Drawing)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this._initialize(options); - - // init control DOM container - this._container = this._initContainer(); - - // ajout du container - (this.element) ? this.element.appendChild(this._container) : this.element = this._container; - - return this; - } - - /** - * Default tools to display for widget - * - * @private - */ - static DefaultTools = { - points : true, - lines : true, - polygons : true, - holes : false, - text : true, - remove : true, - display : true, - tooltip : true, - edit : true, - export : true, - measure : false - }; - - /** - * Default labels for widget - * - * @private - */ - static DefaultLabels = { - control : "Annoter la carte", - creatingTools : "Outils de création", - points : "Placer des points", - lines : "Dessiner des lignes", - polygons : "Dessiner des polygones", - holes : "Créer des trous sur un polygone", - text : "Ecrire sur la carte", - editingTools : "Outils d'édition", - edit : "Editer les tracés", - display : "Modifier l'apparence des objets", - tooltip : "Modifier les textes / infos-bulles", - remove : "Supprimer des objets", - export : "Exporter", - exportTitle : "Exporter en KML", - applyToObject : "Appliquer à l'objet", - saveDescription : "Enregistrer", - setAsDefault : "Définir par défaut", - strokeColor : "Couleur du trait : ", - strokeWidth : "Epaisseur du trait : ", - fillColor : "Couleur de remplissage : ", - fillOpacity : "Opacité du remplissage : ", - markerSize : "Taille du pictogramme : ", - markerColor : "Couleur du pictogramme : ", - labelDisplay : "Afficher le label : " - }; - - /** - * Default styles applyied to drawn features. - * - * @private - */ - static DefaultStyles = { - textFillColor : "#000000", - textStrokeColor : "#FFFFFF", - textStrokeWidth : 6, - // INFO : cette option n'est pas surchargeable via les options du constructeur ! - textIcon1x1 : { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNiYAAAAAkAAxkR2eQAAAAASUVORK5CYII=", - anchor : [0, 0] - }, - polyFillColor : "#ffffff", - polyFillOpacity : 0.4, - polyStrokeColor : "#ffcc33", - polyStrokeWidth : 4, - strokeColor : "#ffcc33", - strokeWidth : 4, - markerSize : 1, - markerColor : "#ffcc33", - // INFO : cette option n'est pas surchargeable via les options du constructeur ! - labelDisplay : true - }; - - /** - * Default styles when drawing - * - * @private - */ - static DefaultCursorStyle = { - radius : 6, - strokeColor : "#FFF", - strokeWidth : 1, - fillColor : "rgba(0, 153, 255, 1)" - }; - - /** - * Overload of {@link http://openlayers.org/en/latest/apidoc/ol.control.Control.html#setMap ol.control.Control.setMap()} method, called when control is added to or removed from map. - * - * @param {Object} map - {@link http://openlayers.org/en/latest/apidoc/ol.Map.html ol.Map} object. - */ - setMap (map) { - // call original setMap method - super.setMap(map); - - if (this.getMap() && this.eventKey) { - olObservableUnByKey(this.eventKey); - } - - // nothing else to do if map == null - if (map == null) { - return; - } - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - - // mode "draggable" - if (this.draggable) { - Draggable.dragElement( - this._drawingPanel, - this._drawingPanelHeader, - this.options.position ? null : map.getTargetElement() - ); - } - - // mode "collapsed" - if (!this.collapsed) { - this._showDrawingButton.setAttribute("aria-pressed", true); - } - - if (this.layer) { - // ajout du layer de dessin à la carte s'il n'y est pas déjà - this.setLayer(this.layer); - } - - // gestion des suppressions "externes" de la couche de dessin. - this.eventKey = this.getMap().getLayers().on("remove", (evtRm) => { - if (evtRm.element === this.layer) { // FIXME object comparison - // found layer removed. - this.layer = null; - // on supprime l'interaction en cours si besoin - if (this.interactionCurrent) { - this.getMap().removeInteraction(this.interactionCurrent); - this.interactionCurrent = null; - } - } - }); - } - - /** - * Export features of current drawing layer (KML by default). - * - * @returns {String} a representation of drawn features (KML, GPX or GeoJSON) or null if not possible. - */ - exportFeatures () { - var result = null; - if (Control.prototype.getMap.call(this) == null) { - logger.log("Impossible to export : control isn't attached to any map."); - return result; - } - if (!this.layer) { - logger.log("Impossible to export : no layer is hosting features."); - return result; - } - if (!this.layer.getSource() || - !this.layer.getSource().getFeatures() || - !this.layer.getSource().getFeatures().length) { - logger.log("Impossible to export : no features found."); - return result; - } - - // on invalide les features... - if (this.featuresCollectionSelected) { - this.featuresCollectionSelected.clear(); - } - - var ClassName = null; - switch (this.getExportFormat()) { - case "KML": - ClassName = new KMLExtended({ - writeStyles : true - }); - break; - case "GPX": - ClassName = new GPXExtended({ - // readExtensions : function (ext) {/* only extensions nodes from wpt, rte and trk can be processed */ } - }); - break; - case "GEOJSON": - ClassName = new GeoJSONExtended({}); - break; - default: - break; - } - - if (!ClassName) { - logger.log("Impossible to export : format unknown !?"); - return result; - } - - var featProj = this.layer.getSource().getProjection(); - featProj = featProj || this.getMap().getView().getProjection(); - - result = ClassName.writeFeatures(this.layer.getSource().getFeatures(), { - dataProjection : "EPSG:4326", - featureProjection : featProj - }); - - return result; - } - - // ################################################################### // - // #################### user interface methods ####################### // - // ################################################################### // - - /** - * Collapse or display control main container - * - * @param {Boolean} collapsed - True to collapse control, False to display it - */ - setCollapsed (collapsed) { - if (collapsed === undefined) { - logger.error("[ERROR] Drawing:setCollapsed - missing collapsed parameter"); - return; - } - if ((collapsed && this.collapsed) || (!collapsed && !this.collapsed)) { - return; - } - // on simule l'ouverture du panneau après un click - this.onShowDrawingClick(); - this._showDrawingButton.click(); - } - - /** - * Setter for Export Name. - * - * @param {String} name - Export Name. By default, "Croquis". - */ - setExportName (name) { - this._exportName = name; - } - - /** - * getter for Export Name. - * - * @returns {String} export name - */ - getExportName () { - return this._exportName; - } - - /** - * Setter for Export format (KML, GPX or GeoJSON). - * - * @param {String} format - Export format. By default, "KML". - */ - setExportFormat (format) { - this._exportFormat = (format) ? format.toUpperCase() : "KML"; - switch (format.toUpperCase()) { - case "KML": - this._exportExt = ".kml"; - this._exportMimeType = "application/vnd.google-earth.kml+xml"; - break; - case "GPX": - this._exportExt = ".gpx"; - this._exportMimeType = "application/gpx+xml"; - break; - case "GEOJSON": - this._exportExt = ".geojson"; - this._exportMimeType = "application/geo+json"; - break; - default: - // redefine format by default ! - this._exportFormat = "KML"; - break; - } - } - - /** - * getter for Export format. - * - * @returns {String} export format - */ - getExportFormat () { - return this._exportFormat; - } - - /** - * Sets vector layer to hosts feature. - * - * @param {ol.layer.Vector} vlayer - vector layer - */ - setLayer (vlayer) { - if (!vlayer) { - this.layer = null; - return; - } - - if (!(vlayer instanceof VectorLayer)) { - logger.log("no valid layer given for hosting drawn features."); - return; - } - - // ajout du layer de dessin à la carte s'il n'y est pas déjà - var layers = this.getMap().getLayers(); - if (layers) { - var found = false; - layers.forEach((mapLayer) => { - if (mapLayer === vlayer) { - logger.trace("layer already in map. Not adding."); - found = true; - } - }); - // si le layer n'est pas sur la carte, on l'ajoute. - if (!found) { - this.getMap().addLayer(vlayer); - } - // style par defaut ! - // application des styles ainsi que ceux par defaut de ol sur le layer - vlayer.getSource().getFeatures().forEach((feature) => { - var style = feature.getStyle(); - if (typeof style !== "function") { - return; - } - var featureStyleFunction = feature.getStyleFunction(); - if (featureStyleFunction) { - var styles = featureStyleFunction.call(this, feature, 0); - if (styles && styles.length !== 0) { - feature.setStyle((Array.isArray(styles)) ? styles[0] : styles); - } - } - }); - this.layer = vlayer; - - // Si un layer switcher est présent dans la carte, on lui affecte des informations pour cette couche - this.getMap().getControls().forEach( - (control) => { - if (control instanceof LayerSwitcher) { - // un layer switcher est présent dans la carte - var layerId = this.layer.gpLayerId; - // on n'ajoute des informations que s'il n'y en a pas déjà (si le titre est le numéro par défaut) - if (control._layers[layerId].title === layerId) { - control.addLayer( - this.layer, { - title : this.options.layerDescription.title, - description : this.options.layerDescription.description - } - ); - } - } - } - ); - } - } - - /** - * Get vector layer - * - * @returns {Object} layer - isocurve layer - */ - getLayer () { - return this.layer; - } - - /** - * Get container - * - * @returns {DOMElement} container - */ - getContainer () { - return this._container; - } - - // ################################################################### // - // ######################## initialize control ####################### // - // ################################################################### // - - /** - * Gets marker options in options.markersList given its src. - * - * @param {String} src - marker image URI, - * @returns {Object} markers options - * @private - */ - _getsMarkersOptionsFromSrc (src) { - var markerOptions = null; - for (var i = 0; i < this.options.markersList.length; i++) { - if (src && this.options.markersList[i].src === src) { - markerOptions = this.options.markersList[i]; - return markerOptions; - } - } - return markerOptions; - } - - /** - * Converts markerElement options into Openlayers IconStyles options. - * - * @param {Object} markerElement - marker element - * @returns {Object} ol.Style.Icon constructor options. - * @private - */ - _getIconStyleOptions (markerElement) { - var iconOptions = {}; - Object.keys(markerElement).forEach((key) => { - switch (key) { - case "src": - case "size": - case "scale": - case "color": - case "anchor": - case "anchorOrigin": - case "anchorXUnits": - case "anchorYUnits": - iconOptions[key] = markerElement[key]; - break; - } - }); - - return iconOptions; - } - - /** - * Initialize control (called by Drawing constructor) - * - * @method _initialize - * @param {Object} options - control options (set by user) - * @private - */ - _initialize (options) { - // determination d'un uid - this._uid = SelectorID.generate(); - - // export name / format / ... - this._exportName = "Croquis"; - this._exportFormat = "KML"; - this._exportMimeType = "application/vnd.google-earth.kml+xml"; - this._exportExt = ".kml"; - - options = options || {}; - // Set default options - this.options = options; - - if (!this.options.layerDescription) { - this.options.layerDescription = { - title : "Croquis", - description : "Mon croquis" - }; - } - - // applying default tools - if (!this.options.tools) { - this.options.tools = {}; - } - Object.keys(Drawing.DefaultTools).forEach((key) => { - if (!this.options.tools.hasOwnProperty(key)) { - this.options.tools[key] = Drawing.DefaultTools[key]; - } - }); - // styles par defaut lors du dessin - if (!this.options.cursorStyle) { - this.options.cursorStyle = {}; - } - Object.keys(Drawing.DefaultCursorStyle).forEach((key) => { - if (!this.options.cursorStyle.hasOwnProperty(key)) { - this.options.cursorStyle[key] = Drawing.DefaultCursorStyle[key]; - } - }); - - this.options.collapsed = (options.collapsed !== undefined) ? options.collapsed : true; - /** {Boolean} specify if Drawing control is collapsed (true) or not (false) */ - this.collapsed = this.options.collapsed; - - this.options.draggable = (options.draggable !== undefined) ? options.draggable : false; - /** {Boolean} specify if Drawing control is draggable (true) or not (false) */ - this.draggable = this.options.draggable; - - this.options.markersList = options.markersList || MarkersOther["drawing_api"]; - - // applying default labels - if (!this.options.labels) { - this.options.labels = {}; - } - Object.keys(Drawing.DefaultLabels).forEach((key) => { - if (!this.options.labels.hasOwnProperty(key)) { - this.options.labels[key] = Drawing.DefaultLabels[key]; - } - }); - - // applying default styles - if (!this.options.defaultStyles) { - this.options.defaultStyles = {}; - } - Object.keys(Drawing.DefaultStyles).forEach((key) => { - if (!options.defaultStyles.hasOwnProperty(key)) { - this.options.defaultStyles[key] = Drawing.DefaultStyles[key]; - return; - } - if (key === "polyFillOpacity" && - (options.defaultStyles[key] < 0 || - options.defaultStyles[key] > 1)) { - logger.log("Wrong value (" + options.defaultStyles[key] + ") for defaultStyles.polyFillOpactity. Must be between 0 and 1"); - this.options.defaultStyles[key] = Drawing.DefaultStyles[key]; - return; - } - if (key === "strokeWidth" || key === "polyStrokeWidth") { - var intValue = parseInt(options.defaultStyles[key], 10); - if (isNaN(intValue) || intValue < 0) { - logger.log("Wrong value (" + options.defaultStyles[key] + ") for defaultStyles.strokeWidth. Must be a positive interger value."); - this.options.defaultStyles[key] = Drawing.DefaultStyles[key]; - return; - } - this.options.defaultStyles[key] = intValue; - } - if (key === "markerSize") { - var floatValue = parseFloat(options.defaultStyles[key]); - if (isNaN(floatValue) || floatValue < 0) { - logger.log("Wrong value (" + options.defaultStyles[key] + ") for defaultStyles.markerSize. Must be a positive value."); - this.options.defaultStyles[key] = Drawing.DefaultStyles[key]; - return; - } - this.options.defaultStyles[key] = floatValue; - } - }); - - this.interactionCurrent = null; - this.interactionSelectEdit = null; - this.featuresCollectionSelected = null; - - this.stylingOvl = null; - this.popupOvl = null; - - this.layer = null; - if (this.options.layer && this.options.layer instanceof VectorLayer) { - this.layer = this.options.layer; - } - - // detection du support : desktop ou tactile - // FIXME : utile ? - this._isDesktop = this._detectSupport(); - - // applying default popup - if (!this.options.popup) { - this.options.popup = { - display : true, - apply : null - }; - } - } - - /** - * Creates empty layer to host features - * - * @private - */ - _createEmptyLayer () { - var features = new Collection(); - var layer = new VectorLayer({ - source : new VectorSource({ - features : features - }) - }); - // on rajoute le champ gpResultLayerId permettant d'identifier une couche crée par le composant. - layer.gpResultLayerId = "drawing"; - // on le rajoute au controle (et à la carte) - this.setLayer(layer); - } - - /** - * this method is called by the constructor. - * this information is useful to switch to touch mode. - * Detection : test for desktop or tactile - * - * @method _detectSupport - * - * @returns {Boolean} is desktop - * @private - */ - _detectSupport () { - // TODO - // Choix de gérer la détection dans le code du composant au lieu du DOM car : - // Utilisation de l'implémentation Leaflet - // http://leafletjs.com/reference.html#browser - - var isDesktop = true; - var userAgent = window.navigator.userAgent.toLowerCase(); - - if (userAgent.indexOf("iphone") !== -1 || - userAgent.indexOf("ipod") !== -1 || - userAgent.indexOf("ipad") !== -1 || - userAgent.indexOf("android") !== -1 || - userAgent.indexOf("mobile") !== -1 || - userAgent.indexOf("blackberry") !== -1 || - userAgent.indexOf("tablet") !== -1 || - userAgent.indexOf("phone") !== -1 || - userAgent.indexOf("touch") !== -1) { - isDesktop = false; - } - - if (userAgent.indexOf("msie") !== -1 || - userAgent.indexOf("trident") !== -1) { - isDesktop = true; - } - - return isDesktop; - } - - // ################################################################### // - // ######################## methods handle dom ####################### // - // ################################################################### // - - /** - * Create control main container (called by Drawing constructor) - * - * @method _initContainer - * - * @returns {DOMElement} DOM element - * @private - */ - _initContainer () { - // creation du container principal - var container = this._createMainContainerElement(); - - var picto = this._showDrawingButton =this._createShowDrawingPictoElement(); - container.appendChild(picto); - - var panel = this._drawingPanel = this._createDrawingPanelElement(); - var panelDiv = this._createDrawingPanelDivElement(); - panel.appendChild(panelDiv); - - var header = this._drawingPanelHeader = this._createDrawingPanelHeaderElement(); - panelDiv.appendChild(header); - - var sections = this._createDrawingToolsDivSections(); - panelDiv.appendChild(sections); - - var tools = this._createDrawingToolsSections(); - for (var i = 0; i < tools.length; i++) { - sections.appendChild(tools[i]); - } - - container.appendChild(panel); - - return container; - } - - // ################################################################### // - // ##################### handlers events to control ################## // - // ################################################################### // - - /** - * Callback de fin de dessin de geometrie - * @param {Object} feature - ol feature - * @param {String} geomType - geometry type - * @param {Boolean} clean - clean last feature - * - * @private - */ - _drawEndFeature (feature, geomType) { - // application des styles par defaut. - var style = null; - - switch (geomType) { - case "Point": - style = new Style({ - image : new Icon(this._getIconStyleOptions(this.options.markersList[0])) - }); - break; - case "LineString": - style = new Style({ - stroke : new Stroke({ - color : this.options.defaultStyles.strokeColor, - width : this.options.defaultStyles.strokeWidth - }) - }); - break; - case "Polygon": - style = new Style({ - fill : new Fill({ - color : Color.hexToRgba( - this.options.defaultStyles.polyFillColor, - this.options.defaultStyles.polyFillOpacity - ) - }), - stroke : new Stroke({ - color : this.options.defaultStyles.polyStrokeColor, - width : this.options.defaultStyles.polyStrokeWidth - }) - }); - break; - } - feature.setStyle(style); - - // gestion des mesures - this._updateMeasure(feature, geomType); - - if (this.options.popup.display) { - // creation overlay pour saisie du label - // contexte - var context = this; - - /** - * Enregistrement de la valeur saisie dans l'input. - * - * @param {String} key - clef de l'attribut. - * @param {String} value - valeur de l'attribut. - * @param {Boolean} save - true si on garde le label. - */ - var setAttValue = function (key, value, save) { - context.getMap().removeOverlay(context.popupOvl); - context.popupOvl = null; - if (save && value && value.trim().length > 0) { - var obj = {}; - obj[key] = value.replace(/\n/g, "
"); - feature.setProperties(obj); - } - }; - - var popup = null; - var popupByDefault = true; - - var displayFunction = this.options.popup.function; - if (displayFunction && typeof displayFunction === "function") { - // la sauvegarde et la fermeture sont des actions à implementer par l'utilisateur - // par contre, la destruction est à gerer en interne - popup = displayFunction.call(context, { - feature : feature, - geomType : geomType, - closeFunc : function () { - setAttValue(null, false); - }, - saveFunc : function (message) { - setAttValue(message, true); - } - }); - if (popup) { - // on est sûr que la popup customisée existe, - // donc on n'utilise pas celle par defaut... - popupByDefault = false; - // FIXME comment forcer le focus sur une div ? - popup.tabIndex = -1; // hack sur le focus sur une div ? - popup.onblur = function () { - context.getMap().removeOverlay(context.popupOvl); - context.popupOvl = null; - }; - } - } - // use popup by default - if (popupByDefault) { - // function by default - popup = this._createLabelDiv({ - applyFunc : setAttValue, - inputId : this._addUID("att-input"), - placeholder : "Saisir une description...", - measure : (this.options.tools.measure) ? feature.getProperties().measure : null, - geomType : geomType, - key : "description" - }); - } - // un peu de menage... - if (this.popupOvl) { - this.getMap().removeOverlay(this.popupOvl); - this.popupOvl = null; - } - // creation de l'overlay - this.popupOvl = new Overlay({ - element : popup, - // FIXME : autres valeurs. - positioning : "top-center" - // stopEvent : false - }); - this.getMap().addOverlay(this.popupOvl); - var geomExtent = feature.getGeometry().getExtent(); - this.popupOvl.setPosition([ - (geomExtent[0] + geomExtent[2]) / 2, (geomExtent[1] + geomExtent[3]) / 2 - ]); - if (document.getElementById(this._addUID("att-input"))) { - document.getElementById(this._addUID("att-input")).focus(); - } - } - } - - /** - * Creates Interaction for features removal. - * - * @returns {SelectInteraction} created interaction. - * @private - */ - _createRemoveInteraction () { - var interaction = new SelectInteraction({ - // features : this.layer.getSource().getFeaturesCollection(), - layers : [this.layer], - style : false - }); - interaction.on("select", (seEv) => { - if (!seEv || !seEv.selected || seEv.selected.length === 0) { - return; - } - this.layer.getSource().removeFeature(seEv.selected[0]); - // suppression puis rajout de l'interaction pour appliquer le changement tout de suite... - this.getMap().removeInteraction(this.interactionCurrent); - this.interactionCurrent = this._createRemoveInteraction(); - this.getMap().addInteraction(this.interactionCurrent); - }); - return interaction; - } - - /** - * Creates Interaction for features style definition. - * - * @returns {ol.interaction.Select} created interaction. - * @private - */ - _createStylingInteraction () { - var interaction = new SelectInteraction({ - layers : [this.layer], - style : false - }); - interaction.on("select", (seEv) => { - // suppression de toute popup existante - if (this.stylingOvl) { - this.getMap().removeOverlay(this.stylingOvl); - } - if (!seEv || !seEv.selected || seEv.selected.length === 0) { - return; - } - - var valuesColor = null; - var hexColor = null; - var popupOvl = null; - var geomType = null; - var initValues = {}; - - // FIXME - // l'appel feature.getStyle() est parfois nul pour des geometries Point - // avec un style par defaut ! - - var geom = seEv.selected[0].getGeometry(); - var style = seEv.selected[0].getStyle(); - if (geom instanceof Point || geom instanceof MultiPoint) { - // INFO - // on determine si c'est un marker (ou cercle), un label ou les 2. - // un label a un pixel transparent comme icone - if (style && - style.getImage() && - typeof style.getImage().getSrc === "function" && - style.getImage().getSrc() !== this.options.defaultStyles.textIcon1x1.src) { - geomType = "Point"; - // on traite un marker - // mais si c'est un cercle !? - if (typeof style.getImage().getSrc === "function") { - initValues.markerSrc = style.getImage().getSrc(); - initValues.markerSize = style.getImage().getScale() || 1; - initValues.markerAnchor = style.getImage().getAnchor(); - if (style.getImage().getColor()) { - valuesColor = style.getImage().getColor(); - if (Array.isArray(valuesColor)) { // FIXME Array !? - valuesColor = "rgba(" + valuesColor.join() + ")"; - } else { - initValues.markerColor = valuesColor; - } - hexColor = Color.isRGB(valuesColor) ? Color.rgbaToHex(valuesColor) : { - hex : valuesColor, - opacity : 1 - }; - initValues.markerColor = hexColor.hex; - initValues.markerOpacity = hexColor.opacity; - } else { - initValues.markerColor = this.options.markersList[0].color || "#ffffff"; - } - } else { - initValues.markerSrc = this.options.markersList[0].src; - initValues.markerSize = this.options.markersList[0].scale || 1; - initValues.markerColor = this.options.markersList[0].color || "#ffffff"; - initValues.markerAnchor = this.options.markersList[0].anchor; - } - initValues.markerCustom = !(this._getsMarkersOptionsFromSrc(initValues.markerSrc)); - } - if (style && style.getText()) { - var labelName = seEv.selected[0].getProperties().name; - if (labelName) { - // test si on a un marker avec un label - geomType = (geomType === "Point") ? "Point&Text" : "Text"; - if (style.getText().getStroke() && style.getText().getStroke().getColor()) { - valuesColor = style.getText().getStroke().getColor(); - if (Array.isArray(valuesColor)) { // FIXME Array !? - valuesColor = "rgba(" + valuesColor.join() + ")"; - } else { - initValues.strokeColor = valuesColor; - } - hexColor = Color.isRGB(valuesColor) ? Color.rgbaToHex(valuesColor) : { - hex : valuesColor, - opacity : 1 - }; - initValues.strokeColor = hexColor.hex; - initValues.strokeOpacity = hexColor.opacity; - } - if (style.getText().getStroke() && style.getText().getStroke().getWidth()) { - initValues.strokeWidth = style.getText().getStroke().getWidth(); - } - if (style.getText().getFill() && style.getText().getFill().getColor()) { - valuesColor = style.getText().getFill().getColor(); - if (Array.isArray(valuesColor)) { - valuesColor = "rgba(" + valuesColor.join() + ")"; - } else { - initValues.fillColor = valuesColor; - } - hexColor = Color.isRGB(valuesColor) ? Color.rgbaToHex(valuesColor) : { - hex : valuesColor, - opacity : 1 - }; - initValues.fillColor = hexColor.hex; - initValues.fillOpacity = hexColor.opacity; - } - initValues.strokeColor = initValues.hasOwnProperty("strokeColor") ? initValues.strokeColor : this.options.defaultStyles.textStrokeColor; - initValues.strokeWidth = initValues.hasOwnProperty("strokeWidth") ? initValues.strokeWidth : this.options.defaultStyles.textStrokeWidth; - initValues.fillColor = initValues.hasOwnProperty("fillColor") ? initValues.fillColor : this.options.defaultStyles.textFillColor; - // Par defaut, pour un marker avec un label, on affiche le label si le tag "name" est renseigné. - if (geomType === "Point&Text") { - var value = style.getText().getText(); - if (!value) { - style.getText().setText(labelName); - } - var checked = seEv.selected[0].get("checked"); - initValues.labelDisplay = (checked === undefined) ? this.options.defaultStyles.labelDisplay : checked; - } - } - } - } else if (geom instanceof LineString || geom instanceof MultiLineString) { - geomType = "Line"; - if (style && style.getStroke()) { - if (style.getStroke().getWidth()) { - initValues.strokeWidth = style.getStroke().getWidth(); - } - if (style.getStroke().getColor()) { - valuesColor = style.getStroke().getColor(); - if (Array.isArray(valuesColor)) { - valuesColor = "rgba(" + valuesColor.join() + ")"; - } else { - initValues.strokeColor = valuesColor; - } - hexColor = Color.isRGB(valuesColor) ? Color.rgbaToHex(valuesColor) : { - hex : valuesColor, - opacity : 1 - }; - initValues.strokeColor = hexColor.hex; - initValues.strokeOpacity = hexColor.opacity; - } - } - initValues.strokeWidth = initValues.hasOwnProperty("strokeWidth") ? initValues.strokeWidth : this.options.defaultStyles.strokeWidth; - initValues.strokeColor = initValues.hasOwnProperty("strokeColor") ? initValues.strokeColor : this.options.defaultStyles.strokeColor; - } else if (geom instanceof Polygon || geom instanceof MultiPolygon) { - geomType = "Polygon"; - if (style && style.getStroke()) { - if (style.getStroke().getWidth()) { - initValues.strokeWidth = style.getStroke().getWidth(); - } - if (style.getStroke().getColor()) { - valuesColor = style.getStroke().getColor(); - if (Array.isArray(valuesColor)) { - valuesColor = "rgba(" + valuesColor.join() + ")"; - } else { - initValues.strokeColor = valuesColor; - } - hexColor = Color.isRGB(valuesColor) ? Color.rgbaToHex(valuesColor) : { - hex : valuesColor, - opacity : 1 - }; - initValues.strokeColor = hexColor.hex; - initValues.strokeOpacity = hexColor.opacity; - } - } - if (style && style.getFill()) { - if (style.getFill().getColor()) { - valuesColor = style.getFill().getColor(); - if (Array.isArray(valuesColor)) { - valuesColor = "rgba(" + valuesColor.join() + ")"; - } else { - initValues.fillColor = valuesColor; - } - hexColor = Color.isRGB(valuesColor) ? Color.rgbaToHex(valuesColor) : { - hex : valuesColor, - opacity : 1 - }; - initValues.fillColor = hexColor.hex; - initValues.fillOpacity = hexColor.opacity; - } - } - initValues.strokeWidth = initValues.hasOwnProperty("strokeWidth") ? initValues.strokeWidth : this.options.defaultStyles.polyStrokeWidth; - initValues.strokeColor = initValues.hasOwnProperty("strokeColor") ? initValues.strokeColor : this.options.defaultStyles.polyStrokeColor; - initValues.fillColor = initValues.hasOwnProperty("fillColor") ? initValues.fillColor : this.options.defaultStyles.polyFillColor; - initValues.fillOpacity = initValues.hasOwnProperty("fillOpacity") ? initValues.fillOpacity : this.options.defaultStyles.polyFillOpacity; - } - if (!geomType) { - logger.log("Unhandled geometry type for styling."); - return; - } - var dtObj = this; - /** - * function called when apply button is pressed. - * - * @param {String} action - "apply" (to selected object), "default" (set as default), "cancel" (do nothing). - */ - var applyStyle = function (action) { - if (action === "cancel") { - dtObj.getMap().removeOverlay(popupOvl); - return; - } - var setDefault = action !== "apply"; - - var fillColorElem = document.getElementById(dtObj._addUID("fillColor")); - var fillOpacityElem = document.getElementById(dtObj._addUID("fillOpacity")); - var strokeColorElem = document.getElementById(dtObj._addUID("strokeColor")); - var strokeWidthElem = document.getElementById(dtObj._addUID("strokeWidth")); - var markerSizeElem = document.getElementById(dtObj._addUID("markerSize")); - // var markerColorElem = document.getElementById(dtObj._addUID("markerColor")); - switch (geomType.toLowerCase()) { - case "text": - if (setDefault) { - dtObj.options.defaultStyles.textStrokeColor = strokeColorElem.value; - dtObj.options.defaultStyles.textStrokeWidth = strokeWidthElem.value; - dtObj.options.defaultStyles.textFillColor = fillColorElem.value; - } else { - seEv.selected[0].setStyle(new Style({ - text : new Text({ - font : "16px sans", - textAlign : "left", - text : style.getText().getText(), - fill : new Fill({ - color : fillColorElem.value - }), - stroke : new Stroke({ - color : strokeColorElem.value, - width : parseInt(strokeWidthElem.value, 10) - }) - }) - })); - } - break; - case "point&text": - case "point": - var labelDisplay = document.querySelector("input[type='checkbox']"); - // FIXME cas où le marker n'est pas dans la liste ? - // si le marker n'existe pas dans le liste, on ne souhaite donc que changer la couleur du - // pictogramme ou la taille..., on garde donc le picto initial. - var markerSelected = null; - var scale = parseInt(markerSizeElem.value, 10) / 10; - var markerChecked = document.querySelector("input[name='marker']:checked"); - if (markerChecked) { - markerSelected = dtObj._getsMarkersOptionsFromSrc(markerChecked.value); - markerSelected.scale = scale; - // markerSelected.color = markerColorElem.value; - } - if (setDefault) { - dtObj.options.defaultStyles.markerSize = scale; - if (dtObj.options.markersList.length > 1) { - // index du marker dans la liste des markers - var idxMarker = dtObj.options.markersList.findIndex(function (mrk) { - if (mrk === markerSelected) { // FIXME object comparison - return true; - } - return false; - }); - if (idxMarker > 0) { - // on enleve le marker de son ancienne position - dtObj.options.markersList.splice(idxMarker, 1); - // on le place en tête de liste - dtObj.options.markersList.splice(0, 0, markerSelected); - } - } - if (geomType.toLowerCase() === "point&text") { - dtObj.options.defaultStyles.textStrokeColor = initValues.strokeColor; - dtObj.options.defaultStyles.textStrokeWidth = initValues.strokeWidth; - dtObj.options.defaultStyles.textFillColor = initValues.fillColor; - dtObj.options.defaultStyles.labelDisplay = initValues.labelDisplay; - } - } else { - var text = {}; - if (geomType.toLowerCase() === "point&text") { - seEv.selected[0].set("checked", labelDisplay.checked); - text = { - text : new Text({ - font : "16px sans", - textAlign : "left", - text : (labelDisplay.checked) ? seEv.selected[0].get("name") : "", - fill : new Fill({ - color : initValues.fillColor - }), - stroke : new Stroke({ - color : initValues.strokeColor, - width : parseInt(initValues.strokeWidth, 10) - }) - }) - }; - } - if (markerSelected) { - seEv.selected[0].setStyle(new Style(Object.assign({ - image : new Icon(dtObj._getIconStyleOptions(markerSelected)) - }, text))); - } else { - // FIXME anchor !? - seEv.selected[0].setStyle(new Style(Object.assign({ - image : new Icon({ - src : initValues.markerSrc, // on garde le pictogramme initial ! - // color : markerColorElem.value, // on recupère la couleur ! - anchor : initValues.markerAnchor, // on garde la position initial ! - anchorOrigin : "top-left", - anchorXUnits : "pixels", - anchorYUnits : "pixels", - scale : scale - }) - }, text))); - } - } - break; - case "line": - if (setDefault) { - dtObj.options.defaultStyles.strokeColor = strokeColorElem.value; - dtObj.options.defaultStyles.strokeWidth = parseInt(strokeWidthElem.value, 10); - } else { - seEv.selected[0].setStyle(new Style({ - stroke : new Stroke({ - width : parseInt(strokeWidthElem.value, 10), - color : strokeColorElem.value - }) - })); - } - break; - case "polygon": - var opacity = parseInt(fillOpacityElem.value, 10) / 10; - if (setDefault) { - dtObj.options.defaultStyles.polyStrokeColor = strokeColorElem.value; - dtObj.options.defaultStyles.polyFillColor = fillColorElem.value; - dtObj.options.defaultStyles.polyFillOpacity = opacity; - dtObj.options.defaultStyles.polyStrokeWidth = parseInt(strokeWidthElem.value, 10); - } else { - seEv.selected[0].setStyle(new Style({ - stroke : new Stroke({ - width : parseInt(strokeWidthElem.value, 10), - color : strokeColorElem.value - }), - fill : new Fill({ - // color : fillColorElem.value - color : Color.hexToRgba(fillColorElem.value, opacity) - }) - })); - } - break; - } - if (!setDefault) { - // application des styles par defaut - // fermeture de la popup (si on applique le style à l'objet) - dtObj.getMap().removeOverlay(popupOvl); - } - }; - - var popupDiv = this._createStylingDiv({ - geomType : geomType, - initValues : initValues, - applyFunc : applyStyle - }); - popupOvl = new Overlay({ - element : popupDiv, - // FIXME : autres valeurs. - positioning : "top-center" - // stopEvent : false - }); - this.getMap().addOverlay(popupOvl); - popupOvl.setPosition(seEv.mapBrowserEvent.coordinate); - this.stylingOvl = popupOvl; - // suppression puis rajout de l'interaction pour appliquer le changement tout de suite... - this.getMap().removeInteraction(this.interactionCurrent); - this.interactionCurrent = this._createStylingInteraction(); - this.getMap().addInteraction(this.interactionCurrent); - }); - return interaction; - } - - /** - * Creates Interaction for text definition. - * - * @returns {SelectInteraction} created interaction. - * @private - */ - _createLabelInteraction () { - var interaction = new SelectInteraction({ - layers : [this.layer], - style : false - }); - interaction.on("select", (seEv) => { - // suppression de toute popup existante - if (this.labelOvl) { - this.getMap().removeOverlay(this.labelOvl); - } - if (!seEv || !seEv.selected || seEv.selected.length === 0) { - return; - } - var popupOvl = null; - var geomType = null; - var _textValue = null; - var _measure = null; - - var geom = seEv.selected[0].getGeometry(); - var style = seEv.selected[0].getStyle(); - if (geom instanceof Point || geom instanceof MultiPoint) { - // on determine si c'est un marker ou un label. - var _label = seEv.selected[0].getProperties().name; - if (style && style.getText() && _label) { - geomType = "Text"; - } else if (style && style.getImage()) { - geomType = "Point"; - } - } else if (geom instanceof LineString || geom instanceof MultiLineString) { - geomType = "Line"; - } else if (geom instanceof Polygon || geom instanceof MultiPolygon) { - geomType = "Polygon"; - } else { - logger.log("Geometry type for styling not supported ."); - return; - } - - if (!geomType) { - logger.log("Unhandled geometry type for styling."); - return; - } - - if (geomType === "Text") { - // pour les labels on récupère la valeur dans le style - _textValue = style.getText().getText(); - } else { - // pour les autres, c'est un attribut du feature - // choix à faire entre description (KML et GeoJSON) ou desc (GPX) - var featProps = seEv.selected[0].getProperties(); - if (featProps && (featProps.hasOwnProperty("description") || featProps.hasOwnProperty("desc"))) { - _textValue = featProps["description"] || featProps["desc"]; - } - if (featProps && featProps.hasOwnProperty("measure")) { - _measure = featProps["measure"]; - } - } - - var context = this; - /** - * Enregistrement de la valeur saisie dans l'input. - * - * @param {String} key - clef de l'attribut. - * @param {String} value - valeur de l'attribut. - * @param {Boolean} save - true si on garde le label. - */ - var setTextValue = function (key, value, save) { - context.getMap().removeOverlay(popupOvl); - if (!save) { - return; - } - - var feature = seEv.selected[0]; - if (geomType === "Text") { - var style = feature.getStyle(); - style.getText().setText(value); - feature.setProperties({ - name : value - }); - feature.setStyle(style); - return; - } - - var obj = {}; - obj[key] = value.replace(/\n/g, "
"); - feature.setProperties(obj); - }; - - var popupDiv = this._createLabelDiv({ - applyFunc : setTextValue, - inputId : this._addUID("label-input"), - placeholder : (geomType === "Text" ? "Saisir un label..." : "Saisir une description..."), - text : _textValue, - key : "description", - measure : (this.options.tools.measure) ? _measure : null, - geomType : geomType - }); - - popupOvl = new Overlay({ - element : popupDiv, - // FIXME : autres valeurs. - positioning : "top-center" - // stopEvent : false - }); - - this.getMap().addOverlay(popupOvl); - popupOvl.setPosition(seEv.mapBrowserEvent.coordinate); - document.getElementById(this._addUID("label-input")).focus(); - this.labelOvl = popupOvl; - // suppression puis rajout de l'interaction pour appliquer le changement tout de suite... - this.getMap().removeInteraction(this.interactionCurrent); - this.interactionCurrent = this._createLabelInteraction(); - this.getMap().addInteraction(this.interactionCurrent); - }); - return interaction; - } - - /** - * Callback de fin de modification du dessin afin de mettre à jour la mesure - * TODO - * @param {Object} feature - ol feature - * @param {String} geomType - geometry type - * - * @private - */ - _updateMeasure (feature, geomType) { - logger.log(feature); - - var measure = null; - - var projection = this.getMap().getView().getProjection(); - - // arrondi - function __roundDecimal (nombre, precision) { - precision = precision || 2; - var factor = Math.pow(10, precision); - return Math.round(nombre * factor) / factor; - } - - var type = (geomType) || feature.getProperties().type; - switch (type) { - case "Point": - var coordinatesPoint = (feature.getGeometry()).getCoordinates(); - var c = olTransformProj(coordinatesPoint, projection, "EPSG:4326"); - measure = "lon : "; - measure += __roundDecimal(c[0], 4) + "°"; - measure += " / "; - measure += "lat : "; - measure += __roundDecimal(c[1], 4) + "°"; - - break; - case "LineString": - var measureLength = 0; - var coordinatesLine = (feature.getGeometry()).getCoordinates(); - for (var i = 0, ii = coordinatesLine.length - 1; i < ii; ++i) { - var c1 = olTransformProj(coordinatesLine[i], projection, "EPSG:4326"); - var c2 = olTransformProj(coordinatesLine[i + 1], projection, "EPSG:4326"); - measureLength += olGetDistanceSphere(c1, c2); - } - measure = (measureLength > 1000) - ? __roundDecimal(measureLength / 1000, 3) + " km" - : __roundDecimal(measureLength, 3) + " m"; - - break; - case "Polygon": - var measureArea = 0; - var geom = (feature.getGeometry()).clone(); - var coordinatesAera = geom.getLinearRing(0).getCoordinates(); - measureArea = Math.abs(olGetAreaSphere(new Polygon([coordinatesAera]))); - - // FIXME on se limite à des trous uniquement ! - // cad les polygones sont strictement contenus dans le 1er ! - var rings = geom.getLinearRings(); - if (rings.length > 1) { - for (var ij = 1; ij < rings.length; ij++) { - var coordinatesRings = rings[ij].getCoordinates(); - measureArea -= Math.abs(olGetAreaSphere(new Polygon([coordinatesRings]))); - } - } - - measure = (measureArea > 1000000) - ? __roundDecimal(measureArea / 1000000, 3) + " km^2" - : __roundDecimal(measureArea, 2) + " m^2"; - - break; - } - - // enregistrement de la mesure dans la feature - feature.setProperties({ - measure : measure, - type : type - }); - } - - /** - * Handles click on drawing tools icons - * - * @param {Event} clickEvent - click event - * @param {String} toolId - selected tool Id - * @param {Drawing} context - Drawing control. - * @private - */ - _handleToolClick (clickEvent, toolId, context) { - var map = context.getMap(); - if (!map) { - logger.trace("Drawing control not attached to any map."); - return; - } - // on supprime les interactions des autres extensions - Interactions.unset(map, { - current : "Drawing" - }); - - // on supprime l'interaction courante s'il y en a une. - if (context.interactionCurrent) { - map.removeInteraction(context.interactionCurrent); - context.interactionCurrent = null; - } - - // on supprime l'interaction de selection courante s'il y en a une. - if (context.interactionSelectEdit) { - map.removeInteraction(context.interactionSelectEdit); - context.interactionSelectEdit = null; - } - - // on supprime la popup courante s'il y en a une. - if (context.popupOvl) { - context.getMap().removeOverlay(context.popupOvl); - context.popupOvl = null; - } - - // si aucune couche de dessin, on en crée une vide. - if (!this.layer) { - this._createEmptyLayer(); - } - switch (toolId) { - case this._addUID("drawing-tool-point"): - if (context.dtOptions["points"].active) { - context.interactionCurrent = new DrawInteraction({ - stopClick : true, - // features : context.layer.getSource().getFeaturesCollection(), - source : context.layer.getSource(), - style : new Style({ - image : new Icon(this._getIconStyleOptions(this.options.markersList[0])) - }), - type : ("Point") - }); - context.interactionCurrent.on("drawend", function (deEv) { - // ajout eventuel d'un attribut description sur le feature - context._drawEndFeature(deEv.feature, "Point"); - }, - context); - } - break; - case this._addUID("drawing-tool-line"): - if (context.dtOptions["lines"].active) { - context.interactionCurrent = new DrawInteraction({ - stopClick : true, - // features : context.layer.getSource().getFeaturesCollection(), - source : context.layer.getSource(), - style : new Style({ - image : new Circle({ - radius : this.options.cursorStyle.radius, - stroke : new Stroke({ - color : this.options.cursorStyle.strokeColor, - width : this.options.cursorStyle.strokeWidth - }), - fill : new Fill({ - color : this.options.cursorStyle.fillColor - }) - }), - stroke : new Stroke({ - color : this.options.defaultStyles.strokeColor, - width : this.options.defaultStyles.strokeWidth - }) - }), - type : ("LineString") - }); - context.interactionCurrent.on("drawend", function (deEv) { - // ajout eventuel d'un attribut description sur le feature - context._drawEndFeature(deEv.feature, "LineString"); - }, - context); - } - break; - case this._addUID("drawing-tool-polygon"): - if (context.dtOptions["polygons"].active) { - context.interactionCurrent = new DrawInteraction({ - stopClick : true, - // features : context.layer.getSource().getFeaturesCollection(), - source : context.layer.getSource(), - style : new Style({ - image : new Circle({ - radius : this.options.cursorStyle.radius, - stroke : new Stroke({ - color : this.options.cursorStyle.strokeColor, - width : this.options.cursorStyle.strokeWidth - }), - fill : new Fill({ - color : this.options.cursorStyle.fillColor - }) - }), - stroke : new Stroke({ - color : this.options.defaultStyles.polyStrokeColor, - width : this.options.defaultStyles.polyStrokeWidth - }), - fill : new Fill({ - color : Color.hexToRgba( - this.options.defaultStyles.polyFillColor, - this.options.defaultStyles.polyFillOpacity - ) - }) - }), - type : ("Polygon") - }); - context.interactionCurrent.on("drawend", function (deEv) { - // ajout eventuel d'un attribut description sur le feature - context._drawEndFeature(deEv.feature, "Polygon"); - }, - context); - } - break; - case this._addUID("drawing-tool-holes"): - if (context.dtOptions["holes"].active) { - // selection du polygone à modifier - context.interactionSelectEdit = new SelectInteraction({ - stopClick : true, - condition : eventPointerMove, - layers : [this.layer] - }); - context.interactionSelectEdit.setProperties({ - name : "Drawing", - source : context - }); - map.addInteraction(context.interactionSelectEdit); - - // saisie - context.interactionCurrent = new DrawInteraction({ - stopClick : true, - features : this.interactionSelectEdit.getFeatures(), - style : new Style({ - image : new Circle({ - radius : this.options.cursorStyle.radius, - stroke : new Stroke({ - color : this.options.cursorStyle.strokeColor, - width : this.options.cursorStyle.strokeWidth - }), - fill : new Fill({ - color : this.options.cursorStyle.fillColor - }) - }), - stroke : new Stroke({ - color : this.options.defaultStyles.polyStrokeColor, - width : this.options.defaultStyles.polyStrokeWidth - }), - fill : new Fill({ - color : Color.hexToRgba( - this.options.defaultStyles.polyFillColor, - this.options.defaultStyles.polyFillOpacity - ) - }) - }), - type : ("Polygon") - }); - - context.interactionCurrent.on("drawstart", function (deEv) {}, context); - - context.interactionCurrent.on("drawend", function (deEv) { - // recuperation du feature selectionné - var features = context.interactionSelectEdit.getFeatures(); - if (features.getLength()) { - // choix sur le 1er feature de la liste - var feature = features.item(0); - var hole = deEv.feature.getGeometry().getCoordinates()[0]; - // test pour savoir si le polygone est entièrement - // inclu dans l'autre afin de faciliter les calculs d'aire ! - var bHoleIsIncluded = true; - for (var i = 0; i < hole.length; i++) { - if (!feature.getGeometry().intersectsCoordinate(hole[i])) { - bHoleIsIncluded = false; - break; - } - } - if (!bHoleIsIncluded) { - return; - } - // ajout du rings - feature.getGeometry().appendLinearRing(new LinearRing(hole)); - // enregistrement ! - deEv.feature = feature; - // finalisation du dessin... - context._drawEndFeature(deEv.feature, "Polygon"); - } - }, - context); - } - break; - case this._addUID("drawing-tool-text"): - // text : creation de points invisibles avec un label. - if (context.dtOptions["text"].active) { - context.interactionCurrent = new DrawInteraction({ - stopClick : true, - // features : context.layer.getSource().getFeaturesCollection(), - source : context.layer.getSource(), - style : new Style({ - image : new Circle({ - radius : this.options.cursorStyle.radius, - stroke : new Stroke({ - color : this.options.cursorStyle.strokeColor, - width : this.options.cursorStyle.strokeWidth - }), - fill : new Fill({ - color : this.options.cursorStyle.fillColor - }) - }) - }), - type : ("Point") - }); - context.interactionCurrent.on("drawend", (deEv) => { - // creation overlay pour saisie du label - var popupOvl = null; - /** - * Enregistrement de la valeur saisie dans l'input. - * - * @param {String} key - clef du label - * @param {String} value - valeur du label - * @param {Boolean} save - true si on garde le label. - */ - var setTextValue = function (key, value, save) { - context.getMap().removeOverlay(popupOvl); - if (!save) { - // removes feature from overlay. - context.layer.getSource().removeFeature(deEv.feature); - return; - } - - var obj = {}; - obj[key] = value; - deEv.feature.setProperties(obj); - - deEv.feature.setStyle(new Style({ - // HACK : on ajoute un icone invisible de 1x1 pixel afin d'eviter - // l'affichage d'une punaise google ! - image : new Icon(context._getIconStyleOptions(context.options.defaultStyles.textIcon1x1)), - text : new Text({ - textAlign : "left", - font : "16px sans", - text : value, - fill : new Fill({ - color : context.options.defaultStyles.textFillColor - }), - stroke : new Stroke({ - color : context.options.defaultStyles.textStrokeColor, - width : 3 - }) - }) - })); - }; - var popup = this._createLabelDiv({ - applyFunc : setTextValue, - inputId : context._addUID("label-input"), - geomType : "Text", - key : "name", - placeholder : "Saisir un label..." - }); - popupOvl = new Overlay({ - element : popup, - // FIXME : autres valeurs. - positioning : "top-center" // par defaut, top-left... - // stopEvent : false - }); - context.getMap().addOverlay(popupOvl); - popupOvl.setPosition(deEv.feature.getGeometry().getCoordinates()); - document.getElementById(this._addUID("label-input")).focus(); - }); - } - break; - case this._addUID("drawing-tool-edit"): - if (context.dtOptions["edit"].active) { - this.featuresCollectionSelected = new Collection(); - context.interactionSelectEdit = new SelectInteraction({ - condition : eventSingleClick, - layers : [this.layer], - features : this.featuresCollectionSelected - }); - context.interactionSelectEdit.on("select", (e) => { - // ... - }); - context.interactionSelectEdit.setProperties({ - name : "Drawing", - source : context - }); - map.addInteraction(context.interactionSelectEdit); - - context.interactionCurrent = new ModifyInteraction({ - stopClick : true, - // features : context.layer.getSource().getFeaturesCollection(), - features : this.interactionSelectEdit.getFeatures(), - style : new Style({ - image : new Circle({ - radius : this.options.cursorStyle.radius, - stroke : new Stroke({ - color : this.options.cursorStyle.strokeColor, - width : this.options.cursorStyle.strokeWidth - }), - fill : new Fill({ - color : this.options.cursorStyle.fillColor - }) - }) - }) - // deleteCondition : function (/* event */) { return false }, - // insertVertexCondition : function (/* event */) { return false } - }); - context.interactionCurrent.on("modifyend", (deEv) => { - var feature = deEv.features.item(0); - context._updateMeasure(feature); - }); - } - break; - case this._addUID("drawing-tool-display"): - if (context.dtOptions["display"].active) { - context.interactionCurrent = this._createStylingInteraction(); - } - break; - case this._addUID("drawing-tool-tooltip"): - - if (context.dtOptions["tooltip"].active) { - context.interactionCurrent = this._createLabelInteraction(); - } - break; - case this._addUID("drawing-tool-remove"): - if (context.dtOptions["remove"].active) { - context.interactionCurrent = context._createRemoveInteraction(); - } - break; - default: - logger.trace("unhandled tool type"); - } - if (context.interactionCurrent) { - context.interactionCurrent.setProperties({ - name : "Drawing", - source : this - }); - map.addInteraction(context.interactionCurrent); - } - logger.log("interactions", map.getInteractions()); - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - - /** - * this method is called by event 'click' on 'GPshowDrawingPicto' tag label - * (cf. this._createShowDrawingPictoElement), - * and toggles event 'mousemove' on map. - * - * @method onShowDrawingClick - * @private - */ - onShowDrawingClick () { - var map = this.getMap(); - // on supprime toutes les interactions - Interactions.unset(map); - - var opened = this._showDrawingButton.ariaPressed; - this.collapsed = !(opened === "true");// on génère nous même l'evenement OpenLayers de changement de propriété - // (utiliser mousePosition.on("change:collapsed", function(e) ) pour s'abonner à cet évènement) - this.dispatchEvent("change:collapsed"); - - // on deselectionne les Tools - for (var toolsType in this.dtOptions) { - if (this.dtOptions.hasOwnProperty(toolsType)) { - if (this.dtOptions[toolsType].active) { - var toolsId = this._addUID("drawing-tool-" + this.dtOptions[toolsType].id); - document.getElementById(toolsId).className = "drawing-tool"; - this.dtOptions[toolsType].active = false; - } - } - } - } - - /** - * this method is called by event 'click' on 'drawing-export' tag button. - * - * @method onExportFeatureClick - * @private - */ - onExportFeatureClick () { - var content = this.exportFeatures(); - if (!content) { - return; - } - var link = document.createElement("a"); - // FIXME : determiner le bon charset ! - var charset = "utf-8"; - link.setAttribute("href", "data:" + this._exportMimeType + ";charset=" + charset + "," + encodeURIComponent(content)); - link.setAttribute("download", this.getExportName() + this._exportExt); - if (document.createEvent) { - var event = document.createEvent("MouseEvents"); - event.initEvent("click", true, true); - link.dispatchEvent(event); - } else { - link.click(); - } - } - -}; - -// on récupère les méthodes de la classe commune Drawing -Object.assign(Drawing.prototype, DrawingDOM); - -export default Drawing; - -// Expose Drawing as ol.control.Drawing (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.Drawing = Drawing; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/DrawingDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/DrawingDOM.d.ts deleted file mode 100644 index 00a145531..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/DrawingDOM.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default DrawingDOM; -declare var DrawingDOM: any; -//# sourceMappingURL=DrawingDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/DrawingDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/DrawingDOM.d.ts.map deleted file mode 100644 index 2cdb721f7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/DrawingDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"DrawingDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Drawing/DrawingDOM.js"],"names":[],"mappings":";AAIA,4BAqtBE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/DrawingDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/DrawingDOM.js deleted file mode 100644 index bcea066d3..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Drawing/DrawingDOM.js +++ /dev/null @@ -1,732 +0,0 @@ -import Logger from "../../Utils/LoggerByDefault"; - -var logger = Logger.getLogger("DrawingDOM"); - -var DrawingDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Main container (DOM) - * - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPdrawing"); - container.className = "GPwidget gpf-widget gpf-widget-button"; - return container; - }, - - // ################################################################### // - // ################### Methods of main container ##################### // - // ################################################################### // - - /** - * Show mouse position control - * - * @returns {DOMElement} DOM element - */ - _createShowDrawingPictoElement : function () { - var self = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowDrawingPicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto GPshowDrawingPicto gpf-btn gpf-btn-icon gpf-btn-icon-drawing fr-btn"; - button.title = this.options.labels.control; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - - // gestionnaire d'evenement : - // on ouvre le menu de saisie de saisie - // L'ouverture/Fermeture permet de faire le menage - // (reinitialisation) - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onShowDrawingClick(e); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onShowDrawingClick(e); - }); - } - - return button; - }, - - /** - * Drawing panel - * - * @returns {DOMElement} DOM element - */ - _createDrawingPanelElement : function () { - var dialog = document.createElement("dialog"); - dialog.id = this._addUID("GPdrawingPanel"); - dialog.className = "GPpanel gpf-panel fr-modal"; - - return dialog; - }, - - _createDrawingPanelDivElement : function () { - var div = document.createElement("div"); - div.className = "gpf-panel__body fr-modal__body"; - return div; - }, - - _createDrawingToolsDivSections : function () { - var div = document.createElement("div"); - div.className = "gpf-panel__content fr-modal__content"; - return div; - }, - - // ################################################################### // - // ####################### Panel container ########################### // - // ################################################################### // - - /** - * Creates drawing Panel header DOM structure - * @returns {DOMElement} DOM element - */ - _createDrawingPanelHeaderElement : function () { - /* - *
- *
Annoter la carte
- *
- *
- */ - - var container = document.createElement("div"); - container.className = "GPpanelHeader gpf-panel__header fr-modal__header fr-m-1w"; - - var divTitle = document.createElement("div"); - divTitle.className = "GPpanelTitle gpf-panel__title fr-modal__title fr-m-1w"; - divTitle.innerHTML = this.options.controlLabel || "Annoter la carte"; - container.appendChild(divTitle); - - var divClose = document.createElement("button"); - divClose.id = this._addUID("GPdrawingPanelClose"); - divClose.className = "GPpanelClose GPdrawingPanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--secondary fr-m-1w"; - divClose.title = "Fermer le panneau"; - - // Link panel close / visibility checkbox - var dtObj = this; - if (divClose.addEventListener) { - divClose.addEventListener("click", function () { - document.getElementById(dtObj._addUID("GPshowDrawingPicto")).click(); - }, false); - } else if (divClose.attachEvent) { - divClose.attachEvent("onclick", function () { - document.getElementById(dtObj._addUID("GPshowDrawingPicto")).click(); - }); - } - - var span = document.createElement("span"); - span.className = "GPelementHidden gpf-visible"; // afficher en dsfr - span.innerText = "Fermer"; - - divClose.appendChild(span); - - container.appendChild(divClose); - - return container; - }, - - /** - * Creates drawing tools section. - * - * @returns {DOMElement} DOM element - */ - _createDrawingToolsSections : function () { - var tools = []; - - this.dtOptions = {}; - if (this.options.tools.points) { - this.dtOptions.points = { - label : this.options.labels.points, - active : false, - panel : "draw", - id : "point" - }; - } - if (this.options.tools.lines) { - this.dtOptions.lines = { - label : this.options.labels.lines, - active : false, - panel : "draw", - id : "line" - }; - } - if (this.options.tools.polygons) { - this.dtOptions.polygons = { - label : this.options.labels.polygons, - active : false, - panel : "draw", - id : "polygon" - }; - } - if (this.options.tools.holes) { - this.dtOptions.holes = { - label : this.options.labels.holes, - active : false, - panel : "draw", - id : "holes" - }; - } - if (this.options.tools.text) { - this.dtOptions.text = { - label : this.options.labels.text, - active : false, - panel : "draw", - id : "text" - }; - } - if (this.options.tools.edit) { - this.dtOptions.edit = { - label : this.options.labels.edit, - active : false, - panel : "edit", - id : "edit" - }; - } - if (this.options.tools.display) { - this.dtOptions.display = { - label : this.options.labels.display, - active : false, - panel : "edit", - id : "display" - }; - } - if (this.options.tools.tooltip) { - this.dtOptions.tooltip = { - label : this.options.labels.tooltip, - active : false, - panel : "edit", - id : "tooltip" - }; - } - if (this.options.tools.remove) { - this.dtOptions.remove = { - label : this.options.labels.remove, - active : false, - panel : "edit", - id : "remove" - }; - } - // ajout drawing tools - if (this.dtOptions.points || - this.dtOptions.lines || - this.dtOptions.polygons || - this.dtOptions.text) { - tools.push(this._createDrawingToolSection(this.options.labels.creatingTools, "draw")); - } - // ajout editing tools - if (this.dtOptions.edit || - this.dtOptions.display || - this.dtOptions.tooltip || - this.dtOptions.remove) { - tools.push(this._createDrawingToolSection(this.options.labels.editingTools, "edit")); - } - // ajout export tools - if (this.options.tools.export) { - tools.push(this._createSavingSection( - this.options.labels.export, - this.options.labels.exportTitle - )); - } - - return tools; - }, - - /** - * Creates drawing tool section DOM structure. - * - * @param {String} sectionLabel - section title - * @param {String} panelType - Drawing ("draw") or editing ("edit") tools panel - * @returns {DOMElement} DOM element - */ - _createDrawingToolSection : function (sectionLabel, panelType) { - /* - * Exemple panelType == "draw" - * - *
- *

Outils de création

- *
    - *
  • - *
  • - *
  • - *
  • - *
- *
- */ - var container = document.createElement("div"); - container.className = "drawing-tool-section fr-m-1w"; - - var p = document.createElement("p"); - p.className = "drawing-tool-section-title fr-m-1w"; - p.innerHTML = sectionLabel; - container.appendChild(p); - - var ul = document.createElement("ul"); - ul.className = "drawing-tools-flex-display fr-m-1w"; - var context = this; - // li click handler function - function liClickHandler (e) { - /* jshint validthis: true */ - // this == elem clicked - context._handleDOMToolClick(e, this.id, context); - context._handleToolClick(e, this.id, context); - } - for (var type in this.dtOptions) { - if (this.dtOptions[type].panel !== panelType) { - continue; - } - var li = document.createElement("li"); - li.className = "drawing-tool fr-m-1w"; - li.id = this._addUID("drawing-tool-" + this.dtOptions[type].id); - li.title = this.dtOptions[type].label; - li.addEventListener("click", liClickHandler); - ul.appendChild(li); - } - container.appendChild(ul); - - return container; - }, - - /** - * Creates drawing tool section DOM structure. - * - * @param {String} buttonLabel - Button label - * @param {String} buttonTitle - Button title - * @returns {DOMElement} DOM element - */ - _createSavingSection : function (buttonLabel, buttonTitle) { - /* - *
- * - *
- */ - var container = document.createElement("div"); - container.className = "drawing-tool-section drawing-tools-flex-display fr-m-1w"; - - var button = document.createElement("button"); - button.title = buttonTitle; - button.className = "tool-form-submit drawing-button fr-btn fr-btn--secondary fr-m-1w"; - button.id = this._addUID("drawing-export"); - button.type = "button"; - button.textContent = buttonLabel; - var context = this; - /** export function */ - button.onclick = function () { - context.onExportFeatureClick(); - }; - container.appendChild(button); - - return container; - }, - - /** - * Creates input for color choosing - * - * @param {Object} options - options - * @param {String} options.defaultValue - defaultValue - * @param {String} options.className - input className - * @returns {DOMElement} - created li element - */ - _createMarkersChooser : function (options) { - var li = document.createElement("li"); - li.className = options.className; - for (var i = 0; i < this.options.markersList.length; i++) { - // radio bouton pour la selection - var inputElem = document.createElement("input"); - inputElem.type = "radio"; - inputElem.name = "marker"; - inputElem.id = this._addUID("marker-" + i); - inputElem.value = this.options.markersList[i].src; - inputElem.className = "marker-input-radio"; - if (options.defaultValue === inputElem.value) { - inputElem.checked = true; - } - li.appendChild(inputElem); - // label pour l'affichage du marker - var labelElem = document.createElement("label"); - labelElem.className = "marker-label"; // utile ? - labelElem.setAttribute("for", inputElem.id); - var imgElem = document.createElement("img"); - imgElem.src = inputElem.value; - labelElem.appendChild(imgElem); - li.appendChild(labelElem); - } - return li; - }, - - /** - * Creates input for color choosing - * - * @param {Object} options - options - * @param {String} options.label - label - * @param {String} options.type - input type for element ("color") - * @param {String} options.defaultValue - defaultValue - * @param {String} options.id - input id - * @param {String} options.title - input title - * @param {String} options.className - input className - * @returns {DOMElement} - created li element - */ - _createStylingElement : function (options) { - var li = document.createElement("li"); - li.className = options.className; - var textNode = document.createTextNode(options.label); - li.appendChild(textNode); - var inputElem = document.createElement("input"); - try { - inputElem.type = options.type; - } catch (e) { - // ie 11 input type== color ne marche pas... - inputElem.type = "text"; - } - inputElem.id = options.id; - inputElem.value = options.defaultValue; - if (options.title) { - inputElem.title = options.title; - } - // si options.type == "checkbox" - if (options.checked !== undefined) { - inputElem.checked = options.checked; - } - // si options.type == "range" - if (options.min !== undefined) { - inputElem.min = options.min; - } - if (options.max !== undefined) { - inputElem.max = options.max; - } - if (options.step !== undefined) { - inputElem.step = options.step; - } - li.appendChild(inputElem); - return li; - }, - - /** - * Creates Styling div to include in popup. - * - * @param {Object} options - toolId selected - * @param {String} options.geomType - gemeotryType selected ("Point", "Line" or "Polygon") - * @param {Object} options.labels - values to title - * @param {Object} options.initValues - values to init fields - * @param {Function} options.applyFunc - function called when apply is selected - * @returns {DOMElement} DOM element created - */ - _createStylingDiv : function (options) { - var div = document.createElement("div"); - div.className = "gp-styling-div"; - var ul = document.createElement("ul"); - var li = null; - /* - * TODO : finir de remplir la div pour tous les styles éditables. - */ - var geomType = options.geomType.toLowerCase(); - switch (geomType) { - case "point&text": - case "point": - li = this._createMarkersChooser({ - className : "gp-styling-option", - // defaultValue : this.options.markersList[0].src - defaultValue : options.initValues.markerSrc - }); - ul.appendChild(li); - li = this._createStylingElement({ - type : "range", - className : "gp-styling-option", - label : this.options.labels.markerSize, - title : "petit, moyen ou grand", - id : this._addUID("markerSize"), - min : 5, - max : 15, - step : 5, - defaultValue : options.initValues.markerSize * 10 - }); - ul.appendChild(li); - // EVOL - // proposer une palette de couleur pour peindre un pictogramme monochrome - // li = this._createStylingElement({ - // type : "color", - // className : "gp-styling-option", - // label : this.options.labels.markerColor, - // id : this._addUID("markerColor"), - // defaultValue : options.initValues.markerColor - // }); - // ul.appendChild(li); - if (options.initValues.markerCustom) { - // FIXME que faire des icones customisés ? - } - if (geomType === "point&text") { - li = this._createStylingElement({ - type : "checkbox", - className : "gp-styling-option", - label : this.options.labels.labelDisplay, - id : this._addUID("labelDisplay"), - checked : options.initValues.labelDisplay, - defaultValue : options.initValues.labelDisplay - }); - ul.appendChild(li); - } - break; - case "text": - li = this._createStylingElement({ - type : "color", - className : "gp-styling-option", - label : this.options.labels.fillColor, - id : this._addUID("fillColor"), - defaultValue : options.initValues.fillColor - }); - ul.appendChild(li); - li = this._createStylingElement({ - type : "color", - className : "gp-styling-option", - label : this.options.labels.strokeColor, - id : this._addUID("strokeColor"), - defaultValue : options.initValues.strokeColor - }); - ul.appendChild(li); - li = this._createStylingElement({ - type : "range", - className : "gp-styling-option", - label : this.options.labels.strokeWidth, - title : "1 à 10 pixels", - id : this._addUID("strokeWidth"), - min : 1, - max : 10, - step : 1, - defaultValue : options.initValues.strokeWidth - }); - ul.appendChild(li); - break; - case "line": - li = this._createStylingElement({ - type : "color", - className : "gp-styling-option", - label : this.options.labels.strokeColor, - id : this._addUID("strokeColor"), - defaultValue : options.initValues.strokeColor - }); - ul.appendChild(li); - li = this._createStylingElement({ - type : "range", - className : "gp-styling-option", - label : this.options.labels.strokeWidth, - title : "1 à 10 pixels", - id : this._addUID("strokeWidth"), - min : 1, - max : 10, - step : 1, - defaultValue : options.initValues.strokeWidth - }); - ul.appendChild(li); - break; - case "polygon": - li = this._createStylingElement({ - type : "color", - className : "gp-styling-option", - label : this.options.labels.strokeColor, - id : this._addUID("strokeColor"), - defaultValue : options.initValues.strokeColor - }); - ul.appendChild(li); - li = this._createStylingElement({ - type : "range", - className : "gp-styling-option", - label : this.options.labels.strokeWidth, - title : "1 à 10 pixels", - id : this._addUID("strokeWidth"), - min : 1, - max : 10, - step : 1, - defaultValue : options.initValues.strokeWidth - }); - ul.appendChild(li); - li = this._createStylingElement({ - type : "color", - className : "gp-styling-option", - label : this.options.labels.fillColor, - id : this._addUID("fillColor"), - defaultValue : options.initValues.fillColor - }); - ul.appendChild(li); - li = this._createStylingElement({ - type : "range", - className : "gp-styling-option", - label : this.options.labels.fillOpacity, - title : "0 (transparent) à 100% (opaque)", - id : this._addUID("fillOpacity"), - min : 0, - max : 10, - step : 1, - defaultValue : options.initValues.fillOpacity * 10 - }); - ul.appendChild(li); - break; - default: - logger.log("Unhandled geometry type for styling."); - } - div.appendChild(ul); - // apply button - var applyButton = document.createElement("input"); - applyButton.type = "button"; - applyButton.className = "gp-styling-button"; - applyButton.value = this.options.labels.applyToObject; - /** click sur applyButton */ - applyButton.onclick = function () { - options.applyFunc.call(this, "apply"); - }; - div.appendChild(applyButton); - // set default button - var setDefaultButton = document.createElement("input"); - setDefaultButton.type = "button"; - setDefaultButton.value = this.options.labels.setAsDefault; - setDefaultButton.className = "gp-styling-button"; - /** click sur set Default Button */ - setDefaultButton.onclick = function () { - options.applyFunc.call(this, "default"); - }; - div.appendChild(setDefaultButton); - // cancel Button - var cancelButton = document.createElement("input"); - cancelButton.type = "button"; - // cancelButton.value = "X" ; - cancelButton.className = "gp-styling-button closer"; - /** click sur cancel Button */ - cancelButton.onclick = function () { - options.applyFunc.call(this, "cancel"); - }; - div.appendChild(cancelButton); - return div; - }, - - /** - * Creates Text editing div to include in popup. - * - * @param {Object} options - options for popup - * @param {String} options.geomType - gemeotryType selected ("Point", "Line" or "Polygon") - * @param {String} options.text - text to fill input. - * @param {String} options.key - property name called when text is to be saved. - * @param {String} options.measure - measure to fill input. - * @param {String} options.placeholder - placeholder for text input. - * @param {String} options.inputId - text input id. - * @param {Function} options.applyFunc - function called when text is to be saved. - * @returns {DOMElement} DOM element created - * @private - */ - _createLabelDiv : function (options) { - var popup = document.createElement("div"); - popup.className = "gp-label-div"; - var inputLabel = null; - if (options.geomType === "Text") { - inputLabel = document.createElement("input"); - inputLabel.type = "text"; - inputLabel.className = "gp-input-label-style"; - } else { - inputLabel = document.createElement("textArea"); - inputLabel.rows = 2; - inputLabel.cols = 40; - inputLabel.className = "gp-textarea-att-label-style"; - } - - if (options.text) { - inputLabel.value = options.text; - } - - inputLabel.autocomplete = "off"; - inputLabel.placeholder = options.placeholder; - inputLabel.id = options.inputId; - popup.appendChild(inputLabel); - // blur - inputLabel.onblur = function () { - options.applyFunc.call(this, options.key, inputLabel.value, true); - }; - // keyup - inputLabel.onkeyup = function (evtk) { - if (options.geomType === "Text" && evtk.keyCode === 13) { - options.applyFunc.call(this, options.key, inputLabel.value, true); - } - if (evtk.keyCode === 27) { - options.applyFunc.call(this, options.key, inputLabel.value, false); - } - }; - - if (options.measure && options.geomType !== "Text") { - var inputMeasure = document.createElement("input"); - inputMeasure.type = "text"; - inputMeasure.readonly = true; - inputMeasure.className = "gp-input-measure-style"; - inputMeasure.value = options.measure; - popup.appendChild(inputMeasure); - } - - if (options.geomType !== "Text") { - // apply button - var applyButton = document.createElement("input"); - applyButton.type = "button"; - applyButton.className = "gp-styling-button"; - applyButton.value = this.options.labels.saveDescription; - /** click sur applyButton */ - applyButton.onclick = function () { - options.applyFunc.call(this, options.key, inputLabel.value, true); - }; - popup.appendChild(applyButton); - // cancel Button - var cancelButton = document.createElement("input"); - cancelButton.type = "button"; - cancelButton.className = "gp-styling-button closer"; - /** click sur cancel Button */ - cancelButton.onclick = function () { - options.applyFunc.call(this, options.key, inputLabel.value, false); - }; - popup.appendChild(cancelButton); - } - - return popup; - }, - - /** - * Handles drawing tool selection from a DOM point of view. - * - * @param {Event} e - DOM Event - * @param {String} toolId - toolId selected - * @param {DrawingDOM} context - Drawing control instance - */ - _handleDOMToolClick : function (e, toolId, context) { - for (var availType in context.dtOptions) { - var availToolId = context._addUID("drawing-tool-" + context.dtOptions[availType].id); - var li = document.getElementById(availToolId); - // ce n'est pas l'outil selectionne : on le desactive (s'il ne l'était pas déjà). - if (availToolId !== toolId) { - li.className = "drawing-tool"; - context.dtOptions[availType].active = false; - continue; - } - // ici, c'est le l'outil selectionne - if (context.dtOptions[availType].active) { - li.className = "drawing-tool"; - } else { - li.className = "drawing-tool drawing-tool-active"; - } - context.dtOptions[availType].active = !context.dtOptions[availType].active; - } - } - -}; - -export default DrawingDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Editor.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Editor.d.ts deleted file mode 100644 index 3ad7649a6..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Editor.d.ts +++ /dev/null @@ -1,257 +0,0 @@ -export default Editor; -/** - * @classdesc - * - * Editor Styles MapBox... - * - * @constructor - * @alias ol.style.Editor - * @param {Object} options - options for function call. - * @fires editor:layer:onclickvisibility - * @fires editor:layer:onclickclone - * @fires editor:layer:onclickremove - * @fires editor:style:oneditjson - * @fires editor:style:scale:onchangemin - * @fires editor:style:scale:onchangemax - * @fires editor:legend:onclickedition - * @fires editor:legend:onchangevalue - * @fires editor:filter:oneditjson - * @fires editor:themes:onclickimage - * @fires editor:themes:onclicktitle - * @fires editor:group:oncollapse - * @fires editor:onloaded - * @example - * var editor = new Editor ({ - * target : "", - * style : "data/styles/layer.json", - * themes: { - * themesSummary : "", - * themes : [{ - * "thumbnail": "data/images/layer0.png", - * "name": "standard0", - * "url": "data/styles/layer0.json", - * "description": "", - * "selected" : true - * },{ - * "thumbnail": "data/images/layer1.png", - * "name": "standard1", - * "url": "data/styles/layer1.json", - * "description": "" - * }] - * }, - * scope : this, - * events : { - * "editor:layer:onclickvisibility" : ..., - * "editor:layer:onclickclone" : ..., - * "editor:layer:onclickremove" : ..., - * "editor:style:oneditjson" : ..., - * "editor:style:scale:onchangemin" : ..., - * "editor:style:scale:onchangemax" : ..., - * "editor:filter:oneditjson" : ..., - * "editor:themes:onclickimage" : this._onClickEventImageTheme(), - * "editor:themes:onclicktitle" : function(e) {...} - * }, - * tools : { - * // afficher/cacher les themes (par defaut) ou utiliser les options - * themes : true | false | { - * target : "...", - * tools : { - * "thumbnails": true, - * "button": { visible : true, type : "checkbox" } - * }, - * }, - * layers : true | false, // afficher les couches (layers) - * search : true | false, // TODO : afficher l'outil de recheche de couches - * style : true | false, // afficher les styles (sous menu layers) - * filter : true | false, // afficher les filtres (sous menu layers) - * legend : true | false, // afficher les legendes (layers) - * group : true | false, // grouper les couches, l'option 'sort' doit être activée (layers) - * groupAuto : true | false, // definir la construction automatiques des groupes - * sort : true | false, // trier les couches (layers) - * sortBy : "id|class|geom", // definir le type de tri (layers) - * sortOrder : "asc, desc", // definir l'ordre de tri (layers) - * title : true | false // afficher les titres des rubriques, - * collapse : true | false | undefined // afficher et/ou plier les couches ou ne pas afficher l'option, - * type : true | false, // afficher le type de geometrie (layers) - * pin : true | false, // afficher la puce pour chaque couche (layers) - * visibility : true | false, // afficher l'icone de visibilité (layers), - * icon : { // afficher l'icone "oeil" ou "checkbox" (layers), - * "image" : true, - * "anchor" : "start" // afficher l'icone au debut ou à la fin de la ligne - * }, - * editable : true | false // active l'edition de la legende (legendes) - * } - * }); - * // options par defaut - * { - * themes : false, - * layers : true, - * search : false, - * style : false, - * filter : false, - * legend : false, - * group : false, - * groupAuto : false, - * sort : true, - * sortBy : "id", - * sortOrder : "asc", - * title : true, - * collapse : undefined, - * type : true, - * pin : true, - * visibility : true, - * icon : { - * image : true, - * anchor : "end" - * }, - * editable : true - * } - * // Context - * editor.setContext("map", map); - * editor.setContext("layer", layer); - * // create DOM - * editor.createElement() - * .then(() => { - * console.warn(editor.getID()); - * console.log(this.getContext("map")); - * console.log(this.getContext("layer")); - * }) - * .catch(error => {}); - * // possibility to add listeners with globale variable : eventbus - * eventbus.addEventListener("editor:style:scale:onchangemin", function (e) {...}); - */ -declare class Editor { - constructor(options: any); - options: any; - /** - * Initialize component - * (called by constructor) - * - * @private - */ - private _initialize; - id: any; - context: {} | undefined; - layers: any[] | undefined; - container: HTMLDivElement | null | undefined; - name: { - target: string; - container: string; - containerID: string; - containerLayers: string; - titleLayers: string; - titleLayersID: string; - titleThemes: string; - titleThemesID: string; - sep: string; - } | undefined; - mapbox: any; - sprites: {} | undefined; - /** - * Initialize events with handlers - * (called by constructor) - * - * List Events : - * "editor:layer:visibility" - * "editor:layer:clone" - * "editor:layer:remove" - * "editor:style:edit" - * "editor:style:minScale" - * "editor:style:maxScale" - * "editor:filter:edit" - * "editor:themes:image", - * "editor:themes:title" - * @private - */ - private _initEvents; - /** - * Graphical rendering of the component - * (called by constructor) - * - * @example - *
- *
Liste des 'thèmes'
- *
- * ... - *
- *
Liste des 'couches'
- *
- *
- *
- * - * - * - *
- *
- *
...
- *
...
- *
- *
- * @private - */ - private _initContainer; - /** - * Getting Sprites informations - * (called by _initialize) - * - * @param {String} sprites - url des sprites - * @returns {Promise} - promise - * @private - */ - private _getSprites; - /** - * Create Editor - * - * @returns {Promise} - promise - */ - createElement(): Promise; - /** - * Set display container (DOM) - * - * @param {Boolean} display - show/hidden container - */ - display(display: boolean): void; - setContext(key: any, value: any): void; - getContext(key: any): any; - /** - * Get id editor - * @returns {Number} id - */ - getID(): number; - /** - * Get container (DOM) - * @returns {DOMElement} DOM element - */ - getContainer(): DOMElement; - /** - * Get Style (json) - * @returns {Object} Style MapBox - */ - getStyle(): Object; - /** - * Get layer style (json) - * @param {Number} i - index - * @returns {Object} Style MapBox of a layers - */ - getStyleLayer(i: number): Object; - /** - * Get layer object from json style - * @param {Number} i - index into style json - * @returns {Object} Style MapBox of a layers - */ - getLayerFromStyle(i: number): Object; - /** - * Get a list of layer object sorted or not (see options.tools.sort) - * @returns {Array} - List of layer object - * @see {ol.style.editor.Layer} - */ - getLayers(): any[]; - /** - * Get the layer object from a list sorted or not (see options.tools.sort) - * @param {Number} i - index - * @returns {Object} - layer object - * @see {ol.style.editor.Layer} - */ - getLayer(i: number): Object; -} -//# sourceMappingURL=Editor.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Editor.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Editor.d.ts.map deleted file mode 100644 index 5dc3c0e48..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Editor.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Editor/Editor.js"],"names":[],"mappings":";AAuBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwHG;AACH;IAEI,0BAaC;IATG,aAEC;IASL;;;;;OAKG;IACH,oBAuFC;IAjCG,QAA0C;IAG1C,wBAAiB;IAEjB,0BAAgB;IAEhB,6CAAqB;IAErB;;;;;;;;;;kBAUC;IAED,YAAgB;IAWhB,wBAAiB;IAGrB;;;;;;;;;;;;;;;MAeE;IACF,oBAgBC;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,uBAuZC;IAED;;;;;;;OAOG;IACH,oBAuFC;IAKD;;;;OAIG;IACH,8BA8DC;IAED;;;;OAIG;IACH,gCAEC;IAED,uCAEC;IAED,0BAEC;IAKD;;;OAGG;IACH,gBAEC;IAED;;;OAGG;IACH,2BAEC;IAED;;;OAGG;IACH,YAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,0BAFa,MAAM,CAclB;IAED;;;;OAIG;IACH,8BAFa,MAAM,CAalB;IAED;;;;OAIG;IACH,mBAEC;IAED;;;;;OAKG;IACH,qBAHa,MAAM,CAKlB;CAEJ"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Editor.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Editor.js deleted file mode 100644 index 6351de78c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Editor.js +++ /dev/null @@ -1,1008 +0,0 @@ -// import CSS -import "../../CSS/Controls/Editor/GPFeditor.css"; -// import "../../CSS/Controls/Editor/GPFeditorStyle.css"; -// import library -import EventBus from "eventbusjs"; -// import local -import Utils from "../../Utils/Helper"; -import ID from "../../Utils/SelectorID"; -import Logger from "../../Utils/LoggerByDefault"; -import Style from "./Style"; -import Themes from "./Themes"; -import Filter from "./Filter"; -import Legend from "./Legend"; -import Layer from "./Layer"; -import Group from "./Group"; -import Event from "./Event"; -import Search from "./Search"; - -// DOM -import EditorDOM from "./EditorDOM"; - -var logger = Logger.getLogger("editor"); - -/** - * @classdesc - * - * Editor Styles MapBox... - * - * @constructor - * @alias ol.style.Editor - * @param {Object} options - options for function call. - * @fires editor:layer:onclickvisibility - * @fires editor:layer:onclickclone - * @fires editor:layer:onclickremove - * @fires editor:style:oneditjson - * @fires editor:style:scale:onchangemin - * @fires editor:style:scale:onchangemax - * @fires editor:legend:onclickedition - * @fires editor:legend:onchangevalue - * @fires editor:filter:oneditjson - * @fires editor:themes:onclickimage - * @fires editor:themes:onclicktitle - * @fires editor:group:oncollapse - * @fires editor:onloaded - * @example - * var editor = new Editor ({ - * target : "", - * style : "data/styles/layer.json", - * themes: { - * themesSummary : "", - * themes : [{ - * "thumbnail": "data/images/layer0.png", - * "name": "standard0", - * "url": "data/styles/layer0.json", - * "description": "", - * "selected" : true - * },{ - * "thumbnail": "data/images/layer1.png", - * "name": "standard1", - * "url": "data/styles/layer1.json", - * "description": "" - * }] - * }, - * scope : this, - * events : { - * "editor:layer:onclickvisibility" : ..., - * "editor:layer:onclickclone" : ..., - * "editor:layer:onclickremove" : ..., - * "editor:style:oneditjson" : ..., - * "editor:style:scale:onchangemin" : ..., - * "editor:style:scale:onchangemax" : ..., - * "editor:filter:oneditjson" : ..., - * "editor:themes:onclickimage" : this._onClickEventImageTheme(), - * "editor:themes:onclicktitle" : function(e) {...} - * }, - * tools : { - * // afficher/cacher les themes (par defaut) ou utiliser les options - * themes : true | false | { - * target : "...", - * tools : { - * "thumbnails": true, - * "button": { visible : true, type : "checkbox" } - * }, - * }, - * layers : true | false, // afficher les couches (layers) - * search : true | false, // TODO : afficher l'outil de recheche de couches - * style : true | false, // afficher les styles (sous menu layers) - * filter : true | false, // afficher les filtres (sous menu layers) - * legend : true | false, // afficher les legendes (layers) - * group : true | false, // grouper les couches, l'option 'sort' doit être activée (layers) - * groupAuto : true | false, // definir la construction automatiques des groupes - * sort : true | false, // trier les couches (layers) - * sortBy : "id|class|geom", // definir le type de tri (layers) - * sortOrder : "asc, desc", // definir l'ordre de tri (layers) - * title : true | false // afficher les titres des rubriques, - * collapse : true | false | undefined // afficher et/ou plier les couches ou ne pas afficher l'option, - * type : true | false, // afficher le type de geometrie (layers) - * pin : true | false, // afficher la puce pour chaque couche (layers) - * visibility : true | false, // afficher l'icone de visibilité (layers), - * icon : { // afficher l'icone "oeil" ou "checkbox" (layers), - * "image" : true, - * "anchor" : "start" // afficher l'icone au debut ou à la fin de la ligne - * }, - * editable : true | false // active l'edition de la legende (legendes) - * } - * }); - * // options par defaut - * { - * themes : false, - * layers : true, - * search : false, - * style : false, - * filter : false, - * legend : false, - * group : false, - * groupAuto : false, - * sort : true, - * sortBy : "id", - * sortOrder : "asc", - * title : true, - * collapse : undefined, - * type : true, - * pin : true, - * visibility : true, - * icon : { - * image : true, - * anchor : "end" - * }, - * editable : true - * } - * // Context - * editor.setContext("map", map); - * editor.setContext("layer", layer); - * // create DOM - * editor.createElement() - * .then(() => { - * console.warn(editor.getID()); - * console.log(this.getContext("map")); - * console.log(this.getContext("layer")); - * }) - * .catch(error => {}); - * // possibility to add listeners with globale variable : eventbus - * eventbus.addEventListener("editor:style:scale:onchangemin", function (e) {...}); - */ -class Editor { - - constructor (options) { - logger.trace("[constructor] Editor", options); - - // options - this.options = options || { - // TODO default... - }; - - if (!(this instanceof Editor)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this._initialize(); - } - - /** - * Initialize component - * (called by constructor) - * - * @private - */ - _initialize () { - // gestion des options - if (!this.options.target) { - logger.info("La 'target' n'est pas renseignée (options.target)."); - } - - if (!this.options.style) { - logger.error("Le 'style' MapBox n'est pas renseigné (options.style) !"); - return; - } - - if (this.options.events) { - this._initEvents(); - } else { - logger.warn("Les 'handlers' ne sont pas renseignés (options.events) !"); - } - - if (!this.options.themes) { - logger.info("Les 'themes' MapBox ne sont pas renseignés (options.themes)."); - } - - // options par defaut - var _toolsDefault = { - themes : false, - layers : true, - search : false, - style : false, - filter : false, - legend : false, - group : false, - groupAuto : false, - sort : true, - sortBy : "id", - sortOrder : "asc", - title : true, - collapse : undefined, - type : true, - pin : true, - visibility : true, - icon : { - image : true, - anchor : "end" - }, - editable : true - }; - - if (!this.options.tools) { - logger.trace("Utilisation des outils MapBox par défaut (options.tools)."); - this.options.tools = _toolsDefault; - } - - Utils.mergeParams(this.options.tools, _toolsDefault, false); - - // id unique - this.id = this.options.id || ID.generate(); - - // context - this.context = {}; - // property layers - this.layers = []; - // dom container - this.container = null; - // dom name - this.name = { - target : "GPEditorMapBoxTarget", - container : "GPEditorMapBoxContainer", - containerID : "GPEditorMapBoxContainer_ID_", - containerLayers : "GPEditorMapBoxLayersContainer", - titleLayers : "GPEditorMapBoxLayersTitle", - titleLayersID : "GPEditorMapBoxLayersTitle_ID_", - titleThemes : "GPEditorMapBoxThemesTitle", - titleThemesID : "GPEditorMapBoxThemesTitle_ID_", - sep : "GPEditorMapBoxSep" - }; - // style json - this.mapbox = {}; - // INFO - // sprites : - // { - // url : null, - // size : { - // h : null, - // w : null - // }, - // json : {} - // } - this.sprites = {}; - } - - /** - * Initialize events with handlers - * (called by constructor) - * - * List Events : - * "editor:layer:visibility" - * "editor:layer:clone" - * "editor:layer:remove" - * "editor:style:edit" - * "editor:style:minScale" - * "editor:style:maxScale" - * "editor:filter:edit" - * "editor:themes:image", - * "editor:themes:title" - * @private - */ - _initEvents () { - var ctx = this.options.scope || this; - var events = this.options.events; - if (events) { - for (var event in events) { - if (events.hasOwnProperty(event)) { - var handler = events[event]; - // test sur les events disponibles ! - if (handler) { - if (!EventBus.hasEventListener(event, handler, ctx)) { - EventBus.addEventListener(event, handler, ctx); - } - } - } - } - } - } - - /** - * Graphical rendering of the component - * (called by constructor) - * - * @example - *
- *
Liste des 'thèmes'
- *
- * ... - *
- *
Liste des 'couches'
- *
- *
- *
- * - * - * - *
- *
- *
...
- *
...
- *
- *
- * @private - */ - _initContainer () { - logger.trace(this.mapbox); - - // existance d'un autre container (editeur) ? - // var _idx = 0; - // var elements = document.querySelectorAll("div[id^=" + this.name.containerID + "]"); - // for (var j = 0; j < elements.length; j++) { - // var element = elements[j]; - // var num = parseInt(element.id.substring(element.id.lastIndexOf("_") + 1), 10); - // if (num > _idx) { - // _idx = num; - // } - // } - // if (elements.length) { - // _idx += 1; - // } - // container principal de l'editeur - var div = document.createElement("div"); - div.id = this.name.containerID + this.id; - div.className = this.name.container; - - // Themes - var _toolsThemes = this.options.tools.themes; - if (_toolsThemes && this.options.themes) { - // title - if (this.options.tools.title) { - var titleThemes = document.createElement("div"); - titleThemes.id = this.name.titleThemesID + this.id; - titleThemes.className = this.name.titleThemes; - titleThemes.innerHTML = "Liste des 'thèmes'"; - div.appendChild(titleThemes); - } - - // lien vers les styles - var themes = new Themes({ - id : this.id, - target : div, - tools : (typeof _toolsThemes === "object") ? _toolsThemes : {}, - obj : this.options.themes - }); - themes.add(); - } - - // TODO : Recheche / filtre de couches - if (this.options.tools.search) { - var search = new Search({ - id : this.id, - target : div, - tools : {}, - obj : this.mapbox.layers // liste des objets layers - }); - search.add(); - } - - for (var source in this.mapbox.sources) { - if (this.mapbox.sources.hasOwnProperty(source)) { - if (this.options.tools.layers) { - // multisources ? Si oui, on renseigne un titre... - var multisources = (Object.keys(this.mapbox.sources).length > 1) ? 1 : 0; - if (multisources) { - var hr = document.createElement("hr"); - hr.className = this.name.sep; - div.appendChild(hr); - } - // title - if (this.options.tools.title) { - var titleLayers = document.createElement("div"); - titleLayers.id = this.name.titleLayersID + this.id; - titleLayers.className = this.name.titleLayers; - titleLayers.innerHTML = (multisources) ? "Liste des 'couches' (" + source + ")" : "Liste des 'couches'"; - div.appendChild(titleLayers); - } - } - - // gestion de l'ordre avant tri avec la metadata 'order' - var _layers = this.mapbox.layers.slice(); // clone - - // une fois les layers triés, la metadata:geoportail:order permet - // de savoir l'emplacement du layers dans le fichier de style. - _layers.forEach(function (layer, order) { - // on écarte les layers sans source: ex. "background" - // if (!layer.source) { - // return; - // } - // ajout de la metadata d'ordre - var _metadata = layer["metadata"]; - if (_metadata) { - _metadata["geoportail:order"] = order; - } else { - layer["metadata"] = { - "geoportail:order" : order - }; - } - }); - // tri des layers - if (this.options.tools.sort) { - var sortBy = this.options.tools.sortBy; - var sortOrder = this.options.tools.sortOrder; - var sortFct = function (a, b) { - // si on utilise les groupements utilisateurs, ils doivent - // tous être renseignés sinon..., ça va coincer ! - var result = 0; - if (a["metadata"] && - a["metadata"]["geoportail:group"] && - b["metadata"] && - b["metadata"]["geoportail:group"]) { - var cmpA = null; - var cmpB = null; - cmpA = a["metadata"]["geoportail:group"]; - cmpB = b["metadata"]["geoportail:group"]; - result = cmpA.localeCompare(cmpB); - } else { - switch (sortBy) { - case "geom": - result = sortOrder === "asc" ? a.type.localeCompare(b.type) || a.id.localeCompare(b.id) - : b.type.localeCompare(a.type) || b.id.localeCompare(a.id); - break; - case "class": - result = sortOrder === "asc" ? a["source-layer"].localeCompare(b["source-layer"]) || a.id.localeCompare(b.id) - : b["source-layer"].localeCompare(a["source-layer"]) || b.id.localeCompare(a.id); - break; - case "id": - default: - // tri sur l'id par defaut - result = sortOrder === "asc" ? a.id.localeCompare(b.id) : b.id.localeCompare(a.id); - break; - } - } - return result; - }; - - _layers.sort(sortFct); - } - - logger.trace("Layers : ", _layers); - - // gestion des groupes avec la metadata de groupe - var groupBy = this.options.tools.sortBy; // le même type de tri que les couches ! - var groupAuto = this.options.tools.groupAuto; - var _groups = {}; // liste et comptage des layers dans chaque groupes - _layers.forEach(function (layer) { - // on écarte les layers sans source: ex. "background" - // if (!layer.source) { - // return; - // } - // balise metadata - var _metadata = layer["metadata"]; - // s'il existe déjà une meta de groupe, on l'utilise... - // sinon, on la met en place. - if (_metadata && _metadata["geoportail:group"]) { - var _groupName = _metadata["geoportail:group"]; - _groups[_groupName] = (_groups[_groupName]) - ? _groups[_groupName] + 1 : 1; - } else { - var _field = null; - switch (groupBy) { - case "class": - _field = layer["source-layer"]; - break; - case "geom": - _field = layer.type; - break; - case "id": - default: - _field = layer.id; - break; - } - var _newGroupName = _field; - if (groupAuto) { - // separateur - var _regex = /_|-|:|=/; // TODO à definir via une option ! - - // index - var _idx = _field.search(_regex); - // y'a t il un separateur ? - _newGroupName = (_idx !== -1) ? _field.substring(0, _idx).trim() : _field; - } - // on compte le nombre d'entrée dans un groupe - _groups[_newGroupName] = (_groups[_newGroupName]) - ? _groups[_newGroupName] + 1 : 1; - - // ajout de la metadata de groupe - if (_metadata) { - _metadata["geoportail:group"] = _newGroupName; - } else { - layer["metadata"] = { - "geoportail:group" : _newGroupName - }; - } - } - }); - - logger.trace("Groups : ", _groups); - - // container principal des couches - var divLayers = document.createElement("div"); - divLayers.className = this.name.containerLayers; - div.appendChild(divLayers); - - var details; - if (this.options.tools.collapse !== undefined) { - details = document.createElement("details"); - details.className = ""; - details.open = !this.options.tools.collapse; - divLayers.appendChild(details); - - var summary = document.createElement("summary"); - summary.className = ""; - summary.innerHTML = ""; - details.appendChild(summary); - } - - // container courant (cf. groupe) pour l'ajout des elements - var target = (this.options.tools.collapse !== undefined) ? details : divLayers; - - // Ex. Layers, Styles, Groups et Filtres - // "id": "ocs - vegetation", - // "type": "fill", - // "source": "pyramide_proto", - // "source-layer": "ocs_vegetation_surf", - // "metadata" : { - // "geoportail:group": "ocs" - // }, - // "layout": { - // "visibility": "visible" - // }, - // "filter": ["in","symbo", - // "SURFACE_D_EAU", - // "BASSIN", - // "ZONE_MARINE" - // ], - // "paint": { - // "fill-color": "#2BB3E1" - // } - var index = -1; - for (var ii = 0; ii < _layers.length; ii++) { - var data = _layers[ii]; - index++; - - // traitement dans l'ordre des sources - if (data.source === source) { - // Groups - // INFO la gestion des groupes est basée sur la balise metadata::geoportail:group - // ainsi que sur l'ordre des couches. - // il n'y a pas de regroupement sans tri des couches ! - if (this.options.tools.group && this.options.tools.sort) { - var mtd = data.metadata; - // creation du container de groupe - // si le tag metadata existe - if (mtd) { - var grp = data.metadata["geoportail:group"]; - if (grp) { - // le groupe doit contenir plus d'un element - if (_groups[grp] > 1) { - // le groupe est déjà créé, on en veut plus par la suite... - _groups[grp] = -1; - // creation du groupe - var oGroup = new Group({ - id : this.id, - target : (this.options.tools.collapse !== undefined) ? details : divLayers, - title : grp, - collapse : true - }); - oGroup.add(); - // le nouveau container pour les elements suivants - target = oGroup.getContainer(); - } else if (_groups[grp] === 1) { - // l'element est seul, donc pas d'ajout dans le - // groupe en cours - target = (this.options.tools.collapse !== undefined) ? details : divLayers; - } else { - // on ajoute l'element dans le groupe courant... - } - } else { - target = (this.options.tools.collapse !== undefined) ? details : divLayers; - } - } else { - target = (this.options.tools.collapse !== undefined) ? details : divLayers; - } - } - // Layers - if (this.options.tools.layers) { - var oLayer = new Layer({ - id : this.id, - target : target, - position : index + "_" + this.id, // unique ! - tools : { - visibility : this.options.tools.visibility, - icon : this.options.tools.icon, - type : this.options.tools.type, - pin : this.options.tools.pin - }, - obj : { - id : data.id, - type : data.type, - source : data.source, - "source-layer" : data["source-layer"] - } - }); - oLayer.add(); - // update visibility layer - if (data.layout && data.layout.visibility && data.layout.visibility === "none") { - oLayer.visibility(false); - } - // sauvegarde des layers - this.layers.push(oLayer); - } - // Legende - if (this.options.tools.legend) { - // gestion de l'edition de la legende : - // l'option "editable" est prioritaire sur le tag "editable" du fichier de style ! - var isEditable = this.options.tools.editable; - if (typeof isEditable === "undefined") { - isEditable = data.editable; - } - var oLegend = new Legend({ - id : this.id, - target : target, - sprites : this.sprites, - obj : { - id : data.id, - source : data.source, - title : data.id, - editable : (typeof isEditable !== "undefined") ? isEditable : false, - paint : data.paint, - layout : data.layout - } - }); - oLegend.add(); - oLegend.display(false); - if (oLayer) { - oLayer.addLegend(oLegend); - oLayer.slotLegend(); // integration de la legende dans le container du layers ! - } - } - // Style - if (this.options.tools.style) { - var oStyle = new Style({ - id : this.id, - target : target, - position : index + "_" + this.id, // unique !, - obj : { - id : data.id, - source : data.source, - layout : data.layout, - paint : data.paint - } - }); - oStyle.add(); - oStyle.display(false); - if (oLayer) { - oLayer.addStyle(oStyle); - } - // update visibility layer - if (data.layout && data.layout.visibility && data.layout.visibility === "none") { - oLayer.visibility(false); - } - } - // Filter - if (this.options.tools.filter) { - var oFilter = new Filter({ - id : this.id, - target : target, - position : index + "_" + this.id, // unique !, - obj : { - id : data.id, - source : data.source, - filter : data.Filter - } - }); - oFilter.add(); - oFilter.display(false); - if (oLayer) { - oLayer.addFilter(oFilter); - } - } - } else { - // on ecarte un layer car il n'est pas reconnu dans la source - // on decremente la position du layer - if (index >= 0) { - index--; - } - } - } - } - } - - // sauvegarde - this.container = div; - - // container principal - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var _target = document.createElement("div"); - _target.id = this.name.target; - var node = document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0] || - document.documentElement; - node.appendChild(_target); - } - this.options.target = document.getElementById(this.name.target); - } - if (this.container) { - this.options.target.appendChild(this.container); - } - // dispatch event - EventBus.dispatch(Event.onloaded, this); - } - - /** - * Getting Sprites informations - * (called by _initialize) - * - * @param {String} sprites - url des sprites - * @returns {Promise} - promise - * @private - */ - _getSprites (sprites) { - var self = this; - - // on ne doit pas mettre de promise en échec... - // car on souhaite continuer le traitement même si on n'a pas de sprites ! - // si le protocole est mapbox:// - if (sprites && sprites.startsWith("mapbox://")) { - return new Promise((resolve, reject) => { - logger.error("Protocole mapbox:// non géré !"); - resolve(self); - }); - } - // si pas de sprites - if (!sprites) { - return new Promise((resolve, reject) => { - logger.error("Auncun sprites disponibles !"); - resolve(self); - }); - } - - var fetchSpritesImage = function () { - var spritesImage = sprites + ".png"; - return fetch(spritesImage, { - credentials : "same-origin" - }) - .then(function (response) { - if (response.ok) { - return response.blob() - .then(function (blob) { - self.sprites.url = spritesImage; - // decode de l'image - var theImage = new Image(); - theImage.src = spritesImage; - return theImage.decode() - .then(function () { - self.sprites.size = {}; - self.sprites.size.h = theImage.height; - self.sprites.size.w = theImage.width; - }); - }) - .catch(error => { - logger.warn("fetch image sprites exception :", error); - }); - } else { - var err = new Error("HTTP status code: " + response.status); - throw err; - } - }) - .catch(error => { - return new Promise((resolve, reject) => { - logger.error("fetch image sprites exception :", error); - reject(error); - }); - }); - }; - var fetchSpritesJson = function () { - var spritesJson = sprites + ".json"; - return fetch(spritesJson, { - credentials : "same-origin" - }) - .then(function (response) { - if (response.ok) { - return response.json() - .then(function (json) { - self.sprites.json = json; - }) - .catch(error => { - logger.warn("fetch json sprites exception :", error); - }); - } else { - var err = new Error("HTTP status code: " + response.status); - throw err; - } - }) - .catch(error => { - return new Promise((resolve, reject) => { - logger.error("fetch json sprites exception :", error); - reject(error); - }); - }); - }; - - // promise - return Promise.all([ - fetchSpritesImage(), - fetchSpritesJson() - ]); - } - - // ################################################################### // - // ########################## INTERFACE ############################## // - // ################################################################### // - /** - * Create Editor - * - * @returns {Promise} - promise - */ - createElement () { - var self = this; - // objet json - if (typeof this.options.style === "object") { - this.mapbox = this.options.style; - // les sprites sont utiles que si on veut une legende ! - if (this.options.tools.legend) { - return this._getSprites(this.mapbox.sprite) - .then(function () { - // init du DOM - self._initContainer(); - return self; - }) - .catch(error => { - logger.warn("fetch sprites exception :", error); - }); - } else { - return new Promise((resolve, reject) => { - self._initContainer(); - resolve(self); - }); - } - } - - // url - if (typeof this.options.style === "string") { - return fetch(this.options.style, { - credentials : "same-origin" - }) - .then(response => { - // sauvegarde du json - return response.json() - .then(style => { - self.mapbox = style; - }) - .then(function () { - // les sprites sont utiles que si on veut une legende ! - if (self.options.tools.legend) { - return self._getSprites(self.mapbox.sprite) - .then(function () { - // init du DOM - self._initContainer(); - return self; - }) - .catch(error => { - logger.warn("fetch sprites exception :", error); - }); - } else { - return new Promise((resolve, reject) => { - self._initContainer(); - resolve(self); - }); - } - }) - .catch(error => { - logger.error("json exception :", error); - }); - }) - .catch(error => { - logger.error("fetch exception :", error); - }); - } - } - - /** - * Set display container (DOM) - * - * @param {Boolean} display - show/hidden container - */ - display (display) { - this.container.style.display = (display) ? "block" : "none"; - } - - setContext (key, value) { - this.context[key] = value; - } - - getContext (key) { - return this.context[key]; - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - /** - * Get id editor - * @returns {Number} id - */ - getID () { - return this.id; - } - - /** - * Get container (DOM) - * @returns {DOMElement} DOM element - */ - getContainer () { - return this.container; - } - - /** - * Get Style (json) - * @returns {Object} Style MapBox - */ - getStyle () { - return this.mapbox; - } - - /** - * Get layer style (json) - * @param {Number} i - index - * @returns {Object} Style MapBox of a layers - */ - getStyleLayer (i) { - var layer = null; - var o = this.getLayer(i); - var id = o.options.obj.id; - for (var k = 0; k < this.mapbox.layers.length; k++) { - var l = this.mapbox.layers[k]; - if (l.id === id) { - layer = l; - break; - } - } - return layer; - } - - /** - * Get layer object from json style - * @param {Number} i - index into style json - * @returns {Object} Style MapBox of a layers - */ - getLayerFromStyle (i) { - var layer = null; - var l = this.mapbox.layers[i]; - for (var k = 0; k < this.getLayers().length; k++) { - var o = this.getLayer(k); - if (l.id === o.options.obj.id) { - layer = o; - break; - } - } - return layer; - } - - /** - * Get a list of layer object sorted or not (see options.tools.sort) - * @returns {Array} - List of layer object - * @see {ol.style.editor.Layer} - */ - getLayers () { - return this.layers; - } - - /** - * Get the layer object from a list sorted or not (see options.tools.sort) - * @param {Number} i - index - * @returns {Object} - layer object - * @see {ol.style.editor.Layer} - */ - getLayer (i) { - return this.layers[i]; - } - -}; - -// on récupère les méthodes de la classe DOM -Utils.assign(Editor.prototype, EditorDOM); - -// ################################################################### // -// ####################### handlers events to dom #################### // -// ################################################################### // - -export default Editor; - -// Expose Editor as ol.editor.View (for a build bundle) -if (window.ol && window.ol.style) { - window.ol.style.Editor = Editor; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/EditorDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/EditorDOM.d.ts deleted file mode 100644 index e6ee82035..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/EditorDOM.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default EditorDOM; -declare namespace EditorDOM { - function _addUID(id: string): string; -} -//# sourceMappingURL=EditorDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/EditorDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/EditorDOM.d.ts.map deleted file mode 100644 index 5b147085f..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/EditorDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"EditorDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Editor/EditorDOM.js"],"names":[],"mappings":";;IAOc,qCAGT"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/EditorDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/EditorDOM.js deleted file mode 100644 index 3facbf4ba..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/EditorDOM.js +++ /dev/null @@ -1,14 +0,0 @@ -var EditorDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - } -}; - -export default EditorDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Event.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Event.d.ts deleted file mode 100644 index a978ce34f..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Event.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -export default EventEditor; -declare namespace EventEditor { - let onloaded: string; - namespace layer { - let onclickvisibility: string; - let onclickclone: string; - let onclickremove: string; - } - namespace legend { - let onclickedition: string; - let onchangevalue: string; - } - namespace group { - let oncollapse: string; - } - namespace style { - let oneditjson: string; - namespace scale { - let onchangemin: string; - let onchangemax: string; - } - } - namespace filter { - let oneditjson_1: string; - export { oneditjson_1 as oneditjson }; - } - namespace themes { - let onclickimage: string; - let onclicktitle: string; - } - namespace search { - let onsubmit: string; - let onautocomplete: string; - } -} -//# sourceMappingURL=Event.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Event.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Event.d.ts.map deleted file mode 100644 index d8979801d..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Event.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Event.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Editor/Event.js"],"names":[],"mappings":""} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Event.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Event.js deleted file mode 100644 index 48bbd1772..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Event.js +++ /dev/null @@ -1,83 +0,0 @@ -/** -* managing events -* -* See {@link http://krasimirtsonev.com/blog/article/javascript-managing-events-dispatch-listen} -* See {@link https://github.com/krasimir/EventBus} -* -* @property {Event} "editor:layer:onclickvisibility" - event ... -* @property {Event} "editor:layer:onclickclone" - event ... -* @property {Event} "editor:layer:onclickremove" - event ... -* @property {Event} "editor:style:oneditjson" - event ... -* @property {Event} "editor:style:scale:onchangemin" - event ... -* @property {Event} "editor:style:scale:onchangemax" - event ... -* @property {Event} "editor:legend:onclickedition" - event ... -* @property {Event} "editor:legend:onchangevalue" - event ... -* @property {Event} "editor:filter:oneditjson" - event ... -* @property {Event} "editor:themes:onclickimage" - event ... -* @property {Event} "editor:themes:onclicktitle" - event ... -* @property {Event} "editor:search:onsubmit" - event ... -* @property {Event} "editor:search:onautocomplete" - event ... -* @property {Event} "editor:group:oncollapse" - event ... -* @property {Event} "editor:onloaded" - event ... -* -* @mixin -* -* @example -* // dispatch event -* EventBus.dispatch(EventEditor.layer.visibility, e); -* // listener -* EventBus.addEventListener(EventEditor.layer.visibility, function (e) {...}, this); -*/ -var EventEditor = { - /** evenement sur la fin de chargement de l'editeur */ - onloaded : "editor:onloaded", - layer : { - /** evenement sur la visibilité : clic sur le bouton 'oeil' */ - onclickvisibility : "editor:layer:onclickvisibility", - /** evenement sur la duplication : clic sur le bouton - (not yet implemented !) */ - onclickclone : "editor:layer:onclickclone", - /** evenement sur la suppression : clic sur le bouton - (not yet implemented !) */ - onclickremove : "editor:layer:onclickremove" - }, - legend : { - /** evenement sur l'affichage du mode edition */ - onclickedition : "editor:legend:onclickedition", - /** evenement sur la modification d'une valeur */ - onchangevalue : "editor:legend:onchangevalue" - }, - group : { - /** evenement pour deplier/plier le groupe - (not yet implemented !) */ - oncollapse : "editor:group:oncollapse" - }, - style : { - /** evenement sur l'édition du style - (not yet implemented !) */ - oneditjson : "editor:style:oneditjson", - /** evenement sur la modification de l'echelle d'affichage */ - scale : { - onchangemin : "editor:style:scale:onchangemin", - onchangemax : "editor:style:scale:onchangemax" - } - }, - filter : { - /** evenement sur l'édition du filtre - (not yet implemented !) */ - oneditjson : "editor:filter:oneditjson" - }, - themes : { - /** evenement sur le clic de l'image */ - onclickimage : "editor:themes:onclickimage", - /** evenement sur le clic du titre */ - onclicktitle : "editor:themes:onclicktitle" - }, - search : { - /** evenement sur la recherche */ - onsubmit : "editor:search:onsubmit", - onautocomplete : "editor:search:onautocomplete" - } -}; - -export default EventEditor; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Filter.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Filter.d.ts deleted file mode 100644 index ccc16adc4..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Filter.d.ts +++ /dev/null @@ -1,91 +0,0 @@ -export default Filter; -/** - * @classdesc - * - * MapBox filter management - * - * @constructor - * @alias ol.style.editor.Filter - * @param {Object} options - options for function call. - * @example - * var filter = new Filter ({ - * target : ..., - * position : 1, // identifiant de position (unique !) - * tools : { - * edition : false - * }, - * title : "Filtres (JSON)", - * obj : { - * filter : [] - * } - * }); - * filter.add(); - * filter.display(true); - * filter.getContainer(); - */ -declare class Filter { - constructor(options: any); - options: any; - /** - * Initialize component - * (called by constructor) - * - * @private - */ - private _initialize; - id: any; - container: HTMLDivElement | null | undefined; - name: { - target: string; - container: string; - containerjson: string; - jsonlabel: string; - jsondisplay: string; - containertoolsedit: string; - } | undefined; - /** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
- *
- * - *
...
- *
- *
- *
- */ - private _initContainer; - /** - * Add element into target DOM - * @returns {Object} - Legend instance - */ - add(): Object; - /** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ - display(display: boolean): boolean; - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer(): DOMElement; - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Filter#editor:style:oneditjson - */ - private onEditJsonFilterMapBox; -} -//# sourceMappingURL=Filter.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Filter.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Filter.d.ts.map deleted file mode 100644 index 3e4e1af70..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Filter.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Filter.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Editor/Filter.js"],"names":[],"mappings":";AAOA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH;IAEI,0BAoBC;IAhBG,aAOC;IAWL;;;;;OAKG;IACH,oBA2CC;IAzCG,QAAiC;IA8BjC,6CAAqB;IAGrB;;;;;;;kBAOC;IAGL;;;;;;;;;;;;;OAaG;IACH,uBA2DC;IAKD;;;OAGG;IACH,OAFa,MAAM,CAkBlB;IAED;;;;;OAKG;IACH,mCAMC;IAED;;;;OAIG;IACH,2BAEC;IAKD;;;;;;;;;OASG;IACH,+BAKC;CAEJ"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Filter.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Filter.js deleted file mode 100644 index 19c7319b1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Filter.js +++ /dev/null @@ -1,252 +0,0 @@ -import EventBus from "eventbusjs"; -import EventEditor from "./Event"; -import Utils from "../../Utils/Helper"; -import Logger from "../../Utils/LoggerByDefault"; - -var logger = Logger.getLogger("editor-filter"); - -/** - * @classdesc - * - * MapBox filter management - * - * @constructor - * @alias ol.style.editor.Filter - * @param {Object} options - options for function call. - * @example - * var filter = new Filter ({ - * target : ..., - * position : 1, // identifiant de position (unique !) - * tools : { - * edition : false - * }, - * title : "Filtres (JSON)", - * obj : { - * filter : [] - * } - * }); - * filter.add(); - * filter.display(true); - * filter.getContainer(); - */ -class Filter { - - constructor (options) { - logger.trace("[constructor] Filter", options); - - // options - this.options = options || { - // default... - target : null, - position : 0, - tools : null, - title : null, - obj : null - }; - - if (!(this instanceof Filter)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this._initialize(); - - this._initContainer(); - } - - /** - * Initialize component - * (called by constructor) - * - * @private - */ - _initialize () { - // unique editor id (optional!) - this.id = this.options.id || null; - - if (!this.options.target) { - // cf. add() - } - - if (!this.options.position) { - this.options.position = 0; - } - - var _toolsDefault = { - edition : false - }; - - if (!this.options.tools) { - this.options.tools = _toolsDefault; - } - - Utils.mergeParams(this.options.tools, _toolsDefault, false); - - if (!this.options.obj) { - // choix d'avoir un objet vide pour une edition futur... - this.options.obj = { - filter : [] - }; - } - - if (!this.options.title) { - this.options.title = "JSON Filtres :"; - } - this.container = null; - - // DOM : className or id - this.name = { - target : "GPEditorMapBoxFilterTarget", - container : "GPEditorMapBoxFilterContainer", - containerjson : "GPEditorMapBoxFilterJsonContainer", - jsonlabel : "GPEditorMapBoxFilterTitleJson", - jsondisplay : "GPEditorMapBoxFilterDisplayJson", - containertoolsedit : "GPEditorMapBoxFilterToolsEditionContainer" - }; - } - - /** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
- *
- * - *
...
- *
- *
- *
- */ - _initContainer () { - // contexte - var self = this; - - var _found = false; - var _filter = JSON.parse(JSON.stringify(this.options.obj)); // on manipule une copie ! - - // FIXME tag filter est obselete ! - // on doit utiliser les expressions dans "paint" ou "layout" ! - if (_filter.filter) { - _found = true; - if (_filter.filter.length === 0) { - logger.info("tag 'filter' is empty !"); - } - } - - var div = document.createElement("div"); - div.className = this.name.container; - - var json = null; - if (_found) { - json = JSON.stringify(_filter.filter, null, 4); - } - - var divJson = document.createElement("div"); - divJson.className = this.name.containerjson; - - var labelJson = document.createElement("label"); - labelJson.className = this.name.jsonlabel; - labelJson.innerHTML = this.options.title; - divJson.appendChild(labelJson); - - var preJson = document.createElement("pre"); - preJson.className = this.name.jsondisplay; - preJson.innerHTML = json; - if (preJson.addEventListener) { - preJson.addEventListener("click", function (e) { - if (self.options.tools.edition) { - self.onEditJsonFilterMapBox(e); - } - }); - } else if (preJson.attachEvent) { - preJson.attachEvent("onclick", function (e) { - if (self.options.tools.edition) { - self.onEditJsonFilterMapBox(e); - } - }); - } - divJson.appendChild(preJson); - div.appendChild(divJson); - - if (this.options.tools.edition) { - var divEdit = document.createElement("div"); - divEdit.className = this.name.containertoolsedit; - div.appendChild(divEdit); - } - - // main container - this.container = div; - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - /** - * Add element into target DOM - * @returns {Object} - Legend instance - */ - add () { - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); - } - this.options.target = document.getElementById(this.name.target); - } - if (this.container) { - this.options.target.appendChild(this.container); - } - return this; - } - - /** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ - display (display) { - logger.trace("display()", display); - if (typeof display !== "undefined") { - this.container.style.display = (display) ? "flex" : "none"; - } - return (this.container.style.display === "flex"); - } - - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer () { - return this.container; - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Filter#editor:style:oneditjson - */ - onEditJsonFilterMapBox (e) { - logger.trace("onEditJsonFilterMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.filter.oneditjson, e); - } - -}; - -export default Filter; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Group.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Group.d.ts deleted file mode 100644 index 194d79c31..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Group.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -export default Group; -/** - * @classdesc - * - * MapBox group management - * - * @constructor - * @alias ol.style.editor.Group - * @param {Object} options - options for function call. - * @example - * var group = new Group ({ - * title : "MyGroup", - * collapse : true, // plier/deplier - * target : ... - * }); - * group.add(); - * group.add(); - */ -declare class Group { - constructor(options: any); - options: any; - /** - * Initialize component - * (called by constructor) - * - * @private - */ - private _initialize; - id: any; - container: HTMLDivElement | null | undefined; - name: { - target: string; - container: string; - details: string; - summary: string; - } | undefined; - /** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
...
- */ - private _initContainer; - /** - * Add element into target DOM - */ - add(): void; - /** - * Set display container (DOM) - * - * @param {Boolean} display - show/hidden container - */ - display(display: boolean): void; - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer(): DOMElement; - /** - * this method is called by event '' on '' tag form - * - * NOT USED ! - * @param {Object} e - HTMLElement - * @private - * @fires Group#editor:group:oncollapse - */ - private onCollapseGroupMapBox; -} -//# sourceMappingURL=Group.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Group.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Group.d.ts.map deleted file mode 100644 index 264fc90d9..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Group.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Group.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Editor/Group.js"],"names":[],"mappings":";AAMA;;;;;;;;;;;;;;;;GAgBG;AACH;IAEI,0BAeC;IAXG,aAEC;IAWL;;;;;OAKG;IACH,oBA2BC;IAzBG,QAAiC;IAgBjC,6CAAqB;IAGrB;;;;;kBAKC;IAGL;;;;;;;OAOG;IACH,uBAmBC;IAKD;;OAEG;IACH,YAeC;IAED;;;;OAIG;IACH,gCAEC;IAED;;;;OAIG;IACH,2BAQC;IAKD;;;;;;;OAOG;IACH,8BAKC;CAEJ"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Group.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Group.js deleted file mode 100644 index 09ca1fda5..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Group.js +++ /dev/null @@ -1,174 +0,0 @@ -import EventBus from "eventbusjs"; -import EventEditor from "./Event"; -import Logger from "../../Utils/LoggerByDefault"; - -var logger = Logger.getLogger("editor-group"); - -/** - * @classdesc - * - * MapBox group management - * - * @constructor - * @alias ol.style.editor.Group - * @param {Object} options - options for function call. - * @example - * var group = new Group ({ - * title : "MyGroup", - * collapse : true, // plier/deplier - * target : ... - * }); - * group.add(); - * group.add(); - */ -class Group { - - constructor (options) { - logger.trace("[constructor] Group", options); - - // options - this.options = options || { - // default... - }; - - if (!(this instanceof Group)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this._initialize(); - - this._initContainer(); - } - - /** - * Initialize component - * (called by constructor) - * - * @private - */ - _initialize () { - // unique editor id (optional!) - this.id = this.options.id || null; - - if (!this.options.target) { - // cf. add() - } - - if (!this.options.title) { - // cf. summary - this.options.title = "Détails du groupe..."; - } - - // plier par defaut - if (typeof this.options.collapse === "undefined") { - this.options.collapse = true; - } - - this.container = null; - - // DOM : className or id - this.name = { - target : "GPEditorMapBoxGroupTarget", - container : "GPEditorMapBoxGroupContainer", - details : "GPEditorMapBoxGroupDetails", - summary : "GPEditorMapBoxGroupSummary" - }; - } - - /** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
...
- */ - _initContainer () { - var div = document.createElement("div"); - div.className = this.name.container; - - // FIXME pas compatible IE ! - // https://caniuse.com/#search=details - // cf. https://css-tricks.com/quick-reminder-that-details-summary-is-the-easiest-way-ever-to-make-an-accordion/ - var details = document.createElement("details"); - details.className = this.name.details; - details.open = !this.options.collapse; - div.appendChild(details); - - var summary = document.createElement("summary"); - summary.className = this.name.summary; - summary.innerHTML = this.options.title; - details.appendChild(summary); - - // main container - this.container = div; - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - /** - * Add element into target DOM - */ - add () { - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); - } - this.options.target = document.getElementById(this.name.target); - } - if (this.container) { - this.options.target.appendChild(this.container); - } - } - - /** - * Set display container (DOM) - * - * @param {Boolean} display - show/hidden container - */ - display (display) { - this.container.style.display = (display) ? "flex" : "none"; - } - - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer () { - var nodes = this.container.childNodes; - if (nodes.length) { - // retourne le noeud "details" ! - return nodes[0]; - } - // sinon le container principal - return this.container; - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - /** - * this method is called by event '' on '' tag form - * - * NOT USED ! - * @param {Object} e - HTMLElement - * @private - * @fires Group#editor:group:oncollapse - */ - onCollapseGroupMapBox (e) { - logger.trace("onCollapseGroupMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.group.oncollapse, e); - } - -}; - -export default Group; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Layer.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Layer.d.ts deleted file mode 100644 index bc76b6ae6..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Layer.d.ts +++ /dev/null @@ -1,211 +0,0 @@ -export default Layer; -/** - * @classdesc - * - * MapBox filter management - * - * @constructor - * @alias ol.style.editor.Layer - * @param {Object} options - options for function call. - * @example - * var layers = new Layer ({ - * target : ..., - * position : 1, // identifiant de position (unique !) - * tools : { - * "visibility" : true, // afficher l'icone de visibilité - * "icon" : { - * "image" : true, // afficher l'icone "oeil" (defaut) ou une checkbox - * "anchor" : "start" | "end" // afficher l'icone au debut ou à la fin (defaut) - * }, - * "type" : true, // afficher l'icone du type de geometrie - * "pin" : true, // afficher l'icone de puce - * "remove" : false, // TODO afficher l'icone de suppression - * "clone" : false // TODO afficher l'icone de duplication - * }, - * obj : { - * "id": "ocs - vegetation", // MANDATORY - * "type": "fill", // OPTIONAL - * "source": "pyramide_proto", // OPTIONAL - * "source-layer": "ocs_vegetation_surf" // OPTIONAL - * } - * }); - * layers.addLegend(oLegend); - * layers.slotLegend(); - * layers.addStyle(oStyle); - * layers.addFilter(oFilter); - * layers.add(); - * layers.active(false); - * layers.visibility(false); - * layers.display(false); - * layers.collapse(); - * EventBus.addEventListener("editor:layer:onclickvisibility", function (e) { - * // e.target.data : options ! - * // e.target.editorID : id or null - * }, this); - */ -declare class Layer { - constructor(options: any); - options: any; - /** - * Initialize component - * (called by constructor) - * - * @private - */ - private _initialize; - id: any; - bSlotLegend: boolean | undefined; - oFilter: Filter | null | undefined; - oStyle: Style | null | undefined; - oLegend: Legend | null | undefined; - container: HTMLDivElement | null | undefined; - DomVisibility: any; - DomToggle: HTMLLabelElement | null | undefined; - name: { - target: string; - container: string; - containerlegend: string; - containertitle: string; - imagelabelinput: string; - imagelabel: string; - typeimg: string; - titleinput: string; - titlelabel: string; - containertools: string; - visibilityinput: string; - visibilitylabel: string; - visibilityinputdisable: string; - visibilitylabeldisable: string; - } | undefined; - /** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - * // >> Titre 1 |OOO| <- menu tools : visibility, clone, remove - * // >> Titre 2 |OXX| <- affichage configurable (cf. options.tools) - * // Event : clic sur le titre -> ex. affiche le menu des styles / filtres - * // : clic visibility, clone, remove - * // DOM : - *
- *
- * - * - * - * - *
- *
- * - * - *
- *
- */ - private _initContainer; - /** - * Add element into target DOM - * @returns {Object} - Layer instance - */ - add(): Object; - /** - * Add style in the submenu - * - * @param {Object} style - style object - */ - addStyle(style: Object): void; - /** - * Add filter in the submenu - * - * @param {Object} filter - filter object - */ - addFilter(filter: Object): void; - /** - * Add Legend in the submenu - * - * @param {Object} legend - legend object - */ - addLegend(legend: Object): void; - /** - * Integrate Legend to the layer container - */ - slotLegend(): void; - /** - * Set visibility or get - * - * @param {Boolean} display - set visibility or undefined to get status - * @returns {Boolean} - true/false - */ - visibility(display: boolean): boolean; - /** - * Collapse a layer panel (event) - */ - collapse(): void; - /** - * Click on visibility icon (event) - */ - visible(): void; - /** - * Set collapse or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ - display(display: boolean): boolean; - /** - * Set disabled/enabled status or get - * - * @param {Boolean} active - disable/enable layer interaction or get status - * @returns {Boolean} - true/false - */ - active(active: boolean): boolean; - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer(): DOMElement; - /** - * this method is called by event '' on '' tag form - * - * @param {Object} e - HTMLElement - * @private - */ - private onClickLayerMapBox; - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Layer#editor:layer:onclickvisibility - */ - private onVisibilityLayerMapBox; - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Layer#editor:layer:onclickclone - */ - private onCloneLayerMapBox; - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Layer#editor:layer:onclickremove - */ - private onRemoveLayerMapBox; -} -import Filter from "./Filter"; -import Style from "./Style"; -import Legend from "./Legend"; -//# sourceMappingURL=Layer.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Layer.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Layer.d.ts.map deleted file mode 100644 index de685c658..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Layer.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Layer.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Editor/Layer.js"],"names":[],"mappings":";AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH;IAEI,0BAaC;IATG,aAA4B;IAchC;;;;;OAKG;IACH,oBAyEC;IAvEG,QAAiC;IA0CjC,iCAAwB;IAGxB,mCAAmB;IACnB,iCAAkB;IAClB,mCAAmB;IAGnB,6CAAqB;IACrB,mBAAyB;IACzB,+CAAqB;IAGrB;;;;;;;;;;;;;;;kBAeC;IAGL;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,uBAgLC;IAKD;;;OAGG;IACH,OAFa,MAAM,CAmBlB;IAED;;;;OAIG;IACH,gBAFW,MAAM,QAQhB;IAED;;;;OAIG;IACH,kBAFW,MAAM,QAQhB;IAED;;;;OAIG;IACH,kBAFW,MAAM,QAQhB;IAED;;OAEG;IACH,mBA6BC;IAKD;;;;;OAKG;IACH,sCASC;IAED;;MAEE;IACF,iBAGC;IAED;;MAEE;IACF,gBAMC;IAED;;;;;OAKG;IACH,mCAgBC;IAED;;;;;OAKG;IACH,iCAQC;IAED;;;;OAIG;IACH,2BAEC;IAKD;;;;;OAKG;IACH,2BA6BC;IAED;;;;;;;;;OASG;IACH,gCAKC;IAED;;;;;;;;;OASG;IACH,2BAKC;IAED;;;;;;;;;OASG;IACH,4BAKC;CAEJ;mBAvnBkB,UAAU;kBAFX,SAAS;mBACR,UAAU"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Layer.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Layer.js deleted file mode 100644 index 6e11fa879..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Layer.js +++ /dev/null @@ -1,638 +0,0 @@ -import EventBus from "eventbusjs"; -import EventEditor from "./Event"; -import Style from "./Style"; -import Legend from "./Legend"; -import Filter from "./Filter"; -import Utils from "../../Utils/Helper"; -import Logger from "../../Utils/LoggerByDefault"; - -var logger = Logger.getLogger("editor-layer"); - -/** - * @classdesc - * - * MapBox filter management - * - * @constructor - * @alias ol.style.editor.Layer - * @param {Object} options - options for function call. - * @example - * var layers = new Layer ({ - * target : ..., - * position : 1, // identifiant de position (unique !) - * tools : { - * "visibility" : true, // afficher l'icone de visibilité - * "icon" : { - * "image" : true, // afficher l'icone "oeil" (defaut) ou une checkbox - * "anchor" : "start" | "end" // afficher l'icone au debut ou à la fin (defaut) - * }, - * "type" : true, // afficher l'icone du type de geometrie - * "pin" : true, // afficher l'icone de puce - * "remove" : false, // TODO afficher l'icone de suppression - * "clone" : false // TODO afficher l'icone de duplication - * }, - * obj : { - * "id": "ocs - vegetation", // MANDATORY - * "type": "fill", // OPTIONAL - * "source": "pyramide_proto", // OPTIONAL - * "source-layer": "ocs_vegetation_surf" // OPTIONAL - * } - * }); - * layers.addLegend(oLegend); - * layers.slotLegend(); - * layers.addStyle(oStyle); - * layers.addFilter(oFilter); - * layers.add(); - * layers.active(false); - * layers.visibility(false); - * layers.display(false); - * layers.collapse(); - * EventBus.addEventListener("editor:layer:onclickvisibility", function (e) { - * // e.target.data : options ! - * // e.target.editorID : id or null - * }, this); - */ -class Layer { - - constructor (options) { - logger.trace("[constructor] Layer", options); - - // options - this.options = options || {}; - - if (!(this instanceof Layer)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this._initialize(); - - this._initContainer(); - } - - // ################################################################### // - // ##################### private methods ############################# // - // ################################################################### // - /** - * Initialize component - * (called by constructor) - * - * @private - */ - _initialize () { - // unique editor id (optional!) - this.id = this.options.id || null; // null si le layer n'appartient pas à un editeur ! - - if (!this.options.target) { - // cf. add() - } - - if (!this.options.position) { - this.options.position = 0; - } - - var _toolsDefault = { - visibility : true, - icon : { - image : true, - anchor : "end" - }, - type : true, - pin : true, - remove : false, // TODO - clone : false // TODO - }; - - if (!this.options.tools) { - this.options.tools = _toolsDefault; - } - - Utils.mergeParams(this.options.tools, _toolsDefault, false); - - var _objDefault = { - id : "", - type : "", // icone sur le type de geometrie - source : "", - "source-layer" : "" - }; - - if (!this.options.obj) { - this.options.obj = _objDefault; - } - - Utils.mergeParams(this.options.obj, _objDefault, false); - - // legende intégrée - this.bSlotLegend = false; - - // obj - this.oFilter = null; - this.oStyle = null; - this.oLegend = null; - - // dom - this.container = null; - this.DomVisibility = null; - this.DomToggle = null; - - // DOM : className or id - this.name = { - target : "GPEditorMapBoxLayerTarget", - container : "GPEditorMapBoxLayerContainer", - containerlegend : "GPEditorMapBoxLayerLegendContainer", - containertitle : "GPEditorMapBoxLayerTitleContainer", - imagelabelinput : "GPEditorMapBoxLayerImageInput", - imagelabel : "GPEditorMapBoxLayerImageLabel", - typeimg : "GPEditorMapBoxLayerTypeImage", - titleinput : "GPEditorMapBoxLayerTitleInput", - titlelabel : "GPEditorMapBoxLayerTitleLabel", - containertools : "GPEditorMapBoxToolsContainer", - visibilityinput : "GPEditorMapBoxToolsVisibilityInput", - visibilitylabel : "GPEditorMapBoxToolsVisibilityLabel", - visibilityinputdisable : "GPEditorMapBoxToolsVisibilityInputDisable", - visibilitylabeldisable : "GPEditorMapBoxToolsVisibilityLabelDisable" - }; - } - - /** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - * // >> Titre 1 |OOO| <- menu tools : visibility, clone, remove - * // >> Titre 2 |OXX| <- affichage configurable (cf. options.tools) - * // Event : clic sur le titre -> ex. affiche le menu des styles / filtres - * // : clic visibility, clone, remove - * // DOM : - *
- *
- * - * - * - * - *
- *
- * - * - *
- *
- */ - _initContainer () { - // contexte - var self = this; - - var obj = this.options.obj; - - var div = document.createElement("div"); - div.className = this.name.container; - - // title - var divTitle = document.createElement("div"); - divTitle.id = this.name.containertitle + "-" + this.options.position; - divTitle.className = this.name.containertitle; - - // puce - if (this.options.tools.pin) { // Optionnel ! - // input - var inputImage = document.createElement("input"); - inputImage.id = this.name.imagelabelinput + "-" + this.options.position; - inputImage.className = this.name.imagelabelinput; - inputImage.type = "checkbox"; - divTitle.appendChild(inputImage); - // puce - var labelImage = document.createElement("label"); - labelImage.className = this.name.imagelabel; - labelImage.htmlFor = inputImage.id; - if (labelImage.addEventListener) { - labelImage.addEventListener("click", function (e) { - self.onClickLayerMapBox(e); - }); - } else if (labelImage.attachEvent) { - labelImage.attachEvent("onclick", function (e) { - self.onClickLayerMapBox(e); - }); - } - divTitle.appendChild(labelImage); - } - - // tools : - // visibility, (remove, clone) - var _addTools = function () { - var divTools = document.createElement("div"); - divTools.id = this.name.containertools + "-" + this.options.position; - divTools.className = this.name.containertools; - - // visibility - if (this.options.tools.visibility) { - var inputTools = document.createElement("input"); - inputTools.id = this.name.visibilityinput + "-" + this.options.position; - inputTools.className = (this.options.tools.icon.image) ? this.name.visibilityinput : this.name.visibilityinputdisable; - inputTools.type = "checkbox"; - inputTools.checked = "checked"; // par défaut, à modifier via visibility(true|false) ! - - // event for visibility change - if (inputTools.addEventListener) { - inputTools.addEventListener("click", function (e) { - self.onVisibilityLayerMapBox(e); - }); - } else if (inputTools.attachEvent) { - // internet explorer - inputTools.attachEvent("onclick", function (e) { - self.onVisibilityLayerMapBox(e); - }); - } - divTools.appendChild(inputTools); - // enregistrement utile pour la méthode : visibility() - this.DomVisibility = inputTools; - - var labelTools = document.createElement("label"); - labelTools.htmlFor = this.name.visibilityinput + "-" + this.options.position; - labelTools.id = this.name.visibilitylabel + "-" + this.options.position; - labelTools.className = (this.options.tools.icon.image) ? this.name.visibilitylabel : this.name.visibilitylabeldisable; - labelTools.title = "Afficher/masquer la couche"; - divTools.appendChild(labelTools); - - div.appendChild(divTools); - } - - // clone - if (this.options.tools.clone) { - // TODO... - logger.warn("Dom for tools clone, it's not yet implemented !"); - } - - // remove - if (this.options.tools.remove) { - // TODO... - logger.warn("Dom for tools remove, it's not yet implemented !"); - } - }; - - // ajout des outils au debut du composant - if (this.options.tools.icon.anchor === "start") { - _addTools.apply(this); - } - - // type - if (this.options.tools.type && obj.type) { // Optionnel ! - var imgType = document.createElement("img"); - imgType.className = this.name.typeimg; - // FIXME il faudrait faire la difference entre : - // - icone uniquement : SYMBOL-ICON - // - texte uniquement : SYMBOL-TEXT - // - les 2 : SYMBOL - // Mais il nous faut les styles complets (paint & layout) - // pour determiner les 3 types ! - switch (obj.type.toUpperCase()) { - case "SYMBOL-ICON": // not used ! - imgType.style["background-position"] = "0px 0"; - break; - case "SYMBOL-TEXT": // not used ! - imgType.style["background-position"] = "-194px 0"; - break; - case "SYMBOL": - imgType.style["background-position"] = "-84px 0"; - break; - case "LINE": - imgType.style["background-position"] = "-28px 0"; - break; - case "FILL": - imgType.style["background-position"] = "-56px 0"; - break; - case "BACKGROUND": - imgType.style["background-position"] = "-140px 0"; - break; - case "CIRCLE": - imgType.style["background-position"] = "-168px 0"; - break; - default: - // type inconnu ou non pris en charge ou par defaut - imgType.style["background-position"] = "-112px 0"; - } - divTitle.appendChild(imgType); - } - - // container legend (empty) - var divLegend = document.createElement("div"); - divLegend.id = this.name.containerlegend + "-" + this.options.position; - divLegend.className = this.name.containerlegend; - divTitle.appendChild(divLegend); - - // input - var inputTitle = document.createElement("input"); - inputTitle.id = this.name.titleinput + "-" + this.options.position; - inputTitle.className = this.name.titleinput; - inputTitle.type = "checkbox"; - divTitle.appendChild(inputTitle); - - // label for - var labelTitle = document.createElement("label"); - labelTitle.className = this.name.titlelabel; - labelTitle.htmlFor = inputTitle.id; - labelTitle.innerHTML = obj["id"] || obj["source-layer"] || obj["source"]; - labelTitle.title = obj["source-layer"] || obj["source"] || obj["id"]; - if (labelTitle.addEventListener) { - labelTitle.addEventListener("click", function (e) { - self.onClickLayerMapBox(e); - }); - } else if (labelTitle.attachEvent) { - labelTitle.attachEvent("onclick", function (e) { - self.onClickLayerMapBox(e); - }); - } - divTitle.appendChild(labelTitle); - // enregistrement utile pour la méthode : collapse() - this.DomToggle = labelTitle; - - div.appendChild(divTitle); - - // ajout des outils au fin du composant - if (this.options.tools.icon.anchor === "end") { - _addTools.apply(this); - } - - // main container - this.container = div; - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - /** - * Add element into target DOM - * @returns {Object} - Layer instance - */ - add () { - logger.trace("add()"); - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); - } - this.options.target = document.getElementById(this.name.target); - } - if (this.container) { - this.options.target.appendChild(this.container); - } - return this; - } - - /** - * Add style in the submenu - * - * @param {Object} style - style object - */ - addStyle (style) { - logger.trace("addStyle()", style); - if (style && typeof style === "object" && style instanceof Style) { - this.oStyle = style; - this.oStyle.display(false); // par defaut ! - } - } - - /** - * Add filter in the submenu - * - * @param {Object} filter - filter object - */ - addFilter (filter) { - logger.trace("addFilter()", filter); - if (filter && typeof filter === "object" && filter instanceof Filter) { - this.oFilter = filter; - this.oFilter.display(false); // par defaut ! - } - } - - /** - * Add Legend in the submenu - * - * @param {Object} legend - legend object - */ - addLegend (legend) { - logger.trace("addLegend()", legend); - if (legend && typeof legend === "object" && legend instanceof Legend) { - this.oLegend = legend; - this.oLegend.display(false); // par defaut ! - } - } - - /** - * Integrate Legend to the layer container - */ - slotLegend () { - // cas particulier : - // on souhaite intégrer une partie de la legende dans le container du layer. - var legend = this.oLegend; - if (legend) { - // FIXME c'est pourri... - var node = null; - var nodesLvl1 = this.container.childNodes; - if (nodesLvl1.length) { - // selon où se situe l'icone de visibilité : au debut ou à la fin... - var idx = (this.options.tools.icon.anchor === "start") ? 1 : 0; - var nodesLvl2 = nodesLvl1[idx].childNodes; - // on recherche le container de la legende - for (var i = 0; i < nodesLvl2.length; i++) { - var curnode = nodesLvl2[i]; - if (curnode.id.indexOf(this.name.containerlegend) !== -1) { - node = curnode; - } - } - } - if (node) { - var render = legend.getRenderContainer(); - if (render) { - node.appendChild(render); - // legende intégrée - this.bSlotLegend = true; - } - } - } - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - /** - * Set visibility or get - * - * @param {Boolean} display - set visibility or undefined to get status - * @returns {Boolean} - true/false - */ - visibility (display) { - logger.trace("visibility()", display); - if (!this.options.tools.visibility) { - return; - } - if (typeof display !== "undefined") { - this.DomVisibility.checked = (display) ? "checked" : ""; - } - return this.DomVisibility.checked; - } - - /** - * Collapse a layer panel (event) - */ - collapse () { - logger.trace("collapse()"); - this.DomToggle.click(); - } - - /** - * Click on visibility icon (event) - */ - visible () { - logger.trace("visible()"); - if (!this.options.tools.visibility) { - return; - } - this.DomVisibility.click(); - } - - /** - * Set collapse or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ - display (display) { - logger.trace("display()", display); - var checked = document.getElementById(this.DomToggle.htmlFor).checked; - if (typeof display !== "undefined") { - this.container.style.display = (display) ? "inline-flex" : "none"; - if (this.oStyle) { - this.oStyle.display(display && checked); - } - if (this.oFilter) { - this.oFilter.display(display && checked); - } - if (this.oLegend) { - this.oLegend.display(display && checked); - } - } - return checked; - } - - /** - * Set disabled/enabled status or get - * - * @param {Boolean} active - disable/enable layer interaction or get status - * @returns {Boolean} - true/false - */ - active (active) { - logger.trace("active()", active); - if (typeof active !== "undefined") { - this.container.className = (active) - ? this.name.container - : this.name.container + " disabled"; - } - return (this.container.className === this.name.container); - } - - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer () { - return this.container; - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - /** - * this method is called by event '' on '' tag form - * - * @param {Object} e - HTMLElement - * @private - */ - onClickLayerMapBox (e) { - logger.trace("onClickLayerMapBox", e); - - var id = e.target.htmlFor.substring(e.target.htmlFor.indexOf("-")); - var checked = document.getElementById(e.target.htmlFor).checked; - - // gestion des inputs - if (e.target.htmlFor === this.name.imagelabelinput + id) { - document.getElementById(this.name.titleinput + id).checked = !checked; - } - if (e.target.htmlFor === this.name.titleinput + id) { - // si options.pin:false, ce DOM n'existe pas ! - if (document.getElementById(this.name.imagelabelinput + id)) { - document.getElementById(this.name.imagelabelinput + id).checked = !checked; - } - } - - // ouverture du panneau des styles / filtres - if (this.oStyle) { - this.oStyle.display(!checked); - } - if (this.oFilter) { - this.oFilter.display(!checked); - } - // attention, - // si la legende est non editable, elle ne se trouve pas dans le sous menu ! - if (this.oLegend && this.oLegend.isEditable()) { - this.oLegend.display(!checked); - } - } - - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Layer#editor:layer:onclickvisibility - */ - onVisibilityLayerMapBox (e) { - logger.trace("onVisibilityLayerMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.layer.onclickvisibility, e); - } - - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Layer#editor:layer:onclickclone - */ - onCloneLayerMapBox (e) { - logger.trace("onCloneLayerMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.layer.onclickclone, e); - } - - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Layer#editor:layer:onclickremove - */ - onRemoveLayerMapBox (e) { - logger.trace("onRemoveLayerMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.layer.onclickremove, e); - } - -}; - -export default Layer; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Legend.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Legend.d.ts deleted file mode 100644 index a5bbe1bbd..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Legend.d.ts +++ /dev/null @@ -1,330 +0,0 @@ -export default Legend; -/** - * @classdesc - * - * MapBox Legend management - * - * @constructor - * @alias ol.style.editor.Legend - * @param {Object} options - options for function call. - * @param {Object} [options.target = null] - ... - * @param {Number} [options.position = 0] - ... - * @param {Number} [options.id = null] - (internal) ... - * @param {Object} [options.sprites = null] - ... - * @param {String} [options.sprites.url] - ... - * @param {Object} [options.sprites.size] - {h:, w:} ... - * @param {Object} [options.sprites.json] - ... - * @param {Object} options.obj - ... - * @param {String} [options.obj.title] - ... - * @param {Boolean} [options.obj.editable = true] - ... - * @param {Object} options.obj.paint - ... - * @param {Object} options.obj.layout - ... - * @example - * var legend = new Legend ({ - * target : ..., - * position : 1, // identifiant de position (unique !) - * sprites : { - * url : "http://localhost/sprites.png", - * size : { w : 450, h : 550 }, - * json : { - * icon-1 : {x:,y:,height:,width:,pixelRatio:}, - * icon-2 : {x:,y:,height:,width:,pixelRatio:} - * } - * }, - * obj : { - * title : "", - * editable : true, // tag non standard issue du style json dédié à l'edition - * paint : {"fill-color": "#2BB3E1"}, - * layout : {visibility:"none"} - * } - * }); - * legend.add(); - * legend.display(true); - * legend.isEditable(); - * legend.getRenderContainer(); - * legend.getToolsContainer(); - * legend.getContainer(); - */ -declare class Legend { - constructor(options: any); - options: any; - /** - * Initialize component - * (called by constructor) - * - * @private - */ - private _initialize; - id: any; - editable: any; - legendRender: Object | { - type: string; - values: { - width: number; - stroke: string; - color: string; - opacity: number; - }; - } | undefined; - container: HTMLDivElement | null | undefined; - rendercontainer: HTMLDivElement | null | undefined; - toolscontainer: any; - name: { - target: string; - container: string; - containerlegendrender: string; - legendrender: string; - legendeditable: string; - legendtitle: string; - containerlegendtools: string; - } | undefined; - labels: { - "line-color": string; - "line-width": string; - "line-opacity": string; - "fill-color": string; - "fill-opacity": string; - } | undefined; - /** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
- *
- *
- * test circle editable... - *
- *
...
- *
- */ - private _initContainer; - /** - * Get properties supported - * - * @param {Object} type - fill, line, circle, text, icon... - * @param {Object} values - raw values from the JSON file - * @returns {Object} - { type : (fill | line | circle | symbol), values : valuesSupported } - * - * @private - * @example - * - * // TODO - * // symbol with text (1) / symbol without text (2) / text (3) - * // "layout":{ - * // "icon-image":"{maki}-11", - * // "text-font":[ - * // "Open Sans Semibold", - * // "Arial Unicode MS Bold" - * // ], - * // "text-field":"{name_en}", - * // "text-max-width":9, - * // "text-padding":2, - * // "text-offset":[ - * // 0, - * // 0.6 - * // ], - * // "text-anchor":"top", - * // "text-size":12 - * // }, - * // "paint":{ - * // "text-color":"#666", - * // "text-halo-color":"#ffffff", - * // "text-halo-width":1, - * // "text-halo-blur":0.5 - * // }, - * - */ - private _getProperties; - /** - * Render thumbnail (SVG) - * - * @param {Object} type - fill, line, circle, text, ... - * @param {Object} values - {"color":..., "width":..., "stroke":...., "opacity":...} - * @returns {Boolean} true/false - * - * @private - * @example - * (...) - */ - private _renderThumbnail; - /** - * Get value - * - * @param {*} value - value of a property (ex. "#2BB3E1") - * @returns {*} return a verified value (ex. color": "#2BB3E1") - * - * @private - * @example - * // type simple for fill, line or circle type with string : - * // "paint": { - * // "fill-color": "#2BB3E1" - * // } - * - * // type simple for fill, line or circle type with array : - * // "paint": { - * // "line-dasharray": [2,10] - * // } - * - * // TODO type complexe : not yet implemented ! - * // "paint": { - * // "fill-color": [ - * // "match", - * // ["get","symbo"], - * // "ZONE_BOISEE","#A7DA81", - * // "ZONE_MANGROVE","#7E8AB5", - * // "#A7DA81" - * // ] - * // } - * - * // other type complexe : - * // "paint": { - * // "fill-color": { - * // "base": 1, - * // "stops": [ - * // [ - * // 15.5, - * // "#f2eae2" - * // ], - * // [ - * // 16, - * // "#dfdbd7" - * // ] - * // ] - * // } - * // } - */ - private _getValue; - /** - * Create a Graphical Legend Icon - * - * @param {Object} params - param - * @param {String} params.title - title - * @param {String} params.type - fill, line, circle, text, icon, ... - * @param {String} params.values - {"color": "#2BB3E1", "width": 10, "opacity": 0.5, "stroke": "#2BB3E1"} - * @param {Boolean} params.edit - editable with a colorPicker for only line, fill and circle legend ! - * @returns {DOMElement} DOM element - * - * @private - * @example - *
- *
- *
- * vide... - *
- */ - private _createElementIconLegend; - /** - * Create a Graphical Legend Edition - * - * @param {Object} params - param - * @param {String} params.type - fill, line, (TODO : circle, icon or text) - * @param {String} params.values - {"fill-color": "#2BB3E1"} - * @param {Boolean} params.edit - editable with a colorPicker for only line and fill legend ! - * @returns {DOMElement} DOM element - * - * @private - * @example - *
- *
- * - * - *
- *
- * - * - *
- *
- * - * - *
- *
- * - * - *
- *
- * - * - *
- *
- */ - private _createElementEditionLegend; - /** - * Add element into target DOM - * - * @returns {Object} - Legend instance - */ - add(): Object; - /** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ - display(display: boolean): boolean; - /** - * Is editable - * - * @returns {Boolean} - true/false - */ - isEditable(): boolean; - /** - * Get container Legend Render (DOM) - * - * @returns {DOMElement} DOM element - * @see Layer.prototype.slotLegend() - * @example - *
- */ - getRenderContainer(): DOMElement; - /** - * Get container Legend Tools (DOM) - * - * @returns {DOMElement} DOM element - * @see Layer.prototype.slotLegend() - * @example - *
...
- */ - getToolsContainer(): DOMElement; - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer(): DOMElement; - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Legend#editor:legend:onclickedition - */ - private onEditionLegendMapBox; - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Legend#editor:legend:onchangevalue - */ - private onChangeValueLegendMapBox; -} -declare namespace Legend { - namespace PROPERTIES { - let line: string[]; - let fill: string[]; - let background: string[]; - let circle: string[]; - let icon: string[]; - let text: string[]; - } -} -//# sourceMappingURL=Legend.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Legend.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Legend.d.ts.map deleted file mode 100644 index a2392a94b..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Legend.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Legend.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Editor/Legend.js"],"names":[],"mappings":";AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH;IAEI,0BAmBC;IAfG,aAMC;IAcL;;;;;OAKG;IACH,oBAgEC;IA9DG,QAAiC;IAyBjC,cAAsE;IAGtE;;;;;;;;kBAQC;IAGD,6CAAqB;IACrB,mDAA2B;IAC3B,oBAA0B;IAG1B;;;;;;;;kBAQC;IAGD;;;;;;kBAMC;IAGL;;;;;;;;;;;;;OAaG;IACH,uBAiFC;IAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAmCE;IACF,uBA8CC;IAED;;;;;;;;;;MAUE;IACF,yBA+FC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACH,kBAwCC;IAKD;;;;;;;;;;;;;;;;;;MAkBE;IACF,iCAqDC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAiCE;IACF,oCAgOC;IAKD;;;;OAIG;IACH,OAFa,MAAM,CAkBlB;IAED;;;;;OAKG;IACH,mCAMC;IAED;;;;OAIG;IACH,sBAEC;IAED;;;;;;;OAOG;IACH,iCAEC;IAED;;;;;;;OAOG;IACH,gCAEC;IAED;;;;OAIG;IACH,2BAEC;IAKD;;;;;;;;;OASG;IACH,8BAKC;IAED;;;;;;;;;OASG;IACH,kCAKC;CAEJ"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Legend.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Legend.js deleted file mode 100644 index a9654512a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Legend.js +++ /dev/null @@ -1,1038 +0,0 @@ -import EventBus from "eventbusjs"; -import EventEditor from "./Event"; -import Logger from "../../Utils/LoggerByDefault"; -import Color from "../../Utils/ColorUtils"; - -var logger = Logger.getLogger("editor-legend"); - -/** - * @classdesc - * - * MapBox Legend management - * - * @constructor - * @alias ol.style.editor.Legend - * @param {Object} options - options for function call. - * @param {Object} [options.target = null] - ... - * @param {Number} [options.position = 0] - ... - * @param {Number} [options.id = null] - (internal) ... - * @param {Object} [options.sprites = null] - ... - * @param {String} [options.sprites.url] - ... - * @param {Object} [options.sprites.size] - {h:, w:} ... - * @param {Object} [options.sprites.json] - ... - * @param {Object} options.obj - ... - * @param {String} [options.obj.title] - ... - * @param {Boolean} [options.obj.editable = true] - ... - * @param {Object} options.obj.paint - ... - * @param {Object} options.obj.layout - ... - * @example - * var legend = new Legend ({ - * target : ..., - * position : 1, // identifiant de position (unique !) - * sprites : { - * url : "http://localhost/sprites.png", - * size : { w : 450, h : 550 }, - * json : { - * icon-1 : {x:,y:,height:,width:,pixelRatio:}, - * icon-2 : {x:,y:,height:,width:,pixelRatio:} - * } - * }, - * obj : { - * title : "", - * editable : true, // tag non standard issue du style json dédié à l'edition - * paint : {"fill-color": "#2BB3E1"}, - * layout : {visibility:"none"} - * } - * }); - * legend.add(); - * legend.display(true); - * legend.isEditable(); - * legend.getRenderContainer(); - * legend.getToolsContainer(); - * legend.getContainer(); - */ -class Legend { - - constructor (options) { - logger.trace("[constructor] Legend", options); - - // options - this.options = options || { - // default... - target : null, - position : 0, - sprites : null, - obj : null - }; - - if (!(this instanceof Legend)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this._initialize(); - - this._initContainer(); - } - - // ################################################################### // - // ########################## init methods ########################### // - // ################################################################### // - /** - * Initialize component - * (called by constructor) - * - * @private - */ - _initialize () { - // unique editor id (optional!) - this.id = this.options.id || null; - - if (!this.options.target) { - // cf. add() - } - - // permet d'avoir un identifiant de position dans la liste des layers - if (!this.options.position) { - this.options.position = 0; - } - - if (!this.options.obj) { - // choix d'avoir un objet vide pour une edition... - this.options.obj = { - title : "vide...", - editable : true, - paint : { - "fill-color" : "#FFFFFF" - } - }; - } - - // la legende est elle editable ? - // le tag 'editable' est à placer dans le fichier de style (dans le layer)... - var _editable = this.options.obj.editable; - this.editable = (typeof _editable !== "undefined") ? _editable : false; - - // liste des caractéristiques de la legende par defaut - this.legendRender = { - type : "fill", - values : { - width : 1, - stroke : "#FFFFFF", - color : "#000000", - opacity : 1 - } - }; - - // DOM : pointer - this.container = null; - this.rendercontainer = null; - this.toolscontainer = null; - - // DOM : className or id - this.name = { - target : "GPEditorMapBoxLegendTarget", - container : "GPEditorMapBoxLegendContainer", - containerlegendrender : "GPEditorMapBoxLegendRenderContainer", - legendrender : "GPEditorMapBoxLegendRender", - legendeditable : "GPEditorMapBoxLegendEditable", - legendtitle : "GPEditorMapBoxLegendTitle", - containerlegendtools : "GPEditorMapBoxLegendToolsContainer" - }; - - // DOM : Label menu Edition - this.labels = { - "line-color" : "Couleur du trait", - "line-width" : "Epaisseur du trait", - "line-opacity" : "Opacité du trait", - "fill-color" : "Couleur de remplissage", - "fill-opacity" : "Opacité du remplissage" - }; - } - - /** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
- *
- *
- * test circle editable... - *
- *
...
- *
- */ - _initContainer () { - var _obj = this.options.obj; - - var div = document.createElement("div"); - div.className = this.name.container; - - // INFO - // on recherche les informations dans le tag 'paint' en priorité, mais pour - // les icones ou textes, les informations peuvent se trouver aussi dans le tag 'layout'... - // on fusionnne paint et layout par facilité - var style = Object.assign({}, _obj.paint, _obj.layout); - - // liste des properties mapbox - // ex. fill-color - var keys = Object.keys(style); - if (keys.length === 0) { - logger.info("tag 'paint' or 'layout' is empty !"); - return; - } - - // FIXME - // - gestion de type plus complexe : texte avec/sans symbole ou symbole ! - // - pour les textes ou icones, les info peuvent être aussi dans le tag 'layout' ! - var params = {}; - var bFound = false; - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - // recherche du type - // ex. fill - if (/fill-/.test(key) || - /line-/.test(key) || - /circle-/.test(key) || - /background-/.test(key) || - /text-/.test(key) || - /icon-/.test(key)) { - // style geré & trouvé - bFound = true; - - var title = _obj.title || ""; - - // INFO - // le type texte ou icone est difficile à trouver car les 2 types cohabitent, - // on le gère en symbole... - var type = key.split("-")[0]; - if (type === "text" || type === "icon") { - type = "symbol"; - } - - this.legendRender = this._getProperties(type, style); - params = { - edit : this.editable, - title : title, - type : this.legendRender.type, - values : this.legendRender.values - }; - div.appendChild(this._createElementIconLegend(params)); - - // on stoppe la recherche - break; - } - } - - // legende avec un style indeterminé ou non géré !? - if (!bFound) { - // on prend la legende par defaut - params = { - edit : this.editable, - title : "", - type : this.legendRender.type, - values : this.legendRender.values - }; - div.appendChild(this._createElementIconLegend(params)); - logger.warn("legend type unknown, default legend used..."); - } - - // ajout mode edition graphique de la legende - this.toolscontainer = this._createElementEditionLegend(params); - div.appendChild(this.toolscontainer); - - // main container - this.container = div; - } - - // ################################################################### // - // ##################### private methods ############################# // - // ################################################################### // - /** - * Get properties supported - * - * @param {Object} type - fill, line, circle, text, icon... - * @param {Object} values - raw values from the JSON file - * @returns {Object} - { type : (fill | line | circle | symbol), values : valuesSupported } - * - * @private - * @example - * - * // TODO - * // symbol with text (1) / symbol without text (2) / text (3) - * // "layout":{ - * // "icon-image":"{maki}-11", - * // "text-font":[ - * // "Open Sans Semibold", - * // "Arial Unicode MS Bold" - * // ], - * // "text-field":"{name_en}", - * // "text-max-width":9, - * // "text-padding":2, - * // "text-offset":[ - * // 0, - * // 0.6 - * // ], - * // "text-anchor":"top", - * // "text-size":12 - * // }, - * // "paint":{ - * // "text-color":"#666", - * // "text-halo-color":"#ffffff", - * // "text-halo-width":1, - * // "text-halo-blur":0.5 - * // }, - * - */ - _getProperties (type, values) { - // cas particulier du symbole complexe - // il existe plusieurs types pour un symbole : - // - text - // - icon - // - icon with text - if (type === "symbol") { - var isTextValue = values["text-field"]; - var isIconValue = values["icon-image"]; - type = (isTextValue && isIconValue) ? "icon" : (isTextValue) ? "text" : (isIconValue) ? "icon" : "unknow"; - if (type === "unknow") { - logger.warn("type unknow !?"); - return; - } - } - - var valuesSupported = {}; - for (const key in values) { - if (Object.hasOwnProperty.call(values, key)) { - const val = values[key]; - if (Legend.PROPERTIES[type].includes(key)) { - var prop = key.replace(type, "").slice(1); - var value = this._getValue(val); - if (value) { - // cas particulier des sprites - if (prop === "pattern" || prop === "image") { - if (!this.options.sprites || - !this.options.sprites.json || - !this.options.sprites.json[value]) { - var k = type + ":" + prop; - logger.warn("sprites mandatory for key ", k); - break; - } - } - valuesSupported[prop] = value; - } - } else { - logger.warn("property not supported : ", key); - } - } - } - - return { - type : type, - values : valuesSupported - }; - } - - /** - * Render thumbnail (SVG) - * - * @param {Object} type - fill, line, circle, text, ... - * @param {Object} values - {"color":..., "width":..., "stroke":...., "opacity":...} - * @returns {Boolean} true/false - * - * @private - * @example - * (...) - */ - _renderThumbnail (type, values) { - // div de rendu de la legende - var div = this.rendercontainer; - - if (!div) { - return false; - } - - // SVG - var svg = null; - // facteur grossissement (x10) pour le trait - var factor = 3; - - // valeur par defaut - if (!values.color) { - values.color = "#FFFFFF"; - } - // en fonction du type, on y ajoute le style - switch (type) { - case "text": - var styleText = "font-size: 5em;font-weight: bold;"; - svg = "url(\"data:image/svg+xml;utf8, T \")"; - div.style["background"] = svg - .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) - .replace("%opacity%", values.opacity || 1) - .replace("%style%", styleText); - break; - case "icon": - if (values.image) { - // FIXME on reste dans le paradigme d'utilisation du SVG..., - // mais probleme de ratio de l'image !? - svg = "" - .replace("%x%", this.options.sprites.json[values.image].x) - .replace("%y%", this.options.sprites.json[values.image].y) - .replace(/%w%/g, this.options.sprites.json[values.image].width) - .replace(/%h%/g, this.options.sprites.json[values.image].height) - .replace("%W%", this.options.sprites.size.w) - .replace("%H%", this.options.sprites.size.h) - .replace("%URL%", this.options.sprites.url); - div.innerHTML = svg; - } else { - var styleTextIcon = "fill: transparent;stroke-width: 10;"; - svg = "url(\"data:image/svg+xml;utf8,\")"; - div.style["background"] = svg - .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) - .replace("%style%", styleTextIcon); - } - break; - case "line": - var lstrockedasharray = (Array.isArray(values["dasharray"])) ? values["dasharray"].join(" ") : 0; - svg = "url(\"data:image/svg+xml;utf8,\")"; - // svg = "url(\"data:image/svg+xml;utf8,\")"; - div.style["background"] = svg - .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) - .replace("%stroke-opacity%", values.opacity || 1) - .replace("%stroke-dasharray%", lstrockedasharray) - .replace("%stroke-width%", (values.width || 0) * factor); - break; - case "circle": - var cstrockcolor = values["stroke-color"] || "#FFFFFF"; - svg = "url(\"data:image/svg+xml;utf8,\")"; - div.style["background"] = svg - .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) - .replace("%opacity%", values.opacity || 1) - .replace("%stroke-color%", (cstrockcolor.indexOf("rgb") === 0) ? cstrockcolor : Color.hexToRgba(cstrockcolor, 1)) - .replace("%stroke-opacity%", values["stroke-opacity"] || 1) - .replace("%stroke-width%", (values["stroke-width"] || 0) * factor); - break; - case "background": - case "fill": - if (values.pattern) { - svg = "" - .replace("%x%", this.options.sprites.json[values.pattern].x) - .replace("%y%", this.options.sprites.json[values.pattern].y) - .replace(/%w%/g, this.options.sprites.json[values.pattern].width) - .replace(/%h%/g, this.options.sprites.json[values.pattern].height) - .replace("%W%", this.options.sprites.size.w) - .replace("%H%", this.options.sprites.size.h) - .replace("%URL%", this.options.sprites.url); - div.innerHTML = svg; - } else { - var fstrokecolor = values["outline-color"] || "#FFFFFF"; - svg = "url(\"data:image/svg+xml;utf8,\")"; - div.style["background"] = svg - .replace("%color%", (values.color.indexOf("rgb") === 0) ? values.color : Color.hexToRgba(values.color, 1)) - .replace("%opacity%", values.opacity || 1) - .replace("%stroke-color%", (fstrokecolor.indexOf("rgb") === 0) ? fstrokecolor : Color.hexToRgba(fstrokecolor, 1)); - } - break; - default: - logger.warn("type not found, no thumbnail..."); - return false; - } - - return true; - } - - /** - * Get value - * - * @param {*} value - value of a property (ex. "#2BB3E1") - * @returns {*} return a verified value (ex. color": "#2BB3E1") - * - * @private - * @example - * // type simple for fill, line or circle type with string : - * // "paint": { - * // "fill-color": "#2BB3E1" - * // } - * - * // type simple for fill, line or circle type with array : - * // "paint": { - * // "line-dasharray": [2,10] - * // } - * - * // TODO type complexe : not yet implemented ! - * // "paint": { - * // "fill-color": [ - * // "match", - * // ["get","symbo"], - * // "ZONE_BOISEE","#A7DA81", - * // "ZONE_MANGROVE","#7E8AB5", - * // "#A7DA81" - * // ] - * // } - * - * // other type complexe : - * // "paint": { - * // "fill-color": { - * // "base": 1, - * // "stops": [ - * // [ - * // 15.5, - * // "#f2eae2" - * // ], - * // [ - * // 16, - * // "#dfdbd7" - * // ] - * // ] - * // } - * // } - */ - _getValue (value) { - var result = null; - if (typeof value === "string") { - result = value; - } else if (typeof value === "number") { - result = value; - } else if (Array.isArray(value)) { - // cas d'un tableau de valeurs numériques : [1,2,3] - var isNumber = true; - value.forEach(v => { - if (typeof v !== "number") { - isNumber = false; - } - }); - if (isNumber) { - result = value; - } - } else if (typeof value === "object") { - result = null; - if ("stops" in value) { - // on realise un ordre inversé sur les zooms - value.stops.sort((a, b) => { - var numA = a[0]; - var numB = b[0]; - if (numA > numB) { - return -1; - } - if (numA < numB) { - return 1; - } - return 0; - }); - // et, on prend le plus petit zoom - var lastStopsValue = value.stops.slice(-1); - result = lastStopsValue[0][1]; - } - } else { - logger.warn("value not supported !"); - } - return result; - } - - // ################################################################### // - // ######################### DOM methods ############################# // - // ################################################################### // - /** - * Create a Graphical Legend Icon - * - * @param {Object} params - param - * @param {String} params.title - title - * @param {String} params.type - fill, line, circle, text, icon, ... - * @param {String} params.values - {"color": "#2BB3E1", "width": 10, "opacity": 0.5, "stroke": "#2BB3E1"} - * @param {Boolean} params.edit - editable with a colorPicker for only line, fill and circle legend ! - * @returns {DOMElement} DOM element - * - * @private - * @example - *
- *
- *
- * vide... - *
- */ - _createElementIconLegend (params) { - // contexte - var self = this; - - var container = document.createElement("div"); - container.className = this.name.containerlegendrender; - - var div = this.rendercontainer = document.createElement("div"); - div.className = this.name.legendrender; - if (params.edit) { - div.className += " "; - div.className += this.name.legendeditable; - if (div.addEventListener) { - div.addEventListener("click", function (e) { - self.onEditionLegendMapBox(e); - }); - } else if (div.attachEvent) { - div.attachEvent("onclick", function (e) { - self.onEditionLegendMapBox(e); - }); - } - } - - // type de legende - var type = params.type; - - // TODO className - // div.className += " legend-not-implemented"; - // ajout du style sur la div de rendu - if (this._renderThumbnail(type, params.values)) { - // className possibles : - // " legend-text" - // " legend-icon" - // " legend-background" - // " legend-line" - // " legend-line-not-editable" - // " legend-circle" - // " legend-circle-not-editable" - // " legend-fill" - // " legend-fill-not-editable" - div.className += (params.edit) ? " legend-" + type : " legend-" + type + "-not-editable"; - } else { - div.className += " legend-unknow"; - } - - container.appendChild(div); - - var span = document.createElement("span"); - span.className = this.name.legendtitle; - span.innerHTML = params.title || ""; - container.appendChild(span); - - return container; - } - - /** - * Create a Graphical Legend Edition - * - * @param {Object} params - param - * @param {String} params.type - fill, line, (TODO : circle, icon or text) - * @param {String} params.values - {"fill-color": "#2BB3E1"} - * @param {Boolean} params.edit - editable with a colorPicker for only line and fill legend ! - * @returns {DOMElement} DOM element - * - * @private - * @example - *
- *
- * - * - *
- *
- * - * - *
- *
- * - * - *
- *
- * - * - *
- *
- * - * - *
- *
- */ - _createElementEditionLegend (params) { - // contexte - var self = this; - - var container = document.createElement("div"); - container.className = this.name.containerlegendtools; - - // uniquement les elements editables ! - if (!params.edit) { - return container; - } - - // on ne traite que l'edition du mode 'traits' ou 'surfaciques' - // mode 'line' - switch (params.type) { - case "line": - createLineColor.call(self); - createLineWidth.call(self); - createLineOpacity.call(self); - break; - case "background": - case "fill": - createFillColor.call(self); - createFillOpacity.call(self); - break; - default: - break; - } - - // couleur du trait - function createLineColor () { - var linecolor = document.createElement("div"); - linecolor.className = "legend-styling-div"; - var lLineColor = document.createElement("label"); - lLineColor.className = "legend-line"; - lLineColor.htmlFor = this.id ? "line-color-" + this.id : "line-color"; - lLineColor.innerHTML = this.labels["line-color"]; - var inputLineColor = document.createElement("input"); - inputLineColor.className = "legend-styling"; - inputLineColor.id = this.id ? "line-color-" + this.id : "line-color"; - inputLineColor.title = "Selectionner une couleur de trait"; - inputLineColor.type = "color"; - inputLineColor.value = params.values.color; - inputLineColor.setAttribute("data-id", "line-color"); - if (inputLineColor.addEventListener) { - inputLineColor.addEventListener("change", function (e) { - self._renderThumbnail(params.type, Object.assign(params.values, { - color : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } else if (inputLineColor.attachEvent) { - inputLineColor.attachEvent("onchange", function (e) { - self._renderThumbnail(params.type, Object.assign(params.values, { - color : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } - linecolor.appendChild(lLineColor); - linecolor.appendChild(inputLineColor); - container.appendChild(linecolor); - } - - // epaisseur du trait - function createLineWidth () { - var linewidth = document.createElement("div"); - linewidth.className = "legend-styling-div"; - var lLineWidth = document.createElement("label"); - lLineWidth.className = "legend-line"; - lLineWidth.htmlFor = this.id ? "line-width-" + this.id : "line-width"; - lLineWidth.innerHTML = this.labels["line-width"]; - var inputLineWidth = document.createElement("input"); - inputLineWidth.className = "legend-styling"; - inputLineWidth.id = this.id ? "line-width-" + this.id : "line-width"; - inputLineWidth.title = params.values.width; - inputLineWidth.type = "range"; - inputLineWidth.min = "0"; - inputLineWidth.max = "10"; - inputLineWidth.step = "1"; - inputLineWidth.defaultValue = params.values.width; - inputLineWidth.setAttribute("data-id", "line-width"); - if (inputLineWidth.addEventListener) { - inputLineWidth.addEventListener("change", function (e) { - logger.trace(e); - e.target.title = e.target.value; - self._renderThumbnail(params.type, Object.assign(params.values, { - width : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } else if (inputLineWidth.attachEvent) { - inputLineWidth.attachEvent("onchange", function (e) { - logger.trace(e); - e.target.title = e.target.value; - self._renderThumbnail(params.type, Object.assign(params.values, { - width : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } - linewidth.appendChild(lLineWidth); - linewidth.appendChild(inputLineWidth); - container.appendChild(linewidth); - } - - // opacité du trait - function createLineOpacity () { - var lineopacity = document.createElement("div"); - lineopacity.className = "legend-styling-div"; - var lLineOpacity = document.createElement("label"); - lLineOpacity.className = "legend-line"; - lLineOpacity.htmlFor = this.id ? "line-opacity-" + this.id : "line-opacity"; - lLineOpacity.innerHTML = this.labels["line-opacity"]; - var inputLineOpacity = document.createElement("input"); - inputLineOpacity.className = "legend-styling"; - inputLineOpacity.id = this.id ? "line-opacity-" + this.id : "line-opacity"; - inputLineOpacity.title = params.values.opacity; - inputLineOpacity.type = "range"; - inputLineOpacity.min = "0"; - inputLineOpacity.max = "1"; - inputLineOpacity.step = "0.1"; - inputLineOpacity.defaultValue = params.values.opacity; - inputLineOpacity.setAttribute("data-id", "line-opacity"); - if (inputLineOpacity.addEventListener) { - inputLineOpacity.addEventListener("change", function (e) { - logger.trace(e); - e.target.title = e.target.value; - self._renderThumbnail(params.type, Object.assign(params.values, { - opacity : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } else if (inputLineOpacity.attachEvent) { - inputLineOpacity.attachEvent("onchange", function (e) { - logger.trace(e); - e.target.title = e.target.value; - self._renderThumbnail(params.type, Object.assign(params.values, { - opacity : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } - lineopacity.appendChild(lLineOpacity); - lineopacity.appendChild(inputLineOpacity); - container.appendChild(lineopacity); - } - - // couleur de remplissage - function createFillColor () { - var fillcolor = document.createElement("div"); - fillcolor.className = "legend-styling-div"; - var lFillColor = document.createElement("label"); - lFillColor.className = "legend-fill"; - lFillColor.htmlFor = this.id ? "fill-color-" + this.id : "fill-color"; - lFillColor.innerHTML = this.labels["fill-color"]; - var inputFillColor = document.createElement("input"); - inputFillColor.className = "legend-styling"; - inputFillColor.id = this.id ? "fill-color-" + this.id : "fill-color"; - inputFillColor.title = "Selectionner une couleur de remplissage"; - inputFillColor.type = "color"; - inputFillColor.value = params.values.color; - inputFillColor.setAttribute("data-id", "fill-color"); - if (inputFillColor.addEventListener) { - inputFillColor.addEventListener("change", function (e) { - self._renderThumbnail(params.type, Object.assign(params.values, { - color : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } else if (inputFillColor.attachEvent) { - inputFillColor.attachEvent("onchange", function (e) { - self._renderThumbnail(params.type, Object.assign(params.values, { - color : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } - fillcolor.appendChild(lFillColor); - fillcolor.appendChild(inputFillColor); - container.appendChild(fillcolor); - } - - // opacité du remplissage - function createFillOpacity () { - var fillopacity = document.createElement("div"); - fillopacity.className = "legend-styling-div"; - var lFillOpacity = document.createElement("label"); - lFillOpacity.className = "legend-fill"; - lFillOpacity.htmlFor = this.id ? "fill-opacity-" + this.id : "fill-opacity"; - lFillOpacity.innerHTML = this.labels["fill-opacity"]; - var inputFillOpacity = document.createElement("input"); - inputFillOpacity.className = "legend-styling"; - inputFillOpacity.id = this.id ? "fill-opacity-" + this.id : "fill-opacity"; - inputFillOpacity.title = params.values.opacity; - inputFillOpacity.type = "range"; - inputFillOpacity.min = "0"; - inputFillOpacity.max = "1"; - inputFillOpacity.step = "0.1"; - inputFillOpacity.defaultValue = params.values.opacity; - inputFillOpacity.setAttribute("data-id", "fill-opacity"); - if (inputFillOpacity.addEventListener) { - inputFillOpacity.addEventListener("change", function (e) { - e.target.title = e.target.value; - self._renderThumbnail(params.type, Object.assign(params.values, { - opacity : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } else if (inputFillOpacity.attachEvent) { - inputFillOpacity.attachEvent("onchange", function (e) { - e.target.title = e.target.value; - self._renderThumbnail(params.type, Object.assign(params.values, { - opacity : e.target.value - })); - self.onChangeValueLegendMapBox(e); - }); - } - fillopacity.appendChild(lFillOpacity); - fillopacity.appendChild(inputFillOpacity); - container.appendChild(fillopacity); - } - - return container; - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - /** - * Add element into target DOM - * - * @returns {Object} - Legend instance - */ - add () { - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); - } - this.options.target = document.getElementById(this.name.target); - } - if (this.container) { - this.options.target.appendChild(this.container); - } - return this; - } - - /** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ - display (display) { - logger.trace("display()", display); - if (typeof display !== "undefined") { - this.container.style.display = (display) ? "flex" : "none"; - } - return (this.container.style.display === "flex"); - } - - /** - * Is editable - * - * @returns {Boolean} - true/false - */ - isEditable () { - return this.editable; - } - - /** - * Get container Legend Render (DOM) - * - * @returns {DOMElement} DOM element - * @see Layer.prototype.slotLegend() - * @example - *
- */ - getRenderContainer () { - return this.rendercontainer; - } - - /** - * Get container Legend Tools (DOM) - * - * @returns {DOMElement} DOM element - * @see Layer.prototype.slotLegend() - * @example - *
...
- */ - getToolsContainer () { - return this.toolscontainer; - } - - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer () { - return this.container; - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Legend#editor:legend:onclickedition - */ - onEditionLegendMapBox (e) { - logger.trace("onEditionLegendMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.legend.onclickedition, e); - } - - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Legend#editor:legend:onchangevalue - */ - onChangeValueLegendMapBox (e) { - logger.trace("onChangeValueLegendMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.legend.onchangevalue, e); - } - -}; - -// ################################################################### // -// ########################## CONSTANTES ############################# // -// ################################################################### // - -/** - * List of supported properties - */ -Legend.PROPERTIES = { - line : [ - "line-color", - "line-dasharray", - "line-opacity", - "line-width" - ], - fill : [ - "fill-color", - "fill-opacity", - "fill-outline-color", - "fill-pattern" - ], - background : [ - "background-color", - "background-opacity", - "background-pattern" - ], - circle : [ - "circle-color", - "circle-opacity", - "circle-stroke-color", - "circle-stroke-opacity", - "circle-stroke-width" - ], - icon : [ - "icon-color", - "icon-image", - "icon-opacity", - "__icon-size" - ], - text : [ - "__text-anchor", - "text-color", - "text-field", - "__text-font", - "__text-opacity", - "__text-size" - ] -}; - -export default Legend; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Search.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Search.d.ts deleted file mode 100644 index b5f4f34d7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Search.d.ts +++ /dev/null @@ -1,92 +0,0 @@ -export default Search; -/** - * @classdesc - * - * TODO MapBox search management - * - * @constructor - * @alias ol.style.editor.Search - * @param {Object} options - options for function call. - * @todo - * @example - * var Search = new Search ({ - * target : ..., - * tools : { - * // ... - * } - * title : "Filtres de recherche :", - * obj : {} - * }); - * Search.add(); - * Search.display(true); - * Search.getContainer(); - */ -declare class Search { - constructor(options: any); - options: any; - /** - * Initialize component - * (called by constructor) - * - * @private - */ - private _initialize; - id: any; - container: HTMLDivElement | null | undefined; - name: { - target: string; - container: string; - } | undefined; - /** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
- * // ... - *
- */ - private _initContainer; - /** - * Add element into target DOM - * @returns {Object} - Search instance - */ - add(): Object; - /** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ - display(display: boolean): boolean; - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer(): DOMElement; - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Search#editor:search:onsubmit - */ - private onSubmitSearchLayersMapBox; - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Search#editor:search:onautocomplete - */ - private onAutocompleteSearchLayersMapBox; -} -//# sourceMappingURL=Search.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Search.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Search.d.ts.map deleted file mode 100644 index 8d5f9f3e6..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Search.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Search.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Editor/Search.js"],"names":[],"mappings":";AAOA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH;IAEI,0BAmBC;IAfG,aAMC;IAWL;;;;;OAKG;IACH,oBAgCC;IA9BG,QAAiC;IAsBjC,6CAAqB;IAGrB;;;kBAIC;IAGL;;;;;;;;;OASG;IACH,uBAyBC;IAKD;;;OAGG;IACH,OAFa,MAAM,CAkBlB;IAED;;;;;OAKG;IACH,mCAMC;IAED;;;;OAIG;IACH,2BAEC;IAKD;;;;;;;;;OASG;IACH,mCAKC;IAED;;;;;;;;;OASG;IACH,yCAKC;CAEJ"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Search.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Search.js deleted file mode 100644 index 171d0395e..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Search.js +++ /dev/null @@ -1,217 +0,0 @@ -import EventBus from "eventbusjs"; -import EventEditor from "./Event"; -import Utils from "../../Utils/Helper"; -import Logger from "../../Utils/LoggerByDefault"; - -var logger = Logger.getLogger("editor-search"); - -/** - * @classdesc - * - * TODO MapBox search management - * - * @constructor - * @alias ol.style.editor.Search - * @param {Object} options - options for function call. - * @todo - * @example - * var Search = new Search ({ - * target : ..., - * tools : { - * // ... - * } - * title : "Filtres de recherche :", - * obj : {} - * }); - * Search.add(); - * Search.display(true); - * Search.getContainer(); - */ -class Search { - - constructor (options) { - logger.trace("[constructor] Search", options); - - // options - this.options = options || { - // default... - target : null, - tools : null, - title : null, - obj : null - }; - - if (!(this instanceof Search)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this._initialize(); - - this._initContainer(); - } - - /** - * Initialize component - * (called by constructor) - * - * @private - */ - _initialize () { - // unique editor id (optional!) - this.id = this.options.id || null; - - if (!this.options.target) { - // cf. add() - } - - var _toolsDefault = {}; - - if (!this.options.tools) { - this.options.tools = _toolsDefault; - } - - Utils.mergeParams(this.options.tools, _toolsDefault, false); - - if (!this.options.obj) { - // choix d'avoir un objet vide pour une edition futur... - this.options.obj = {}; - } - - if (!this.options.title) { - this.options.title = "Recherche de couches :"; - } - this.container = null; - - // DOM : className or id - this.name = { - target : "GPEditorMapBoxSearchTarget", - container : "GPEditorMapBoxSearchContainer" - // TODO ... - }; - } - - /** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
- * // ... - *
- */ - _initContainer () { - // contexte - // var self = this; - var _search = JSON.parse(JSON.stringify(this.options.obj)); // on manipule une copie ! - - if (_search.layers) { - if (_search.layers.length === 0) { - logger.info("tag 'layers' is empty !"); - } - } - - var div = document.createElement("div"); - div.className = this.name.container; - - // TODO... - // outil de recherche des couches mapbox. - // 2 modes de recherches : exact ou par autocompletion - // affichage des resultats directement dans la liste des couches - // la recherche porte sur les champs suiavnts (options): - // * id (par defaut) - // * source-layer (par defaut) - // * type (ex. Symbol) - // * field (ex. HOPITAL_PONC) > recherche dans le champs filtre - // main container - this.container = div; - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - /** - * Add element into target DOM - * @returns {Object} - Search instance - */ - add () { - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); - } - this.options.target = document.getElementById(this.name.target); - } - if (this.container) { - this.options.target.appendChild(this.container); - } - return this; - } - - /** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ - display (display) { - logger.trace("display()", display); - if (typeof display !== "undefined") { - this.container.style.display = (display) ? "flex" : "none"; - } - return (this.container.style.display === "flex"); - } - - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer () { - return this.container; - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Search#editor:search:onsubmit - */ - onSubmitSearchLayersMapBox (e) { - logger.trace("onSubmitSearchLayersMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.search.onsubmit, e); - } - - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Search#editor:search:onautocomplete - */ - onAutocompleteSearchLayersMapBox (e) { - logger.trace("onAutocompleteSearchLayersMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.search.onautocomplete, e); - } - -}; - -export default Search; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Style.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Style.d.ts deleted file mode 100644 index 3b171ad31..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Style.d.ts +++ /dev/null @@ -1,154 +0,0 @@ -export default Style; -/** - * @classdesc - * - * MapBox styles management - * - * @constructor - * @alias ol.style.editor.Style - * @param {Object} options - options for function call. - * @example - * var style = new Style ({ - * target : ..., - * position : 1, // identifiant de position (unique !) - * tools : { - * edition : false, - * scale : true - * }, - * title : "Styles (JSON)", - * obj : { - * paint : {}, - * layout : {} - * } - * }); - * style.add(); - * style.display(true); - * style.getContainer(); - */ -declare class Style { - constructor(options: any); - options: any; - /** - * Initialize component - * (called by constructor) - * - * @private - */ - private _initialize; - id: any; - container: HTMLDivElement | null | undefined; - name: { - target: string; - container: string; - containerjson: string; - jsonlabel: string; - jsondisplay: string; - containertoolsscale: string; - scaletitle: string; - containertoolsminscale: string; - scalelabelmin: string; - scaleinputmin: string; - containertoolsmaxscale: string; - scalelabelmax: string; - scaleinputmax: string; - containertoolsedit: string; - } | undefined; - /** - * Graphical rendering of the component - * ie. this.container - * (called by constructor) - * - * @private - * @example - *
- *
- * - *
...
- *
- *
- *
- *
- */ - private _initContainer; - /** - * Graphical rendering of the scale tools - * - * @param {Object} scale - {min,max} or 0|21 - * @returns {DOMElement} DOM element - * - * @private - * @example - *
- */ - private _createElementToolsScale; - /** - * Graphical rendering of the edition tools - * - * @returns {DOMElement} DOM element - * - * @private - * @example - *
- */ - private _createElementToolsEdition; - /** - * Transform a JSON into a DOM with a syntax in color - * - * @private - * @param {Object} json - json. - * @returns {DOMElement} dom element - */ - private _syntaxHighlight; - /** - * Add element into target DOM - * @returns {Object} - Legend instance - */ - add(): Object; - /** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ - display(display: boolean): boolean; - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer(): DOMElement; - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Style#editor:style:oneditjson - */ - private onEditJsonStyleMapBox; - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Style#editor:style:scale:onchangemin - */ - private onChangeStyleScaleMinMapBox; - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Style#editor:style:scale:onchangemax - */ - private onChangeStyleScaleMaxMapBox; -} -//# sourceMappingURL=Style.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Style.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Style.d.ts.map deleted file mode 100644 index 41655b057..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Style.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Style.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Editor/Style.js"],"names":[],"mappings":";AAOA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH;IAEI,0BAoBC;IAhBG,aAOC;IAWL;;;;;OAKG;IACH,oBAsDC;IApDG,QAAiC;IAiCjC,6CAAqB;IAGrB;;;;;;;;;;;;;;;kBAeC;IAGL;;;;;;;;;;;;;;;OAeG;IACH,uBAiFC;IAED;;;;;;;;;OASG;IACH,iCA4EC;IAED;;;;;;;;OAQG;IACH,mCAOC;IAKD;;;;;;OAMG;IACH,yBAiBC;IAKD;;;OAGG;IACH,OAFa,MAAM,CAkBlB;IAED;;;;;OAKG;IACH,mCAMC;IAED;;;;OAIG;IACH,2BAEC;IAKD;;;;;;;;;OASG;IACH,8BAKC;IAED;;;;;;;;;OASG;IACH,oCAKC;IAED;;;;;;;;;OASG;IACH,oCAKC;CAEJ"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Style.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Style.js deleted file mode 100644 index 99ae4bc00..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Style.js +++ /dev/null @@ -1,458 +0,0 @@ -import EventBus from "eventbusjs"; -import EventEditor from "./Event"; -import Utils from "../../Utils/Helper"; -import Logger from "../../Utils/LoggerByDefault"; - -var logger = Logger.getLogger("editor-style"); - -/** - * @classdesc - * - * MapBox styles management - * - * @constructor - * @alias ol.style.editor.Style - * @param {Object} options - options for function call. - * @example - * var style = new Style ({ - * target : ..., - * position : 1, // identifiant de position (unique !) - * tools : { - * edition : false, - * scale : true - * }, - * title : "Styles (JSON)", - * obj : { - * paint : {}, - * layout : {} - * } - * }); - * style.add(); - * style.display(true); - * style.getContainer(); - */ -class Style { - - constructor (options) { - logger.trace("[constructor] Style", options); - - // options - this.options = options || { - // default... - target : null, - position : 0, - tools : null, - title : null, - obj : null - }; - - if (!(this instanceof Style)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this._initialize(); - - this._initContainer(); - } - - /** - * Initialize component - * (called by constructor) - * - * @private - */ - _initialize () { - // unique editor id (optional!) - this.id = this.options.id || null; - - if (!this.options.target) { - // cf. add() - } - - if (!this.options.position) { - this.options.position = 0; - } - - var _toolsDefault = { - scale : true, - edition : false - }; - - if (!this.options.tools) { - this.options.tools = _toolsDefault; - } - - Utils.mergeParams(this.options.tools, _toolsDefault, false); - - if (!this.options.obj) { - // choix d'avoir un objet vide pour une edition futur... - this.options.obj = { - paint : {}, - layout : {} - }; - } - - if (!this.options.title) { - this.options.title = "JSON Styles :"; - } - - this.container = null; - - // DOM : className or id - this.name = { - target : "GPEditorMapBoxStyleTarget", - container : "GPEditorMapBoxStyleContainer", - containerjson : "GPEditorMapBoxStyleJsonContainer", - jsonlabel : "GPEditorMapBoxStyleJsonTitle", - jsondisplay : "GPEditorMapBoxStyleJsonDisplay", - containertoolsscale : "GPEditorMapBoxStyleToolsScaleContainer", - scaletitle : "GPEditorMapBoxStyleScaleTitle", - containertoolsminscale : "GPEditorMapBoxStyleToolsScaleMinContainer", - scalelabelmin : "GPEditorMapBoxStyleScaleLabelMin", - scaleinputmin : "GPEditorMapBoxStyleScaleInputMin", - containertoolsmaxscale : "GPEditorMapBoxStyleToolsScaleMaxContainer", - scalelabelmax : "GPEditorMapBoxStyleScaleLabelMax", - scaleinputmax : "GPEditorMapBoxStyleScaleInputMax", - containertoolsedit : "GPEditorMapBoxStyleToolsEditionContainer" - }; - } - - /** - * Graphical rendering of the component - * ie. this.container - * (called by constructor) - * - * @private - * @example - *
- *
- * - *
...
- *
- *
- *
- *
- */ - _initContainer () { - // contexte - var self = this; - - var _found = false; - var _obj = JSON.parse(JSON.stringify(this.options.obj)); // on manipule une copie ! - var _style = {}; - - // styles into tag 'paint' ? - if (_obj.paint) { - _found = true; - _style.paint = _obj.paint; - if (Object.keys(_obj.paint).length === 0) { - logger.info("tag 'paint' is empty !"); - } - } - - // if not, search into tag 'layout' ! - if (_obj.layout) { - _found = true; - _style.layout = _obj.layout; - // FIXME delete visibility from display ? - if (_obj.layout.visibility) { - delete _style.visibility; - } - if (Object.keys(_obj.layout).length === 0) { - logger.info("tag 'layout' is empty !"); - } - } - - var div = document.createElement("div"); - div.className = this.name.container; - - var json = null; - if (_found) { - var strJson = JSON.stringify(_style, null, 4); - json = this._syntaxHighlight(strJson); - } - - var divJson = document.createElement("div"); - divJson.className = this.name.containerjson; - - var label = document.createElement("label"); - label.className = this.name.jsonlabel; - label.innerHTML = this.options.title; - divJson.appendChild(label); - - var pre = document.createElement("pre"); - pre.className = this.name.jsondisplay; - pre.innerHTML = json; - if (pre.addEventListener) { - pre.addEventListener("click", function (e) { - if (self.options.tools.edition) { - self.onEditJsonStyleMapBox(e); - } - }); - } else if (pre.attachEvent) { - pre.attachEvent("onclick", function (e) { - if (self.options.tools.edition) { - self.onEditJsonStyleMapBox(e); - } - }); - } - divJson.appendChild(pre); - div.appendChild(divJson); - - // scale - if (this.options.tools.scale) { - div.appendChild(this._createElementToolsScale({ - min : (_style.layout) ? _style.layout.minzoom : 0, - max : (_style.layout) ? _style.layout.maxzoom : 21 - })); - } - - // TODO menu d'edition - if (this.options.tools.edition) { - div.appendChild(this._createElementToolsEdition()); - } - - // main container - this.container = div; - } - - /** - * Graphical rendering of the scale tools - * - * @param {Object} scale - {min,max} or 0|21 - * @returns {DOMElement} DOM element - * - * @private - * @example - *
- */ - _createElementToolsScale (scale) { - logger.trace("_createElementToolsScale"); - - var self = this; - - var obj = this.options.obj; - - var divToolsScale = document.createElement("div"); - divToolsScale.className = this.name.containertoolsscale; - - // FIXME Titre ? - // var label = document.createElement("label"); - // label.className = this.name.scaletitle; - // label.innerHTML = "Scale :"; - // divToolsScale.appendChild(label); - var divMin = document.createElement("div"); - divMin.className = this.name.containertoolsminscale; - - var labelMin = document.createElement("label"); - labelMin.className = this.name.scalelabelmin; - labelMin.innerHTML = "min :"; - divMin.appendChild(labelMin); - - var inputMin = document.createElement("input"); - inputMin.className = this.name.scaleinputmin; - inputMin.type = "range"; - inputMin.value = scale.min || 0; - inputMin.title = scale.min || 0; - inputMin.disabled = false; - inputMin.min = 0; - inputMin.max = 21; - inputMin.data = obj; // on lie le DOM et la couche, utile lors d'evenement ! - if (inputMin.addEventListener) { - inputMin.addEventListener("change", function (e) { - self.onChangeStyleScaleMinMapBox(e); - }); - } else if (inputMin.appendChild) { - inputMin.appendChild("onchange", function (e) { - self.onChangeStyleScaleMinMapBox(e); - }); - } - divMin.appendChild(inputMin); - - divToolsScale.appendChild(divMin); - - var divMax = document.createElement("div"); - divMax.className = this.name.containertoolsmaxscale; - - var labelMax = document.createElement("label"); - labelMax.className = this.name.scalelabelmax; - labelMax.innerHTML = "max :"; - divMax.appendChild(labelMax); - - var inputMax = document.createElement("input"); - inputMax.className = this.name.scaleinputmin; - inputMax.type = "range"; - inputMax.value = scale.max || 21; - inputMax.title = scale.max || 21; - inputMax.disabled = false; - inputMax.min = 0; - inputMax.max = 21; - inputMax.data = obj; // on lie le DOM et la couche, utile lors d'evenement ! - if (inputMax.addEventListener) { - inputMax.addEventListener("change", function (e) { - self.onChangeStyleScaleMaxMapBox(e); - }); - } else if (inputMax.appendChild) { - inputMax.appendChild("onchange", function (e) { - self.onChangeStyleScaleMaxMapBox(e); - }); - } - divMax.appendChild(inputMax); - - divToolsScale.appendChild(divMax); - - return divToolsScale; - } - - /** - * Graphical rendering of the edition tools - * - * @returns {DOMElement} DOM element - * - * @private - * @example - *
- */ - _createElementToolsEdition () { - logger.warn("_createElementToolsEdition, it's not yet implemented !"); - - var divToolsEdit = document.createElement("div"); - divToolsEdit.className = this.name.containertoolsedit; - - return divToolsEdit; - } - - // ################################################################### // - // ##################### private methods ############################# // - // ################################################################### // - /** - * Transform a JSON into a DOM with a syntax in color - * - * @private - * @param {Object} json - json. - * @returns {DOMElement} dom element - */ - _syntaxHighlight (json) { - json = json.replace(/&/g, "&").replace(//g, ">"); - return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g, function (match) { - var cls = "gp-json-number"; - if (/^"/.test(match)) { - if (/:$/.test(match)) { - cls = "gp-json-key"; - } else { - cls = "gp-json-string"; - } - } else if (/true|false/.test(match)) { - cls = "gp-json-boolean"; - } else if (/null/.test(match)) { - cls = "gp-json-null"; - } - return "" + match + ""; - }); - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - /** - * Add element into target DOM - * @returns {Object} - Legend instance - */ - add () { - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); - } - this.options.target = document.getElementById(this.name.target); - } - if (this.container) { - this.options.target.appendChild(this.container); - } - return this; - } - - /** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ - display (display) { - logger.trace("display()", display); - if (typeof display !== "undefined") { - this.container.style.display = (display) ? "flex" : "none"; - } - return (this.container.style.display === "flex"); - } - - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer () { - return this.container; - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Style#editor:style:oneditjson - */ - onEditJsonStyleMapBox (e) { - logger.trace("onEditJsonStyleMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.style.oneditjson, e); - } - - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Style#editor:style:scale:onchangemin - */ - onChangeStyleScaleMinMapBox (e) { - logger.trace("onChangeStyleScaleMinMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.style.scale.onchangemin, e); - } - - /** - * this method is called by event '' on '' tag form... - * - * 'e' contains the option object into 'e.target.data' ! - * 'e' contains the id editor into 'e.target.editorID' ! - * - * @param {Object} e - HTMLElement - * @private - * @fires Style#editor:style:scale:onchangemax - */ - onChangeStyleScaleMaxMapBox (e) { - logger.trace("onChangeStyleScaleMaxMapBox", e); - e.editorID = this.id; - e.data = this.options; - EventBus.dispatch(EventEditor.style.scale.onchangemax, e); - } - -}; - -export default Style; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Themes.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Themes.d.ts deleted file mode 100644 index d946d3c07..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Themes.d.ts +++ /dev/null @@ -1,120 +0,0 @@ -export default Themes; -/** - * @classdesc - * - * Mapbox Themes management - * - * @constructor - * @alias ol.style.editor.Theme - * @param {Object} options - options for function call. - * @example - * var theme = new Themes ({ - * "target": "", - * "tools": { - * "thumbnails": true, - * "button" : { - * "visible" : true, - * "type" : "radio" (par defaut) | "checkbox" - * } - * }, - * "obj": { - * "themesSummary": "", // Titre du composant (non graphique !) - * "themes": [{ - * "thumbnail": "data/images/layer0.png", - * "name": "standard0", - * "url": "data/styles/layer0.json", - * "description": "", - * "selected" : true - * },{ - * "thumbnail": "data/images/layer1.png", - * "name": "standard1", - * "url": "data/styles/layer1.json", - * "description": "" - * }] - * } - * }); - * theme.add(); - * theme.display(true); - * theme.getContainer(); - */ -declare class Themes { - constructor(options: any); - options: any; - /** - * Initialize component - * (called by constructor) - * - * @private - */ - private _initialize; - id: any; - container: HTMLDivElement | null | undefined; - name: { - target: string; - container: string; - containertheme: string; - containerthemeID: string; - input: string; - inputID: string; - label: string; - labelID: string; - image: string; - imageID: string; - message: string; - } | undefined; - /** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
- *
- * - * Description1 - * - *
- *
- * - * Description2 - * - *
- *
- */ - private _initContainer; - /** - * Add element into target DOM - * @returns {Object} - Legend instance - */ - add(): Object; - /** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ - display(display: boolean): boolean; - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer(): DOMElement; - /** - * this method is called by event '' on '' tag form - * - * @param {Object} e - HTMLElement - * @private - * @fires Themes#editor:themes:image - */ - private onClickThemeImageMapBox; - /** - * this method is called by event '' on '' tag form - * - * @param {Object} e - HTMLElement - * @private - * @fires Themes#editor:themes:title - */ - private onClickThemeTitleMapBox; -} -//# sourceMappingURL=Themes.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Themes.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Themes.d.ts.map deleted file mode 100644 index ccec6c8c1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Themes.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Themes.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Editor/Themes.js"],"names":[],"mappings":";AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH;IAEI,0BAeC;IAXG,aAEC;IAWL;;;;;OAKG;IACH,oBAgDC;IA9CG,QAAiC;IA8BjC,6CAAqB;IAGrB;;;;;;;;;;;;kBAYC;IAGL;;;;;;;;;;;;;;;;;;OAkBG;IACH,uBA4HC;IAKD;;;OAGG;IACH,OAFa,MAAM,CAkBlB;IAED;;;;;OAKG;IACH,mCAMC;IAED;;;;OAIG;IACH,2BAEC;IAKD;;;;;;OAMG;IACH,gCAuBC;IAED;;;;;;OAMG;IACH,gCAqBC;CAEJ"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Themes.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Themes.js deleted file mode 100644 index d7225fbbd..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Editor/Themes.js +++ /dev/null @@ -1,382 +0,0 @@ -import EventBus from "eventbusjs"; -import EventEditor from "./Event"; -import Utils from "../../Utils/Helper"; -import ID from "../../Utils/SelectorID"; -import Logger from "../../Utils/LoggerByDefault"; - -var logger = Logger.getLogger("editor-themes"); - -/** - * @classdesc - * - * Mapbox Themes management - * - * @constructor - * @alias ol.style.editor.Theme - * @param {Object} options - options for function call. - * @example - * var theme = new Themes ({ - * "target": "", - * "tools": { - * "thumbnails": true, - * "button" : { - * "visible" : true, - * "type" : "radio" (par defaut) | "checkbox" - * } - * }, - * "obj": { - * "themesSummary": "", // Titre du composant (non graphique !) - * "themes": [{ - * "thumbnail": "data/images/layer0.png", - * "name": "standard0", - * "url": "data/styles/layer0.json", - * "description": "", - * "selected" : true - * },{ - * "thumbnail": "data/images/layer1.png", - * "name": "standard1", - * "url": "data/styles/layer1.json", - * "description": "" - * }] - * } - * }); - * theme.add(); - * theme.display(true); - * theme.getContainer(); - */ -class Themes { - - constructor (options) { - logger.trace("[constructor] Themes", options); - - // options - this.options = options || { - // TODO default... - }; - - if (!(this instanceof Themes)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this._initialize(); - - this._initContainer(); - } - - /** - * Initialize component - * (called by constructor) - * - * @private - */ - _initialize () { - // unique editor id (optional!) - this.id = this.options.id || null; - - if (!this.options.target) { - // cf. add() - } - - var _toolsDefault = { - thumbnails : true, - button : { - visible : true, - type : "radio" - } - }; - - if (!this.options.tools || Object.keys(this.options.tools).length === 0) { - this.options.tools = _toolsDefault; - } - - Utils.mergeParams(this.options.tools, _toolsDefault, false); - - if (typeof this.options.obj === "undefined" || - this.options.obj === null || - !this.options.obj) { - // vide par defaut ? - this.options.obj = { - themesSummary : "", - themes : [] - }; - } - - this.container = null; - - // DOM : className or id - this.name = { - target : "GPEditorMapBoxThemeTarget", - container : "GPEditorMapBoxThemesContainer", - containertheme : "GPEditorMapBoxThemeContainer", - containerthemeID : "GPEditorMapBoxThemeContainer_ID_", - input : "GPEditorMapBoxThemeInput", - inputID : "GPEditorMapBoxThemeInput_ID_", - label : "GPEditorMapBoxThemeTitle", - labelID : "GPEditorMapBoxThemeTitle_ID_", - image : "GPEditorMapBoxThemeImage", - imageID : "GPEditorMapBoxThemeImage_ID_", - message : "GPEditorMapBoxThemeMessage" - }; - } - - /** - * Graphical rendering of the component - * (called by constructor) - * - * @private - * @example - *
- *
- * - * Description1 - * - *
- *
- * - * Description2 - * - *
- *
- */ - _initContainer () { - // contexte - var self = this; - - var obj = this.options.obj; - - var id = this.id || ID.generate(); - - // div principale - var div = document.createElement("div"); - div.className = this.name.container; - div.title = obj.themesSummary || ""; - - var _lstThemes = obj.themes; - if (_lstThemes) { - for (var i = 0; i < _lstThemes.length; i++) { - var _theme = _lstThemes[i]; - - // div pour chaque theme - var divTheme = document.createElement("div"); - divTheme.id = this.name.containerthemeID + i + "_" + id; - divTheme.className = this.name.containertheme; - divTheme.tabIndex = i; - - // url du style est obligatoire ! - var _url = _theme.url; - // style selectionné par defaut (uniquement en mode radio-button !?) - var _selected = _theme.selected || false; - if (_url) { - // bouton - var button = this.options.tools.button; - if (button.visible) { - var _type = (button.type === "checkbox") ? "checkbox" : "radio"; - var _button = document.createElement("input"); - _button.type = _type; - _button.id = this.name.inputID + i + "_" + id; - _button.className = this.name.input; - _button.name = id; - _button.checked = _selected; - _button.data = _url; // on lie le DOM et la couche, utile lors d'evenement ! - if (_button.addEventListener) { - _button.addEventListener("click", function (e) { - self.onClickThemeTitleMapBox(e); - }); - } else if (_button.attachEvent) { - _button.attachEvent("onclick", function (e) { - self.onClickThemeTitleMapBox(e); - }); - } - divTheme.appendChild(_button); - } - // vignette - if (this.options.tools.thumbnails) { - if (_theme.thumbnail) { - var _img = document.createElement("img"); - _img.id = this.name.imageID + i + "_" + id; - _img.className = this.name.image; - _img.src = _theme.thumbnail; - _img.alt = _theme.thumbnail; - _img.title = _theme.description || ""; // une description au survol de l'image ou titre... - _img.data = _url; // on lie le DOM et la couche, utile lors d'evenement ! - if (_img.addEventListener) { - _img.addEventListener("click", function (e) { - self.onClickThemeImageMapBox(e); - // maj du radio button - var nodes = e.target.parentElement.childNodes; - if (nodes) { - var node = nodes[0]; - if (node.tagName.toLowerCase() === "input") { - node.checked = !node.checked; - } - } - }); - } else if (_img.attachEvent) { - _img.attachEvent("onclick", function (e) { - self.onClickThemeImageMapBox(e); - var nodes = e.target.parentElement.childNodes; - if (nodes) { - var node = nodes[0]; - if (node.tagName.toLowerCase() === "input") { - node.checked = !node.checked; - } - } - }); - } - divTheme.appendChild(_img); - } - } - // label - if (_theme.name) { - var _label = document.createElement("label"); - _label.id = this.name.labelID + i + "_" + id; - if (this.options.tools.button.visible) { - _label.htmlFor = _button.id; - } - _label.className = this.name.label; - _label.innerHTML = _theme.name; - _label.title = _theme.description || ""; // une description au survol de l'image ou titre... - _label.data = _url; // on lie le DOM et la couche, utile lors d'evenement ! - if (!this.options.tools.button.visible) { - if (_label.addEventListener) { - _label.addEventListener("click", function (e) { - self.onClickThemeTitleMapBox(e); - }); - } else if (_label.attachEvent) { - _label.attachEvent("onclick", function (e) { - self.onClickThemeTitleMapBox(e); - }); - } - } - divTheme.appendChild(_label); - } - } else { - var _msg = document.createElement("label"); - _msg.className = this.name.message; - _msg.innerHTML = "Thème non disponible..."; - divTheme.appendChild(_msg); - } - - div.appendChild(divTheme); - } - } - - this.container = div; - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - /** - * Add element into target DOM - * @returns {Object} - Legend instance - */ - add () { - if (!this.options.target) { - if (!document.getElementById(this.name.target)) { - var div = document.createElement("div"); - div.id = this.name.target; - var node = document.documentElement || - document.getElementsByTagName("body")[0] || - document.getElementsByTagName("head")[0]; - node.appendChild(div); - } - this.options.target = document.getElementById(this.name.target); - } - if (this.container) { - this.options.target.appendChild(this.container); - } - return this; - } - - /** - * Set display container or get - * - * @param {Boolean} display - show/hidden container or get status - * @returns {Boolean} - true/false - */ - display (display) { - logger.trace("display()", display); - if (typeof display !== "undefined") { - this.container.style.display = (display) ? "flex" : "none"; - } - return (this.container.style.display === "flex"); - } - - /** - * Get container (DOM) - * - * @returns {DOMElement} DOM element - */ - getContainer () { - return this.container; - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - /** - * this method is called by event '' on '' tag form - * - * @param {Object} e - HTMLElement - * @private - * @fires Themes#editor:themes:image - */ - onClickThemeImageMapBox (e) { - logger.trace("onClickThemeImageMapBox", e); - e.editorID = this.id; - e.data = this.options; - if (this.options.tools.button.type === "checkbox") { - // GPEditorMapBoxThemeInput_ID_0_1571317605868 - var targetIDX = e.target.previousSibling.id.substring( - e.target.previousSibling.id.lastIndexOf("_") + 1 - ); - var _inputs = document.getElementsByClassName(this.name.input); - for (var i = 0; i < _inputs.length; i++) { - var el = _inputs[i]; - if (el.id === e.target.previousSibling.id) { - continue; - } - var elIDX = el.id.substring(el.id.lastIndexOf("_") + 1); - if (elIDX !== targetIDX) { - continue; - } - el.checked = false; - } - } - EventBus.dispatch(EventEditor.themes.onclickimage, e); - } - - /** - * this method is called by event '' on '' tag form - * - * @param {Object} e - HTMLElement - * @private - * @fires Themes#editor:themes:title - */ - onClickThemeTitleMapBox (e) { - logger.trace("onClickThemeTitleMapBox", e); - e.editorID = this.id; - e.data = this.options; - if (this.options.tools.button.type === "checkbox") { - // GPEditorMapBoxThemeInput_ID_0_1571317605868 - var targetIDX = e.target.id.substring(e.target.id.lastIndexOf("_") + 1); - var _inputs = document.getElementsByClassName(this.name.input); - for (var i = 0; i < _inputs.length; i++) { - var el = _inputs[i]; - if (el.id === e.target.id) { - continue; - } - var elIDX = el.id.substring(el.id.lastIndexOf("_") + 1); - if (elIDX !== targetIDX) { - continue; - } - el.checked = false; - } - } - EventBus.dispatch(EventEditor.themes.onclicktitle, e); - } - -}; - -export default Themes; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPath.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPath.d.ts deleted file mode 100644 index 4e04cf781..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPath.d.ts +++ /dev/null @@ -1,73 +0,0 @@ -export default ElevationPath; -/** - * @classdesc - * - * Elevation Path Control. Allows users to draw a path on a Openlayers map see the elevation profile computed with geoportal elevation path web service along that path. - * - * @constructor - * @alias ol.control.ElevationPath - * @type {ol.control.ElevationPath} - * @extends ol.control.Control - * @param {Object} options - options for function call. - * @param {String} [options.apiKey] - API key for services call (isocurve and autocomplete services). The key "calcul" is used by default. - * @param {Boolean} [options.active = false] - specify if control should be actived at startup. Default is false. - * @param {Boolean} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean|Object} [options.export = false] - Specify if button "Export" is displayed. For the use of the options of the "Export" control, see {@link ol.control.Export} - * @param {Object} [options.elevationOptions = {}] - elevation path service options. See {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~getAltitude Gp.Services.getAltitude()} for available options - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Profil altimétrique"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Mon profil altimétrique"] - Layer description to be displayed in LayerSwitcher - * @param {Object} [options.stylesOptions] - styles management - * @param {Object} [options.stylesOptions.marker = {}] - styles management of marker displayed on map when the user follows the elevation path. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Image-ImageStyle.html ol.style.Image} subclass object - * @param {Object} [options.stylesOptions.draw = {}] - styles used when drawing. Specified with following properties. - * @param {Object} [options.stylesOptions.draw.pointer = {}] - Style for mouse pointer when drawing the line. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Image-ImageStyle.html ol.style.Image} subclass object. - * @param {Object} [options.stylesOptions.draw.start = {}] - Line Style when drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Stroke-Stroke.html ol.style.Stroke} object. - * @param {Object} [options.stylesOptions.draw.finish = {}] - Line Style when finished drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Stroke-Stroke.html ol.style.Stroke} object. - * @param {Object} [options.displayProfileOptions = {}] - profile options. - * @param {Boolean} [options.displayProfileOptions.totalDistance = true] - display the total distance of the path - * @param {Boolean} [options.displayProfileOptions.greaterSlope = true] - display the greater slope into the graph - * @param {Boolean} [options.displayProfileOptions.meanSlope = true] - display the mean slope into the graph - * @param {Boolean} [options.displayProfileOptions.ascendingElevation = true] - display the ascending elevation into the graph - * @param {Boolean} [options.displayProfileOptions.descendingElevation = true] - display the descending elevation into the graph - * @param {Boolean} [options.displayProfileOptions.currentSlope = true] - display current slope value on profile mouseover - * @param {Function} [options.displayProfileOptions.apply] - function to display profile if you want to cutomise it. By default, ([DISPLAY_PROFILE_BY_DEFAULT()](./ol.control.ElevationPath.html#.DISPLAY_PROFILE_BY_DEFAULT)) is used. Helper functions to use with D3 ([DISPLAY_PROFILE_LIB_D3()](./ol.control.ElevationPath.html#.DISPLAY_PROFILE_LIB_D3)) or AmCharts ([DISPLAY_PROFILE_LIB_AMCHARTS()](./ol.control.ElevationPath.html#.DISPLAY_PROFILE_LIB_AMCHARTS)) frameworks are also provided. You may also provide your own function. - * @param {Object} [options.displayProfileOptions.target] - DOM container to use to display the profile. - * @fires elevationpath:drawstart - * @fires elevationpath:drawend - * @fires elevationpath:compute - * @fires export:compute - * @example - * - * var measure = new ol.control.ElevationPath({ - * export : false, - * stylesOptions : { - * draw : { - * finish : new ol.style.Stroke({ - * color : "rgba(0, 0, 0, 0.5)", - * width : 2 - * }) - * }, - * } - * displayProfileOptions : { - * apply : ol.control.ElevationPath.DISPLAY_PROFILE_RAW, - * } - * }); - * - * // if you want to pluggued the control Export with options : - * var measure = new ol.control.ElevationPath({ - * export : { - * name : "export", - * format : "geojson", - * title : "Exporter", - * menu : false - * } - * }); - * - * Exemples : - * - displayProfileOptions.apply : null - * - displayProfileOptions.apply : function (elevations, container, context) { // do some stuff... } - * - displayProfileOptions.apply : ol.control.ElevationPath.DISPLAY_PROFILE_{LIB_AMCHARTS | LIB_D3 | RAW} - * - */ -declare var ElevationPath: ol.control.ElevationPath; -//# sourceMappingURL=ElevationPath.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPath.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPath.d.ts.map deleted file mode 100644 index 7ea280b92..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPath.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ElevationPath.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/ElevationPath/ElevationPath.js"],"names":[],"mappings":";AA0CA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,oDAolDE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPath.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPath.js deleted file mode 100644 index ce666a4c3..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPath.js +++ /dev/null @@ -1,1743 +0,0 @@ -/** globals AmCharts, d3 */ -// import CSS -import "../../CSS/Controls/ElevationPath/GPFelevationPath.css"; -// import "../../CSS/Controls/ElevationPath/GPFelevationPathStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -import { - Fill, - Icon, - Stroke, - Style, - Image, - Circle -} from "ol/style"; -import { Point } from "ol/geom"; -import { Draw as DrawInteraction } from "ol/interaction"; -import { transform as olTransformProj } from "ol/proj"; -import { getDistance as olGetDistanceSphere } from "ol/sphere"; -import Feature from "ol/Feature"; -import VectorLayer from "ol/layer/Vector"; -import VectorSource from "ol/source/Vector"; -// import geoportal library access -import Gp from "geoportal-access-lib"; -// import local -import Utils from "../../Utils/Helper"; -import Logger from "../../Utils/LoggerByDefault"; -import ID from "../../Utils/SelectorID"; -import Markers from "../Utils/Markers"; -// import local with ol dependencies -import Interactions from "../Utils/Interactions"; -import MeasureToolBox from "../ToolBoxMeasure/MeasureToolBox"; -import Measures from "../Measures/Measures"; -import LayerSwitcher from "../LayerSwitcher/LayerSwitcher"; -import ButtonExport from "../Export/Export"; -import GeoJSONExtended from "../../Formats/GeoJSON"; -// DOM -import ElevationPathDOM from "./ElevationPathDOM"; -import ProfileElevationPathDOM from "./ProfileElevationPathDOM"; - -var logger = Logger.getLogger("elevationpath"); - -/** - * @classdesc - * - * Elevation Path Control. Allows users to draw a path on a Openlayers map see the elevation profile computed with geoportal elevation path web service along that path. - * - * @constructor - * @alias ol.control.ElevationPath - * @type {ol.control.ElevationPath} - * @extends ol.control.Control - * @param {Object} options - options for function call. - * @param {String} [options.apiKey] - API key for services call (isocurve and autocomplete services). The key "calcul" is used by default. - * @param {Boolean} [options.active = false] - specify if control should be actived at startup. Default is false. - * @param {Boolean} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean|Object} [options.export = false] - Specify if button "Export" is displayed. For the use of the options of the "Export" control, see {@link ol.control.Export} - * @param {Object} [options.elevationOptions = {}] - elevation path service options. See {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~getAltitude Gp.Services.getAltitude()} for available options - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Profil altimétrique"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Mon profil altimétrique"] - Layer description to be displayed in LayerSwitcher - * @param {Object} [options.stylesOptions] - styles management - * @param {Object} [options.stylesOptions.marker = {}] - styles management of marker displayed on map when the user follows the elevation path. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Image-ImageStyle.html ol.style.Image} subclass object - * @param {Object} [options.stylesOptions.draw = {}] - styles used when drawing. Specified with following properties. - * @param {Object} [options.stylesOptions.draw.pointer = {}] - Style for mouse pointer when drawing the line. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Image-ImageStyle.html ol.style.Image} subclass object. - * @param {Object} [options.stylesOptions.draw.start = {}] - Line Style when drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Stroke-Stroke.html ol.style.Stroke} object. - * @param {Object} [options.stylesOptions.draw.finish = {}] - Line Style when finished drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Stroke-Stroke.html ol.style.Stroke} object. - * @param {Object} [options.displayProfileOptions = {}] - profile options. - * @param {Boolean} [options.displayProfileOptions.totalDistance = true] - display the total distance of the path - * @param {Boolean} [options.displayProfileOptions.greaterSlope = true] - display the greater slope into the graph - * @param {Boolean} [options.displayProfileOptions.meanSlope = true] - display the mean slope into the graph - * @param {Boolean} [options.displayProfileOptions.ascendingElevation = true] - display the ascending elevation into the graph - * @param {Boolean} [options.displayProfileOptions.descendingElevation = true] - display the descending elevation into the graph - * @param {Boolean} [options.displayProfileOptions.currentSlope = true] - display current slope value on profile mouseover - * @param {Function} [options.displayProfileOptions.apply] - function to display profile if you want to cutomise it. By default, ([DISPLAY_PROFILE_BY_DEFAULT()](./ol.control.ElevationPath.html#.DISPLAY_PROFILE_BY_DEFAULT)) is used. Helper functions to use with D3 ([DISPLAY_PROFILE_LIB_D3()](./ol.control.ElevationPath.html#.DISPLAY_PROFILE_LIB_D3)) or AmCharts ([DISPLAY_PROFILE_LIB_AMCHARTS()](./ol.control.ElevationPath.html#.DISPLAY_PROFILE_LIB_AMCHARTS)) frameworks are also provided. You may also provide your own function. - * @param {Object} [options.displayProfileOptions.target] - DOM container to use to display the profile. - * @fires elevationpath:drawstart - * @fires elevationpath:drawend - * @fires elevationpath:compute - * @fires export:compute - * @example - * - * var measure = new ol.control.ElevationPath({ - * export : false, - * stylesOptions : { - * draw : { - * finish : new ol.style.Stroke({ - * color : "rgba(0, 0, 0, 0.5)", - * width : 2 - * }) - * }, - * } - * displayProfileOptions : { - * apply : ol.control.ElevationPath.DISPLAY_PROFILE_RAW, - * } - * }); - * - * // if you want to pluggued the control Export with options : - * var measure = new ol.control.ElevationPath({ - * export : { - * name : "export", - * format : "geojson", - * title : "Exporter", - * menu : false - * } - * }); - * - * Exemples : - * - displayProfileOptions.apply : null - * - displayProfileOptions.apply : function (elevations, container, context) { // do some stuff... } - * - displayProfileOptions.apply : ol.control.ElevationPath.DISPLAY_PROFILE_{LIB_AMCHARTS | LIB_D3 | RAW} - * - */ -var ElevationPath = class ElevationPath extends Control { - - /** - * See {@link ol.control.ElevationPath} - * @module ElevationPath - * @alias module:~Controls/ElevationPath - * @param {*} options - options - * @example - * import ElevationPath from "src/OpenLayers/Controls/ElevationPath" - */ - constructor (options) { - logger.trace("ElevationPath()"); - - /** - * options - * @private - */ - options = options || {}; - - // call ol.control.Control constructor - super({ - element : options.element, - target : options.target, - render : options.render - }); - - if (!(this instanceof ElevationPath)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - /** - * Nom de la classe (heritage) - * @private - */ - this.CLASSNAME = "ElevationPath"; - - // uuid - this._uid = ID.generate(); - - // container : HTMLElement - this._showContainer = null; - this._pictoButton = null; - this._panelContainer = null; - this._profileContainer = null; - this._waitingContainer = null; - this._infoContainer = null; - - // timer sur la fenetre d'informations des données - this._timerHdlr = null; - - // objet de type "ol.style" - this._drawStyleStart = null; - this._drawStyleFinish = null; - this._markerStyle = null; - - // graph - this._profile = null; - - // data elevations - this._data = {}; - - /* objet de type - "ol.source.Vector", - "ol.layer.Vector", - "ol.interaction.Draw" - */ - this._measureSource = null; - this._measureVector = null; - this._measureDraw = null; - - // objet de type ol.feature, saisie en cours - this._lastSketch = null; - this._currentSketch = null; - - // objet de type ol.feature, marker - this._marker = null; - - // initialisation du composant - this._initialize(options); - - // creation du DOM container - this._container = this._initializeContainer(); - - // ajout du container - (this.element) ? this.element.appendChild(this._container) : this.element = this._container; - - return this; - } - - /** - * Styles applied by default if stylesOptions property is not set. - */ - static DEFAULT_STYLES = { - // styling drawing by default - // see => Measures.DEFAULTS_STYLES - // stying marker to the profile by default - MARKER : new Icon({ - src : Markers["lightOrange"], - // image avec un mauvais ratio size 51/38 pixels - // src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAsCAYAAAAATWqyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABTtJREFUeNq8WGtsFUUU/rb3gtdCAykFG9AUDTQUKimhxUewEusrJYoBo4FfEgoqotHERH6oP9TGmJhIrIlWAf9hjAaEiME2pgFfVVpFii8sWqIQLLSx3EJLW7p+Z2Z2b2l7d/b23vZLTmZ2duacb2fmnDk7DlKA67rXs1hJKacsohRQppjXFygnKT9TDlH2O47zFzIFGnco91EOuqnjoBnr2Ow4FhIlLN6m3DykFTh3BGj/Doj/CfSe082xPCDnBmDWTUBeyXDVjZTHOUNHUiZCEs+weI0ySTV0/w0c2wa07gIungn+vOx8YN46oPhpYOp1Xms/5TmSeSMUERKImFnYqBoGuPRNL5LEW8BgX2rrmjWZZLYApS8BUW8r4T0zO5eTEjFr+S6lSjV0HgPqVwNdf6S30abNB+7aDeQWey3bKZtIxvU5DxvyrE/izJfAvuXpkxCIDtElOjWqjK2RM8LZWMbiG0oEnUc5kB7a14WMYvI04H56du5ieZKluZWz8r0/IyQh5TuKRH8cqFuTeRIC0Sm6xYbYok1j21+ahyhLVO3wC8D5VowbRLfY0FhibOulIavDLEoRZyD8sJDeMWBXKG5ZsIobsdDsg+OMq3u1m1u9KQo8zP45EqjRxOUpk6i50IRl4FuGjpZtwUoiMYa314GFj/EzIsN8n8v+C1e4kfvwcm+wnhsZY27xQ8oiWZpKrWRQB6tAElfxpKnjsCdGklDzG9HvpI/0DYLYEpsalVnmAAM6fgR62oMHl70C5N9mn3rpI32DILbEpkZ5ljlFgbPNFtebzij5VPhNKX1lTBASNtXSzPZ3cxCuvVOH7FTCu4yxeZDGbCES0z5+PniQ3uGpwTYmYTOWCPGTpgYP6u9OnYhtzBCbQkSH0NiM4EEdP6VOxDYmYbNLiJxQ1elFwYPaG3XQCn3QHddjgpCweUKI6K2bvzw4YROf//rJob6fZl/H2FRoFiINfqo3qyzYwD8MVIeYLw32J+8j76SP9A2C2BKbGg1CZL+EF/W4YKP9a3/fCeyhkrY9DOOXEu1SlzZ5J31sSNjqURm/OfQkY9qgvkYOvXhbuH0g505Oga7HT9rPF9+t5+pDL0ulwzt46FV5ROax+JUSRRtP0LoHMK64+xNg7iqVEVOKSKRVxRGpsKhRnaRD4SPjR0J0axKCGmP7ilQxm4X8d8xXmfvHJZlPkCR3WfODl9FLMlxCIhevSJ5Nwzo1XdKxYpe3hpmB6BKdmoS43VqPxIgsni+aWOg8biZ3f+nLmSMiuvKWek/P01az7QdLyNVT7lC/l59WAKcb0iMxhzpW1nvmvpDtSiKD1l9OkpnDgv8UyMWFU9wvTP8vdY6NhJwnD1JVtso2OiiLSeL0iJUbNfg6zikVVwRTyOn2HWOfjfLtHgnBhtFIJCViyNDZUatdmnGlaFPqJIoe1WM1aqlz71ivJbLNobgAA9zgu7nZ/vstHAk5WVdzaPRqmGC5lER6kjpV4OWJdq+1kkshSk4VH9izcy/bV66qSPQZV+0J9G7rTY6+XNmqHmYwyJVV24kse1X31dhKHdasygkzy+a64oC4nWr47F4e858nSbLv4V/KAe9JKpVDrx/SImLIXMOiRUKdujESl+49O8xVZxpXzVc/C/I/RxL/hgq8YYkYhev9q6kVO4d9B+sr3vdICNaHJTHWW8Ya/87wqy2uWwstUk/gTYw3aCRGOarMDfS67kfFWqSuIe9imAjQEC272nJHixYNaSvGRIIGN49ywbsZEw1zI11N6TZSHeaGORn+F2AAJtRIMx4t+hUAAAAASUVORK5CYII=", - anchor : [0.5, 1], - snapToPixel : true - }), - // styling service results points by default - RESULTS : { - // INFO orienté maintenance ! - imageRadius : 5, - imageFillColor : "rgba(128, 128, 128, 0.2)", - imageStrokeColor : "rgba(0, 0, 0, 0.7)", - imageStrokeWidth : 2 - } - // FIXME ??? - // PROFILE : { - // type : "serial", - // pathToImages : "http://cdn.amcharts.com/lib/3/images/", - // categoryField : "dist", - // autoMarginOffset : 0, - // marginRight : 10, - // marginTop : 10, - // startDuration : 0, - // color : "#5E5E5E", - // fontSize : 10, - // theme : "light", - // thousandsSeparator : "", - // categoryAxis : { - // color : "#5E5E5E", - // gridPosition : "start", - // minHorizontalGap : 40, - // tickPosition : "start", - // title : "Distance (km)", - // titleColor : "#5E5E5E", - // startOnAxis : true - // }, - // chartCursor : { - // animationDuration : 0, - // bulletsEnabled : true, - // bulletSize : 10, - // categoryBalloonEnabled : false, - // cursorColor : "#F90", - // graphBulletAlpha : 1, - // graphBulletSize : 1, - // zoomable : false - // }, - // trendLines : [], - // graphs : [ - // { - // balloonColor : "#CCCCCC", - // balloonText : "[[title]] : [[value]]m
(lat: [[lat]] / lon:[[lon]])", - // bullet : "round", - // bulletAlpha : 0, - // bulletBorderColor : "#FFF", - // bulletBorderThickness : 2,currentSlope - // bulletColor : "#F90", - // bulletSize : 6, - // hidden : false, - // id : "AmGraph-1", - // fillAlphas : 0.4, - // fillColors : "#C77A04", - // lineAlpha : 1, - // lineColor : "#C77A04", - // lineThickness : 1, - // title : "Altitude", - // valueField : "z" - // } - // ], - // guides : [], - // valueAxes : [ - // { - // id : "ValueAxis-1", - // minVerticalGap : 20, - // title : "Altitude (m)" - // } - // ], - // allLabels : [], - // balloon : { - // borderColor : "#CCCCCC", - // borderThickness : 1, - // fillColor : "#FFFFFF", - // showBullet : true - // }, - // titles : [] - // } - }; - - /** - * suppression du marker - * - * @param {Object} context - context - * - * @private - */ - static __removeProfileMarker (context) { - var self = context; - // suppression de l'ancien marker - if (self._marker) { - self._measureSource.removeFeature(self._marker); - self._marker = null; - } - }; - - /** - * suppression du marker - * - * @param {Object} context - context - * @param {Object} d - d - * - * @private - */ - static __createProfileMarker (context, d) { - var self = context; - // suppression de l'ancien marker - if (self._marker) { - self._measureSource.removeFeature(self._marker); - self._marker = null; - } - var map = self.getMap(); - var proj = map.getView().getProjection(); - - var _coordinate = olTransformProj([d.lon, d.lat], "EPSG:4326", proj); - var _coordinateProj = self._measureSource - .getFeatures()[0] - .getGeometry() - .getClosestPoint(_coordinate); - - var _geometry = new Point(_coordinateProj); - - self._marker = new Feature({ - geometry : _geometry - }); - logger.trace(_geometry); - - // style - self._marker.setStyle(self._markerStyle); - - // ajout du marker sur la map - self._measureSource.addFeature(self._marker); - } - - /** - * mise à jour du marker - * - * @param {Object} context - context - * @param {Object} d - data - * - * @private - */ - static __updateProfileMarker (context, d) { - var self = context; - ElevationPath.__removeProfileMarker(self); - ElevationPath.__createProfileMarker(self, d); - } - - /** - * TODO : customisation possible d'une opération sur le profil - * - * @param {Object} context - context - * @param {Object} d - data - * - * @private - */ - static __customRawProfileOperation (context, d) { - logger.log("__customRawProfileOperation"); - - var self = context; - - var _pts = d.points; - var _proj = self.getMap().getView().getProjection(); - for (var i = 0; i < _pts.length; i++) { - var obj = _pts[i]; - var _coordinate = olTransformProj([obj.lon, obj.lat], "EPSG:4326", _proj); - var _geometry = new Point(_coordinate); - - self._marker = new Feature({ - geometry : _geometry - }); - logger.trace(_geometry); - - // TODO style en options ? - var styles = ElevationPath.DEFAULT_STYLES.RESULTS; - var _image = new Circle({ - radius : styles.imageRadius, - stroke : new Stroke({ - color : styles.imageStrokeColor, - width : styles.imageStrokeWidth - }), - fill : new Fill({ - color : styles.imageFillColor - }) - }); - self._marker.setStyle(new Style({ - image : _image - })); - - // ajout du marker sur la map - self._measureSource.addFeature(self._marker); - } - } - - /** - * TODO : customisation possible d'une opération sur le profil - * Ex. Methode appélée dans le DOM : ProfileElevationPathDOM - * - * @param {Object} context - context - * @param {Object} e - event - * @private - */ - static __customRawProfileMouseOverEvent (context, e) { - logger.log("__customRawProfileMouseOverEvent", context, e); - } - - /** - * display Profile using Amcharts framework. This method needs AmCharts libraries to be loaded. - * - * @param {Object} data - collection elevations - * @param {HTMLElement} container - container - * @param {Object} context - this control object - */ - static DISPLAY_PROFILE_LIB_AMCHARTS (data, container, context) { - logger.trace("ElevationPath.DISPLAY_PROFILE_LIB_AMCHARTS"); - - // Calcul du profile - if (typeof AmCharts === "undefined") { - logger.log("Lib. AmCharts is not loaded !"); - return; - } - - var profile = ProfileElevationPathDOM.displayProfileLibAmCharts(data, container, context, ElevationPath); - // on sauvegarde le profil du container dans l'objet - if (profile) { - this._profile = profile; - } - } - - /** - * display Profile using D3 javascript framework. This method needs D3 libraries to be loaded. - * - * @param {Object} data - elevations values for profile - * @param {HTMLElement} container - html container where to display profile - * @param {Object} context - this control object - */ - static DISPLAY_PROFILE_LIB_D3 (data, container, context) { - logger.trace("ElevationPath.DISPLAY_PROFILE_LIB_D3"); - - // Calcul du profile - if (typeof d3 === "undefined") { - logger.log("Lib. D3 is not loaded !"); - return; - } - - var profile = ProfileElevationPathDOM.displayProfileLibD3(data, container, context, ElevationPath); - // on sauvegarde le profil du container dans l'objet - if (profile) { - this._profile = profile; - } - } - - /** - * display Profile without graphical rendering (raw service response) - * - * @param {Object} data - elevations values for profile - * @param {HTMLElement} container - html container where to display profile - * @param {Object} context - this control object - */ - static DISPLAY_PROFILE_RAW (data, container, context) { - logger.trace("ElevationPath.DISPLAY_PROFILE_RAW"); - - var profile = ProfileElevationPathDOM.displayProfileRaw(data, container, context, ElevationPath); - // on sauvegarde le profil du container dans l'objet - if (profile) { - this._profile = profile; - } - }; - - /** - * Display Profile function used by default : no additonal framework needed. - * - * @param {Object} data - elevations values for profile - * @param {HTMLElement} container - html container where to display profile - * @param {Object} context - this control object - */ - static DISPLAY_PROFILE_BY_DEFAULT (data, container, context) { - logger.trace("ElevationPath.DISPLAY_PROFILE_BY_DEFAULT"); - - var profile = ProfileElevationPathDOM.displayProfileByDefault(data, container, context, ElevationPath); - // on sauvegarde le profil du container dans l'objet - if (profile) { - this._profile = profile; - } - }; - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - - /** - * Attach control to map. Overloaded ol.control.Control.setMap() method. - * - * @param {ol.Map} map - Map. - */ - setMap (map) { - logger.trace("ElevationPath::setMap"); - - if (map) { - // activation des interactions de dessin selon la valeur de - // l'option active - if (this.options.active) { - // on n'affiche pas la fenetre de profile s'il n'existe pas... - if (this._profile === null) { - this._panelContainer.style.display = "none"; - // this._panelContainer.style.visibility = "hidden"; - } - this._initMeasureInteraction(map); - this._addMeasureInteraction(map); - } - - // ajout du composant dans une toolbox - if (!this.options.target && !this.options.position) { - MeasureToolBox.add(map, this); - } - - // ajout d'un bouton d'export - if (this.options.export) { - var opts = Utils.assign({ control : this }, this.options.export); - this.export = new ButtonExport(opts); - this.export.render(); - var self = this; - this.export.on("export:compute", (e) => { - self.dispatchEvent({ - type : "export:compute", - content : e.content - }); - }); - } - } - - // on appelle la méthode setMap originale d'OpenLayers - super.setMap(map); - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - }; - - /** - * Returns true if widget is actived (drawing), - * false otherwise - * - * @returns {Boolean} active - true or false - */ - getActive () { - logger.trace("ElevationPath::getActive"); - return this.options.active; - } - - /** - * Actived widget drawing or not - * - * @param {Boolean} active - true / false - */ - setActive (active) { - logger.trace("ElevationPath::setActive"); - this.options.active = active; - } - - /** - * Get elevation data - * - * @returns {Object} data - elevations - * @example - * { - * type // "elevationpath" - * greaterSlope // pente max - * meanSlope // pente moyenne - * distancePlus // distance cumulée positive - * distanceMinus // distance cumulée négative - * ascendingElevation // dénivelé cumulée positive - * descendingElevation // dénivelé cumulée négative - * altMin // altitude min - * altMax // altitude max - * distance // distance totale - * unit // unité des mesures de distance - * points // elevations - * } - */ - getData () { - return Utils.assign({ - type : "elevationpath" - }, this._data); - } - - /** - * Set profile data - * - * @param {*} data - elevations - * @example - * { - * greaterSlope // pente max - * meanSlope // pente moyenne - * distancePlus // distance cumulée positive - * distanceMinus // distance cumulée négative - * ascendingElevation // dénivelé cumulée positive - * descendingElevation // dénivelé cumulée négative - * altMin // altitude min - * altMax // altitude max - * distance // distance totale - * unit // unité des mesures de distance - * points // elevations - * } - */ - setData (data) { - this._data = data; - } - - /** - * Get container - * - * @returns {DOMElement} container - */ - getContainer () { - return this._container; - } - - /** - * Get layer - * - * @returns {ol.layer.Vector} layer - */ - getLayer () { - return this._measureVector; - } - - /** - * Set layer - * - * @param {Object} layer - ol.layer.Vector profil layer - */ - setLayer (layer) { - if (!layer) { - this._measureVector = null; - return; - } - - if (!(layer instanceof VectorLayer)) { - logger.log("no valid layer given for hosting drawn features."); - return; - } - - // application des styles - layer.setStyle(this._drawStyleFinish); - // sauvegarde - this._measureVector = layer; - this._measureSource = layer.getSource(); - } - - /** - * Get vector layer - * - * @returns {String} geojson - GeoJSON format layer - */ - getGeoJSON () { - var features = this._measureVector.getSource().getFeatures(); - - var Format = new GeoJSONExtended({ - defaultStyle : this._drawStyleFinish - }); - // INFO - // par defaut, webmercator ou "EPSG:3857" - var geojson = Format.writeFeatures(features, { - dataProjection : "EPSG:4326", - featureProjection : "EPSG:3857" - }); - - return geojson; - } - - /** - * Get default style - * - * @returns {ol.style} style - */ - getStyle () { - return this._drawStyleFinish; - } - - /** - * clean - * @param {Boolean} remove - remove layer - */ - clean (remove) { - logger.trace("ElevationPath::clean"); - - var map = this.getMap(); - - // fenetre du profil - this._panelContainer.style.display = "none"; - // this._panelContainer.style.visibility = "hidden"; - - // picto - this._pictoButton.setAttribute("aria-pressed", false); - - // this._removeMeasure(); - this._removeProfile(); - this._removeMeasureInteraction(map, typeof remove !== "undefined" ? remove : false); - - this.setLayer(); - } - - /** - * This method is public. - * It allows to init the control. - * @fixme - */ - init () { - // FIXME - // le panneau du profil ne peut pas afficher un profil si il est caché - // car le profil est calculé en fonction de la taille du panneau (clientHeight / clientWidth), - // et ces valeurs sont à 0 !? - this._pictoButton.setAttribute("aria-pressed", true); - this._panelContainer.style.display = "block"; - this._displayProfile(this._data); - this._waitingContainer.className = "GPwaitingContainer GPwaitingContainerHidden gpf-waiting gpf-waiting--hidden"; - } - - // ################################################################### // - // ##################### init component ############################## // - // ################################################################### // - - /** - * Initialize control (called by constructor) - * - * @param {Object} options - options - * - * @private - */ - _initialize (options) { - logger.trace("ElevationPath::_initialize : ", options); - - // liste des options - this.options = { - target : null, - render : null, - active : false, - apiKey : null, - export : false, - elevationOptions : { - outputFormat : "json" - }, - layerDescription : { - title : "Profil altimétrique", - description : "Mon profil altimétrique" - }, - displayProfileOptions : { - totalDistance : true, - greaterSlope : true, - meanSlope : true, - ascendingElevation : true, - descendingElevation : true, - currentSlope : true, - apply : null, - target : null - }, - stylesOptions : { - profile : null, - draw : null, - marker : null - } - }; - - // merge with user options - Utils.mergeParams(this.options, options); - - this.options.target = options.target || null; - // this.options.render = options.render || null; - - // cle API sur le service - this.options.apiKey = options.apiKey; - - // gestion de l'affichage du profil - var _profile = options.displayProfileOptions || {}; - - // bouton export - this.export = null; - - // gestion de la fonction du profil - var displayFunction = _profile.apply; - this.options.displayProfileOptions.apply = (typeof displayFunction === "function") - ? displayFunction : ElevationPath.DISPLAY_PROFILE_BY_DEFAULT; - - // gestion du container du profil - var displayContainer = _profile.target; - this.options.displayProfileOptions.target = (typeof displayContainer !== "undefined") - ? displayContainer : null; - - // gestion des styles - var _styles = options.stylesOptions || {}; - - // FIXME ??? - // gestion du style du profil - // var profileStyle = _styles.profile; - // this.options.stylesOptions.profile = ( typeof profileStyle === "undefined" || Object.keys(profileStyle).length === 0 ) ? - // ElevationPath.DEFAULT_STYLES.PROFILE : profileStyle; - // this._createStylingProfile(); - - // gestion des styles du tracé - this.options.stylesOptions.draw = _styles.draw || {}; - this._createStylingDraw(); - - // gestion des styles du marker - this.options.stylesOptions.marker = _styles.marker || {}; - this._createStylingMarker(); - } - - /** - * initialize component container (DOM) - * - * @returns {DOMElement} DOM element - * - * @private - */ - _initializeContainer () { - logger.trace("ElevationPath::_initializeContainer : ", this._uid); - - // create main container - var container = this._createMainContainerElement(); - - var picto = this._pictoButton = this._createShowElevationPathPictoElement(); - container.appendChild(picto); - - // mode "active" - if (this.options.active) { - this._pictoButton.click(); - } - - // panneau - var panel = this._panelContainer = this._createElevationPathPanelElement(); - var panelDiv = this._createElevationPathPanelDivElement(); - panel.appendChild(panelDiv); - - // header - var header = this._createElevationPathPanelHeaderElement(); - panelDiv.appendChild(header); - - // profile - var profile = this._profileContainer = this._createElevationPathPanelProfilElement(); - panelDiv.appendChild(profile); - - // waiting - var waiting = this._waitingContainer = this._createElevationPathWaitingElement(); - panelDiv.appendChild(waiting); - - // info - var info = this._infoContainer = this._createElevationPathInformationsElement(); - panelDiv.appendChild(info); - - if (this.options.displayProfileOptions.target === null) { - container.appendChild(panel); - } - - return container; - } - - // ################################################################### // - // ###################### init styles ################################ // - // ################################################################### // - - /** - * create style marker object : "ol.style" - * - * @private - */ - _createStylingMarker () { - logger.trace("ElevationPath::_createStylingMarker "); - - var marker = ElevationPath.DEFAULT_STYLES.MARKER; - logger.trace("style marker", marker); - - // si marker n'est pas un objet ol.style.Image, on applique le - // style par défaut. - if (this.options.stylesOptions.marker instanceof Image) { - marker = this.options.stylesOptions.marker; - } - - this._markerStyle = new Style({ - image : marker - }); - } - - /** - * create style draw object : "ol.style" - * - * @private - */ - _createStylingDraw () { - logger.trace("ElevationPath::_createStylingDraw"); - - // on interprete les params pour y creer un objet ol.Style - var styles = this.options.stylesOptions.draw; - - // style de depart - logger.trace("style start", styles.start); - - // Creation à partir des styles par défaut - var startStyleOpts = { - image : Measures.DEFAULT_POINTER_STYLE, - stroke : Measures.DEFAULT_DRAW_START_STYLE.getStroke() - }; - // ecrasement à partir des propriétés renseignées - if (styles.hasOwnProperty("pointer") && styles.pointer instanceof Image) { - startStyleOpts.image = styles.pointer; - } - if (styles.hasOwnProperty("start") && styles.start instanceof Stroke) { - startStyleOpts.stroke = styles.start; - } - - this._drawStyleStart = new Style(startStyleOpts); - - // style de fin - logger.trace("style finish", styles.finish); - - var finishStyleOpts = { - stroke : Measures.DEFAULT_DRAW_FINISH_STYLE.getStroke() - }; - // ecrasement à partir des propriétés renseignées - if (styles.hasOwnProperty("finish") && styles.finish instanceof Stroke) { - finishStyleOpts.stroke = styles.finish; - } - - this._drawStyleFinish = new Style(finishStyleOpts); - } - - /** - * create style graph - * FIXME : à revoir car ne sert que pour AmCharts !? - * - * @private - */ - _createStylingProfile () { - logger.trace("ElevationPath::_createStylingProfile"); - - var userStyles = this.options.stylesOptions.profile; - - logger.trace("style profile", userStyles); - - var defaultStyle = ElevationPath.DEFAULT_STYLES.PROFILE; - Object.keys(defaultStyle).forEach((key) => { - if (!userStyles.hasOwnProperty(key)) { - // si le style user n'existe pas, on ajoute celui par defaut - userStyles[key] = defaultStyle[key]; - } else { - var _defaultStyle = defaultStyle[key]; - if (typeof _defaultStyle === "object") { - // on merge avec un objet, - // les styles user ecrasent ceux par defaut... - Utils.mergeParams(_defaultStyle, userStyles[key]); - userStyles[key] = _defaultStyle; - } - } - }); - } - - // ################################################################### // - // ################### Map interactions management ################### // - // ################################################################### // - - /** - * this method is called by this.onShowElevationPathClick, - * and initialize a vector layer, if widget is active. - * - * @param {ol.Map} map - Map - * @private - */ - _initMeasureInteraction (map) { - logger.trace("ElevationPath::_initMeasureInteraction()"); - - // var map = this.getMap(); - if (!map) { - return; - } - - this._measureSource = new VectorSource(); - - this._measureVector = new VectorLayer({ - source : this._measureSource, - style : this._drawStyleFinish - }); - - // on rajoute le champ gpResultLayerId permettant d'identifier une couche crée par le composant. - this._measureVector.gpResultLayerId = "measure:profil"; - - map.addLayer(this._measureVector); - - // Si un layer switcher est présent dans la carte, on lui affecte des informations pour cette couche - map.getControls().forEach( - (control) => { - if (control instanceof LayerSwitcher) { - // un layer switcher est présent dans la carte - var layerId = this._measureVector.gpLayerId; - // on n'ajoute des informations que s'il n'y en a pas déjà (si le titre est le numéro par défaut) - if (control._layers[layerId].title === layerId) { - control.addLayer( - this._measureVector, { - title : this.options.layerDescription.title, - description : this.options.layerDescription.description - } - ); - } - } - } - ); - } - - /** - * this method is called by this.onShowElevationPathClick, - * and add draw interaction to map, if widget is not active. - * - * @param {ol.Map} map - Map - * @private - */ - _addMeasureInteraction (map) { - logger.trace("ElevationPath::_addMeasureInteraction()"); - - // var map = this.getMap(); - if (!map) { - return; - } - - // Creates and adds the interaction - this._measureDraw = new DrawInteraction({ - source : this._measureSource, - type : "LineString", - style : this._drawStyleStart, - stopClick : true - }); - - this._measureDraw.setProperties({ - name : "ElevationPath", - source : this - }); - - map.addInteraction(this._measureDraw); - - // Event start - this._measureDraw.on("drawstart", (evt) => { - logger.trace("drawstart", evt); - - // delete marker current - if (this._marker !== null) { - this._measureSource.removeFeature(this._marker); - this._marker = null; - } - - // set new feature and remove last feature - if (this._lastSketch !== null) { - this._measureSource.removeFeature(this._lastSketch); - this._lastSketch = null; - } - this._currentSketch = evt.feature; - - // and, all features - var _features = this._measureSource.getFeatures(); - for (var i = 0; i < _features.length; i++) { - this._measureSource.removeFeature(_features[i]); - } - /** - * event triggered at the start of drawing input - * @event elevationpath:drawstart - */ - this.dispatchEvent("elevationpath:drawstart"); - }); - - // Event end - this._measureDraw.on("drawend", (evt) => { - logger.trace("drawend", evt); - /** - * event triggered at the end of drawing input - * @event elevationpath:drawend - */ - this.dispatchEvent("elevationpath:drawend"); - - // set feature - this._lastSketch = this._currentSketch; - - // Si il n'y a pas de surcharge utilisateur de la fonction de recuperation des - // resultats, on realise l'affichage du panneau - if (typeof this.options.elevationOptions.onSuccess === "undefined" && this.options.displayProfileOptions.target === null) { - this._panelContainer.style.display = "block"; - // self._panelContainer.style.visibility = "visible"; - } - - // set an alti request and display results - this._measureDraw.setActive(false); - this._requestService(); - }); - } - - /** - * this method is called by this.onShowElevationPathClick, - * and removes draw interaction from map (if exists) - * And removes layer too... - * - * @param {ol.Map} map - Map - * @param {Boolean} remove - Remove layer - * @private - */ - _removeMeasureInteraction (map, remove) { - logger.trace("ElevationPath::_removeMeasureInteraction()"); - - // var map = this.getMap(); - if (!map) { - return; - } - - if (remove) { - if (this._measureVector) { - map.removeLayer(this._measureVector); - this._measureVector = null; - } - } - - if (this._measureDraw) { - map.removeInteraction(this._measureDraw); - this._measureDraw = null; - } - } - - // ################################################################### // - // ############################ Alti request ######################### // - // ################################################################### // - - /** - * transforme geometry feature to position coordinate (service) - * - * @returns {Object[]} geometry - * - * @private - */ - _getGeometry () { - // INFO - // on transmet toujours des coordonnées au service en EPSG:4326 - - if (this._currentSketch === null) { - logger.warn("Current Feature undefined !?"); - return; - } - - var geometry = []; - - var map = this.getMap(); - var projSrc = map.getView().getProjection(); - var projDest = "EPSG:4326"; - var coordinates = this._currentSketch.getGeometry().getCoordinates(); - for (var i = 0; i < coordinates.length; i++) { - var xy = coordinates[i]; - var ll = xy; - // on transmet au service des coordonnées en EPSG:4326 - if (projSrc !== projDest) { - ll = olTransformProj(xy, projSrc, projDest); - } - geometry.push({ - lon : Math.round(ll[0] * 1e8) / 1e8, - lat : Math.round(ll[1] * 1e8) / 1e8 - }); - } - - return geometry; - } - - /** - * get geometry feature length - * - * @returns {Integer} length - * - * @private - */ - _getLength () { - if (this._currentSketch === null) { - logger.warn("Current Feature undefined !?"); - return; - } - - var length = 0; - - var map = this.getMap(); - var projSrc = map.getView().getProjection(); - var projDest = "EPSG:4326"; - - var coordinates = this._currentSketch.getGeometry().getCoordinates(); - for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) { - var c1 = olTransformProj(coordinates[i], projSrc, projDest); - var c2 = olTransformProj(coordinates[i + 1], projSrc, projDest); - c1[0] = Math.round(c1[0] * 1e8) / 1e8; - c1[1] = Math.round(c1[1] * 1e8) / 1e8; - c2[0] = Math.round(c2[0] * 1e8) / 1e8; - c2[1] = Math.round(c2[1] * 1e8) / 1e8; - length += olGetDistanceSphere(c1, c2); - } - - return length; - } - - /** - * get geometry feature point coords in EPSG:4326 [lon, lat] - * - * @returns {Array} point coords in EPSG:4326 [lon, lat] - * - * @private - */ - _getSketchCoords () { - if (this._currentSketch === null) { - logger.warn("Current Feature undefined !?"); - return; - } - - var map = this.getMap(); - var projSrc = map.getView().getProjection(); - var projDest = "EPSG:4326"; - - var pointCoords = []; - - var coordinates = this._currentSketch.getGeometry().getCoordinates(); - for (var i = 0; i < coordinates.length; i++) { - var c1 = olTransformProj(coordinates[i], projSrc, projDest); - c1[0] = Math.round(c1[0] * 1e8) / 1e8; - c1[1] = Math.round(c1[1] * 1e8) / 1e8; - pointCoords.push(c1); - } - - return pointCoords; - } - - /** - * this method is called at the end of the path, - * it generates and sends alti request, then displays results - * - * @private - */ - _requestService () { - logger.trace("ElevationPath::_requestService"); - - // les coordonnées sont obligatoires - var geometry = this._getGeometry(); - logger.trace("geometry", geometry); - if (!geometry) { - logger.warn("missing geometry !?"); - return; - } - - // on construit les options pour la requête - var options = {}; - - // on surcharge avec les options de l'utilisateur - Utils.mergeParams(options, this.options.elevationOptions); - - // au cas où ... - Utils.mergeParams(options, { - apiKey : options.apiKey || this.options.apiKey - }); - - // si l'utilisateur a spécifié le paramètre ssl au niveau du control, on s'en sert - // true par défaut (https) - if (typeof options.ssl !== "boolean") { - if (typeof this.options.ssl === "boolean") { - options.ssl = this.options.ssl; - } else { - options.ssl = true; - } - } - - Utils.mergeParams(options, { - ssl : options.ssl - }); - - // les callbacks - var self = this; - - // gestion des callback - var bOnFailure = !!(this.options.elevationOptions.onFailure !== null && typeof this.options.elevationOptions.onFailure === "function"); // cast variable to boolean - var bOnSuccess = !!(this.options.elevationOptions.onSuccess !== null && typeof this.options.elevationOptions.onSuccess === "function"); - - // callback _requestServiceOnSuccess - var _requestServiceOnSuccess = function (result) { - logger.trace(result); - if (result) { - self._panelContainer.style.display = "block"; - // self._panelContainer.style.visibility = "visible"; - if (self._data) { - self._data = {}; - } - self._data = self._computeElevationMeasure(result.elevations); - self._displayProfile(self._data); - self._waitingContainer.className = "GPwaitingContainer GPwaitingContainerHidden gpf-waiting gpf-waiting--hidden"; - self._waiting = false; - self._measureDraw.setActive(true); - } - if (bOnSuccess) { - self.options.elevationOptions.onSuccess.call(self, self.getData()); - } - }; - - // callback _requestServiceOnFailure - var _requestServiceOnFailure = function (error) { - // on ferme le panneau en cas d'erreur ! - self._panelContainer.style.display = "none"; - // self._panelContainer.style.visibility = "hidden"; - logger.error(error.message); - self._waitingContainer.className = "GPwaitingContainer GPwaitingContainerHidden gpf-waiting gpf-waiting--hidden"; - self._waiting = false; - self._measureDraw.setActive(true); - if (bOnFailure) { - self.options.elevationOptions.onFailure.call(self, error); - } - }; - - Utils.mergeParams(options, { - onSuccess : _requestServiceOnSuccess, - onFailure : _requestServiceOnFailure - }); - - // le sampling est soit defini par l'utilisateur (opts), - // ou soit calculé dynamiquement... - var sampling = options.sampling; - if (!sampling) { - // computing sampling - var _sampling; - var _length = this._getLength(); - logger.trace("length", _length); - var p = Math.max(50, Math.floor(_length) / 5); // en mètre sur un pas moyen de 5m ! - if (p > 200) { - _sampling = 200; - } else { - _sampling = Math.floor(p); - } - var pointNumber = this._getSketchCoords().length; - if (pointNumber > 100) { - _sampling = 0; - } - } - - if (_sampling > 0) { - Utils.mergeParams(options, { - sampling : _sampling - }); - } - - // et enfin, la geometrie - Utils.mergeParams(options, { - positions : geometry - }); - - logger.trace("options du service", options); - - // mise en place de la patience - this._waitingContainer.className = "GPwaitingContainer GPwaitingContainerVisible gpf-waiting gpf-waiting--visible"; - - // Request altitude service - Gp.Services.getAltitude(options); - } - - // ################################################################### // - // ########################## Profil display ######################### // - // ################################################################### // - - /** - * this method computes results elevations (Z and distance) - * - * @param {Array} elevations - array of elevation - * @return {Array} elevations - * @private - */ - _computeElevationMeasure (elevations) { - logger.trace("ElevationPath::_computeElevationMeasure", elevations); - - var _data = elevations; - - var _unit = "m"; - - var _sketchPoints = this._getSketchCoords(); - if (!_sketchPoints) { - return; - } - // section actuelle du sketch sur laquelle on est - var _currentSection = 0; - // longueur cumulée des sections précédentes - var _previousSectionsLength = 0; - var _nextSectionBegining = _sketchPoints[1]; - - // Calcul de la distance au départ pour chaque point + arrondi des lat/lon - _data[0].dist = 0; - _data[0].slope = 0; - _data[0].lat = Math.round(_data[0].lat * 10000) / 10000; - _data[0].lon = Math.round(_data[0].lon * 10000) / 10000; - - var _distanceMinus = 0; - var _distancePlus = 0; - var _ascendingElevation = 0; - var _descendingElevation = 0; - var _distance = 0; - var _slopes = 0; - - var distances = []; - - for (var i = 1; i < _data.length; i++) { - var a = [_data[i].lon, _data[i].lat]; - var distanceToStart = _previousSectionsLength + olGetDistanceSphere(a, _sketchPoints[_currentSection]); - var dist = distanceToStart - _distance; - - // Changement de section - if (a[0] === _nextSectionBegining[0] && a[1] === _nextSectionBegining[1]) { - _currentSection++; - _previousSectionsLength = distanceToStart; - // Pas de next section si on est sur le dernier point - if (i !== _data.length - 1) { - _nextSectionBegining = _sketchPoints[_currentSection + 1]; - } - } - - var za = _data[i].z; - var zb = _data[i - 1].z; - if (za < 0) { - za = 0; - } - if (zb < 0) { - zb = 0; - } - var slope = za - zb; - if (slope < 0) { - _distanceMinus += dist; - _descendingElevation += slope; - } else if (slope > 0) { - _distancePlus += dist; - _ascendingElevation += slope; - } - _distance = distanceToStart; - _data[i].dist = distanceToStart; - - distances.push(distanceToStart); - - _slopes += (slope) ? Math.abs(Math.round(slope / dist * 100)) : 0; - _data[i].slope = (slope) ? Math.abs(Math.round(slope / dist * 100)) : 0; - - // EVOL ? - // cf. gradiant - // http://www.color-hex.com/color/00b798 - var value = _data[i].slope; - if (value > 15 && value < 30) { - _data[i].color = "#005b4c"; - } else if (value > 30 && value < 45) { - _data[i].color = "#00362d"; - } else if (value > 45) { - _data[i].color = "#00120f"; - } else { - _data[i].color = "#00B798"; - } - - _data[i].lat = Math.round(_data[i].lat * 10000) / 10000; - _data[i].lon = Math.round(_data[i].lon * 10000) / 10000; - } - - // check distance totale - logger.trace("List Distances", distances); - - // Correction des altitudes aberrantes + arrondi des calculs de distance + ... - var _altMin = _data[0].z; - var _altMax = _data[0].z; - var _greaterSlope = _data[0].slope; - - for (var ji = 0; ji < _data.length; ji++) { - var d = _data[ji]; - if (d.z < -100) { - d.z = 0; - } - if (d.z > _altMax) { - _altMax = d.z; - } - if (d.z < _altMin) { - _altMin = d.z; - } - - if (d.slope > _greaterSlope) { - _greaterSlope = d.slope; - } - } - - return { - greaterSlope : _greaterSlope, // pente max - meanSlope : Math.round(_slopes / _data.length), // pente moyenne - distancePlus : _distancePlus, // distance cumulée positive - distanceMinus : _distanceMinus, // distance cumulée négative - ascendingElevation : _ascendingElevation, // dénivelé cumulée positive - descendingElevation : _descendingElevation, // dénivelé cumulée négative - altMin : _altMin.toLocaleString(), // altitude min TODO: inutile ? - altMax : _altMax.toLocaleString(), // altitude max TODO: inutile ? - distance : this._getLength(), // distance totale - unit : _unit, // unité des mesures de distance - points : _data - }; - } - - /** - * this method is called after service request (in case of success) - * and display results - * - * @param {Array} elevations - array of elevation - * @private - */ - _displayProfile (elevations) { - logger.trace("ElevationPath::_displayProfile", elevations); - - this._updateInfoContainer(); - - // container - var container = this.options.displayProfileOptions.target; - if (container) { - container.appendChild(this._panelContainer); - } - container = this._profileContainer; - - // TODO contexte ? - var context = this; - - // fonction - var displayFunction = this.options.displayProfileOptions.apply; - - // execution... - displayFunction.call(this, elevations, container, context); - - var opts = this.options.displayProfileOptions; - var element = document.getElementById("GPelevationPathPanelInfo-" + this._uid); - if (element) { - if (opts.totalDistance || - opts.greaterSlope || - opts.meanSlope || - opts.ascendingElevation || - opts.descendingElevation) { - // on affiche les informations - element.style.display = "block"; - } - } - - /** - * event triggered when the compute is finished - * - * @event elevationpath:compute - * @typedef {Object} - * @property {Object} type - event - * @property {Object} target - instance ElevationPath - * @example - * ElevationPath.on("elevationpath:compute", function (e) { - * console.log(e.target.getData()); - * }) - */ - this.dispatchEvent({ - type : "elevationpath:compute" - }); - } - - /** - * update info container - * - * @private - */ - _updateInfoContainer () { - logger.trace("ElevationPath::_updateInfoContainer"); - - // options d'affichage - var totalDistance = this.options.displayProfileOptions.totalDistance; - var meanSlope = this.options.displayProfileOptions.meanSlope; - var greaterSlope = this.options.displayProfileOptions.greaterSlope; - var ascendingElevation = this.options.displayProfileOptions.ascendingElevation; - var descendingElevation = this.options.displayProfileOptions.descendingElevation; - - // clean - var div = this._infoContainer; - if (div.childElementCount) { - while (div.firstChild) { - div.removeChild(div.firstChild); - } - } - - // creation des infomations - if (totalDistance) { - this._addElevationPathInformationsItem("Distance totale : " + Math.round(this._data.distance).toLocaleString() + " m"); - } - - if (ascendingElevation) { - this._addElevationPathInformationsItem("Dénivelé positif : " + this._data.ascendingElevation.toLocaleString() + " m"); - } - - if (descendingElevation) { - this._addElevationPathInformationsItem("Dénivelé négatif : " + this._data.descendingElevation.toLocaleString() + " m"); - } - - if (meanSlope) { - this._addElevationPathInformationsItem("Pente moyenne : " + this._data.meanSlope.toLocaleString() + " %"); - } - - if (greaterSlope) { - this._addElevationPathInformationsItem("Plus forte pente : " + this._data.greaterSlope.toLocaleString() + " %"); - } - } - - /** - * Remove measure - * @private - */ - _removeMeasure () { - // sketch - this._lastSketch = null; - this._currentSketch = null; - - if (this._measureSource) { - // marker - if (this._marker) { - this._measureSource.removeFeature(this._marker); - this._marker = null; - } - - // all other features - var _features = this._measureSource.getFeatures(); - for (var i = 0; i < _features.length; i++) { - this._measureSource.removeFeature(_features[i]); - } - } - } - - /** - * Remove profile - * @private - */ - _removeProfile () { - // graph - this._profile = null; - - // on vide le container - if (this._profileContainer) { - while (this._profileContainer.firstChild) { - this._profileContainer.removeChild(this._profileContainer.firstChild); - } - } - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - - /** - * this method is called by event 'click' on '' picto - * and enable or disable the entry of the path - * - * @param {Object} e - event - * @private - */ - onShowElevationPathClick (e) { - var map = this.getMap(); - Interactions.unset(map, { - current : "ElevationPath" - }); - - // Activation/Desactivation des interactions de dessins - var opened = this._pictoButton.ariaPressed; - if (opened === "true") { - // on n'affiche pas la fenetre de profile s'il n'existe pas... - if (this._profile === null) { - this._panelContainer.style.display = "none"; - // this._panelContainer.style.visibility = "hidden"; - } - this._initMeasureInteraction(map); - this._addMeasureInteraction(map); - } else { - this._panelContainer.style.display = "none"; - // HACK - // il est possible de faire passer une instruction via le DOM et les dataset : - // * data-remove-measure : true|false - // * data-remove-layer : true|false - if (e && e.target.dataset && e.target.dataset.removeMeasure) { - if (e.target.dataset.removeMeasure === "true") { - this._removeMeasure(); - } else { - // sketch - this._lastSketch = null; - this._currentSketch = null; - } - } else { - this._removeMeasure(); - } - this._removeProfile(); - - if (e && e.target.dataset && e.target.dataset.removeLayer) { - this._removeMeasureInteraction(map, (e.target.dataset.removeLayer === "true")); - } else { - this._removeMeasureInteraction(map, true); - } - } - } - - /** - * this method is called by event 'click' on '' picto - * (cf. this.), - * and display the panel info - * - * @private - */ - onOpenElevationPathInfoClick () { - var div = this._infoContainer; - - // show des informations ! - if (div.className === "GPelementVisible gpf-visible") { - clearTimeout(this._timerHdlr); - div.className = "GPelementHidden gpf-hidden"; - } else { - div.className = "GPelevationPathInformationsContainerVisible"; - } - - // hidden des informations ! - this._timerHdlr = setTimeout(function () { - div.className = "GPelementHidden gpf-hidden"; - }, 4000); - } - -}; - -// on récupère les méthodes de la classe commune ElevationPath -Object.assign(ElevationPath.prototype, ElevationPathDOM); - -export default ElevationPath; - -// Expose ElevationPath as ol.control.ElevationPath (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.ElevationPath = ElevationPath; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPathDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPathDOM.d.ts deleted file mode 100644 index dad7e7f99..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPathDOM.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -export default ElevationPathDOM; -declare namespace ElevationPathDOM { - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createShowElevationPathPictoElement(): DOMElement; - function _createElevationPathPanelElement(): DOMElement; - function _createElevationPathPanelDivElement(): HTMLDivElement; - function _createElevationPathPanelHeaderElement(): DOMElement; - function _createElevationPathPanelProfilElement(): DOMElement; - function _createElevationPathWaitingElement(): DOMElement; - function _createElevationPathInformationsElement(): DOMElement; - function _addElevationPathInformationsItem(value: string): DOMElement; -} -//# sourceMappingURL=ElevationPathDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPathDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPathDOM.d.ts.map deleted file mode 100644 index 85b99b83f..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPathDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ElevationPathDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/ElevationPath/ElevationPathDOM.js"],"names":[],"mappings":";;IAOc,qCAGT;IAO6B,mDAK7B;IAYsC,4DA8BtC;IAekC,wDASlC;IAEqC,+DAIrC;IAOwC,8DA8ExC;IAQwC,8DAKxC;IAOoC,0DAYpC;IAOyC,+DAWzC;IAQmC,sEAWnC"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPathDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPathDOM.js deleted file mode 100644 index 6a6486b7c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ElevationPathDOM.js +++ /dev/null @@ -1,252 +0,0 @@ -var ElevationPathDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Main container (DOM) - * - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPelevationPath"); - container.className = "GPwidget gpf-widget gpf-widget-button"; - return container; - }, - - // ################################################################### // - // ################# Methods to display Main Panel ################### // - // ################################################################### // - - /** - * Show control - * see event ! - * - * @returns {DOMElement} DOM element - */ - _createShowElevationPathPictoElement : function () { - // contexte d'execution - var context = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowElevationPathPicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto gpf-btn gpf-btn-icon gpf-btn-icon-elevation fr-btn"; - button.title = "Calculer un profil"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // gestionnaire d'evenement : - // on ouvre le menu de saisie de saisie - // L'ouverture/Fermeture permet de faire le menage - // (reinitialisation) - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowElevationPathClick(e); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowElevationPathClick(e); - }); - } - - return button; - }, - - // ################################################################### // - // ######################### Methods to Panel ######################## // - // ################################################################### // - - /** - * Create Container Panel - * - * FIXME - * don't call this._createElevationPathPanelHeaderElement - * don't call this._createElevationPathPanelProfilElement - * - * @returns {DOMElement} DOM element - */ - _createElevationPathPanelElement : function () { - var dialog = document.createElement("dialog"); - dialog.id = this._addUID("GPelevationPathPanel"); - dialog.className = "GPpanel gpf-panel fr-modal"; - - // dialog.appendChild(this._createElevationPathPanelHeaderElement()); - // dialog.appendChild(this._createElevationPathPanelProfilElement()); - - return dialog; - }, - - _createElevationPathPanelDivElement : function () { - var div = document.createElement("div"); - div.className = "gpf-panel__body fr-modal__body"; - return div; - }, - - /** - * Create Header Panel - * - * @returns {DOMElement} DOM element - */ - _createElevationPathPanelHeaderElement : function () { - var self = this; - - var container = document.createElement("div"); - container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; - - var divInfo = document.createElement("button"); - divInfo.id = this._addUID("GPelevationPathPanelInfo"); - divInfo.className = "GPpanelInfo gpf-btn gpf-btn-icon-info fr-btn fr-btn--secondary"; - divInfo.title = "Informations"; - // add event on click - if (divInfo.addEventListener) { - divInfo.addEventListener( - "click", - function () { - self.onOpenElevationPathInfoClick(); - } - ); - } else if (divInfo.attachEvent) { - // internet explorer - divInfo.attachEvent( - "onclick", - function () { - self.onOpenElevationPathInfoClick(); - } - ); - } - container.appendChild(divInfo); - - var divTitle = document.createElement("div"); - divTitle.className = "GPpanelTitle gpf-panel__title fr-modal__title"; - divTitle.innerHTML = "Profil Altimétrique"; - container.appendChild(divTitle); - - var buttonReduce = document.createElement("button"); - buttonReduce.id = this._addUID("GPelevationPathPanelReduce"); - buttonReduce.className = "GPpanelReduce gpf-btn gpf-btn-icon-reduce fr-btn fr-btn--secondary"; - buttonReduce.title = "Masquer le panneau"; - - if (buttonReduce.addEventListener) { - buttonReduce.addEventListener("click", function (e) { - if (typeof self.onReduceElevationPathPanelClick === "function") { - self.onReduceElevationPathPanelClick(); - } - }, false); - } else if (buttonReduce.attachEvent) { - buttonReduce.attachEvent("onclick", function (e) { - if (typeof self.onReduceElevationPathPanelClick === "function") { - self.onReduceElevationPathPanelClick(); - } - }); - } - container.appendChild(buttonReduce); - - var buttonClose = document.createElement("button"); - buttonClose.id = this._addUID("GPelevationPathPanelClose"); - buttonClose.className = "GPpanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--secondary fr-m-1w"; - buttonClose.title = "Fermer le panneau"; - - // Link panel close / visibility checkbox - if (buttonClose.addEventListener) { - buttonClose.addEventListener("click", function () { - document.getElementById(self._addUID("GPshowElevationPathPicto")).click(); - }, false); - } else if (buttonClose.attachEvent) { - buttonClose.attachEvent("onclick", function () { - document.getElementById(self._addUID("GPshowElevationPathPicto")).click(); - }); - } - - var span = document.createElement("span"); - span.className = "GPelementHidden gpf-visible"; // afficher en dsfr - span.innerText = "Fermer"; - - buttonClose.appendChild(span); - container.appendChild(buttonClose); - - return container; - }, - - /** - * Create Form - * see evenement ! - * - * @returns {DOMElement} DOM element - */ - _createElevationPathPanelProfilElement : function () { - var div = document.createElement("div"); - div.id = "GPelevationPathProfil"; - - return div; - }, - - /** - * Create Waiting Panel - * - * @returns {DOMElement} DOM element - */ - _createElevationPathWaitingElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPelevationPathCalcWaitingContainer"); - div.className = "GPwaitingContainer GPwaitingContainerHidden gpf-waiting gpf-waiting--hidden"; - - var p = document.createElement("p"); - p.className = "GPwaitingContainerInfo gpf-waiting_info"; - p.innerHTML = "Recherche en cours..."; - - div.appendChild(p); - - return div; - }, - - /** - * Create information Panel - * - * @returns {DOMElement} DOM element - */ - _createElevationPathInformationsElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPelevationPathInformationsContainer"); - div.className = "GPelementHidden gpf-hidden"; - - var p = document.createElement("p"); - p.className = "GPelevationPathInformations"; - p.innerHTML = "Aucune information..."; - div.appendChild(p); - - return div; - }, - - /** - * Add a information into Panel - * - * @param {String} value - value of item - * @returns {DOMElement} DOM element - */ - _addElevationPathInformationsItem : function (value) { - var div = document.getElementById(this._addUID("GPelevationPathInformationsContainer")); - - if (div) { - var p = document.createElement("p"); - p.className = "GPelevationPathInformations"; - p.innerHTML = value; - div.appendChild(p); - } - - return div; - } -}; - -export default ElevationPathDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ProfileElevationPathDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ProfileElevationPathDOM.d.ts deleted file mode 100644 index 13e7df17d..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ProfileElevationPathDOM.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -export default ProfileElevationPathDOM; -declare namespace ProfileElevationPathDOM { - function _getCssProperty(element: HTMLElement, property: string): string; - function _getTextWidth(text: string, container: HTMLElement, font?: string): number; - function _dataZToSvgY(z: Object, pathHeight: number, minGraphZ: number, pxPerMZ: number): number; - function _dataDistToSvgX(dist: number, svgWidth: number, pathWidth: number, pxPerMX: number): any[]; - function _svgXToDataDist(svgX: number, svgWidth: number, pathWidth: number, pxPerMX: number): any[]; - function _arrayBisect(array: any[], value: number): number; - function displayProfileByDefault(data: Object, container: HTMLElement, context: Object, className: Object): DOMElement; - function displayProfileRaw(data: Object, container: HTMLElement, context: Object, className: Object): DOMElement; - function displayProfileLibD3(data: Object, container: HTMLElement, context: Object, className: Object): DOMElement; - function displayProfileLibAmCharts(data: Object, container: HTMLElement, context: Object, className: Object): DOMElement; -} -//# sourceMappingURL=ProfileElevationPathDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ProfileElevationPathDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ProfileElevationPathDOM.d.ts.map deleted file mode 100644 index 4e4077c7f..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ProfileElevationPathDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ProfileElevationPathDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/ElevationPath/ProfileElevationPathDOM.js"],"names":[],"mappings":";;IAoBsB,yEAEjB;IAae,oFAYf;IAac,iGAEd;IAaiB,oGAEjB;IAaiB,oGAEjB;IAWc,2DAWd;IAYyB,uHAsiBzB;IAYmB,iHAqCnB;IAYqB,mHA2OrB;IAY2B,yHA6H3B"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ProfileElevationPathDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ProfileElevationPathDOM.js deleted file mode 100644 index 8853ea87a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ElevationPath/ProfileElevationPathDOM.js +++ /dev/null @@ -1,1113 +0,0 @@ -/* globals AmCharts, d3 */ - -/** - * @module ProfileElevationPathDOM - * @alias [private] ProfileElevationPathDOM - * @description - * create DOM element - */ -var ProfileElevationPathDOM = { - - /** - * Gets a css property from an element - * - * @private - * @param {HTMLElement} element The element to get the property from - * @param {String} property The css property - * @returns {String} The value of the property - * - * @see https://stackoverflow.com/questions/7444451/how-to-get-the-actual-rendered-font-when-its-not-defined-in-css - */ - _getCssProperty : function (element, property) { - return window.getComputedStyle(element, null).getPropertyValue(property); - }, - - /** - * Uses canvas.measureText to compute and return the width of the given text of given font in pixels. - * - * @private - * @param {String} text The text to be rendered. - * @param {HTMLElement} container The container of the text - * @param {String} font The font of the container if known, format: 'weight size familiy' - * @returns {Number} The width of the text - * - * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393 - */ - _getTextWidth : function (text, container, font = null) { - // re-use canvas object for better performance - var canvas = /** ts-syntax */(this.canvas) || ((this.canvas) = document.createElement("canvas")); - var context = canvas.getContext("2d"); - if (font === null) { - context.font = `${this._getCssProperty(container, "font-weight")} ${this._getCssProperty(container, "font-size")} ${this._getCssProperty(container, "font-family")}`; - } else { - context.font = font; - } - - var metrics = context.measureText(text); - return metrics.width; - }, - - /** - * Converts a data point z to svg y coord - * - * @private - * @param {Object} z The z to convert. - * @param {Number} pathHeight The height of the path in the svg container in px - * @param {Number} minGraphZ Min z of the graph - * @param {Number} pxPerMZ Number of pixels per meter for the z (y) axis - * @returns {Number} The y svg coordinate of the point - * - */ - _dataZToSvgY : function (z, pathHeight, minGraphZ, pxPerMZ) { - return pathHeight - (z - minGraphZ) * pxPerMZ - 0.5; - }, - - /** - * Converts a data point dist value to svg x coord - * - * @private - * @param {Number} dist The dist to convert - * @param {Number} svgWidth The witdth of the svg container in px - * @param {Number} pathWidth The witdth of the path in the svg container in px - * @param {Number} pxPerMX Number of pixels per meter for the x axis - * @returns {Array} The x svg coordinate of the point - * - */ - _dataDistToSvgX : function (dist, svgWidth, pathWidth, pxPerMX) { - return (svgWidth - pathWidth) + dist * pxPerMX; - }, - - /** - * Converts a svg x coord to dist value - * - * @private - * @param {Number} svgX The dist to convert - * @param {Number} svgWidth The witdth of the svg container in px - * @param {Number} pathWidth The witdth of the path in the svg container in px - * @param {Number} pxPerMX Number of pixels per meter for the x axis - * @returns {Array} The dist value - * - */ - _svgXToDataDist : function (svgX, svgWidth, pathWidth, pxPerMX) { - return (svgX + pathWidth - svgWidth) / pxPerMX; - }, - - /** - * Returns the index of value if it were inserted in sorted (by dist) array of data points. - * - * @private - * @param {Array} array Sorted array of data points (with dist property) - * @param {Number} value Value to test the index of. - * @returns {Number} The index the value would have. - * - */ - _arrayBisect : function (array, value) { - let idx; - if (array.length === 0) { - return 0; - } - for (idx = 0; idx < array.length; idx++) { - if (value < array[idx].dist) { - return idx; - } - } - return idx - 1; - }, - - /** - * Display Profile function used by default : no additonal framework needed. - * - * @public - * @param {Object} data - elevations values for profile - * @param {HTMLElement} container - html container where to display profile - * @param {Object} context - this control object - * @param {Object} className - calling class (ie ElevationPath) - * @returns {DOMElement} profil container - */ - displayProfileByDefault : function (data, container, context, className) { - var self = context; - - if (!container) { - return; - } - - if (!data) { - return; - } - - // on nettoie toujours... - while (container.firstChild) { - container.removeChild(container.firstChild); - } - - const margin = { - top : 25, - right : 15, - bottom : 10, - left : 10 - }; - - var _displayProfileOptions = self.options.displayProfileOptions; - var _points = data.points; - - var sortedElev = JSON.parse(JSON.stringify(_points)); - sortedElev.sort(function (e1, e2) { - return e1.z - e2.z; - }); - - var minZ = sortedElev[0].z; - var maxZ = sortedElev[sortedElev.length - 1].z; - var dist = data.distance; - let distUnit = "m"; - - const widgetDiv = document.createElement("div"); - widgetDiv.id = "profileElevationByDefault"; - container.appendChild(widgetDiv); - - // Détermination des tailles en pixels des éléments du widget - var clientWidth = window.getComputedStyle(container).getPropertyValue("width").replace(/px/, ""); - var clientHeight = window.getComputedStyle(container).getPropertyValue("height").replace(/px/, ""); - const widgetHeigth = clientHeight - margin.top - margin.bottom; - const widgetWidth = clientWidth - margin.left - margin.right; - // const widgetHeigth = container.clientHeight - margin.top - margin.bottom; - // const widgetWidth = container.clientWidth - margin.left - margin.right; - - const zLabelWidth = 17; - const zGradWidth = this._getTextWidth(Math.round(maxZ).toLocaleString() + ",88", container, "400 10 Verdana"); - const xLabelHeight = 17; - const xGradHeight = 15; - - const minZguideHeigth = 15; - const minXguideWidth = this._getTextWidth(Math.round(dist).toLocaleString() + ",5", container); - const minNumXGuides = 1; - - const pathHeight = widgetHeigth - xLabelHeight - xGradHeight; - const pathWidth = widgetWidth - zLabelWidth - zGradWidth; - - const elevationSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - elevationSvg.id = "profileElevationByDefaultSvg"; - elevationSvg.setAttribute("style", "display: block; margin: auto; overflow: visible; position: absolute; left: 10px;"); - elevationSvg.setAttribute("viewBox", `0 0 ${clientWidth} ${clientHeight}`); - elevationSvg.setAttribute("width", "100%"); - elevationSvg.setAttribute("height", "100%"); - - // Détermination des guides en ordonnée : - const maxNumZguides = Math.floor(pathHeight / minZguideHeigth); - let gradZ; - // Traitement du cas altitude max = altitude min - if (maxZ === minZ) { - gradZ = 0.1; - } else { - gradZ = Math.pow(10, (Math.ceil(Math.log((maxZ - minZ) / maxNumZguides) / Math.log(10)))) / 2; - } - let minGraphZ = Math.floor(minZ / gradZ) * gradZ; - let maxGraphZ = Math.ceil(maxZ / gradZ) * gradZ; - // cas où le path atteint pile les graduations extremes : ajout d'une gradiation - if (maxGraphZ === maxZ) { - maxGraphZ += gradZ; - } - // cas où gradZ < 1 : nombres flottants capricieux... - minGraphZ = Math.round(minGraphZ * 100) / 100; - maxGraphZ = Math.round(maxGraphZ * 100) / 100; - - let numZguides = Math.round((maxGraphZ - minGraphZ) / gradZ); - - // Si plus de guides que le max, on passe à une graduation de 10**x en 10**x (et non 10**x / 2) - if (numZguides + 1 > maxNumZguides) { - gradZ = Math.pow(10, (Math.ceil(Math.log((maxZ - minZ) / maxNumZguides) / Math.log(10)))); - minGraphZ = Math.floor(minZ / gradZ) * gradZ; - maxGraphZ = Math.ceil(maxZ / gradZ) * gradZ; - // cas où le path atteint pile les graduations extremes : ajout d'une gradiation - if (maxGraphZ === maxZ) { - maxGraphZ += gradZ; - } - // cas où gradZ < 1 : nombres flottants capricieux... - minGraphZ = Math.round(minGraphZ * 100) / 100; - maxGraphZ = Math.round(maxGraphZ * 100) / 100; - numZguides = Math.floor((maxGraphZ - minGraphZ) / gradZ); - } - - numZguides = Math.max(Math.round(numZguides), 1); - - const axisZ = document.createElementNS("http://www.w3.org/2000/svg", "g"); - axisZ.setAttribute("class", "profile-z-vertical"); - - const guidesZ = document.createElementNS("http://www.w3.org/2000/svg", "g"); - - const gradZyOffsetPx = pathHeight / numZguides; - let pxPerMZ; - // Traitement du cas altitude max = altitude min - if (maxZ === minZ) { - pxPerMZ = pathHeight / 0.2; - } else { - pxPerMZ = pathHeight / (maxGraphZ - minGraphZ); - } - - let gradZtext; - let yTextTranslation; - let yStrokeTranslation; - let gradZstroke; - let gradZpath; - let gradZgrad; - // Ajout des graduations au graphique - for (let i = 0; i <= numZguides; i++) { - gradZtext = document.createElementNS("http://www.w3.org/2000/svg", "text"); - gradZtext.setAttribute("class", "profile-z-graduation"); - gradZtext.setAttribute("font-family", "Verdana"); - gradZtext.setAttribute("font-size", "10px"); - gradZtext.setAttribute("fill", "#5E5E5E"); - // Cas où gradZ < 1 : nombres flottants capricieux... - // Le Math.round est pour éviter des ennuis du genre 3 * 0.1 = 0.300000000000004 - gradZtext.textContent = (Math.round(100 * (minGraphZ + i * gradZ)) / 100).toLocaleString(); - - yTextTranslation = pathHeight - i * gradZyOffsetPx; - - gradZtext.setAttribute("transform", `translate(${zLabelWidth + zGradWidth - 8}, ${yTextTranslation + 5})`); - gradZtext.setAttribute("text-anchor", "end"); - axisZ.appendChild(gradZtext); - - yStrokeTranslation = Math.round(yTextTranslation) - 0.5; - - gradZstroke = document.createElementNS("http://www.w3.org/2000/svg", "g"); - gradZpath = document.createElementNS("http://www.w3.org/2000/svg", "path"); - gradZpath.setAttribute("cs", "100,100"); - gradZpath.setAttribute("stroke-width", "1"); - if (i !== 0) { - gradZpath.setAttribute("stroke-opacity", "0.2"); - } else { - gradZpath.setAttribute("stroke-opacity", "1"); - } - gradZpath.setAttribute("stroke", "#000000"); - gradZpath.setAttribute("fill", "none"); - gradZpath.setAttribute("d", `M${zLabelWidth + zGradWidth},${yStrokeTranslation} L${pathWidth + zLabelWidth + zGradWidth},${yStrokeTranslation}`); - - gradZgrad = document.createElementNS("http://www.w3.org/2000/svg", "path"); - gradZgrad.setAttribute("cs", "100,100"); - gradZgrad.setAttribute("stroke-width", "1"); - gradZgrad.setAttribute("stroke-opacity", "1"); - gradZgrad.setAttribute("stroke", "#000000"); - gradZgrad.setAttribute("fill", "none"); - gradZgrad.setAttribute("d", `M${zLabelWidth + zGradWidth},${yStrokeTranslation} L${zLabelWidth + zGradWidth + 5},${yStrokeTranslation}`); - gradZgrad.setAttribute("transform", "translate(-5, 0)"); - - gradZstroke.appendChild(gradZgrad); - gradZstroke.appendChild(gradZpath); - guidesZ.appendChild(gradZstroke); - } - - var axisZLegend = document.createElementNS("http://www.w3.org/2000/svg", "text"); - axisZLegend.setAttribute("class", "profile-z-legend"); - axisZLegend.setAttribute("font-family", "Verdana"); - axisZLegend.setAttribute("font-size", "11px"); - axisZLegend.setAttribute("fill", "#5E5E5E"); - axisZLegend.textContent = "Altitude (m)"; - - axisZLegend.setAttribute("transform", `translate(${zLabelWidth - 8}, ${Math.round(pathHeight / 2)}) rotate(-90)`); - axisZLegend.setAttribute("text-anchor", "middle"); - - axisZ.appendChild(axisZLegend); - elevationSvg.appendChild(axisZ); - elevationSvg.appendChild(guidesZ); - - // Détermination des guides en abscisse : - // Passage éventuel en km - if (dist > 2000) { - dist /= 1000; - distUnit = "km"; - } - - const maxNumXguides = Math.floor(pathWidth / minXguideWidth); - let gradX = Math.pow(10, (Math.ceil(Math.log((dist) / maxNumXguides) / Math.log(10)))) / 2; - const maxGraphX = dist; - - // Si plus de guides que le max, on passe à une graduation de 10**x en 10**x (et non 10**x / 2) - let numXguides = Math.floor(maxGraphX / gradX); - if (numXguides > maxNumXguides) { - gradX = Math.pow(10, (Math.ceil(Math.log((dist) / maxNumXguides) / Math.log(10)))); - numXguides = Math.floor(maxGraphX / gradX); - } else if (numXguides < minNumXGuides) { - gradX = Math.pow(10, (Math.ceil(Math.log((dist) / maxNumXguides) / Math.log(10))) - 1); - numXguides = Math.floor(maxGraphX / gradX); - } - - numXguides = Math.max(numXguides, 1); - const lastGradX = gradX * numXguides; - - const axisX = document.createElementNS("http://www.w3.org/2000/svg", "g"); - axisX.setAttribute("class", "profile-x-vertical"); - - const guidesX = document.createElementNS("http://www.w3.org/2000/svg", "g"); - - // Décalage des graduations pour que la dernière corresponde à la distance max - const pxPerMX = pathWidth / maxGraphX; - const xOffset = (maxGraphX - lastGradX) * pxPerMX; - const gradXxOffsetPx = Math.round((pathWidth - xOffset) / numXguides); - - let gradXtext; - let xTextTranslation; - let xStrokeTranslation; - let gradXstroke; - let gradXpath; - let gradXgrad; - // Ajout des graduations au graphique - for (let i = 0; i <= numXguides + 1; i++) { - gradXtext = document.createElementNS("http://www.w3.org/2000/svg", "text"); - gradXtext.setAttribute("class", "profile-x-graduation"); - gradXtext.setAttribute("font-family", "Verdana"); - gradXtext.setAttribute("font-size", "10px"); - gradXtext.setAttribute("fill", "#5E5E5E"); - - // Exclusion du cas de la dernière graduation : correspond à la distance max : pas de texte - if (i !== numXguides + 1) { - // Cas où gradX < 1 : nombres flottants capricieux... - gradXtext.textContent = (Math.round(100 * i * gradX) / 100).toLocaleString(); - } - - xTextTranslation = zLabelWidth + zGradWidth + i * gradXxOffsetPx; - // Cas de la dernière graduation : correspond à la distance max - if (i === numXguides + 1) { - xTextTranslation = zLabelWidth + zGradWidth + pathWidth; - } - - gradXtext.setAttribute("transform", `translate(${xTextTranslation}, ${pathHeight + xGradHeight + 5})`); - gradXtext.setAttribute("text-anchor", "middle"); - axisX.appendChild(gradXtext); - - xStrokeTranslation = xTextTranslation - 0.5; - - gradXstroke = document.createElementNS("http://www.w3.org/2000/svg", "g"); - gradXpath = document.createElementNS("http://www.w3.org/2000/svg", "path"); - gradXpath.setAttribute("cs", "100,100"); - gradXpath.setAttribute("stroke-width", "1"); - if (i !== 0) { - gradXpath.setAttribute("stroke-opacity", "0.2"); - } else { - gradXpath.setAttribute("stroke-opacity", "1"); - } - gradXpath.setAttribute("stroke", "#000000"); - gradXpath.setAttribute("fill", "none"); - gradXpath.setAttribute("d", `M${xStrokeTranslation},${pathHeight} L${xStrokeTranslation},0`); - - gradXgrad = document.createElementNS("http://www.w3.org/2000/svg", "path"); - gradXgrad.setAttribute("cs", "100,100"); - gradXgrad.setAttribute("stroke-width", "1"); - gradXgrad.setAttribute("stroke-opacity", "1"); - gradXgrad.setAttribute("stroke", "#000000"); - gradXgrad.setAttribute("fill", "none"); - gradXgrad.setAttribute("d", `M${xStrokeTranslation},${pathHeight} L${xStrokeTranslation},${pathHeight - 5}`); - gradXgrad.setAttribute("transform", "translate(0, 5)"); - - gradXstroke.appendChild(gradXgrad); - gradXstroke.appendChild(gradXpath); - guidesX.appendChild(gradXstroke); - } - - var axisXLegend = document.createElementNS("http://www.w3.org/2000/svg", "text"); - axisXLegend.setAttribute("class", "profile-x-legend"); - axisXLegend.setAttribute("font-family", "Verdana"); - axisXLegend.setAttribute("font-size", "11px"); - axisXLegend.setAttribute("fill", "#5E5E5E"); - axisXLegend.textContent = `Distance (${distUnit})`; - - axisXLegend.setAttribute("transform", `translate(${zLabelWidth + zGradWidth + pathWidth / 2}, ${pathHeight + xGradHeight + xLabelHeight + 3})`); - axisXLegend.setAttribute("text-anchor", "middle"); - - axisX.appendChild(axisXLegend); - elevationSvg.appendChild(axisX); - elevationSvg.appendChild(guidesX); - - const elevationPathG = document.createElementNS("http://www.w3.org/2000/svg", "g"); - - let factor = 1; - if (distUnit === "km") { - factor = 1000; - } - - let pointX = this._dataDistToSvgX(_points[0].dist / factor, widgetWidth, pathWidth, pxPerMX); - let pointY = this._dataZToSvgY(_points[0].z, pathHeight, minGraphZ, pxPerMZ); - let pathD = `M${pointX},${pointY}`; - - for (let i = 1; i < _points.length; i++) { - pointX = this._dataDistToSvgX(_points[i].dist / factor, widgetWidth, pathWidth, pxPerMX); - pointY = this._dataZToSvgY(_points[i].z, pathHeight, minGraphZ, pxPerMZ); - pathD += ` L${pointX},${pointY}`; - } - - const pathPath = document.createElementNS("http://www.w3.org/2000/svg", "path"); - pathPath.setAttribute("cs", "100,100"); - pathPath.setAttribute("stroke-width", "1"); - pathPath.setAttribute("stroke-opacity", "1"); - pathPath.setAttribute("stroke", "#0B6BA7"); - pathPath.setAttribute("fill", "none"); - pathPath.setAttribute("d", pathD); - - // Fermeture du path pour le fill - pathD += ` L${pointX},${pathHeight}`; - pathD += ` L${widgetWidth - pathWidth},${pathHeight}`; - - const pathFill = document.createElementNS("http://www.w3.org/2000/svg", "path"); - pathFill.setAttribute("cs", "100,100"); - pathFill.setAttribute("stroke-width", "1"); - pathFill.setAttribute("stroke-opacity", "0"); - pathFill.setAttribute("stroke", "#000000"); - pathFill.setAttribute("fill", "#00B798"); - pathFill.setAttribute("fill-opacity", "0.4"); - pathFill.setAttribute("d", pathD); - - elevationPathG.appendChild(pathPath); - elevationPathG.appendChild(pathFill); - elevationSvg.appendChild(elevationPathG); - - // Mise en place de l'écouteur d'évènement : pour l'affichage dynamique - const dynamicsG = document.createElementNS("http://www.w3.org/2000/svg", "g"); - // Pour écouter la position de la souris - const pathRectangle = document.createElementNS("http://www.w3.org/2000/svg", "rect"); - pathRectangle.setAttribute("width", pathWidth); - pathRectangle.setAttribute("height", pathHeight); - pathRectangle.setAttribute("transform", `translate(${widgetWidth - pathWidth},0)`); - pathRectangle.setAttribute("visibility", "hidden"); - pathRectangle.setAttribute("pointer-events", "all"); - - const sortedDist = JSON.parse(JSON.stringify(_points)); - sortedDist.sort(function (e1, e2) { - return e1.dist - e2.dist; - }); - - const focusLineX = document.createElementNS("http://www.w3.org/2000/svg", "line"); - focusLineX.setAttribute("id", "focusLineX"); - focusLineX.setAttribute("class", "focusLine-default"); - focusLineX.setAttribute("fill", "none"); - focusLineX.setAttribute("stroke", "#F90"); - focusLineX.setAttribute("stroke-width", "0.5px"); - focusLineX.setAttribute("visibility", "hidden"); - - const focusLineY = document.createElementNS("http://www.w3.org/2000/svg", "line"); - focusLineY.setAttribute("id", "focusLineY"); - focusLineY.setAttribute("class", "focusLine-default"); - focusLineY.setAttribute("fill", "none"); - focusLineY.setAttribute("stroke", "#F90"); - focusLineY.setAttribute("stroke-width", "0.5px"); - focusLineY.setAttribute("visibility", "hidden"); - - const focusCircle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); - focusCircle.setAttribute("id", "focusCircle"); - focusCircle.setAttribute("r", 4); - focusCircle.setAttribute("class", "circle-default focusCircle-default"); - focusCircle.setAttribute("fill", "#F90"); - focusCircle.setAttribute("visibility", "hidden"); - - dynamicsG.appendChild(focusCircle); - dynamicsG.appendChild(focusLineX); - dynamicsG.appendChild(focusLineY); - - // Tooltip - const tooltipDiv = document.createElementNS("http://www.w3.org/2000/svg", "text"); - const altiSpan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - const slopeSpan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - const coordsSpan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - - tooltipDiv.setAttribute("style", "text-align:center; max-width:220px; font-size:10px; color:#000000; font-family:Verdana; z-index:50;"); - tooltipDiv.style.pointerEvents = "none"; - tooltipDiv.style.position = "fixed"; - // tooltipDiv.classList.add("tooltipInit"); - // IE... - tooltipDiv.setAttribute("class", "tooltipInit"); - tooltipDiv.setAttribute("text-anchor", "middle"); - - widgetDiv.appendChild(tooltipDiv); - - altiSpan.setAttribute("class", "altiPathValue"); - altiSpan.setAttribute("x", "0"); - altiSpan.setAttribute("dy", "-.7em"); - - slopeSpan.setAttribute("class", "altiPathValue"); - slopeSpan.setAttribute("x", "0"); - slopeSpan.setAttribute("dy", "1em"); - - coordsSpan.setAttribute("class", "altiPathCoords"); - coordsSpan.setAttribute("x", "0"); - coordsSpan.setAttribute("dy", "1em"); - - tooltipDiv.appendChild(altiSpan); - if (_displayProfileOptions.currentSlope) { - tooltipDiv.appendChild(slopeSpan); - } - tooltipDiv.appendChild(coordsSpan); - - const tooltipG = document.createElementNS("http://www.w3.org/2000/svg", "g"); - - dynamicsG.appendChild(tooltipG); - - const tooltipBubble = document.createElementNS("http://www.w3.org/2000/svg", "path"); - tooltipBubble.setAttribute("cs", "100,100"); - tooltipBubble.setAttribute("fill", "#FFFFFF"); - tooltipBubble.setAttribute("stroke", "#CCCCCC"); - tooltipBubble.setAttribute("fill-opacity", "0.8"); - tooltipBubble.setAttribute("stroke-width", "1"); - tooltipBubble.setAttribute("stroke-opacity", "1"); - - const tooltipBubbleShadow = document.createElementNS("http://www.w3.org/2000/svg", "path"); - tooltipBubbleShadow.setAttribute("cs", "100,100"); - tooltipBubbleShadow.setAttribute("fill", "#FFFFFF"); - tooltipBubbleShadow.setAttribute("stroke", "#000000"); - tooltipBubbleShadow.setAttribute("fill-opacity", "0"); - tooltipBubbleShadow.setAttribute("stroke-width", "1"); - tooltipBubbleShadow.setAttribute("stroke-opacity", "0.4"); - tooltipBubbleShadow.setAttribute("transform", "translate(1,1)"); - - tooltipG.appendChild(tooltipBubbleShadow); - tooltipG.appendChild(tooltipBubble); - tooltipG.appendChild(tooltipDiv); - - // tooltipG.classList.add("tooltipInit"); - // IE... deprecated - tooltipG.setAttribute("class", "tooltipInit"); - tooltipG.style.pointerEvents = "none"; - - function onMouseOver () { - focusLineX.setAttribute("visibility", "visible"); - focusLineY.setAttribute("visibility", "visible"); - focusCircle.setAttribute("visibility", "visible"); - className.__createProfileMarker(self, _points[0]); - - // tooltips - // tooltipDiv.classList.remove("tooltipInit"); - // tooltipG.classList.remove("tooltipInit"); - // tooltipDiv.classList.remove("tooltipFadeOut"); - // tooltipG.classList.remove("tooltipFadeOut"); - // tooltipDiv.classList.add("tooltipFadeIn"); - // tooltipG.classList.add("tooltipFadeIn"); - // IE... deprecated - tooltipDiv.setAttribute("class", "tooltipFadeIn"); - tooltipG.setAttribute("class", "tooltipFadeIn"); - } - - function onMouseOut () { - focusLineX.setAttribute("visibility", "hidden"); - focusLineY.setAttribute("visibility", "hidden"); - focusCircle.setAttribute("visibility", "hidden"); - className.__removeProfileMarker(self); - // tooltips - // tooltipDiv.classList.remove("tooltipFadeIn"); - // tooltipG.classList.remove("tooltipFadeIn"); - // tooltipDiv.classList.add("tooltipFadeOut"); - // tooltipG.classList.add("tooltipFadeOut"); - // IE... deprecated - tooltipDiv.setAttribute("class", "tooltipFadeOut"); - tooltipG.setAttribute("class", "tooltipFadeOut"); - } - - function onMouseMove (e) { - const mousePoint = elevationSvg.createSVGPoint(); - mousePoint.x = e.clientX; - mousePoint.y = e.clientY; - const svgMousePoint = mousePoint.matrixTransform(elevationSvg.getScreenCTM().inverse()); - const mouseDist = this._svgXToDataDist(svgMousePoint.x, widgetWidth, pathWidth, pxPerMX) * factor; - - // Math.max pour éviter de sortir de l'array - const distIndex = Math.max(1, this._arrayBisect(sortedDist, mouseDist)); - - const d0 = _points[distIndex - 1]; - const d1 = _points[distIndex]; - let d = d0; - if (mouseDist - d0.dist > d1.dist - mouseDist) { - d = d1; - } - - const focusX = this._dataDistToSvgX(d.dist / factor, widgetWidth, pathWidth, pxPerMX); - const focusY = this._dataZToSvgY(d.z, pathHeight, minGraphZ, pxPerMZ); - - // Mise à jour des éléments graphiques - focusCircle.setAttribute("cx", focusX); - focusCircle.setAttribute("cy", focusY); - - focusLineX.setAttribute("x1", focusX); - focusLineX.setAttribute("y1", pathHeight); - focusLineX.setAttribute("x2", focusX); - focusLineX.setAttribute("y2", 0); - - focusLineY.setAttribute("x1", zLabelWidth + zGradWidth); - focusLineY.setAttribute("y1", focusY); - focusLineY.setAttribute("x2", pathWidth + zLabelWidth + zGradWidth); - focusLineY.setAttribute("y2", focusY); - - className.__updateProfileMarker(self, d); - - // Mise à jour du tooltip - const altiSpanTxt = `Altitude : ${d.z.toLocaleString()} m`; - const slopeSpanTxt = `Pente : ${d.slope} %`; - const coordsSpanTxt = `(lat : ${d.lat.toLocaleString()} / lon : ${d.lon.toLocaleString()})`; - - altiSpan.innerHTML = altiSpanTxt; - slopeSpan.innerHTML = slopeSpanTxt; - coordsSpan.innerHTML = coordsSpanTxt; - - const tooltipTextWidth = Math.max( - this._getTextWidth(coordsSpanTxt, coordsSpan), - this._getTextWidth(altiSpanTxt, altiSpan) - ); - - let toolTipBubbleD; - if (d.dist > (dist * factor) / 2) { - toolTipBubbleD = `M -0.5 -0.5 l -6 6 l 0 16 l -${tooltipTextWidth + 10} 0 l 0 -44 l ${tooltipTextWidth + 10} 0 l 0 16 l 6 6`; - tooltipDiv.setAttribute("transform", `translate(${-(tooltipTextWidth / 2 + 12)},0)`); // IE11 ! - } else if (d.dist <= (dist * factor) / 2) { - toolTipBubbleD = `M -0.5 -0.5 l 6 6 l 0 16 l ${tooltipTextWidth + 10} 0 l 0 -44 l -${tooltipTextWidth + 10} 0 l 0 16 l -6 6`; - // Largeur de la fleche de la bulle du tooltip - tooltipDiv.setAttribute("transform", `translate(${(tooltipTextWidth / 2 + 12)},0)`); // IE11 ! - } - - tooltipBubble.setAttribute("d", toolTipBubbleD); - tooltipBubbleShadow.setAttribute("d", toolTipBubbleD); - - tooltipG.setAttribute("transform", `translate(${focusX},${focusY})`); // IE11 ! - tooltipG.style.transform = `translate(${focusX}px,${focusY}px)`; - } - - pathRectangle.addEventListener("pointerover", onMouseOver); - pathRectangle.addEventListener("pointerout", onMouseOut); - pathRectangle.addEventListener("pointermove", onMouseMove.bind(this)); - - dynamicsG.appendChild(pathRectangle); - elevationSvg.appendChild(dynamicsG); - - widgetDiv.appendChild(elevationSvg); - - return container; - }, - - /** - * Display Profile without graphical rendering (raw service response) - * - * @public - * @param {Object} data - elevations values for profile - * @param {HTMLElement} container - html container where to display profile - * @param {Object} context - this control object - * @param {Object} className - calling class (ie ElevationPath) - * @returns {DOMElement} profil container - */ - displayProfileRaw : function (data, container, context, className) { - if (!container) { - return; - } - - // on nettoie toujours... - while (container.firstChild) { - container.removeChild(container.firstChild); - } - - var _points = (data && data.points) ? data.points : {}; - - var div = document.createElement("textarea"); - div.id = "profilElevationResults"; - div.rows = 10; - div.cols = 50; - div.style.width = "100%"; - div.innerHTML = JSON.stringify(_points, undefined, 4); - div.addEventListener("mouseover", function (e) { - className.__customRawProfileMouseOverEvent(context, e); - }); - - // TODO - // for (var i = 0; i < _points.length; i++) { - // var point = _points[i]; - // var divC = document.createElement("code"); - // divC.id = "point_" + i; - // divC.innerHTML = JSON.stringify(point, undefined, 4); - // div.appendChild(divC); - // divC.addEventListener("mouseover", function (e) { - // className.__customRawProfileMouseOverEvent(context, e); - // }); - // } - - container.appendChild(div); - - return container; - }, - - /** - * Display Profile using D3 javascript framework. This method needs D3 libraries to be loaded. - * - * @public - * @param {Object} data - elevations values for profile - * @param {HTMLElement} container - html container where to display profile - * @param {Object} context - this control object - * @param {Object} className - calling class (ie ElevationPath) - * @returns {DOMElement} profil container - */ - displayProfileLibD3 : function (data, container, context, className) { - var self = context; - - if (!container) { - return; - } - - if (!data) { - return; - } - - // on nettoie toujours... - while (container.firstChild) { - container.removeChild(container.firstChild); - } - - var _points = data.points; - - if (data.distance > 2000) { - data.unit = "km"; - for (let i = 0; i < _points.length; i++) { - _points[i].dist /= 1000; - } - } - - var _displayProfileOptions = self.options.displayProfileOptions; - - var margin = { - top : 20, - right : 20, - bottom : 30, - left : 40 - }; - - var widgetWidth = window.getComputedStyle(container).getPropertyValue("width"); - var widgetHeigth = window.getComputedStyle(container).getPropertyValue("height"); - var width = widgetWidth.replace(/px/, "") - margin.left - margin.right; - var height = widgetHeigth.replace(/px/, "") - margin.top - margin.bottom; - - var x = d3.scale.linear() - .range([0, width]); - - var y = d3.scale.linear() - .range([height, 0]); - - var xAxis = d3.svg.axis() - .scale(x) - .orient("bottom") - .ticks(5); - - var yAxis = d3.svg.axis() - .scale(y) - .orient("left") - .ticks(5); - - var line = d3.svg.line() - .interpolate("basis") - .x(function (d) { - return x(d.dist); - }) - .y(function (d) { - return y(d.z); - }); - - var area = d3.svg.area() - .interpolate("basis") - .x(function (d) { - return x(d.dist); - }) - .y0(height) - .y1(function (d) { - return y(d.z); - }); - - var svg = d3.select(container) - .append("svg") - .attr("width", width + margin.left + margin.right) - .attr("height", height + margin.top + margin.bottom) - .append("g") - .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); - - var xDomain = d3.extent(_points, function (d) { - return d.dist; - }); - x.domain(xDomain); - - var yDomain = [ - 0, - d3.max(_points, function (d) { - return d.z; - }) - ]; - y.domain(yDomain); - - svg.append("path") - .datum(_points) - .attr("class", "area-d3") - .attr("d", area); - - svg.append("g") - .attr("class", "x axis-d3") - .attr("transform", "translate(0," + height + ")") - .call(xAxis) - .append("text") - .attr("y", -15) - .attr("dy", ".71em") - .attr("x", width) - .text("Distance (" + data.unit + ")"); - - svg.append("g") - .attr("class", "y axis-d3") - .call(yAxis) - .append("text") - .attr("transform", "rotate(-90)") - .attr("y", 6) - .attr("dy", ".71em") - .text("Altitude (m)"); - - svg.append("g") - .attr("class", "grid-d3 vertical") - .attr("transform", "translate(0," + height + ")") - .call(xAxis - .orient("bottom") - .tickSize(-height, 0, 0) - .tickFormat("") - ); - - svg.append("g") - .attr("class", "grid-d3 horizontal") - .call(yAxis - .orient("left") - .tickSize(-width, 0, 0) - .tickFormat("") - ); - - svg.append("path") - .datum(_points) - .attr("class", "line-d3") - .attr("d", line); - - svg.selectAll("circle") - .data(_points) - .enter() - .append("circle") - .attr("cx", function (d) { - return x(d.dist); - }) - .attr("cy", function (d) { - return y(d.z); - }) - .attr("r", 0) - .attr("class", "circle-d3"); - - var focus = svg.append("g").style("display", "none"); - - focus.append("line") - .attr("id", "focusLineX") - .attr("class", "focusLine-d3"); - focus.append("line") - .attr("id", "focusLineY") - .attr("class", "focusLine-d3"); - focus.append("circle") - .attr("id", "focusCircle") - .attr("r", 4) - .attr("class", "circle-d3 focusCircle-d3"); - - var div = d3.select(container).append("div") - .attr("class", "tooltip-d3") - .style("opacity", 0); - - var bisectDist = d3.bisector(function (d) { - return d.dist; - }).left; - - svg.append("rect") - .attr("class", "overlay-d3") - .attr("width", width) - .attr("height", height) - .on("mouseover", function () { - focus.style("display", null); - className.__createProfileMarker(self, _points[0]); - }) - .on("mouseout", function () { - focus.style("display", "none"); - className.__removeProfileMarker(self); - - // tooltips - div.transition() - .duration(500) - .style("opacity", 0); - }) - .on("mousemove", function () { - var m = d3.mouse(this); - var distance = x.invert(m[0]); - // Math.max pour éviter de sortir de l'array - var i = Math.max(1, bisectDist(_points, distance)); - - var d0 = _points[i - 1]; - var d1 = _points[i]; - var d = distance - d0[0] > d1[0] - distance ? d1 : d0; - - var xc = x(d.dist); - var yc = y(d.z); - - focus.select("#focusCircle") - .attr("cx", xc) - .attr("cy", yc); - focus.select("#focusLineX") - .attr("x1", xc).attr("y1", y(yDomain[0])) - .attr("x2", xc).attr("y2", y(yDomain[1])); - focus.select("#focusLineY") - .attr("x1", x(xDomain[0])).attr("y1", yc) - .attr("x2", x(xDomain[1])).attr("y2", yc); - - className.__updateProfileMarker(self, d); - - // tooltips - div.transition() - .duration(200) - .style("opacity", 0.9); - - var _message = ""; - _message += " Altitude : " + d.z + " m"; - if (_displayProfileOptions.currentSlope) { - _message += "
Pente : " + d.slope + " %"; - } - _message += "
(Lat : " + d.lat + "/ Lon : " + d.lon + ")"; - - div.html(_message) - .style("left", (d3.event.pageX) + "px") - .style("top", (d3.event.pageY - 28) + "px"); - }); - - // return d3.selectAll("rect.overlay")[0][0]; - return svg; - }, - - /** - * Display Profile using Amcharts framework. This method needs AmCharts libraries to be loaded. - * - * @public - * @param {Object} data - elevations values for profile - * @param {HTMLElement} container - html container where to display profile - * @param {Object} context - this control object - * @param {Object} className - calling class (ie ElevationPath) - * @returns {DOMElement} profil container - */ - displayProfileLibAmCharts : function (data, container, context, className) { - var self = context; - - if (!container) { - return; - } - - if (!data) { - return; - } - - var _points = data.points; - - var ballonText = "[[title]] : [[value]]m
"; - var currentSlope = self.options.displayProfileOptions.currentSlope; - if (currentSlope) { - ballonText += "Pente : [[slope]] %
"; - } - ballonText += "(Lat: [[lat]] / Lon:[[lon]])"; - - AmCharts.addInitHandler(function () {}); - - if (data.distance > 2000) { - data.unit = "km"; - for (let i = 0; i < _points.length; i++) { - _points[i].dist /= 1000; - } - } - - for (let i = 0; i < _points.length; i++) { - var dist = _points[i].dist; - var coeffArrond = 100; - if (dist > 100) { - coeffArrond = 1; - } else if (dist > 10) { - coeffArrond = 10; - } - - // Correction arrondi distance totale - dist = Math.round(dist * coeffArrond) / coeffArrond; - _points[i].dist = dist; - } - - var settings = { - type : "serial", - pathToImages : "http://cdn.amcharts.com/lib/3/images/", - categoryField : "dist", - autoMarginOffset : 0, - marginRight : 10, - marginTop : 10, - startDuration : 0, - color : "#5E5E5E", - fontSize : 8, - theme : "light", - thousandsSeparator : "", - numberFormatter : { - precision : -1, - decimalSeparator : ",", - thousandsSeparator : " " - }, - categoryAxis : { - color : "#5E5E5E", - gridPosition : "start", - minHorizontalGap : 40, - tickPosition : "start", - title : "Distance (" + data.unit + ")", - titleColor : "#5E5E5E", - labelOffset : 0, - startOnAxis : true - }, - chartCursor : { - animationDuration : 0, - bulletsEnabled : true, - bulletSize : 10, - categoryBalloonEnabled : false, - cursorColor : "#F90", - graphBulletAlpha : 1, - graphBulletSize : 1, - zoomable : false - }, - trendLines : [], - graphs : [{ - balloonColor : "#CCCCCC", - balloonText : ballonText, - bullet : "round", - bulletAlpha : 0, - bulletBorderColor : "#FFF", - bulletBorderThickness : 2, - bulletColor : "#F90", - bulletSize : 6, - hidden : false, - id : "AmGraph-1", - fillAlphas : 0.4, - fillColors : "#C77A04", - lineAlpha : 1, - lineColor : "#C77A04", - lineThickness : 1, - title : "Altitude", - valueField : "z" - }], - guides : [], - valueAxes : [{ - id : "ValueAxis-1", - minVerticalGap : 20, - title : "Altitude (m)" - }], - balloon : { - borderColor : "#CCCCCC", - borderThickness : 1, - fillColor : "#FFFFFF", - showBullet : true - }, - titles : [], - allLabels : [], - dataProvider : _points - }; - - var _containerProfile = AmCharts.makeChart(container, settings); - - _containerProfile.addListener("changed", function (e) { - var obj = e.chart.dataProvider[e.index]; - className.__updateProfileMarker(self, obj); - }); - - return _containerProfile; - } -}; - -export default ProfileElevationPathDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/Export.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/Export.d.ts deleted file mode 100644 index 02c556254..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/Export.d.ts +++ /dev/null @@ -1,266 +0,0 @@ -export default ButtonExport; -/** - * @classdesc - * - * Export button - * - * @constructor - * @alias ol.control.Export - * @param {Object} options - options for function call. - * @param {String} [options.format = "geojson"] - geojson / kml / gpx - * @param {String} [options.name = "export"] - export name - * @param {String} [options.title = "Exporter"] - button name - * @param {Boolean} [options.menu = false] - displays the format choice menu - * @param {Function} [options.onExport] - callback - * @param {DOMElement} [options.target] - target - * @param {Object} options.control - instance of control - * @fires export:compute - * @example - * // pluggued widget Export into control Isocurve - * var iso = new ol.control.Isocurve(); - * map.addControl(iso); - * - * // method : call render() - * var export = new ButtonExport(); - * export.setControl(iso); - * export.setTarget(); - * export.setName("export"); - * export.setFormat("geojson"); - * export.setTitle("Exporter"); - * export.setMenu(false); - * export.render(); // <-- direct call to render function ! - * export.on("export:compute", (data) => { console.log(data); }); - * - * // method : call map.addControl() - * var export = new ButtonExport(); - * export.setControl(iso); - * export.setTarget(); - * export.setName("export"); - * export.setFormat("geojson"); - * export.setTitle("Exporter"); - * export.setMenu(false); - * export.on("export:compute", (data) => { console.log(data); }); - * map.addControl(export); // <-- using the OpenLayers mechanism, don't call to render function ! - * - * // use control options instead of setters - * var export = new ButtonExport({ - * control : iso, - * target : , - * name : "export", - * format : "geojson", - * title : "Exporter", - * menu : false - * }); - * map.addControl(export); - * - * // method with passing option into the control Isocurve - * var iso = new ol.control.Isocurve({ export : true }); - * // with control options : - * var iso = new ol.control.Isocurve({ export : { - * name : "export", - * format : "geojson", - * title : "Exporter", - * menu : false - * }}); - */ -declare class ButtonExport { - /** - * See {@link ol.control.Export} - * @module ButtonExport - * @alias module:~Controls/ButtonExport - * @param {Object} [options] - options - * @example - * import ButtonExport from "src/OpenLayers/Controls/Export" - */ - constructor(options?: Object | undefined); - /** - * Response to the export of the route calculation - * (only for jsdoc) - * - * @example - * // GeoJSON format - * { - * "type":"FeatureCollection", - * "features":[...], - * "geoportail:compute":{ - * "points":[ [2.588024210134887, 48.84192678293002 ] ], - * "transport":"Voiture", - * "exclusions":[...], - * "computation":"fastest", - * "results":{ } - * } - * - * @see {@link https://ignf.github.io/geoportal-access-lib/latest/jsdoc/Gp.Services.RouteResponse.html|Service} - */ - EXPORT_ROUTE: {}; - /** - * Response to the export of the isochron calculation - * (only for jsdoc) - * - * @example - * // GeoJSON format - * { - * "type":"FeatureCollection", - * "features":[...], - * "geoportail:compute":{ - * "transport":"Pieton", - * "computation":"time", - * "exclusions":[ - * - * ], - * "direction":"departure", - * "point":[ 2.587835382718464, 48.84192678293002 ], - * "results":{ - * "message":"", - * "id":"", - * "location":{ - * "x":"2.587835382718464", - * "y":"48.84192678293002" - * }, - * "srs":"EPSG:4326", - * "geometry":{ - * "type":"Polygon", - * "coordinates":[[...]] - * }, - * "time":180, - * "distance":"" - * } - * } - * } - * - * @see {@link https://ignf.github.io/geoportal-access-lib/latest/jsdoc/Gp.Services.IsoCurveResponse.html|Service} - */ - EXPORT_ISOCHRON: {}; - /** - * Response to the export of the profile calculation - * (only for jsdoc) - * - * @example - * // GeoJSON format - * { - * "type":"FeatureCollection", - * "features":[...], - * "geoportail:compute":{ - * "greaterSlope":76, - * "meanSlope":7, - * "distancePlus":84, - * "distanceMinus":48, - * "ascendingElevation":5, - * "descendingElevation":-4, - * "altMin":"92,04", - * "altMax":"96,71", - * "distance":163, - * "unit":"m", - * "points":[ - * { - * "z":95.68, - * "lon":2.5874, - * "lat":48.8419, - * "acc":2.5, - * "dist":0, - * "slope":0 - * } - * ] - * } - * } - * - * @see {@link https://ignf.github.io/geoportal-access-lib/latest/jsdoc/Gp.Services.AltiResponse.html|Service} - */ - EXPORT_PROFILE: {}; - uid: any; - extension: string | null; - mimeType: string | null; - container: HTMLDivElement | null; - button: any; - menu: any; - icon: string; - menuClassHidden: string; - /** - * Render DOM - * - * @public - */ - public render(): void; - /** - * Initialize options - * (called by constructor) - * - * @param {Object} options - options - * @private - */ - private initOptions; - options: Object | undefined; - /** - * Initialize container - * (called by constructor) - * - * @private - * @todo menu des options - */ - private initContainer; - /** - * ... - * - * @param {String} str - ... - * @returns {DOMElement} - ... - * @private - */ - private stringToHTML; - /** - * ... - * @returns {Boolean} - ... - * @private - */ - private isPluggableControl; - /** - * ... - * @param {Object} layer - ... - * @param {Object} [data] - ... - * @param {Object} [style] - ... - * @returns {String} - ... - * @private - */ - private exportFeatures; - /** - * ... - * @param {*} e - Click - */ - onClickButtonExport(e: any): void; - /** - * ... - * @param {Object} control - ... - * @public - */ - public setControl(control: Object): void; - /** - * ... - * @param {DOMElement} target - ... - * @public - */ - public setTarget(target: DOMElement): void; - /** - * ... - * @param {String} format - ... - * @public - */ - public setFormat(format: string): void; - /** - * ... - * @param {String} name - ... - * @public - */ - public setName(name: string): void; - /** - * ... - * @param {String} title - ... - * @public - */ - public setTitle(title: string): void; - /** - * ... - * @param {Boolean} active - ... - * @public - */ - public setMenu(active: boolean): void; -} -//# sourceMappingURL=Export.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/Export.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/Export.d.ts.map deleted file mode 100644 index 72ad27200..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/Export.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Export.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Export/Export.js"],"names":[],"mappings":";AAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AACH;IAEI;;;;;;;OAOG;IACH,0CA2IC;IApHG;;;;;;;;;;;;;;;;;;OAkBG;IAEH,iBAAsB;IAEtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;IAEH,oBAAyB;IAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IAEH,mBAAwB;IAGxB,SAAsC;IAGtC,yBAAqB;IACrB,wBAAoB;IAGpB,iCAAqB;IACrB,YAAkB;IAClB,UAAgB;IAChB,aAAqB;IACrB,wBAAmD;IAUvD;;;;OAIG;IACH,sBAaC;IAMD;;;;;;OAMG;IACH,oBA0BC;IAxBG,4BAAsB;IA0B1B;;;;;;OAMG;IACH,sBAmFC;IAED;;;;;;OAMG;IACH,qBAyBC;IAED;;;;OAIG;IACH,2BAUC;IAED;;;;;;;OAOG;IACH,uBA8EC;IAKD;;;OAGG;IACH,kCAoDC;IAKD;;;;OAIG;IACH,2BAHW,MAAM,QAKhB;IAED;;;;OAIG;IACH,2CAEC;IAED;;;;OAIG;IACH,uCAsBC;IAED;;;;OAIG;IACH,mCAEC;IAED;;;;OAIG;IACH,qCAMC;IAED;;;;OAIG;IACH,sCAmBC;CAEJ"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/Export.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/Export.js deleted file mode 100644 index 253055adc..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/Export.js +++ /dev/null @@ -1,700 +0,0 @@ -// import CSS -import "../../CSS/Controls/Export/GPFexport.css"; -// import "../../CSS/Controls/Export/GPFexportStyle.css"; - -// import OpenLayers -import Control from "ol/control/Control"; - -// import local -import ID from "../../Utils/SelectorID"; -import Logger from "../../Utils/LoggerByDefault"; - -// import local with ol dependencies -import KMLExtended from "../../Formats/KML"; -import GeoJSONExtended from "../../Formats/GeoJSON"; -import GPXExtended from "../../Formats/GPX"; - -// DOM -import ExportDOM from "./ExportDOM"; - -var logger = Logger.getLogger("export"); - -/** - * @classdesc - * - * Export button - * - * @constructor - * @alias ol.control.Export - * @param {Object} options - options for function call. - * @param {String} [options.format = "geojson"] - geojson / kml / gpx - * @param {String} [options.name = "export"] - export name - * @param {String} [options.title = "Exporter"] - button name - * @param {Boolean} [options.menu = false] - displays the format choice menu - * @param {Function} [options.onExport] - callback - * @param {DOMElement} [options.target] - target - * @param {Object} options.control - instance of control - * @fires export:compute - * @example - * // pluggued widget Export into control Isocurve - * var iso = new ol.control.Isocurve(); - * map.addControl(iso); - * - * // method : call render() - * var export = new ButtonExport(); - * export.setControl(iso); - * export.setTarget(); - * export.setName("export"); - * export.setFormat("geojson"); - * export.setTitle("Exporter"); - * export.setMenu(false); - * export.render(); // <-- direct call to render function ! - * export.on("export:compute", (data) => { console.log(data); }); - * - * // method : call map.addControl() - * var export = new ButtonExport(); - * export.setControl(iso); - * export.setTarget(); - * export.setName("export"); - * export.setFormat("geojson"); - * export.setTitle("Exporter"); - * export.setMenu(false); - * export.on("export:compute", (data) => { console.log(data); }); - * map.addControl(export); // <-- using the OpenLayers mechanism, don't call to render function ! - * - * // use control options instead of setters - * var export = new ButtonExport({ - * control : iso, - * target : , - * name : "export", - * format : "geojson", - * title : "Exporter", - * menu : false - * }); - * map.addControl(export); - * - * // method with passing option into the control Isocurve - * var iso = new ol.control.Isocurve({ export : true }); - * // with control options : - * var iso = new ol.control.Isocurve({ export : { - * name : "export", - * format : "geojson", - * title : "Exporter", - * menu : false - * }}); - */ -class ButtonExport extends Control { - - /** - * See {@link ol.control.Export} - * @module ButtonExport - * @alias module:~Controls/ButtonExport - * @param {Object} [options] - options - * @example - * import ButtonExport from "src/OpenLayers/Controls/Export" - */ - constructor (options) { - options = options || { - control : null, - target : null, - format : "geojson", - name : "export", - title : "Exporter", - menu : false, - onExport : null - }; - - logger.trace("[constructor] Export", options); - - super({ - element : document.createElement("div"), - render : options.render, - target : options.target - }); - - if (!(this instanceof ButtonExport)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - /** - * Response to the export of the route calculation - * (only for jsdoc) - * - * @example - * // GeoJSON format - * { - * "type":"FeatureCollection", - * "features":[...], - * "geoportail:compute":{ - * "points":[ [2.588024210134887, 48.84192678293002 ] ], - * "transport":"Voiture", - * "exclusions":[...], - * "computation":"fastest", - * "results":{ } - * } - * - * @see {@link https://ignf.github.io/geoportal-access-lib/latest/jsdoc/Gp.Services.RouteResponse.html|Service} - */ - // eslint-disable-next-line no-undef - this.EXPORT_ROUTE = {}; - - /** - * Response to the export of the isochron calculation - * (only for jsdoc) - * - * @example - * // GeoJSON format - * { - * "type":"FeatureCollection", - * "features":[...], - * "geoportail:compute":{ - * "transport":"Pieton", - * "computation":"time", - * "exclusions":[ - * - * ], - * "direction":"departure", - * "point":[ 2.587835382718464, 48.84192678293002 ], - * "results":{ - * "message":"", - * "id":"", - * "location":{ - * "x":"2.587835382718464", - * "y":"48.84192678293002" - * }, - * "srs":"EPSG:4326", - * "geometry":{ - * "type":"Polygon", - * "coordinates":[[...]] - * }, - * "time":180, - * "distance":"" - * } - * } - * } - * - * @see {@link https://ignf.github.io/geoportal-access-lib/latest/jsdoc/Gp.Services.IsoCurveResponse.html|Service} - */ - // eslint-disable-next-line no-undef - this.EXPORT_ISOCHRON = {}; - - /** - * Response to the export of the profile calculation - * (only for jsdoc) - * - * @example - * // GeoJSON format - * { - * "type":"FeatureCollection", - * "features":[...], - * "geoportail:compute":{ - * "greaterSlope":76, - * "meanSlope":7, - * "distancePlus":84, - * "distanceMinus":48, - * "ascendingElevation":5, - * "descendingElevation":-4, - * "altMin":"92,04", - * "altMax":"96,71", - * "distance":163, - * "unit":"m", - * "points":[ - * { - * "z":95.68, - * "lon":2.5874, - * "lat":48.8419, - * "acc":2.5, - * "dist":0, - * "slope":0 - * } - * ] - * } - * } - * - * @see {@link https://ignf.github.io/geoportal-access-lib/latest/jsdoc/Gp.Services.AltiResponse.html|Service} - */ - // eslint-disable-next-line no-undef - this.EXPORT_PROFILE = {}; - - // id unique - this.uid = options.id || ID.generate(); - - // export - this.extension = null; - this.mimeType = null; - - // dom - this.container = null; - this.button = null; - this.menu = null; - this.icon = "\u2630 "; - this.menuClassHidden = "GPelementHidden gpf-hidden"; - - this.initOptions(options); - this.initContainer(); - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - - /** - * Render DOM - * - * @public - */ - render () { - // container principal - if (!this.options.target) { - if (this.options.control) { - // insertion du composant dans le panneau du controle - var container = this.options.control.getContainer(); - // ex. GP(iso|route)Panel- - this.options.target = container.lastChild; - } - } - if (this.container) { - this.options.target.appendChild(this.container); - } - } - - // ################################################################### // - // #################### privates methods ############################# // - // ################################################################### // - - /** - * Initialize options - * (called by constructor) - * - * @param {Object} options - options - * @private - */ - initOptions (options) { - // options - this.options = options; - - if (this.options.control) { - // ... - } - - if (this.options.target) { - // ... - } - - var format = this.options.format; - (format) ? this.setFormat(format) : this.setFormat(""); - - if (!this.options.name) { - this.setName("export"); - } - - if (!this.options.title) { - this.setTitle("Exporter"); - } - - if (this.options.menu === undefined) { - this.setMenu(false); - } - } - - /** - * Initialize container - * (called by constructor) - * - * @private - * @todo menu des options - */ - initContainer () { - // TODO - // menu des options de l'export : - // * [ nom ] - // * format - // https://www.w3schools.com/howto/howto_css_dropdown.asp - // https://www.w3schools.com/howto/howto_css_custom_checkbox.asp - - // afficher l'icone du menu - var title = this.options.title; - if (this.options.menu) { - title = this.icon + this.options.title; - } - - var div = document.createElement("div"); - div.id = this._addUID("GPexportContainer"); - div.className = "GPexportMenuContainer"; - - // bouton Exporter - // utiliser les templates literals avec la substitution ${...} - var button = this.stringToHTML(` - - `); - - // add event click button - this.button = button.firstChild; - if (this.button) { - this.button.addEventListener("click", (e) => this.onClickButtonExport(e)); - } - div.appendChild(button.firstChild); - - // menu des options - // utiliser les templates literals avec la substitution ${...} - var menu = this.stringToHTML(` -
- - - -
- `); - - this.menu = menu.firstChild; - if (this.menu) { - if (this.options.menu) { - var className = this.menu.className; - this.menu.className = className.replace(this.menuClassHidden, ""); - } - var radios = this.menu.querySelectorAll(`input[type=radio][name="format"]`); - radios.forEach((radio) => { - // radio checked par defaut - if (radio.id.toUpperCase().includes(this.options.format.toUpperCase())) { - radio.checked = true; - } - // ecouteur pour changer de format - radio.addEventListener("change", (e) => { - this.setFormat(e.target.value); - }); - }); - } - div.appendChild(menu.firstChild); - - this.container = div; - } - - /** - * ... - * - * @param {String} str - ... - * @returns {DOMElement} - ... - * @private - */ - stringToHTML (str) { - var support = function () { - if (!window.DOMParser) { - return false; - } - var parser = new DOMParser(); - try { - parser.parseFromString("x", "text/html"); - } catch (err) { - return false; - } - return true; - }; - - // If DOMParser is supported, use it - if (support()) { - var parser = new DOMParser(); - var doc = parser.parseFromString(str, "text/html"); - return doc.body; - } - - // Otherwise, fallback to old-school method - var dom = document.createElement("div"); - dom.innerHTML = str; - return dom; - } - - /** - * ... - * @returns {Boolean} - ... - * @private - */ - isPluggableControl () { - // tester toutes les méthodes des widgets pluggable - // la méthode getData() n'est pas obligatoire car certains widgets - // n'ont pas de configuration. - if (this.options.control && - typeof this.options.control.getContainer === "function" && - typeof this.options.control.getLayer === "function") { - return true; - } - return false; - } - - /** - * ... - * @param {Object} layer - ... - * @param {Object} [data] - ... - * @param {Object} [style] - ... - * @returns {String} - ... - * @private - */ - exportFeatures (layer, data, style) { - var result = null; - if (!layer) { - logger.warn("Impossible to export : no layer is hosting features."); - return result; - } - if (!layer.getSource() || - !layer.getSource().getFeatures() || - !layer.getSource().getFeatures().length) { - logger.warn("Impossible to export : no features found."); - return result; - } - - // INFO - // les styles sont bien transmis pour l'outil de dessin - // mais, ce n'est pas toujours le cas pour certains widgets !? - // donc, on y ajoute les styles par defaut... - layer.getSource().getFeatures().forEach((feature) => { - var style = feature.getStyle(); - if (!style && typeof this.options.control.getStyle === "function") { - feature.setStyle(this.options.control.getStyle()); - } - }); - - // ajouter les metadonnées de calcul et de configuration - var options = { - defaultStyle : style - }; - if (data) { - // properties ajoutées à la racine : - // ex. "geoportail:compute" : {} - options.extensions = { - "geoportail:compute" : data - }; - } - - var ClassName = null; - switch (this.options.format.toUpperCase()) { - case "KML": - options.writeStyles = true; - options.showPointNames = true; - ClassName = new KMLExtended(options); - break; - case "GPX": - ClassName = new GPXExtended(options); - break; - case "GEOJSON": - ClassName = new GeoJSONExtended(options); - break; - default: - break; - } - - if (!ClassName) { - logger.warn("Impossible to export : format unknown !?"); - return result; - } - - var featProj = layer.getSource().getProjection(); - - // INFO - // on determine la projection de la carte - // si le composant a été ajouté sur la carte via le mécanisme d'OpenLayer... - var map = this.getMap(); - if (map) { - featProj = featProj || map.getView().getProjection(); - } - - var features = layer.getSource().getFeatures(); - - // INFO - // par defaut, webmercator ou "EPSG:3857" - result = ClassName.writeFeatures(features, { - dataProjection : "EPSG:4326", - featureProjection : featProj || "EPSG:3857" - }); - - return result; - } - // ################################################################### // - // ######################## event dom ################################ // - // ################################################################### // - - /** - * ... - * @param {*} e - Click - */ - onClickButtonExport (e) { - if (!this.isPluggableControl()) { - logger.warn("Componant not pluggable with the control !"); - return; - } - - var layer = this.options.control.getLayer(); - var data = (this.options.control.getData !== undefined) ? this.options.control.getData() : {}; - var style = (this.options.control.getStyle !== undefined) ? this.options.control.getStyle() : {}; - - var content = this.exportFeatures(layer, data, style); - if (!content || content === "null") { - return; - } - - /** - * event triggered when the export is finished - * - * @event export:compute - * @typedef {Object} - * @property {Object} type - event - * @property {Object} target - instance Export - * @property {String} content - export data - * @example - * Export.on("export:compute", function (e) { - * console.log(e.target); - * }) - */ - this.dispatchEvent({ - type : "export:compute", - content : content - }); - - // INFO - // la callback annule le download du fichier. - if (this.options.onExport && typeof this.options.onExport === "function") { - this.options.onExport(content); - return; - } - - var link = document.createElement("a"); - // determiner le bon charset ! - var charset = "utf-8"; - link.setAttribute("href", "data:" + this.mimeType + ";charset=" + charset + "," + encodeURIComponent(content)); - link.setAttribute("download", this.options.name + this.extension); - if (document.createEvent) { - var event = document.createEvent("MouseEvents"); - event.initEvent("click", true, true); - link.dispatchEvent(event); - } else { - link.click(); - } - } - - // ################################################################### // - // ##################### public setters ############################## // - // ################################################################### // - /** - * ... - * @param {Object} control - ... - * @public - */ - setControl (control) { - this.options.control = control; - } - - /** - * ... - * @param {DOMElement} target - ... - * @public - */ - setTarget (target) { - this.options.target = target; - } - - /** - * ... - * @param {String} format - ... - * @public - */ - setFormat (format) { - this.options.format = format.toUpperCase(); - switch (this.options.format) { - case "KML": - this.extension = ".kml"; - this.mimeType = "application/vnd.google-earth.kml+xml"; - break; - case "GPX": - this.extension = ".gpx"; - this.mimeType = "application/gpx+xml"; - break; - case "GEOJSON": - this.extension = ".geojson"; - this.mimeType = "application/geo+json"; - break; - default: - // redefine format by default ! - this.options.format = "GEOJSON"; - this.extension = ".geojson"; - this.mimeType = "application/geo+json"; - break; - } - } - - /** - * ... - * @param {String} name - ... - * @public - */ - setName (name) { - this.options.name = name; - } - - /** - * ... - * @param {String} title - ... - * @public - */ - setTitle (title) { - this.options.title = title; - if (this.button) { - // afficher l'icone du menu / titre - this.button.value = (this.options.menu) ? this.icon + title : title; - } - } - - /** - * ... - * @param {Boolean} active - ... - * @public - */ - setMenu (active) { - this.options.menu = active; - if (this.button) { - // afficher l'icone du menu / titre - this.button.value = (this.options.menu) ? this.icon + this.options.title : this.options.title; - } - if (this.menu && this.options.menu) { - // afficher le menu - var className = this.menu.className; - this.menu.className = className.replace(this.menuClassHidden, ""); - // format par defaut - var radios = this.menu.querySelectorAll(`input[type=radio][name="format"]`); - radios.forEach((radio) => { - // radio checked par defaut - if (radio.id.toUpperCase().includes(this.options.format.toUpperCase())) { - radio.checked = true; - } - }); - } - } - -}; - -// on récupère les méthodes de la classe DOM -Object.assign(ButtonExport.prototype, ExportDOM); - -export default ButtonExport; - -// Expose Export as ol.control.Export (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.Export = ButtonExport; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/ExportDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/ExportDOM.d.ts deleted file mode 100644 index 5bba9d425..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/ExportDOM.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default ExportDOM; -declare namespace ExportDOM { - function _addUID(id: string): string; -} -//# sourceMappingURL=ExportDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/ExportDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/ExportDOM.d.ts.map deleted file mode 100644 index e75eeb56e..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/ExportDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ExportDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Export/ExportDOM.js"],"names":[],"mappings":";;IAOc,qCAGT"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/ExportDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/ExportDOM.js deleted file mode 100644 index b0cae9264..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Export/ExportDOM.js +++ /dev/null @@ -1,14 +0,0 @@ -var ExportDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this.uid) ? id + "-" + this.uid : id; - return uid; - } -}; - -export default ExportDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfo.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfo.d.ts deleted file mode 100644 index 67cd7af5b..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfo.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -export default GetFeatureInfo; -/** - * @classdesc - * OpenLayers Control to manage getFeatureInfo capability. All queryable layers can be requested. - * For the vector objects the information displayed are the objects properties. For the wms and wmts layers - * this is the response of the getFeatureInfo request which is shown to the user. - * - * @constructor - * @alias ol.control.GetFeatureInfo - * @extends {ol.control.Control} - * @type {ol.control.GetFeatureInfo} - * @param {Object} options - control options - * @param {Array.} [options.layers] - list of layers which can be requested through the control. Each array element is an object, with following properties : - * @param {ol.layer.Layer} options.layers.obj - {@link http://openlayers.org/en/latest/apidoc/ol.layer.Layer.html ol.layer.Layer} layer handled by the control (that has been added to map). - * @param {String} [options.layers.event] - name of the mouse event triggering getFeatureInfo on this layer (that has been added to map). allowed values are : 'singleclick', 'dblclick' and 'contextmenu'. If not specified the triggering event is the current default event (see options.options.defaultEvent). - * @param {String} [options.layers.infoFormat] - indicates the format mime-type of the response of GetFeatureInfo requests. - * @param {Object} [options.options] - custom options object to configure the control, with following properties : - * @param {Boolean} [options.options.hidden=false] - specifies if the widget should be hidden. - * @param {Boolean} [options.options.auto=false] - specifies if the control run in automatic mode. In automatic mode all vector layers added on run time or added at map initialization can be requested through the control. The triggering event of those layers is the default event. - * @param {Boolean} [options.options.active=true] - specifies if the control is active or inactive. In inactive mode requests are not fired and no information are displayed. - * @param {String} [options.options.defaultEvent="singleclick"] - default triggering event chosen in the list ('singleclick', 'dblclick', 'contextmenu'). This is the triggering event of all layers added to the control without configured triggering event. - * @param {String} [options.options.defaultInfoFormat="text/html"] - indicates the default format mime-type of the response of GetFeatureInfo requests. - * @param {String} [options.options.cursorStyle="pointer"] - specifies the type of cursor to be displayed when pointing on vector feature of a layer previously added to the control. The value must be choosen in the possible values of the css cursor property. - * @param {String} [options.options.proxyUrl] - Proxy URL to avoid cross-domain problems. - * @param {Array.} [options.options.noProxyDomains] - Proxy will not be used for this list of domain names. Only use if you know what you're doing. - * @param {Boolean} [options.options.autoPan = true] - Specifies whether the map should auto-pan if the pop-up is rendered outside of the canvas. Defaults to true. - * @param {Object} [options.options.autoPanAnimation] - Used to customize the auto-pan animation. See {@link https://openlayers.org/en/latest/apidoc/module-ol_Overlay.html#~PanOptions PanOptions}. - * @param {Number} [options.options.autoPanMargin] - Margin (in pixels) between the pop-up and the border of the map when autopanning. Default is 20. - */ -declare var GetFeatureInfo: ol.control.GetFeatureInfo; -//# sourceMappingURL=GetFeatureInfo.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfo.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfo.d.ts.map deleted file mode 100644 index 0d8ff641d..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfo.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"GetFeatureInfo.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/GetFeatureInfo/GetFeatureInfo.js"],"names":[],"mappings":";AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,sDAknBE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfo.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfo.js deleted file mode 100644 index 2f5b8f0f2..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfo.js +++ /dev/null @@ -1,681 +0,0 @@ -// import CSS -import "../../CSS/Controls/GetFeatureInfo/GPFgetFeatureInfo.css"; -// import "../../CSS/Controls/GetFeatureInfo/GPFgetFeatureInfoStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -// import local -import SelectorID from "../../Utils/SelectorID"; -import Logger from "../../Utils/LoggerByDefault"; -// import local with ol dependencies -import GfiUtils from "../Utils/Gfi"; -// DOM -import GetFeatureInfoDOM from "./GetFeatureInfoDOM"; - -var logger = Logger.getLogger("getfeatureinfo"); - -/** - * @classdesc - * OpenLayers Control to manage getFeatureInfo capability. All queryable layers can be requested. - * For the vector objects the information displayed are the objects properties. For the wms and wmts layers - * this is the response of the getFeatureInfo request which is shown to the user. - * - * @constructor - * @alias ol.control.GetFeatureInfo - * @extends {ol.control.Control} - * @type {ol.control.GetFeatureInfo} - * @param {Object} options - control options - * @param {Array.} [options.layers] - list of layers which can be requested through the control. Each array element is an object, with following properties : - * @param {ol.layer.Layer} options.layers.obj - {@link http://openlayers.org/en/latest/apidoc/ol.layer.Layer.html ol.layer.Layer} layer handled by the control (that has been added to map). - * @param {String} [options.layers.event] - name of the mouse event triggering getFeatureInfo on this layer (that has been added to map). allowed values are : 'singleclick', 'dblclick' and 'contextmenu'. If not specified the triggering event is the current default event (see options.options.defaultEvent). - * @param {String} [options.layers.infoFormat] - indicates the format mime-type of the response of GetFeatureInfo requests. - * @param {Object} [options.options] - custom options object to configure the control, with following properties : - * @param {Boolean} [options.options.hidden=false] - specifies if the widget should be hidden. - * @param {Boolean} [options.options.auto=false] - specifies if the control run in automatic mode. In automatic mode all vector layers added on run time or added at map initialization can be requested through the control. The triggering event of those layers is the default event. - * @param {Boolean} [options.options.active=true] - specifies if the control is active or inactive. In inactive mode requests are not fired and no information are displayed. - * @param {String} [options.options.defaultEvent="singleclick"] - default triggering event chosen in the list ('singleclick', 'dblclick', 'contextmenu'). This is the triggering event of all layers added to the control without configured triggering event. - * @param {String} [options.options.defaultInfoFormat="text/html"] - indicates the default format mime-type of the response of GetFeatureInfo requests. - * @param {String} [options.options.cursorStyle="pointer"] - specifies the type of cursor to be displayed when pointing on vector feature of a layer previously added to the control. The value must be choosen in the possible values of the css cursor property. - * @param {String} [options.options.proxyUrl] - Proxy URL to avoid cross-domain problems. - * @param {Array.} [options.options.noProxyDomains] - Proxy will not be used for this list of domain names. Only use if you know what you're doing. - * @param {Boolean} [options.options.autoPan = true] - Specifies whether the map should auto-pan if the pop-up is rendered outside of the canvas. Defaults to true. - * @param {Object} [options.options.autoPanAnimation] - Used to customize the auto-pan animation. See {@link https://openlayers.org/en/latest/apidoc/module-ol_Overlay.html#~PanOptions PanOptions}. - * @param {Number} [options.options.autoPanMargin] - Margin (in pixels) between the pop-up and the border of the map when autopanning. Default is 20. - */ -var GetFeatureInfo = class GetFeatureInfo extends Control { - - /** - * See {@link ol.control.GetFeatureInfo} - * @module GetFeatureInfo - * @alias module:~Controls/GetFeatureInfo - * @param {*} options - options - * @example - * import GetFeatureInfo from "src/OpenLayers/Controls/GetFeatureInfo" - */ - constructor (options) { - options = options || {}; - - var _options = options.options || {}; - var _layers = options.layers || []; - - // call ol.control.Control constructor - super({ - element : _options.element, - target : _options.target, - render : _options.render - }); - - if (!(this instanceof GetFeatureInfo)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - if (!Array.isArray(_layers)) { - throw new Error("ERROR WRONG_TYPE : layers should be an array"); - } - - if (typeof _options !== "object") { - throw new Error("ERROR WRONG_TYPE : options should be an object"); - } - - this._initialize(_options, _layers); - - // init control DOM container - this._container = this._initContainer(_options); - - // ajout du container - (this.element) ? this.element.appendChild(this._container) : this.element = this._container; - - return this; - }; - - // ################################################################### // - // ######################## initialize control ####################### // - // ################################################################### // - - /** - * Initializes GetFeatureInfo control (called by constructor) - * - * @param {Object} options - General options of the control set by user. - * @param {Array.} layers - Array of ol layers with their configuration options (obj, event, infoFormat) - * @private - */ - _initialize (options, layers) { - // identifiant du contrôle : utile pour suffixer les identifiants CSS (pour gérer le cas où il y en a plusieurs dans la même page) - this._uid = SelectorID.generate(); - - this.options = options; - this.options.layers = layers; - - // List of triggering events associated to a boolean indicating if the event is listened (there must be - // almost one layer having this triggering event configured) - this._events = { - dblclick : false, - singleclick : false, - contextmenu : false - }; - - // Object associating a event (key) to his handler (value) in order to unlisten events which have - // no more layers related to. - this._eventsHandler = {}; - - if (typeof options.auto !== "undefined" && typeof options.auto !== "boolean") { - logger.log("[ERROR] GetFeatureInfo:_initialize - auto parameter should be a boolean"); - return; - } - this._auto = options.auto || false; - - if (typeof options.active !== "undefined" && typeof options.active !== "boolean") { - logger.log("[ERROR] GetFeatureInfo:_initialize - active parameter should be a boolean"); - return; - } - this._active = (typeof options.active === "undefined") ? true : options.active; - - if (options.defaultEvent && typeof options.defaultEvent !== "string") { - logger.log("[ERROR] GetFeatureInfo:_initialize - defaultEvent parameter should be a string"); - return; - } - this._defaultEvent = options.defaultEvent || "singleclick"; - if (!this._isValidEvent(this._defaultEvent)) { - logger.log("[ERROR] GetFeatureInfo:_initialize - _defaultEvent '" + this._defaultEvent + "' is not a valid event"); - return; - } - - if (options.defaultInfoFormat && typeof options.defaultInfoFormat !== "string") { - logger.log("[ERROR] GetFeatureInfo:_initialize - defaultInfoFormat parameter should be a string"); - return; - } - this._defaultInfoFormat = options.defaultInfoFormat || "text/html"; - - if (options.cursorStyle && typeof options.cursorStyle !== "string") { - logger.log("[ERROR] GetFeatureInfo:_initialize - cursorStyle parameter should be a string"); - return; - } - this._cursorStyle = options.cursorStyle || "pointer"; - - if (options.proxyUrl) { - if (typeof options.proxyUrl !== "string") { - logger.log("[ERROR] GetFeatureInfo:_initialize - proxyUrl parameter should be a string"); - return; - } - this._proxyUrl = options.proxyUrl; - } - - if (options.noProxyDomains) { - if (!Array.isArray(options.noProxyDomains)) { - logger.log("[ERROR] GetFeatureInfo:_initialize - noProxyDomains parameter should be a array"); - return; - } - this._noProxyDomains = options.noProxyDomains; - } - - if (typeof options.autoPan !== "undefined" && typeof options.autoPan !== "boolean") { - logger.log("[ERROR] GetFeatureInfo:_initialize - autoPan parameter should be a boolean"); - return; - } - this._autoPan = (typeof options.autoPan === "undefined") ? true : options.autoPan; - - if (options.autoPanAnimation) { - if (options.autoPanAnimation.duration) { - if (typeof options.autoPanAnimation.duration !== "number") { - logger.log("[ERROR] GetFeatureInfo:_initialize - autoPanAnimation parameter is invalid : duration should be a number."); - return; - } - } - - if (options.autoPanAnimation.easing) { - if (typeof options.autoPanAnimation.easing !== "function") { - logger.log("[ERROR] GetFeatureInfo:_initialize - autoPanAnimation parameter is invalid : easing should be a ol.easing function or a custom function."); - return; - } - } - this._autoPanAnimation = options.autoPanAnimation; - } - - if (options.autoPanMargin) { - if (typeof options.autoPanMargin !== "number") { - logger.log("[ERROR] GetFeatureInfo:_initialize - autoPanMargin parameter should be a number"); - return; - } - this._autoPanMargin = options.autoPanMargin; - } - - // {Object} control layers list. - if (!Array.isArray(layers)) { - logger.log("[ERROR] GetFeatureInfo:_initialize - layers parameter should be an array"); - return; - } - this._setLayers(layers); - - // {Object} control panel container (DOM Element) - this._activateGetFeatureInfoButton = null; - } - - /** - * Binds map to control. - * - * @param {ol.Map} map - Map. - */ - setMap (map) { - if (map) { - // on active les evenements (si des couches sont configurees) - this._updateEvents(map); - - if (this._cursorStyle && this._active) { - this._activateCursor(true, map); - } - - map.getLayers().on( - "remove", - (evt) => { - for (var i = 0; i < this._layers.length; ++i) { - if (this._layers[i].obj === evt.element) { - this._layers.splice(i, 1); - break; - } - } - this._updateEvents(map); - } - ); - - if (this._auto) { - // ajout des couches vecteur deja dans la carte - var updated = false; - map.getLayers().forEach((olLayer) => { - var layerFormat = GfiUtils.getLayerFormat(olLayer); - if (!this._hasLayer(olLayer) && layerFormat === "vector") { - this._layers.push({ - obj : olLayer - }); - updated = true; - } - }); - - if (updated) { - this._updateEvents(map); - } - - map.getLayers().on( - "add", - (evt) => { - var layerFormat = GfiUtils.getLayerFormat(evt.element); - if (layerFormat === "vector") { - this._layers.push({ - obj : evt.element - }); - } - this._updateEvents(map); - } - ); - } - } else { - this._clearEvents(); - this._activateCursor(false); - } - - // call original setMap method - super.setMap(map); - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - } - - // ################################################################### // - // #################### user interface methods ####################### // - // ################################################################### // - - /** - * Gets the list of layers already added to the map and attached to the control. - * - * @returns {Array.} gfiLayers List of layers. - * @returns {ol.layer.Layer} gfiLayers.obj {@link http://openlayers.org/en/latest/apidoc/ol.layer.Layer.html ol.layer.Layer} layer handled by the control (that has been added to map). - * @returns {String} gfiLayers.event Optional. Name of the mouse event triggering getFeatureInfo on this layer (that has been added to map). allowed values are : 'singleclick', 'dblclick' and 'contextmenu'. - * @returns {String} gfiLayers.infoFormat Optional. Indicates the format mime-type of the response of GetFeatureInfo requests. - */ - getLayers () { - return this._layers; - } - - /** - * Sets the default event applied to layer with no triggering event configured. - * This can be set on run time. - * - * @param {String} eventName - name of the mouse event chosen in the list : 'singleclick', 'dblclick', 'contextmenu'. - */ - setDefaultEvent (eventName) { - if (typeof eventName !== "string") { - logger.log("[ERROR] GetFeatureInfo:setDefaultEvent - eventName parameter should be a string"); - return; - } - if (!eventName || !this._isValidEvent(eventName)) { - logger.log("[ERROR] GetFeatureInfo:setDefaultEvent - event '" + eventName + "' is not allowed."); - return; - } - - this._defaultEvent = eventName; - this._updateEvents(); - } - - /** - * Sets the cursor style when hovering vector layers features. - * - * @param {String} cursorStyle - cursor style. The value must be choosen in the possible values of the css cursor property. - */ - setCursorStyle (cursorStyle) { - if (typeof cursorStyle !== "string") { - logger.log("[ERROR] GetFeatureInfo:setCursorStyle - cursorStyle parameter should be a string"); - return; - } - if (this._active) { - if (!this._cursorStyle && cursorStyle) { - this._activateCursor(true); - } else if (this._cursorStyle && !cursorStyle) { - this._activateCursor(false); - } - } - this._cursorStyle = cursorStyle; - } - - /** - * Sets active control property - * - * @param {Boolean} active - specify the value the active property must be set to. - */ - setActive (active) { - this._setActive(active); - this._activateGetFeatureInfoButton.setAttribute("aria-pressed", active); - } - - /** - * Sets active control property - * - * @param {Boolean} active - specify the value the active property must be set to. - * - * @private - */ - _setActive (active) { - if (typeof active !== "boolean") { - logger.log("[ERROR] GetFeatureInfo:_setActive - active parameter should be a boolean"); - return; - } - if (this._active === active) { - return; - } - this._active = active; - if (this._cursorStyle) { - this._activateCursor(active); - } - } - - /** - * Gets active control property - * - * @return {Boolean} active - */ - isActive () { - return this._active; - } - - /** - * Hides/displays widget - * - * @param {Boolean} hidden - specify if the widget must be hidden - */ - setHidden (hidden) { - this.element.style.visibility = (hidden) ? "hidden" : ""; - } - - /** - * Indicates if the widget is hidden - * - * @return {Boolean} is hidden - */ - isHidden () { - return this.element.style.visibility === "hidden"; - } - - /** - * Set the layers list the control is attached to. Listened events are updated according to this list. - * - * @param {Array.} gfiLayers - list of layers which can be requested through the control. - * @param {ol.layer.Layer} gfiLayers.obj - {@link http://openlayers.org/en/latest/apidoc/ol.layer.Layer.html ol.layer.Layer} layer handled by the control (that has been added to map). - * @param {String} [gfiLayers.event] - Name of the mouse event triggering getFeatureInfo on this layer (that has been added to map). allowed values are : 'singleclick', 'dblclick' and 'contextmenu'. - * @param {String} [gfiLayers.infoFormat] - Indicates the format mime-type of the response of GetFeatureInfo requests. - */ - setLayers (gfiLayers) { - this._setLayers(gfiLayers); - this._updateEvents(); - } - - /** - * Indicates if an event is allowed - * - * @param {String} eventName - name of the mouse event chosen in the list : 'singleclick', 'dblclick', 'contextmenu'. - * - * @returns {Boolean} is valid event - * - * @private - */ - _isValidEvent (eventName) { - return Object.keys(this._events).indexOf(eventName) > -1; - } - - /** - * Adds an event listener to the specified event. - * - * @param {String} eventName - name of the mouse event chosen in the list : 'singleclick', 'dblclick', 'contextmenu'. - * @param {Object} map - map on wich event are attached. - * - * @private - */ - _activateEvent (eventName, map) { - var gfiObj = this; - - var getFeatureInfoHandler = function (e) { - GfiUtils.onDisplayFeatureInfo(e, gfiObj); - }; - - if (eventName === "contextmenu") { - map.getViewport().addEventListener( - eventName, - getFeatureInfoHandler - ); - } else { - map.on( - eventName, - getFeatureInfoHandler - ); - } - - this._eventsHandler[eventName] = getFeatureInfoHandler; - - this._events[eventName] = true; - } - - /** - * Unlistens the specified event. - * @param {String} eventName - name of the mouse event chosen in the list : 'singleclick', 'dblclick', 'contextmenu'. - * @param {Object} map - map on wich event are attached. - * - * @private - */ - _deactivateEvent (eventName, map) { - if (eventName === "contextmenu") { - map.getViewport().removeEventListener( - eventName, - this._eventsHandler[eventName] - ); - } else { - map.un( - eventName, - this._eventsHandler[eventName] - ); - } - - delete this._eventsHandler[eventName]; - - this._events[eventName] = false; - } - - /** - * Updates the listener (listen/unlisten) in accordance with the layers attached to the control and their triggering events. - * - * @param {Object} map - map on wich event are attached. - * - * @private - */ - _updateEvents (map) { - if (!map) { - map = this.getMap(); - } - var sEvent = []; - for (var i = 0; i < this._layers.length; ++i) { - var event = (this._layers[i].event) ? this._layers[i].event : this._defaultEvent; - if (sEvent.indexOf(event) < 0) { - sEvent.push(event); - } - } - - for (var eventName in this._events) { - if (!this._events[eventName] && sEvent.indexOf(eventName) >= 0) { - this._activateEvent(eventName, map); - } else if (this._events[eventName] && sEvent.indexOf(eventName) < 0) { - this._deactivateEvent(eventName, map); - } - } - } - - /** - * Clears all the listeners. - * - * @private - */ - _clearEvents () { - var map = this.getMap(); - for (var eventName in this._events) { - if (this._events[eventName]) { - this._deactivateEvent(eventName, map); - } - } - } - - /** - * Indicates if the control has the specified layer attached - * - * @param {ol.layer.Layer} olLayer - layer openlayers - * - * @returns {Boolean} has layer - * - * @private - */ - _hasLayer (olLayer) { - for (var i = 0; i < this._layers.length; ++i) { - if (this._layers[i].obj === olLayer) { - return true; - } - } - return false; - } - - /** - * Listens/unlistens 'pointermove' event displaying specific cursor style when hovering vector features - * - * @param {Boolean} activate - specify if the control must be activated or deactivated - * @param {Object} map - map on wich cursor is attached. - * - * @private - */ - _activateCursor (activate, map) { - if (!map) { - map = this.getMap(); - } - - if (activate) { - if (this._eventsHandler.hasOwnProperty("pointermove")) { - logger.log("[ERROR] _activateCursor - inconsistent state: pointermove event handler already registered"); - return; - } - var gfiObj = this; - - var displayCursor = function (evt) { - var hit = map.forEachFeatureAtPixel(evt.pixel, (feature, layer) => { - // on ne prend en compte que les couches vecteurs connues du controle - var gfiLayers = gfiObj.getLayers(); - for (var m = 0; m < gfiLayers.length; ++m) { - if (gfiLayers[m].obj === layer) { - return true; - } - } - }); - if (hit) { - map.getTargetElement().style.cursor = gfiObj._cursorStyle; - } else { - map.getTargetElement().style.cursor = ""; - } - }; - - this._eventsHandler["pointermove"] = displayCursor; - map.on("pointermove", displayCursor); - } else { - if (this._eventsHandler.hasOwnProperty("pointermove")) { // si le widget n'a jamais ete active l'evenement pointermove n'existe pas - map.un("pointermove", this._eventsHandler["pointermove"]); - delete this._eventsHandler["pointermove"]; - } - map.getTargetElement().style.cursor = ""; - } - } - - /** - * Sets the layers list the control is attached to. - * @param {Array.} gfiLayers - list of layers which can be requested through the control. - * - * @private - */ - _setLayers (gfiLayers) { - if (!gfiLayers || !Array.isArray(gfiLayers)) { - logger.log("[ERROR] GetFeatureInfo:setLayers - gfiLayers parameter should be a array"); - return; - } - this._layers = []; - - for (var i = 0; i < gfiLayers.length; ++i) { - var ind = this._layers.push({}) - 1; - - if (gfiLayers[i].event) { - if (!this._isValidEvent(gfiLayers[i].event)) { - logger.log("[ERROR] GetFeatureInfo:setLayers - layer event '" + this._layers[i].event + "' is not allowed."); - } else { - this._layers[ind].event = gfiLayers[i].event; - } - } - - if (gfiLayers[i].infoFormat) { - this._layers[ind].infoFormat = gfiLayers[i].infoFormat; - } - - this._layers[ind].obj = gfiLayers[i].obj; - } - } - - // ################################################################### // - // ######################## methods handle dom ####################### // - // ################################################################### // - - /** - * This method is called by event 'change' on 'GPactivateGetFeatureInfo' - * tag select (cf. this._createActivateGetFeatureInfoElement). - * - * @method onActivateGetFeatureInfoElementChange - * @param {Object} e - HTMLElement - * - * @private - */ - onActivateGetFeatureInfoElementChange (e) { - var opened = e.target.getAttribute("aria-pressed"); - this._setActive(opened === "true"); - } - - /** - * Creates control main container (called by GetFeatureInfo constructor) - * @param {Object} [options] - options object to configure the widget : - * @param {Boolean} [options.hidden] - specifies if the widget should be hidden. - * - * @return {DOMElement} DOM element - * - * @method _initContainer - * - * @private - */ - _initContainer (options) { - // creation du container principal - var container = this._createMainContainerElement(); - - // ajout dans le container principal du picto du controle - var picto = this._createMainPictoElement(); - container.appendChild(picto); - - if (typeof options.hidden !== "undefined") { - if (typeof options.hidden !== "boolean") { - logger.log("[ERROR] GetFeatureInfo:_initContainer - hidden parameter should be a boolean"); - return; - } - if (options.hidden) { - container.style.visibility = "hidden"; - } - } - - return container; - } - -}; - -// on récupère les méthodes de la classe commune GetFeatureInfo -Object.assign(GetFeatureInfo.prototype, GetFeatureInfoDOM); - -export default GetFeatureInfo; - -// Expose GetFeatureInfo as ol.control.GetFeatureInfo (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.GetFeatureInfo = GetFeatureInfo; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.d.ts deleted file mode 100644 index 7e11b9159..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default GetFeatureInfoDOM; -declare namespace GetFeatureInfoDOM { - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createMainPictoElement(): DOMElement; -} -//# sourceMappingURL=GetFeatureInfoDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.d.ts.map deleted file mode 100644 index a9050cc66..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"GetFeatureInfoDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.js"],"names":[],"mappings":";;IAOc,qCAGT;IAO6B,mDAK7B;IAUyB,+CAwBzB"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.js deleted file mode 100644 index b83c268cd..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/GetFeatureInfo/GetFeatureInfoDOM.js +++ /dev/null @@ -1,60 +0,0 @@ -var GetFeatureInfoDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Main container (DOM) - * - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPgetFeatureInfo"); - container.className = "GPwidget gpf-widget gpf-widget-button"; - return container; - }, - - // ################################################################### // - // ################# Methods to display Main Panel ################### // - // ################################################################### // - - /** - * Creation du container du picto du controle (DOM) - * @returns {DOMElement} DOM element - */ - _createMainPictoElement : function () { - var self = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPgetFeatureInfoPicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto GPgetFeatureInfoPicto gpf-btn gpf-btn-icon gpf-btn-icon-getfeatureinfo fr-btn"; - button.title = "activer/desactiver l'interrogation des couches"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onActivateGetFeatureInfoElementChange(e); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onActivateGetFeatureInfoElementChange(e); - }); - } - return button; - } -}; - -export default GetFeatureInfoDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/Isocurve.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/Isocurve.d.ts deleted file mode 100644 index f5dcc04e1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/Isocurve.d.ts +++ /dev/null @@ -1,65 +0,0 @@ -export default Isocurve; -/** - * @classdesc - * - * Isocurve Control. - * - * @constructor - * @alias ol.control.Isocurve - * @type {ol.control.Isocurve} - * @extends {ol.control.Control} - * @param {Object} options - Isocurve control options - * @param {String} [options.apiKey] - API key for services call (isocurve and autocomplete services). The key "calcul" is used by default. - * @param {Boolean} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean} [options.collapsed = true] - Specify if widget has to be collapsed (true) or not (false) on map loading. Default is true. - * @param {Boolean} [options.draggable = false] - Specify if widget is draggable - * @param {Boolean|Object} [options.export = false] - Specify if button "Export" is displayed. For the use of the options of the "Export" control, see {@link ol.control.Export} - * @param {Object} [options.exclusions = {"toll" : false, "tunnel" : false, "bridge" : false}] - list of exclusions with status (true = checked). By default : no exclusions checked. - * @param {Array} [options.graphs = ["Voiture", "Pieton"]] - list of graph resources to be used for isocurve calculation, by default : ["Voiture", "Pieton"]. Possible values are "Voiture" and "Pieton". The first element is selected. - * @param {Array} [options.methods = ["time", "distance"]] - list of methods, by default : ["time", "distance"]. Possible values are "time" and "distance". The first element is selected by default. - * @param {Array} [options.directions = ["departure", "arrival"]] - list of directions to be displayed, by default : ["departure", "arrival"]. The first element is selected by default. Possible values are "departure" and "arrival". - * Directions enable to specify if input location point will be used as a departure point ("departure") or as an arrival point ("arrival") - * @param {Object} [options.isocurveOptions = {}] - isocurve service options. see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~isoCurve Gp.Services.isoCurve()} to know all isocurve options. - * @param {Object} [options.autocompleteOptions = {}] - autocomplete service options. see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~autoComplete Gp.Services.autoComplete()} to know all autocomplete options - * @param {Object} [options.markerOpts] - options to use your own marker. Default is a lightOrange marker. - * @param {String} [options.markerOpts.url] - marker base64 encoded url (ex "data:image/png;base64,...""). Mandatory for a custom marker - * @param {Array} [options.markerOpts.offset] - Offsets in pixels used when positioning the overlay. The first element in the array is the horizontal offset. A positive value shifts the overlay right. The second element in the array is the vertical offset. A positive value shifts the overlay down. Default is [0, 0]. (see http://openlayers.org/en/latest/apidoc/ol.Overlay.html) - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Isochrone/Isodistance"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "isochrone/isodistance basé sur un graphe"] - Layer description to be displayed in LayerSwitcher - * @fires isocurve:drawstart - * @fires isocurve:drawend - * @fires isocurve:compute - * @fires export:compute - * @example - * var iso = ol.control.Isocurve({ - * "collapsed" : false, - * "draggable" : true, - * "export" : false, - * "methods" : ["time", "distance"], - * "exclusions" : { - * "toll" : true, - * "bridge" : false, - * "tunnel" : true - * }, - * "graphs" : ["Pieton", "Voiture"], - * "markerOpts" : { - * "url" : "...", - * "offset" : [0,0] - * } - * "isocurveOptions" : {}, - * "autocompleteOptions" : {} - * }); - * - * // if you want to pluggued the control Export with options : - * var iso = new ol.control.Isocurve({ - * export : { - * name : "export", - * format : "geojson", - * title : "Exporter", - * menu : false - * } - * }); - */ -declare var Isocurve: ol.control.Isocurve; -//# sourceMappingURL=Isocurve.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/Isocurve.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/Isocurve.d.ts.map deleted file mode 100644 index d891879ae..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/Isocurve.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Isocurve.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Isocurve/Isocurve.js"],"names":[],"mappings":";AAmCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,0CAk+CE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/Isocurve.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/Isocurve.js deleted file mode 100644 index fdd8490cd..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/Isocurve.js +++ /dev/null @@ -1,1637 +0,0 @@ -// import CSS -import "../../CSS/Controls/Isochron/GPFisochron.css"; -// import "../../CSS/Controls/Isochron/GPFisochronStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -import { unByKey as olObservableUnByKey } from "ol/Observable"; -import VectorLayer from "ol/layer/Vector"; -import VectorSource from "ol/source/Vector"; -// import GeoJSON from "ol/format/GeoJSON"; -import { - Fill, - Stroke, - Style -} from "ol/style"; -// import geoportal library access -import Gp from "geoportal-access-lib"; -// import local -import Utils from "../../Utils/Helper"; -import Logger from "../../Utils/LoggerByDefault"; -import SelectorID from "../../Utils/SelectorID"; -import Markers from "../Utils/Markers"; -import Draggable from "../../Utils/Draggable"; -import Interactions from "../Utils/Interactions"; -// import local with ol dependencies -import LayerSwitcher from "../LayerSwitcher/LayerSwitcher"; -import LocationSelector from "../LocationSelector/LocationSelector"; -import ButtonExport from "../Export/Export"; -import GeoJSONExtended from "../../Formats/GeoJSON"; - -// DOM -import IsocurveDOM from "./IsocurveDOM"; - -var logger = Logger.getLogger("isocurve"); - -/** - * @classdesc - * - * Isocurve Control. - * - * @constructor - * @alias ol.control.Isocurve - * @type {ol.control.Isocurve} - * @extends {ol.control.Control} - * @param {Object} options - Isocurve control options - * @param {String} [options.apiKey] - API key for services call (isocurve and autocomplete services). The key "calcul" is used by default. - * @param {Boolean} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean} [options.collapsed = true] - Specify if widget has to be collapsed (true) or not (false) on map loading. Default is true. - * @param {Boolean} [options.draggable = false] - Specify if widget is draggable - * @param {Boolean|Object} [options.export = false] - Specify if button "Export" is displayed. For the use of the options of the "Export" control, see {@link ol.control.Export} - * @param {Object} [options.exclusions = {"toll" : false, "tunnel" : false, "bridge" : false}] - list of exclusions with status (true = checked). By default : no exclusions checked. - * @param {Array} [options.graphs = ["Voiture", "Pieton"]] - list of graph resources to be used for isocurve calculation, by default : ["Voiture", "Pieton"]. Possible values are "Voiture" and "Pieton". The first element is selected. - * @param {Array} [options.methods = ["time", "distance"]] - list of methods, by default : ["time", "distance"]. Possible values are "time" and "distance". The first element is selected by default. - * @param {Array} [options.directions = ["departure", "arrival"]] - list of directions to be displayed, by default : ["departure", "arrival"]. The first element is selected by default. Possible values are "departure" and "arrival". - * Directions enable to specify if input location point will be used as a departure point ("departure") or as an arrival point ("arrival") - * @param {Object} [options.isocurveOptions = {}] - isocurve service options. see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~isoCurve Gp.Services.isoCurve()} to know all isocurve options. - * @param {Object} [options.autocompleteOptions = {}] - autocomplete service options. see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~autoComplete Gp.Services.autoComplete()} to know all autocomplete options - * @param {Object} [options.markerOpts] - options to use your own marker. Default is a lightOrange marker. - * @param {String} [options.markerOpts.url] - marker base64 encoded url (ex "data:image/png;base64,...""). Mandatory for a custom marker - * @param {Array} [options.markerOpts.offset] - Offsets in pixels used when positioning the overlay. The first element in the array is the horizontal offset. A positive value shifts the overlay right. The second element in the array is the vertical offset. A positive value shifts the overlay down. Default is [0, 0]. (see http://openlayers.org/en/latest/apidoc/ol.Overlay.html) - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Isochrone/Isodistance"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "isochrone/isodistance basé sur un graphe"] - Layer description to be displayed in LayerSwitcher - * @fires isocurve:drawstart - * @fires isocurve:drawend - * @fires isocurve:compute - * @fires export:compute - * @example - * var iso = ol.control.Isocurve({ - * "collapsed" : false, - * "draggable" : true, - * "export" : false, - * "methods" : ["time", "distance"], - * "exclusions" : { - * "toll" : true, - * "bridge" : false, - * "tunnel" : true - * }, - * "graphs" : ["Pieton", "Voiture"], - * "markerOpts" : { - * "url" : "...", - * "offset" : [0,0] - * } - * "isocurveOptions" : {}, - * "autocompleteOptions" : {} - * }); - * - * // if you want to pluggued the control Export with options : - * var iso = new ol.control.Isocurve({ - * export : { - * name : "export", - * format : "geojson", - * title : "Exporter", - * menu : false - * } - * }); - */ -var Isocurve = class Isocurve extends Control { - - /** - * See {@link ol.control.Isocurve} - * @module Isocurve - * @alias module:~Controls/Isocurve - * @param {*} options - options - * @example - * import Isocurve from "src/OpenLayers/Controls/Isocurve" - */ - constructor (options) { - options = options || {}; - - // call ol.control.Control constructor - super({ - element : options.element, - target : options.target, - render : options.render - }); - - if (!(this instanceof Isocurve)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - // initialisation du composant - this.initialize(options); - - // // Widget main DOM container - this._container = this._createMainContainerElement(); - - // ajout du container - (this.element) ? this.element.appendChild(this._container) : this.element = this._container; - - return this; - } - - /** - * Overwrite OpenLayers setMap method - * - * @param {ol.Map} map - Map. - */ - setMap (map) { - if (map) { - // enrichissement du DOM du container lors de l'ajout à la carte - this._container = this._initContainer(map); - - // ajout d'un bouton d'export - if (this.options.export) { - var opts = Utils.assign({ control : this }, this.options.export); - this.export = new ButtonExport(opts); - this.export.render(); - var self = this; - this.export.on("export:compute", (e) => { - self.dispatchEvent({ - type : "export:compute", - content : e.content - }); - }); - } - - // mode "draggable" - if (this.draggable) { - Draggable.dragElement( - this._IsoPanelContainer, - this._IsoPanelHeaderContainer, - this.options.position ? null : map.getTargetElement() - ); - } - - // mode "collapsed" - if (!this.collapsed) { - this._pictoIsoButton.setAttribute("aria-pressed", true); - } - } - - // on appelle la méthode setMap originale d'OpenLayers - super.setMap(map); - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - - /** - * Returns true if widget is collapsed (minimized), false otherwise - * - * @returns {Boolean} collapsed - true if widget is collapsed - */ - getCollapsed () { - return this.collapsed; - } - - /** - * Collapse or display widget main container - * - * @param {Boolean} collapsed - True to collapse widget, False to display it - */ - setCollapsed (collapsed) { - if (collapsed === undefined) { - logger.log("[ERROR] Isocurve:setCollapsed - missing collapsed parameter"); - return; - } - if ((collapsed && this.collapsed) || (!collapsed && !this.collapsed)) { - return; - } - if (collapsed) { - document.getElementById("GPisochronPanelClose-" + this._uid).click(); - } else { - this._pictoIsoButton.click(); - } - this.collapsed = collapsed; - } - - /** - * Get vector layer where Isocurve geometry is drawn - * - * @returns {Object} layer - ol.layer.Vector isocurve layer - */ - getLayer () { - return this._geojsonLayer; - } - - /** - * Set vector layer where Isocurve geometry is drawn - * - * @param {Object} layer - ol.layer.Vector isocurve layer - */ - setLayer (layer) { - if (!layer) { - this._geojsonLayer = null; - return; - } - - if (!(layer instanceof VectorLayer)) { - logger.log("no valid layer given for hosting drawn features."); - return; - } - - // application des styles - layer.setStyle(this._defaultFeatureStyle); - - // sauvegarde - this._geojsonLayer = layer; - } - - /** - * Get vector layer - * - * @returns {String} geojson - GeoJSON format layer - */ - getGeoJSON () { - return JSON.stringify(this._geojsonObject); - } - - /** - * Set vector layer - * - * @param {String} geojson - GeoJSON format layer - */ - setGeoJSON (geojson) { - try { - this._geojsonObject = JSON.parse(geojson); - } catch (e) { - logger.log("no valid geojson given :" + e.message); - } - } - - /** - * Get isocurve data - * - * @returns {Object} data - process results - */ - getData () { - var data = { - type : "isocurve", - transport : this._currentTransport, - computation : this._currentComputation, - exclusions : this._currentExclusions, - direction : this._currentDirection, - point : this._originPoint.getCoordinate(), // lon/lat wgs84 - results : {} - }; - Utils.assign(data.results, this._currentIsoResults); - return data; - } - - /** - * Set isocurve data - * - * @param {Object} data - control informations - * @param {String} data.transport - transport type - * @param {String} data.computation - computation type - * @param {Array} data.exclusions - list of exclusions - * @param {String} data.direction - direction type - * @param {Array} data.point - [lon, lat] - * @param {Object} data.results - service response - */ - setData (data) { - this._currentTransport = data.transport; - this._currentComputation = data.computation; - this._currentExclusions = data.exclusions; - this._currentDirection = data.direction; - // INFO - // > this._originPoint.clear(); - // l'utilisation de cette méthode declenche des evenements qui retirent la couche en cours ! - // (cf. _createIsoPanelFormPointElement), - var inputPointer = document.getElementById("GPlocationOriginPointer_" + 1 + "-" + this._uid); - inputPointer.checked = true; - var inputCoords = document.getElementById("GPlocationOriginCoords_" + 1 + "-" + this._uid); - inputCoords.value = ""; - this._originPoint.setCoordinate(data.point, "EPSG:4326"); - this._currentIsoResults = data.results; - } - - /** - * Get container - * - * @returns {DOMElement} container - */ - getContainer () { - return this._container; - } - - /** - * Get default style - * - * @returns {ol.style} style - */ - getStyle () { - return this._defaultFeatureStyle; - } - - /** - * This method is public. - * It allows to control the execution of a traitment. - * - * @param {Array} position - position in the projection map [ x, y ] - * @param {Object} value - distance in km or hours-minutes - * @param {Object} options - options = {...} - */ - compute (position, value, options) { - this._clear(); - - var opened = this._pictoIsoButton.ariaPressed; - if (!(opened === "true")) { - this._pictoIsoButton.click(); - } - - var map = this.getMap(); - if (!map) { - return; - } - - // Les options par defauts - var settings = { - direction : "departure", - method : "time", - transport : "Voiture", - exclusions : [] - }; - - // On recupere les options - Utils.assign(settings, options); - - this._originPoint.setCoordinate(position); - var coordinate = this._originPoint.getCoordinate(); - - var input = document.getElementById("GPlocationOrigin_" + 1 + "-" + this._uid); - input.value = coordinate[0].toFixed(4) + " / " + coordinate[1].toFixed(4); - - this._currentTransport = settings.transport; - if (settings.transport === "Voiture") { - document.getElementById("GPisochronTransportCar-" + this._uid).checked = true; - } else { - document.getElementById("GPisochronTransportPedestrian-" + this._uid).checked = true; - } - - this._currentExclusions = settings.exclusions; - - this._currentComputation = settings.method; - if (settings.method === "time") { - var time = value.split("."); - this._currentTimeHour = time[0] || 0; - document.getElementById("GPisochronValueChronInput1-" + this._uid).value = this._currentTimeHour; - this._currentTimeMinute = time[1] || 0; - document.getElementById("GPisochronValueChronInput2-" + this._uid).value = this._currentTimeMinute; - document.getElementById("GPisochronChoiceAltChron-" + this._uid).click(); - } else { - this._currentDistance = value; - document.getElementById("GPisochronValueDistInput-" + this._uid).value = this._currentDistance; - document.getElementById("GPisochronChoiceAltDist-" + this._uid).click(); - } - - this._currentDirection = settings.direction; - (settings.direction === "departure") - ? document.getElementById("GPisochronDirectionSelect-" + this._uid).selectedIndex = 0 : document.getElementById("GPisochronDirectionSelect-" + this._uid).selectedIndex = 1; - - this.onIsoComputationSubmit(); - } - - /** - * This method is public. - * It allows to init the control. - */ - init () { - // point - var coordinate = this._originPoint.getCoordinate(); - - var input = document.getElementById("GPlocationOrigin_" + 1 + "-" + this._uid); - input.value = coordinate[1].toFixed(4) + " / " + coordinate[0].toFixed(4); - - // transport - if (this._currentTransport === "Voiture") { - document.getElementById("GPisochronTransportCar-" + this._uid).checked = true; - } else { - document.getElementById("GPisochronTransportPedestrian-" + this._uid).checked = true; - } - - // method - if (this._currentComputation === "time") { - var minutes = this._currentIsoResults.time / 60; - this._currentTimeHour = Math.floor(minutes / 60); - document.getElementById("GPisochronValueChronInput1-" + this._uid).value = this._currentTimeHour; - this._currentTimeMinute = Math.round(((minutes / 60) - this._currentTimeHour) * 60); - document.getElementById("GPisochronValueChronInput2-" + this._uid).value = this._currentTimeMinute; - document.getElementById("GPisochronChoiceAltChron-" + this._uid).click(); - } else { - this._currentDistance = this._currentIsoResults.distance / 1000; - document.getElementById("GPisochronValueDistInput-" + this._uid).value = this._currentDistance; - document.getElementById("GPisochronChoiceAltDist-" + this._uid).click(); - } - - // direction - (this._currentDirection === "departure") - ? document.getElementById("GPisochronDirectionSelect-" + this._uid).selectedIndex = 0 : document.getElementById("GPisochronDirectionSelect-" + this._uid).selectedIndex = 1; - } - - /** - * Clean UI : reinit control - */ - clean () { - this._clearIsoInputs(); - // INFO - // le comportement est surchargé, ceci supprime la couche !? - // cf. _createIsoPanelFormPointElement() - this._originPoint.clearResults(); - document.getElementById("GPlocationPoint_1-" + this._uid).style.cssText = ""; - document.getElementById("GPlocationOriginCoords_1-" + this._uid).value = ""; - document.getElementById("GPlocationOrigin_1-" + this._uid).value = ""; - document.getElementById("GPlocationPoint_1-" + this._uid).style.cssText = ""; - document.getElementById("GPlocationOriginPointer_1-" + this._uid).checked = false; - document.getElementById("GPlocationOrigin_1-" + this._uid).className = "GPlocationOriginVisible gpf-visible"; - document.getElementById("GPlocationOriginCoords_1-" + this._uid).className = "GPlocationOriginHidden gpf-hidden"; - this._currentIsoResults = null; - this.setLayer(); - } - - // ################################################################### // - // ##################### init component ############################## // - // ################################################################### // - - /** - * Initialize Isocurve control (called by Isocurve constructor) - * - * @param {Object} options - constructor options - * @private - */ - initialize (options) { - this._checkInputOptions(options); - - // set default options - this.options = { - collapsed : true, - draggable : false, - export : false, - methods : ["time", "distance"], - graphs : ["Voiture", "Pieton"], - exclusions : { - toll : false, - tunnel : false, - bridge : false - }, - directions : ["departure", "arrival"], - markerOpts : { - url : Markers["lightOrange"], - offset : Markers.defaultOffset - }, - isocurveOptions : {}, - autocompleteOptions : {}, - layerDescription : { - title : "Isochrone/Isodistance", - description : "isochrone/isodistance basé sur un graphe" - } - }; - - // merge with user options - Utils.assign(this.options, options); - - /** {Boolean} specify if isocurve control is collapsed (true) or not (false) */ - this.collapsed = this.options.collapsed; - - /** {Boolean} specify if isocurve control is draggable (true) or not (false) */ - this.draggable = this.options.draggable; - - // identifiant du contrôle : utile pour suffixer les identifiants CSS (pour gérer le cas où il y en a plusieurs dans la même page) - this._uid = SelectorID.generate(); - - // Options du service paramétrables via l'interface (graph, method, exclusions) - // Mode de transport selectionné : 'Voiture' ou 'Pieton' - this._currentTransport = null; - this._initTransport(); - // Mode de calcul selectionné : 'time' (isochron) ou 'distance' (isodistance) - this._currentComputation = null; - this._initComputation(); - // Exclusions selectionnées : Tunnel, Toll et Bridge - this._currentExclusions = []; - this._initExclusions(); - // sens de parcours : "departure" ou "arrival" - this._currentDirection = null; - this._initDirection(); - - // point de saisie - this._originPoint = null; - - // containers principaux - this._pictoIsoButton = null; - this._waitingContainer = null; - this._formContainer = null; - this._IsoPanelContainer = null; - this._IsoPanelHeaderContainer = null; - - // les résultats du calcul - this._currentIsoResults = null; - - // la géométrie - this._geojsonLayer = null; - this._geojsonObject = null; - - // bouton export - this.export = null; - - // si un calcul est en cours ou non - this._waiting = false; - // timer pour cacher la patience après un certain temps - this._timer = null; - - // styles pour les sélections des features - this._defaultFeatureStyle = new Style({ - fill : new Fill({ - color : "rgba(0, 183, 152, 0.7)" - }), - stroke : new Stroke({ - color : "rgba(0, 183, 152, 0)", - width : 1 - }) - }); - - // liste des ressources avec droits par service - // Ex. { - // "Isocurve" : { - // key : "ger4g456re45er456t4er5ge5", - // resources : ["Pieton", "Voiture"] - // } - // } - this._resources = {}; - - // listener key for event click on map - this.listenerKey = null; - } - - /** - * this method is called by this.initialize() - * - * @param {Object} options - options - * - * @private - */ - _checkInputOptions (options) { - // vérification des options - // on ne permet pas de n'afficher aucun mode de calcul ou aucun mode de transport ? - var i; - - // modes de calcul - if (options.methods) { - if (Array.isArray(options.methods)) { - // on ne permet pas de passer un tableau vide : on spécifie au moins une méthode - if (options.methods.length === 0) { - options.methods = null; - } else { - for (i = 0; i < options.methods.length; i++) { - if (typeof options.methods[i] !== "string") { - logger.log("[ol.control.Isocurve] ERROR : parameter 'methods' elements should be of type 'string'"); - } - } - } - } else { - logger.warn("'methods' parameter should be an array"); - options.methods = null; - } - } - - // mode de transport - if (options.graphs) { - if (Array.isArray(options.graphs)) { - // on ne permet pas de passer un tableau vide : on spécifie au moins un graph - if (options.graphs.length === 0) { - options.graphs = null; - } else { - for (i = 0; i < options.graphs.length; i++) { - if (typeof options.graphs[i] !== "string") { - logger.log("[ol.control.Isocurve] ERROR : parameter 'graphs' elements should be of type 'string'"); - } else { - if (options.graphs[i].toLowerCase() === "pieton") { - options.graphs[i] = "Pieton"; - } - if (options.graphs[i].toLowerCase() === "voiture") { - options.graphs[i] = "Voiture"; - } - } - } - } - } else { - logger.warn("'graphs' parameter should be an array"); - options.graphs = null; - } - } - - // sens du parcours - if (options.directions) { - if (Array.isArray(options.directions)) { - // on ne permet pas de passer un tableau vide : on spécifie au moins une direction - if (options.directions.length === 0) { - options.directions = null; - } else { - for (i = 0; i < options.directions.length; i++) { - if (typeof options.directions[i] !== "string") { - logger.log("[ol.control.Isocurve] ERROR : parameter 'directions' elements should be of type 'string'"); - } - } - } - } else { - logger.warn("'directions' parameter should be an array"); - options.directions = null; - } - } - - // collapsed - if (options.collapsed === "true") { - options.collapsed = true; - } - if (options.collapsed === "false") { - options.collapsed = false; - } - } - - /** - * this method is called by this.initialize() and initialize transport mode - * ("Voiture" ou "Pieton") - * - * @private - */ - _initTransport () { - // Mode de transport selectionné - this._currentTransport = "Voiture"; // par defaut - - // par defaut - var transports = this.options.graphs; - if (!transports || transports.length === 0) { - this.options.graphs = ["Voiture", "Pieton"]; - } - - // option - if (Array.isArray(transports) && transports.length) { - // FIXME pb si le 1er graphe n'est pas une ressource connue ! - if (transports[0] === "Voiture" || transports[0] === "Pieton") { - this._currentTransport = transports[0]; - } - } - - // si l'utilisateur a spécifié un graph dans le service, on surcharge les options du widget - var serviceOptions = this.options.isocurveOptions; - if (serviceOptions.graph) { - this._currentTransport = serviceOptions.graph; - } - } - - /** - * this method is called by this.initialize() and initialize computation mode - * (time or distance) - * - * @private - */ - _initComputation () { - // Mode de calcul selectionné - this._currentComputation = "time"; // par defaut - - // par defaut - var methods = this.options.methods; - if (!methods || methods.length === 0) { - this.options.methods = ["time", "distance"]; - } - - // option - if (Array.isArray(methods) && methods.length) { - // FIXME pb si le 1er graphe n'est pas une ressource connue ! - if (methods[0] === "time" || methods[0] === "distance") { - this._currentComputation = methods[0]; - } - } - - // si l'utilisateur a spécifié une méthode dans le service, on surcharge les options du widget - var serviceOptions = this.options.isocurveOptions; - if (serviceOptions.method) { - this._currentComputation = serviceOptions.method; - } - if (serviceOptions.time) { - this._currentComputation = "time"; - } - if (serviceOptions.distance) { - this._currentComputation = "distance"; - } - } - - /** - * this method is called by this.initialize() and initialize direction mode - * (departure or arrival) - * - * @private - */ - _initDirection () { - // Mode de calcul selectionné - this._currentDirection = "departure"; // par defaut - - // par defaut - var directions = this.options.directions; - if (!directions || directions.length === 0) { - this.options.directions = ["departure", "arrival"]; - } - - // option - if (Array.isArray(directions) && directions.length) { - // FIXME pb si le 1er graphe n'est pas une ressource connue ! - if (directions[0] === "departure" || directions[0] === "arrival") { - this._currentDirection = directions[0]; - } - } - - // si l'utilisateur a spécifié une méthode dans le service, on surcharge les options du widget - var serviceOptions = this.options.isocurveOptions; - if (!serviceOptions.reverse) { - this._currentDirection = "departure"; - } - if (serviceOptions.reverse === true) { - this._currentDirection = "arrival"; - this.options.directions = ["arrival", "departure"]; - } - } - - /** - * this method is called by this.initialize() and initialize exclusions - * - * @private - */ - _initExclusions () { - // Exclusions selectionnées : Tunnel, Toll et Bridge - this._currentExclusions = []; // par defaut - - // par defaut - var exclusion = this.options.exclusions; - if (!exclusion || (typeof exclusion === "object" && Object.keys(exclusion).length === 0)) { - this.options.exclusions = { - toll : false, - tunnel : false, - bridge : false - }; - } - - // option - if (exclusion && typeof exclusion === "object" && Object.keys(exclusion).length) { - for (var k in exclusion) { - if (exclusion.hasOwnProperty(k)) { - if (exclusion.k) { - this._currentExclusions.push(k); - } - } - } - } - - // si l'utilisateur a spécifié des exclusions dans le service, on surcharge les options du widget - var serviceOptions = this.options.isocurveOptions; - if (Array.isArray(serviceOptions.exclusions)) { - this._currentExclusions = serviceOptions.exclusions; - } - } - - // ################################################################### // - // ######################## DOM initialize ########################### // - // ################################################################### // - - /** - * initialize component container (DOM) - * - * @param {Object} map - the map - * - * @returns {DOMElement} DOM element - * - * @private - */ - _initContainer (map) { - // get main container - var container = this._container; - - var picto = this._pictoIsoButton = this._createShowIsoPictoElement(); - container.appendChild(picto); - - // panneau - var panel = this._IsoPanelContainer = this._createIsoPanelElement(); - var panelDiv = this._createIsoPanelDivElement(); - panel.appendChild(panelDiv); - - // header - var header = this._IsoPanelHeaderContainer = this._createIsoPanelHeaderElement(); - panelDiv.appendChild(header); - - // form - var form = this._formContainer = this._createIsoPanelFormElement(); - - // form: input de saisie de la localisation (fonction de Isocurve, voir ci-dessous) - var point = this._createIsoPanelFormPointElement(map); - form.appendChild(point); - - var isoChronChecked = false; - var isoDistChecked = false; - var typeChoice = this._createIsoPanelFormTypeChoiceElement(); - for (var i = 0; i < this.options.methods.length; i++) { - if (this.options.methods[i] === "time") { - isoChronChecked = (i === 0); - typeChoice.appendChild(this._createIsoPanelFormTypeChoiceChronElement(isoChronChecked)); - } - if (this.options.methods[i] === "distance") { - isoDistChecked = (i === 0); - typeChoice.appendChild(this._createIsoPanelFormTypeChoiceDistElement(isoDistChecked)); - } - } - form.appendChild(typeChoice); - - // form: menu du choix des valeurs - form.appendChild(this._createIsoPanelFormValueIsochronElement(isoChronChecked)); - form.appendChild(this._createIsoPanelFormValueIsodistanceElement(isoDistChecked)); - - // form: menu du choix du transport et du sens du parcours - var modeChoice = this._createIsoPanelFormModeChoiceElement(); - modeChoice.appendChild(this._createIsoPanelFormModeChoiceTransportElement(this.options.graphs)); - // FIXME : doit on passer le paramètre defaultDirection ? - modeChoice.appendChild(this._createIsoPanelFormModeChoiceDirectionElement(this.options.directions)); - form.appendChild(modeChoice); - - // form: menu des exclusions - if (this.options.exclusions && (typeof this.options.exclusions === "object") && (Object.keys(this.options.exclusions).length !== 0)) { - form.appendChild(this._createShowIsoExclusionsPictoElement()); - var exclusion = this._createIsoPanelFormExclusionsElement(); - exclusion.appendChild(this._createIsoPanelFormExclusionOptionsElement(this.options.exclusions)); - form.appendChild(exclusion); - } - - // footer - var footer = this._createIsoPanelFooterElement(); - form.appendChild(footer); - - var buttonReset = this._createIsoFormResetElement(); - footer.appendChild(buttonReset); - - // form: bouton du calcul - var buttonSubmit = this._submitContainer = this._createIsoSubmitFormElement(); - footer.appendChild(buttonSubmit); - - panelDiv.appendChild(form); - - // waiting - var waiting = this._waitingContainer = this._createIsoWaitingElement(); - panel.appendChild(waiting); - - container.appendChild(panel); - - // hide autocomplete suggested locations on container click - if (container.addEventListener) { - container.addEventListener("click", (e) => this._hideIsoSuggestedLocations(e)); - } - - return container; - } - - /** - * Create start point - * - * @param {Object} map - the map - * - * @returns {Object} DOM element - * @private - */ - _createIsoPanelFormPointElement (map) { - this._originPoint = new LocationSelector({ - apiKey : this.options.apiKey || null, - tag : { - id : 1, - groupId : this._uid, - markerOpts : this.options.markerOpts, - label : "Départ", - display : true - }, - autocompleteOptions : this.options.autocompleteOptions || null - }); - this._originPoint.setMap(map); - // a la sélection d'un nouveau point, on réinitialise aussi le tracé - var self = this; - // click sur le pointer - document.getElementById("GPlocationOriginPointerImg_1-" + this._uid).onclick = function () { - self._clearGeojsonLayer(); - var map = self.getMap(); - if (self._originPoint._inputShowPointerContainer.checked) { - // au click sur l'input pour pointer sur la carte: on minimise le formulaire - self._formContainer.className = "GPisochronFormMini gpf-panel__content fr-modal__content"; - // et au clic sur la carte, on réaffichera le formulaire "normal" - this.listenerKey = map.on( - "click", - () => { - self._formContainer.className = "gpf-panel__content fr-modal__content"; - self.dispatchEvent("isocurve:drawend"); - } - ); - } else { - // si on déselectionne le pointer, on rétablit le formulaire en mode normal - self._formContainer.className = "gpf-panel__content fr-modal__content"; - // et on enlève l'écouteur d'évènement sur la carte - // map.un("click", () => { self._formContainer.className = ""; }); - olObservableUnByKey(this.listenerKey); - } - /** - * event triggered at the start of drawing input - * - * @event isocurve:drawstart - */ - self.dispatchEvent("isocurve:drawstart"); - }; - // click sur le label - document.getElementById("GPlocationOriginLabel_1-" + this._uid).onclick = function () { - self._clearGeojsonLayer(); - self._formContainer.className = "gpf-panel__content fr-modal__content"; - // on désactive l'écouteur d'événements sur la carte (pour ne pas placer un marker au clic) - map.un( - "click", - () => { - self._formContainer.className = "gpf-panel__content fr-modal__content"; - } - ); - self.dispatchEvent("isocurve:drawend"); - }; - // click sur la zone de saisie - document.getElementById("GPlocationOrigin_1-" + this._uid).onclick = function () { - self._clearGeojsonLayer(); - /** - * event triggered at the end of drawing input - * - * @event isocurve:drawend - */ - self.dispatchEvent("isocurve:drawend"); - }; - return this._originPoint._container; - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - - /** - * this method is called by event 'submit' on 'GPisochronForm' tag form - * (cf. this._createIsoPanelFormElement), - * and call isocurve service to display results - * - * @private - */ - onIsoComputationSubmit () { - // si on n'a pas de valeur récupérée pour notre point origine, on ne fait rien - if (!this._originPoint || !this._originPoint.getCoordinate || !this._originPoint.getCoordinate()) { - logger.log("[Isocurve] Missing position parameter to submit isocurve request"); - return; - } - - // récupération de l'origine - var positionCoordinates = this._originPoint.getCoordinate(); - var position = { - x : positionCoordinates[0], - y : positionCoordinates[1] - }; - logger.log("origin : ", position); - - // récupération du temps ou de la distance - var time; - var distance; - if (this._currentComputation.toLowerCase() === "time") { - var timeHourInput = document.getElementById("GPisochronValueChronInput1-" + this._uid); - var hours = parseInt(timeHourInput.value, 10); - if (isNaN && isNaN(hours)) { - hours = 0; - } - var timeMinutesInput = document.getElementById("GPisochronValueChronInput2-" + this._uid); - var minutes = parseInt(timeMinutesInput.value, 10); - if (isNaN && isNaN(minutes)) { - minutes = 0; - } - // durée exprimée en secondes - time = hours * 3600 + minutes * 60; - logger.log("time : " + time); - } - if (this._currentComputation.toLowerCase() === "distance") { - var distInput = document.getElementById("GPisochronValueDistInput-" + this._uid); - // distance exprimée en mètres - distance = parseFloat(distInput.value) * 1000; - logger.log("distance : " + distance); - } - - // si on n'a pas de valeur de calcul renseignée, on ne lance pas la requête. - if (!time && !distance) { - logger.log("[Isocurve] Missing time or distance parameter to submit isocurve request"); - return; - } - - // on recupere les éventuelles options du service passées par l'utilisateur - var options = this.options.isocurveOptions || {}; - - // gestion du protocole et du timeout - // le timeout est indispensable sur le protocole JSONP. - var _protocol = options.protocol || "XHR"; - var _timeout = options.timeOut || 0; - if (_protocol === "JSONP" && _timeout === 0) { - // FIXME le timeout est obligatoire pour ce type de protocole... - _timeout = 15000; - } - - // gestion des callback - var bOnFailure = !!(options.onFailure !== null && typeof options.onFailure === "function"); // cast variable to boolean - var bOnSuccess = !!(options.onSuccess !== null && typeof options.onSuccess === "function"); - - // on met en place l'affichage des resultats dans la fenetre de resultats. - var context = this; - var isoRequestOptions = { - position : position, - graph : options.graph || this._currentTransport, - exclusions : options.exclusions || this._currentExclusions, - method : options.method || this._currentComputation, - smoothing : options.smoothing || true, - timeOut : _timeout, - protocol : _protocol, - resource : options.resource, - // callback onSuccess - onSuccess : function (results) { - logger.log(results); - if (results) { - context._drawIsoResults(results); - } - if (bOnSuccess) { - options.onSuccess.call(context, results); - } - }, - // callback onFailure - onFailure : function (error) { - // FIXME mise à jour du controle mais le service ne repond pas en 200 !? - context._hideWaitingContainer(); - logger.log(error.message); - if (bOnFailure) { - options.onFailure.call(context, error); - } - } - }; - if ((this._currentDirection.toLowerCase() === "arrival") || (options.reverse)) { - isoRequestOptions.reverse = true; - } - if (time) { - isoRequestOptions.time = time; - } - if (distance) { - isoRequestOptions.distance = distance; - } - - this._requestIsoCurve(isoRequestOptions); - } - - /** - * this method is called by event 'click' on 'GPshowIsochronPicto' picto - * (cf. this._createShowIsoPictoElement), - * and clear inputs and previous isocurve drawings - * - * @private - */ - onShowIsoPanelClick () { - var map = this.getMap(); - // on supprime toutes les interactions - Interactions.unset(map); - var opened = this._pictoIsoButton.ariaPressed; - this.collapsed = !(opened === "true"); - // on génère nous même l'evenement OpenLayers de changement de propriété - // (utiliser ol.control.Isocurve.on("change:collapsed", function ) pour s'abonner à cet évènement) - this.dispatchEvent("change:collapsed"); - } - - /** - * this method is called by event 'change' on 'GPisochronChoiceAltDist' or 'GPisochronChoiceAltChron' - * input (cf. this._createIsoPanelFormTypeChoiceElement), - * and updates current computation mode - * - * @param {Object} e - HTMLElement - * @private - */ - onIsoTypeChoiceChange (e) { - var value = e.target.value; - if (!value) { - return; - } - if (value === "isodistance") { - this._currentComputation = "distance"; - } - if (value === "isochron") { - this._currentComputation = "time"; - } - } - - /** - * this method is called by event 'click' on 'GPisochronTransportPedestrian' or 'GPisochronTransportCar' - * input (cf. this._createIsoPanelFormModeChoiceTransportElement), - * and updates current transport mode - * - * @param {Object} e - HTMLElement - * @private - */ - onIsoModeTransportChange (e) { - var value = e.target.value; - if (!value) { - return; - } - this._currentTransport = value; - } - - /** - * this method is called by event 'change' on 'GPisochronDirectionSelect' select - * (cf. this._createIsoPanelFormModeChoiceDirectionElement), - * and updates current direction mode - * - * @param {Object} e - HTMLElement - * @private - */ - onIsoModeDirectionChange (e) { - var value = e.target.value; - if (!value) { - return; - } - if (value.toLowerCase() === "arrival") { - this._originPoint._buttonLabel.innerHTML = "Arrivée"; - } else { - this._originPoint._buttonLabel.innerHTML = "Départ"; - } - this._currentDirection = value; - } - - /** - * this method is called by event 'change' on 'GPIsoExclusionsToll' - * or 'GPIsoeExclusionsTunnel' or 'GPIsoExclusionsBridge' tag input - * (cf. this._createIsoPanelFormExclusionOptionsElement). - * this value is saved as a parameter for the service isocurve. - * - * @param {Object} e - HTMLElement - * @private - */ - onIsoExclusionsChange (e) { - var value = e.target.value; - var checked = e.target.checked; - - if (!value) { - return; - } - - var bFound = false; - var iFound = null; - for (var i = 0; i < this._currentExclusions.length; i++) { - if (deepEqual(this._currentExclusions[i], value.toLowerCase())) { - iFound = i; - bFound = true; - } - } - // on l'ajoute si la valeur n'existe pas et est selectionnée - if (!bFound && !checked) { - this._currentExclusions.push(value.toLowerCase()); - } - // on la retire si la valeur existe et est deselectionnée - if (bFound && checked) { - this._currentExclusions[iFound] = null; - } - } - - /** - * this method is called by event 'click' on 'GPisoReset' - * tag label (cf. this._createIsoFormResetElement), - * and it cleans all isochron input options and results. - * - * @private - */ - onIsoResetClick () { - // clear - this._clear(); - } - - /** - * ... - * @private - */ - onShowIsoSettingsClick () {} - - // ################################################################### // - // ######################## isocurve calculation ##################### // - // ################################################################### // - - /** - * this method is called by this.onIsoComputationSubmit - * and executes a request to the service. - * - * @param {Object} options - isocurve service request options - * @private - */ - _requestIsoCurve (options) { - // on ne fait pas de requête si on n'a pas renseigné de parametres ! - if (!options || ((typeof options === "object") && (Object.keys(options).length === 0))) { - return; - } - // on ne fait pas de requête si on n'a pas de point d'origine - if (!options.position) { - return; - } - - // si l'utilisateur a spécifié le paramètre ssl au niveau du control, on s'en sert - // true par défaut (https) - if (typeof options.ssl !== "boolean") { - if (typeof this.options.ssl === "boolean") { - options.ssl = this.options.ssl; - } else { - options.ssl = true; - } - } - - logger.log(options); - - // on efface une éventuelle précédente couche - this._clearGeojsonLayer(); - - // mise en place de la patience - this._displayWaitingContainer(); - - // appel du service de calcul d'isochrones - Gp.Services.isoCurve(options); - } - - /** - * this method is called by this.onIsoComputationSubmit (in case of success) - * and draw isocurve results geometry on map - * - * @param {Object} results - isocurve response results - * @private - */ - _drawIsoResults (results) { - // sauvegarde de l'etat des resultats - this._currentIsoResults = results; - // cache la patience - this._hideWaitingContainer(); - - if (!results.geometry) { - return; - } - - var map = this.getMap(); - - // 1. création de l'objet geoJSON - this._geojsonObject = { - type : "FeatureCollection", - crs : { - type : "name", - properties : { - name : "EPSG:4326" - } - }, - features : [ - { - type : "Feature", - crs : { - type : "name", - properties : { - name : "EPSG:4326" - } - }, - geometry : results.geometry - } - ] - }; - this._geojsonObject.features.push({ - type : "Feature", - geometry : { - type : "Point", - coordinates : this._originPoint.getCoordinate() - }, - properties : { - description : "Point d'origine", - "marker-symbol" : this.options.markerOpts.url - } - }); - var geojsonformat = new GeoJSONExtended({ - defaultDataProjection : "EPSG:4326", - defaultStyle : this._defaultFeatureStyle - }); - var mapProj = map.getView().getProjection().getCode(); - var features = geojsonformat.readFeatures( - this._geojsonObject, { - dataProjection : "EPSG:4326", - featureProjection : mapProj - } - ); - - // 2. ajout de la géométrie comme nouvelle couche vecteur à la carte - this._geojsonLayer = new VectorLayer({ - source : new VectorSource({ - features : features - }), - style : this._defaultFeatureStyle, - opacity : 0.9 - }); - // ajout d'un identifiant à la couche - var graph; - if (this._currentTransport === "Pieton") { - graph = "piéton"; - this._geojsonLayer.gpResultLayerId = "Pieton$GEOPORTAIL:GPP:Isocurve"; - } else { - graph = "voiture"; - this._geojsonLayer.gpResultLayerId = "Voiture$GEOPORTAIL:GPP:Isocurve"; - } - // ajout à la carte - map.addLayer(this._geojsonLayer); - - /** - * event triggered when the compute is finished - * - * @event isocurve:compute - * @typedef {Object} - * @property {Object} type - event - * @property {Object} target - instance Isocurve - * @example - * Isocurve.on("isocurve:compute", function (e) { - * console.log(e.target.getData()); - * }) - */ - this.dispatchEvent({ - type : "isocurve:compute" - }); - - // 3. Zoom sur l'emprise de la geometry - if (features[0] && features[0].getGeometry() && features[0].getGeometry().getExtent()) { - var extent = features[0].getGeometry().getExtent(); - map.getView().fit(extent, map.getSize()); - } - - // 5. Si un layer switcher est présent dans la carte, on lui affecte des informations pour cette couche - var method = (this._currentComputation === "time") ? "Isochrone" : "Isodistance"; - map.getControls().forEach( - (control) => { - if (control instanceof LayerSwitcher) { - // un layer switcher est présent dans la carte - var layerId = this._geojsonLayer.gpLayerId; - // on n'ajoute des informations que s'il n'y en a pas déjà (si le titre est le numéro par défaut) - if (control._layers[layerId].title === layerId) { - control.addLayer( - this._geojsonLayer, { - title : this.options.layerDescription.title + " (" + method + "/" + graph + ")", - description : this.options.layerDescription.description - } - ); - } - } - } - ); - } - - // ################################################################### // - // ############################# Clean ############################### // - // ################################################################### // - - /** - * this method is called by this.onShowIsoPanelClick() - * and it clears all elements (reinit). - * - * @private - */ - _clear () { - // clear inputs - this._clearIsoInputs(); - - // clear origin point (and marker) - this._originPoint.clear(); - - // remove geometry layer - this._clearGeojsonLayer(); - - // clear results - this._currentIsoResults = null; - } - - /** - * this method is called by this._clear() - * and it clears all input elements (dist and time) - * - * @private - */ - _clearIsoInputs () { - // 1. clear inputs - // clear time inputs (if exists) : - // hours - var timeHourInput = document.getElementById("GPisochronValueChronInput1-" + this._uid); - if (timeHourInput) { - timeHourInput.value = "0"; - } - // minutes - var timeMinutesInput = document.getElementById("GPisochronValueChronInput2-" + this._uid); - if (timeMinutesInput) { - timeMinutesInput.value = "0"; - } - // clear distance input (if exists) - var distInput = document.getElementById("GPisochronValueDistInput-" + this._uid); - if (distInput) { - distInput.value = "0"; - } - - // 2. reinit options to default - this._initTransport(); - this._initComputation(); - this._initDirection(); - this._initExclusions(); - - // 3. set transport mode to default - var transportdiv; - if (this._currentTransport === "Pieton") { - transportdiv = document.getElementById("GPisochronTransportPedestrian-" + this._uid); - if (transportdiv) { - transportdiv.checked = "true"; - } - } else { - transportdiv = document.getElementById("GPisochronTransportCar-" + this._uid); - if (transportdiv) { - transportdiv.checked = "true"; - } - } - - // 4. set computation mode to default (distance or time) - var computationdiv; - if (this._currentComputation.toLowerCase() === "distance") { - computationdiv = document.getElementById("GPisochronChoiceAltDist-" + this._uid); - if (computationdiv) { - computationdiv.checked = "true"; - } - if (document.getElementById("GPisochronValueDist-" + this._uid)) { - document.getElementById("GPisochronValueDist-" + this._uid).className = "GPflexInput gpf-flex"; - } - if (document.getElementById("GPisochronValueChron-" + this._uid)) { - document.getElementById("GPisochronValueChron-" + this._uid).className = "GPelementHidden gpf-hidden"; - } - } else { - computationdiv = document.getElementById("GPisochronChoiceAltChron-" + this._uid); - if (computationdiv) { - computationdiv.checked = "true"; - } - if (document.getElementById("GPisochronValueChron-" + this._uid)) { - document.getElementById("GPisochronValueChron-" + this._uid).className = "GPflexInput gpf-flex"; - } - if (document.getElementById("GPisochronValueDist-" + this._uid)) { - document.getElementById("GPisochronValueDist-" + this._uid).className = "GPelementHidden gpf-hidden"; - } - } - - // 5. set direction mode to default (arrival or departure) - var directionSelect = document.getElementById("GPisochronDirectionSelect-" + this._uid); - if (directionSelect) { - directionSelect.value = this._currentDirection; - } - if (this._currentDirection === "arrival") { - this._originPoint._buttonLabel.innerHTML = "Arrivée"; - } else { - this._originPoint._buttonLabel.innerHTML = "Départ"; - } - - // 6. set exclusions to default - var tollInput = document.getElementById("GPisoExclusionsToll-" + this._uid); - if (tollInput) { - if (this._currentExclusions.indexOf("toll") !== -1) { - tollInput.checked = false; - } else { - tollInput.checked = true; - } - } - var tunnelInput = document.getElementById("GPisoExclusionsTunnel-" + this._uid); - if (tunnelInput) { - if (this._currentExclusions.indexOf("tunnel") !== -1) { - tunnelInput.checked = false; - } else { - tunnelInput.checked = true; - } - } - var bridgeInput = document.getElementById("GPisoExclusionsBridge-" + this._uid); - if (bridgeInput) { - if (this._currentExclusions.indexOf("bridge") !== -1) { - bridgeInput.checked = false; - } else { - bridgeInput.checked = true; - } - } - } - - /** - * this method is called by this.onIsoComputationSubmit (in case of failure) - * and it clears all geometries - * - * @private - */ - _clearGeojsonLayer () { - var map = this.getMap(); - // remove layer - if (this._geojsonLayer) { - map.removeLayer(this._geojsonLayer); - this._geojsonLayer = null; - } - // remove geojson object - this._geojsonObject = null; - } - - /** - * this method is called by event 'click' on control main container - * and hide suggested Locations (unless target is an autocomplete input) - * - * @param {Object} e - event - * - * @private - */ - _hideIsoSuggestedLocations (e) { - // si on clique sur l'input de saisie du point d'origine - if (e.target && e.target.id && e.target.id.indexOf("GPlocationOrigin_") !== -1) { - - } else { - // si on clique ailleurs dans le DOM du control, on cache tous les résultats d'autocomplétion - this._originPoint._hideSuggestedLocation(); - } - } - - /** - * this method displays waiting container and sets a timeout - * - * @private - */ - _displayWaitingContainer () { - this._waitingContainer.className = "GPwaitingContainer GPwaitingContainerVisible gpf-waiting gpf-waiting--visible"; - this._waiting = true; - - // mise en place d'un timeout pour réinitialiser le panel (cacher la patience) - // si on est toujours en attente (si la requête est bloquée par exemple) - var opts = this.options.isocurveOptions; - if (opts && opts.timeOut) { - if (this._timer) { - clearTimeout(this._timer); - this._timer = null; - } - var context = this; - this._timer = setTimeout(function () { - if (context._waiting === true) { - context._hideWaitingContainer(); - } else { - if (context._timer) { - clearTimeout(context._timer); - } - } - }, 16000); - } - } - - /** - * this method hides waiting container and clears timeout - * - * @private - */ - _hideWaitingContainer () { - if (this._waiting) { - this._waitingContainer.className = "GPwaitingContainer GPwaitingContainerHidden gpf-waiting gpf-waiting--hidden"; - this._waiting = false; - var opts = this.options.isocurveOptions; - if (opts && opts.timeOut) { - clearTimeout(this._timer); - this._timer = null; - } - } - } - -}; - -// on récupère les méthodes de la classe commune MousePosition -Object.assign(Isocurve.prototype, IsocurveDOM); - -export default Isocurve; - -// Expose Isocurve as ol.control.Isocurve (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.Isocurve = Isocurve; -} - -const deepEqual = function (x, y) { - if (x === y) { - return true; - } else if ((typeof x === "object" && x != null) && (typeof y === "object" && y != null)) { - if (Object.keys(x).length !== Object.keys(y).length) { - return false; - } - - for (var prop in x) { - if (y.hasOwnProperty(prop)) { - if (!deepEqual(x[prop], y[prop])) { - return false; - } - } else { - return false; - } - } - return true; - } else { - return false; - } -}; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/IsocurveDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/IsocurveDOM.d.ts deleted file mode 100644 index 29f0c3c11..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/IsocurveDOM.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -export default IsoDOM; -declare namespace IsoDOM { - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createShowIsoPictoElement(): DOMElement; - function _createIsoPanelElement(): DOMElement; - function _createIsoPanelDivElement(): HTMLDivElement; - function _createIsoPanelHeaderElement(): DOMElement; - function _createIsoPanelFormElement(): DOMElement; - function _createIsoWaitingElement(): DOMElement; - function _createIsoPanelFooterElement(): DOMElement; - function _createIsoPanelFormTypeChoiceElement(): DOMElement; - function _createIsoPanelFormTypeChoiceChronElement(checked: boolean): DOMElement; - function _createIsoPanelFormTypeChoiceDistElement(checked: boolean): DOMElement; - function _createIsoPanelFormValueIsochronElement(checked: boolean): DOMElement; - function _createIsoPanelFormValueIsodistanceElement(checked: boolean): DOMElement; - function _createIsoPanelFormModeChoiceElement(): DOMElement; - function _createIsoPanelFormModeChoiceTransportElement(transports: any[]): DOMElement; - function _createIsoPanelFormModeChoiceDirectionElement(directions: any[]): DOMElement; - function _createShowIsoExclusionsPictoElement(): DOMElement; - function _createIsoPanelFormExclusionsElement(): DOMElement; - function _createIsoPanelFormExclusionOptionsElement(exclusions: any[]): DOMElement; - function _createIsoSubmitFormElement(): DOMElement; - function _createIsoFormResetElement(): DOMElement; -} -//# sourceMappingURL=IsocurveDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/IsocurveDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/IsocurveDOM.d.ts.map deleted file mode 100644 index 35cd7c993..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/IsocurveDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"IsocurveDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Isocurve/IsocurveDOM.js"],"names":[],"mappings":";;IAOc,qCAGT;IAO6B,mDAK7B;IAY4B,kDA8B5B;IAewB,8CASxB;IAE2B,qDAI3B;IAO8B,oDA2D9B;IAQ4B,kDAe5B;IAO0B,gDAY1B;IAO8B,oDAK9B;IAesC,4DAStC;IAS2C,iFAmD3C;IAS0C,gFAoD1C;IAYyC,+EAuEzC;IAQ4C,kFA2C5C;IAesC,4DAStC;IAS+C,sFAuF/C;IAS+C,sFA8C/C;IAWsC,4DA2BtC;IAOsC,4DAYtC;IAS4C,mFAoG5C;IAY6B,mDAQ7B;IAW4B,kDAiB5B"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/IsocurveDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/IsocurveDOM.js deleted file mode 100644 index 0fbaa5bb3..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Isocurve/IsocurveDOM.js +++ /dev/null @@ -1,886 +0,0 @@ -var IsoDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Main container (DOM) - * - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPisochron"); - container.className = "GPwidget gpf-widget gpf-widget-button"; - return container; - }, - - // ################################################################### // - // ################# Methods to display Main Panel ################### // - // ################################################################### // - - /** - * Show iso control - * see event ! - * - * @returns {DOMElement} DOM element - */ - _createShowIsoPictoElement : function () { - // contexte d'execution - var context = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowIsochronPicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto GPshowIsochronPicto gpf-btn gpf-btn-icon gpf-btn-icon-isocurve fr-btn"; - button.title = "Calculer une isochrone"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // gestionnaire d'evenement : - // on ouvre le menu de saisie du calcul d'isochrone - // L'ouverture/Fermeture permet de faire le menage - // (reinitialisation) - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowIsoPanelClick(e); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowIsoPanelClick(e); - }); - } - - return button; - }, - - // ################################################################### // - // ################## Methods to display Inputs Panel ################ // - // ################################################################### // - - /** - * Create Container Panel - * - * FIXME - * don't call this._createIsoPanelHeaderElement - * don't call this._createIsoPanelFormElement - * - * @returns {DOMElement} DOM element - */ - _createIsoPanelElement : function () { - var dialog = document.createElement("dialog"); - dialog.id = this._addUID("GPisochronPanel"); - dialog.className = "GPpanel gpf-panel fr-modal"; - - // dialog.appendChild(this._createIsoPanelHeaderElement()); - // dialog.appendChild(this._createIsoPanelFormElement()); - - return dialog; - }, - - _createIsoPanelDivElement : function () { - var div = document.createElement("div"); - div.className = "gpf-panel__body fr-modal__body"; - return div; - }, - - /** - * Create Header Panel - * - * @returns {DOMElement} DOM element - */ - _createIsoPanelHeaderElement : function () { - var self = this; - - var container = document.createElement("div"); - container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; - - var div = document.createElement("div"); - div.className = "GPpanelTitle gpf-panel__title fr-modal__title fr-m-1w"; - div.innerHTML = "Calcul d'isochrone"; - container.appendChild(div); - - // on desactive l'impl. reduction de la fenetre - // var divReduce = document.createElement("div"); - // divReduce.id = this._addUID("GPisochronPanelReduce"); - // divReduce.className = "GPpanelReduce"; - // divReduce.title = "Masquer le panneau"; - // - // if (divReduce.addEventListener) { - // divReduce.addEventListener("click", function () { - // if ( typeof self.onReduceIsoPanelClick === "function") { - // document.getElementById(self._addUID("GPshowIsochron")).checked = false; - // self.onReduceIsoPanelClick(); - // } - // }, false); - // } else if (divReduce.attachEvent) { - // divReduce.attachEvent("onclick", function () { - // if ( typeof self.onReduceIsoPanelClick === "function") { - // document.getElementById(self._addUID("GPshowIsochron")).checked = false; - // self.onReduceIsoPanelClick(); - // } - // }); - // } - // container.appendChild(divReduce); - - var divClose = document.createElement("button"); - divClose.id = this._addUID("GPisochronPanelClose"); - divClose.className = "GPpanelClose GPisochronPanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--secondary fr-m-1w"; - divClose.title = "Fermer le panneau"; - - // Link panel close / visibility checkbox - if (divClose.addEventListener) { - divClose.addEventListener("click", function () { - document.getElementById(self._addUID("GPshowIsochronPicto")).click(); - }, false); - } else if (divClose.attachEvent) { - divClose.attachEvent("onclick", function () { - document.getElementById(self._addUID("GPshowIsochronPicto")).click(); - }); - } - - var span = document.createElement("span"); - span.className = "GPelementHidden gpf-visible"; // afficher en dsfr - span.innerText = "Fermer"; - - divClose.appendChild(span); - - container.appendChild(divClose); - - return container; - }, - - /** - * Create Form - * see evenement ! - * - * @returns {DOMElement} DOM element - */ - _createIsoPanelFormElement : function () { - // contexte d'execution - var self = this; - - var form = document.createElement("form"); - form.id = this._addUID("GPisochronForm"); - form.className = "GPform gpf-panel__content fr-modal__content"; - - form.addEventListener("submit", function (e) { - e.preventDefault(); - self.onIsoComputationSubmit(e); - return false; - }); - - return form; - }, - - /** - * Create Waiting Panel - * - * @returns {DOMElement} DOM element - */ - _createIsoWaitingElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPisochronCalcWaitingContainer"); - div.className = "GPwaitingContainer GPwaitingContainerHidden gpf-waiting gpf-waiting--hidden"; - - var p = document.createElement("p"); - p.className = "GPwaitingContainerInfo gpf-waiting_info"; - p.innerHTML = "Recherche en cours..."; - - div.appendChild(p); - - return div; - }, - - /** - * Create Footer Panel - * - * @returns {DOMElement} DOM element - */ - _createIsoPanelFooterElement : function () { - var container = document.createElement("div"); - container.className = "GPpanelFooter gpf-panel__footer fr-modal__footer"; - - return container; - }, - - // ################################################################### // - // ############# Methods to the type choice into form ################ // - // ################################################################### // - - /** - * Create Container to type choice - * - * FIXME - * don't call this._createIsoPanelFormTypeChoiceChronElement - * don't call this._createIsoPanelFormTypeChoiceDistElement - * - * @returns {DOMElement} DOM element - */ - _createIsoPanelFormTypeChoiceElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPisochronChoice"); - div.className = "fr-mt-4w"; - - // div.appendChild(this._createIsoPanelFormTypeChoiceChronElement()); - // div.appendChild(this._createIsoPanelFormTypeChoiceDistElement()); - - return div; - }, - - /** - * Create Type choice Chron - * see event ! - * FIXME event not useful - * @param {Boolean} checked - checked - * @returns {DOMElement} DOM element - */ - _createIsoPanelFormTypeChoiceChronElement : function (checked) { - var self = this; - - var div = document.createElement("div"); - div.className = "GPisochronChoiceAlt gpf-flex gpf-flex-isocurve gpf-radio-group fr-radio-group"; - - var input = document.createElement("input"); - input.id = this._addUID("GPisochronChoiceAltChron"); - input.name = "GPisochronChoiceMode"; - input.type = "radio"; - input.checked = !!(checked); - if (input.addEventListener) { - input.addEventListener("change", function (e) { - document.getElementById(self._addUID("GPisochronValueChron")).className = "GPflexInput gpf-flex fr-mt-1w"; - document.getElementById(self._addUID("GPisochronValueDist")).className = "GPelementHidden gpf-hidden"; - self.onIsoTypeChoiceChange(e); - }, false); - } else if (input.attachEvent) { - input.attachEvent("onchange", function () { - document.getElementById(self._addUID("GPisochronValueChron")).className = "GPflexInput gpf-flex fr-mt-1w"; - document.getElementById(self._addUID("GPisochronValueDist")).className = "GPelementHidden gpf-hidden"; - self.onIsoTypeChoiceChange(); - }); - } - // info: Internet explorer support - input.value = "isochron"; - div.appendChild(input); - - var label = document.createElement("label"); - label.className = "GPisochronChoiceAltImg gpf-label fr-label"; - label.htmlFor = this._addUID("GPisochronChoiceAltChron"); - label.innerHTML = "isochrone"; - label.title = "isochrone"; - div.appendChild(label); - - var span = document.createElement("span"); - span.id = this._addUID("GPisochronChoiceAltChronTxt"); - span.className = "gpf-hidden"; - span.innerHTML = "isochrone"; - if (span.addEventListener) { - span.addEventListener("click", function () { - document.getElementById(self._addUID("GPisochronChoiceAltChron")).click(); - }, false); - } else if (span.attachEvent) { - span.attachEvent("onclick", function () { - document.getElementById(self._addUID("GPisochronChoiceAltChron")).click(); - }); - } - div.appendChild(span); - - return div; - }, - - /** - * Create Type choice Dist - * see event ! - * FIXME event not useful - * @param {Boolean} checked - checked - * @returns {DOMElement} DOM element - */ - _createIsoPanelFormTypeChoiceDistElement : function (checked) { - var self = this; - - var div = document.createElement("div"); - div.className = "GPisochronChoiceAlt gpf-flex gpf-flex-isocurve gpf-radio-group fr-radio-group"; - - var input = document.createElement("input"); - input.id = this._addUID("GPisochronChoiceAltDist"); - input.name = "GPisochronChoiceMode"; - input.type = "radio"; - input.checked = !!(checked); - if (input.addEventListener) { - input.addEventListener("change", function (e) { - document.getElementById(self._addUID("GPisochronValueDist")).className = "GPflexInput gpf-flex fr-mt-1w"; - document.getElementById(self._addUID("GPisochronValueChron")).className = "GPelementHidden gpf-hidden"; - self.onIsoTypeChoiceChange(e); - }, false); - } else if (input.attachEvent) { - input.attachEvent("onchange", function () { - document.getElementById(self._addUID("GPisochronValueDist")).className = "GPflexInput gpf-flex fr-mt-1w"; - document.getElementById(self._addUID("GPisochronValueChron")).className = "GPelementHidden gpf-hidden"; - self.onIsoTypeChoiceChange(); - }); - } - // info: Internet explorer support - input.value = "isodistance"; - div.appendChild(input); - - var label = document.createElement("label"); - label.className = "GPisochronChoiceAltImg gpf-label fr-label"; - label.htmlFor = this._addUID("GPisochronChoiceAltDist"); - label.innerHTML = "isodistance"; - label.title = "isodistance"; - - div.appendChild(label); - - var span = document.createElement("span"); - span.id = this._addUID("GPisochronChoiceAltDistTxt"); - span.className = "gpf-hidden"; - span.innerHTML = "isodistance"; - if (span.addEventListener) { - span.addEventListener("click", function () { - document.getElementById(self._addUID("GPisochronChoiceAltDist")).click(); - }, false); - } else if (span.attachEvent) { - span.attachEvent("onclick", function () { - document.getElementById(self._addUID("GPisochronChoiceAltDist")).click(); - }); - } - div.appendChild(span); - - return div; - }, - - // ################################################################### // - // ############### Methods to the value iso into form ################ // - // ################################################################### // - - /** - * Create isochron inputs values - * see event ! - * @param {Boolean} checked - checked - * @returns {DOMElement} DOM element - */ - _createIsoPanelFormValueIsochronElement : function (checked) { - // contexte - var context = this; - - var div = document.createElement("div"); - div.id = this._addUID("GPisochronValueChron"); - div.className = (checked) ? "GPflexInput gpf-flex fr-mt-1w" : "GPelementHidden gpf-hidden"; - - var label = document.createElement("label"); - label.id = this._addUID("GPisochronValueChronLabel"); - label.className = "gpf-label fr-label"; - label.htmlFor = this._addUID("GPisochronValueChronInput"); - label.innerHTML = "Temps"; - div.appendChild(label); - - var input1 = document.createElement("input"); - input1.id = this._addUID("GPisochronValueChronInput1"); - input1.className = "gpf-input fr-input"; - input1.min = "0"; - input1.step = "1"; - input1.value = "0"; - input1.type = "number"; - if (input1.addEventListener) { - input1.addEventListener("change", function (e) { - if (typeof context.onIsoValueChronTimeMinuteChange === "function") { - context.onIsoValueChronTimeHourChange(e); - } - }); - } else if (input1.attachEvent) { - input1.attachEvent("onchange", function (e) { - if (typeof context.onIsoValueChronTimeMinuteChange === "function") { - context.onIsoValueChronTimeHourChange(e); - } - }); - } - div.appendChild(input1); - - var label1 = document.createElement("label"); - label1.innerHTML = "h"; - label1.className = "gpf-label fr-label"; - div.appendChild(label1); - - var input2 = document.createElement("input"); - input2.id = this._addUID("GPisochronValueChronInput2"); - input2.className = "gpf-input fr-input"; - input2.min = "0"; - input2.max = "59"; - input2.step = "1"; - input2.value = "0"; - input2.type = "number"; - if (input2.addEventListener) { - input2.addEventListener("change", function (e) { - if (typeof context.onIsoValueChronTimeMinuteChange === "function") { - context.onIsoValueChronTimeMinuteChange(e); - } - }); - } else if (input2.attachEvent) { - input2.attachEvent("onchange", function (e) { - if (typeof context.onIsoValueChronTimeMinuteChange === "function") { - context.onIsoValueChronTimeMinuteChange(e); - } - }); - } - div.appendChild(input2); - - var label2 = document.createElement("label"); - label2.innerHTML = "min"; - label2.className = "gpf-label fr-label"; - div.appendChild(label2); - - return div; - }, - - /** - * Create isodistance inputs values - * see event ! - * @param {Boolean} checked - checked - * @returns {DOMElement} DOM element - */ - _createIsoPanelFormValueIsodistanceElement : function (checked) { - // contexte - var context = this; - - var div = document.createElement("div"); - div.id = this._addUID("GPisochronValueDist"); - div.className = (checked) ? "GPflexInput gpf-flex fr-mt-1w" : "GPelementHidden gpf-hidden"; - - var label = document.createElement("label"); - label.id = this._addUID("GPisochronValueDistLabel"); - label.className = "gpf-label fr-label fr-mr-1w"; - label.htmlFor = this._addUID("GPisochronValueDistInput"); - label.innerHTML = "Distance"; - div.appendChild(label); - - var input1 = document.createElement("input"); - input1.id = this._addUID("GPisochronValueDistInput"); - input1.className = "gpf-input fr-input fr-ml-1w"; - input1.min = "0"; - input1.step = "any"; - input1.value = "0"; - input1.type = "number"; - if (input1.addEventListener) { - input1.addEventListener("change", function (e) { - if (typeof context.onIsoValueDistChange === "function") { - context.onIsoValueDistChange(e); - } - }); - } else if (input1.attachEvent) { - input1.attachEvent("onchange", function (e) { - if (typeof context.onIsoValueDistChange === "function") { - context.onIsoValueDistChange(e); - } - }); - } - div.appendChild(input1); - - var label1 = document.createElement("label"); - label1.innerHTML = "km"; - label.className = "gpf-label fr-label"; - div.appendChild(label1); - - return div; - }, - - // ################################################################### // - // ############ Methods to the mode choice into form ################# // - // ################################################################### // - - /** - * Create Container to Mode choice - * - * FIXME - * don't call this._createIsoPanelFormModeChoiceTransportElement - * don't call this._createIsoPanelFormModeChoiceDirectionElement - * - * @returns {DOMElement} DOM element - */ - _createIsoPanelFormModeChoiceElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPisochronModeChoice"); - div.className = "fr-my-4w"; - - // div.appendChild(this._createIsoPanelFormModeChoiceTransportElement()); - // div.appendChild(this._createIsoPanelFormModeChoiceDirectionElement()); - - return div; - }, - - /** - * Create Mode choice transport - * see event ! - * FIXME event not useful - * @param {Array} transports - transports in a list - * @returns {DOMElement} DOM element - */ - _createIsoPanelFormModeChoiceTransportElement : function (transports) { - // contexte d'execution - var context = this; - - var divContainer = document.createElement("div"); - divContainer.id = this._addUID("GPisochronTransportChoice"); - - var label = document.createElement("label"); - label.className = "GPisochronModeLabel gpf-label fr-label"; - label.innerHTML = "Mode de transport"; - divContainer.appendChild(label); - - /* jshint -W083 */ - for (var i = 0; i < transports.length; i++) { - var transport = transports[i]; - - var div = document.createElement("div"); - div.className = "GPisochronTransportChoice gpf-flex gpf-radio-group fr-radio-group fr-m-1w"; - - if (transport === "Voiture") { - var inputCar = document.createElement("input"); - inputCar.id = this._addUID("GPisochronTransportCar"); - inputCar.type = "radio"; - inputCar.name = "GPisochronTransport"; - if (i === 0) { - inputCar.checked = true; - } - // gestionnaire d'evenement : - // on stocke le mode de transport, - // utilisation pour la requête sur le service de calcul d'itiniraire - if (inputCar.addEventListener) { - inputCar.addEventListener("change", function (e) { - context.onIsoModeTransportChange(e); - }); - } else if (inputCar.attachEvent) { - inputCar.attachEvent("onchange", function (e) { - context.onIsoModeTransportChange(e); - }); - } - // info : internet explorer support - inputCar.value = "Voiture"; - div.appendChild(inputCar); - - var labelCar = document.createElement("label"); - labelCar.className = "GPisochronTransportImg gpf-label fr-label"; - labelCar.htmlFor = this._addUID("GPisochronTransportCar"); - labelCar.title = "Voiture"; - labelCar.innerHTML = "Voiture"; - div.appendChild(labelCar); - } - - if (transport === "Pieton") { - var inputPedestrian = document.createElement("input"); - inputPedestrian.id = this._addUID("GPisochronTransportPedestrian"); - inputPedestrian.type = "radio"; - inputPedestrian.name = "GPisochronTransport"; - if (i === 0) { - inputPedestrian.checked = true; - } - // gestionnaire d'evenement : - // on stocke le mode de transport, - // utilisation pour la requête sur le service de calcul d'itiniraire - if (inputPedestrian.addEventListener) { - inputPedestrian.addEventListener("change", function (e) { - context.onIsoModeTransportChange(e); - }); - } else if (inputPedestrian.attachEvent) { - inputPedestrian.attachEvent("onchange", function (e) { - context.onIsoModeTransportChange(e); - }); - } - // info : internet explorer support - inputPedestrian.value = "Pieton"; - div.appendChild(inputPedestrian); - - var labelPedestrian = document.createElement("label"); - labelPedestrian.className = "GPisochronTransportImg gpf-label fr-label"; - labelPedestrian.htmlFor = this._addUID("GPisochronTransportPedestrian"); - labelPedestrian.title = "Piéton"; - labelPedestrian.innerHTML = "Piéton"; - div.appendChild(labelPedestrian); - } - - divContainer.appendChild(div); - } - - return divContainer; - }, - - /** - * Create Mode choice direction - * see event! - * - * @param {Array} directions - directions to display in list ("Departure", "Arrival"). First element will be selected by default - * @returns {DOMElement} DOM element - */ - _createIsoPanelFormModeChoiceDirectionElement : function (directions) { - // contexte d'execution - var self = this; - - var div = document.createElement("div"); - div.id = this._addUID("GPisochronDirectionChoice"); - - var label = document.createElement("label"); - label.className = "GPisochronModeLabel gpf-label fr-label"; - label.innerHTML = "Sens de parcours"; - div.appendChild(label); - - var select = document.createElement("select"); - select.id = this._addUID("GPisochronDirectionSelect"); - select.className = "GPselect gpf-select fr-select"; - // gestionnaire d'evenement : - // on stocke la valeur du mode de calcul, - // utilisation pour la requête sur le service de calcul d'iso - select.addEventListener("change", function (e) { - self.onIsoModeDirectionChange(e); - }); - - for (var i = 0; i < directions.length; i++) { - var direction = directions[i]; - if (direction.toLowerCase() === "departure") { - var departureOption = document.createElement("option"); - if (i === 0) { - departureOption.selected = "selected"; - } - departureOption.value = "departure"; - departureOption.text = "Départ"; - select.appendChild(departureOption); - } - if (direction.toLowerCase() === "arrival") { - var arrivalOption = document.createElement("option"); - if (i === 0) { - arrivalOption.selected = "selected"; - } - arrivalOption.value = "arrival"; - arrivalOption.text = "Arrivée"; - select.appendChild(arrivalOption); - } - } - div.appendChild(select); - - return div; - }, - - // ################################################################### // - // ################# Methods to the choice exclusions ################ // - // ################################################################### // - - /** - * Label to Exclusions Options - * - * @returns {DOMElement} DOM element - */ - _createShowIsoExclusionsPictoElement : function () { - var self = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowIsoExclusionsPicto"); - button.className = "GPshowAdvancedToolPicto GPshowMoreOptionsImage GPshowMoreOptions GPshowIsoExclusionsPicto gpf-btn fr-btn--sm fr-btn--secondary fr-icon-arrow-down-fill"; - button.title = "Exclusions"; - // button.style.top = "240px"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // Close all results and panels when minimizing the widget - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onShowIsoSettingsClick(e); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onShowIsoSettingsClick(e); - }); - } - - return button; - }, - - /** - * Create Container to Exclusions - * - * @returns {DOMElement} DOM element - */ - _createIsoPanelFormExclusionsElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPisoExclusions"); - - var label = document.createElement("label"); - label.className = "GPisoExclusionsLabel gpf-label fr-label"; - label.innerHTML = "Passages autorisés"; - div.appendChild(label); - - // div.appendChild(this._createIsoPanelFormExclusionOptionsElement()); - - return div; - }, - - /** - * Create Exclusions Options - * see event ! - * FIXME event not useful - * @param {Array} exclusions - exclusions to display in list - * @returns {DOMElement} DOM element - */ - _createIsoPanelFormExclusionOptionsElement : function (exclusions) { - // contexte d'execution - var context = this; - - var div = document.createElement("div"); - div.className = "GPisoExclusionsOptions gpf-flex fr-checkbox-group fr-m-1w"; - - /* jshint -W083 */ - for (var value in exclusions) { - if (exclusions.hasOwnProperty(value)) { - var status = exclusions[value]; - switch (value) { - case "toll": - var inputToll = document.createElement("input"); - inputToll.id = this._addUID("GPisoExclusionsToll"); - inputToll.type = "checkbox"; - inputToll.checked = !status; - // gestionnaire d'evenement : - // on stocke l'exclusion, - // utilisation pour la requête sur le service de calcul d'itiniraire - if (inputToll.addEventListener) { - inputToll.addEventListener("change", function (e) { - context.onIsoExclusionsChange(e); - }); - } else if (inputToll.attachEvent) { - inputToll.attachEvent("onchange", function (e) { - context.onIsoExclusionsChange(e); - }); - } - // info : internet explorer support - inputToll.value = "Toll"; - div.appendChild(inputToll); - - var labelToll = document.createElement("label"); - labelToll.className = "GPisoExclusionsOption"; - labelToll.htmlFor = this._addUID("GPisoExclusionsToll"); - labelToll.innerHTML = "Péages"; - div.appendChild(labelToll); - break; - - case "tunnel": - var inputTunnel = document.createElement("input"); - inputTunnel.id = this._addUID("GPisoExclusionsTunnel"); - inputTunnel.type = "checkbox"; - inputTunnel.checked = !status; - // gestionnaire d'evenement : - // on stocke l'exclusion, - // utilisation pour la requête sur le service de calcul d'itiniraire - if (inputTunnel.addEventListener) { - inputTunnel.addEventListener("change", function (e) { - context.onIsoExclusionsChange(e); - }); - } else if (inputTunnel.attachEvent) { - inputTunnel.attachEvent("onchange", function (e) { - context.onIsoExclusionsChange(e); - }); - } - // info : internet explorer support - inputTunnel.value = "Tunnel"; - div.appendChild(inputTunnel); - - var labelTunnel = document.createElement("label"); - labelTunnel.className = "GPisoExclusionsOption"; - labelTunnel.htmlFor = this._addUID("GPisoExclusionsTunnel"); - labelTunnel.innerHTML = "Tunnels"; - div.appendChild(labelTunnel); - break; - - case "bridge": - var inputBridge = document.createElement("input"); - inputBridge.id = this._addUID("GPisoExclusionsBridge"); - inputBridge.type = "checkbox"; - inputBridge.checked = !status; - // gestionnaire d'evenement : - // on stocke l'exclusion, - // utilisation pour la requête sur le service de calcul d'itiniraire - if (inputBridge.addEventListener) { - inputBridge.addEventListener("change", function (e) { - context.onIsoExclusionsChange(e); - }); - } else if (inputBridge.attachEvent) { - inputBridge.attachEvent("onchange", function (e) { - context.onIsoExclusionsChange(e); - }); - } - // info : internet explorer support - inputBridge.value = "Bridge"; - div.appendChild(inputBridge); - - var labelBridge = document.createElement("label"); - labelBridge.className = "GPisoExclusionsOption"; - labelBridge.htmlFor = this._addUID("GPisoExclusionsBridge"); - labelBridge.innerHTML = "Ponts"; - div.appendChild(labelBridge); - break; - } - } - } - - return div; - }, - - // ################################################################### // - // ############################### Submit Form ####################### // - // ################################################################### // - - - /** - * Create Submit Form Element - * - * @returns {DOMElement} DOM element - */ - _createIsoSubmitFormElement : function () { - var input = document.createElement("input"); - input.id = this._addUID("GPisochronSubmit"); - input.className = "GPsubmit gpf-btn fr-btn fr-btn--secondary"; - input.type = "submit"; - input.value = "Calculer"; - - return input; - }, - - // ################################################################### // - // ############################### Reset picto ####################### // - // ################################################################### // - - /** - * Create Reset Picto Element - * - * @returns {DOMElement} DOM element - */ - _createIsoFormResetElement : function () { - var self = this; - - var buttonReset = document.createElement("button"); - buttonReset.id = this._addUID("GPisochronReset"); - buttonReset.className = "GPresetPicto GPisochronReset gpf-btn gpf-btn-icon-reset gpf-btn-icon-isocurve-reset fr-btn fr-btn--secondary"; - buttonReset.title = "Réinitialiser les paramètres"; - buttonReset.setAttribute("tabindex", "0"); - buttonReset.setAttribute("aria-pressed", false); - - buttonReset.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onIsoResetClick(e); - }); - - return buttonReset; - } -}; - -export default IsoDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImport.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImport.d.ts deleted file mode 100644 index 2dacada69..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImport.d.ts +++ /dev/null @@ -1,84 +0,0 @@ -export default LayerImport; -/** - * @classdesc - * - * LayerImport Control. Allows users to add geographical data in standards formats from their own sources to the map. - * - * @constructor - * @alias ol.control.LayerImport - * @extends {ol.control.Control} - * @type {ol.control.LayerImport} - * @param {Object} options - options for function call. - * @param {Boolean} [options.collapsed = true] - Specify if LayerImport control should be collapsed at startup. Default is true. - * @param {Boolean} [options.draggable = false] - Specify if widget is draggable - * @param {Array} [options.layerTypes = ["KML", "GPX", "GeoJSON", "WMS", "WMTS", "MAPBOX"]] - data types that could be imported : "KML", "GPX", "GeoJSON", "WMS", "WMTS" and "MAPBOX". Values will be displayed in the same order in widget list. - * @param {Object} [options.webServicesOptions = {}] - Options to import WMS or WMTS layers - * @param {String} [options.webServicesOptions.proxyUrl] - Proxy URL to avoid cross-domain problems. Mandatory to import WMS and WMTS layer. - * @param {Array.} [options.webServicesOptions.noProxyDomains] - Proxy will not be used for this list of domain names. Only use if you know what you're doing. - * @param {Object} [options.vectorStyleOptions] - Options for imported vector layer styling (KML, GPX, GeoJSON) - * @param {Object} [options.vectorStyleOptions.KML] - Options for KML layer styling - * @param {Boolean} [options.vectorStyleOptions.KML.extractStyles = true] - Extract styles from the KML. Default is true. - * @param {Boolean} [options.vectorStyleOptions.KML.showPointNames = true] - Show names as labels for KML placemarks which contain points. Default is true. - * @param {Object} [options.vectorStyleOptions.KML.defaultStyle] - default style to be applied to KML imports in case no style is defined. defaultStyle is an {@link http://openlayers.org/en/latest/apidoc/ol.style.Style.html ol.style.Style} object. - * @param {Object} [options.vectorStyleOptions.GPX] - Options for GPX layer styling - * @param {Object} [options.vectorStyleOptions.GPX.defaultStyle] - default style to be applied to GPX imports in case no style is defined. defaultStyle is an {@link http://openlayers.org/en/latest/apidoc/ol.style.Style.html ol.style.Style} object. - * @param {Object} [options.vectorStyleOptions.GeoJSON] - Options for GeoJSON layer styling - * @param {Object} [options.vectorStyleOptions.GeoJSON.defaultStyle] - default style to be applied to GeoJSON imports in case no style is defined. defaultStyle is an {@link http://openlayers.org/en/latest/apidoc/ol.style.Style.html ol.style.Style} object. - * @param {Object} [options.vectorStyleOptions.MapBox] - Options for MapBox layer styling - * @param {Object} [options.vectorStyleOptions.MapBox.defaultStyle] - default style to be applied to MapBox imports in case no style is defined. defaultStyle is an {@link http://openlayers.org/en/latest/apidoc/ol.style.Style.html ol.style.Style} object. - * @param {Object} [options.vectorStyleOptions.MapBox.editor] - options for tools editor - * @param {Boolean} [options.vectorStyleOptions.MapBox.display = true] - display tools editor - * @example - * var LayerImport = new ol.control.LayerImport({ - * "collapsed" : false, - * "draggable" : true, - * "layerTypes" : ["KML", "GPX"], - * "webServicesOptions" : { - * "proxyUrl" : "http://localhost/proxy/php/proxy.php?url=", - * "noProxyDomains" : [] - * }, - * "vectorStyleOptions" : { - * "KML" : { - * extractStyles : true, - * defaultStyle : new ol.style.Style({ - * image : new ol.style.Icon({ - * src : "data:image/png;base64....", - * size : [51, 38], - * }), - * stroke : new ol.style.Stroke({ - * color : "#ffffff", - * width : 7 - * }), - * fill : new ol.style.Fill({ - * color : "rgba(255, 183, 152, 0.2)" - * }), - * text : new ol.style.Text({ - * font : "16px Sans", - * textAlign : "left", - * fill : new ol.style.Fill({ - * color : "rgba(255, 255, 255, 1)" - * }), - * stroke : new ol.style.Stroke({ - * color : "rgba(0, 0, 0, 1)", - * width : 2 - * }) - * }) - * }) - * }, - * "GPX" : { - * defaultStyle : new ol.style.Style({ - * image : new ol.style.Icon({ - * src : "path/to/my/icon.png", - * size : [51, 38], - * }), - * stroke : new ol.style.Stroke({ - * color : "#ffffff", - * width : 7 - * }) - * }) - * } - * } - * }); - */ -declare var LayerImport: ol.control.LayerImport; -//# sourceMappingURL=LayerImport.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImport.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImport.d.ts.map deleted file mode 100644 index 344680b3f..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImport.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"LayerImport.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/LayerImport/LayerImport.js"],"names":[],"mappings":";AA8DA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AACH,gDAu0FE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImport.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImport.js deleted file mode 100644 index 164f8bae7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImport.js +++ /dev/null @@ -1,3041 +0,0 @@ -// import CSS -import "../../CSS/Controls/LayerImport/GPFlayerImport.css"; -// import "../../CSS/Controls/LayerImport/GPFlayerImportStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -import { unByKey as olObservableUnByKey } from "ol/Observable"; -import Collection from "ol/Collection"; -import Feature from "ol/Feature"; -import WMTSTileGrid from "ol/tilegrid/WMTS"; -// import { createXYZ as olCreateXYZTileGrid } from "ol/tilegrid"; // FIXME olCreateXYZTileGrid !? -import { - transform as olTransformProj, - get as olGetProj, - transformExtent as olTransformExtentProj -} from "ol/proj"; -import MVT from "ol/format/MVT"; -import WMSCapabilities from "ol/format/WMSCapabilities"; -import WMTSCapabilities from "ol/format/WMTSCapabilities"; -import VectorTileLayer from "ol/layer/VectorTile"; -import VectorLayer from "ol/layer/Vector"; -import TileLayer from "ol/layer/Tile"; -import VectorTileSource from "ol/source/VectorTile"; -import VectorSource from "ol/source/Vector"; -import TileWMSSource from "ol/source/TileWMS"; -import WMTSSource from "ol/source/WMTS"; -import TileJSONSource from "ol/source/TileJSON"; -import { - Fill, - Icon, - Stroke, - Style, - Text -} from "ol/style"; -// import olms : module ES6 -import { applyStyle as applyStyleOlms } from "ol-mapbox-style"; -// import olms : bundle -// import olms from "ol-mapbox-style"; -// import geoportal library access -import Gp from "geoportal-access-lib"; -// import local -import Editor from "../Editor/Editor"; -import Markers from "../Utils/Markers"; -import Draggable from "../../Utils/Draggable"; -import Interactions from "../Utils/Interactions"; -import Utils from "../../Utils/Helper"; -import Logger from "../../Utils/LoggerByDefault"; -import SelectorID from "../../Utils/SelectorID"; -import ProxyUtils from "../../Utils/ProxyUtils"; -// DOM -import LayerImportDOM from "./LayerImportDOM"; -// import local with ol dependencies -import KMLExtended from "../../Formats/KML"; -import GeoJSONExtended from "../../Formats/GeoJSON"; -import GPXExtended from "../../Formats/GPX"; -import LayerSwitcher from "../LayerSwitcher/LayerSwitcher"; -import Route from "../Route/Route"; -import Isocurve from "../Isocurve/Isocurve"; -import ElevationPath from "../ElevationPath/ElevationPath"; - -var logger = Logger.getLogger("layerimport"); - -/** - * @classdesc - * - * LayerImport Control. Allows users to add geographical data in standards formats from their own sources to the map. - * - * @constructor - * @alias ol.control.LayerImport - * @extends {ol.control.Control} - * @type {ol.control.LayerImport} - * @param {Object} options - options for function call. - * @param {Boolean} [options.collapsed = true] - Specify if LayerImport control should be collapsed at startup. Default is true. - * @param {Boolean} [options.draggable = false] - Specify if widget is draggable - * @param {Array} [options.layerTypes = ["KML", "GPX", "GeoJSON", "WMS", "WMTS", "MAPBOX"]] - data types that could be imported : "KML", "GPX", "GeoJSON", "WMS", "WMTS" and "MAPBOX". Values will be displayed in the same order in widget list. - * @param {Object} [options.webServicesOptions = {}] - Options to import WMS or WMTS layers - * @param {String} [options.webServicesOptions.proxyUrl] - Proxy URL to avoid cross-domain problems. Mandatory to import WMS and WMTS layer. - * @param {Array.} [options.webServicesOptions.noProxyDomains] - Proxy will not be used for this list of domain names. Only use if you know what you're doing. - * @param {Object} [options.vectorStyleOptions] - Options for imported vector layer styling (KML, GPX, GeoJSON) - * @param {Object} [options.vectorStyleOptions.KML] - Options for KML layer styling - * @param {Boolean} [options.vectorStyleOptions.KML.extractStyles = true] - Extract styles from the KML. Default is true. - * @param {Boolean} [options.vectorStyleOptions.KML.showPointNames = true] - Show names as labels for KML placemarks which contain points. Default is true. - * @param {Object} [options.vectorStyleOptions.KML.defaultStyle] - default style to be applied to KML imports in case no style is defined. defaultStyle is an {@link http://openlayers.org/en/latest/apidoc/ol.style.Style.html ol.style.Style} object. - * @param {Object} [options.vectorStyleOptions.GPX] - Options for GPX layer styling - * @param {Object} [options.vectorStyleOptions.GPX.defaultStyle] - default style to be applied to GPX imports in case no style is defined. defaultStyle is an {@link http://openlayers.org/en/latest/apidoc/ol.style.Style.html ol.style.Style} object. - * @param {Object} [options.vectorStyleOptions.GeoJSON] - Options for GeoJSON layer styling - * @param {Object} [options.vectorStyleOptions.GeoJSON.defaultStyle] - default style to be applied to GeoJSON imports in case no style is defined. defaultStyle is an {@link http://openlayers.org/en/latest/apidoc/ol.style.Style.html ol.style.Style} object. - * @param {Object} [options.vectorStyleOptions.MapBox] - Options for MapBox layer styling - * @param {Object} [options.vectorStyleOptions.MapBox.defaultStyle] - default style to be applied to MapBox imports in case no style is defined. defaultStyle is an {@link http://openlayers.org/en/latest/apidoc/ol.style.Style.html ol.style.Style} object. - * @param {Object} [options.vectorStyleOptions.MapBox.editor] - options for tools editor - * @param {Boolean} [options.vectorStyleOptions.MapBox.display = true] - display tools editor - * @example - * var LayerImport = new ol.control.LayerImport({ - * "collapsed" : false, - * "draggable" : true, - * "layerTypes" : ["KML", "GPX"], - * "webServicesOptions" : { - * "proxyUrl" : "http://localhost/proxy/php/proxy.php?url=", - * "noProxyDomains" : [] - * }, - * "vectorStyleOptions" : { - * "KML" : { - * extractStyles : true, - * defaultStyle : new ol.style.Style({ - * image : new ol.style.Icon({ - * src : "data:image/png;base64....", - * size : [51, 38], - * }), - * stroke : new ol.style.Stroke({ - * color : "#ffffff", - * width : 7 - * }), - * fill : new ol.style.Fill({ - * color : "rgba(255, 183, 152, 0.2)" - * }), - * text : new ol.style.Text({ - * font : "16px Sans", - * textAlign : "left", - * fill : new ol.style.Fill({ - * color : "rgba(255, 255, 255, 1)" - * }), - * stroke : new ol.style.Stroke({ - * color : "rgba(0, 0, 0, 1)", - * width : 2 - * }) - * }) - * }) - * }, - * "GPX" : { - * defaultStyle : new ol.style.Style({ - * image : new ol.style.Icon({ - * src : "path/to/my/icon.png", - * size : [51, 38], - * }), - * stroke : new ol.style.Stroke({ - * color : "#ffffff", - * width : 7 - * }) - * }) - * } - * } - * }); - */ -var LayerImport = class LayerImport extends Control { - - /** - * See {@link ol.control.LayerImport} - * @module LayerImport - * @alias module:~Controls/LayerImport - * @param {*} options - options - * @example - * import LayerImport from "src/OpenLayers/Controls/LayerImport" - */ - constructor (options) { - options = options || {}; - - // call ol.control.Control constructor - super({ - element : options.element, - target : options.target, - render : options.render - }); - - if (!(this instanceof LayerImport)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this._initialize(options); - - // init control DOM container - this._container = this._initContainer(options); - - // ajout du container - (this.element) ? this.element.appendChild(this._container) : this.element = this._container; - - return this; - }; - - /** - * Default styles applyied to KML, GPX and GeoJSON features. - * - * @private - */ - static DefaultStyles = { - image : new Icon({ - src : Markers["lightOrange"], - anchor : [25.5, 38], - anchorOrigin : "top-left", - anchorXUnits : "pixels", - anchorYUnits : "pixels" - }), - stroke : new Stroke({ - color : "rgba(0,42,80,0.8)", - width : 4 - }), - fill : new Fill({ - color : "rgba(0, 183, 152, 0.5)" - }), - text : new Text({ - font : "16px Sans", - textAlign : "left", - fill : new Fill({ - color : "rgba(255, 255, 255, 1)" - }), - stroke : new Stroke({ - color : "rgba(0, 0, 0, 1)", - width : 2 - }) - }) - }; - - // ################################################################### // - // ############## public methods (getters, setters) ################## // - // ################################################################### // - - /** - * Overwrite OpenLayers setMap method - * - * @param {ol.Map} map - Map. - */ - setMap (map) { - // ajout de la patience pour le chargement des tuiles - if (map) { - // Animation au centre de la carte ? - // var center = this._loadingContainer = this._createLoadingElement(); - // map.getViewport().appendChild(center); - - var self = this; - map.getLayers().on( - "remove", - function (e) { - // import de type layerimport:MapBox ? - if (e.element.gpResultLayerId === "layerimport:MAPBOX") { - // layer ayant un editor ID associé ? - if (e.element.gpEditorId) { - // le panneau des résultats existe t il ? - if (self._mapBoxPanel && self._importPanel) { - self.cleanMapBoxResults(e.element.gpEditorId); - self._mapBoxPanel.style.display = "none"; - self._importPanel.style.display = ""; - } - } - } - }, - self - ); - - // mode "draggable" - if (this.draggable) { - Draggable.dragElement( - this._importPanel, - this._importPanelHeader, - this.options.position ? null : map.getTargetElement() - ); - - // panneau draggable pour les resultats ? - Draggable.dragElement( - this._getCapPanel, - this._getCapPanelHeader, - map.getTargetElement() - - ); - Draggable.dragElement( - this._mapBoxPanel, - this._mapBoxPanelHeader, - map.getTargetElement() - ); - } - // mode "collapsed" - if (!this.collapsed) { - this._showImportButton.setAttribute("aria-pressed", true); - } - } - - // on appelle la méthode setMap originale d'OpenLayers - super.setMap(map); - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - } - - /** - * Returns true if widget is collapsed (minimized), false otherwise - * - * @returns {Boolean} collapsed - true if widget is collapsed - */ - getCollapsed () { - return this.collapsed; - } - - /** - * Collapse or display widget main container - * - * @param {Boolean} collapsed - True to collapse widget, False to display it - */ - setCollapsed (collapsed) { - if (collapsed === undefined) { - logger.error("[ERROR] LayerImport:setCollapsed - missing collapsed parameter"); - return; - } - if ((collapsed && this.collapsed) || (!collapsed && !this.collapsed)) { - return; - } - if (collapsed) { - this._panelCloseButton.click(); - } else { - this._showImportButton.click(); - } - this.collapsed = collapsed; - } - - /** - * Returns content of a static import (KML, GPX or GeoJSON) - * - * @returns {String} contentStatic - content static - */ - getStaticImportContent () { - return this.contentStatic; - } - - /** - * Returns content of a service import (GetCapabilities) - * - * @returns {String} contentService - content service - */ - getServiceImportContent () { - return this.contentService; - } - - /** - * Returns layer name - * - * @returns {String} name - layer name - */ - getName () { - return this._name; - } - - // ################################################################### // - // ##################### init component ############################## // - // ################################################################### // - - /** - * Initialize LayerImport control (called by LayerImport constructor) - * - * @param {Object} options - constructor options - * @private - */ - _initialize (options) { - // ############################################################ // - // ################### Options du composant ################### // - - // check input options format - this._checkInputOptions(options); - - // set default options - this.options = { - collapsed : true, - draggable : false, - layerTypes : ["KML", "GPX", "GeoJSON", "WMS", "WMTS", "MAPBOX"], - webServicesOptions : {}, - vectorStyleOptions : { - KML : { - extractStyles : true, - showPointNames : true, - defaultStyle : {} - }, - GPX : { - defaultStyle : {} - }, - GeoJSON : { - defaultStyle : {} - }, - MapBox : { - defaultStyle : {}, - editor : {} - } - } - }; - - // TODO gestion du proxy - - // set extractStyles parameter - if (options.vectorStyleOptions && options.vectorStyleOptions.KML && options.vectorStyleOptions.KML.extractStyles) { - this.options.vectorStyleOptions.KML.extractStyles = options.vectorStyleOptions.KML.extractStyles; - } // TODO - // set showPointNames parameter - if (options.vectorStyleOptions && options.vectorStyleOptions.KML && options.vectorStyleOptions.KML.showPointNames) { - this.options.vectorStyleOptions.KML.showPointNames = options.vectorStyleOptions.KML.showPointNames; - } - - // set vector layers default styles (KML, GPX, GeoJSON, MapBox) - if (options.vectorStyleOptions && options.vectorStyleOptions.KML && options.vectorStyleOptions.KML.defaultStyle) { - // get from options if specified - this.options.vectorStyleOptions.KML.defaultStyle = options.vectorStyleOptions.KML.defaultStyle; - } else { - // get from control default options otherwise - this.options.vectorStyleOptions.KML.defaultStyle = new Style({ - image : LayerImport.DefaultStyles.image, - stroke : LayerImport.DefaultStyles.stroke, - fill : LayerImport.DefaultStyles.fill, - text : LayerImport.DefaultStyles.text - }); - } - if (options.vectorStyleOptions && options.vectorStyleOptions.GPX && options.vectorStyleOptions.GPX.defaultStyle) { - // get from options if specified - this.options.vectorStyleOptions.GPX.defaultStyle = options.vectorStyleOptions.GPX.defaultStyle; - } else { - // get from control default options otherwise - this.options.vectorStyleOptions.GPX.defaultStyle = new Style({ - image : LayerImport.DefaultStyles.image, - stroke : LayerImport.DefaultStyles.stroke, - fill : LayerImport.DefaultStyles.fill, - text : LayerImport.DefaultStyles.text - }); - } - if (options.vectorStyleOptions && options.vectorStyleOptions.GeoJSON && options.vectorStyleOptions.GeoJSON.defaultStyle) { - // get from options if specified - this.options.vectorStyleOptions.GeoJSON.defaultStyle = options.vectorStyleOptions.GeoJSON.defaultStyle; - } else { - // get from control default options otherwise - this.options.vectorStyleOptions.GeoJSON.defaultStyle = new Style({ - image : LayerImport.DefaultStyles.image, - stroke : LayerImport.DefaultStyles.stroke, - fill : LayerImport.DefaultStyles.fill, - text : LayerImport.DefaultStyles.text - }); - } - // FIXME tester les styles par defaut sur une couche vecteur tuilé sans style ! - if (options.vectorStyleOptions && options.vectorStyleOptions.MapBox && options.vectorStyleOptions.MapBox.defaultStyle) { - // get from options if specified - this.options.vectorStyleOptions.MapBox.defaultStyle = options.vectorStyleOptions.MapBox.defaultStyle; - } else { - // get from control default options otherwise - this.options.vectorStyleOptions.MapBox.defaultStyle = new Style({ - image : LayerImport.DefaultStyles.image, - stroke : LayerImport.DefaultStyles.stroke, - fill : LayerImport.DefaultStyles.fill, - text : LayerImport.DefaultStyles.text - }); - } - - if (options.vectorStyleOptions && options.vectorStyleOptions.MapBox && options.vectorStyleOptions.MapBox.editor) { - // get from options if specified - this.options.vectorStyleOptions.MapBox.editor = options.vectorStyleOptions.MapBox.editor; - } else { - this.options.vectorStyleOptions.MapBox.editor = { - title : true, - collapse : false, - themes : false, - layers : true, - style : true, - filter : false, - legend : true, - group : false - }; - } - - if (options.vectorStyleOptions && options.vectorStyleOptions.MapBox && options.vectorStyleOptions.MapBox.hasOwnProperty("display")) { - this.options.vectorStyleOptions.MapBox.display = options.vectorStyleOptions.MapBox.display; - } else { - this.options.vectorStyleOptions.MapBox.display = true; - } - - // merge layer types - if (Array.isArray(options.layerTypes)) { - var layerTypes = []; - for (var i = 0; i < options.layerTypes.length; i++) { - layerTypes.push(options.layerTypes[i]); - } - this.options.layerTypes = layerTypes; - } - - // merge with user options - Utils.mergeParams(this.options, options); - - /** {Boolean} specify if LayerImport control is collapsed (true) or not (false) */ - this.collapsed = this.options.collapsed; - - /** {Boolean} specify if LayerImport control is draggable (true) or not (false) */ - this.draggable = this.options.draggable; - - // identifiant du contrôle : utile pour suffixer les identifiants CSS (pour gérer le cas où il y en a plusieurs dans la même page) - this._uid = SelectorID.generate(); - - // si une requête est en cours ou non - this._waiting = false; - // timer pour cacher la patience après un certain temps - this._timer = null; - - // initialisation des types d'import - this._initImportTypes(); - // initialisation des styles par défaut - this._initDefaultStyles(); - - // ################################################################## // - // ################### Elements principaux du DOM ################### // - - // containers principaux (FIXME : tous utiles ?) - this._showImportButton = null; - this._importPanel = null; - this._panelCloseButton = null; - this._importPanelHeader = null; - this._formContainer = null; - this._staticLocalImportInput = null; - this._staticUrlImportInput = null; - this._serviceUrlImportInput = null; - this._getCapPanel = null; - this._getCapPanelHeader = null; - this._getCapResultsListContainer = null; - this._mapBoxPanel = null; - this._mapBoxPanelHeader = null; - this._mapBoxResultsListContainer = null; - - this._waitingContainer = null; - this._loadingContainer = null; - - // ################################################################## // - // ################ Interrogation du GetCapabilities ################ // - - this._getCapRequestUrl = null; - this._getCapResponseWMS = null; - this._getCapResponseWMSLayers = []; - this._getCapResponseWMTS = null; - this._getCapResponseWMTSLayers = []; - - // ################################################################## // - // ########################### MapBox ############################### // - this._hasMapBoxResults = false; - - // ################################################################## // - // ########################### file or url ########################## // - this.contentStatic = null; - this._url = null; - this._file = null; - this._name = null; - } - - /** - * this method is called by this.initialize() - * and makes sure input options are correctly formated - * - * @param {Object} options - control input options - * @private - */ - _checkInputOptions (options) { - // on vérifie le tableau des types - if (options.layerTypes) { - var layerTypes = options.layerTypes; - // on vérifie que la liste des types est bien un tableau - if (!Array.isArray(layerTypes)) { - logger.warn("[ol.control.LayerImport] 'options.layerTypes' parameter should be an array. Set default values [\"KML\", \"GPX\", \"GeoJSON\", \"WMS\", \"WMTS\"]"); - options.layerTypes = [ - "KML", - "GPX", - "GeoJSON", - "WMS", - "WMTS", - "MAPBOX" - ]; - } else { - var typesList = [ - "KML", - "GPX", - "GEOJSON", - "WMS", - "WMTS", - "WFS", - "MAPBOX" - ]; - var wrongTypesIndexes = []; - for (var i = 0; i < layerTypes.length; i++) { - if (typeof layerTypes[i] !== "string") { - // si l'élément du tableau n'est pas une chaine de caractères, on stocke l'index pour le retirer du tableau - wrongTypesIndexes.push(i); - logger.warn("[ol.control.LayerImport] 'options.layerTypes' elements should be of type string (" + layerTypes[i] + ")"); - } else { - // on passe en majuscules pour comparer - layerTypes[i] = layerTypes[i].toUpperCase(); - if (typesList.indexOf(layerTypes[i]) === -1) { - // si le type n'est pas référencé, on stocke son index pour le retirer du tableau (après avoir terminé de parcourir le tableau) - wrongTypesIndexes.push(i); - logger.log("[ol.control.LayerImport] options.layerTypes : " + layerTypes[i] + " is not a supported type"); - } - // cas spécial du GeoJSON qu'on ne laisse pas en majuscules - if (layerTypes[i] === "GEOJSON") { - layerTypes[i] = "GeoJSON"; - } - if (layerTypes[i] === "MAPBOX") { - layerTypes[i] = "MAPBOX"; - } - } - } - // on retire les types non référencés qu'on a pu rencontrer - if (wrongTypesIndexes.length !== 0) { - for (var j = wrongTypesIndexes.length - 1; j >= 0; j--) { - layerTypes.splice(wrongTypesIndexes[j], 1); - } - } - } - } - } - - /** - * this method is called by this.initialize() - * and initializes default styles for vector layers (KML/GPX/GeoJSON) - * - * @private - */ - _initDefaultStyles () { - var kmlDefaultStyles = this.options.vectorStyleOptions.KML.defaultStyle; - this._defaultKMLStyle = new Style({ - image : kmlDefaultStyles.image, - stroke : kmlDefaultStyles.stroke, - fill : kmlDefaultStyles.fill, - text : kmlDefaultStyles.text - }); - var gpxDefaultStyles = this.options.vectorStyleOptions.GPX.defaultStyle; - this._defaultGPXStyle = new Style({ - image : gpxDefaultStyles.image, - stroke : gpxDefaultStyles.stroke, - fill : gpxDefaultStyles.fill, - text : gpxDefaultStyles.text - }); - var geoJSONDefaultStyles = this.options.vectorStyleOptions.GeoJSON.defaultStyle; - this._defaultGeoJSONStyle = new Style({ - image : geoJSONDefaultStyles.image, - stroke : geoJSONDefaultStyles.stroke, - fill : geoJSONDefaultStyles.fill, - text : geoJSONDefaultStyles.text - }); - var MapBoxDefaultStyles = this.options.vectorStyleOptions.MapBox.defaultStyle; - this._defaultMapBoxStyle = new Style({ - image : MapBoxDefaultStyles.image, - stroke : MapBoxDefaultStyles.stroke, - fill : MapBoxDefaultStyles.fill, - text : MapBoxDefaultStyles.text - }); - } - - /** - * this method is called by this.initialize() - * and initializes import types parameter - * - * @private - */ - _initImportTypes () { - this._currentImportType = this.options.layerTypes[0] || "KML"; - if (this._currentImportType === "KML" || this._currentImportType === "GPX" || this._currentImportType === "GeoJSON" || this._currentImportType === "MAPBOX") { - this._isCurrentImportTypeStatic = true; - } else if (this._currentImportType === "WMS" || this._currentImportType === "WMTS" || this._currentImportType === "WFS") { - this._isCurrentImportTypeStatic = false; - } - this._currentStaticImportType = "local"; - } - - /** - * Create control main container (DOM initialize) - * - * @private - * @returns {DOMElement} container - control main container - */ - _initContainer () { - // create main container - var container = this._createMainContainerElement(); - - // create Import picto - var picto = this._showImportButton = this._createShowImportPictoElement(); - container.appendChild(picto); - - // panel - var importPanel = this._importPanel = this._createImportPanelElement(); - var importPanelPanelDiv = this._createImportPanelDivElement(); - importPanel.appendChild(importPanelPanelDiv); - - // header - var panelHeader = this._importPanelHeader = this._createImportPanelHeaderElement(); - - // panel title - var panelTitle = this._createImportPanelTitleElement(); - panelHeader.appendChild(panelTitle); - // close picto - var panelClose = this._panelCloseButton = this._createImportPanelCloseElement(); - panelHeader.appendChild(panelClose); - importPanelPanelDiv.appendChild(panelHeader); - - // form : initialisation du formulaire d'import des couches (types d'import et saisie de l'url / du fichier) - var importForm = this._formContainer = this._initInputFormElement(); - importPanelPanelDiv.appendChild(importForm); - - // results (dans le panel) - var getCapPanel = this._getCapPanel = this._createImportGetCapPanelElement(); - var getCapPanelHeader = this._getCapPanelHeader = this._createImportGetCapPanelHeaderElement(); - getCapPanel.appendChild(getCapPanelHeader); - var importGetCapResultsList = this._getCapResultsListContainer = this._createImportGetCapResultsContainer(); - getCapPanel.appendChild(importGetCapResultsList); - importPanelPanelDiv.appendChild(getCapPanel); - - // mapbox panel results - var mapBoxPanel = this._mapBoxPanel = this._createImportMapBoxPanelElement(); - var mapBoxPanelHeader = this._mapBoxPanelHeader = this._createImportMapBoxPanelHeaderElement(); - mapBoxPanel.appendChild(mapBoxPanelHeader); - var importMapBoxResultsList = this._mapBoxResultsListContainer = this._createImportMapBoxResultsContainer(); - mapBoxPanel.appendChild(importMapBoxResultsList); - - // loading element mapbox - var loading = this._loadingContainer = this._createLoadingElement(); - mapBoxPanel.appendChild(loading); - - importPanelPanelDiv.appendChild(mapBoxPanel); - - // waiting - var waiting = this._waitingContainer = this._createImportWaitingElement(); - importPanelPanelDiv.appendChild(waiting); - - container.appendChild(importPanel); - - return container; - } - - /** - * Create control main container (DOM initialize) - * - * @private - * @returns {DOMElement} importForm - form main container - */ - _initInputFormElement () { - // form main container - var importForm = this._createImportPanelFormElement(); - - // Format choice - var importTypeChoiceDiv = this._createImportTypeLineElement(this.options.layerTypes); - importForm.appendChild(importTypeChoiceDiv); - - // params for KML/GPX/GeoJSON - - var importStaticParamsContainer = this._createImportStaticParamsContainer(this.options.layerTypes[0]); - // static file name - var staticNameLabel = this._createStaticNameLabel(); - importStaticParamsContainer.appendChild(staticNameLabel); - // static import choice (local / url) - var staticImportChoice = this._createStaticModeChoiceDiv(); - // TODO : passer un paramètre "checked" ?? - var staticLocalImportChoice = this._createStaticLocalChoiceDiv(); - staticImportChoice.appendChild(staticLocalImportChoice); - var staticUrlImportChoice = this._createStaticUrlChoiceDiv(); - staticImportChoice.appendChild(staticUrlImportChoice); - importStaticParamsContainer.appendChild(staticImportChoice); - - // div for local file import - var staticLocalInputDiv = this._createStaticLocalInputDiv(); - // label - staticLocalInputDiv.appendChild(this._createStaticLocalInputLabel()); - // file input - this._staticLocalImportInput = this._createStaticLocalInput(); - staticLocalInputDiv.appendChild(this._staticLocalImportInput); - // append div to params container - importStaticParamsContainer.appendChild(staticLocalInputDiv); - - // div for url input (info: séparation pour récupérer l'élément input) - var staticUrlInputDiv = this._createStaticUrlInputDiv(); - // label - staticUrlInputDiv.appendChild(this._createStaticUrlInputLabel()); - // url input - this._staticUrlImportInput = this._createStaticUrlInput(); - staticUrlInputDiv.appendChild(this._staticUrlImportInput); - // append div to params container - importStaticParamsContainer.appendChild(staticUrlInputDiv); - - // append static params container to form container - importForm.appendChild(importStaticParamsContainer); - - // params for WMS/WMTS/WFS - - var importServiceParamsContainer = this._createServiceParamsContainer(this.options.layerTypes[0]); - // div for service url - var importServiceUrlDiv = this._createServiceUrlDiv(); - // label - importServiceUrlDiv.appendChild(this._createServiceUrlInputLabel()); - // input - this._serviceUrlImportInput = this._createServiceUrlInput(); - importServiceUrlDiv.appendChild(this._serviceUrlImportInput); - // append div to params container - importServiceParamsContainer.appendChild(importServiceUrlDiv); - // append service params container to form container - importForm.appendChild(importServiceParamsContainer); - - // submit (bouton "Importer") - var submit = this._createImportSubmitFormElement(); - importForm.appendChild(submit); - - return importForm; - } - - // ################################################################### // - // ######################### DOM events ############################## // - // ################################################################### // - - /** - * this method is called by event 'click' on 'GPshowImportPicto' picto - * (cf. LayerImportDOM._createShowImportPictoElement), - * and dispatch event change:collapsed (for tools listening this property) - * - * @private - */ - _onShowImportClick () { - var map = this.getMap(); - // on supprime toutes les interactions - Interactions.unset(map); - // info : on génère nous même l'evenement OpenLayers de changement de propriété - // (utiliser ol.control.LayerImport.on("change:collapsed", function ) pour s'abonner à cet évènement) - var opened = this._showImportButton.ariaPressed; - this.collapsed = !(opened === "true"); - this.dispatchEvent("change:collapsed"); - // on affiche les resultats d'une couche MapBox - if (this._hasMapBoxResults) { - this._mapBoxPanel.style.display = "block"; - } else { - this._formContainer.style.display = "block"; - this._importPanelHeader.style.display = ""; - } - } - - /** - * this method is called by event 'change' on 'GPimportType' tag form - * (cf. LayerImportDOM._createImportTypeLineElement), - * and change current import type - * - * @param {Object} e - HTMLElement - * @private - */ - _onImportTypeChange (e) { - this._currentImportType = e.target.value; - if (this._currentImportType === "KML" || this._currentImportType === "GPX" || this._currentImportType === "GeoJSON" || this._currentImportType === "MAPBOX") { - this._isCurrentImportTypeStatic = true; - } else if (this._currentImportType === "WMS" || this._currentImportType === "WMTS" || this._currentImportType === "WFS") { - this._isCurrentImportTypeStatic = false; - } - } - - /** - * this method is called by event 'change' on 'GPimportType' tag form - * (cf. LayerImportDOM._createImportTypeLineElement), - * and change current import type - * - * @param {Object} e - HTMLElement - * @private - */ - _onStaticImportTypeChange (e) { - this._currentStaticImportType = e.target.value; - } - - /** - * this method is called by event 'click' on 'GPimportGetCapPanelClose' tag form - * (cf. LayerImportDOM._createImportGetCapPanelHeaderElement), - * and reset getCapabilities information - * - * @private - */ - _onGetCapPanelClose () { - // this._clearGetCapParams(); - if (this._currentImportType === "WMS" || - this._currentImportType === "WMTS" || - this._currentImportType === "WFS") { - this.cleanGetCapResultsList(); - } - } - - /** - * this method is called by event 'click' on 'GPimportMapBoxPanelClose' tag form - * (cf. LayerImportDOM._createImportMapBoxPanelHeaderElement), - * and reset mapbox information - * - * @private - */ - _onMapBoxPanelClose () { - this.cleanMapBoxResultsList(); - this._loadingContainer.className = ""; - } - - /** - * this method is called by event 'click' on 'GPimportMapBoxPanelReturnPicto' tag form - * (cf. LayerImportDOM._createImportMapBoxPanelHeaderElement), - * and return to information - * - * @param {Object} e - HTMLElement - * @private - */ - _onMapBoxReturnPictoClick (e) { - // on bascule sur l'icone d'ouverture du composant - this._mapBoxPanel.style.display = "none"; - this._loadingContainer.className = ""; - } - - // ################################################################### // - // ######################## Submit form ############################## // - // ################################################################### // - - /** - * this method is called by event 'submit' on 'GPimportForm' tag form - * (cf. LayerImportDOM._createImportPanelFormElement), - * and import static layer or call getCap service (according to import type) - * - * @private - */ - _onImportSubmit () { - logger.log("import d'une couche de type : " + this._currentImportType); - - // reinitialisation du contenu d'un import de type - // - static (KML ou GPX ou GeoJSON) - this.contentStatic = null; - // - service (WMS, ...) - this.contentService = null; - - if (this._isCurrentImportTypeStatic) { - this._importStaticLayer(); - } else { - this._importServiceLayers(); - } - } - - // ################################################################### // - // ############## Import KML/GPX/GeoJSON/MapBox layers ############### // - // ################################################################### // - - /** - * this method is called by this_onImportSubmit method - * and import static layer (KML/GPX/GeoJSON) from url or file - * - * @private - */ - _importStaticLayer () { - var layerName; - var staticImportNameInput = document.getElementById(this._addUID("GPimportName")); - if (staticImportNameInput) { - layerName = staticImportNameInput.value || ""; - logger.log("import layer name : " + layerName); - } - - if (this._currentStaticImportType === "local") { - logger.log("import static layer from local file"); - this._importStaticLayerFromLocalFile(layerName); - } else if (this._currentStaticImportType === "url") { - logger.log("import static layer from url"); - this._importStaticLayerFromUrl(layerName); - } - } - - /** - * this method is called by _importStaticLayer method - * and import static layer (KML/GPX/GeoJSON) from url - * - * @param {String} layerName - imported layer name - * @private - */ - _importStaticLayerFromUrl (layerName) { - // 1. Récupération de l'url - var url = this._staticUrlImportInput.value; - logger.log("url : ", url); - if (url.length === 0) { - logger.error("[ol.control.LayerImport] url parameter is mandatory"); - return; - } - // on supprime les éventuels espaces avant ou après - if (url.trim) { - url = url.trim(); - } - - // sauvegarde - this._url = url; - - // si le nom n'est pas renseigné, on extrait le nom du fichier - if (!layerName) { - layerName = this._url.substring(this._url.lastIndexOf("/") + 1, this._url.lastIndexOf(".")); - } - - // sauvegarde - this._name = layerName; - - // 2. récupération proxy - if (this.options.webServicesOptions && this.options.webServicesOptions.proxyUrl) { - url = ProxyUtils.proxifyUrl(url, this.options.webServicesOptions); - } - - // FIXME pb de surcharge en mode UMD !? ça ne marche pas... - // this._hideWaitingContainer(); - // this._addFeaturesFromImportStaticLayerUrl(url, layerName); - - var context = this; - Gp.Protocols.XHR.call({ - url : url, - method : "GET", - timeOut : 15000, - // on success callback : display results in container - onResponse : function (response) { - context._hideWaitingContainer(); - context._addFeaturesFromImportStaticLayer(response, layerName); - }, - // on error callback : log error - onFailure : function (error) { - // en cas d'erreur, on revient au panel initial et on cache la patience - context._hideWaitingContainer(); - logger.error("[ol.control.LayerImport] KML/GPX/GeoJSON/MapBox request failed : ", error); - } - }); - } - - /** - * this method is called by _importStaticLayer method - * and import static layer (KML/GPX/GeoJSON) from local file - * - * @param {String} layerName - imported layer name - * @private - */ - _importStaticLayerFromLocalFile (layerName) { - var file = this._staticLocalImportInput.files[0]; - if (!file) { - logger.warn("[ol.control.LayerImport] missing file"); - return; - } - - // sauvegarde - this._file = file; - - // si le nom n'est pas renseigné, on extrait le nom du fichier - if (!layerName) { - layerName = this._file.name.substring(this._file.name.lastIndexOf("/") + 1, this._file.name.lastIndexOf(".")); - } - - // sauvegarde - this._name = layerName; - - // Création d'un objet FileReader qui permet de lire le contenu du fichier chargé - var fReader = new FileReader(); - - // Définition des fonctions de callbacks associées au reader, - // notamment la fonction onload qui affichera les entités chargées à la carte - var context = this; - // on readAsText error - fReader.onerror = (e) => { - // en cas d'erreur, on revient au panel initial et on cache la patience - context._hideWaitingContainer(); - logger.error("error fileReader : ", e); - }; - /** on readAsText progress */ - fReader.onprogress = () => { - logger.log("onprogress"); - }; - /** on load start */ - fReader.onloadstart = () => { - // affichage d'une patience le temps du chargement - context._displayWaitingContainer(); - logger.log("onloadstart"); - }; - /** on readAsText abort */ - fReader.onabort = () => { - // en cas d'erreur, on revient au panel initial et on cache la patience - context._hideWaitingContainer(); - logger.log("onabort"); - }; - // on readAsText loadend - fReader.onloadend = (e) => { - // fReader = null ? - // en cas d'erreur, on revient au panel initial et on cache la patience - // context._hideWaitingContainer(); - // TODO : replier le formulaire ? - logger.log("onloadend : ", e); - }; - // on readAsText load - fReader.onload = (e) => { - logger.log("fileReader onload - file content : ", e.target.result); - - // on cache la patience - context._hideWaitingContainer(); - context._addFeaturesFromImportStaticLayer(e.target.result, layerName); - }; - - // Lecture du fichier chargé à l'aide de fileReader - fReader.readAsText(file); - } - - /** - * this method is called by _importStaticLayerFom* method - * and add features to the map - * - * @param {String} fileContent - content file - * @param {String} layerName - imported layer name - * @private - */ - _addFeaturesFromImportStaticLayer (fileContent, layerName) { - // récupération du contenu du fichier - var map = this.getMap(); - if (!map || !fileContent) { - return; - } - - var vectorLayer = null; - var vectorSource = null; - var vectorFormat = null; - var vectorStyle = null; - - // sauvegarde du content KML/GPX/GeoJSON/MapBox - this.contentStatic = fileContent; - - if (this._currentImportType === "MAPBOX") { - // INFO - // on ne nettoie pas délibérément la liste de résultats de type MapBox - // car on souhaite pouvoir interagir sur les couches (editeur). - // du coup, à chaque import, on empile les éditeurs. - this._hasMapBoxResults = true; - - // contexte - var self = this; - - // style mapbox - var _glStyles = JSON.parse(fileContent); - - // liste des sources - var _glSources = _glStyles.sources; - - // FIXME a t on du multi-sources ? - // mais comment doit on les traiter ? - // EXPERIMENTAL ! - var _multiSources = (Object.keys(_glSources).length > 1) ? 1 : 0; - - for (var _glSourceId in _glSources) { - if (_glSources.hasOwnProperty(_glSourceId)) { - var _title = ""; - var _description = ""; - var _quicklookUrl = null; - var _legends = null; - var _metadata = null; - var _originators = null; - - // lecture des informations dans le style - // ex. metadata : { - // geoportail:[title | description | quicklookUrl | legends | originators | metadata] - // } - if (_glStyles.metadata) { - for (var ns in _glStyles.metadata) { - if (_glStyles.metadata.hasOwnProperty(ns)) { - var _keys = ns.split(":"); - if (_keys[0] === "geoportail") { - var key = _keys[1]; - if (key === "title") { - _title = _glStyles.metadata[ns]; - continue; - } - if (key === "description") { - _description = _glStyles.metadata[ns]; - continue; - } - if (key === "quicklookUrl") { - _quicklookUrl = _glStyles.metadata[ns]; - continue; - } - if (key === "legends") { - _legends = _glStyles.metadata[ns]; - continue; - } - if (key === "metadata") { - _metadata = _glStyles.metadata[ns]; - continue; - } - if (key === "originators") { - _originators = _glStyles.metadata[ns]; - continue; - } - } - } - } - } - - // titre par defaut - if (!_title) { - _title = "Couche MapBox"; - } - // description par defaut - if (!_description) { - _description = "Couche MapBox"; - } - // cas des multisources - _title = (_multiSources) ? _title + "(" + _glSourceId + ")" : _title; - - // source mapbox - var _glSource = _glSources[_glSourceId]; - - // construction de la couche en fonction du type - var _glType = _glSource.type; - - if (_glType === "vector") { - // url du tilejson ou flux mapbox - var _glUrl = _glSource.url; - // url du service tuilé - var _glTiles = _glSource.tiles; - // sprites - var _glSprite = _glStyles.sprite; - - // FIXME si on a un import par fichier local (this._file), - // - comment passe t on la clef / le token ? - // - comment remplacer un flux mapbox sur une url de service tuilé avec un import local ? - if (_glUrl && _glUrl.indexOf("mapbox://") === 0) { - var _urlService = this._url; // FIXME si fichier local !? - if (_urlService) { - _glTiles = ["a", "b", "c", "d"].map(function (host) { - var path = _glUrl.replace("mapbox://", ""); - var accessToken = _urlService.split("?")[1]; - return "https://" + - host + ".tiles.mapbox.com/v4/" + - path + "/{z}/{x}/{y}.vector.pbf?" + - accessToken; - }); - // conversion des sprites sur un autre scheme que "mapbox://" - if (_glSprite.indexOf("mapbox://") === 0) { - var s = _urlService.split("?"); // FIXME si fichier local !? - _glStyles.sprite = s[0] + "/sprite" + "?" + s[1]; - } - } else { - logger.warn("Not yet implemented, can't use the local import scheme with a 'mapbox://' in the file.!"); - } - } - - if (_glTiles) { - // service tuilé et/ou mapbox - vectorFormat = new MVT({ - featureClass : Feature - }); - vectorSource = new VectorTileSource({ - attributions : _glSource.attribution, - format : vectorFormat, - // INFO - // on supprime la grille pour forcer l'utilisation par defaut des tuiles en 512 - // sur du vecteur tuilé - // tileGrid : olCreateXYZTileGrid({ // TODO scheme tms ? - // extent : _glSource.bounds, // [minx, miny, maxx, maxy] - // maxZoom : _glSource.maxzoom || 22, - // minZoom : _glSource.minzoom || 1, - // tileSize : _glSource.tileSize || 256 - // }), - urls : _glTiles - }); - vectorSource._title = _title; - vectorSource._description = _description; - vectorSource._quicklookUrl = _quicklookUrl; - vectorSource._metadata = _metadata; - vectorSource._legends = _legends; - vectorSource._originators = _originators; - // waiting - vectorSource.on("tileloadstart", function (e) { - self._loadingContainer.className = "GPmapLoadingVisible"; - }); - vectorSource.on("tileloadend", function (e) { - self._loadingContainer.className = ""; - }); - vectorSource.on("tileloaderror", function (e) { - self._loadingContainer.className = ""; - }); - vectorLayer = new VectorTileLayer({ - source : vectorSource, - visible : false, - // zIndex: 0, // FIXME gerer l'ordre sur des multisources ? - declutter : true // TODO utile ? - }); - vectorLayer.id = _glSourceId; - vectorLayer.gpResultLayerId = "layerimport:" + this._currentImportType; - } else if (_glUrl) { - // service avec un tilejson - vectorFormat = new MVT({ - featureClass : Feature - }); - vectorLayer = new VectorTileLayer({ - visible : false, - // zIndex : 0 - declutter : true - }); - vectorLayer.id = _glSourceId; - vectorLayer.gpResultLayerId = "layerimport:" + this._currentImportType; - var vectorTileJson = new TileJSONSource({ - url : _glUrl - }); - // lecture du tilejson avec extension IGN - // les extensions sont enregistrées - // dans les propriétés de la couche : layer.set(mapbox-extension) - // pour une utilisation ulterieur (ex. editeur) - var _key = vectorTileJson.on("change", function () { - if (vectorTileJson.getState() === "ready") { - var _tileJSONDoc = vectorTileJson.getTileJSON(); - - var tiles = Array.isArray(_tileJSONDoc.tiles) ? _tileJSONDoc.tiles : [_tileJSONDoc.tiles]; - for (var i = 0; i < tiles.length; i++) { - var tile = tiles[i]; - if (tile.indexOf("http") !== 0) { - tiles[i] = _glUrl + tile; - } - } - vectorSource = new VectorTileSource({ - attributions : vectorTileJson.getAttributions() || _tileJSONDoc.attribution, - format : vectorFormat, - // tileGrid : olCreateXYZTileGrid({ - // extent : _glSource.bounds, // [minx, miny, maxx, maxy] - // maxZoom : _glSource.maxzoom || 22, - // minZoom : _glSource.minzoom || 1, - // tileSize : _glSource.tileSize || 256 - // }), - urls : tiles - }); - vectorSource._title = _title; - vectorSource._description = _description; - vectorSource._quicklookUrl = _quicklookUrl; - vectorSource._metadata = _metadata; - vectorSource._legends = _legends; - vectorSource._originators = _originators; - // waiting - vectorSource.on("tileloadstart", function (e) { - self._loadingContainer.className = "GPmapLoadingVisible"; - }); - vectorSource.on("tileloadend", function (e) { - self._loadingContainer.className = ""; - }); - vectorLayer.setSource(vectorSource); - vectorLayer.set("mapbox-extension", _tileJSONDoc["vector_layers"]); - olObservableUnByKey(_key); - } - }); - } - } else if (_glType === "geojson") { - // FIXME - // - cas avec un objet de type features ? - // - cas avec une url relative ? - var _glData = _glSource.data; - - vectorFormat = new GeoJSONExtended(); - vectorSource = new VectorTileSource({ - attributions : _glSource.attribution, - format : vectorFormat, - url : _glData - }); - vectorSource._title = _title; - vectorSource._description = _description; - vectorSource._quicklookUrl = _quicklookUrl; - vectorSource._metadata = _metadata; - vectorSource._legends = _legends; - vectorSource._originators = _originators; - vectorLayer = new VectorTileLayer({ - source : vectorSource, - visible : false, - // zIndex: 0, // FIXME gerer l'ordre sur des multisources ? - declutter : true // TODO utile ? - }); - vectorLayer.id = _glSourceId; - vectorLayer.gpResultLayerId = "layerimport:" + this._currentImportType; - } else { - logger.warn("Type MapBox format unknown !"); - return; - } - - // clone - var _glStyle = JSON.parse(JSON.stringify(_glStyles)); - // cas du multi source - if (_multiSources) { - // on supprime les layers inutiles - var _glLayers = _glStyle.layers; - for (var ii = 0; ii < _glLayers.length; ii++) { - var _glLayer = _glLayers[ii]; - if (_glLayer.source !== _glSourceId) { - _glLayers.splice(ii, 1); - continue; - } - } - // on supprime les sources inutiles - for (var keySource in _glStyle.sources) { - if (_glStyle.sources.hasOwnProperty(keySource)) { - if (keySource !== _glSourceId) { - delete _glStyle.sources[keySource]; - } - } - } - } - - // parametre à transmettre à la fonction auto-invoquée - var params = { - id : _glSourceId, - styles : _glStyle, - layer : vectorLayer, - options : { - title : layerName || _title, - description : _description, - quicklookUrl : _quicklookUrl, - metadata : _metadata, - legends : _legends, - originators : _originators - } - }; - // fonction auto-invoquée - (function (p) { - // TODO ajouter le style de type background ! - // fonction de style de la couche - var setStyle = () => { - applyStyleOlms(p.layer, p.styles, p.id) - .then(function () { - var visibility = true; - p.layer.setVisible(visibility); - var opacity = 1; - p.layer.setOpacity(opacity); - }) - .then(function () { - // gestion du centre sur la carte si center renseigné ! - var projCode = map.getView().getProjection().getCode(); - if (map.getView() && p.styles.center && p.styles.center.length) { - map.getView().setCenter(olTransformProj(p.styles.center, "EPSG:4326", projCode)); - } - - // gestion du zoom sur la carte si zoom renseigné ! - if (map.getView() && (p.styles.zoom || p.styles.zoom === 0)) { - map.getView().setZoom(p.styles.zoom); - } - - // zoom sur l'étendue des entités récupérées (si possible) - var source = p.layer.getSource(); - if (map.getView() && map.getSize() && source.getExtent) { - var sourceExtent = source.getExtent(); - if (sourceExtent && sourceExtent[0] !== Infinity) { - map.getView().fit(source.getExtent(), map.getSize()); - } - } - }) - .then(function () { - // on cache le panneau principal des imports - self._formContainer.style.display = "none"; - self._importPanelHeader.style.display = "none"; - - // editeur de styles - var editor = new Editor({ - target : self._mapBoxResultsListContainer, - style : JSON.parse(JSON.stringify(p.styles)), // clone - scope : this, - events : { - "editor:onloaded" : self._onLoadedMapBox, // utile ? - "editor:layer:onclickvisibility" : self._onChangeVisibilitySourceMapBox, - "editor:style:scale:onchangemin" : self._onChangeScaleMinSourceMapBox, - "editor:style:scale:onchangemax" : self._onChangeScaleMaxSourceMapBox, - "editor:legend:onchangevalue" : self._onChangeLegendValueSourceMapBox, - "editor:legend:onclickedition" : self._onDisplayLayerSourceMapBox - }, - tools : self.options.vectorStyleOptions.MapBox.editor - }); - editor.setContext("map", map); - editor.setContext("layer", p.layer); - // creation de l'editeur - return editor.createElement() - .then(function () { - // exception... - if (editor.getLayers().length === 0) { - throw new Error("Il n'existe pas de styles pour la source demandée !?"); - } - }) - .then(function () { - // affichage du panneau des couches accessibles à l'edition - if (self.options.vectorStyleOptions.MapBox.display) { - self._mapBoxPanel.style.display = "block"; - } - }) - .then(function () { - // hack pour modifier le titre de la couche de fond - var elements = self._mapBoxResultsListContainer.getElementsByClassName("GPEditorMapBoxLayerTitleLabel"); - for (let index = 0; index < elements.length; index++) { - const element = elements[index]; - if (element.textContent === "bckgrd") { - element.textContent = "Couleur de remplissage"; - } - } - }) - .then(function () { - // association entre le layer et l'editeur via l'id - p.layer.set("mapbox-editor", editor.getID()); - // envoi d'un evenement - // un peu en décalé pour laisser le temps au DOM de faire le job... - setTimeout(function () { - map.dispatchEvent({ - id : editor.getID(), - type : "editor:loaded", - style : p.styles, - layer : p.layer - }); - }, 100); - }) - .catch(function (e) { - // on propage l'exception - throw e; - }); - }) - .then(function () { - // envoi d'un evenement ! - map.dispatchEvent({ - id : p.id, - type : "render:success", - style : p.styles - }); - }) - .catch(function (e) { - logger.error(e); - // envoi d'un evenement ! - map.dispatchEvent({ - id : p.id, - type : "render:failure", - error : e - }); - }); - }; - - // etat des layers en cours - logger.warn(p.layer); - - // ajout des styles dans la carte pour une utilisation - // eventuelle (ex. editeur) - // > map.set("mapbox-styles") - var styles = map.get("mapbox-styles") || {}; - var id = p.id; // FIXME : construction d'un id unique - styles[id] = p.styles; - map.set("mapbox-styles", styles); - - // ajout des differents styles de la couche - // pour une utilisation eventuelle (ex. editeur) - // > layer.set("mapbox-styles") - p.layer.set("mapbox-styles", p.styles); - - // ajout du layer sur la carte - map.addLayer(p.layer); - - // application du style - if (p.layer.getSource()) { - setStyle(); - } else { - p.layer.once("change:source", setStyle); - } - - // maj du gestionnaire de couche - map.getControls().forEach( - (control) => { - if (control instanceof LayerSwitcher) { - control.addLayer( - p.layer, - p.options - ); - } - } - ); - })(params); - } - } - - // TODO style par defaut au cas où l'application du style échoue ! - // TODO au niveau de la couche : minResolution et maxResolution - // FIXME bug avec le geojson, très bizarre !? - // Si on desactive l'editeur, OK - // Sinon NOK !? - } else { - if (this._currentImportType === "KML") { - // lecture du fichier KML : création d'un format ol.format.KML, qui possède une méthode readFeatures (et readProjection) - vectorStyle = this.options.vectorStyleOptions.KML.defaultStyle; - vectorFormat = new KMLExtended({ - showPointNames : this.options.vectorStyleOptions.KML.showPointNames, - extractStyles : this.options.vectorStyleOptions.KML.extractStyles, - defaultStyle : [ - vectorStyle - ] - }); - } else if (this._currentImportType === "GPX") { - // lecture du fichier GPX : création d'un format ol.format.GPX, qui possède une méthode readFeatures (et readProjection) - vectorStyle = this.options.vectorStyleOptions.GPX.defaultStyle; - vectorFormat = new GPXExtended({ - defaultStyle : vectorStyle - }); - } else if (this._currentImportType === "GeoJSON") { - // lecture du fichier GeoJSON : création d'un format ol.format.GeoJSON, qui possède une méthode readFeatures (et readProjection) - vectorStyle = this.options.vectorStyleOptions.GeoJSON.defaultStyle; - vectorFormat = new GeoJSONExtended({ - defaultStyle : vectorStyle - }); - } - - // lecture de la géométrie des entités à partir du fichier, pour éventuelle reprojection. - var fileProj = vectorFormat.readProjection(fileContent); - // récupération de la projection de la carte pour reprojection des géométries - var mapProj = this._getMapProjectionCode(); - - // récupération des entités avec reprojection éventuelle des géométries - var features = null; - features = vectorFormat.readFeatures( - fileContent, { - dataProjection : fileProj, - featureProjection : mapProj - } - ); - - logger.log("loaded features : ", features); - - // création d'une couche vectorielle à partir de ces features - vectorSource = new VectorSource({ - features : new Collection() - }); - vectorSource.addFeatures(features); - - logger.trace(vectorSource); - - // ajout des informations pour le layerSwitcher (titre, description) - vectorSource._title = vectorSource._description = layerName; - - vectorLayer = new VectorLayer({ - source : vectorSource, - style : vectorStyle - }); - - // on rajoute le champ gpResultLayerId permettant d'identifier une couche crée par le composant. - vectorLayer.gpResultLayerId = "layerimport:" + this._currentImportType; - - // cette couche est elle une couche de calcul ? - var configControl = vectorFormat.readRootExtensions("geoportail:compute"); - if (configControl && Object.keys(configControl).length !== 0) { - // identifier le type de calcul authorisé : - // * route - // * isocurve - // * elevationpath - var authorizedControls = { - route : { class : Route, name : "itineraire" }, - isocurve : { class : Isocurve, name : "isocurve" }, - elevationpath : { class : ElevationPath, name : "profil altimetrique" } - }; - // information à transmettre à la couche - var typeControl = configControl.type; - var graphControl = configControl.transport; - if (typeControl) { - // la classe du controle - var nameControl = authorizedControls[typeControl].name; - var titleControl = (graphControl) ? nameControl + " (" + graphControl + ")" : nameControl; - var classControl = authorizedControls[typeControl].class; - if (classControl) { - // on est bien sur une couche de calcul authorisé ! - vectorLayer.gpResultLayerId = "layerimport:COMPUTE"; - // on transmet les infomations utiles - vectorLayer.set("control", typeControl); - vectorLayer.set("name", nameControl); - vectorLayer.set("graph", graphControl); - vectorLayer.set("data", configControl); - vectorLayer.set("title", titleControl); - var formatGeoJSON = new GeoJSONExtended({ - defaultStyle : vectorStyle - }); - var geojson = formatGeoJSON.writeFeatures(features, { - dataProjection : "EPSG:4326", - featureProjection : "EPSG:3857" - }); - vectorLayer.set("geojson", geojson); - // recherche et initialiser le controle - this.getMap().getControls().forEach((control) => { - if (control instanceof classControl) { - control.setData(configControl); - control.setLayer(vectorLayer); - control.init(); - } - }); - } - } - } - - map.addLayer(vectorLayer); - - // TODO : appeler fonction commune - // zoom sur l'étendue des entités récupérées (si possible) - if (map.getView() && map.getSize() && vectorSource.getExtent) { - var sourceExtent = vectorSource.getExtent(); - if (sourceExtent && sourceExtent[0] !== Infinity) { - map.getView().fit(vectorSource.getExtent(), map.getSize()); - } - } - } - } - - /** - * NOT USE : this method is called by _importStaticLayerFom* method - * and add features to the map - * - * @param {String} url - url - * @param {String} layerName - imported layer name - * @private - */ - _addFeaturesFromImportStaticLayerUrl (url, layerName) { - // récupération du contenu du fichier - var map = this.getMap(); - if (!map || !url) { - return; - } - - var vectorSource; - var vectorLayer; - var vectorFormat; - if (this._currentImportType === "MAPBOX") { - // TODO - logger.trace("Not yet implemented !"); - } else { - if (this._currentImportType === "KML") { - // lecture du fichier KML : création d'un format ol.format.KML, qui possède une méthode readFeatures (et readProjection) - vectorFormat = new KMLExtended({ - showPointNames : true, // FIXME option ! - extractStyles : this.options.vectorStyleOptions.KML.extractStyles, - defaultStyle : [ - this.options.vectorStyleOptions.KML.defaultStyle - ] - }); - } else if (this._currentImportType === "GPX") { - // lecture du fichier GPX : création d'un format ol.format.GPX, qui possède une méthode readFeatures (et readProjection) - vectorFormat = new GPXExtended({ - defaultStyle : this.options.vectorStyleOptions.GPX.defaultStyle - }); - } else if (this._currentImportType === "GeoJSON") { - // lecture du fichier GeoJSON : création d'un format ol.format.GeoJSON, qui possède une méthode readFeatures (et readProjection) - vectorFormat = new GeoJSONExtended({ - defaultStyle : this.options.vectorStyleOptions.GeoJSON.defaultStyle - }); - } - - // création d'une couche vectorielle à partir de ces features - vectorSource = new VectorSource({ - url : url, - format : vectorFormat - }); - - if (this._currentImportType === "GPX") { - vectorSource.forEachFeature( - function (feature) { - // si aucun style n'est associé au feature - if (feature.getStyle() == null) { - logger.log("[ol.control.LayerImport] set default style for GPX feature"); - feature.setStyle( - this.options.vectorStyleOptions.GPX.defaultStyle - ); - } - } - ); - } - if (this._currentImportType === "GeoJSON") { - vectorSource.forEachFeature( - function (feature) { - // si aucun style n'est associé au feature - if (feature.getStyle() == null) { - logger.log("[ol.control.LayerImport] set default style for GeoJSON feature"); - feature.setStyle( - this.options.vectorStyleOptions.GeoJSON.defaultStyle - ); - } - } - ); - } - - // ajout des informations pour le layerSwitcher (titre, description) - vectorSource._title = vectorSource._description = layerName; - - vectorLayer = new VectorLayer({ - source : vectorSource - }); - } - - // on rajoute le champ gpResultLayerId permettant d'identifier une couche crée par le composant. (pour layerSwitcher par ex) - vectorLayer.gpResultLayerId = "layerimport:" + this._currentImportType; - map.addLayer(vectorLayer); - - // TODO : appeler fonction commune - // zoom sur l'étendue des entités récupérées (si possible) - if (map.getView() && map.getSize() && vectorSource.getExtent) { - var sourceExtent = vectorSource.getExtent(); - if (sourceExtent && sourceExtent[0] !== Infinity) { - map.getView().fit(vectorSource.getExtent(), map.getSize()); - } - } - } - - // Events MapBox DOM - - /** - * this method is called when the editor is loaded - * - * @param {Object} e - editor - */ - _onLoadedMapBox (e) { - var data = e.target.data.obj; - var layer = this.getContext("layer"); - if (layer.get("mapbox-source") === data.source && layer.get("mapbox-editor") === e.target.editorID) { - // some stuff.. - } - } - - /** - * this method is called on '_addImportMapBoxVisibilitySource' input click - * and change visibility source to map - * - * @param {Object} e - HTMLElement - * @private - */ - _onChangeVisibilitySourceMapBox (e) { - var data = e.target.data.obj; - var target = e.target.srcElement; - var layer = this.getContext("layer"); - - // logger.trace(layer); - if (layer.get("mapbox-source") === data.source && layer.get("mapbox-editor") === e.target.editorID) { - // reload style with new param : layout.visibility : "visible" or "none"... - var styles = layer.get("mapbox-styles"); - var layers = styles.layers; - for (var i = 0; i < layers.length; i++) { - if (layers[i].id === data.id) { - var layout = layers[i].layout; - if (layout) { - layout.visibility = (target.checked) ? "visible" : "none"; - } else { - layers[i].layout = { - visibility : (target.checked) ? "visible" : "none" - }; - } - break; - } - } - applyStyleOlms(layer, styles, data.source) - .then(function () {}) - .catch(function (error) { - logger.error(error); - }); - } - } - - /** - * this method is called on '_addImportMapBoxScaleSource' input slide - * and change zoom source to map - * - * @param {Object} e - HTMLElement - * @private - */ - _onChangeScaleMinSourceMapBox (e) { - var data = e.target.data.obj; - var target = e.target.srcElement; - var layer = this.getContext("layer"); - - if (layer.get("mapbox-source") === data.source && layer.get("mapbox-editor") === e.target.editorID) { - // reload style with new param : minZoom = ... - var styles = layer.get("mapbox-styles"); - var layers = styles.layers; - for (var i = 0; i < layers.length; i++) { - if (layers[i].id === data.id) { - layers[i].minzoom = target.value; - target.title = target.value; - break; - } - } - applyStyleOlms(layer, styles, data.source) - .then(function () {}) - .catch(function (error) { - logger.error(error); - }); - } - } - - /** - * this method is called on '_addImportMapBoxScaleSource' input slide - * and change zoom source to map - * - * @param {Object} e - HTMLElement - * @private - */ - _onChangeScaleMaxSourceMapBox (e) { - var data = e.target.data.obj; - var target = e.target.srcElement; - var layer = this.getContext("layer"); - - // logger.trace(layer); - if (layer.get("mapbox-source") === data.source && layer.get("mapbox-editor") === e.target.editorID) { - // reload style with new param : minZoom = ... - var styles = layer.get("mapbox-styles"); - var layers = styles.layers; - for (var i = 0; i < layers.length; i++) { - if (layers[i].id === data.id) { - layers[i].maxzoom = target.value; - target.title = target.value; - break; - } - } - applyStyleOlms(layer, styles, data.source) - .then(function () {}) - .catch(function (error) { - logger.error(error); - }); - } - } - - /** - * this method is called on '' - * and change zoom source to map - * - * @param {Object} e - HTMLElement - * @private - */ - _onChangeLegendValueSourceMapBox (e) { - var data = e.target.data.obj; - var target = e.target.srcElement; - var layer = this.getContext("layer"); - - // logger.trace(layer); - if (layer.get("mapbox-source") === data.source && layer.get("mapbox-editor") === e.target.editorID) { - // reload style with new param : - var styles = layer.get("mapbox-styles"); - var layers = styles.layers; - for (var i = 0; i < layers.length; i++) { - if (layers[i].id === data.id) { - var paint = layers[i].paint; - if (paint) { - paint[target.dataset.id] = target.value; - } - break; - } - } - applyStyleOlms(layer, styles, data.source) - .then(function () {}) - .catch(function (error) { - logger.error(error); - }); - } - } - - /** - * this method is called on '' - * and change zoom source to map - * - * @param {Object} e - HTMLElement - * @private - */ - _onDisplayLayerSourceMapBox (e) { - var data = e.target.data.obj; - var layer = this.getContext("layer"); - - if (layer.get("mapbox-source") === data.source && layer.get("mapbox-editor") === e.target.editorID) { - var idDOM = e.target.currentTarget.parentNode.id; - var id = idDOM.substring(idDOM.indexOf("-") + 1, idDOM.indexOf("_")); - var l = this.getLayer(id); - l.collapse(); - } - } - - // ################################################################### // - // #################### Import WMS/WMTS layers ####################### // - // ################################################################### // - - /** - * this method is called by this_onImportSubmit method - * and call getCap service from specified url, then display layers list in new panel - * - * @private - */ - _importServiceLayers () { - if (this._currentImportType === "WFS") { - logger.warn("[ol.control.LayerImport] WFS layer import is not implemented yet"); - return; - } - - // 0. on vide d'éventuels résultats précédents dans le panel GetCapResults - this.cleanGetCapResultsList(); - - // 1. récupération de l'url renseignée - var url = this._getCapRequestUrl = this._serviceUrlImportInput.value; - if (!url) { - logger.error("[ol.control.LayerImport] url parameter is mandatory"); - return; - } - logger.log("url : ", url); - - // on supprime les éventuels espaces avant ou après - if (url.trim) { - url = url.trim(); - } - // Info : on ajoute des paramètres uniquement si l'utilisateur n'en a pas déjà saisi (on vérifie la position du caractère "?") - var questionMarkIndex = url.indexOf("?"); - if (questionMarkIndex < 0) { - // dans le cas d'une url du type https://data.geopf.fr/wmts - url += "?SERVICE=" + this._currentImportType + "&REQUEST=GetCapabilities"; - } else if (questionMarkIndex === (url.length - 1)) { - // dans le cas où l'url se termine par "?" - url += "SERVICE=" + this._currentImportType + "&REQUEST=GetCapabilities"; - } - // si on n'est pas dans ces deux cas : l'utilisateur a déjà saisit des paramètres après "?" => on ne fait rien. - - // 2. récupération proxy - if (this.options.webServicesOptions && this.options.webServicesOptions.proxyUrl) { - url = ProxyUtils.proxifyUrl(url, this.options.webServicesOptions); - } - - // 3. affichage d'une patience le temps de la requête - this._displayWaitingContainer(); - - // 4. send getcapabilities request (XHR protocol => proxy Url is needed) - var context = this; - Gp.Protocols.XHR.call({ - url : url, - method : "GET", - timeOut : 15000, - // on success callback : display results in container - onResponse : function (response) { - context._hideWaitingContainer(); - context._displayGetCapResponseLayers(response); - }, - // on error callback : log error - onFailure : function (error) { - // en cas d'erreur, on revient au panel initial et on cache la patience - context._hideWaitingContainer(); - logger.error("[ol.control.LayerImport] getCapabilities request failed : ", error); - } - }); - } - - /** - * this method is called by this._importServiceLayers method - * and display layers list from getcapabilities response - * - * @param {Object} xmlResponse - getCapabilities response (xml format) - * @private - */ - _displayGetCapResponseLayers (xmlResponse) { - var parser; - var layers; - var layerDescription = { - content : null, - title : null - }; - var projection; - this._getCapResponseWMSLayers = []; - - // sauvegarde du content d'un GetCapabilities - this.contentService = xmlResponse; - - // Affichage du panel des couches accessibles - this._importPanel.style.display = "none"; - this._getCapPanel.style.display = "block"; - - // Parse GetCapabilities Response - if (this._currentImportType === "WMS") { - parser = new WMSCapabilities(); - var getCapResponseWMS = this._getCapResponseWMS = parser.read(xmlResponse); - logger.log("getCapabilities response : ", getCapResponseWMS); - - if (getCapResponseWMS && getCapResponseWMS.Capability && getCapResponseWMS.Capability.Layer) { - // info: le parser Openlayers récupère la première layer de comme un unique objet (il écrase les précédents s'il y a pls à la racine de ) - // /!\ être vigilant si le parser est modifié (notamment pour récupérer les différentes layers à la racine. ex http://geoservices.brgm.fr/geologie?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities) - - var getCapLayer = getCapResponseWMS.Capability.Layer; - // on va lire le contenu de la (ou les) pour l'afficher ou en afficher les couches disponibles - if (Array.isArray(getCapLayer)) { - // cas où on a plusieurs à la racine, mais non géré encore par ol.format.WMSCapabilities jusqu'à la v3.18.2. - for (var i = 0; i < getCapLayer.length; i++) { - this._displayGetCapResponseWMSLayer(getCapLayer[i]); - } - } else { - // cas du parser ol.format.WMSCapabilities jusqu'à la v3.18.2. - this._displayGetCapResponseWMSLayer(getCapLayer); - } - } - } else if (this._currentImportType === "WMTS") { - parser = new WMTSCapabilities(); - var getCapResponseWMTS = this._getCapResponseWMTS = parser.read(xmlResponse); - logger.log("getCapabilities response : ", getCapResponseWMTS); - - if (getCapResponseWMTS && getCapResponseWMTS.Contents && getCapResponseWMTS.Contents.Layer) { - layers = getCapResponseWMTS.Contents.Layer; - - if (Array.isArray(layers)) { - // on stocke la liste des couches pour faire le lien avec le DOM - this._getCapResponseWMTSLayers = layers; - - for (var j = 0; j < layers.length; j++) { - // on vérifie que la projection de la couche WMTS est compatible avec celle de la carte - // (ie elle doit être connue par ol.proj) - projection = this._getWMTSLayerProjection(layers[j], getCapResponseWMTS); - if (projection && typeof projection === "string") { - if (olGetProj(projection) || olGetProj(projection.toUpperCase())) { - // si la projection de la couche est connue par ol.proj, - // on ajoute chaque couche de la réponse dans la liste des couches accessibles - layerDescription = { - content : layers[j].Title, - title : layers[j].Abstract || layers[j].Title - }; - if (this._getCapResultsListContainer) { - this._addImportGetCapResultLayer(layerDescription, j, this._getCapResultsListContainer); - } - } else { - // si la projection de la couche n'est pas connue par ol.proj, - // on n'affiche pas la couche dans le panel des résultats - logger.warn("[ol.control.LayerImport] wmts layer cannot be added to map : unknown projection", layers[j]); - continue; - } - } - } - } - } - } - } - - /** - * this method is called by this._displayGetCapResponseLayers method - * and display WMS layer in list from getcapabilities response - * - * @param {Object} layerObj - object corresponding to content in WMS GetCapabilities response - * @param {Object} [parentLayersInfos] - object corresponding to parents content in WMS GetCapabilities response (without children infos) - * @private - */ - _displayGetCapResponseWMSLayer (layerObj, parentLayersInfos) { - if (!layerObj) { - logger.warn("[ol.control.LayerImport] _displayGetCapResponseWMSLayer : getCapabilities layer object not found"); - return; - } - - logger.log("[ol.control.LayerImport] _displayGetCapResponseWMSLayer - layerObj : ", layerObj); - - // récupération de la projection de la map (pour vérifier que l'on peut reprojeter les couches disponibles) - var mapProjCode = this._getMapProjectionCode(); - var projection; - var layerDescription = { - content : null, - title : null - }; - - // 1. héritage éventuels des informations de la couche parent - if (parentLayersInfos) { - var key; - var i; - - // propriétés héritées à ajouter aux propriétés parent - var addKeys = [ - "CRS", - "Style" - // "AuthorityURL" // TODO - ]; - for (i = 0; i < addKeys.length; i++) { - key = addKeys[i]; - if (Array.isArray(parentLayersInfos[key]) && parentLayersInfos[key].length !== 0) { - if (Array.isArray(layerObj[key]) && layerObj[key].length !== 0) { - // on ajoute celles de la couche parent - for (var n = 0; n < parentLayersInfos[key].length; n++) { - if (layerObj[key].indexOf(parentLayersInfos[key][n]) === -1) { - // si le CRS/Style parent n'est pas dans les CRS/Style de la couche, on l'ajoute - layerObj[key].push(parentLayersInfos[key][n]); - } - } - } else { - // si la couche n'a pas de CRS ou Style, on récupère ceux de la couche parent - layerObj[key] = parentLayersInfos[key]; - } - } - } - - // propriétés qui remplacent les valeurs des propriétés héritées, - // càd on récupère la propriété parent seulement si elle n'est pas définie pour l'élément enfant - var replaceKeys = [ - "BoundingBox", - "EX_GeographicBoundingBox", - "MaxScaleDenominator", - "MinScaleDenominator", - "Attribution", - "Dimension", - "queryable", - "cascaded", - "opaque", - "noSubsets", - "fixedWidth", - "fixedHeight" - ]; - for (i = 0; i < replaceKeys.length; i++) { - key = replaceKeys[i]; - if (parentLayersInfos[key] && !layerObj[key]) { - layerObj[key] = parentLayersInfos[key]; - } - } - } else { - // si on n'a pas d'infos de couche parent, on est à la racine du Capability, on le note - layerObj._isRootLayer = true; - layerObj._container = this._getCapResultsListContainer; - if (!layerObj.Title) { - layerObj.Title = "Liste des couches"; - } - } - - // 2. si on a d'autres couches imbriquées, on descend d'un niveau, sinon on affiche la couche dans la liste des résultats - if (layerObj.Layer) { - if (Array.isArray(layerObj.Layer)) { - var _container = (layerObj) ? layerObj._container : parentLayersInfos._container; - var _title = (layerObj) ? layerObj.Title : parentLayersInfos.Title; - layerObj._container = this._addImportGetCapResultListRubrique(_title, _container).lastChild; - for (var j = 0; j < layerObj.Layer.length; j++) { - // on recommence pour chaque sous couche, avec les infos éventuellement héritées - var bRubriqueExist = false; - var lstRubrique = layerObj._container.getElementsByClassName("GPimportGetCapRubriqueTitle"); - for (var ii = 0; ii < lstRubrique.length; ii++) { - if (lstRubrique[ii].title === layerObj.Title) { - bRubriqueExist = true; - layerObj.Layer[j]._container = lstRubrique[ii].parentElement; - } - } - if (!bRubriqueExist) { - layerObj.Layer[j]._container = this._addImportGetCapResultRubrique(layerObj.Title, layerObj._container).lastChild; - } - this._displayGetCapResponseWMSLayer(layerObj.Layer[j], layerObj); - } - } - } else { - // on récupère la longueur de la liste des couches déjà récupérées, pour avoir ce qui sera l'index de la couche à ajouter. - var lastIndex = this._getCapResponseWMSLayers.length; - - // on vérifie que la couche ait une projection compatible avec celle de la carte - // ou soit connue par proj4js, et on stocke cette projection dans les infos de la couche. - projection = this._getWMSLayerProjection(layerObj, mapProjCode); - - if (!projection) { - // si aucune projection n'est compatible avec celle de la carte ou connue par ol.proj, - // on n'affiche pas la couche dans le panel des résultats - logger.warn("[ol.control.LayerImport] wms layer cannot be added to map : unknown projection", layerObj); - } else { - // si on a une projection compatible : on la stocke et la couche sera éventuellement reprojetée à l'ajout - layerObj._projection = projection; - // on ajoute chaque couche de la réponse dans la liste des couches accessibles - layerDescription = { - content : layerObj.Title, - title : layerObj.Abstract || layerObj.Title - }; - // FIXME beurk !? - var _isGoodContainer = layerObj._container; - if (_isGoodContainer.localName === "ul") { - _isGoodContainer = _isGoodContainer.lastChild; - } - this._addImportGetCapResultLayer(layerDescription, lastIndex, _isGoodContainer); - - // puis on stoke la couche dans la liste pour faire le lien avec le DOM - this._getCapResponseWMSLayers[lastIndex] = layerObj; - } - } - } - - /** - * this method is called on 'GPimportGetCapProposal' div click - * and add corresponding layer to map - * - * @param {Object} e - HTMLElement - * @private - */ - _onGetCapResponseLayerClick (e) { - if (e.target && e.target.id) { - var proposalId = parseInt(e.target.id.substr(23), 10); - - if (isNaN(proposalId)) { - return; - } - - var layerInfo; - - if (this._currentImportType === "WMS") { - // récupération des informations liées à la couche - layerInfo = this._getCapResponseWMSLayers[proposalId]; - // ajout de la couche à la carte - this._addGetCapWMSLayer(layerInfo); - } else if (this._currentImportType === "WMTS") { - // récupération des informations liées à la couche - layerInfo = this._getCapResponseWMTSLayers[proposalId]; - // ajout de la couche à la carte - this._addGetCapWMTSLayer(layerInfo); - } - } - } - - // ################################################################### // - // ######### create WMS layer from getCapabilities response ######### // - // ################################################################### // - - /** - * this method is called by this._onGetCapResponseLayerClick - * and add WMS layer to map using parameters from getCapabilities response - * - * @param {Object} layerInfo - layer information from getCapabilities response - * @private - */ - _addGetCapWMSLayer (layerInfo) { - var map = this.getMap(); - if (!map) { - logger.warn("[ol.control.LayerImport] _addGetCapWMSLayer error : map is not defined"); - return; - } - if (!layerInfo) { - logger.warn("[ol.control.LayerImport] _addGetCapWMSLayer error : layerInfo is not defined"); - return; - } - - // récupération de la projection de la carte - var mapProjCode = this._getMapProjectionCode(); - - var wmsSourceOptions = {}; - - // Récupération de l'url - var getMapUrl = this._getWMSLayerGetMapUrl(); - // on essaie de récupérer l'url du service dans le getCapbilities - if (getMapUrl) { - wmsSourceOptions.url = getMapUrl; - } else { - // sinon, on récupère l'url du getCapabilities, à laquelle on enlève éventuellement les paramètres - var questionMarkIndex = this._getCapRequestUrl.indexOf("?"); - if (questionMarkIndex !== -1) { - wmsSourceOptions.url = this._getCapRequestUrl.substring(0, questionMarkIndex); - } else { - wmsSourceOptions.url = this._getCapRequestUrl; - } - } - - wmsSourceOptions.params = {}; - if (layerInfo.Name) { - wmsSourceOptions.params["LAYERS"] = layerInfo.Name; - } else { - logger.warn("[ol.control.LayerImport] unable to add wms layer : mandatory layer 'name' parameter cannot be found", layerInfo); - return; - } - wmsSourceOptions.params["SERVICE"] = "WMS"; - if (this._getCapResponseWMS.version) { - wmsSourceOptions.params["VERSION"] = this._getCapResponseWMS.version; - } - - // on a déjà vérifié que la couche peut être reprojetée, - // on vérifie que la couche ait une projection compatible avec celle de la carte - // ou soit connue par proj4js - var projection = layerInfo._projection; - if (!projection) { - logger.warn("[ol.control.LayerImport] wms layer cannot be added to map : unknown projection"); - return; - } else if (projection !== mapProjCode) { - // si la projection de la carte n'est pas disponible pour cette couche, - // on spécifie une projection (qui doit avoir été définie dans proj4js) pour reprojection par Openlayers - wmsSourceOptions.projection = projection; - } - - // récupération du premier style disponible (pas d'info default?) - var legend; - if (layerInfo.Style && Array.isArray(layerInfo.Style)) { - var style = layerInfo.Style[0]; - wmsSourceOptions.params["STYLES"] = style.Name; - if (style.LegendURL && Array.isArray(style.LegendURL) && style.LegendURL.length !== 0) { - legend = style.LegendURL[0].OnlineResource; - } - } - - // Création de la source (tester un try catch ?) - var wmsSource = new TileWMSSource(wmsSourceOptions); - // ajout des informations pour le layerSwitcher (titre, description, legendes, metadata) ou originators - this._getWMSLayerInfoForLayerSwitcher(layerInfo, legend, wmsSource); - - var layerTileOptions = {}; - layerTileOptions["source"] = wmsSource; - // récupération des résolutions min et max de la layer à partir des dénominateurs d'échelle - this._getWMSLayerMinMaxResolution(layerInfo, mapProjCode, layerTileOptions); - // récupération de l'étendue (bbox) - this._getWMSLayerExtent(layerInfo, mapProjCode, layerTileOptions); - - // création de la couche à partir de la source - var wmsLayer = new TileLayer(layerTileOptions); - // on rajoute le champ gpResultLayerId permettant d'identifier une couche crée par le composant. (pour layerSwitcher par ex) - wmsLayer.gpResultLayerId = "layerimport:WMS"; - // on rajoute le champ gpGFIparams permettant d'identifier si la couche est queryable, et de transmettre les formats reconnus par GetFeatureInfo - if (layerInfo.queryable) { - wmsLayer.gpGFIparams = { - queryable : true - }; - // récupération des différents formats reconnus par le GetFeatureInfo - if (this._getCapResponseWMS && this._getCapResponseWMS.Capability && this._getCapResponseWMS.Capability.Request && this._getCapResponseWMS.Capability.Request.GetFeatureInfo && this._getCapResponseWMS.Capability.Request.GetFeatureInfo.Format && Array.isArray(this._getCapResponseWMS.Capability.Request.GetFeatureInfo.Format)) { - wmsLayer.gpGFIparams.formats = this._getCapResponseWMS.Capability.Request.GetFeatureInfo.Format; - } - } - - map.addLayer(wmsLayer); - } - - /** - * this method is called by this._addGetCapWMSLayer - * and gets service getMap request url - * - * @return {String} getmapurl - service getMap request url - * @private - */ - _getWMSLayerGetMapUrl () { - var getmapurl; - if (this._getCapResponseWMS && this._getCapResponseWMS.Capability && this._getCapResponseWMS.Capability.Request && this._getCapResponseWMS.Capability.Request.GetMap) { - var getmap = this._getCapResponseWMS.Capability.Request.GetMap; - if (getmap.DCPType && Array.isArray(getmap.DCPType) && getmap.DCPType.length !== 0) { - var url = getmap.DCPType[0]; - if (url && url.HTTP && url.HTTP.Get) { - getmapurl = url.HTTP.Get.OnlineResource; - } - } - } - return getmapurl; - } - - /** - * this method is called by this._addGetCapWMSLayer - * and gets a projection both available for a given layer and already defined in proj4js (ol.proj) - * (openlayers raster reprojection will be then able to reproject layer in map projection) - * - * @param {Object} layerInfo - layer information from getCapabilities response - * @param {String} mapProjCode - map projection code (e.g. "EPSG:4326") - * @return {String} projection - ol.proj projection alias (e.g. "EPSG:4326") - * @private - */ - _getWMSLayerProjection (layerInfo, mapProjCode) { - var projection; - - if (!layerInfo || typeof layerInfo !== "object") { - logger.warn("missing layer information (from getCapabilities)"); - return; - } - - // on va parcourir la liste des CRS disponibles pour la couche - // si on trouve la projection de la carte : c'est parfait - // si on trouve une projection qui est connue par ol.proj : Openlayers gère la reprojection - var CRSList = layerInfo.CRS; - if (Array.isArray(CRSList)) { - // on check si la projection de la carte est dans le tableau de projections issues du getCap, - // si oui, on la prend - if (CRSList.includes(mapProjCode)) { - projection = mapProjCode; - return projection; - } - var layerCRS, i; - // si aucune projection du getCap pour la couche n'est égale à celle de la carte - // on retourne la première projection listée dans le getCap qui est gérée par openLayers - for (i = 0; i < CRSList.length; i++) { - layerCRS = CRSList[i]; - if (layerCRS && typeof layerCRS === "string") { - if (olGetProj(layerCRS) || olGetProj(layerCRS.toUpperCase())) { - projection = layerCRS; - // on renvoie la première projection gérée par openLayers - return projection; - } - } - } - } - // si la liste des projections n'est pas un tableau ou si aucune projection n'est égale à celle de la carte ou si aucune n'est gérée par openLayers - // on return undefined (comportement d'origine de la fonction) - return projection; - } - - /** - * this method is called by this._addGetCapWMSLayer - * and sets minResolution and maxResolution parameters for WMS layer (if available in getCapabilities response) - * - * @param {Object} layerInfo - layer information from getCapabilities response - * @param {String} mapProjCode - map projection code (e.g. "EPSG:4326") - * @param {Object} layerTileOptions - options for ol.layer.Tile (to be filled) - * @private - */ - _getWMSLayerMinMaxResolution (layerInfo, mapProjCode, layerTileOptions) { - // récupération des résolutions min et max à partir des dénominateurs d'échelle - var mapUnits = olGetProj(mapProjCode).getUnits(); - if (mapUnits === "m") { - // info : 1 pixel = 0.00028 m - if (layerInfo.MinScaleDenominator) { - layerTileOptions.minResolution = layerInfo.MinScaleDenominator * 0.00028; - } - if (layerInfo.MaxScaleDenominator) { - layerTileOptions.maxResolution = layerInfo.MaxScaleDenominator * 0.00028; - } - } else if (mapUnits === "degrees") { - // info : 6378137 * 2 * pi / 360 = rayon de la terre (ellipsoide WGS84) - var cste = 0.00028 * 180 / (Math.PI * 6378137); - if (layerInfo.MinScaleDenominator) { - layerTileOptions.minResolution = layerInfo.MinScaleDenominator * cste; - } - if (layerInfo.MaxScaleDenominator) { - layerTileOptions.maxResolution = layerInfo.MaxScaleDenominator * cste; - } - } - } - - /** - * this method is called by this._addGetCapWMSLayer - * and sets extent for WMS layer in map projection (if available in getCapabilities response) - * - * @param {Object} layerInfo - layer information from getCapabilities response - * @param {String} mapProjCode - map projection code (e.g. "EPSG:4326") - * @param {Object} layerTileOptions - options for ol.layer.Tile (to be filled) - * @private - */ - _getWMSLayerExtent (layerInfo, mapProjCode, layerTileOptions) { - if (!layerInfo) { - logger.warn("[ol.control.LayerImport] _getWMSLayerExtent error : layerInfo is not defined"); - return; - } - - // récupération des 2 propriétés qui peuvent spécifier l'étendue (bbox) selon les specs OGC WMS 1.3.0 : - // 1. layerInfo.EX_GeographicBoundingBox est un tableau de type [westBoundLongitude, southBoundLatitude, eastBoundLongitude, northBoundLatitude] en WGS84 - var exGeographicBoundingBox = layerInfo["EX_GeographicBoundingBox"]; - // 2. layerInfo.BoundingBox est un tableau dont chaque élément est un objet (balise bbox) avec les propriétés suivantes : - // crs (String) et extent (tableau de type [minx, miny, maxx, maxy]) - var boundingBox = layerInfo.BoundingBox; - - if (exGeographicBoundingBox && Array.isArray(exGeographicBoundingBox)) { - if (mapProjCode === "EPSG:4326") { - // si la projection de la carte est la même que celle de l'extent (EPSG:4326), on la passe telle quelle - layerTileOptions.extent = exGeographicBoundingBox; - } else { - layerTileOptions.extent = olTransformExtentProj(exGeographicBoundingBox, "EPSG:4326", mapProjCode); - } - - // si jamais EX_GeographicBoundingBox n'est pas ou est mal renseigné, on essaie de récupérer via le paramètre BoundingBox - } else if (boundingBox && Array.isArray(boundingBox)) { - var crs; - var extent; - for (var i = 0; i < boundingBox.length; i++) { // on peut avoir plusieurs BoundingBox - crs = boundingBox[i].crs; - extent = boundingBox[i].extent; - if (crs) { - if (crs === mapProjCode) { - // si la bbox est dans la projection de la carte, on la passe telle quelle - layerTileOptions.extent = extent; - break; - } else { - if (typeof crs === "string") { - var olProj = olGetProj(crs) ? olGetProj(crs) : olGetProj(crs.toUpperCase()); - // if ( olGetProj(crs) || olGetProj(crs.toUpperCase()) ) { - if (olProj) { - // si la bbox est dans une projection connue, on va la reprojeter - // tout d'abord, on gère le cas des systèmes EPSG géographiques : inversion des axes x et y - if (olProj.getUnits() === "degrees" && crs.toUpperCase().indexOf("EPSG") === 0) { - // le tableau extent est inversé, on a besoin de : [miny, minx, maxx, maxy] - var reversedExtent = [extent[1], extent[0], extent[3], extent[2]]; - layerTileOptions.extent = olTransformExtentProj(reversedExtent, olProj, mapProjCode); - } else { - // reprojection dans la projection de la carte - layerTileOptions.extent = olTransformExtentProj(extent, olProj, mapProjCode); - } - break; - } - } - } - } - } - } - } - - /** - * this method is called by this._addGetCapWMSLayer - * and sets more information about layer (legends, title, description, metadata, originators) for layerSwitcher or attributions controls - * - * @param {Object} layerInfo - layer information from getCapabilities response - * @param {String} legend - legend url - * @param {Object} wmsSource - options for ol.source.TileWMS (to be filled) - * @private - */ - _getWMSLayerInfoForLayerSwitcher (layerInfo, legend, wmsSource) { - // ajout des informations pour le layerSwitcher (titre, description) - if (layerInfo.Title) { - wmsSource._title = layerInfo.Title; - wmsSource._description = layerInfo.Abstract ? layerInfo.Abstract : layerInfo.Title; - } else { - wmsSource._title = layerInfo.Name; - wmsSource._description = layerInfo.Abstract ? layerInfo.Abstract : layerInfo.Name; - } - // ajout de légende si on en a trouvé - if (legend) { - wmsSource._legends = [{ - url : legend - }]; - } - // ajout d'éventuelles métadonnées - if (layerInfo.MetadataURL && Array.isArray(layerInfo.MetadataURL)) { - wmsSource._metadata = []; - for (var i = 0; i < layerInfo.MetadataURL.length; i++) { - var metadata = layerInfo.MetadataURL[i].OnlineResource; - if (metadata) { - wmsSource._metadata.push({ - url : metadata - }); - } - } - } - // ajout d'éventuelles attributions / originators - if (layerInfo.Attribution) { - var attribution = layerInfo.Attribution; - wmsSource._originators = {}; - if (attribution.OnlineResource) { - wmsSource._originators.url = attribution.OnlineResource; - } - if (attribution.Title) { - wmsSource._originators.name = wmsSource._originators.attribution = attribution.Title; - } - if (attribution.LogoURL && attribution.LogoURL.OnlineResource) { - wmsSource._originators.logo = attribution.LogoURL.OnlineResource; - } - } - } - - // ################################################################### // - // ######### create WMTS layer from getCapabilities response ######### // - // ################################################################### // - - /** - * this method is called by this._onGetCapResponseLayerClick - * and add WMTS layer to map using parameters from getCapabilities response - * - * @param {Object} layerInfo - layer information from getCapabilities response - * @private - */ - _addGetCapWMTSLayer (layerInfo) { - if (!layerInfo || !layerInfo.Identifier) { - logger.warn("[ol.control.LayerImport] layer information not found in getCapabilities response for layer "); - return; - } - - var map = this.getMap(); - if (!map) { - return; - } - - var wmtsSourceOptions = {}; - wmtsSourceOptions.layer = layerInfo.Identifier; - // service version - if (this._getCapResponseWMTS.version) { - wmtsSourceOptions.version = this._getCapResponseWMTS.version; - } - // Récupération de l'url - var getMapUrl = this._getWMTSLayerGetTileUrl(); - // on essaie de récupérer l'url du service dans le getCapbilities - if (getMapUrl) { - wmtsSourceOptions.url = getMapUrl; - } else { - // sinon, on récupère l'url du getCapabilities, à laquelle on enlève éventuellement les paramètres - var questionMarkIndex = this._getCapRequestUrl.indexOf("?"); - if (questionMarkIndex !== -1) { - wmtsSourceOptions.url = this._getCapRequestUrl.substring(0, questionMarkIndex); - } else { - wmtsSourceOptions.url = this._getCapRequestUrl; - } - } - - // Récupération des informations de la pyramide (tileGrid information) : matrixIds, resolutions, origin et projection - var tmsOptions = this._getTMSParams(layerInfo); - wmtsSourceOptions.matrixSet = tmsOptions.tms; - wmtsSourceOptions.projection = tmsOptions.projCode; - wmtsSourceOptions.tileGrid = new WMTSTileGrid({ - resolutions : tmsOptions.resolutions, - matrixIds : tmsOptions.matrixIds, - origin : tmsOptions.origin - }); - - // Récupération du style par défaut - var defaultStyle; - var legend; - if (layerInfo.Style && Array.isArray(layerInfo.Style)) { - var style; - for (var s = 0; s < layerInfo.Style.length; s++) { - style = layerInfo.Style[s]; - // on récupère le style - defaultStyle = style.Identifier; - if (style.isDefault) { - // si c'est celui par défaut, on le garde (on ne boucle plus sur les autres styles) - break; - } - // et une éventuelle légende - if (style.LegendURL && Array.isArray(style.LegendURL) && style.LegendURL.length !== 0) { - legend = style.LegendURL[0].href; - } - } - } - if (defaultStyle == null) { - logger.warn("[ol.control.LayerImport] style information not found in getCapabilities response for layer " + layerInfo.Identifier); - } - wmtsSourceOptions.style = defaultStyle; - - // Récupération du format (le premier trouvé) - var format; - if (layerInfo.Format && Array.isArray(layerInfo.Format)) { - format = layerInfo.Format[0]; - } - if (format == null) { - logger.warn("[ol.control.LayerImport] format information not found in getCapabilities response for layer " + layerInfo.Identifier); - } - wmtsSourceOptions.format = format; - - // Création de la source (tester un try catch ?) - var wmtsSource = new WMTSSource(wmtsSourceOptions); - - // ajout des informations pour le layerSwitcher (titre, description) - if (layerInfo.Title) { - wmtsSource._title = layerInfo.Title; - wmtsSource._description = layerInfo.Abstract ? layerInfo.Abstract : layerInfo.Title; - } else { - wmtsSource._title = layerInfo.Identifier; - wmtsSource._description = layerInfo.Abstract ? layerInfo.Abstract : layerInfo.Identifier; - } - // ajout d'une éventuelle légende - if (legend) { - wmtsSource._legends = [{ - url : legend - }]; - } - - var layerTileOptions = {}; - layerTileOptions.source = wmtsSource; - // récupération de l'étendue (bbox) - layerTileOptions.extent = this._getWMTSLayerExtent(layerInfo); - var wmtsLayer; - try { - wmtsLayer = new TileLayer(layerTileOptions); - } catch (e) { - logger.warn("[ol.control.LayerImport] an error occured while trying to create ol.layer.Tile from getCapabilities information. error : ", e); - return; - } - // on rajoute le champ gpResultLayerId permettant d'identifier une couche crée par le composant. (pour layerSwitcher par ex) - wmtsLayer.gpResultLayerId = "layerimport:WMTS"; - - map.addLayer(wmtsLayer); - } - - /** - * this method is called by this._addGetCapWMTSLayer - * and gets service getTile request url - * - * @return {String} gettileurl - service getTile request url - * @private - */ - _getWMTSLayerGetTileUrl () { - var gettileurl; - if (this._getCapResponseWMTS && this._getCapResponseWMTS.OperationsMetadata && this._getCapResponseWMTS.OperationsMetadata.GetTile) { - var gettile = this._getCapResponseWMTS.OperationsMetadata.GetTile; - if (gettile.DCP && gettile.DCP.HTTP && gettile.DCP.HTTP.Get && Array.isArray(gettile.DCP.HTTP.Get) && gettile.DCP.HTTP.Get.length !== 0) { - gettileurl = gettile.DCP.HTTP.Get[0].href; - } - } - return gettileurl; - } - - /** - * this method is called by this._displayGetCapResponseLayers - * and gets layer TileMatrixSet projection if defined in proj4js - * - * @param {Object} layerInfo - layer information from getCapabilities response - * @param {Object} getCapResponseWMTS - whole getCapabilities response - * @return {String} projection - ol.proj projection alias (e.g. "EPSG:4326") - * @private - */ - _getWMTSLayerProjection (layerInfo, getCapResponseWMTS) { - var projection; - - if (!layerInfo || typeof layerInfo !== "object") { - logger.warn("missing layer information (from getCapabilities)"); - return; - } - - if (!getCapResponseWMTS || typeof getCapResponseWMTS !== "object") { - logger.warn("missing getCapabilities response"); - return; - } - - if (layerInfo.TileMatrixSetLink && Array.isArray(layerInfo.TileMatrixSetLink)) { - var tms = layerInfo.TileMatrixSetLink[0].TileMatrixSet; - var crs; - if (getCapResponseWMTS.Contents && Array.isArray(getCapResponseWMTS.Contents.TileMatrixSet)) { - var tileMatrixSets = getCapResponseWMTS.Contents.TileMatrixSet; - for (var i = 0; i < tileMatrixSets.length; i++) { - if (tileMatrixSets[i].Identifier === tms && tileMatrixSets[i].TileMatrix) { - // on a trouvé le TMS correspondant - var tileMatrixSet = tileMatrixSets[i]; - crs = tileMatrixSet.SupportedCRS; - if (crs && typeof crs === "string") { - if (olGetProj(crs) || olGetProj(crs.toUpperCase())) { - projection = crs; - } - } - break; - } - } - } - }; - - return projection; - } - - /** - * this method is called by this._addGetCapWMTSLayer - * and get ol.tileGrid.WMTS parameters using getCapabilities response - * - * @param {Object} layerInfo - layer information from getCapabilities response - * @return {Object} tmsOptions - ol.tileGrid.WMTS options - * @private - */ - _getTMSParams (layerInfo) { - var tmsOptions = {}; - - var matrixIds = []; - var resolutions = []; - var origin = []; - var tms; - var projCode; - var projection; - - // TODO : recup TOUS les autres params d'un tileGrid ! (tileSize, width...) - - var map = this.getMap(); - if (!map) { - return; - } - - // Récupération des informations de la pyramide (tileGrid information) : matrixIds, resolutions, origin - if (layerInfo.TileMatrixSetLink && Array.isArray(layerInfo.TileMatrixSetLink)) { - tms = layerInfo.TileMatrixSetLink[0].TileMatrixSet; - - if (this._getCapResponseWMTS.Contents && Array.isArray(this._getCapResponseWMTS.Contents.TileMatrixSet)) { - var tileMatrixSets = this._getCapResponseWMTS.Contents.TileMatrixSet; - for (var i = 0; i < tileMatrixSets.length; i++) { - if (tileMatrixSets[i].Identifier === tms && tileMatrixSets[i].TileMatrix) { - // on a trouvé le TMS correspondant - var tileMatrixSet = tileMatrixSets[i]; - - var tilematrix; - var id; - var scaledenominator; - var resolution; - var units; - - if (tileMatrixSet.SupportedCRS) { - projCode = tileMatrixSet.SupportedCRS; - projection = olGetProj(projCode); - } - if (projection && projection.getUnits) { - units = projection.getUnits(); - } - - if (Array.isArray(tileMatrixSet.TileMatrix)) { - for (var j = 0; j < tileMatrixSet.TileMatrix.length; j++) { - // construction du tableau des matrixIds - tilematrix = tileMatrixSet.TileMatrix[j]; - if (tilematrix.Identifier != null) { - id = parseInt(tilematrix.Identifier, 10); - matrixIds.push(id); - } - - // construction du tableau des résolutions, calculées à partir des dénominateurs d'échelle (scaledenominator) - scaledenominator = tilematrix.ScaleDenominator; - // calcul des résolutions selon la projection du TMS : selon si on a des coordonnées planes ou géographiques - if (units === "degrees") { - // info : 6378137 * 2 * pi / 360 = rayon de la terre (ellipsoide WGS84) - resolution = scaledenominator * 0.00028 * 180 / (Math.PI * 6378137); - } else { - // info : 1 pixel = 0.00028 m - resolution = scaledenominator * 0.00028; - } - resolutions.push(resolution); - - origin = tilematrix.TopLeftCorner; - } - } - - // tri des résolutions par ordre décroissant - if (resolutions.sort !== undefined) { - resolutions.sort( - function (x, y) { - return y - x; - } - ); - } - // tri des identifiants des niveaux de pyramide (matrixIds) par ordre croissant - if (matrixIds.sort !== undefined) { - matrixIds.sort( - function (x, y) { - return x - y; - } - ); - } - } - } - } else { - logger.warn("[ol.control.LayerImport] TileMatrixSet data not found in getCapabilities response for layer " + layerInfo.Identifier); - } - } else { - return; - } - - tmsOptions.tms = tms; - tmsOptions.projCode = projCode; - tmsOptions.matrixIds = matrixIds; - tmsOptions.resolutions = resolutions; - tmsOptions.origin = origin; - - return tmsOptions; - } - - /** - * this method is called by this._addGetCapWMTSLayer - * and sets extent for WMTS layer in map projection (if available in getCapabilities response) - * - * @param {Object} layerInfo - layer information from getCapabilities response - * @return {Array} extent - layer extent - * @private - */ - _getWMTSLayerExtent (layerInfo) { - var extent; - var mapProjCode = this._getMapProjectionCode(); - - // récupération de l'étendue (bbox) - if (layerInfo.WGS84BoundingBox && Array.isArray(layerInfo.WGS84BoundingBox)) { - extent = olTransformExtentProj(layerInfo.WGS84BoundingBox, "EPSG:4326", mapProjCode); - } - - return extent; - } - - // ################################################################### // - // ################################ utils ############################ // - // ################################################################### // - - /** - * gets control map projection code - * - * @return {String} mapProjCode - control map projection code (e.g. "EPSG:3857") - * @private - */ - _getMapProjectionCode () { - var map = this.getMap(); - if (!map || !map.getView || !map.getView().getProjection) { - logger.warn("unable to get layerimport's map"); - return; - } - var mapProjCode = map.getView().getProjection().getCode(); - return mapProjCode; - } - - // ################################################################### // - // ################################ clean ############################ // - // ################################################################### // - - /** - * this method displays waiting container and sets a timeout - * - * @private - */ - _displayWaitingContainer () { - this._waitingContainer.className = "GPwaitingContainer GPwaitingContainerVisible gpf-waiting gpf-waiting--visible"; - this._waiting = true; - - // mise en place d'un timeout pour réinitialiser le panel (cacher la patience) - // si on est toujours en attente (si la requête est bloquée par exemple) - if (this._timer) { - clearTimeout(this._timer); - this._timer = null; - } - var context = this; - this._timer = setTimeout(function () { - if (context._waiting === true) { - context._hideWaitingContainer(); - } else { - if (context._timer) { - clearTimeout(context._timer); - } - } - }, 16000); - } - - /** - * this method hides waiting container and clears timeout - * - * @private - */ - _hideWaitingContainer () { - if (this._waiting) { - this._waitingContainer.className = "GPwaitingContainer GPwaitingContainerHidden gpf-waiting gpf-waiting--hidden"; - this._waiting = false; - clearTimeout(this._timer); - this._timer = null; - } - } - - /** - * this method empties getCap results list (DOM element) - * - * @private - */ - cleanGetCapResultsList () { - this._getCapRequestUrl = null; - this._getCapResponseWMS = null; - this._getCapResponseWMTS = null; - this._getCapResponseWMSLayers = null; - this._getCapResponseWMTSLayers = null; - if (this._getCapResultsListContainer) { - while (this._getCapResultsListContainer.firstChild) { - this._getCapResultsListContainer.removeChild(this._getCapResultsListContainer.firstChild); - } - } - } - - /** - * this method empties MapBox results list (DOM element) - * - * @private - */ - cleanMapBoxResultsList () { - this._hasMapBoxResults = false; - if (this._mapBoxResultsListContainer) { - while (this._mapBoxResultsListContainer.firstChild) { - this._mapBoxResultsListContainer.removeChild(this._mapBoxResultsListContainer.firstChild); - } - } - } - - /** - * this method empties MapBox results list (DOM element) - * - * @param {*} id - DOM id - * @private - */ - cleanMapBoxResults (id) { - this._hasMapBoxResults = false; - if (this._mapBoxResultsListContainer) { - var nodes = this._mapBoxResultsListContainer.childNodes; - for (let index = 0; index < nodes.length; index++) { - const element = nodes[index]; - if (element.id === "GPEditorMapBoxContainer_ID_" + id) { - element.remove(); - } - } - } - } - -}; - -// on récupère les méthodes de la classe commune LayerImport -Object.assign(LayerImport.prototype, LayerImportDOM); - -export default LayerImport; - -// Expose LayerImport as ol.control.LayerImport (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.LayerImport = LayerImport; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImportDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImportDOM.d.ts deleted file mode 100644 index 4ef41676c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImportDOM.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -export default LayerImportDOM; -declare namespace LayerImportDOM { - function _addUID(id: string): string; - function _createLoadingElement(): DOMElement; - function _createMainContainerElement(): DOMElement; - function _createShowImportPictoElement(): DOMElement; - function _createImportPanelElement(): DOMElement; - function _createImportPanelDivElement(): HTMLDivElement; - function _createImportPanelHeaderElement(): DOMElement; - function _createImportPanelTitleElement(): DOMElement; - function _createImportPanelCloseElement(): DOMElement; - function _createImportPanelFormElement(): DOMElement; - function _createImportTypeLineElement(importTypes: any[]): DOMElement; - function _createImportWaitingElement(): DOMElement; - function _createImportStaticParamsContainer(currentType: string): DOMElement; - function _createStaticNameLabel(): DOMElement; - function _createStaticModeChoiceDiv(): DOMElement; - function _createStaticLocalChoiceDiv(): DOMElement; - function _createStaticUrlChoiceDiv(): DOMElement; - function _createStaticLocalInputDiv(): DOMElement; - function _createStaticLocalInputLabel(): DOMElement; - function _createStaticLocalInput(): DOMElement; - function _createStaticUrlInputDiv(): DOMElement; - function _createStaticUrlInputLabel(): DOMElement; - function _createStaticUrlInput(): DOMElement; - function _createServiceParamsContainer(currentType: string): DOMElement; - function _createServiceUrlDiv(): DOMElement; - function _createServiceUrlInputLabel(): DOMElement; - function _createServiceUrlInput(): DOMElement; - function _createImportSubmitFormElement(): DOMElement; - function _createImportGetCapPanelElement(): DOMElement; - function _createImportGetCapPanelHeaderElement(): DOMElement; - function _createImportGetCapResultsContainer(): DOMElement; - function _addImportGetCapResultListRubrique(title: any, container: any): any; - function _addImportGetCapResultRubrique(title: any, container: any): any; - function _addImportGetCapResultListLayer(container: any): any; - function _addImportGetCapResultLayer(description: any, id: any, container: any): any; - function _createImportMapBoxPanelElement(): DOMElement; - function _createImportMapBoxPanelHeaderElement(): DOMElement; - function _createImportMapBoxResultsContainer(): DOMElement; -} -//# sourceMappingURL=LayerImportDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImportDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImportDOM.d.ts.map deleted file mode 100644 index 77ee781f9..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImportDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"LayerImportDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/LayerImport/LayerImportDOM.js"],"names":[],"mappings":";;IASc,qCAGT;IAOuB,6CAKvB;IAO6B,mDAK7B;IAY+B,qDA2B/B;IAW2B,iDAM3B;IAE8B,wDAI9B;IAOiC,uDAIjC;IAOgC,sDAMhC;IAOgC,sDA2BhC;IAY+B,qDAsB/B;IAQ8B,sEAuE9B;IAO6B,mDAW7B;IAWoC,6EAUpC;IAOwB,8CAkBxB;IAO4B,kDAK5B;IAO6B,mDAmC7B;IAO2B,iDAmC3B;IAO4B,kDAK5B;IAO8B,oDAO9B;IAOyB,+CAMzB;IAO0B,gDAK1B;IAO4B,kDAO5B;IAOuB,6CAMvB;IAW+B,wEAU/B;IAOsB,4CAItB;IAO6B,mDAO7B;IAOwB,8CAMxB;IAWgC,sDAQhC;IAWiC,uDAKjC;IAOuC,6DAmCvC;IAOqC,2DAMrC;IAEoC,6EAOpC;IAEgC,yEAqBhC;IAEiC,8DAMjC;IAE6B,qFAoB7B;IAWiC,uDAKjC;IAOuC,6DAqDvC;IAOqC,2DAKrC"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImportDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImportDOM.js deleted file mode 100644 index 1fc498a86..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerImport/LayerImportDOM.js +++ /dev/null @@ -1,1057 +0,0 @@ -import SelectorID from "../../Utils/SelectorID"; - -var LayerImportDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Map loading - * - * @returns {DOMElement} container - */ - _createLoadingElement : function () { - var div = document.createElement("div"); - div.id = "GPmapLoading"; - div.className = ""; - return div; - }, - - /** - * Main container (DOM) - * - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPimport"); - container.className = "GPwidget gpf-widget gpf-widget-button"; - return container; - }, - - // ################################################################### // - // ######################### show widget ############################# // - // ################################################################### // - - - /** - * Show Import - * - * @returns {DOMElement} DOM element - */ - _createShowImportPictoElement : function () { - // contexte d'execution - var self = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowImportPicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto GPshowImportPicto gpf-btn gpf-btn-icon gpf-btn-icon-import fr-btn"; - button.title = "Ouvrir l'import de couches"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // Close all results and panels when minimizing the widget - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self._onShowImportClick(); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self._onShowImportClick(); - }); - } - - return button; - }, - - // ################################################################### // - // ################################ Panel ############################ // - // ################################################################### // - - /** - * Create Container Panel - * - * @returns {DOMElement} DOM element - */ - _createImportPanelElement : function () { - var dialog = document.createElement("dialog"); - dialog.id = this._addUID("GPimportPanel"); - dialog.className = "GPpanel gpf-panel fr-modal"; - - return dialog; - }, - - _createImportPanelDivElement : function () { - var div = document.createElement("div"); - div.className = "gpf-panel__body fr-modal__body"; - return div; - }, - - /** - * Create Header Panel - * - * @returns {DOMElement} DOM element - */ - _createImportPanelHeaderElement : function () { - var container = document.createElement("div"); - container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; - return container; - }, - - /** - * Create Header Title Panel - * - * @returns {DOMElement} DOM element - */ - _createImportPanelTitleElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPimportHeaderTitle"); - div.className = "GPpanelTitle gpf-panel__title fr-modal__title fr-m-1w"; - div.innerHTML = "Import de données"; - return div; - }, - - /** - * Create Header close div - * - * @returns {DOMElement} DOM element - */ - _createImportPanelCloseElement : function () { - // contexte - var self = this; - - var divClose = document.createElement("button"); - divClose.id = this._addUID("GPimportPanelClose"); - divClose.className = "GPpanelClose GPimportPanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--secondary fr-m-1w"; - divClose.title = "Fermer le panneau"; - - // Link panel close / visibility checkbox - if (divClose.addEventListener) { - divClose.addEventListener("click", function () { - document.getElementById(self._addUID("GPshowImportPicto")).click(); - }, false); - } else if (divClose.attachEvent) { - divClose.attachEvent("onclick", function () { - document.getElementById(self._addUID("GPshowImportPicto")).click(); - }); - } - - var span = document.createElement("span"); - span.className = "GPelementHidden gpf-visible"; // afficher en dsfr - span.innerText = "Fermer"; - - divClose.appendChild(span); - - return divClose; - }, - - // ################################################################### // - // ########################### Form panel ############################ // - // ################################################################### // - - /** - * Create Form - * see event ! - * - * @returns {DOMElement} DOM element - */ - _createImportPanelFormElement : function () { - // contexte d'execution - var self = this; - - var form = document.createElement("form"); - form.id = this._addUID("GPimportForm"); - form.className = "GPform gpf-panel__content fr-modal__content"; - - // TODO ? - if (form.addEventListener) { - form.addEventListener("submit", function (e) { - e.preventDefault(); - self._onImportSubmit(); - }); - } else if (form.attachEvent) { - form.attachEvent("onsubmit", function (e) { - e.preventDefault(); - self._onImportSubmit(); - }); - } - - return form; - }, - - /** - * Create Container for import type choice - * - * @param {Array} importTypes - import types to be displayed (and used) - * @returns {DOMElement} DOM element - */ - _createImportTypeLineElement : function (importTypes) { - // contexte d'execution - var context = this; - - var div = document.createElement("div"); - div.id = this._addUID("GPimportTypeLine"); - div.className = "GPimportInputLine"; - - var label = document.createElement("label"); - label.id = this._addUID("GPimportTypeLabel"); - label.className = "GPlabel gpf-label fr-label"; - label.innerHTML = "Type de donnée"; - label.title = "Type de donnée"; - div.appendChild(label); - - var select = document.createElement("select"); - select.setAttribute("aria-labelledby", this._addUID("GPimportTypeLabel")); - select.className = "GPselect gpf-select fr-select"; - // gestionnaire d'evenement : on stocke la valeur du type d'import - if (select.addEventListener) { - select.addEventListener("change", function (e) { - if (this.value === "KML" || this.value === "GPX" || this.value === "GeoJSON" || this.value === "MAPBOX") { - // static import - document.getElementById(context._addUID("GPimportStaticParams")).className = "GPelementVisible gpf-visible fr-my-4w"; - document.getElementById(context._addUID("GPimportServiceParams")).className = "GPelementHidden gpf-hidden"; - } else if (this.value === "WMS" || this.value === "WMTS" || this.value === "WFS") { - // service import - document.getElementById(context._addUID("GPimportServiceParams")).className = "GPelementVisible gpf-visible fr-my-4w"; - document.getElementById(context._addUID("GPimportStaticParams")).className = "GPelementHidden gpf-hidden"; - } - context._onImportTypeChange(e); - }); - } else if (select.attachEvent) { - select.attachEvent("onchange", function () { - if (this.value === "KML" || this.value === "GPX" || this.value === "GeoJSON" || this.value === "MAPBOX") { - // static import - document.getElementById(context._addUID("GPimportStaticParams")).className = "GPelementVisible gpf-visible fr-my-4w"; - document.getElementById(context._addUID("GPimportServiceParams")).className = "GPelementHidden gpf-hidden"; - } else if (this.value === "WMS" || this.value === "WMTS" || this.value === "WFS") { - // service import - document.getElementById(context._addUID("GPimportServiceParams")).className = "GPelementVisible gpf-visible fr-my-4w"; - document.getElementById(context._addUID("GPimportStaticParams")).className = "GPelementHidden gpf-hidden"; - } - context._onImportTypeChange(); - }); - } - select.id = this._addUID("GPimportTypeSelect"); - - // on prend soit les valeurs passées par l'utilisateur, soit des valeurs par défaut - if (!importTypes || !Array.isArray(importTypes)) { - importTypes = [ - "KML", - "GPX", - "GeoJSON", - "MAPBOX", - "WMS", - "WMTS", - "WFS" - ]; - } - var option; - for (var i = 0; i < importTypes.length; i++) { - option = document.createElement("option"); - option.value = importTypes[i]; - option.text = (importTypes[i] === "MAPBOX") ? "Tuiles vectorielles" : importTypes[i]; - select.appendChild(option); - } - - div.appendChild(select); - - return div; - }, - - /** - * Create Waiting Panel - * - * @returns {DOMElement} DOM element - */ - _createImportWaitingElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPimportWaitingContainer"); - div.className = "GPwaitingContainer GPwaitingContainerHidden gpf-waiting gpf-waiting--hidden"; - - var p = document.createElement("p"); - p.className = "GPwaitingContainerInfo gpf-waiting_info"; - p.innerHTML = "Recherche en cours..."; - div.appendChild(p); - - return div; - }, - - // ################################################################### // - // ##### Params for static import (KML / GPX / GeoJSON) ############## // - // ################################################################### // - - /** - * Create container for KML/GPX/GeoJSON parameters - * @param {String} currentType - GeoJSON, GPX or KML value - * @returns {DOMElement} DOM element - */ - _createImportStaticParamsContainer : function (currentType) { - var div = document.createElement("div"); - div.id = this._addUID("GPimportStaticParams"); - if (currentType === "KML" || currentType === "GPX" || currentType === "GeoJSON" || currentType === "MAPBOX") { - div.className = "GPelementVisible gpf-visible fr-my-4w"; - } else { - div.className = "GPelementHidden gpf-hidden"; - } - - return div; - }, - - /** - * Create name label for KML/GPX/GeoJSON parameters - * - * @returns {DOMElement} DOM element - */ - _createStaticNameLabel : function () { - var div = document.createElement("div"); - div.className = "GPimportInputLine fr-mb-1w"; - - var label = document.createElement("label"); - label.className = "GPlabel gpf-label fr-label"; - label.htmlFor = this._addUID("GPimportName"); - label.innerHTML = "Nom"; - label.title = "Nom"; - div.appendChild(label); - - var input = document.createElement("input"); - input.type = "text"; - input.id = this._addUID("GPimportName"); - input.className = "GPinput gpf-input fr-input"; - div.appendChild(input); - - return div; - }, - - /** - * Create import choice for KML/GPX/GeoJSON parameters (local or url) - * - * @returns {DOMElement} DOM element - */ - _createStaticModeChoiceDiv : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPimportChoice"); - div.className = "fr-my-1w"; - return div; - }, - - /** - * Create local import choice for KML/GPX/GeoJSON parameters - * - * @returns {DOMElement} DOM element - */ - _createStaticLocalChoiceDiv : function () { - var context = this; - - var div = document.createElement("div"); - div.className = "GPimportChoiceAlt gpf-radio-group fr-radio-group"; - - var input = document.createElement("input"); - input.type = "radio"; - if (input.addEventListener) { - input.addEventListener("change", function (e) { - document.getElementById(context._addUID("GPimportValueLocal")).className = "GPimportInputLine fr-mb-1w"; - document.getElementById(context._addUID("GPimportValueUrl")).className = "GPelementHidden gpf-hidden"; - context._onStaticImportTypeChange(e); - }); - } else if (input.appendChild) { - input.appendChild("onchange", function () { - document.getElementById(context._addUID("GPimportValueLocal")).className = "GPimportInputLine fr-mb-1w"; - document.getElementById(context._addUID("GPimportValueUrl")).className = "GPelementHidden gpf-hidden"; - context._onStaticImportTypeChange(); - }); - } - input.name = "GPimportChoiceMode"; - input.value = "local"; - input.checked = true; - input.id = this._addUID("GPimportChoiceAltLocal"); - div.appendChild(input); - - var label = document.createElement("label"); - label.className = "GPimportChoiceAltTxt gpf-label fr-label"; - label.htmlFor = this._addUID("GPimportChoiceAltLocal"); - label.innerHTML = "par fichier local"; - label.title = "par fichier local"; - div.appendChild(label); - - return div; - }, - - /** - * Create url import choice for KML/GPX/GeoJSON parameters - * - * @returns {DOMElement} DOM element - */ - _createStaticUrlChoiceDiv : function () { - var context = this; - - var div = document.createElement("div"); - div.className = "GPimportChoiceAlt gpf-radio-group fr-radio-group"; - - var input = document.createElement("input"); - input.type = "radio"; - if (input.addEventListener) { - input.addEventListener("change", function (e) { - document.getElementById(context._addUID("GPimportValueUrl")).className = "GPimportInputLine"; - document.getElementById(context._addUID("GPimportValueLocal")).className = "GPelementHidden gpf-hidden"; - context._onStaticImportTypeChange(e); - }); - } else if (input.appendChild) { - input.appendChild("onchange", function () { - document.getElementById(context._addUID("GPimportValueUrl")).className = "GPimportInputLine"; - document.getElementById(context._addUID("GPimportValueLocal")).className = "GPelementHidden gpf-hidden"; - context._onStaticImportTypeChange(); - }); - } - input.id = this._addUID("GPimportChoiceAltUrl"); - input.name = "GPimportChoiceMode"; - input.value = "url"; - input.checked = false; - div.appendChild(input); - - var label = document.createElement("label"); - label.className = "GPimportChoiceAltTxt gpf-label fr-label"; - label.htmlFor = this._addUID("GPimportChoiceAltUrl"); - label.innerHTML = "par URL"; - label.title = "par URL"; - div.appendChild(label); - - return div; - }, - - /** - * Create input div for KML/GPX/GeoJSON parameters local import - * - * @returns {DOMElement} DOM element - */ - _createStaticLocalInputDiv : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPimportValueLocal"); - div.className = "GPimportInputLine"; - return div; - }, - - /** - * Create input label for KML/GPX/GeoJSON parameters local import - * - * @returns {DOMElement} DOM element - */ - _createStaticLocalInputLabel : function () { - var label = document.createElement("label"); - label.className = "GPlabel gpf-label fr-label fr-mb-1w"; - label.htmlFor = this._addUID("GPimportFile"); - label.innerHTML = "Fichier local"; - label.title = "Fichier local"; - return label; - }, - - /** - * Create file input for KML/GPX/GeoJSON parameters local import - * - * @returns {DOMElement} DOM element - */ - _createStaticLocalInput : function () { - var input = document.createElement("input"); - input.type = "file"; - input.id = this._addUID("GPimportFile"); - input.className = "GPimportInputFile gpf-upload fr-upload"; - return input; - }, - - /** - * Create input div for KML/GPX/GeoJSON parameters url import - * - * @returns {DOMElement} DOM element - */ - _createStaticUrlInputDiv : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPimportValueUrl"); - div.className = "GPelementHidden gpf-hidden"; - return div; - }, - - /** - * Create input label for KML/GPX/GeoJSON parameters url import - * - * @returns {DOMElement} DOM element - */ - _createStaticUrlInputLabel : function () { - var label = document.createElement("label"); - label.className = "GPlabel gpf-label fr-label"; - label.htmlFor = this._addUID("GPimportUrl"); - label.innerHTML = "URL"; - label.title = "URL"; - return label; - }, - - /** - * Create url input for KML/GPX/GeoJSON parameters url import - * - * @returns {DOMElement} DOM element - */ - _createStaticUrlInput : function () { - var input = document.createElement("input"); - input.type = "text"; - input.id = this._addUID("GPimportUrl"); - input.className = "GPinput gpf-input fr-input"; - return input; - }, - - // ################################################################### // - // ######## Params for service params import (WMS//WMTS/WFS) ######### // - // ################################################################### // - - /** - * Create container for WMS/WMTS/WFS parameters - * @param {String} currentType - WMS, WMTS or WFS value - * @returns {DOMElement} DOM element - */ - _createServiceParamsContainer : function (currentType) { - var div = document.createElement("div"); - div.id = this._addUID("GPimportServiceParams"); - if (currentType === "WMS" || currentType === "WMTS" || currentType === "WFS") { - div.className = "GPelementVisible gpf-visible"; - } else { - div.className = "GPelementHidden gpf-hidden"; - } - - return div; - }, - - /** - * Create div for WMS/WMTS/WFS url - * - * @returns {DOMElement} DOM element - */ - _createServiceUrlDiv : function () { - var div = document.createElement("div"); - div.className = "GPimportInputLine"; - return div; - }, - - /** - * Create input label for WMS/WMTS/WFS url - * - * @returns {DOMElement} DOM element - */ - _createServiceUrlInputLabel : function () { - var label = document.createElement("label"); - label.className = "GPlabel gpf-label fr-label"; - label.htmlFor = this._addUID("GPimportServiceUrl"); - label.innerHTML = "URL du service"; - label.title = "URL du service"; - return label; - }, - - /** - * Create input for WMS/WMTS/WFS parameters url - * - * @returns {DOMElement} DOM element - */ - _createServiceUrlInput : function () { - var input = document.createElement("input"); - input.type = "text"; - input.id = this._addUID("GPimportServiceUrl"); - input.className = "GPinput gpf-input fr-input"; - return input; - }, - - // ################################################################### // - // ########################### Submit Form ########################### // - // ################################################################### // - - /** - * Create Submit Form Element - * - * @returns {DOMElement} DOM element - */ - _createImportSubmitFormElement : function () { - var input = document.createElement("input"); - input.id = this._addUID("GPimportSubmit"); - input.className = "GPsubmit gpf-btn fr-btn fr-btn--secondary"; - input.type = "submit"; - input.value = "Importer"; - - return input; - }, - - // ################################################################### // - // ########################### GetCap Panel ########################## // - // ################################################################### // - - /** - * Create GetCap Panel Element - * - * @returns {DOMElement} DOM element - */ - _createImportGetCapPanelElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPimportGetCapPanel"); - div.className = "GPpanel gpf-panel fr-modal"; - return div; - }, - - /** - * Create GetCap Panel Header Element - * - * @returns {DOMElement} DOM element - */ - _createImportGetCapPanelHeaderElement : function () { - // contexte - var context = this; - - var container = document.createElement("div"); - container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; - - // panel title - var panelTitle = document.createElement("div"); - panelTitle.className = "GPpanelTitle gpf-panel__title fr-modal__title"; - panelTitle.innerHTML = "Couches accessibles"; - panelTitle.title = "Couches accessibles"; - container.appendChild(panelTitle); - - // close picto - var closeDiv = document.createElement("button"); - closeDiv.className = "GPpanelClose GPimportGetCapPanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--secondary fr-m-1w"; - closeDiv.title = "Fermer le panneau"; - closeDiv.id = this._addUID("GPimportGetCapPanelClose"); - if (closeDiv.addEventListener) { - closeDiv.addEventListener("click", function () { - document.getElementById(context._addUID("GPshowImportPicto")).click(); - document.getElementById(context._addUID("GPimportGetCapPanel")).style.display = "none"; - context._onGetCapPanelClose(); - }); - } else if (closeDiv.attachEvent) { - closeDiv.attachEvent("click", function () { - document.getElementById(context._addUID("GPshowImportPicto")).click(); - document.getElementById(context._addUID("GPimportGetCapPanel")).style.display = "none"; - context._onGetCapPanelClose(); - }); - } - container.appendChild(closeDiv); - - return container; - }, - - /** - * Create GetCap Results List Element - * - * @returns {DOMElement} DOM element - */ - _createImportGetCapResultsContainer : function () { - var container = document.createElement("div"); - container.className = "GPimportGetCapRoot gpf-panel__list"; - container.id = this._addUID("GPimportGetCapResults"); - - return container; - }, - - _addImportGetCapResultListRubrique : function (title, container) { - var ul = document.createElement("ul"); - ul.className = "GPimportGetCapListRubrique"; - ul.title = title; - - container.appendChild(ul); - return container; - }, - - _addImportGetCapResultRubrique : function (title, container) { - var li = document.createElement("li"); - li.className = "GPimportGetCapRubrique gpf-panel__items"; - - // input - var input = document.createElement("input"); - input.id = "GPimportGetCapRubrique-" + SelectorID.generate(); - input.className = "GPimportGetCapRubrique"; - input.type = "checkbox"; - li.appendChild(input); - - // label for - var label = document.createElement("label"); - label.className = "GPimportGetCapRubriqueTitle gpf-label fr-btn fr-btn--secondary"; - label.htmlFor = input.id; - label.innerHTML = title; - label.title = title; - li.appendChild(label); - - container.appendChild(li); - return container; - }, - - _addImportGetCapResultListLayer : function (container) { - var ul = document.createElement("ul"); - ul.className = "GPimportGetCapListLayer"; - - container.appendChild(ul); - return container; - }, - - _addImportGetCapResultLayer : function (description, id, container) { - var li = document.createElement("li"); - li.className = "GPimportGetCapProposal gpf-panel__items"; - li.innerHTML = description.content; - li.title = description.title; - li.id = "GPimportGetCapProposal_" + id; - - var context = this; - if (li.addEventListener) { - li.addEventListener("click", function (e) { - context._onGetCapResponseLayerClick(e); - }); - } else if (li.attachEvent) { - li.attachEvent("onclick", function () { - context._onGetCapResponseLayerClick(); - }); - } - - container.appendChild(li); - return container; - }, - - // ################################################################### // - // ########################### MapBox Panel ########################## // - // ################################################################### // - - /** - * Create MapBox Panel Element - * - * @returns {DOMElement} DOM element - */ - _createImportMapBoxPanelElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPimportMapBoxPanel"); - div.className = "GPpanel gpf-panel fr-modal"; - return div; - }, - - /** - * Create MapBox Panel Header Element - * - * @returns {DOMElement} DOM element - */ - _createImportMapBoxPanelHeaderElement : function () { - // contexte - var context = this; - - var container = document.createElement("div"); - container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; - - // return picto - var returnDiv = document.createElement("button"); - returnDiv.id = this._addUID("GPimportMapBoxPanelReturnPicto"); - returnDiv.title = "Masquer le panneau"; - returnDiv.className = "GPreturnPicto GPimportMapBoxPanelReturnPicto gpf-btn gpf-btn-icon-return fr-btn fr-btn--secondary"; - if (returnDiv.addEventListener) { - returnDiv.addEventListener("click", function (e) { - document.getElementById(context._addUID("GPshowImportPicto")).click(); - context._onMapBoxReturnPictoClick(e); - }); - } else if (returnDiv.attachEvent) { - returnDiv.attachEvent("onclick", function (e) { - document.getElementById(context._addUID("GPshowImportPicto")).click(); - context._onMapBoxReturnPictoClick(e); - }); - } - container.appendChild(returnDiv); - - // panel title - var panelTitle = document.createElement("div"); - panelTitle.className = "GPpanelTitle gpf-panel__title fr-modal__title"; - panelTitle.innerHTML = "Edition des styles"; - panelTitle.title = "Edition des styles"; - container.appendChild(panelTitle); - - // close picto - var closeDiv = document.createElement("button"); - closeDiv.className = "GPpanelClose GPimportMapBoxPanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--secondary fr-m-1w"; - closeDiv.title = "Fermer le panneau"; - closeDiv.id = this._addUID("GPimportMapBoxPanelClose"); - if (closeDiv.addEventListener) { - closeDiv.addEventListener("click", function () { - document.getElementById(context._addUID("GPshowImportPicto")).click(); - document.getElementById(context._addUID("GPimportMapBoxPanel")).style.display = "none"; - context._onMapBoxPanelClose(); - }); - } else if (closeDiv.attachEvent) { - closeDiv.attachEvent("click", function () { - document.getElementById(context._addUID("GPshowImportPicto")).click(); - document.getElementById(context._addUID("GPimportMapBoxPanel")).style.display = "none"; - context._onMapBoxPanelClose(); - }); - } - container.appendChild(closeDiv); - - return container; - }, - - /** - * Create MapBox Results List Element - * - * @returns {DOMElement} DOM element - */ - _createImportMapBoxResultsContainer : function () { - var container = document.createElement("div"); - container.className = "GPimportMapBoxpRoot"; - container.id = this._addUID("GPimportMapBoxResults"); - return container; - } - - // _addImportMapBoxResultListSource : function (id, source, container) { - // var ul = document.createElement("ul"); - // ul.className = "GPimportMapBoxListSource"; - // ul.title = id; - // - // var label = document.createElement("label"); - // label.className = "GPimportMapBoxListSourceTitle"; - // label.innerHTML = "Listes des couches pour la source '" + id + "' :"; - // label.title = source.attribution || id; - // ul.appendChild(label); - // - // container.appendChild(ul); - // return container; - // }, - // - // _addImportMapBoxResultSource : function (layer, container) { - // var li = document.createElement("li"); - // li.className = "GPimportMapBoxSource"; - // - // // input - // var input = document.createElement("input"); - // input.id = "GPimportMapBoxSource-" + SelectorID.generate(); - // input.className = "GPimportMapBoxSource"; - // input.type = "checkbox"; - // li.appendChild(input); - // - // // label for - // var name = layer["source-layer"] || layer.id || layer.source; - // var label = document.createElement("label"); - // label.className = "GPimportMapBoxSourceTitle"; - // label.htmlFor = input.id; - // label.innerHTML = name; - // label.title = JSON.stringify(layer.metadata) || name; - // li.appendChild(label); - // - // container.appendChild(li); - // return container; - // }, - // - // _addImportMapBoxStyleSource : function (layer, container) { - // // contexte - // var self = this; - // - // var _style = false; - // var _obj = {}; - // var _layer = JSON.parse(JSON.stringify(layer)); // on utilise une copie ! - // if (_layer.paint && Object.keys(_layer.paint).length) { - // _style = true; - // _obj.paint = _layer.paint; - // } - // - // // pas de style dans paint, on teste dans layout ! - // if (_layer.layout && Object.keys(_layer.layout).length) { - // _style = true; - // _obj.layout = _layer.layout; - // // on supprime visibility à l'affichage uniquement - // // cf. _addImportMapBoxVisibilitySource ! - // if (_layer.layout.visibility) { - // delete _obj.visibility; - // } - // } - // - // function syntaxHighlight (json) { - // json = json.replace(/&/g, "&").replace(//g, ">"); - // return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g, function (match) { - // var cls = "gp-json-number"; - // if (/^"/.test(match)) { - // if (/:$/.test(match)) { - // cls = "gp-json-key"; - // } else { - // cls = "gp-json-string"; - // } - // } else if (/true|false/.test(match)) { - // cls = "gp-json-boolean"; - // } else if (/null/.test(match)) { - // cls = "gp-json-null"; - // } - // return "" + match + ""; - // }); - // } - // - // var div = document.createElement("div"); - // div.className = "GPimportMapBoxSourceStyle"; - // - // if (_style) { - // var strJson = JSON.stringify(_obj, null, 4); - // - // var label = document.createElement("label"); - // label.innerHTML = "JSON Styles :"; - // div.appendChild(label); - // var pre = document.createElement("pre"); - // pre.className = "GPimportMapBoxJsonEdit"; - // pre.innerHTML = syntaxHighlight(strJson); - // if (pre.addEventListener) { - // pre.addEventListener("click", function (e) { - // self._onSwitchStyleEditSourceMapBox(e); - // }); - // } else if (pre.appendChild) { - // pre.appendChild("onclick", function (e) { - // self._onSwitchStyleEditSourceMapBox(e); - // }); - // } - // div.appendChild(pre); - // } - // - // container.appendChild(div); - // return container; - // }, - // - // _addImportMapBoxFilterSource : function (layer, container) { - // // contexte - // var self = this; - // - // var _filter = false; - // // FIXME tag filter est obselete ! - // // on doit utiliser les expressions dans "paint" ou "layout" ! - // if (layer.filter && layer.filter.length) { - // _filter = true; - // } - // - // var div = document.createElement("div"); - // div.className = "GPimportMapBoxSourceFilter"; - // - // if (_filter) { - // var label = document.createElement("label"); - // label.innerHTML = "JSON Filtres :"; - // div.appendChild(label); - // var pre = document.createElement("pre"); - // pre.className = "GPimportMapBoxJsonEdit"; - // pre.innerHTML = JSON.stringify(layer.filter, null, 4); - // if (pre.addEventListener) { - // pre.addEventListener("click", function (e) { - // self._onSwitchFilterEditSourceMapBox(e); - // }); - // } else if (pre.appendChild) { - // pre.appendChild("onclick", function (e) { - // self._onSwitchFilterEditSourceMapBox(e); - // }); - // } - // div.appendChild(pre); - // } - // - // container.appendChild(div); - // return container; - // }, - // - // _addImportMapBoxScaleSource : function (layer, container) { - // // contexte - // var self = this; - // - // var _scaleMin = layer.minzoom || 0; - // var _scaleMax = layer.maxzoom || 21; - // - // var div = document.createElement("div"); - // div.className = "GPimportMapBoxSourceScale"; - // - // var labelMin = document.createElement("label"); - // labelMin.className = "GPimportMapBoxSourceScaleLabel"; - // labelMin.innerHTML = "minZoom :"; - // div.appendChild(labelMin); - // - // var inputMin = document.createElement("input"); - // inputMin.className = "GPimportMapBoxSourceScaleInput"; - // inputMin.type = "range"; - // inputMin.value = _scaleMin; - // inputMin.title = _scaleMin; - // inputMin.disabled = false; - // inputMin.min = 0; - // inputMin.max = 21; - // if (inputMin.addEventListener) { - // inputMin.addEventListener("change", function (e) { - // self._onChangeScaleMinSourceMapBox(e, layer); - // }); - // } else if (inputMin.appendChild) { - // inputMin.appendChild("onchange", function (e) { - // self._onChangeScaleMinSourceMapBox(e, layer); - // }); - // } - // div.appendChild(inputMin); - // - // div.appendChild(document.createElement("br")); - // - // var labelMax = document.createElement("label"); - // labelMax.className = "GPimportMapBoxSourceScaleLabel"; - // labelMax.innerHTML = "maxZoom :"; - // div.appendChild(labelMax); - // - // var inputMax = document.createElement("input"); - // inputMax.className = "GPimportMapBoxSourceScaleInput"; - // inputMax.type = "range"; - // inputMax.value = _scaleMax; - // inputMax.title = _scaleMax; - // inputMax.disabled = false; - // inputMax.min = 0; - // inputMax.max = 21; - // if (inputMax.addEventListener) { - // inputMax.addEventListener("change", function (e) { - // self._onChangeScaleMaxSourceMapBox(e, layer); - // }); - // } else if (inputMax.appendChild) { - // inputMax.appendChild("onchange", function (e) { - // self._onChangeScaleMaxSourceMapBox(e, layer); - // }); - // } - // div.appendChild(inputMax); - // - // container.appendChild(div); - // return container; - // }, - // - // _addImportMapBoxVisibilitySource : function (layer, container) { - // // contexte - // var self = this; - // - // var _visibility = true; - // if (layer.layout && layer.layout.visibility && layer.layout.visibility === "none") { - // _visibility = false; - // } - // - // var div = document.createElement("div"); - // div.className = "GPimportMapBoxSourceVisibility"; - // - // var label = document.createElement("label"); - // label.className = "GPimportMapBoxSourceVisibilityLabel"; - // label.innerHTML = "Visibilité :"; - // div.appendChild(label); - // - // var input = document.createElement("input"); - // input.className = "GPimportMapBoxSourceVisibilityInput"; - // input.type = "checkbox"; - // input.checked = _visibility; - // input.disabled = false; - // if (input.addEventListener) { - // input.addEventListener("change", function (e) { - // self._onChangeVisibilitySourceMapBox(e, layer); - // }); - // } else if (input.appendChild) { - // input.appendChild("onchange", function (e) { - // self._onChangeVisibilitySourceMapBox(e, layer); - // }); - // } - // div.appendChild(input); - // - // container.appendChild(div); - // return container; - // } -}; - -export default LayerImportDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcher.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcher.d.ts deleted file mode 100644 index 3aa865e17..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcher.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -export default LayerSwitcher; -/** - * @classdesc - * OpenLayers Control to manage map layers : their order, visibility and opacity, and display their informations (title, description, legends, metadata...) - * - * @constructor - * @extends {ol.control.Control} - * @alias ol.control.LayerSwitcher - * @type {ol.control.LayerSwitcher} - * @param {Object} options - control options - * @param {Array} [options.layers] - list of layers to be configured. Each array element is an object, with following properties : - * @param {ol.layer.Layer} [options.layers.layer] - ol.layer.Layer layer to be configured (that has been added to map) - * @param {Object} [options.layers.config] - custom configuration object for layer information (title, description, legends, metadata, quicklook url), with following properties : - * @param {String} [options.layers.config.title] - layer alias, to be displayed in widget layer list. E.g. : "Cartes IGN" - * @param {String} [options.layers.config.description] - layer description, to be displayed on title hover, or in layer information panel. - * @param {String} [options.layers.config.quicklookUrl] - link to a quick look image for this layer. - * @param {Array} [options.layers.config.legends] - array of layer legends. Each array element is an object, with following properties : - * - url (String, mandatory) : link to a legend - * - minScaleDenominator (Number, optional) : min scale denominator for legend validity. - * @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. - * @example - * map.addControl(new ol.control.LayerSwitcher( - * [ - * { - * layer : wms1, - * config : { - * title : "test layer name 1", - * description : "test layer desc 1", - * } - * } - * ], - * { - * collapsed : true - * } - * )); - */ -declare var LayerSwitcher: ol.control.LayerSwitcher; -//# sourceMappingURL=LayerSwitcher.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcher.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcher.d.ts.map deleted file mode 100644 index f8938b13b..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcher.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"LayerSwitcher.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/LayerSwitcher/LayerSwitcher.js"],"names":[],"mappings":";AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,oDA+/BE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcher.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcher.js deleted file mode 100644 index e83b6b46b..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcher.js +++ /dev/null @@ -1,1087 +0,0 @@ -// import CSS -import "../../CSS/Controls/LayerSwitcher/GPFlayerSwitcher.css"; -// import "../../CSS/Controls/LayerSwitcher/GPFlayerSwitcherStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -import { unByKey as olObservableUnByKey } from "ol/Observable"; -import { intersects as olIntersects } from "ol/extent"; -// import local -import SelectorID from "../../Utils/SelectorID"; -import Logger from "../../Utils/LoggerByDefault"; -// DOM -import LayerSwitcherDOM from "./LayerSwitcherDOM"; - -var logger = Logger.getLogger("layerswitcher"); - -/** - * @classdesc - * OpenLayers Control to manage map layers : their order, visibility and opacity, and display their informations (title, description, legends, metadata...) - * - * @constructor - * @extends {ol.control.Control} - * @alias ol.control.LayerSwitcher - * @type {ol.control.LayerSwitcher} - * @param {Object} options - control options - * @param {Array} [options.layers] - list of layers to be configured. Each array element is an object, with following properties : - * @param {ol.layer.Layer} [options.layers.layer] - ol.layer.Layer layer to be configured (that has been added to map) - * @param {Object} [options.layers.config] - custom configuration object for layer information (title, description, legends, metadata, quicklook url), with following properties : - * @param {String} [options.layers.config.title] - layer alias, to be displayed in widget layer list. E.g. : "Cartes IGN" - * @param {String} [options.layers.config.description] - layer description, to be displayed on title hover, or in layer information panel. - * @param {String} [options.layers.config.quicklookUrl] - link to a quick look image for this layer. - * @param {Array} [options.layers.config.legends] - array of layer legends. Each array element is an object, with following properties : - * - url (String, mandatory) : link to a legend - * - minScaleDenominator (Number, optional) : min scale denominator for legend validity. - * @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. - * @example - * map.addControl(new ol.control.LayerSwitcher( - * [ - * { - * layer : wms1, - * config : { - * title : "test layer name 1", - * description : "test layer desc 1", - * } - * } - * ], - * { - * collapsed : true - * } - * )); - */ -var LayerSwitcher = class LayerSwitcher extends Control { - - /** - * See {@link ol.control.LayerSwitcher} - * @module LayerSwitcher - * @alias module:~Controls/LayerSwitcher - * @param {*} options - options - * @example - * import LayerSwitcher from "src/OpenLayers/Controls/LayerSwitcher" - */ - constructor (options) { - options = options || {}; - var _options = options.options || {}; - var _layers = options.layers || []; - - // call ol.control.Control constructor - super({ - element : _options.element, - target : _options.target, - render : _options.render - }); - - if (!(this instanceof LayerSwitcher)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - if (!Array.isArray(_layers)) { - throw new Error("ERROR WRONG_TYPE : layers should be an array"); - } - - if (typeof _options !== "object") { - throw new Error("ERROR WRONG_TYPE : options should be an object"); - } - - this._initialize(_options, _layers); - - this.container = this._initContainer(_options); - - // ajout du container - (this.element) ? this.element.appendChild(this.container) : this.element = this.container; - - return this; - } - - // ################################################################### // - // ############## public methods (getters, setters) ################## // - // ################################################################### // - - /** - * Overload setMap function, that enables to catch map events, such as movend events. - * - * @param {ol.Map} map - Map. - */ - setMap (map) { - // info : cette méthode est appelée (entre autres?) après un map.addControl() ou map.removeControl() - - if (map) { // dans le cas de l'ajout du contrôle à la map - // on ajoute les couches - this._addMapLayers(map); - - // At every map movement, layer switcher may be updated, - // according to layers on map, and their range. - this._listeners.onMoveListener = map.on( - "moveend", - () => this._onMapMoveEnd(map) - ); - - // add event listeners when a new layer is added to map, to add it in LayerSwitcher control (and DOM) - this._listeners.onAddListener = map.getLayers().on( - "add", - (evt) => { - var layer = evt.element; - var id; - // on attribue un nouvel identifiant à cette couche, - // sauf si c'est une couche qui a déjà été ajoutée dans le LayerSwitcher au préalable (si gpLayerId existe) - if (!layer.hasOwnProperty("gpLayerId")) { - id = this._layerId; - layer.gpLayerId = id; - this._layerId++; - } else { - id = layer.gpLayerId; - } - if (!this._layers[id]) { - this.addLayer(layer); - } - } - ); - - // add event listeners when a layer is removed from map, to remove it from LayerSwitcher control (and DOM) - this._listeners.onRemoveListener = map.getLayers().on( - "remove", - (evt) => { - var layer = evt.element; - var id = layer.gpLayerId; - if (this._layers[id]) { - this.removeLayer(layer); - } - } - ); - } else { - // we are in a setMap(null) case - // we forget the listeners linked to the layerSwitcher - olObservableUnByKey(this._listeners.onMoveListener); - olObservableUnByKey(this._listeners.onAddListener); - olObservableUnByKey(this._listeners.onRemoveListener); - - // we put all the layers at Zindex = 0, without changing the visual order - // in order that the next added layers are not hidden by layers with Zindex > 0 - for (var i = this._layersOrder.length - 1; i >= 0; i--) { - this._layersOrder[i].layer.setZIndex(0); - } - } - - // on appelle la méthode setMap originale d'OpenLayers - super.setMap(map); - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - } - - /** - * Add a new layer to control (when added to map) or add new layer configuration - * - * @param {ol.layer.Layer} layer - layer to add to layer switcher - * @param {Object} [config] - additional options for layer configuration - * @param {Object} [config.title] - layer title (default is layer identifier) - * @param {Object} [config.description] - layer description (default is null) - * @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) - * @example - * layerSwitcher.addLayer( - * gpParcels, - * { - * title : "Parcelles cadastrales", - * description : "description de la couche", - * quicklookUrl : "http://quicklookUrl.fr" - * } - * ) - */ - addLayer (layer, config) { - var map = this.getMap(); - config = config || {}; - - if (!layer) { - logger.log("[ERROR] LayerSwitcher:addLayer - missing layer parameter"); - return; - } - - var id = layer.gpLayerId; - if (typeof id === "undefined") { - logger.trace("[WARN] LayerSwitcher:addLayer - configuration cannot be set for this layer (layer id not found)", layer); - return; - } - - // make sure layer is in map layers - var isLayerInMap = false; - map.getLayers().forEach( - (lyr) => { - if (lyr.gpLayerId === id) { - isLayerInMap = true; - } - } - ); - if (!isLayerInMap) { - logger.log("[ERROR] LayerSwitcher:addLayer - configuration cannot be set for ", layer, " layer (layer is not in map.getLayers() )"); - return; - } - - // if layer is not already in layers list, add it to control (layers list and container div) - if (!this._layers[id]) { - // 1. add layer to layers list - var layerInfos = this.getLayerInfo(layer) || {}; - var opacity = layer.getOpacity(); - var visibility = layer.getVisible(); - var isInRange = this.isInRange(layer, map); - var layerOptions = { - layer : layer, - id : id, - opacity : opacity != null ? opacity : 1, - visibility : visibility != null ? visibility : true, - inRange : isInRange != null ? isInRange : true, - title : config.title != null ? config.title : (layerInfos._title || id), - description : config.description || layerInfos._description || null, - legends : config.legends || layerInfos._legends || [], - metadata : config.metadata || layerInfos._metadata || [], - quicklookUrl : config.quicklookUrl || layerInfos._quicklookUrl || null - }; - this._layers[id] = layerOptions; - - // 2. create layer div (to be added to control main container) - // Création de la div correspondante à cette couche - var layerDiv = this._createLayerDiv(layerOptions); - // on stocke la div dans les options de la couche, pour une éventuelle réorganisation (setZIndex par ex) - this._layers[id].div = layerDiv; - - // 3. réorganisation des couches si un zIndex est spécifié - // FIXME : - // _forceNullzIndex !? - // getZIndex() retourne undefined au lieu de 0 !? - if ((layer.getZIndex && layer.getZIndex() !== 0 && typeof layer.getZIndex() !== "undefined") || layer._forceNullzIndex) { - // réorganisation des couches si un zIndex est spécifié - this._updateLayersOrder(); - } else { - // sinon on ajoute la couche au dessus des autres - this._layersOrder.unshift(layerOptions); - this._lastZIndex++; - layer.setZIndex(this._lastZIndex); - this._layerListContainer.insertBefore(layerDiv, this._layerListContainer.firstChild); - } - - // 3. Add listeners for opacity and visibility changes - this._listeners.updateLayerOpacity = layer.on( - "change:opacity", - (e) => this._updateLayerOpacity(e) - ); - this._listeners.updateLayerVisibility = layer.on( - "change:visible", - (e) => this._updateLayerVisibility(e) - ); - - if (this._layers[id].onZIndexChangeEvent == null) { - this._layers[id].onZIndexChangeEvent = layer.on( - "change:zIndex", - () => this._updateLayersOrder() - ); - } - - // user may also add a new configuration for an already added layer - } else { - // add new configuration parameters to layer informations - for (var prop in config) { - if (config.hasOwnProperty(prop)) { - this._layers[id][prop] = config[prop]; - } - } - // set new title in layer div - if (config.title) { - var nameDiv = document.getElementById(this._addUID("GPname_ID_" + id)); - if (nameDiv) { - nameDiv.innerHTML = config.title; - nameDiv.title = config.description || config.title; - } - } - // add layer info picto if necessary - var infodiv = document.getElementById(this._addUID("GPinfo_ID_" + id)); - if (!document.getElementById(this._addUID("GPinfo_ID_" + id)) && config.description) { - var advancedTools = document.getElementById(this._addUID("GPadvancedTools_ID_" + id)); - if (advancedTools) { - advancedTools.appendChild( - this._createAdvancedToolInformationElement({ - id : id - }) - ); - } - } - // close layer info element if open, to update information. - if (infodiv && infodiv.className === "GPlayerInfoOpened") { - document.getElementById(this._addUID("GPlayerInfoPanel")).className = "GPlayerInfoPanelClosed"; - infodiv.className = "GPlayerInfo"; - } - } - }; - - /** - * Remove a layer from control - * - * @param {ol.layer.Layer} layer - layer. - * @deprecated on the future version ... - */ - removeLayer (layer) { - if (!layer) { - return; - } - - olObservableUnByKey(this._listeners.updateLayerOpacity); - olObservableUnByKey(this._listeners.updateLayerVisibility); - // olObservableUnByKey(this._listeners.updateLayersOrder); - - logger.trace(layer); - - var layerID = layer.gpLayerId; - var layerList = document.getElementById(this._addUID("GPlayersList")).firstChild; - // 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"; - } - // remove layer div - var layerDiv = document.getElementById(this._addUID("GPlayerSwitcher_ID_" + layerID)); - if (layerDiv) { - layerList.removeChild(layerDiv); - } - - var layerIndex = Math.abs(layer.getZIndex() - this._lastZIndex); - // on retire la couche de la liste ordonnée des layers - this._layersOrder.splice(layerIndex, 1); - this._lastZIndex--; - // on met à jour les zindex des couches restantes - var layerOrderTemp = this._layersOrder; - for (var i = 0; i < layerOrderTemp.length; i++) { - layerOrderTemp[i].layer.setZIndex(this._lastZIndex - i); - } - // on retire la couche de la liste des layers - delete this._layers[layerID]; - } - - /** - * Collapse or display control main container - * - * @param {Boolean} collapsed - True to collapse control, False to display it - */ - setCollapsed (collapsed) { - if (collapsed === undefined) { - logger.log("[ERROR] LayerSwitcher:setCollapsed - missing collapsed parameter"); - return; - } - var isCollapsed = !document.getElementById(this._addUID("GPshowLayersList")).checked; - if ((collapsed && isCollapsed) || (!collapsed && !isCollapsed)) { - return; - } - // 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"; - } - document.getElementById(this._addUID("GPshowLayersList")).checked = !collapsed; - } - - /** - * Returns true if widget is collapsed (minimize), false otherwise - * @returns {Boolean} is collapsed - */ - getCollapsed () { - return this.collapsed; - } - - /** - * Display or hide removeLayerPicto from layerSwitcher for this layer - * - * @param {ol.layer.Layer} layer - ol.layer to be configured - * @param {Boolean} removable - specify if layer can be remove from layerSwitcher (true) or not (false). Default is true - */ - setRemovable (layer, removable) { - if (!layer) { - return; - } - var layerID = layer.gpLayerId; - if (layerID == null) { // on teste si layerID est null ou undefined - logger.log("[LayerSwitcher:setRemovable] layer should be added to map before calling setRemovable method"); - return; - } - var removalDiv = document.getElementById(this._addUID("GPremove_ID_" + layerID)); - if (removalDiv) { - if (removable === false) { - removalDiv.style.display = "none"; - } else if (removable === true) { - removalDiv.style.display = "block"; - } else { - - } - } - } - - // ################################################################### // - // ##################### init component ############################## // - // ################################################################### // - - /** - * Initialize LayerSwitcher control (called by constructor) - * - * @param {Object} options - ol.control.Control options (see {@link http://openlayers.org/en/latest/apidoc/ol.control.Control.html ol.control.Control}) - * @param {Array} layers - list of layers to be configured. Each array element is an object, with following properties : - * @private - */ - _initialize (options, layers) { - // identifiant du contrôle : utile pour suffixer les identifiants CSS (pour gérer le cas où il y en a plusieurs dans la même page) - this._uid = SelectorID.generate(); - - this.options = options; - this.options.layers = layers; - - // {Object} control layers list. Each key is a layer id, and its value is an object of layers options (layer, id, opacity, visibility, title, description...) - this._layers = {}; - // [Array] array of ordered control layers - this._layersOrder = []; - // [Object] associative array of layers ordered by zindex (keys are zindex values, and corresponding values are arrays of layers at this zindex) - this._layersIndex = {}; - // {Number} layers max z index, to order layers using their z index - this._lastZIndex = 0; - // {Number} layers max id, incremented when a new layer is added - this._layerId = 0; - /** {Boolean} true if widget is collapsed, false otherwise */ - this.collapsed = (options.collapsed !== undefined) ? options.collapsed : true; - // div qui contiendra les div des listes. - this._layerListContainer = null; - // [Object] listeners added to the layerSwitcher saved here in order to delete them if we remove the control from the map) - this._listeners = {}; - - // add options layers to layerlist. - // (seulement les couches configurées dans les options du layerSwitcher par l'utilisateur), - // les autres couches de la carte seront ajoutées dans la méthode setMap - for (var i = 0; i < layers.length; i++) { - // recup la layer, son id, - var layer = layers[i].layer; - if (layer) { - var id; - // 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; - layer.gpLayerId = id; - this._layerId++; - } else { - id = layer.gpLayerId; - } - - // et les infos de la conf si elles existent (title, description, legends, quicklook, metadata) - var conf = layers[i].config || {}; - var opacity = layer.getOpacity(); - var visibility = layer.getVisible(); - var layerOptions = { - layer : layer, // la couche ol.layer concernée - id : id, - opacity : opacity != null ? opacity : 1, - visibility : visibility != null ? visibility : true, - title : conf.title != null ? conf.title : conf.id ? conf.id : id, - description : conf.description || null, - legends : conf.legends || [], - metadata : conf.metadata || [], - quicklookUrl : conf.quicklookUrl || null - }; - this._layers[id] = layerOptions; - } - } - } - - /** - * Create control main container (called by constructor) - * - * @returns {DOMElement} container - control container - * @private - */ - _initContainer () { - // creation du container principal - var container = this._createMainContainerElement(); - - // ajout dans le container principal d'affichage des layers - var input = this._createMainLayersShowElement(); - container.appendChild(input); - - // gestion du mode "collapsed" - if (!this.collapsed) { - input.checked = "checked"; - this.collapsed = false; - } else { - this.collapsed = true; - } - - // on ajoute un écouteur d'évènement sur le bouton (checkbox) de dépliement/repliement des couches, - // pour modifier la propriété this.collapsed quand on clique dessus - var context = this; - // event listener - var changeCollapsed = function (e) { - this.collapsed = !e.target.checked; - // on génère nous même l'evenement OpenLayers de changement de pté - // (utiliser layerSwitcher.on("change:collapsed", function ) pour s'abonner à cet évènement) - this.dispatchEvent("change:collapsed"); - }; - input.addEventListener( - "click", - function (e) { - changeCollapsed.call(context, e); - } - ); - - // ajout dans le container principal du picto du controle - var picto = this._createMainPictoElement(); - container.appendChild(picto); - - // ajout dans le container principal de la liste des layers - var divL = this._createMainLayersElement(); - container.appendChild(divL); - - var div = this._layerListContainer = this._createMainLayersDivElement(); - divL.appendChild(div); - - // creation du mode draggable - this._createDraggableElement(div, this); - - // ajout dans le container principal du panneau d'information - var divI = this._createMainInfoElement(); - container.appendChild(divI); - - return container; - } - - /** - * Add all map layers to control main container - * - * @param {Object} map - ol.Map object, to which control is added - * @private - */ - _addMapLayers (map) { - this._layersIndex = {}; - - // on parcourt toutes les couches de la carte, pour les ajouter à la liste du controle si ce n'est pas déjà le cas. - // 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; - // 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; - layer.gpLayerId = id; - this._layerId++; - } else { - id = layer.gpLayerId; - } - - var layerInfos = this.getLayerInfo(layer) || {}; - if (!this._layers[id]) { - // si la couche n'est pas encore dans la liste des layers (this._layers), on l'ajoute - var opacity = layer.getOpacity(); - var visibility = layer.getVisible(); - var isInRange = this.isInRange(layer, map); - var layerOptions = { - layer : layer, - id : id, - opacity : opacity != null ? opacity : 1, - visibility : visibility != null ? visibility : true, - inRange : isInRange != null ? isInRange : true, - title : layerInfos._title || id, - description : layerInfos._description || null, - legends : layerInfos._legends || [], - metadata : layerInfos._metadata || [], - quicklookUrl : layerInfos._quicklookUrl || null - }; - this._layers[id] = layerOptions; - } else { - // si elle existe déjà, on met à jour ses informations (visibility, opacity, inRange) - this._layers[id].opacity = layer.getOpacity(); - this._layers[id].visibility = layer.getVisible(); - this._layers[id].inRange = this.isInRange(layer, map); - } - - // Ajout de listeners sur les changements d'opacité, visibilité - this._listeners.updateLayerOpacity = layer.on( - "change:opacity", - (e) => this._updateLayerOpacity(e) - ); - this._listeners._updateLayerVisibility = layer.on( - "change:visible", - (e) => this._updateLayerVisibility(e) - ); - - // récupération des zindex des couches s'ils existent, pour les ordonner. - if (layer.getZIndex !== undefined) { - var layerIndex = layer.getZIndex() || 0; // FIXME le zIndex peut être undefined !? donc par defaut à 0 ! - if (!this._layersIndex[layerIndex] || !Array.isArray(this._layersIndex[layerIndex])) { - this._layersIndex[layerIndex] = []; - } - this._layersIndex[layerIndex].push(this._layers[id]); - }; - }); - - // on récupère l'ordre d'affichage des couches entre elles dans la carte, à partir de zindex. - for (var zindex in this._layersIndex) { - if (this._layersIndex.hasOwnProperty(zindex)) { - var layers = this._layersIndex[zindex]; - for (var l = 0; l < layers.length; l++) { // à ce stade layers[l] est une couche de this._layers. - // on conserve l'ordre des couches : la première est celle qui se situe tout en haut, et la dernière est le "fond de carte" - this._layersOrder.unshift(layers[l]); - // et on réordonne les couches avec des zindex, uniques. - this._lastZIndex++; - layers[l].layer.setZIndex(this._lastZIndex); - if (this._layers[layers[l].layer.gpLayerId].onZIndexChangeEvent == null) { - this._layers[layers[l].layer.gpLayerId].onZIndexChangeEvent = layers[l].layer.on( - "change:zIndex", - () => this._updateLayersOrder() - ); - } - } - } - } - - // on ajoute les div correspondantes aux différentes couches (dans l'ordre inverse d'affichage) dans le controle. - for (var j = 0; j < this._layersOrder.length; j++) { - var layerOptions = this._layersOrder[j]; - var layerDiv = this._createLayerDiv(layerOptions); - this._layerListContainer.appendChild(layerDiv); - // on stocke la div dans les options de la couche, pour une éventuelle réorganisation (setZIndex par ex) - this._layers[layerOptions.id].div = layerDiv; - } - } - - /** - * create layer div (to append to control DOM element). - * - * @param {Object} layerOptions - layer options (id, title, description, legends, metadata, quicklookUrl ...) - * - * @returns {DOMElement} DOM element - * - * @private - */ - _createLayerDiv (layerOptions) { - var isLegends = layerOptions.legends && layerOptions.legends.length !== 0; - var isMetadata = layerOptions.metadata && layerOptions.metadata.length !== 0; - var isQuicklookUrl = layerOptions.quicklookUrl; - // on n'affiche les informations que si elles sont renseignées (pour ne pas avoir un panneau vide) - if (isLegends || isMetadata || isQuicklookUrl) { - layerOptions.displayInformationElement = true; - } - - // ajout d'une div pour cette layer dans le control - var layerDiv = this._createContainerLayerElement(layerOptions); - - if (!layerOptions.inRange) { - layerDiv.classList.add("outOfRange"); - } - - return layerDiv; - } - - // ################################################################### // - // ######################### DOM events ############################## // - // ################################################################### // - - /** - * Change layer opacity on layer opacity picto click - * - * @param {Object} e - event - * @private - */ - _onChangeLayerOpacity (e) { - var divId = e.target.id; // ex GPvisibilityPicto_ID_26 - var layerID = SelectorID.index(divId); // ex. 26 - var layer = this._layers[layerID].layer; - - var opacityValue = e.target.value; - var opacityId = document.getElementById(this._addUID("GPopacityValue_ID_" + layerID)); - opacityId.innerHTML = opacityValue + "%"; - - layer.setOpacity(opacityValue / 100); - } - - /** - * Update picto opacity value on layer opacity change - * - * @param {Object} e - event - * @private - */ - _updateLayerOpacity (e) { - var opacity = e.target.getOpacity(); - if (opacity > 1) { - opacity = 1; - } - if (opacity < 0) { - opacity = 0; - } - var id = e.target.gpLayerId; - - var layerOpacityInput = document.getElementById(this._addUID("GPopacityValueDiv_ID_" + id)); - if (layerOpacityInput) { - layerOpacityInput.value = Math.round(opacity * 100); - } - - var layerOpacitySpan = document.getElementById(this._addUID("GPopacityValue_ID_" + id)); - if (layerOpacitySpan) { - layerOpacitySpan.innerHTML = Math.round(opacity * 100) + "%"; - } - } - - /** - * Change layer visibility on layer visibility picto click - * - * @param {Object} e - event - * @private - */ - _onVisibilityLayerClick (e) { - 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); - } - - /** - * Change picto visibility on layer visibility change - * - * @param {Object} e - event - * @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; - } - } - - /** - * Change layers order in layerswitcher (control container) on a layer index change (on map) or when a layer is added to a specific zindex - * - * @private - */ - _updateLayersOrder () { - // info : - // 1. on récupère les zindex et les couches associées dans un tableau associatif (objet) - // 2. on réordonne les couche selon leur index : on leur attribue de nouveaux zindex uniques - // 3. on vide le container des layers, et rajoute les div des couches dans l'ordre décroissant des zindex - - var map = this.getMap(); - if (!map) { - return; - } - this._layersIndex = {}; - var layerIndex; - var id; - - // on parcourt toutes les couches pour récupérer leur ordre : - // on stocke les couches dans un tableau associatif ou les clés sont les zindex, et les valeurs sont des tableaux des couches à ce zindex. - map.getLayers().forEach( - (layer) => { - id = layer.gpLayerId; - - // on commence par désactiver temporairement l'écouteur d'événements sur le changement de zindex. - olObservableUnByKey(this._layers[id].onZIndexChangeEvent); - this._layers[id].onZIndexChangeEvent = null; - - // on ajoute la couche dans le tableau (de l'objet this._layersIndex) correspondant à son zindex - layerIndex = null; - if (layer.getZIndex !== undefined) { - layerIndex = layer.getZIndex(); - if (!this._layersIndex[layerIndex] || !Array.isArray(this._layersIndex[layerIndex])) { - this._layersIndex[layerIndex] = []; - } - this._layersIndex[layerIndex].push(this._layers[id]); - }; - } - ); - - // on réordonne les couches entre elles dans la carte, à partir des zindex stockés ci-dessus. - this._lastZIndex = 0; - this._layersOrder = []; - for (var zindex in this._layersIndex) { - if (this._layersIndex.hasOwnProperty(zindex)) { - var layers = this._layersIndex[zindex]; - for (var l = 0; l < layers.length; l++) { // à ce stade layers[l] est une couche de this._layers. - // on conserve l'ordre des couches : la première est celle qui se situe tout en haut, et la dernière est le "fond de carte" - this._layersOrder.unshift(layers[l]); - // et on réordonne les couches avec des zindex, uniques. - this._lastZIndex++; - // layers[l].layer.setZIndex(lastZIndex); - // et on réactive l'écouteur d'événement sur les zindex - if (this._layers[layers[l].layer.gpLayerId].onZIndexChangeEvent == null) { - this._layers[layers[l].layer.gpLayerId].onZIndexChangeEvent = layers[l].layer.on( - "change:zIndex", - () => this._updateLayersOrder() - ); - } - } - } - } - - if (this._layerListContainer) { - // on vide le container précédent - while (this._layerListContainer.firstChild) { - this._layerListContainer.removeChild(this._layerListContainer.firstChild); - } - // 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++) { - var layerOptions = this._layersOrder[j]; - this._layerListContainer.appendChild(layerOptions.div); - } - } else { - logger.log("[ol.control.LayerSwitcher] _updateLayersOrder : layer list container not found to update layers order ?!"); - } - } - - /** - * Open layer information panel on picto click - * - * @param {Event} e - MouseEvent - * @private - */ - _onOpenLayerInfoClick (e) { - var divId = e.target.id; // ex GPvisibilityPicto_ID_26 - var layerID = SelectorID.index(divId); // 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"); - } - - panel = document.getElementById(this._addUID("GPlayerInfoPanel")); - if (panel.classList !== undefined) { - panel.classList.remove("GPpanel"); - panel.classList.remove("GPlayerInfoPanelOpened"); - panel.classList.add("GPlayerInfoPanelClosed"); - } - - info = document.getElementById(this._addUID("GPlayerInfoContent")); - panel.removeChild(info); - 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"); - 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"); - } - - info = document.getElementById(this._addUID("GPlayerInfoContent")); - if (info) { - panel.removeChild(info); - } - - // on récupère les infos associées au layer pour mettre dynamiquement le contenu du panel d'informations - var obj = { - title : layerOptions.title, - description : layerOptions.description, - quicklookUrl : layerOptions.quicklookUrl, - metadata : layerOptions.metadata, - legends : layerOptions.legends - }; - // get layer max scale denominator - var maxResolution = layerOptions.layer.getMaxResolution(); - if (maxResolution === Infinity) { - obj._maxScaleDenominator = 560000000; - } else { - obj._maxScaleDenominator = Math.round(maxResolution / 0.00028); - } - var infoLayer = this._createContainerLayerInfoElement(obj); - panel.appendChild(infoLayer); - } - - /** - * remove layer from layer switcher and map on picto click - * - * @param {Event} e - MouseEvent - * @private - */ - _onDropLayerClick (e) { - var divId = e.target.id; // ex GPvisibilityPicto_ID_26 - var layerID = SelectorID.index(divId); // ex. 26 - var layer = this._layers[layerID].layer; - - // le retrait de la couche va déclencher l'ecouteur d'évenement, - // et appeler this.removeLayer qui va supprimer la div. - this.getMap().getLayers().remove(layer); - } - - /** - * change layers order (on map) on drag and drop (on control container) - * - * @private - */ - _onDragAndDropLayerClick () { - // INFO : e.oldIndex et e.newIndex marchent en mode AMD mais pas Bundle. - var map = this.getMap(); - - // on récupère l'ordre des div dans le contrôle pour réordonner les couches (avec zindex) - var matchesLayers = document.querySelectorAll("div.GPlayerSwitcher_layer"); - var maxZIndex = matchesLayers.length; - // on vide la liste ordonnée avant de la remplir avec l'ordre des couches selon les div. - this._layersOrder = []; - for (var i = 0; i < matchesLayers.length; i++) { - var tag = matchesLayers[i].id; - var id = SelectorID.index(tag); - var layer = this._layers[id].layer; - - // on commence par désactiver temporairement l'écouteur d'événements sur le changement de zindex. - olObservableUnByKey(this._layers[id].onZIndexChangeEvent); - this._layers[id].onZIndexChangeEvent = null; - - if (layer.setZIndex) { - // maxZIndex--; - layer.setZIndex(maxZIndex); - this._layersOrder.push(this._layers[id]); - maxZIndex--; - } - - // et on réactive l'écouteur d'événement sur les zindex - if (this._layers[id].onZIndexChangeEvent == null) { - this._layers[id].onZIndexChangeEvent = layer.on( - "change:zIndex", - () => this._updateLayersOrder() - ); - } - } - - // mise à jour de la visu - map.updateSize(); - } - - /** - * check layers range on map movement - * - * @param {ol.Map} map - ol map on which event occured - * @private - */ - _onMapMoveEnd (map) { - // pour chaque couche de la map, on vérifie qu'elle soit toujours dans la visu (inRange) - map.getLayers().forEach( - (layer) => { - var id = layer.gpLayerId; - if (this._layers[id]) { - var layerOptions = this._layers[id]; - - // Check if layer is out of range. - var layerDiv; - if (this.isInRange(layer, map) && !layerOptions.inRange) { - layerOptions.inRange = true; - layerDiv = document.getElementById(this._addUID("GPlayerSwitcher_ID_" + id)); - layerDiv.classList.remove("outOfRange"); - } else if (!this.isInRange(layer, map) && layerOptions.inRange) { - layerOptions.inRange = false; - layerDiv = document.getElementById(this._addUID("GPlayerSwitcher_ID_" + id)); - layerDiv.classList.add("outOfRange"); - } - } - } - ); - } - - // ################################################################### // - // ############################ Utils ################################ // - // ################################################################### // - - /** - * Returns Layer Container Id associated with given olLayer - * - * @param {ol.layer.Layer} olLayer - ol layer object - * @returns {String} - div container Id ; null if layer not found. - */ - getLayerDOMId (olLayer) { - var foundId = null; - - this.getMap().getLayers().forEach((layer) => { - if (layer === olLayer) { - foundId = layer.hasOwnProperty("gpLayerId") ? layer.gpLayerId : null; - } - }); - - // TODO : recuperer "GPlayerSwitcher_ID" depuis une constante - return foundId !== null ? this._addUID("GPlayerSwitcher_ID_" + foundId) : null; - } - - /** - * Check if map view is out of layer range (in terms of extent and zoom) - * - * @param {Object} layer - the ol.layer object - * @param {Object} map - the ol.Map object - * @returns {Boolean} outOfRange - false if map view is out of layer range - */ - isInRange (layer, map) { - if (!map) { - return; - } - // check if map zoom is in layer zoom range - var mapResolution = map.getView().getResolution(); - if (mapResolution > layer.getMaxResolution() || mapResolution < layer.getMinResolution()) { - return false; - } - - // check if map extent intersects layer extent (if defined) - var mapExtent = map.getView().calculateExtent(map.getSize()); - var layerExtent = layer.getExtent(); - if (layerExtent && !olIntersects(mapExtent, layerExtent)) { - return false; - } - - return true; - } - - /** - * Get layer informations : title, description, quicklookurl, legends, metadata - * - * @param {Object} layer - the ol.layer object - * @returns {Object} layerInfo - layer informations - */ - getLayerInfo (layer) { - var layerInfo = {}; - if (layer.getProperties !== undefined && layer.getSource !== undefined) { - var layerProperties = layer.getProperties(); - var src = layerProperties.source; - if (src) { - layerInfo._title = src._title || layerProperties.id || ""; - layerInfo._description = src._description || ""; - layerInfo._quicklookUrl = src._quicklookUrl || ""; - layerInfo._metadata = src._metadata || []; - layerInfo._legends = src._legends || []; - } - } - return layerInfo; - } - -}; - -// on récupère les méthodes de la classe commune LayerSwitcherDOM -Object.assign(LayerSwitcher.prototype, LayerSwitcherDOM); - -export default LayerSwitcher; - -// Expose LayerSwitcher as ol.control.LayerSwitcher (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.LayerSwitcher = LayerSwitcher; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.d.ts deleted file mode 100644 index 55ced871c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -export default LayerSwitcherDOM; -declare namespace LayerSwitcherDOM { - function _createDraggableElement(elementDraggable: Object, context: Object): void; - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createMainLayersShowElement(): DOMElement; - function _createMainLayersElement(): DOMElement; - function _createMainLayersDivElement(): HTMLDivElement; - function _createMainPictoElement(): DOMElement; - function _createMainInfoElement(): DOMElement; - function _createContainerLayerElement(obj: { - layer: Object; - id: string; - title: string; - description: string; - visibility: boolean; - opacity: Float; - }): DOMElement; - function _createBasicToolElement(obj: Object): DOMElement; - function _createBasicToolNameElement(obj: Object): DOMElement; - function _createBasicToolVisibilityElement(obj: Object): DOMElement[]; - function _createAdvancedToolShowElement(obj: Object): DOMElement[]; - function _createAdvancedToolElement(obj: Object): DOMElement; - function _createAdvancedToolDeleteElement(obj: Object): DOMElement; - function _createAdvancedToolInformationElement(obj: Object): DOMElement; - function _createAdvancedToolOpacityElement(obj: Object): DOMElement[]; - function _createContainerLayerInfoElement(obj: Object): DOMElement; -} -//# sourceMappingURL=LayerSwitcherDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.d.ts.map deleted file mode 100644 index fac14a5e6..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"LayerSwitcherDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js"],"names":[],"mappings":";;IAU8B,kFA8BzB;IAWS,qCAGT;IAO6B,mDAK7B;IAO8B,oDAM9B;IAO0B,gDAS1B;IAE6B,uDAI7B;IAOyB,+CAuCzB;IAOwB,8CAOxB;IAmB8B;;;;;;;mBAsC9B;IAayB,0DAmBzB;IAS6B,8DAU7B;IASmC,sEA4CnC;IASgC,mEAoBhC;IAS4B,6DA0B5B;IASkC,mEA6BlC;IASuC,wEA6BvC;IASmC,sEAgFnC;IAgBkC,mEA4HlC"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js deleted file mode 100644 index 2e87705fe..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js +++ /dev/null @@ -1,695 +0,0 @@ -import Sortable from "sortablejs"; - -var LayerSwitcherDOM = { - - /** - * Creation du drag and drop - * - * @param {Object} elementDraggable - Element HTML (DOM) Container - * @param {Object} context - this - */ - _createDraggableElement : function (elementDraggable, context) { - // FIXME retirer cette détection user-agent pour solution propre - // option forcefallback pour réparer sortable sous Chrome 97 - // option forcefallback casse le layerswitcher du portail sous firefox - if (navigator.userAgent.match(/chrome|chromium|crios/i)) { - Sortable.create(elementDraggable, { - handle : ".GPlayerName", - draggable : ".draggable-layer", - ghostClass : "GPghostLayer", - animation : 200, - forceFallback : true, - // Call event function on drag and drop - onEnd : function (e) { - // FIXME pas terrrible, mais il faut bien passer ce contexte... - context._onDragAndDropLayerClick(e); - } - }); - } else { - Sortable.create(elementDraggable, { - handle : ".GPlayerName", - draggable : ".draggable-layer", - ghostClass : "GPghostLayer", - animation : 200, - // Call event function on drag and drop - onEnd : function (e) { - // FIXME pas terrrible, mais il faut bien passer ce contexte... - context._onDragAndDropLayerClick(e); - } - }); - } - }, - - // ################################################################### // - // ######################### Main container ########################## // - // ################################################################### // - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Creation du container principal (DOM) - * - * @returns {DOMElement} container - layer switcher DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPlayerSwitcher"); - container.className = "GPwidget gpf-widget gpf-widget-button"; - return container; - }, - - /** - * Creation du container principal d"affichage des layers (DOM) - * - * @returns {DOMElement} input - element for minimizing/maximizing the layer switcher - */ - _createMainLayersShowElement : function () { - // - var input = document.createElement("input"); - input.id = this._addUID("GPshowLayersList"); - input.type = "checkbox"; - return input; - }, - - /** - * Creation du container principal des layers (DOM) - * - * @returns {DOMElement} container - layers list container - */ - _createMainLayersElement : function () { - // ajout de la liste des layers dans le container principal - //
- // (...) - //
- var dialog = document.createElement("dialog"); - dialog.id = this._addUID("GPlayersList"); - dialog.className = "GPpanel gpf-panel fr-modal"; - return dialog; - }, - - _createMainLayersDivElement : function () { - var div = document.createElement("div"); - div.className = "gpf-panel__body fr-modal__body"; - return div; - }, - - /** - * Creation du container du picto du controle (DOM) - * - * @returns {DOMElement} label - */ - _createMainPictoElement : function () { - var self = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowLayersListPicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto gpf-btn gpf-btn-icon-layerswitcher fr-btn"; - button.htmlFor = this._addUID("GPshowLayersList"); - button.title = "Afficher/masquer le gestionnaire de couches"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - 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"; - } - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - 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"; - } - }); - } - - return button; - }, - - /** - * Creation du container du panneau d"information (DOM) - * - * @returns {DOMElement} container - */ - _createMainInfoElement : function () { - // gestion du panneau d"information dans le container principal - //
...
- var div = document.createElement("div"); - div.id = this._addUID("GPlayerInfoPanel"); - div.className = "GPpanel GPlayerInfoPanelClosed gpf-panel fr-modal"; - return div; - }, - - // ################################################################### // - // ######################### Layer container ######################### // - // ################################################################### // - - /** - * Creation du container du layer (DOM) - * - * @param {Object} obj - options de la couche à ajouter dans le layer switcher - * @param {Object} obj.layer - couche (ol ou leaflet) - * @param {String} obj.id - identifiant de la couche (pour ol ou leaflet) - * @param {String} obj.title - nom de la couche à afficher dans le controle - * @param {String} obj.description - description de la couche à afficher - * @param {Boolean} obj.visibility - visibilité de la couche dans la carte (true or false) - * @param {Float} obj.opacity - opacité de la couche - * - * @returns {DOMElement} container - */ - _createContainerLayerElement : function (obj) { - // exemple : - //
- // - // - // - //
- - // - // - var container = document.createElement("div"); - container.id = this._addUID("GPlayerSwitcher_ID_" + obj.id); - container.className = "GPlayerSwitcher_layer gpf-panel__content fr-modal__content draggable-layer"; - - // ajout des outils basiques (visibility / layer name) - container.appendChild(this._createBasicToolElement(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; - }, - - // ################################################################### // - // ############################ Layer tool ########################### // - // ################################################################### // - - /** - * Creation du container des outils basiques du layer (DOM) - * - * @param {Object} obj - options de la couche à ajouter dans le layer switcher - * - * @returns {DOMElement} container - */ - _createBasicToolElement : function (obj) { - // exemple : - //
- // - // - //
- - var div = document.createElement("div"); - div.id = this._addUID("GPbasicTools_ID_" + obj.id); - div.className = "GPlayerBasicTools"; - - div.appendChild(this._createBasicToolNameElement(obj)); - - var array = this._createBasicToolVisibilityElement(obj); - for (var i = 0; i < array.length; i++) { - div.appendChild(array[i]); - } - - return div; - }, - - /** - * Creation du nom du layer (DOM) - * - * @param {Object} obj - options de la couche à ajouter dans le layer switcher - * - * @returns {DOMElement} container - */ - _createBasicToolNameElement : function (obj) { - // exemple : - // Quartiers prioritaires de la ville - var label = document.createElement("label"); - label.id = this._addUID("GPname_ID_" + obj.id); - label.className = "GPlayerName gpf-label fr-label"; - label.title = obj.description || obj.title; - label.innerHTML = obj.title; - - return label; - }, - - /** - * Creation de l'icone de visibilité du layer (DOM) - * - * @param {Object} obj - options de la couche à ajouter dans le layer switcher - - * @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 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 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); - } - ); - } - - list.push(input); - list.push(label); - - return list; - }, - - /** - * Creation de l'affichage du menu des outils avancés du layer (DOM) - * - * @param {Object} obj - options de la couche à ajouter dans le layer switcher - * - * @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 input = document.createElement("input"); - input.type = "checkbox"; - input.id = this._addUID("GPshowAdvancedTools_ID_" + obj.id); - - list.push(input); - list.push(label); - - return list; - }, - - /** - * Creation du container des outils avancés du layer (DOM) - * - * @param {Object} obj - options de la couche à ajouter dans le layer switcher - * - * @returns {DOMElement} container - */ - _createAdvancedToolElement : function (obj) { - // exemple : - //
- // - // - // - //
- - var container = document.createElement("div"); - container.id = this._addUID("GPadvancedTools_ID_" + obj.id); - container.className = "GPlayerAdvancedTools"; - - container.appendChild(this._createAdvancedToolDeleteElement(obj)); - - // si on n'a de l'informations à afficher, on met en place ce composant - if (obj.title && obj.description) { - container.appendChild(this._createAdvancedToolInformationElement(obj)); - } - if (obj.type !== "feature") { - var array = this._createAdvancedToolOpacityElement(obj); - for (var i = 0; i < array.length; i++) { - container.appendChild(array[i]); - } - } - - return container; - }, - - /** - * Creation de l'icone de suppression du layer (DOM) - * - * @param {Object} obj - options de la couche à ajouter dans le layer switcher - * - * @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 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); - } - ); - } - - return div; - }, - - /** - * Creation de l'icone d'information du layer (DOM) - * - * @param {Object} obj - options de la couche à ajouter dans le layer switcher - * - * @returns {DOMElement} container - */ - _createAdvancedToolInformationElement : function (obj) { - // 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; - // add event on click - var context = this; - if (div.addEventListener) { - div.addEventListener( - "click", - function (e) { - context._onOpenLayerInfoClick(e); - } - ); - } else if (div.attachEvent) { - // internet explorer - div.attachEvent( - "onclick", - function (e) { - context._onOpenLayerInfoClick(e); - } - ); - } - - return div; - }, - - /** - * Creation de l'icone de gestion de l'opacité du layer (DOM) - * - * @param {Object} obj - options de la couche à ajouter dans le layer switcher - * - * @returns {DOMElement[]} array of two containers - */ - _createAdvancedToolOpacityElement : function (obj) { - // exemple : - //
- // - //
- //
- // 100 - // % - //
- - var list = []; - - // curseur pour changer l'opacité - var divO = document.createElement("div"); - divO.id = this._addUID("GPopacity_ID_" + obj.id); - divO.className = "GPlayerOpacity"; - divO.title = "Opacité"; - - var opacity = (typeof obj.opacity !== "undefined") ? obj.opacity : 1; - opacity = Math.round(opacity * 100); - - var input = document.createElement("input"); - input.id = this._addUID("GPopacityValueDiv_ID_" + obj.id); - input.type = "range"; - input.value = opacity; - input.ariaLabel = "Opacité"; - - // add event for opacity change - var context = this; - if (input.addEventListener) { - input.addEventListener( - "change", - function (e) { - context._onChangeLayerOpacity(e); - } - ); - } else if (input.attachEvent) { - // internet explorer - input.attachEvent( - "onchange", - function (e) { - context._onChangeLayerOpacity(e); - } - ); - } - - if (input.addEventListener) { - input.addEventListener( - "input", - function (e) { - context._onChangeLayerOpacity(e); - } - ); - } else if (input.attachEvent) { - // internet explorer - input.attachEvent( - "oninput", - function (e) { - context._onChangeLayerOpacity(e); - } - ); - } - - divO.appendChild(input); - - // Valeur d'opacité - var divC = document.createElement("div"); - divC.id = this._addUID("GPopacityValueDiv_ID_" + obj.id); - divC.className = "GPlayerOpacityValue"; - - var span = document.createElement("span"); - span.id = this._addUID("GPopacityValue_ID_" + obj.id); - span.innerHTML = opacity + "%"; - - divC.appendChild(span); - - list.push(divO); - list.push(divC); - - return list; - }, - - // ################################################################### // - // ############################ Layer info ########################### // - // ################################################################### // - - /** - * Creation du container du layer info (DOM) - * - * TODO GPlayerInfoPopup : ??? - * TODO GPlayerInfoLink : mettre en forme les échelles ! - * - * @param {Object} obj - options de la couche à ajouter dans le layer switcher - * - * @returns {DOMElement} container - */ - _createContainerLayerInfoElement : function (obj) { - var container = document.createElement("div"); - container.id = this._addUID("GPlayerInfoContent"); - - var title = document.createElement("div"); - title.id = this._addUID("GPlayerInfoTitle"); - title.innerHTML = obj.title; - container.appendChild(title); - - if (obj.quicklookUrl) { - var quick = document.createElement("div"); - quick.id = this._addUID("GPlayerInfoQuicklook"); - quick.title = "Afficher un aperçu de la couche"; - 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); - } - container.appendChild(close); - - var desc = document.createElement("div"); - desc.id = this._addUID("GPlayerInfoDescription"); - desc.innerHTML = obj.description; - container.appendChild(desc); - - if (obj.metadata) { - var mtd = document.createElement("div"); - mtd.id = this._addUID("GPlayerInfoMetadata"); - - var mtdtitle = document.createElement("div"); - mtdtitle.className = "GPlayerInfoSubtitle"; - mtdtitle.innerHTML = "Métadonnées"; - mtd.appendChild(mtdtitle); - - for (var i = 0; i < obj.metadata.length; i++) { - var urlmtd = obj.metadata[i].url; - - var mtdlink = document.createElement("div"); - mtdlink.className = "GPlayerInfoLink"; - - var refmtd = document.createElement("a"); - refmtd.href = urlmtd; - refmtd.innerHTML = urlmtd; - mtdlink.appendChild(refmtd); - mtd.appendChild(mtdlink); - } - - if (obj.metadata.length !== 0) { - container.appendChild(mtd); - } - } - - if (obj.legends) { - var lgd = document.createElement("div"); - lgd.id = this._addUID("GPlayerInfoLegend"); - - var lgdtitle = document.createElement("div"); - lgdtitle.className = "GPlayerInfoSubtitle"; - lgdtitle.innerHTML = "Légende"; - lgd.appendChild(lgdtitle); - - var legends = {}; - var maxScale = obj.maxScaleDenominator || 560000000; - - // on crée un tableau temporaire pour ordonner les légendes selon le dénominateur d'échelle - for (var k = 0; k < obj.legends.length; k++) { - var minScale = obj.legends[k].minScaleDenominator; - if (minScale) { - var s = minScale.toString(); - minScale = Math.round(parseInt(s.substring(0, 3), 10) / 10) * Math.pow(10, s.length - 2); - } else { - minScale = 270; - } - legends[minScale] = obj.legends[k]; - } - - for (var scale in legends) { - if (legends.hasOwnProperty(scale)) { - var urllgd = legends[scale].url; - // on n'affiche pas les légendes pointant vers "nolegend.jpg" - if (typeof urllgd === "string" && urllgd.toLowerCase().indexOf("nolegend.jpg") === -1) { - // TODO GPlayerInfoPopup - var lgdlink = document.createElement("div"); - lgdlink.className = "GPlayerInfoLink"; - - maxScale = legends[scale].maxScaleDenominator || maxScale; - - var reflgd = document.createElement("a"); - reflgd.href = urllgd; - reflgd.innerHTML = "Du 1/" + scale + " au 1/" + maxScale; - lgdlink.appendChild(reflgd); - lgd.appendChild(lgdlink); - } else { - delete legends[scale]; - } - } - } - - if (Object.keys(legends).length !== 0) { - container.appendChild(lgd); - } - } - - return container; - } -}; - -export default LayerSwitcherDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelector.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelector.d.ts deleted file mode 100644 index b4e5c240b..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelector.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -export default LocationSelector; -/** - * @classdesc - * - * LocationSelector component. Enables to select a location, using autocompletion or picking location on the map - * @type {ol.control.LocationSelector} - * @param {Object} [options] - component options - * @param {String} [options.apiKey] - API key for autocomplete service call. The key "calcul" is used by default. - * @param {Boolean} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean} [options.displayInfo = true] - whether to display info in a popup or not (not implemented yet) Default is true - * @param {Object} [options.tag] - tag options - * @param {Number} [options.tag.id = 1] - order id number in a locations group, in case several LocationSelector are used. For instance in route case : departure tag id should be 0, arrival tag id should be 1, and other ones : 2, 3, ... - * @param {Number} [options.tag.groupId = null] - locationSelector global component id (in case locationSelector is called by another graphic component, e.g. route control) - * @param {String} [options.tag.label] - text to display in component (e.g. "Departure"). Default is ">" - * @param {Object} [options.tag.markerOpts] - options to use your own marker. Default is a lightOrange marker. - * @param {String} [options.tag.markerOpts.url] - marker base64 encoded url (ex "data:image/png;base64,...""). Mandatory for a custom marker - * @param {Array} [options.tag.markerOpts.offset] - Offsets in pixels used when positioning the overlay. The first element in the array is the horizontal offset. A positive value shifts the overlay right. The second element in the array is the vertical offset. A positive value shifts the overlay down. Default is [0, 0]. (see {@link http://openlayers.org/en/latest/apidoc/ol.Overlay.html ol.Overlay}) - * @param {Boolean} [options.tag.display = true] - whether to display or hide component. Default is true - * @param {Boolean} [options.tag.addOption = false] - whether to display picto to add another LocationSelector (in case of route control) - * @param {Boolean} [options.tag.removeOption = false] - whether to display picto to remove a LocationSelector (in case of route control) - * @param {Object} [options.autocompleteOptions] - autocomplete service options (see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~autoComplete Gp.Services.autoComplete()} to know all autocomplete options) - * @example - * var locationselector = new LocationSelector({ - * apiKey : "", - * tag : { - * id : 1, - * groupId : null, - * label : "Départ", - * markerOpts : { - * url : "...", - * offset : [0,0] - * }, - * display : true - * }, - * autocompleteOptions : {} - * }); - */ -declare var LocationSelector: ol.control.LocationSelector; -//# sourceMappingURL=LocationSelector.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelector.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelector.d.ts.map deleted file mode 100644 index b3537e11f..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelector.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"LocationSelector.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/LocationSelector/LocationSelector.js"],"names":[],"mappings":";AAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,0DA0uBE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelector.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelector.js deleted file mode 100644 index 2c665a213..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelector.js +++ /dev/null @@ -1,814 +0,0 @@ -// import CSS -import "../../CSS/Controls/LocationSelector/GPFlocation.css"; -// import "../../CSS/Controls/LocationSelector/GPFlocationStyle.css"; -// import OpenLayers -import Control from "ol/control/Control"; -import Overlay from "ol/Overlay"; -import { transform as olTransformProj } from "ol/proj"; -import { unByKey as olObservableUnByKey } from "ol/Observable"; -// import geoportal library access -import Gp from "geoportal-access-lib"; -// import local -import Logger from "../../Utils/LoggerByDefault"; -import Utils from "../../Utils/Helper"; -import GeocodeUtils from "../../Utils/GeocodeUtils"; -import SelectorID from "../../Utils/SelectorID"; -import Markers from "../Utils/Markers"; -// DOM -import LocationSelectorDOM from "./LocationSelectorDOM"; - -var logger = Logger.getLogger("locationselector"); - -/** - * @classdesc - * - * LocationSelector component. Enables to select a location, using autocompletion or picking location on the map - * @type {ol.control.LocationSelector} - * @param {Object} [options] - component options - * @param {String} [options.apiKey] - API key for autocomplete service call. The key "calcul" is used by default. - * @param {Boolean} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean} [options.displayInfo = true] - whether to display info in a popup or not (not implemented yet) Default is true - * @param {Object} [options.tag] - tag options - * @param {Number} [options.tag.id = 1] - order id number in a locations group, in case several LocationSelector are used. For instance in route case : departure tag id should be 0, arrival tag id should be 1, and other ones : 2, 3, ... - * @param {Number} [options.tag.groupId = null] - locationSelector global component id (in case locationSelector is called by another graphic component, e.g. route control) - * @param {String} [options.tag.label] - text to display in component (e.g. "Departure"). Default is ">" - * @param {Object} [options.tag.markerOpts] - options to use your own marker. Default is a lightOrange marker. - * @param {String} [options.tag.markerOpts.url] - marker base64 encoded url (ex "data:image/png;base64,...""). Mandatory for a custom marker - * @param {Array} [options.tag.markerOpts.offset] - Offsets in pixels used when positioning the overlay. The first element in the array is the horizontal offset. A positive value shifts the overlay right. The second element in the array is the vertical offset. A positive value shifts the overlay down. Default is [0, 0]. (see {@link http://openlayers.org/en/latest/apidoc/ol.Overlay.html ol.Overlay}) - * @param {Boolean} [options.tag.display = true] - whether to display or hide component. Default is true - * @param {Boolean} [options.tag.addOption = false] - whether to display picto to add another LocationSelector (in case of route control) - * @param {Boolean} [options.tag.removeOption = false] - whether to display picto to remove a LocationSelector (in case of route control) - * @param {Object} [options.autocompleteOptions] - autocomplete service options (see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~autoComplete Gp.Services.autoComplete()} to know all autocomplete options) - * @example - * var locationselector = new LocationSelector({ - * apiKey : "", - * tag : { - * id : 1, - * groupId : null, - * label : "Départ", - * markerOpts : { - * url : "...", - * offset : [0,0] - * }, - * display : true - * }, - * autocompleteOptions : {} - * }); - */ -var LocationSelector = class LocationSelector extends Control { - - /** - * See {@link ol.control.LocationSelector} - * @module LocationSelector - * @alias module:~Controls/LocationSelector - * @param {*} options - options - * @example - * import LocationSelector from "src/OpenLayers/Controls/LocationSelector" - */ - constructor (options) { - options = options || {}; - - super({ - element : options.element || document.createElement("div"), - render : options.render, - target : options.target - }); - - if (!(this instanceof LocationSelector)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - // initialisation du composant - this.initialize(options); - - // creation du DOM - this._container = this._initContainer(); - - // ajout du container - (this.element) ? this.element.appendChild(this._container) : this.element = this._container; - - return this; - } - - /** - * initialize component - * - * @param {Object} options - options - */ - initialize (options) { - // set default options - this.options = { - tag : { - id : 1, // numero d'ordre sur un groupe de locations - groupId : null, // id du composant global contenant le LocationSelector - label : ">", - display : true, - addOption : false, - removeOption : false - }, - displayInfo : true, - autocompleteOptions : {} - }; - - // merge with user options - Utils.mergeParams(this.options, options); - - /** uuid */ - this._uid = this.options.tag.groupId || SelectorID.generate(); - // info : si un uid (groupId) est spécifié - // (par ex si ce composant est appélé par un autre composant graphique) - // alors on le récupère, sinon c'est qu'il est indépendant : on génère donc un uuid - - /** container map */ - this._map = null; - - /** container principal des entrées */ - this._inputsContainer = null; - - /** container du label du point */ - this._buttonLabel = null; - - /** container de la saisi de l'autocompletion */ - this._inputAutoComplete = null; - - /** container du pointer de saisi sur la carte */ - this._inputShowPointerContainer = null; - - /** label du pointer de saisi sur la carte (avec img) */ - this._inputShowPointer = null; - - /** container des coordonnées */ - this._inputCoordinateContainer = null; - - /** elements pour ajouter ou supprimer un nouveau point */ - this._addPointElement = null; - this._removePointElement = null; - - /** coordonnées du point selectionné, en EPSG:4326 */ - this._coordinate = null; - - /** container des reponses de l'autocompletion */ - this._suggestedContainer = null; - this._suggestedList = null; - - /** listes des reponses de l'autocompletion */ - this._suggestedLocations = []; - - /** localisant */ - this._currentLocation = null; - - /** marker */ - this._initMarker(); - - /** ressources du services d'autocompletion (ayant droit!) */ - this._resources = {}; - - // listener key for event click on map - this.listenerKey = null; - } - - /** - * initialize marker : url and offset - * - * @private - */ - _initMarker () { - // init marker properties - this._marker = null; - this._markerUrl = ""; - this._markerOffset = [0, 0]; - - if (this.options.tag.markerOpts && this.options.tag.markerOpts.url) { - // get marker src url - this._markerUrl = this.options.tag.markerOpts.url; - - // get marker offset - var offset = this.options.tag.markerOpts.offset; - if (offset) { - if (Array.isArray(offset) && offset.length === 2) { - this._markerOffset = offset; - } else { - logger.log("markerOpts.offset should be an array. e.g. : [0,0]"); - } - } - } else { - // set default options for marker - this._markerUrl = Markers["lightOrange"]; - this._markerOffset = Markers.defaultOffset; - } - } - - // ################################################################### // - // ########################## publics methods ######################## // - // ################################################################### // - - /** - * get coordinate - * - * @returns {Array} this._coordinate - point coordinate (EPSG:4326) : [lon, lat] - */ - getCoordinate () { - return this._coordinate; - } - - /** - * set coordinate - * @param {Object} coordinate - Coordinate in the map projection by default, otherwise, the projection is entered in the following parameter - * @param {String} crs - Coordinate projection - */ - setCoordinate (coordinate, crs) { - var map = this.getMap(); - var proj = map.getView().getProjection().getCode(); - // on utilise la projection de la carte - if (!crs) { - crs = proj; - } - - this._setCoordinate(coordinate, crs); - - // on utilise toujours la projection de la carte pour placer le marker - coordinate = olTransformProj(coordinate, crs, proj); - this._setMarker([ - coordinate[0], - coordinate[1] - ], null, false); - } - - /** - * clean all and input - */ - clear () { - this.clearResults(); - this._buttonLabel.click(); - } - - /** - * clear all results and the marker. - */ - clearResults () { - this._currentLocation = null; - this._coordinate = null; - this._hideSuggestedLocation(); - this._clearSuggestedLocation(); - this._setMarker(); - // map.un("click", (e) => this.onMouseMapClick(e)); - olObservableUnByKey(this.listenerKey); - } - - // ################################################################### // - // ##################### init component (private) #################### // - // ################################################################### // - - /** - * initialize component container - * - * @returns {DOMElement} DOM element - */ - _initContainer () { - var id = this.options.tag.id; - - // create main container - var container = this._createMainContainerElement(); - - var inputs = this._inputsContainer = this._createLocationPointElement(id, this.options.tag.display); - container.appendChild(inputs); - - var _buttonLabel = this._buttonLabel = this._createLocationPointLabelElement(id, this.options.tag.label); - inputs.appendChild(_buttonLabel); - var _inputAutoComplete = this._inputAutoComplete = this._createLocationAutoCompleteteInputElement(id); - if (_inputAutoComplete.addEventListener) { - _inputAutoComplete.addEventListener("click", () => this.onAutoCompleteInputClick()); - } else if (_inputAutoComplete.attachEvent) { - _inputAutoComplete.attachEvent("onclick", () => this.onAutoCompleteInputClick()); - } - inputs.appendChild(_inputAutoComplete); - var _inputCoordinate = this._inputCoordinateContainer = this._createLocationCoordinateInputElement(id); - inputs.appendChild(_inputCoordinate); - var _inputShowPointer = this._inputShowPointerContainer = this._createLocationPointerShowInputElement(id); - inputs.appendChild(_inputShowPointer); - var _inputPointer = this._inputShowPointer = this._createLocationPointerInputElement(id); - inputs.appendChild(_inputPointer); - - if (this.options.tag.addOption) { - var _inputAddStage = this._addPointElement = this._createLocationAddPointElement(); - inputs.appendChild(_inputAddStage); - } - - if (this.options.tag.removeOption) { - var _inputRemoveStage = this._removePointElement = this._createLocationRemovePointElement(id); - inputs.appendChild(_inputRemoveStage); - } - - var resultsPanel = this._suggestedContainer = this._createLocationAutoCompleteElement(id); - var results = this._suggestedList = this._createLocationAutoCompleteResultElement(id); - resultsPanel.appendChild(results); - container.appendChild(resultsPanel); - - return container; - } - - // ################################################################### // - // ###################### handlers events (dom) ###################### // - // ################################################################### // - - /** - * this method is called by event 'click' on 'GPlocationOrigin' input - * - * @private - */ - onAutoCompleteInputClick () { - if (this._inputAutoComplete && this._inputAutoComplete.value.length > 2) { - this._displaySuggestedLocation(); - } - } - - /** - * this method is called by event 'keyup' on 'GProuteOrigin' tag input - * (cf. this._createRouteAutoCompleteteInputElement), and it gets the value of input. - * this value is passed as a parameter for the service autocomplete (text). - * the results of the request are displayed into a drop down menu. - * FIXME - * - * @param {Object} e - HTMLElement - * @private - */ - onAutoCompleteSearchText (e) { - var value = e.target.value; - if (!value) { - return; - } - - // on recupere les options du service - var serviceOptions = this.options.autocompleteOptions || {}; - var _customOnSuccess = serviceOptions.onSuccess || null; - var _customOnFailure = serviceOptions.onFailure || null; - - // on sauvegarde le localisant - this._currentLocation = value; - - // on limite les requêtes à partir de 3 car. saisie ! - if (value.length < 3) { - this._clearSuggestedLocation(); - return; - } - - // INFORMATION - // on effectue la requête au service d'autocompletion. - // on met en place des callbacks afin de recuperer les resultats ou - // les messages d'erreurs du service. - // les resultats sont affichés dans une liste deroulante. - // les messages d'erreurs sont affichés sur la console (?) - var context = this; - this._requestAutoComplete({ - text : value, - maximumResponses : 5, // FIXME je limite le nombre de reponse car le container DOM est limité dans l'affichage !!! - // callback onSuccess - onSuccess : function (results) { - if (results) { - var locations = results.suggestedLocations; - context._fillAutoCompletedLocationListContainer(locations); - if (_customOnSuccess) { - _customOnSuccess.call(this, results); - } - } - }, - // callback onFailure - onFailure : function (error) { - // FIXME - // où affiche t on les messages : ex. 'No suggestion matching the search' ? - // doit on nettoyer la liste des suggestions dernierement enregistrée : - context._clearSuggestedLocation(); - logger.log(error.message); - if (_customOnFailure) { - _customOnFailure.call(this, error); - } - } - }); - - var map = this.getMap(); - map.on( - "click", - () => this._hideSuggestedLocation() - ); - map.on( - "pointerdrag", - () => this._hideSuggestedLocation() - ); - } - - /** - * this method is called by event 'click' on 'GPautoCompleteResultsList' tag div - * (cf. this._createAutoCompleteListElement), and it selects the location. - * this location displays a marker on the map. - * FIXME - * - * @param {Object} e - HTMLElement - * @private - */ - onAutoCompletedResultsItemClick (e) { - var idx = SelectorID.index(e.target.id); - - if (!idx) { - return; - } - - // FIXME - // les coordonnées sont inversées entre les 2 services !? - // AutoCompletion : lon/lat ("EPSG:4326") - // Geocoding : lat/lon - var position = [ - this._suggestedLocations[idx].position.x, - this._suggestedLocations[idx].position.y - ]; - // on sauvegarde le point courant (en EPSG:4326, [lon, lat]) - this._coordinate = position; - - var info = { - type : this._suggestedLocations[idx].type, - fields : this._suggestedLocations[idx] - }; - - // on ajoute le texte de l'autocomplétion dans l'input - var label = GeocodeUtils.getSuggestedLocationFreeform(this._suggestedLocations[idx]); - this._setLabel(label); - - // Info : la position est en EPSG:4326, à transformer dans la projection de la carte - var view = this.getMap().getView(); - var mapProj = view.getProjection().getCode(); - if (mapProj !== "EPSG:4326") { - // on retransforme les coordonnées de la position dans la projection de la carte - position = olTransformProj(position, "EPSG:4326", mapProj); - } - // on centre la vue et positionne le marker, à la position reprojetée dans la projection de la carte - this._setPosition(position); - this._setMarker(position, info, this.options.displayInfo); - } - - /** - * this method is called by event 'click' on 'GProuteOriginPointerImg' tag input - * (cf. this._createRoutePointerInputElement), and it create or remove the event of click map. - * - * @private - */ - onActivateMapPointClick () { - var map = this.getMap(); - - if (this._inputShowPointerContainer.checked) { - // on efface l'ancien resultat - this.clearResults(); - this.listenerKey = map.on( - "click", - (e) => this.onMouseMapClick(e) - ); - this._setCursor("crosshair"); - } else { - // map.un("click", (e) => this.onMouseMapClick(e)); - olObservableUnByKey(this.listenerKey); - this._setCursor(); - } - } - - /** - * this method is called by event 'click' on 'GProuteOriginLabel' tag label - * (cf. this._createRoutePointLabelElement). - * this point is erased. - *Missing - * @private - */ - onLocationClearPointClick () { - this._setCursor(); - this.clearResults(); - } - - /** - * this method is called by event 'click' on 'GProuteStageRemove' tag input - * (cf. this._createRouteRemovePointElement). - * this point is deleted - * - * @private - */ - onLocationRemovePointClick () { - this._setCursor(); - this.clearResults(); - } - - /** - * TODO this method is called by event 'click' on 'GProuteStageAdd' tag input - * (cf. this._createRouteAddPointElement). - * this point is added as a parameter for the service route. - * - * @param {Object} e - HTMLElement - */ - onLocationAddPointClick (e) { - logger.log("onRouteAddPointClick", e); - } - - // ################################################################### // - // #################### handlers events (control) #################### // - // ################################################################### // - - /** - * this method is called by event 'click' on map - * (cf. this.onRouteMapPointClick), and it gets the coordinate of click on map. - * this point is saved as a parameter for the service route. - * - * @param {Object} e - HTMLElement - * @private - */ - onMouseMapClick (e) { - var coordinate = e.coordinate; - if (!e.map || !e.map.getView()) { - return; - } - var crs = e.map.getView().getProjection(); - - this._setCoordinate(coordinate, crs); - - this._setMarker([ - coordinate[0], - coordinate[1] - ], null, false); - - // on desactive l'event sur la map ! - this.onActivateMapPointClick(e); - } - - // ################################################################### // - // ################# pivates methods use by events ################### // - // ################################################################### // - - /** - * this sends the label to the panel. - * - * @param {String} label - label suggested location - * @private - */ - _setLabel (label) { - this._inputAutoComplete.value = label; - } - - /** - * this change the cursor of the map when entering a point. - * - * @param {String} cursor - cursor style - * @private - */ - _setCursor (cursor) { - var map = this.getMap(); - var div = map.getTargetElement(); - - if (cursor) { - div.style.cursor = cursor; - } else { - div.style.cursor = null; - } - } - - /** - * this sends the coordinates to the panel. - * - * @method _setCoordinate - * @param {Array} olCoordinate - ol.Coordinate object [lon, lat] ou [x, y] (proj = map proj system) - * @param {Object} crs - coordinate CRS (ol.proj.Projection) - * @private - */ - _setCoordinate (olCoordinate, crs) { - // structure - // ol.Coordinate - // [ - // 4 // lon ou x - // 48 // lat ou y - // ] - - // on transforme olCoodinate (dont la projection est celle de la carte) en EPSG:4326 - this._coordinate = olTransformProj(olCoordinate, crs, "EPSG:4326"); - - // INFO : si on veut des DMS - // var coords = ol.coordinate.toStringHDMS(this._coordinate, 2).split("N "); - // // coords est du type : "48° 00′ 00″ N 2° 00′ 00″ E". On veut récupérer les 2 coordonnées séparément. - // var lat = coords[0] + "N"; - // var lng = coords[1]; - - // Pour avoir des degrés décimaux : - var lat = this._coordinate[0].toFixed(4); - var lng = this._coordinate[1].toFixed(4); - - var value = lng + " / " + lat; - this.GPdisplayCoordinate(value); - } - - /** - * this method is called by this.on*ResultsItemClick() - * and set center at given position. - * - * @param {Array} position - ol.Coordinate object [lon, lat] (en lat/lon : "EPSG:4326") - * @private - */ - _setPosition (position) { - var view = this.getMap().getView(); - view.setCenter(position); - } - - /** - * this method is called by this.on*ResultsItemClick() - * and displays a marker. - * FIXME : marker IGN et informations ? - * - * @param {Array} position - ol.Coordinate object [lon, lat] ou [x, y] - * @param {Object} information - suggested or geocoded information - * @param {Boolean} display - display a popup information - * @private - */ - _setMarker (position, information, display) { - var map = this.getMap(); - // remove previous markers - if (this._marker != null) { - map.removeOverlay(this._marker); - this._marker = null; - } - - if (position) { - var markerDiv = document.createElement("img"); - markerDiv.src = this._markerUrl; - this._marker = new Overlay({ - position : position, - offset : this._markerOffset, - element : markerDiv, - stopEvent : false - }); - map.addOverlay(this._marker); - - if (display) { - logger.log("marker information : ", information); - } - // // FIXME - // // doit on mettre une information - // // - correctement construite ? - // // - uniquement informatif ? - // // - RIEN ? - // if (display) { - // var popupContent = null; - // - // var values = []; - // - // values.push(information.fields.fullText || ""); - // values.push(information.fields.street || ""); - // values.push(information.fields.postalCode || ""); - // values.push(information.fields.commune || ""); - // - // if (information.type === "PositionOfInterest") { - // values.push(information.fields.poi || ""); - // values.push(information.fields.kind || ""); - // } - // - // popupContent = values.join(" | "); - // - // this._marker.bindPopup(popupContent); - // } - } - } - - /** - * this method is called by this.onAutoCompleteSearchText() - * and it clears all suggested location. - * - * @private - */ - _clearSuggestedLocation () { - // suppression du dom - this._suggestedLocations = []; - if (this._suggestedList) { - while (this._suggestedList.firstChild) { - this._suggestedList.removeChild(this._suggestedList.firstChild); - } - } - } - - /** - * this method is called by event 'click' on map - * and it hide suggested locations - * - * @private - */ - _hideSuggestedLocation () { - if (this._suggestedContainer) { - this._suggestedContainer.classList.replace("GPelementVisible", "GPelementHidden"); - this._suggestedContainer.classList.replace("gpf-visible", "gpf-hidden"); - } - } - - /** - * this method is called by this.onAutoCompleteSearchText() - * and it clears all suggested location. - * - * @private - */ - _displaySuggestedLocation () { - if (this._suggestedContainer) { - this._suggestedContainer.classList.replace("GPelementHidden", "GPelementVisible"); - this._suggestedContainer.classList.replace("gpf-hidden", "gpf-visible"); - } - } - - /** - * this method is called by this.onAutoCompleteSearch() - * and executes a request to the service. - * - * @param {Object} settings - service settings - * @param {String} settings.text - text - * @param {Function} settings.onSuccess - callback - * @param {Function} settings.onFailure - callback - * @private - */ - _requestAutoComplete (settings) { - logger.log("_requestAutoComplete()", settings); - - // on ne fait pas de requête si on n'a pas renseigné de parametres ! - if (!settings || Object.keys(settings).length === 0) { - return; - } - - // on ne fait pas de requête si la parametre 'text' est vide ! - if (!settings.text) { - return; - } - - logger.log(settings); - - var options = {}; - // on recupere les options du service - Utils.assign(options, this.options.autocompleteOptions); - // ainsi que la recherche et les callbacks - Utils.assign(options, settings); - - // les ressources - var resources = this._resources["AutoCompletion"] || null; - if (resources && Array.isArray(resources)) { - if (!options.filterOptions) { - options.filterOptions = {}; - } - options.filterOptions.type = resources; - } - - // cas où la clef API n'est pas renseignée dans les options du service, - // on utilise celle renseignée au niveau du controle ou la clé "calcul" par défaut. - options.apiKey = options.apiKey || this.options.apiKey; - - // si l'utilisateur a spécifié le paramètre ssl au niveau du control, on s'en sert - // true par défaut (https) - if (typeof options.ssl !== "boolean") { - if (typeof this.options.ssl === "boolean") { - options.ssl = this.options.ssl; - } else { - options.ssl = true; - } - } - - logger.log(options); - - Gp.Services.autoComplete(options); - } - - /** - * this method is called by this.onAutoCompleteSearchText() - * and fills the container of the location list. - * it creates a HTML Element per location - * (cf. this. ...) - * - * @param {Object[]} locations - locations - * - * @private - */ - _fillAutoCompletedLocationListContainer (locations) { - if (!locations || locations.length === 0) { - return; - } - - // on vide la liste avant de la construire - var element = this._suggestedList; - if (element.childElementCount) { - while (element.firstChild) { - element.removeChild(element.firstChild); - } - } - - for (var i = 0; i < locations.length; i++) { - // Proposals are dynamically filled in Javascript by autocomplete service - this._createLocationAutoCompletedLocationElement(this.options.tag.id, locations[i], i); - } - - // sauvegarde de l'etat des locations - this._suggestedLocations = locations; - } - -}; - -// on récupère les méthodes de la classe DOM -Object.assign(LocationSelector.prototype, LocationSelectorDOM); - -export default LocationSelector; - -// Expose LocationSelector as ol.control.LocationSelector (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.LocationSelector = LocationSelector; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelectorDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelectorDOM.d.ts deleted file mode 100644 index 0a427d6d2..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelectorDOM.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -export default LocationSelectorDOM; -declare namespace LocationSelectorDOM { - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createLocationPointElement(id: number, display: number): DOMElement; - function _createLocationPointLabelElement(id: number, text: string): DOMElement; - function _createLocationAutoCompleteteInputElement(id: number): DOMElement; - function _createLocationCoordinateInputElement(id: number): DOMElement; - function _createLocationPointerShowInputElement(id: number): DOMElement; - function _createLocationPointerInputElement(id: number): DOMElement; - function _createLocationRemovePointElement(id: number): DOMElement; - function _createLocationAddPointElement(): DOMElement; - function _createLocationAutoCompleteElement(id: any): HTMLDivElement; - function _createLocationAutoCompleteResultElement(id: number): DOMElement; - function _createLocationAutoCompletedLocationElement(id: number, location: Object, n: number): void; - function GPdisplayCoordinate(value: string): void; -} -//# sourceMappingURL=LocationSelectorDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelectorDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelectorDOM.d.ts.map deleted file mode 100644 index a97012cbd..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelectorDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"LocationSelectorDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/LocationSelector/LocationSelectorDOM.js"],"names":[],"mappings":";;IAac,qCAGT;IAM6B,mDAK7B;IAU6B,8EAO7B;IAUkC,gFAiClC;IAQ2C,2EAkG3C;IAQuC,uEAcvC;IAQwC,wEAOxC;IAQoC,oEAyEpC;IASmC,mEAwCnC;IAQgC,sDA6ChC;IAEoC,qEAUpC;IAS0C,0EAuB1C;IAY6C,oGAS7C;IAMqB,kDAuBrB"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelectorDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelectorDOM.js deleted file mode 100644 index ee9f8159e..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/LocationSelector/LocationSelectorDOM.js +++ /dev/null @@ -1,511 +0,0 @@ -import ID from "../../Utils/SelectorID"; -import Logger from "../../Utils/LoggerByDefault"; -import GeocodeUtils from "../../Utils/GeocodeUtils"; - -var logger = Logger.getLogger("LocationSelectorDOM"); - -var LocationSelectorDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Main container (DOM) - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.className = this._addUID("GPlocationPoint"); // ceci permet de gerer les groupes de points ! - container.className += " GPwidget gpf-widget "; - return container; - }, - - /** - * Create Container Point - * see event ! - * - * @param {Number} id - tag ID - * @param {Number} display - display - * @returns {DOMElement} DOM element - */ - _createLocationPointElement : function (id, display) { - var div = document.createElement("div"); - div.id = this._addUID("GPlocationPoint_" + id); - div.className = (display) ? "GPflexInput GPlocationStageFlexInput gpf-flex" : "GPflexInput GPelementHidden gpf-flex gpf-hidden"; - div.style.cssText = ""; - - return div; - }, - - /** - * Create Container Point - * see event ! - * - * @param {Number} id - tag ID - * @param {String} text - label - * @returns {DOMElement} DOM element - */ - _createLocationPointLabelElement : function (id, text) { - // contexte d'execution - var self = this; - - var buttonOrigin = document.createElement("button"); - buttonOrigin.id = this._addUID("GPlocationOriginLabel_" + id); - buttonOrigin.innerHTML = text; - buttonOrigin.className = "GPlocationOriginLabel gpf-btn gpf-btn-icon-label fr-btn fr-btn--secondary"; - buttonOrigin.addEventListener("click", function (e) { - var i = ID.index(this.id); - var points = document.getElementsByClassName(self._addUID("GPlocationPoint")); - for (var j = 0; j < points.length; j++) { - var tag = points[j].childNodes[0].id; - var id = ID.index(tag); - document.getElementById(self._addUID("GPlocationPoint_" + id)).style.cssText = ""; - } - document.getElementById(self._addUID("GPlocationOriginCoords_" + i)).value = ""; - document.getElementById(self._addUID("GPlocationOrigin_" + i)).value = ""; - document.getElementById(self._addUID("GPlocationPoint_" + i)).style.cssText = ""; - document.getElementById(self._addUID("GPlocationOriginPointer_" + i)).checked = false; - document.getElementById(self._addUID("GPlocationOrigin_" + i)).className = "GPelementShow gpf-show gpf-input fr-input"; - document.getElementById(self._addUID("GPlocationOriginCoords_" + i)).className = "GPelementHidden gpf-hidden"; - if (document.getElementById(self._addUID("GPlocationStageRemove_" + i))) { - document.getElementById(self._addUID("GPlocationStageRemove_" + i)).className = "GPlocationStageRemove gpf-btn gpf-btn-icon-remove fr-btn--sm fr-btn--secondary"; - } - if (document.getElementById(self._addUID("GPlocationStageAdd"))) { - document.getElementById(self._addUID("GPlocationStageAdd")).className = "GPlocationStageAdd gpf-btn gpf-btn-icon-add fr-btn--sm fr-btn--secondary"; - } - // document.getElementById(self._addUID("GPlocationOriginCoords_" + i)).disabled = true; - self.onLocationClearPointClick(e); - }); - - return buttonOrigin; - }, - - /** - * Create Input AutoComplete Point tag - * - * @param {Number} id - tag ID - * @returns {DOMElement} DOM element - */ - _createLocationAutoCompleteteInputElement : function (id) { - // contexte d'execution - var self = this; - - var inputOrigin = document.createElement("input"); - inputOrigin.id = this._addUID("GPlocationOrigin_" + id); - inputOrigin.className = "GPelementShow gpf-show gpf-input fr-input"; - inputOrigin.type = "text"; - inputOrigin.placeholder = "Saisir une adresse"; - inputOrigin.autocomplete = "off"; - inputOrigin.addEventListener("keyup", function (e) { - var charCode = e.which || e.keyCode; - if (charCode === 13 || charCode === 10 || charCode === 38 || charCode === 40) { - return; - } - - var i = ID.index(this.id); - if (document.getElementById(self._addUID("GPlocationOrigin_" + i)).value.length > 2) { - document.getElementById(self._addUID("GPlocationAutoCompleteList_" + i)).classList.replace("GPelementHidden", "GPelementVisible"); - document.getElementById(self._addUID("GPlocationAutoCompleteList_" + i)).classList.replace("gpf-hidden", "gpf-visible"); - } else { - document.getElementById(self._addUID("GPlocationAutoCompleteList_" + i)).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPlocationAutoCompleteList_" + i)).classList.replace("gpf-visible", "gpf-hidden"); - } - // gestionnaire d'evenement : - // on récupère la valeur de saisie pour une requête sur le service d'autocompletion. - // le resultat de la requête nous permet de recuperer les coordonnées du point... - self.onAutoCompleteSearchText(e); - }); - - inputOrigin.addEventListener("keydown", function (e) { - var charCode = e.which || e.keyCode; - - var container = document.getElementById(self._addUID("GPlocationAutoCompleteResult_" + id)); - - // si aucun container !? - if (!container) { - return; - } - - var curr = container.getElementsByClassName("GPautoCompleteProposal current"); - var list = container.getElementsByClassName("GPautoCompleteProposal"); - - // si aucune suggestion, on ne va pas plus loin ! - var length = list.length; - if (!length) { - return; - } - - var current = null; - - // si aucun item courant, on prend le 1er ! - if (!curr.length) { - current = list[0]; - current.className = "GPautoCompleteProposal current"; - current.style.color = "#000000"; - current.style["background-color"] = "#CEDBEF"; - return; - } else { - current = curr[0]; - } - - var index = parseInt(ID.index(current.id), 10); - var next = (index === length - 1) ? list[0] : list[index + 1]; - var prev = (index === 0) ? list[length - 1] : list[index - 1]; - - current.style["background-color"] = ""; - current.style.color = ""; - prev.style["background-color"] = ""; - prev.style.color = ""; - next.style["background-color"] = ""; - next.style.color = ""; - - switch (charCode) { - case 38: // arrow up - logger.log("arrow up"); - current.className = "GPautoCompleteProposal"; - prev.className = "GPautoCompleteProposal current"; - prev.style.color = "#000000"; - prev.style["background-color"] = "#CEDBEF"; - break; - case 40: // arrow down - logger.log("arrow down"); - current.className = "GPautoCompleteProposal"; - next.className = "GPautoCompleteProposal current"; - next.style.color = "#000000"; - next.style["background-color"] = "#CEDBEF"; - break; - case 13: // enter - logger.log("enter"); - current.click(e); - break; - } - - current.focus(); - }); - - return inputOrigin; - }, - - /** - * Create Input Coordinate Point tag - * - * @param {Number} id - tag ID - * @returns {DOMElement} DOM element - */ - _createLocationCoordinateInputElement : function (id) { - // contexte d'execution - var self = this; - - var inputOriginCoord = document.createElement("input"); - inputOriginCoord.id = this._addUID("GPlocationOriginCoords_" + id); - inputOriginCoord.className = "GPelementHidden gpf-input gpf-hidden fr-input"; - inputOriginCoord.type = "text"; - inputOriginCoord.disabled = false; - inputOriginCoord.addEventListener("click", function () { - var i = ID.index(this.id); - document.getElementById(self._addUID("GPlocationOriginLabel_" + i)).click(); - }); - return inputOriginCoord; - }, - - /** - * Create Show Pointer tag - * - * @param {Number} id - tag ID - * @returns {DOMElement} DOM element - */ - _createLocationPointerShowInputElement : function (id) { - var inputOriginPointer = document.createElement("input"); - inputOriginPointer.id = this._addUID("GPlocationOriginPointer_" + id); - inputOriginPointer.className = "GPelementHidden gpf-hidden"; - inputOriginPointer.type = "checkbox"; - - return inputOriginPointer; - }, - - /** - * Create Input Pointer tag - * - * @param {Number} id - tag ID - * @returns {DOMElement} DOM element - */ - _createLocationPointerInputElement : function (id) { - // contexte d'execution - var self = this; - - var buttonOriginPointer = document.createElement("button"); - buttonOriginPointer.id = this._addUID("GPlocationOriginPointerImg_" + id); - buttonOriginPointer.htmlFor = this._addUID("GPlocationOriginPointer_" + id); - buttonOriginPointer.className = "GPlocationOriginPointerImg gpf-btn gpf-btn-icon-pointer fr-btn fr-btn--secondary"; - buttonOriginPointer.title = "Pointer un lieu sur la carte"; - buttonOriginPointer.addEventListener("click", function (e) { - e.preventDefault(); - e.stopPropagation(); - var i = ID.index(this.id); - var points = document.getElementsByClassName(self._addUID("GPlocationPoint")); - var j; - var tag; - var id; - for (j = 0; j < points.length; j++) { - tag = points[j].childNodes[0].id; - id = ID.index(tag); - if (i !== id) { - document.getElementById(self._addUID("GPlocationOriginPointer_" + id)).checked = false; - if (document.getElementById(self._addUID("GPlocationOriginCoords_" + id)).value === "Pointer un lieu sur la carte") { - document.getElementById(self._addUID("GPlocationOriginCoords_" + id)).value = ""; - document.getElementById(self._addUID("GPlocationOrigin_" + id)).className = "GPelementShow gpf-show gpf-input fr-input"; - document.getElementById(self._addUID("GPlocationOriginCoords_" + id)).className = "GPelementHidden gpf-hidden"; - } - } - } - if (document.getElementById(self._addUID("GPlocationOriginPointer_" + i)).checked) { - document.getElementById(self._addUID("GPlocationOriginCoords_" + i)).value = ""; - for (j = 0; j < points.length; j++) { - tag = points[j].childNodes[0].id; - id = ID.index(tag); - document.getElementById(self._addUID("GPlocationPoint_" + id)).style.cssText = ""; - } - if (document.getElementById(self._addUID("GPlocationStageRemove_" + i))) { - document.getElementById(self._addUID("GPlocationStageRemove_" + i)).className = "GPlocationStageRemove gpf-btn gpf-btn-icon-remove fr-btn--sm fr-btn--secondary"; - } - if (document.getElementById(self._addUID("GPlocationStageAdd"))) { - document.getElementById(self._addUID("GPlocationStageAdd")).className = "GPlocationStageAdd gpf-btn gpf-btn-icon-add fr-btn--sm fr-btn--secondary"; - } - document.getElementById(self._addUID("GPlocationOriginPointer_" + i)).checked = false; - document.getElementById(self._addUID("GPlocationOrigin_" + i)).className = "GPelementShow gpf-show gpf-input fr-input"; - document.getElementById(self._addUID("GPlocationOriginCoords_" + i)).className = "GPelementHidden gpf-hidden"; - } else { - document.getElementById(self._addUID("GPlocationOriginCoords_" + i)).value = "Pointer un lieu sur la carte"; - for (j = 0; j < points.length; j++) { - tag = points[j].childNodes[0].id; - id = ID.index(tag); - if (i === id) { - document.getElementById(self._addUID("GPlocationPoint_" + id)).style.cssText = ""; - } else { - document.getElementById(self._addUID("GPlocationPoint_" + id)).style.display = "none"; - } - } - if (document.getElementById(self._addUID("GPlocationStageRemove_" + i))) { - document.getElementById(self._addUID("GPlocationStageRemove_" + i)).className = "GPelementHidden gpf-hidden"; - } - if (document.getElementById(self._addUID("GPlocationStageAdd"))) { - document.getElementById(self._addUID("GPlocationStageAdd")).className = "GPelementHidden gpf-hidden"; - } - document.getElementById(self._addUID("GPlocationOriginPointer_" + i)).checked = true; - document.getElementById(self._addUID("GPlocationOrigin_" + i)).className = "GPelementHidden gpf-hidden"; - document.getElementById(self._addUID("GPlocationOriginCoords_" + i)).className = "GPelementShow gpf-show gpf-input fr-input"; - document.getElementById(self._addUID("GPlocationOriginCoords_" + i)).disabled = true; - } - // gestionnaire d'evenement : - // on stocke la valeur du point, utilisée pour la requête sur le service de calcul d'itiniraire - self.onActivateMapPointClick(e); - }); - - return buttonOriginPointer; - }, - - /** - * Create Remove Point tag - * see event ! - * - * @param {Number} id - tag ID - * @returns {DOMElement} DOM element - */ - _createLocationRemovePointElement : function (id) { - // contexte d'execution - var self = this; - - var buttonRm = document.createElement("button"); - buttonRm.id = this._addUID("GPlocationStageRemove_" + id); - buttonRm.className = "GPlocationOpen GPlocationStageRemove gpf-btn gpf-btn-icon-remove fr-btn--sm fr-btn--secondary"; - buttonRm.title = "Supprimer l'étape"; - buttonRm.setAttribute("tabindex", "0"); - buttonRm.setAttribute("aria-pressed", false); - buttonRm.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - var points = document.getElementsByClassName(self._addUID("GPlocationPoint")); - var last = points.length - 1; - var start = points[0].childNodes[0].id; - var end = points[last].childNodes[0].id; - - var startID = ID.index(start); - var endID = ID.index(end); - - if (id !== startID && id !== endID) { - var i = ID.index(this.id); - document.getElementById(self._addUID("GPlocationPoint_" + i)).className = "GPflexInput GPelementHidden gpf-flex gpf-hidden"; - document.getElementById(self._addUID("GPlocationOrigin_" + i)).value = ""; - document.getElementById(self._addUID("GPlocationOrigin_" + i)).className = "GPelementShow gpf-show gpf-input fr-input"; - document.getElementById(self._addUID("GPlocationOriginCoords_" + i)).value = ""; - document.getElementById(self._addUID("GPlocationOriginCoords_" + i)).className = "GPelementHidden gpf-hidden"; - document.getElementById(self._addUID("GPlocationStageAdd")).style.display = ""; - // Moving up exclusions picto - // var exclusionsPictoTop = document.getElementById(self._addUID("GPshowLocationExclusionsPicto")).style.top; - // document.getElementById(self._addUID("GPshowLocationExclusionsPicto")).style.top = (parseInt(exclusionsPictoTop) - 33).toString() + "px"; - - // gestionnaire d'evenement : - // on supprime le point, utilisé pour la requête sur le service d'itiniraire - self.onLocationRemovePointClick(e); - } - }); - - return buttonRm; - }, - - /** - * Create Add Point tag - * see event ! - * - * @returns {DOMElement} DOM element - */ - _createLocationAddPointElement : function () { - // contexte d'execution - var self = this; - - var buttonAdd = document.createElement("button"); - buttonAdd.id = this._addUID("GPlocationStageAdd"); - buttonAdd.className = "GPlocationOpen GPlocationStageAdd gpf-btn gpf-btn-icon-add fr-btn--sm fr-btn--secondary"; - buttonAdd.title = "Ajouter une étape"; - buttonAdd.setAttribute("tabindex", "0"); - buttonAdd.setAttribute("aria-pressed", false); - buttonAdd.addEventListener("click", function (e) { - var lastStage = 1; - var nbStages = 0; - var points = document.getElementsByClassName(self._addUID("GPlocationPoint")); - for (var i = 1; i < points.length - 1; i++) { - var tag = points[i].childNodes[0].id; - var id = ID.index(tag); - if (document.getElementById(self._addUID("GPlocationPoint_" + id))) { - if (document.getElementById(self._addUID("GPlocationPoint_" + id)).className === "GPflexInput GPelementHidden gpf-flex gpf-hidden") { - if (lastStage === 1) { - lastStage = id; - } - } else { - nbStages++; - } - } - } - // FIXME algo à revoir : lastStage = id hors si id = 300 sur 3 points !? - if (lastStage < points.length) { - document.getElementById(self._addUID("GPlocationPoint_" + lastStage)).className = "GPflexInput GPlocationStageFlexInput gpf-flex"; - // Moving down exclusions picto - // var exclusionsPictoTop = document.getElementById(self._addUID("GPshowLocationExclusionsPicto")).style.top; - // document.getElementById(self._addUID("GPshowLocationExclusionsPicto")).style.top = (parseInt(exclusionsPictoTop) + 33).toString() + "px"; - } - if (nbStages === 4) { - document.getElementById(self._addUID("GPlocationStageAdd")).style.display = "none"; - } - // gestionnaire d'evenement : - // on ajoute le point, utilisé pour la requête sur le service d'itiniraire - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onLocationAddPointClick(e); - }); - - return buttonAdd; - }, - - _createLocationAutoCompleteElement : function (id) { - var div = document.createElement("div"); - div.id = this._addUID("GPlocationAutoCompleteList_" + id); - div.className = "GPlocationAutoCompleteList GPelementHidden gpf-panel gpf-hidden fr-modal"; // GPpanel ? - - // FIXME on decompose la fonction pour les besoins du controle, - // on ajoutera ces childs à la main... - // div.appendChild(this._createLocationAutoCompleteResultElement ()); - - return div; - }, - - /** - * Create Results autocompletion to the point - * see event! - * - * @param {Number} id - tag ID - * @returns {DOMElement} DOM element - */ - _createLocationAutoCompleteResultElement : function (id) { - // contexte d'execution - var self = this; - - var div = document.createElement("div"); - div.id = this._addUID("GPlocationAutoCompleteResult_" + id); - div.className = "GPadvancedAutoCompleteResult gpf-panel__list"; - - if (div.addEventListener) { - div.addEventListener("click", function (e) { - self.onAutoCompletedResultsItemClick(e); - document.getElementById(self._addUID("GPlocationAutoCompleteList_" + id)).classList.replace("GPelementHidden", "GPelementVisible"); - document.getElementById(self._addUID("GPlocationAutoCompleteList_" + id)).classList.replace("gpf-hidden", "gpf-visible"); - }, false); - } else if (div.attachEvent) { - div.attachEvent("onclick", function (e) { - self.onAutoCompletedResultsItemClick(e); - document.getElementById(self._addUID("GPlocationAutoCompleteList_" + id)).classList.replace("GPelementHidden", "GPelementVisible"); - document.getElementById(self._addUID("GPlocationAutoCompleteList_" + id)).classList.replace("gpf-hidden", "gpf-visible"); - }); - } - - return div; - }, - - /** - * Autocompletion result to a point. - * Proposals are dynamically filled in Javascript by autocomplete service - * - * TODO formaliser le contenu des reponse - * - * @param {Number} id - tag ID - * @param {Object} location - suggested location result - * @param {Number} n - number of the point - */ - _createLocationAutoCompletedLocationElement : function (id, location, n) { - var container = document.getElementById(this._addUID("GPlocationAutoCompleteResult_" + id)); - - var div = document.createElement("div"); - div.id = this._addUID("AutoCompletedLocation_" + n); - div.className = "GPautoCompleteProposal gpf-panel__items"; - div.innerHTML = GeocodeUtils.getSuggestedLocationFreeform(location); - - container.appendChild(div); - }, - - /** - * Display Coordinate - * @param {String} value - a Coordinate - */ - GPdisplayCoordinate : function (value) { - var points = document.getElementsByClassName(this._addUID("GPlocationPoint")); - for (var i = 0; i < points.length; i++) { - var tag = points[i].childNodes[0].id; - var id1 = ID.index(tag); - if (document.getElementById(this._addUID("GPlocationOriginPointer_" + id1)).checked) { - document.getElementById(this._addUID("GPlocationOriginCoords_" + id1)).value = value; - document.getElementById(this._addUID("GPlocationOriginCoords_" + id1)).disabled = false; - for (var j = 0; j < points.length; j++) { - tag = points[j].childNodes[0].id; - var id2 = ID.index(tag); - document.getElementById(this._addUID("GPlocationPoint_" + id2)).style.cssText = ""; - if (document.getElementById(this._addUID("GPlocationStageRemove_" + id2))) { - document.getElementById(this._addUID("GPlocationStageRemove_" + id2)).className = "GPlocationStageRemove gpf-btn gpf-btn-icon-remove fr-btn--sm fr-btn--secondary"; - } - } - document.getElementById(this._addUID("GPlocationOriginPointer_" + id1)).checked = false; - if (document.getElementById(this._addUID("GPlocationStageAdd"))) { - document.getElementById(this._addUID("GPlocationStageAdd")).className = "GPlocationStageAdd gpf-btn gpf-btn-icon-add fr-btn--sm"; - } - return; - } - } - } -}; - -export default LocationSelectorDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureArea.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureArea.d.ts deleted file mode 100644 index b96aa59dd..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureArea.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -export default MeasureArea; -/** - * @classdesc - * - * Tool Measure Area Control. Allows users to measure the length of a path drawn on the map. - * - * @constructor - * @alias ol.control.MeasureArea - * @type {ol.control.MeasureArea} - * @extends {ol.control.Control} - * @param {Object} options - options for function call. - * @param {Boolean} [options.geodesic = true] - If true, area will be computed on the global sphere using the {@link https://openlayers.org/en/latest/apidoc/module-ol_sphere.html#geodesicArea ol.Sphere.geodesicArea()} function. Otherwise, area will be computed on the projected plane. - * @param {Object} [options.styles = {}] - styles used when drawing. Specified with following properties. - * @param {Object} [options.styles.pointer = {}] - Style for mouse pointer when drawing the polygon to measure. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Image-ImageStyle.html ol.style.Image} subclass object. - * @param {Object} [options.styles.start = {}] - Polygon Style when drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Style-Style.htmll ol.style.Style} object. - * @param {Object} [options.styles.finish = {}] - Polygon Style when finished drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Style-Style.htmll ol.style.Style} object. - * - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Mesures de surface"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Mes mesures"] - Layer description to be displayed in LayerSwitcher - * @example - * var measureArea = new ol.control.MeasureArea({ - * geodesic : false - * }); - */ -declare var MeasureArea: ol.control.MeasureArea; -//# sourceMappingURL=MeasureArea.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureArea.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureArea.d.ts.map deleted file mode 100644 index 7036c901c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureArea.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MeasureArea.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Measures/MeasureArea.js"],"names":[],"mappings":";AAsBA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,gDAmPE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureArea.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureArea.js deleted file mode 100644 index 8a58a6cc0..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureArea.js +++ /dev/null @@ -1,302 +0,0 @@ -// import CSS -import "../../CSS/Controls/Measures/GPFmeasureArea.css"; -// import "../../CSS/Controls/Measures/GPFmeasureAreaStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -import { getArea as olGetAreaSphere } from "ol/sphere"; -import { Polygon } from "ol/geom"; -// import local -import Logger from "../../Utils/LoggerByDefault"; -import ID from "../../Utils/SelectorID"; -// DOM -import MeasureAreaDOM from "./MeasureAreaDOM"; -// import local with ol dependencies -import Measures from "./Measures"; -import MeasureToolBox from "../ToolBoxMeasure/MeasureToolBox"; - -// Derived from OpenLayers measure example -// http://openlayers.org/en/latest/examples/measure.html - -var logger = Logger.getLogger("measurearea"); - -/** - * @classdesc - * - * Tool Measure Area Control. Allows users to measure the length of a path drawn on the map. - * - * @constructor - * @alias ol.control.MeasureArea - * @type {ol.control.MeasureArea} - * @extends {ol.control.Control} - * @param {Object} options - options for function call. - * @param {Boolean} [options.geodesic = true] - If true, area will be computed on the global sphere using the {@link https://openlayers.org/en/latest/apidoc/module-ol_sphere.html#geodesicArea ol.Sphere.geodesicArea()} function. Otherwise, area will be computed on the projected plane. - * @param {Object} [options.styles = {}] - styles used when drawing. Specified with following properties. - * @param {Object} [options.styles.pointer = {}] - Style for mouse pointer when drawing the polygon to measure. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Image-ImageStyle.html ol.style.Image} subclass object. - * @param {Object} [options.styles.start = {}] - Polygon Style when drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Style-Style.htmll ol.style.Style} object. - * @param {Object} [options.styles.finish = {}] - Polygon Style when finished drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Style-Style.htmll ol.style.Style} object. - * - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Mesures de surface"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Mes mesures"] - Layer description to be displayed in LayerSwitcher - * @example - * var measureArea = new ol.control.MeasureArea({ - * geodesic : false - * }); - */ -var MeasureArea = class MeasureArea extends Control { - - constructor (options) { - /** - * options - * @private - */ - options = options || {}; - - // call ol.control.Control constructor - super({ - element : options.element, - target : options.target, - render : options.render - }); - - if (!(this instanceof MeasureArea)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - /** - * Nom de la classe (heritage) - * @private - */ - this.CLASSNAME = "MeasureArea"; - - // uuid - this._uid = ID.generate(); - - // container d'activation du controle - this._pictoContainer = null; - - // initialisation du composant - this._initialize(options); - - // creation du DOM container - this._container = this._initializeContainer(); - - // ajout du container - (this.element) ? this.element.appendChild(this._container) : this.element = this._container; - - return this; - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - - /** - * Overwrite OpenLayers setMap method - * - * @param {ol.Map} map - Map. - */ - setMap (map) { - logger.trace("setMap()"); - - var className = this.CLASSNAME; - - // on fait le choix de ne pas activer les events sur la map à l'init de l'outil, - // mais uniquement à son utilisation ! - if (map) { - // var self = this; - // map.on("click", function (e) { - // logger.trace("event on map with click!"); - // self.onPointerMoveHandler(e); - // }); - // - // map.on("singleclick", function (e) { - // logger.trace("event on map with singleclick!"); - // self.onPointerMoveHandler(e); - // }); - // - // map.on("pointermove", function (e) { - // logger.trace("event on map with pointermove!"); - // self.onPointerMoveHandler(e); - // }); - - if (!this.options.target && !this.options.position) { - MeasureToolBox.add(map, this); - } - } else { - this.clean(); - } - - // sauvegarde de l'état de l'outil - this.tools[className].push({ - instance : (map) ? this : null, - active : false, - map : (map) ? map.getTargetElement().id : null - }); - - // contexte d'execution - var context = typeof window !== "undefined" ? window : typeof self !== "undefined" ? self : null; - if (context) { - // Pour info - // les objets de mesures ont du code partagé - // (afin de gerer les interactions entre eux). - // Dans un mode "modules", on partage cet objet (this.tools) via le contexte - // d'execution (ex. avec window) - if (!context.gpShareMeasures) { - context.gpShareMeasures = {}; - } - context.gpShareMeasures[className] = this.tools[className]; - } - - // on appelle la méthode setMap originale d'OpenLayers - super.setMap(map); - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - } - - // ################################################################### // - // ##################### init component ############################## // - // ################################################################### // - - /** - * Initialize measure control (called by constructor) - * - * @param {Object} options - options - * - * @private - */ - _initialize (options) { - logger.trace("call MeasureArea::_initialize() : ", options); - - // liste des options - this.options = {}; - this.options.geodesic = (typeof options.geodesic !== "undefined") ? options.geodesic : true; - this.options.position = (typeof options.position !== "undefined") ? options.position : null; - this.options.target = (typeof options.target !== "undefined") ? options.target : null; - this.options.render = (typeof options.render !== "undefined") ? options.render : null; - this.options.layerDescription = (typeof options.layerDescription !== "undefined") ? options.layerDescription : { - title : "Mesures de surface", - description : "Mes mesures" - }; - - // gestion des styles ! - this.createStylingMeasureInteraction(options.styles); - } - - /** - * initialize component container (DOM) - * - * @returns {DOMElement} DOM element - * - * @private - */ - _initializeContainer () { - logger.trace("call MeasureArea::_initializeContainer() : ", this._uid); - - var container = this._createMainContainerElement(); ; - - var picto = this._pictoContainer = this._createShowMeasureAreaPictoElement(); - container.appendChild(picto); - - return container; - } - - // ################################################################### // - // ##################### overridden methods ########################## // - // ################################################################### // - - /** - * Add all events on map - * - * @private - */ - addMeasureEvents () { - logger.trace("call MeasureArea::addMeasureEvents()"); - - var map = this.getMap(); - - map.on("singleclick", (e) => this.onPointerMoveHandler(e)); - map.on("pointermove", (e) => this.onPointerMoveHandler(e)); - } - - /** - * Remove all events on map - * - * @private - */ - removeMeasureEvents () { - logger.trace("call MeasureArea::removeMeasureEvents()"); - - var map = this.getMap(); - - map.un("singleclick", (e) => this.onPointerMoveHandler(e)); - map.un("pointermove", (e) => this.onPointerMoveHandler(e)); - } - - /** - * Format length output. - * - * @param {ol.geom.Polygon} polygon - geometry polygon. - * @return {String} The formatted output. - * @private - */ - format (polygon) { - logger.trace("call MeasureArea::format()"); - - var measure; - if (this.options.geodesic) { - var geom = polygon.clone(); - var coordinates = geom.getLinearRing(0).getCoordinates(); - measure = Math.abs(olGetAreaSphere(new Polygon([coordinates]))); - } else { - measure = polygon.getArea(); - } - - var output; - if (measure > 1000000) { - output = (Math.round(measure / 1000000 * 100) / 100) + " " + "km2"; - } else if (measure > 100000) { - output = (Math.round(measure / 1000000 * 1000) / 1000) + " " + "km2"; - } else if (measure > 1000) { - output = (Math.round(measure / 10) * 10) + " " + "m2"; - } else { - output = (Math.round(measure * 100) / 100) + " " + "m2"; - } - return output; - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - - /** - * this method is called by event 'click' on picto - * - * @param {Object} e - HTMLElement - * - * @private - */ - onShowMeasureAreaClick (e) { - logger.trace("call MeasureArea::onShowMeasureAreaClick()", e); - - // appel de la methode commune - this.onShowMeasureClick(e, "Polygon"); - } - -}; - -// on récupère les mixins de la classe "MeasureAreaDOM" ainsi que celles -// de "Measures". -Object.assign(MeasureArea.prototype, Measures); -Object.assign(MeasureArea.prototype, MeasureAreaDOM); - -export default MeasureArea; - -// Expose MeasureArea as ol.control.MeasureArea (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.MeasureArea = MeasureArea; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAreaDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAreaDOM.d.ts deleted file mode 100644 index 91d48c562..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAreaDOM.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default MeasureAreaDOM; -declare namespace MeasureAreaDOM { - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createShowMeasureAreaPictoElement(): DOMElement; -} -//# sourceMappingURL=MeasureAreaDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAreaDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAreaDOM.d.ts.map deleted file mode 100644 index 952124c4c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAreaDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MeasureAreaDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Measures/MeasureAreaDOM.js"],"names":[],"mappings":";;IAOc,qCAGT;IAO6B,mDAK7B;IAYoC,0DA+BpC"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAreaDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAreaDOM.js deleted file mode 100644 index 90c6c2e74..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAreaDOM.js +++ /dev/null @@ -1,69 +0,0 @@ -var MeasureAreaDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Main container (DOM) - * - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPmeasureArea"); - container.className = "GPwidget gpf-widget gpf-widget-button"; - return container; - }, - - // ################################################################### // - // ################### Methods of main container ##################### // - // ################################################################### // - - /** - * Show control - * see event ! - * - * @returns {DOMElement} DOM element - */ - _createShowMeasureAreaPictoElement : function () { - // contexte d'execution - var context = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowMeasureAreaPicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto gpf-btn gpf-btn-icon gpf-btn-icon-area fr-btn"; - button.title = "Mesurer une surface"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - - // gestionnaire d'evenement : - // on ouvre le menu de saisie... - // L'ouverture/Fermeture permet de faire le menage - // (reinitialisation) - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowMeasureAreaClick(e); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowMeasureAreaClick(e); - }); - } - - return button; - } -}; - -export default MeasureAreaDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuth.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuth.d.ts deleted file mode 100644 index 0a81e72a6..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuth.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -export default MeasureAzimuth; -/** - * @classdesc - * - * Azimuth measurement Control. Allows users to draw a line on an Openlayers map and have its angle in decimal degrees clockwise from the geographical north. - * - * @constructor - * @alias ol.control.MeasureAzimuth - * @type {ol.control.MeasureAzimuth} - * @extends {ol.control.Control} - * @param {Object} options - options for function call. - * @param {Boolean} [options.geodesic = false] - If true, azimuth will be computed on the global sphere. Otherwise, it will be computed on the projected plane. - * @param {Object} [options.styles = {}] - styles used when drawing. Specified with following properties. - * @param {Object} [options.styles.pointer = {}] - Style for mouse pointer when drawing the line. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Image-ImageStyle.html ol.style.Image} subclass object. - * @param {Object} [options.styles.start = {}] - Line Style when drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Style-Style.htmll ol.style.Style} object. - * @param {Object} [options.styles.finish = {}] - Line Style when finished drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Style-Style.htmll ol.style.Style} object. - * - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Mesures d'azimuth"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Mes mesures"] - Layer description to be displayed in LayerSwitcher - * @example - * var measure = new ol.control.MeasureAzimuth({ - * geodesic : true - * }); - */ -declare var MeasureAzimuth: ol.control.MeasureAzimuth; -//# sourceMappingURL=MeasureAzimuth.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuth.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuth.d.ts.map deleted file mode 100644 index accc31ba3..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuth.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MeasureAzimuth.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Measures/MeasureAzimuth.js"],"names":[],"mappings":";AAsBA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,sDA0SE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuth.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuth.js deleted file mode 100644 index 7e62ac791..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuth.js +++ /dev/null @@ -1,357 +0,0 @@ -// import CSS -import "../../CSS/Controls/Measures/GPFmeasureAzimuth.css"; -// import "../../CSS/Controls/Measures/GPFmeasureAzimuthStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -import { getDistance as olGetDistanceSphere } from "ol/sphere"; -import { transform as olTransformProj } from "ol/proj"; -// import local -import Logger from "../../Utils/LoggerByDefault"; -import ID from "../../Utils/SelectorID"; -// DOM -import MeasureAzimuthDOM from "./MeasureAzimuthDOM"; -// import local with ol dependencies -import MeasureToolBox from "../ToolBoxMeasure/MeasureToolBox"; -import Measures from "./Measures"; - -// Derived from OpenLayers measure example -// http://openlayers.org/en/latest/examples/measure.html - -var logger = Logger.getLogger("measureazimut"); - -/** - * @classdesc - * - * Azimuth measurement Control. Allows users to draw a line on an Openlayers map and have its angle in decimal degrees clockwise from the geographical north. - * - * @constructor - * @alias ol.control.MeasureAzimuth - * @type {ol.control.MeasureAzimuth} - * @extends {ol.control.Control} - * @param {Object} options - options for function call. - * @param {Boolean} [options.geodesic = false] - If true, azimuth will be computed on the global sphere. Otherwise, it will be computed on the projected plane. - * @param {Object} [options.styles = {}] - styles used when drawing. Specified with following properties. - * @param {Object} [options.styles.pointer = {}] - Style for mouse pointer when drawing the line. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Image-ImageStyle.html ol.style.Image} subclass object. - * @param {Object} [options.styles.start = {}] - Line Style when drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Style-Style.htmll ol.style.Style} object. - * @param {Object} [options.styles.finish = {}] - Line Style when finished drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Style-Style.htmll ol.style.Style} object. - * - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Mesures d'azimuth"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Mes mesures"] - Layer description to be displayed in LayerSwitcher - * @example - * var measure = new ol.control.MeasureAzimuth({ - * geodesic : true - * }); - */ -var MeasureAzimuth = class MeasureAzimuth extends Control { - - constructor (options) { - /** - * options - * @private - */ - options = options || {}; - - // call ol.control.Control constructor - super({ - element : options.element, - target : options.target, - render : options.render - }); - - if (!(this instanceof MeasureAzimuth)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - /** - * Nom de la classe (heritage) - * @private - */ - this.CLASSNAME = "MeasureAzimuth"; - - // uuid - this._uid = ID.generate(); - - // container d'activation du controle - this._pictoContainer = null; - - // initialisation du composant - this._initialize(options); - - // creation du DOM container - this._container = this._initializeContainer(); - - // ajout du container - (this.element) ? this.element.appendChild(this._container) : this.element = this._container; - - return this; - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - - /** - * Overwrite OpenLayers setMap method - * - * @param {ol.Map} map - Map. - */ - setMap (map) { - logger.trace("setMap()"); - - var className = this.CLASSNAME; - - // on fait le choix de ne pas activer les events sur la map à l'init de l'outil, - // mais uniquement à son utilisation ! - if (map) { - // var self = this; - // map.on("click", function (e) { - // logger.trace("event on map with click!"); - // self.onPointerMoveAzimutHandler(e); - // }); - // - // map.on("singleclick", function (e) { - // logger.trace("event on map with singleclick!"); - // self.onPointerMoveAzimutHandler(e); - // }); - // - // map.on("pointermove", function (e) { - // logger.trace("event on map with pointermove!"); - // self.onPointerMoveAzimutHandler(e); - // }); - - if (!this.options.target && !this.options.position) { - MeasureToolBox.add(map, this); - } - } else { - this.clean(); - } - - // sauvegarde de l'état de l'outil - this.tools[className].push({ - instance : (map) ? this : null, - active : false, - map : (map) ? map.getTargetElement().id : null - }); - - // contexte d'execution - var context = typeof window !== "undefined" ? window : typeof self !== "undefined" ? self : null; - if (context) { - // Pour info - // les objets de mesures ont du code partagé - // (afin de gerer les interactions entre eux). - // Dans un mode "modules", on partage cet objet (this.tools) via le contexte - // d'execution (ex. avec window) - if (!context.gpShareMeasures) { - context.gpShareMeasures = {}; - } - context.gpShareMeasures[className] = this.tools[className]; - } - - // on appelle la méthode setMap originale d'OpenLayers - super.setMap(map); - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - } - - /** - * Setter for option Geodesic - * - * @param {Boolean} value - geodesic value - */ - setGeodesic (value) { - this.options.geodesic = (typeof value !== "undefined") ? value : false; - } - - /** - * Getter for option Geodesic - * - * @return {Boolean} geodesic value - */ - isGeodesic () { - return this.options.geodesic; - } - - // ################################################################### // - // ##################### init component ############################## // - // ################################################################### // - - /** - * Initialize measure control (called by constructor) - * - * @param {Object} options - options - * - * @private - */ - _initialize (options) { - logger.trace("call MeasureAzimuth::_initialize() : ", options); - - // liste des options - this.options = {}; - this.options.geodesic = (typeof options.geodesic !== "undefined") ? options.geodesic : false; - this.options.position = (typeof options.position !== "undefined") ? options.position : null; - this.options.target = (typeof options.target !== "undefined") ? options.target : null; - this.options.render = (typeof options.render !== "undefined") ? options.render : null; - this.options.layerDescription = (typeof options.layerDescription !== "undefined") ? options.layerDescription : { - title : "Mesures d'azimuth", - description : "Mes mesures" - }; - - // gestion des styles ! - this.createStylingMeasureInteraction(options.styles); - } - - /** - * initialize component container (DOM) - * - * @returns {DOMElement} DOM element - * - * @private - */ - _initializeContainer () { - logger.trace("call MeasureAzimuth::_initializeContainer() : ", this._uid); - - var container = this._createMainContainerElement(); ; - - var picto = this._pictoContainer = this._createShowMeasureAzimuthPictoElement(); - container.appendChild(picto); - - return container; - } - - // ################################################################### // - // ##################### overridden methods ########################## // - // ################################################################### // - - /** - * Add all events on map - * - * @private - */ - addMeasureEvents () { - logger.trace("call MeasureAzimuth::addMeasureEvents()"); - - var map = this.getMap(); - - map.on("singleclick", (e) => this.onPointerMoveAzimutHandler(e)); - map.on("pointermove", (e) => this.onPointerMoveAzimutHandler(e)); - } - - /** - * Remove all events on map - * - * @private - */ - removeMeasureEvents () { - logger.trace("call MeasureAzimuth::removeMeasureEvents()"); - - var map = this.getMap(); - - map.un("singleclick", (e) => this.onPointerMoveAzimutHandler(e)); - map.un("pointermove", (e) => this.onPointerMoveAzimutHandler(e)); - } - - /** - * Format length output. - * - * @param {ol.geom.LineString} line - geometry line. - * @return {String} The formatted output. - * @private - */ - format (line) { - logger.trace("call MeasureAzimuth::format()"); - - var map = this.getMap(); - - var sourceProj = map.getView().getProjection(); - - var c1 = olTransformProj(line.getFirstCoordinate(), sourceProj, "EPSG:4326"); - var c2 = olTransformProj(line.getLastCoordinate(), sourceProj, "EPSG:4326"); - - if (!this.options.geodesic) { - // TODO calcul sur une petite distance (>500m) afin de simuler un cap ! - var lengthGeodesic = olGetDistanceSphere(c1, c2); - logger.trace("measure between 2 points with geodesic method", lengthGeodesic); - if (lengthGeodesic > 500) { - var fraction = 500.0 / lengthGeodesic; - logger.trace("%", fraction); - c2 = olTransformProj(line.getCoordinateAt(fraction), sourceProj, "EPSG:4326"); - } - } - - var degrees2radians = Math.PI / 180; - var radians2degrees = 180 / Math.PI; - - var lon1 = degrees2radians * c1[0]; - var lon2 = degrees2radians * c2[0]; - - var lat1 = degrees2radians * c1[1]; - var lat2 = degrees2radians * c2[1]; - - var a = Math.sin(lon2 - lon1) * Math.cos(lat2); - var b = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1); - - var atan = Math.atan2(a, b); - - var azimut = radians2degrees * atan; - logger.trace("azimut", azimut); - - if (azimut < 0) { - azimut += 360; - } - var output = Math.round(azimut * 100) / 100 + " °"; - - return output; - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - - /** - * this method is called by event 'click' on picto - * - * @param {Object} e - HTMLElement - * @private - */ - onShowMeasureAzimuthClick (e) { - logger.trace("call MeasureAzimuth::onShowMeasureAzimuthClick()", e); - - // appel de la methode commune - this.onShowMeasureClick(e, "LineString"); - } - - /** - * Handle pointer click. - * - * @param {ol.MapBrowserEvent} e - The event. - * @private - */ - onPointerMoveAzimutHandler (e) { - this.onPointerMoveHandler(e); - - if (this.sketch) { - var geom = (/** @type {ol.geom.LineString} */ (this.sketch.getGeometry())); - if (geom.getCoordinates().length > 2) { - this.measureDraw.finishDrawing(); - } - } - } - -}; - -// on récupère les mixins de la classe "MeasureAreaDOM" ainsi que celles -// de "Measures". -Object.assign(MeasureAzimuth.prototype, Measures); -Object.assign(MeasureAzimuth.prototype, MeasureAzimuthDOM); - -export default MeasureAzimuth; - -// Expose MeasureAzimuth as ol.control.MeasureAzimuth (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.MeasureAzimuth = MeasureAzimuth; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuthDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuthDOM.d.ts deleted file mode 100644 index 20bd93e98..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuthDOM.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default MeasureAzimuthDOM; -declare namespace MeasureAzimuthDOM { - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createShowMeasureAzimuthPictoElement(): DOMElement; -} -//# sourceMappingURL=MeasureAzimuthDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuthDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuthDOM.d.ts.map deleted file mode 100644 index 2fc40f089..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuthDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MeasureAzimuthDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Measures/MeasureAzimuthDOM.js"],"names":[],"mappings":";;IAOc,qCAGT;IAO6B,mDAK7B;IAYuC,6DA+BvC"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuthDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuthDOM.js deleted file mode 100644 index 19bb89463..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureAzimuthDOM.js +++ /dev/null @@ -1,69 +0,0 @@ -var MeasureAzimuthDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Main container (DOM) - * - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPmeasureAzimuth"); - container.className = "GPwidget gpf-widget gpf-widget-button"; - return container; - }, - - // ################################################################### // - // ################### Methods of main container ##################### // - // ################################################################### // - - /** - * Show control - * see event ! - * - * @returns {DOMElement} DOM element - */ - _createShowMeasureAzimuthPictoElement : function () { - // contexte d'execution - var context = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowMeasureAzimuthPicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto gpf-btn gpf-btn-icon gpf-btn-icon-azimuth fr-btn"; - button.title = "Mesurer un azimut"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - - // gestionnaire d'evenement : - // on ouvre le menu de saisie... - // L'ouverture/Fermeture permet de faire le menage - // (reinitialisation) - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowMeasureAzimuthClick(e); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowMeasureAzimuthClick(e); - }); - } - - return button; - } -}; - -export default MeasureAzimuthDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLength.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLength.d.ts deleted file mode 100644 index b8352620a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLength.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -export default MeasureLength; -/** - * @classdesc - * - * Length measurement Control. Allows users to draw a path on Openlayers map and have its length computed and displayed. - * - * @constructor - * @alias ol.control.MeasureLength - * @type {ol.control.MeasureLength} - * @extends {ol.control.Control} - * @param {Object} options - options for function call. - * @param {Boolean} [options.geodesic = true] - If true, length will be computed on the global sphere using the {@link https://openlayers.org/en/latest/apidoc/module-ol_sphere.html#haversineDistance ol.Sphere.haversineDistance()} function. Otherwise, length will be computed on the projected plane. - * @param {Object} [options.styles = {}] - styles used when drawing. Specified with following properties. - * @param {Object} [options.styles.pointer = {}] - Style for mouse pointer when drawing the path. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Image-ImageStyle.html ol.style.Image} subclass object. - * @param {Object} [options.styles.start = {}] - Line Style when drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Style-Style.htmll ol.style.Style} object. - * @param {Object} [options.styles.finish = {}] - Line Style when finished drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Style-Style.htmll ol.style.Style} object. - * - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Mesures de distance"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Mes mesures"] - Layer description to be displayed in LayerSwitcher - * @example - * var measureLength = new ol.control.MeasureLength({ - * geodesic : false - * }); - */ -declare var MeasureLength: ol.control.MeasureLength; -//# sourceMappingURL=MeasureLength.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLength.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLength.d.ts.map deleted file mode 100644 index 79365ab47..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLength.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MeasureLength.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Measures/MeasureLength.js"],"names":[],"mappings":";AAsBA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,oDAgPE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLength.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLength.js deleted file mode 100644 index d78a741f2..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLength.js +++ /dev/null @@ -1,299 +0,0 @@ -// import CSS -import "../../CSS/Controls/Measures/GPFmeasureLength.css"; -// import "../../CSS/Controls/Measures/GPFmeasureLengthStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -import { getDistance as olGetDistanceSphere } from "ol/sphere"; -import { transform as olTransformProj } from "ol/proj"; -// import local -import Logger from "../../Utils/LoggerByDefault"; -import ID from "../../Utils/SelectorID"; -// DOM -import MeasureLengthDOM from "./MeasureLengthDOM"; -// import local with ol dependencies -import MeasureToolBox from "../ToolBoxMeasure/MeasureToolBox"; -import Measures from "./Measures"; - -// Derived from OpenLayers measure example -// http://openlayers.org/en/latest/examples/measure.html - -var logger = Logger.getLogger("measurelength"); - -/** - * @classdesc - * - * Length measurement Control. Allows users to draw a path on Openlayers map and have its length computed and displayed. - * - * @constructor - * @alias ol.control.MeasureLength - * @type {ol.control.MeasureLength} - * @extends {ol.control.Control} - * @param {Object} options - options for function call. - * @param {Boolean} [options.geodesic = true] - If true, length will be computed on the global sphere using the {@link https://openlayers.org/en/latest/apidoc/module-ol_sphere.html#haversineDistance ol.Sphere.haversineDistance()} function. Otherwise, length will be computed on the projected plane. - * @param {Object} [options.styles = {}] - styles used when drawing. Specified with following properties. - * @param {Object} [options.styles.pointer = {}] - Style for mouse pointer when drawing the path. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Image-ImageStyle.html ol.style.Image} subclass object. - * @param {Object} [options.styles.start = {}] - Line Style when drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Style-Style.htmll ol.style.Style} object. - * @param {Object} [options.styles.finish = {}] - Line Style when finished drawing. Specified with an {@link https://openlayers.org/en/latest/apidoc/module-ol_style_Style-Style.htmll ol.style.Style} object. - * - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Mesures de distance"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Mes mesures"] - Layer description to be displayed in LayerSwitcher - * @example - * var measureLength = new ol.control.MeasureLength({ - * geodesic : false - * }); - */ -var MeasureLength = class MeasureLength extends Control { - - constructor (options) { - // options - options = options || {}; - - // call ol.control.Control constructor - super({ - element : options.element, - target : options.target, - render : options.render - }); - - if (!(this instanceof MeasureLength)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - // Nom de la classe (heritage) - this.CLASSNAME = "MeasureLength"; - - // uuid - this._uid = ID.generate(); - - // container d'activation du controle - this._pictoContainer = null; - - // initialisation du composant - this._initialize(options); - - // creation du DOM container - this._container = this._initializeContainer(); - - // ajout du container - (this.element) ? this.element.appendChild(this._container) : this.element = this._container; - - return this; - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - - /** - * Overwrite OpenLayers setMap method - * - * @param {ol.Map} map - Map. - */ - setMap (map) { - logger.trace("setMap()"); - - var className = this.CLASSNAME; - - // on fait le choix de ne pas activer les events sur la map à l'init de l'outil, - // mais uniquement à son utilisation ! - if (map) { - // var self = this; - // map.on("click", function (e) { - // logger.trace("event on map with click!"); - // self.onPointerMoveHandler(e); - // }); - // - // map.on("singleclick", function (e) { - // logger.trace("event on map with singleclick!"); - // self.onPointerMoveHandler(e); - // }); - // - // map.on("pointermove", function (e) { - // logger.trace("event on map with pointermove!"); - // self.onPointerMoveHandler(e); - // }); - - if (!this.options.target && !this.options.position) { - MeasureToolBox.add(map, this); - } - } else { - this.clean(); - } - - // sauvegarde de l'état de l'outil - this.tools[className].push({ - instance : (map) ? this : null, - active : false, - map : (map) ? map.getTargetElement().id : null - }); - - // contexte d'execution - var context = typeof window !== "undefined" ? window : typeof self !== "undefined" ? self : null; - if (context) { - // Pour info - // les objets de mesures ont du code partagé - // (afin de gerer les interactions entre eux). - // Dans un mode "modules", on partage cet objet (this.tools) via le contexte - // d'execution (ex. avec window) - if (!context.gpShareMeasures) { - context.gpShareMeasures = {}; - } - context.gpShareMeasures[className] = this.tools[className]; - } - - // on appelle la méthode setMap originale d'OpenLayers - super.setMap(map); - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - } - - // ################################################################### // - // ##################### init component ############################## // - // ################################################################### // - - /** - * Initialize measure control (called by constructor) - * - * @param {Object} options - options - * - * @private - */ - _initialize (options) { - logger.trace("call MeasureLength::_initialize() : ", options); - - // liste des options - this.options = {}; - this.options.geodesic = (typeof options.geodesic !== "undefined") ? options.geodesic : true; - this.options.position = (typeof options.position !== "undefined") ? options.position : null; - this.options.target = (typeof options.target !== "undefined") ? options.target : null; - this.options.render = (typeof options.render !== "undefined") ? options.render : null; - this.options.layerDescription = (typeof options.layerDescription !== "undefined") ? options.layerDescription : { - title : "Mesures de distance", - description : "Mes mesures" - }; - - // gestion des styles ! - this.createStylingMeasureInteraction(options.styles); - } - - /** - * initialize component container (DOM) - * - * @returns {DOMElement} DOM element - * - * @private - */ - _initializeContainer () { - logger.trace("call MeasureLength::_initializeContainer() : ", this._uid); - - var container = this._createMainContainerElement(); - - var picto = this._pictoContainer = this._createShowMeasureLengthPictoElement(); - container.appendChild(picto); - - return container; - } - - // ################################################################### // - // ########################## methods ################################ // - // ################################################################### // - - /** - * Add all events on map - * - * @private - */ - addMeasureEvents () { - logger.trace("call MeasureLength::addMeasureEvents()"); - - var map = this.getMap(); - - map.on("singleclick", (e) => this.onPointerMoveHandler(e)); - map.on("pointermove", (e) => this.onPointerMoveHandler(e)); - } - - /** - * Remove all events on map - * - * @private - */ - removeMeasureEvents () { - logger.trace("call MeasureLength::removeMeasureEvents()"); - - var map = this.getMap(); - - map.un("singleclick", (e) => this.onPointerMoveHandle(e)); - map.un("pointermove", (e) => this.onPointerMoveHandler(e)); - } - - /** - * Format length output. - * - * @param {ol.geom.Line} line - geometry line. - * @return {String} The formatted output. - * @private - */ - format (line) { - logger.trace("call MeasureLength::format()"); - - var map = this.getMap(); - - var measure; - if (this.options.geodesic) { - var coordinates = line.getCoordinates(); - measure = 0; - var sourceProj = map.getView().getProjection(); - for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) { - var c1 = olTransformProj(coordinates[i], sourceProj, "EPSG:4326"); - var c2 = olTransformProj(coordinates[i + 1], sourceProj, "EPSG:4326"); - measure += olGetDistanceSphere(c1, c2); - } - } else { - measure = Math.round(line.getLength() * 100) / 100; - } - - var output; - if (measure > 1000) { - output = (Math.round(measure / 1000 * 100) / 100) + " " + "km"; - } else { - output = (Math.round(measure * 100) / 100) + " " + "m"; - } - return output; - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - - /** - * this method is called by event 'click' on picto - * - * @param {Object} e - HTMLElement - * - * @private - */ - onShowMeasureLengthClick (e) { - logger.trace("call MeasureLength::onShowMeasureLengthClick()", e); - - // appel de la methode commune - this.onShowMeasureClick(e, "LineString"); - } - -}; - -// on récupère les mixins de la classe "MeasureAreaDOM" ainsi que celles -// de "Measures". -Object.assign(MeasureLength.prototype, Measures); -Object.assign(MeasureLength.prototype, MeasureLengthDOM); - -export default MeasureLength; - -// Expose MeasureLength as ol.control.MeasureLength (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.MeasureLength = MeasureLength; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLengthDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLengthDOM.d.ts deleted file mode 100644 index 937f00812..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLengthDOM.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default MeasureLengthDOM; -declare namespace MeasureLengthDOM { - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createShowMeasureLengthPictoElement(): DOMElement; -} -//# sourceMappingURL=MeasureLengthDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLengthDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLengthDOM.d.ts.map deleted file mode 100644 index 6b0fa1170..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLengthDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MeasureLengthDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Measures/MeasureLengthDOM.js"],"names":[],"mappings":";;IAOc,qCAGT;IAO6B,mDAK7B;IAYsC,4DA8BtC"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLengthDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLengthDOM.js deleted file mode 100644 index 6d3f8bd31..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/MeasureLengthDOM.js +++ /dev/null @@ -1,68 +0,0 @@ -var MeasureLengthDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Main container (DOM) - * - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPmeasureLength"); - container.className = "GPwidget gpf-widget gpf-widget-button"; - return container; - }, - - // ################################################################### // - // ################### Methods of main container ##################### // - // ################################################################### // - - /** - * Show control - * see event ! - * - * @returns {DOMElement} DOM element - */ - _createShowMeasureLengthPictoElement : function () { - // contexte d'execution - var context = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowMeasureLengthPicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto gpf-btn gpf-btn-icon gpf-btn-icon-length fr-btn"; - button.title = "Mesurer une distance"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // gestionnaire d'evenement : - // on ouvre le menu de saisie... - // L'ouverture/Fermeture permet de faire le menage - // (reinitialisation) - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowMeasureLengthClick(e); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowMeasureLengthClick(e); - }); - } - - return button; - } -}; - -export default MeasureLengthDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/Measures.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/Measures.d.ts deleted file mode 100644 index cc4f46b48..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/Measures.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -export default Measures; -/** - * @type {ol.control.Measures} - * @abstract - * Measures Tools : - * - length - * - aera - * - azimut - */ -declare var Measures: ol.control.Measures; -//# sourceMappingURL=Measures.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/Measures.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/Measures.d.ts.map deleted file mode 100644 index 05f3569cc..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/Measures.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Measures.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Measures/Measures.js"],"names":[],"mappings":";AAsBA;;;;;;;GAOG;AACH,0CAufE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/Measures.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/Measures.js deleted file mode 100644 index 9030d4a6a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Measures/Measures.js +++ /dev/null @@ -1,536 +0,0 @@ -// import OpenLayers -import Overlay from "ol/Overlay"; -import { Draw as DrawInteraction } from "ol/interaction"; -import { - Fill, - Stroke, - Style, - Circle -} from "ol/style"; -import VectorLayer from "ol/layer/Vector"; -import VectorSource from "ol/source/Vector"; -// import local -import Logger from "../../Utils/LoggerByDefault"; -import Interactions from "../Utils/Interactions"; -// import local with ol dependencies -import LayerSwitcher from "../LayerSwitcher/LayerSwitcher"; - -// Derived from OpenLayers measure example -// http://openlayers.org/en/latest/examples/measure.html - -var logger = Logger.getLogger("measures"); - -/** - * @type {ol.control.Measures} - * @abstract - * Measures Tools : - * - length - * - aera - * - azimut - */ -var Measures = { - - // ****************************************************************** // - // > Default Styles - // ****************************************************************** // - - /* - * Pointer - */ - DEFAULT_POINTER_STYLE : new Circle({ - radius : 5, - stroke : new Stroke({ - color : "#002A50", - width : 2 - }), - fill : new Fill({ - color : "rgba(255, 155, 0, 0.7)" - }) - }), - - /* - * Measures style line - */ - DEFAULT_DRAW_START_STYLE : new Style({ - fill : new Fill({ - color : "rgba(0, 183, 152, 0.2)" - }), - stroke : new Stroke({ - color : "#002A50", - lineDash : [10, 10], - width : 2 - }) - }), - - /* - * Measures final style line - */ - DEFAULT_DRAW_FINISH_STYLE : new Style({ - fill : new Fill({ - color : "rgba(0, 183, 152, 0.3)" - }), - stroke : new Stroke({ - color : "#002A50", - width : 3 - }) - }), - - // ****************************************************************** // - // > ToolBox : these tools work together - // ****************************************************************** // - // sample : - // tools[name_control][0].(active|instance|map) - // tools : { - // MeasureLength : [ - // { active : true, instance : [Object MeasureLength], map : "map1" }, - // { active : true, instance : [Object MeasureLength], map : "map2" } - // ], - // MeasureArea : [], - // MeasureAzimuth : [] - // } - tools : { - MeasureLength : [], - MeasureArea : [], - MeasureAzimuth : [] - }, - - // ****************************************************************** // - // > Variables - // ****************************************************************** // - - /** - * Global measure draw interaction - * @type {ol.interaction.Draw} - */ - measureDraw : null, - - /** - * Global vector source for measure - * @type {ol.source.Vector} - */ - measureSource : null, - - /** - * Global vector layer for measure - * @type {ol.layer.Vector} - */ - measureVector : null, - - /** - * Currently drawn feature. - * @type {ol.Feature} - */ - sketch : null, - - /** - * The measure tooltip element. - * @type {Element} - */ - measureTooltipElement : null, - - /** - * Overlay to show the measurement. - * @type {ol.Overlay} - */ - measureTooltip : null, - - /** - * TODO The help tooltip element. - * @type {Element} - */ - helpTooltipElement : null, - - /** - * TODO Overlay to show the help. - * @type {ol.Overlay} - */ - helpTooltip : null, - - // ****************************************************************** // - // > Methods Public - // ****************************************************************** // - - /** Desactived Tool Measure */ - clean : function () { - var _class = this.CLASSNAME; - - logger.trace("[" + _class + "] deactived tool !"); - // sur la desactivation de l'outil de mesure - // on fait un nettoyage des ressources - // ainsi que le DOM - this.clearMeasure(); - this.clearMeasureToolTip(); - this.removeMeasureEvents(); - this._pictoContainer.setAttribute("aria-pressed", false); - }, - - // ****************************************************************** // - // > Methods Events - // ****************************************************************** // - - /** - * Handle pointer move. - * - * @param {ol.MapBrowserEvent} e - The event. - */ - onPointerMoveHandler : function (e) { - if (e.dragging) { - return; - } - - /** @type {ol.Coordinate|undefined} */ - var tooltipCoord = e.coordinate; - - if (this.sketch) { - var output; - var geom = (this.sketch.getGeometry()); - output = this.format((geom)); - if (geom.getType() === "LineString") { - tooltipCoord = geom.getLastCoordinate(); - } else if (geom.getType() === "Polygon") { - tooltipCoord = geom.getInteriorPoint().getCoordinates(); - } else { - return; - } - this.measureTooltipElement.innerHTML = output; - this.measureTooltip.setPosition(tooltipCoord); - } - }, - - /** - * Main program ! - * This method is called by event 'click' on control picto - * - * @param {Object} e - HTMLElement - * @param {String} type - LineString or Polygon - * @private - */ - onShowMeasureClick : function (e, type) { - var map = this.getMap(); - var currentMapId = map.getTargetElement().id; - - // contexte d'execution - var context = typeof window !== "undefined" ? window : typeof self !== "undefined" ? self : null; - if (context) { - // Pour info - // les objets de mesures ont du code partagé - // (afin de gerer les interactions entre eux). - // Dans un mode "modules", on partage cet objet (this.tools) via le contexte - // d'execution (ex. avec window) - this.tools = context.gpShareMeasures || {}; - } - - // desactivation des controles de mesures sur la carte courrante - var mySelf = this.CLASSNAME; // this.constructor.name : pas possible en mode minifié/manglifié ! - for (var className in this.tools) { - if (this.tools.hasOwnProperty(className)) { - var measures = this.tools[className]; - for (var i = 0; i < measures.length; i++) { - var o = measures[i]; - if (o && o.active && className !== mySelf && o.map === currentMapId) { - o.active = false; - if (o.instance !== null) { // au cas où le controle a été supprimé ! - o.instance.clean(); - } - } - } - } - } - - // desactivation des autres interactions parasites - Interactions.unset(map, { - current : "Measures" - }); - - var opened = this._pictoContainer.ariaPressed; - if (opened === "true") { - this.addMeasureEvents(); - this.initMeasureInteraction(); - this.addMeasureInteraction(type); - for (var j = 0; j < this.tools[mySelf].length; j++) { - if (this.tools[mySelf][j].map === currentMapId) { - this.tools[mySelf][j].active = true; - } - } - } else { - this.clearMeasure(); - this.clearMeasureToolTip(); - this.removeMeasureEvents(); - for (var k = 0; k < this.tools[mySelf].length; k++) { - if (this.tools[mySelf][k].map === currentMapId) { - this.tools[mySelf][k].active = false; - } - } - } - }, - - // ****************************************************************** // - // > Methods not Public - // ****************************************************************** // - - /** - * Clear all dom tooltip of length, area or azimut object. - */ - clearMeasureToolTip : function () { - var map = this.getMap(); - if (!map) { - return; - } - - var mapContainer = map.getTargetElement(); - // au cas où il y'aurait plusieurs container de carte ! - var overlays = mapContainer.getElementsByClassName("ol-overlaycontainer"); - for (var k = 0; k < overlays.length; k++) { - var nodes = overlays[k]; - var len = nodes.children.length; - var nodesToRemove = []; - for (var i = 0; i < len; i++) { - var node = nodes.children[i]; - if (node.children.length !== 0) { - var child = node.children[0]; - if (child.className === "GPmeasureTooltip GPmeasureTooltip-static" || - child.className === "GPmeasureTooltip GPmeasureTooltip-measure") { - nodesToRemove.push(node); - } - } - } - for (var j = 0; j < nodesToRemove.length; j++) { - nodes.removeChild(nodesToRemove[j]); - } - } - }, - - /** - * Clear all length, area or azimut object. - */ - clearMeasure : function () { - var map = this.getMap(); - - // FIXME !? - // if (this.measureTooltip) { - // map.removeOverlay(this.measureTooltip); - // this.measureTooltip = null; - // } - - if (this.measureVector) { - map.removeLayer(this.measureVector); - this.measureVector = null; - } - - if (this.measureDraw) { - map.removeInteraction(this.measureDraw); - this.measureDraw = null; - } - }, - - /** - * Creates a new measure tooltip - * FIXME bug d'affichage de la tooltip de saisie en cours si on ne termine pas - * la saisie !? - * - * @param {ol.Map} map - The Map. - */ - createMeasureTooltip : function (map) { - if (this.measureTooltipElement) { - this.measureTooltipElement.parentNode.removeChild(this.measureTooltipElement); - } - - this.measureTooltipElement = document.createElement("div"); - this.measureTooltipElement.className = "GPmeasureTooltip GPmeasureTooltip-measure"; - - this.measureTooltip = new Overlay({ - element : this.measureTooltipElement, - stopEvent : false, - offset : [0, -15], - positioning : "bottom-center" - }); - - map.addOverlay(this.measureTooltip); - }, - - /** - * TODO evolution - * Creates a new help tooltip - * - * @param {ol.Map} map - The Map. - */ - createHelpTooltip : function (map) { - if (this.helpTooltipElement) { - this.helpTooltipElement.parentNode.removeChild(this.helpTooltipElement); - } - - this.helpTooltipElement = document.createElement("div"); - this.helpTooltipElement.className = "tooltip hidden"; - - this.helpTooltip = new Overlay({ - element : this.helpTooltipElement, - stopEvent : false, - offset : [15, 0], - positioning : "center-left" - }); - - map.addOverlay(this.helpTooltip); - }, - - /** - * Creates a style for drawing - * - * @param {Object} styles - styles. - */ - createStylingMeasureInteraction : function (styles) { - this.options.styles = styles || {}; - - // style de depart - logger.trace("style start", this.options.styles.start); - - // Creation à partir des styles par défaut - var startStyleOpts = { - image : Measures.DEFAULT_POINTER_STYLE, - fill : Measures.DEFAULT_DRAW_START_STYLE.getFill(), - stroke : Measures.DEFAULT_DRAW_START_STYLE.getStroke() - }; - // ecrasement à partir des propriétés renseignées - if (this.options.styles.hasOwnProperty("pointer") && this.options.styles.pointer instanceof Image) { - startStyleOpts.image = this.options.styles.pointer; - } - if (this.options.styles.hasOwnProperty("start") && this.options.styles.start instanceof Style) { - if (this.options.styles.start.getFill() != null) { - startStyleOpts.fill = this.options.styles.start.getFill(); - } - if (this.options.styles.start.getStroke() != null) { - startStyleOpts.stroke = this.options.styles.start.getStroke(); - } - } - - this.options.styles.start = new Style(startStyleOpts); - - // style de fin - logger.trace("style finish", this.options.styles.finish); - - var finishStyleOpts = { - fill : Measures.DEFAULT_DRAW_FINISH_STYLE.getFill(), - stroke : Measures.DEFAULT_DRAW_FINISH_STYLE.getStroke() - }; - // ecrasement à partir des propriétés renseignées - if (this.options.styles.hasOwnProperty("finish") && this.options.styles.finish instanceof Style) { - if (this.options.styles.finish.getFill() != null) { - finishStyleOpts.fill = this.options.styles.finish.getFill(); - } - if (this.options.styles.finish.getStroke() != null) { - finishStyleOpts.stroke = this.options.styles.finish.getStroke(); - } - } - - this.options.styles.finish = new Style(finishStyleOpts); - }, - - /** - * Add the measure interaction - * - * @param {String} type - LineString or Polygon. - */ - addMeasureInteraction : function (type) { - var map = this.getMap(); - - // Creates and adds the interaction - var self = this; - this.measureDraw = new DrawInteraction({ - source : this.measureSource, - // condition : permet de gerer la suppression des derniers points saisis - condition : function (event) { - if (event.originalEvent.ctrlKey) { - if (self.sketch) { - this.removeLastPoint(); - } - return false; - } - return true; - }, - type : type, - style : this.options.styles.start || Measures.DEFAULT_DRAW_START_STYLE - }); - this.measureDraw.setProperties({ - name : "Measures", - source : this - }); - map.addInteraction(this.measureDraw); - - // Create tooltips - this.createMeasureTooltip(map); - - // Event start measuring - this.measureDraw.on("drawstart", (evt) => { - // set sketch - self.sketch = evt.feature; - }); - - // Event end measuring - this.measureDraw.on("drawend", () => { - // FIXME MaJ de la tooltip en mode mobile ! - if (self.sketch) { - var output; - var tooltipCoord; - var geom = (self.sketch.getGeometry()); - output = self.format((geom)); - if (geom.getType() === "LineString") { - tooltipCoord = geom.getLastCoordinate(); - } else if (geom.getType() === "Polygon") { - tooltipCoord = geom.getInteriorPoint().getCoordinates(); - } else { - return; - } - self.measureTooltipElement.innerHTML = output; - self.measureTooltip.setPosition(tooltipCoord); - } - - self.measureTooltipElement.className = "GPmeasureTooltip GPmeasureTooltip-static"; - self.measureTooltip.setOffset([0, -7]); - - // unset sketch - self.sketch = null; - // unset tooltip so that a new one can be created - self.measureTooltipElement = null; - self.createMeasureTooltip(map); - }); - }, - - /** - * Init the measure interaction - */ - initMeasureInteraction : function () { - var map = this.getMap(); - - this.measureSource = new VectorSource(); - - this.measureVector = new VectorLayer({ - source : this.measureSource, - style : this.options.styles.finish || Measures.DEFAULT_DRAW_FINISH_STYLE - }); - - // on rajoute le champ gpResultLayerId permettant d'identifier une couche crée par le composant. - this.measureVector.gpResultLayerId = "measure"; - - map.addLayer(this.measureVector); - - // Si un layer switcher est présent dans la carte, on lui affecte des informations pour cette couche - map.getControls().forEach( - (control) => { - if (control instanceof LayerSwitcher) { - // un layer switcher est présent dans la carte - var layerId = this.measureVector.gpLayerId; - // on n'ajoute des informations que s'il n'y en a pas déjà (si le titre est le numéro par défaut) - if (control._layers[layerId].title === layerId) { - control.addLayer( - this.measureVector, { - title : this.options.layerDescription.title, - description : this.options.layerDescription.description - } - ); - } - } - } - ); - } -}; - -export default Measures; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePosition.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePosition.d.ts deleted file mode 100644 index 92ae157de..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePosition.d.ts +++ /dev/null @@ -1,87 +0,0 @@ -export default MousePosition; -/** - * @classdesc - * MousePosition Control. - * - * @constructor - * @alias ol.control.GeoportalMousePosition - * @type {ol.control.GeoportalMousePosition} - * @extends {ol.control.Control} - * @param {Object} options - options for function call. - * @param {String} [options.apiKey] - API key. The key "calcul" is used by default. - * @param {Boolean} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean} [options.draggable = false] - Specify if widget is draggable - * @param {Boolean} [options.collapsed = true] - Specify if MousePosition control should be collapsed at startup. Default is true. - * @param {Array} [options.units] - list of coordinates units, to be displayed in control units list. - * Values may be "DEC" (decimal degrees), "DMS" (sexagecimal), "RAD" (radians) and "GON" (grades) for geographical coordinates, - * and "M" or "KM" for metric coordinates - * @param {Boolean} [options.displayAltitude = true] - activate (true) or deactivate (false) the altitude panel. True by default - * @param {Boolean} [options.displayCoordinates = true] - activate (true) or deactivate (false) the coordinates panel. True by default - * @param {Boolean} [options.editCoordinates = false] - If true, coordinates from the MousePosition control can be edited by users to re-center the view. False by default. - * @param {Function} [options.mapCenterCallback] - callback... - * @param {Array} [options.systems] - list of projection systems, default are Geographical ("EPSG:4326"), Web Mercator ("EPSG:3857"), Lambert 93 ("EPSG:2154") and extended Lambert 2 ("EPSG:27572"). - * Each array element (=system) is an object with following properties : - * @param {String} options.systems.crs - Proj4 crs alias (from proj4 defs). e.g. : "EPSG:4326". Required - * @param {String} [options.systems.label] - CRS label to be displayed in control. Default is crs code (e.g. "EPSG:4326") - * @param {String} options.systems.type - CRS units type for coordinates conversion : "Geographical" or "Metric". Default: "Metric" - * @param {Object} [options.systems.geoBBox] - Aera covered by the system (WGS84 coordinates). - * @param {Number} options.systems.geoBBox.right - Right bound. - * @param {Number} options.systems.geoBBox.left - Left bound. - * @param {Number} options.systems.geoBBox.top - Top bound. - * @param {Number} options.systems.geoBBox.bottom - Bottom bound. - * @param {Object} [options.positionMarker] - options for position marker - * @param {String} options.positionMarker.url - Marker url (define in src/Openlayers/Controls/Utils/Markers.js) - * @param {Array} options.positionMarker.offset - Offsets in pixels used when positioning the marker towards targeted point. - * The first element in the array is the horizontal offset. A positive value shifts the marker right. - * The second element in the array is the vertical offset. A positive value shifts the marker down. [0,0] value positions the top-left corner of the marker image to the targeted point. - * Default is offset associated to default marker image. - * @param {Boolean} options.positionMarker.hide - if true, marker is not displayed, otherwise displayed (False by default.) - * @param {Object} [options.altitude] - elevation configuration - * @param {Object} [options.altitude.serviceOptions] - options of elevation service - * @param {Number} [options.altitude.responseDelay] - latency for altitude request, 500 ms by default - * @param {Number} [options.altitude.triggerDelay] - immobilisation time of movement on the map to trigger the elevation calculation, 200 ms by default - * @param {Number} [options.altitude.noDataValue] - value used for altitude service no data (default is -99999). In this case, "---m" will be displayed instead of "-99999m" - * @param {Number} [options.altitude.noDataValueTolerance] - tolerance for no data value : - * values in [noDataValue + noDataValueTolerance ; noDataValue - noDataValueTolerance] interval will not be displayed, but "---m" will be displayed instead. - * Default is 90000 (no data values = [-9999 ; -189999]) - * @example - * var MousePosition = new ol.control.GeoportalMousePosition({ - * "collapsed" : false, - * "graggable" : true, - * "displayCoordinates" : true, - * "displayAltitude" : true, - * "altitude" : { - * "triggerDelay" : 100, - * "responseDelay" : 500, - * "noDataValue" : -99999, - * "noDataValueTolerance" : 99000, - * "serviceOptions" : {} - * }, - * "systems" : [ - * { - * "crs" : "EPSG:3857", - * "label" : "Web Mercator", - * "type" : "Metric" - * }, - * { - * "crs" : "EPSG:4326", - * "label" : "Géographiques", - * "type" : "Geographical" - * }, - * { - * "label" : "Lambert 93", - * "crs" : "EPSG:2154", - * "type" : "Metric", - * "geoBBox" : { - * "left" : -9.86, - * "bottom" : 41.15, - * "right" : 10.38, - * "top" : 51.56 - * } - * } - * ], - * "units" : ["DEC", "DMS"] - * }); - */ -declare var MousePosition: ol.control.GeoportalMousePosition; -//# sourceMappingURL=MousePosition.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePosition.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePosition.d.ts.map deleted file mode 100644 index 2cac46f5c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePosition.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MousePosition.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/MousePosition/MousePosition.js"],"names":[],"mappings":";AAoCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AACH,6DAojDE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePosition.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePosition.js deleted file mode 100644 index afa3f62d9..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePosition.js +++ /dev/null @@ -1,1719 +0,0 @@ -// import CSS -import "../../CSS/Controls/MousePosition/GPFmousePosition.css"; -// import "../../CSS/Controls/MousePosition/GPFmousePositionStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -import Overlay from "ol/Overlay"; -import { unByKey as olObservableUnByKey } from "ol/Observable"; -import { - transform as olTransformProj, - get as olGetProj, - transformExtent as olTransformExtentProj -} from "ol/proj"; -// import geoportal library access -import Gp from "geoportal-access-lib"; -// import local -import Logger from "../../Utils/LoggerByDefault"; -import Utils from "../../Utils/Helper"; -import Interactions from "../Utils/Interactions"; -import Markers from "../Utils/Markers"; -import SelectorID from "../../Utils/SelectorID"; -import MathUtils from "../../Utils/MathUtils"; -import Draggable from "../../Utils/Draggable"; -// import defs proj4 manually (cf. line 125) -// import Proj4 from "proj4"; -// import { register } from "ol/proj/proj4"; -// import Register from "../../Utils/Register"; -// import local with ol dependencies -import CRS from "../../CRS/CRS"; -// import "../CRS/AutoLoadCRS"; - -// DOM -import MousePositionDOM from "./MousePositionDOM"; - -var logger = Logger.getLogger("GeoportalMousePosition"); - -/** - * @classdesc - * MousePosition Control. - * - * @constructor - * @alias ol.control.GeoportalMousePosition - * @type {ol.control.GeoportalMousePosition} - * @extends {ol.control.Control} - * @param {Object} options - options for function call. - * @param {String} [options.apiKey] - API key. The key "calcul" is used by default. - * @param {Boolean} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean} [options.draggable = false] - Specify if widget is draggable - * @param {Boolean} [options.collapsed = true] - Specify if MousePosition control should be collapsed at startup. Default is true. - * @param {Array} [options.units] - list of coordinates units, to be displayed in control units list. - * Values may be "DEC" (decimal degrees), "DMS" (sexagecimal), "RAD" (radians) and "GON" (grades) for geographical coordinates, - * and "M" or "KM" for metric coordinates - * @param {Boolean} [options.displayAltitude = true] - activate (true) or deactivate (false) the altitude panel. True by default - * @param {Boolean} [options.displayCoordinates = true] - activate (true) or deactivate (false) the coordinates panel. True by default - * @param {Boolean} [options.editCoordinates = false] - If true, coordinates from the MousePosition control can be edited by users to re-center the view. False by default. - * @param {Function} [options.mapCenterCallback] - callback... - * @param {Array} [options.systems] - list of projection systems, default are Geographical ("EPSG:4326"), Web Mercator ("EPSG:3857"), Lambert 93 ("EPSG:2154") and extended Lambert 2 ("EPSG:27572"). - * Each array element (=system) is an object with following properties : - * @param {String} options.systems.crs - Proj4 crs alias (from proj4 defs). e.g. : "EPSG:4326". Required - * @param {String} [options.systems.label] - CRS label to be displayed in control. Default is crs code (e.g. "EPSG:4326") - * @param {String} options.systems.type - CRS units type for coordinates conversion : "Geographical" or "Metric". Default: "Metric" - * @param {Object} [options.systems.geoBBox] - Aera covered by the system (WGS84 coordinates). - * @param {Number} options.systems.geoBBox.right - Right bound. - * @param {Number} options.systems.geoBBox.left - Left bound. - * @param {Number} options.systems.geoBBox.top - Top bound. - * @param {Number} options.systems.geoBBox.bottom - Bottom bound. - * @param {Object} [options.positionMarker] - options for position marker - * @param {String} options.positionMarker.url - Marker url (define in src/Openlayers/Controls/Utils/Markers.js) - * @param {Array} options.positionMarker.offset - Offsets in pixels used when positioning the marker towards targeted point. - * The first element in the array is the horizontal offset. A positive value shifts the marker right. - * The second element in the array is the vertical offset. A positive value shifts the marker down. [0,0] value positions the top-left corner of the marker image to the targeted point. - * Default is offset associated to default marker image. - * @param {Boolean} options.positionMarker.hide - if true, marker is not displayed, otherwise displayed (False by default.) - * @param {Object} [options.altitude] - elevation configuration - * @param {Object} [options.altitude.serviceOptions] - options of elevation service - * @param {Number} [options.altitude.responseDelay] - latency for altitude request, 500 ms by default - * @param {Number} [options.altitude.triggerDelay] - immobilisation time of movement on the map to trigger the elevation calculation, 200 ms by default - * @param {Number} [options.altitude.noDataValue] - value used for altitude service no data (default is -99999). In this case, "---m" will be displayed instead of "-99999m" - * @param {Number} [options.altitude.noDataValueTolerance] - tolerance for no data value : - * values in [noDataValue + noDataValueTolerance ; noDataValue - noDataValueTolerance] interval will not be displayed, but "---m" will be displayed instead. - * Default is 90000 (no data values = [-9999 ; -189999]) - * @example - * var MousePosition = new ol.control.GeoportalMousePosition({ - * "collapsed" : false, - * "graggable" : true, - * "displayCoordinates" : true, - * "displayAltitude" : true, - * "altitude" : { - * "triggerDelay" : 100, - * "responseDelay" : 500, - * "noDataValue" : -99999, - * "noDataValueTolerance" : 99000, - * "serviceOptions" : {} - * }, - * "systems" : [ - * { - * "crs" : "EPSG:3857", - * "label" : "Web Mercator", - * "type" : "Metric" - * }, - * { - * "crs" : "EPSG:4326", - * "label" : "Géographiques", - * "type" : "Geographical" - * }, - * { - * "label" : "Lambert 93", - * "crs" : "EPSG:2154", - * "type" : "Metric", - * "geoBBox" : { - * "left" : -9.86, - * "bottom" : 41.15, - * "right" : 10.38, - * "top" : 51.56 - * } - * } - * ], - * "units" : ["DEC", "DMS"] - * }); - */ -var MousePosition = class MousePosition extends Control { - - /** - * See {@link ol.control.GeoportalMousePosition} - * @module MousePosition - * @alias module:~Controls/MousePosition - * @param {*} options - options - * @example - * import GeoportalMousePosition from "src/OpenLayers/Controls/MousePosition" - */ - constructor (options) { - options = options || {}; - - // call ol.control.Control constructor - super({ - element : options.element, - target : options.target, - render : options.render - }); - - if (!(this instanceof MousePosition)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - // init Proj4 defs manually - // Register.load(Proj4); - // try { - // register(Proj4); - // } catch (e) {} - - this._initialize(options); - - // init control DOM container - var container = this._initContainer(this.options); - - // ajout du container - (this.element) ? this.element.appendChild(container) : this.element = container; - - return this; - }; - - /** - * Overload ol.control.Control setMap method, called when - * - * @param {Object} map - the map - * - */ - setMap (map) { - var context = this; - - if (map) { // dans le cas de l'ajout du contrôle à la map - var center = this._createMapCenter(); - map.getViewport().appendChild(center); - if (!this.collapsed && !this._isDesktop) { - center.className = "GPmapCenterVisible"; - } - - // mode "draggable" - if (this.draggable) { - Draggable.dragElement( - this._panelMousePositionContainer, - this._panelHeaderMousePositionContainer, - this.options.position ? null : map.getTargetElement() - ); - } - - // on met en place l'evenement sur la carte pour recuperer les coordonnées, - // on l'active à l'ouverture du panneau uniquement ! - if (!this.collapsed) { - // evenement valable pour le mode desktop ! - if (this._isDesktop) { - this.listenerKey = map.on( - "pointermove", - (e) => { this.onMouseMove(e); } - ); - } else { - this.listenerKey = map.on( - "moveend", - (e) => this.onMapMove(e) - ); - } - - this._showMousePositionButton.setAttribute("aria-pressed", true); - } - - // add overlay only if option editCoordinates is true - if (this.options.editCoordinates) { - // création de l'élément DOM - var markerDiv = document.createElement("img"); - markerDiv.id = this._addUID("GPmousePositionMarker"); - markerDiv.src = this._markerUrl; - markerDiv.title = "Cliquer pour supprimer"; - markerDiv.addEventListener("click", function () { - context._markerOverlay.setPosition(undefined); - }); - - this._markerOverlay = new Overlay({ - offset : this._markerOffset, - element : markerDiv, - stopEvent : false - }); - map.addOverlay(this._markerOverlay); - } - } else { - olObservableUnByKey(this.listenerKey); - } - - // call original setMap method - super.setMap(map); - - // HACK: on arrête l'execution de la fonction... - if (map === null) { - return; - } - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - - // mode "collapsed" - if (!this.collapsed) { - var inputShow = document.getElementById("GPshowMousePosition-" + this._uid); - inputShow.checked = "checked"; - this._setElevationPanel(this.options.displayAltitude); - this._setCoordinatesPanel(this.options.displayCoordinates); - if (!this.options.displayCoordinates) { - this._setSettingsPanel(false); - } - } - } - - // ################################################################### // - // #################### user interface methods ####################### // - // ################################################################### // - - /** - * Set additional projection system - * - * @param {Object} system - projection system - * @param {String} system.crs - Proj4 crs alias (from proj4 defs) e.g. "EPSG:4326" - * @param {String} [system.label] - CRS label to be displayed in control. Default is system.crs alias - * @param {String} [system.type] - CRS units type for coordinates conversion (one of control options.units). Default is "Metric" - */ - addSystem (system) { - if (typeof system !== "object") { - logger.log("[ERROR] MousePosition:addSystem - system parameter should be an object"); - return; - } - if (!system.crs) { - logger.error("crs not defined !"); - return; - } - if (!system.label) { - logger.warn("crs label not defined, use crs code by default."); - system.label = system.crs; - } - if (!system.type) { - logger.warn("type srs not defined, use 'Metric' by default."); - system.type = "Metric"; - } - - // chargement de la definition de la projection - // même si déjà chargé... - CRS.loadByName(system.crs); - - if (!olGetProj(system.crs)) { - logger.error("crs '{}' not available into proj4 definitions !", system.crs); - return; - } - - // 1. add system to control systems - for (var j = 0; j < this._projectionSystems.length; j++) { - var obj = this._projectionSystems[j]; - if (system.crs === obj.crs) { - // warn user - logger.info("crs '{}' already configured", obj.crs); - } - } - system.code = this._projectionSystems.length; - this._projectionSystems.push(system); - - // 2. add system settings option to container (if it was already build) - var selectSystem = document.getElementById("GPmousePositionProjectionSystem-" + this._uid); - if (selectSystem) { - var option = document.createElement("option"); - option.value = system.code; - option.text = system.label; - selectSystem.appendChild(option); - } - } - - /** - * Set additional projection systems - * - * @param {Array} systems - Array of system object, with following properties : - * @param {String} systems.crs - Proj4 CRS alias (from proj4 defs) e.g. "EPSG:4326" - * @param {String} systems.label - CRS label (for coordinates conversion) - * @param {String} systems.type - CRS units type to be displayed in control (one of control options.units). Default is "Metric" - */ - addSystems (systems) { - if (!systems) { - return; - } - if (!Array.isArray(systems)) { - logger.log("[ERROR] MousePosition:addSystems - systems parameter should be an array"); - return; - } - for (var i = 0; i < systems.length; i++) { - this.addSystem(systems[i]); - } - } - - /** - * Remove projection system (in case there are several system with same code, only the first one will be removed) - * - * @param {String} systemCrs - CRS alias (from proj4 defs) - */ - removeSystem (systemCrs) { - if (!systemCrs || typeof systemCrs !== "string") { - logger.log("[ERROR] MousePosition:removeSystem - systemCode parameter should be a string"); - return; - } - - var systemList = document.getElementById("GPmousePositionProjectionSystem-" + this._uid); - - var systemCode = null; - // find system in control projection systems list - for (var i = 0; i < this._projectionSystems.length; i++) { - var proj = this._projectionSystems[i]; - if (systemCrs === proj.crs) { - systemCode = proj.code; - // remove system from control projection systems list - this._projectionSystems.splice(i, 1); - break; - } - } - - if (systemCode == null) { - logger.log("[WARN] MousePosition:removeSystem - system not found"); - return; - } - - /* re-initialization of codes */ - var oldNewCodeMap = []; - - for (var j = 0; j < this._projectionSystems.length; j++) { - oldNewCodeMap[Number(this._projectionSystems[j].code)] = j; - this._projectionSystems[j].code = j; - } - - /* find system in control container systems list */ - var indexChildToRemove = null; - - for (var k = 0; k < systemList.childNodes.length; k++) { - if (systemCode === systemList.childNodes[j].value) { - indexChildToRemove = k; - continue; - } - systemList.childNodes[j].value = oldNewCodeMap[Number(systemList.childNodes[j].value)]; - } - /* remove system from control container systems list */ - if (indexChildToRemove != null) { - systemList.removeChild(systemList.childNodes[indexChildToRemove]); - } - - // choose arbitrarily a new current system if needed - if (this._currentProjectionSystems.code === Number(systemCode)) { - systemList.childNodes[0].setAttribute("selected", "selected"); - this._setCurrentSystem(systemList.childNodes[0].value); - } - } - - /** - * Set control units (to be displayed) - * - * @param {Array} units - list of all coordinates units, to be displayed in control units list. - * Values may be "DEC" (decimal degrees), "DMS" (sexagecimal), "RAD" (radians) and "GON" (grades) for geographical coordinates, - * and "M" or "KM" for metric coordinates - */ - setUnits (units) { - if (!units || !Array.isArray(units)) { - return; - } - this.options.units = units; - this._projectionUnits = []; - this._initProjectionUnits(); - if (this._currentProjectionType) { - this._setTypeUnitsPanel(this._currentProjectionType); - } - } - - /** - * Set control altitude options (useless if displayAltitude == false) - * - * @param {Object} options - altitude options - * @param {Object} [options.serviceOptions] - options of elevation service - * @param {Number} [options.responseDelay] - latency for elevation request, 500 ms by default - * @param {Number} [options.triggerDelay] - immobilisation time of movement on the map to trigger the elevation calculation, 200 ms by default - */ - setAltitudeOptions (options) { - if (!options || typeof options !== "object") { - return; - } - this.options.altitude.triggerDelay = options.triggerDelay; - this.options.altitude.responseDelay = options.responseDelay; - if (options.serviceOptions) { - for (var opt in options.serviceOptions) { - if (options.serviceOptions.hasOwnProperty(opt)) { - this.options.altitude.serviceOptions[opt] = options.serviceOptions[opt]; - } - } - } - } - - /** - * Display or hide elevation panel - * - * @param {Boolean} displayAltitude - true to display elevation panel, false to hide it - */ - displayAltitude (displayAltitude) { - if (displayAltitude === undefined) { - return; - } - - this.options.displayAltitude = displayAltitude; - this._setElevationPanel(displayAltitude); - } - - /** - * Display or hide coordinates panel - * - * @param {Boolean} displayCoordinates - true to display coordinates panel, false to hide it - */ - displayCoordinates (displayCoordinates) { - if (displayCoordinates === undefined) { - return; - } - this.options.displayCoordinates = displayCoordinates; - this._setCoordinatesPanel(displayCoordinates); - this._setSettingsPanel(displayCoordinates); - } - - /** - * Collapse or display control main container - * - * @param {Boolean} collapsed - True to collapse control, False to display it - */ - setCollapsed (collapsed) { - if (collapsed === undefined) { - logger.log("[ERROR] MousePosition:setCollapsed - missing collapsed parameter"); - return; - } - if ((collapsed && this.collapsed) || (!collapsed && !this.collapsed)) { - return; - } - if (!this._isDesktop) { - document.getElementById("GPmapCenter").className = collapsed ? "" : "GPmapCenterVisible"; - } - // on simule l'ouverture du panneau après un click - this.onShowMousePositionClick(); - this._showMousePositionContainer.checked = !collapsed; - } - - // ################################################################### // - // ######################## initialize control ####################### // - // ################################################################### // - - /** - * Initialize control (called by MousePosition constructor) - * - * @param {Object} options - control options (set by user) - * @private - */ - _initialize (options) { - // Set default options - options = options || {}; - // {Object} control options - set by user or by default - this.options = options; - this.options.collapsed = (options.collapsed !== undefined) ? options.collapsed : true; - /** {Boolean} specify if MousePosition control is collapsed (true) or not (false) */ - this.collapsed = this.options.collapsed; - - this.options.draggable = (options.draggable !== undefined) ? options.draggable : false; - /** {Boolean} specify if MousePosition control is draggable (true) or not (false) */ - this.draggable = this.options.draggable; - - // position marker - this._markerOverlay = null; - this._markerUrl = null; - this._markerOffset = [0, 0]; - this._hideMarker = false; - this._initMarker(options.positionMarker); - - this.options.units = options.units || []; - this.options.displayAltitude = (options.displayAltitude !== undefined) ? options.displayAltitude : true; - this.options.displayCoordinates = (options.displayCoordinates !== undefined) ? options.displayCoordinates : true; - if (this.options.displayCoordinates) { - this.options.editCoordinates = (options.editCoordinates !== undefined) ? options.editCoordinates : false; - } else { - // si les coordonnées ne sont pas affichées : pas besoin de les éditer... - this.options.editCoordinates = false; - } - this.editing = false; - - this.options.systems = options.systems || []; - if (options.altitude) { - var altitude = options.altitude; - this.options.altitude = { - triggerDelay : (altitude.triggerDelay !== undefined) ? altitude.triggerDelay : 200, - responseDelay : (altitude.responseDelay !== undefined) ? altitude.responseDelay : 500, - serviceOptions : altitude.serviceOptions || {}, - noDataValue : (altitude.noDataValue !== undefined) ? altitude.noDataValue : -99999, - noDataValueTolerance : (altitude.noDataValueTolerance !== undefined) ? altitude.noDataValueTolerance : 90000 - }; - } else { - this.options.altitude = { - triggerDelay : 200, - responseDelay : 500, - serviceOptions : {} - }; - } - - // identifiant du contrôle : utile pour suffixer les identifiants CSS (pour gérer le cas où il y en a plusieurs dans la même page) - this._uid = SelectorID.generate(); - - // initialisation des systemes de projections - this._projectionSystems = []; - this._initProjectionSystems(); - - // initialisation des systemes des unités - this._projectionUnits = {}; - this._initProjectionUnits(); - - // detection du support : desktop ou tactile - this._isDesktop = Utils.detectSupport(); - - // on met en place un seuil sur le timer - if (this.options.altitude.triggerDelay < 100) { - this.options.altitude.triggerDelay = 100; - } - - // {Number} timer on movestopped delay (altitude calculation) - this._timer = this.options.altitude.triggerDelay; - - // {Object} Selected projection system - this._currentProjectionSystems = this._projectionSystems[0]; - - // {String} Selected projection units typs : Geographical or metric - this._currentProjectionType = this._projectionSystems[0].type; - - // {String} Selected projection unit - this._currentProjectionUnits = this._projectionUnits[this._currentProjectionType][0].code; - - // {Object} Projection units container (DOM Element) - this._projectionUnitsContainer = null; - - // {Object} control panel container (DOM Element) - this._showMousePositionContainer = null; - this._panelMousePositionContainer = null; - this._panelHeaderMousePositionContainer = null; - - // gestion de l'affichage du panneau de l'altitude - if (!this.options.displayAltitude && !this.options.displayCoordinates) { - // on reactive l'affichage des coordonnées, pour ne pas afficher un panneau vide ! - this.options.displayCoordinates = true; - } - - // listener key for event on pointermove or moveend map - this.listenerKey = null; - } - - /** - * - * @param {Object} option - positionMarker option - * @private - */ - _initMarker (option) { - if (!this.options.editCoordinates) { - return; - } - - if (!option) { - this._markerUrl = Markers["lightOrange"]; - this._markerOffset = Markers.defaultOffset; - return; - } - - // hide - this._hideMarker = (option.hide !== undefined) ? option.hide : false; - - // offset - if (option.offset) { - if (Array.isArray(option.offset) && option.offset.length === 2) { - this._markerOffset = option.offset; - } else { - logger.log("positionMarker.offset should be an array. e.g. : [0,0]"); - this._markerOffset = Markers.defaultOffset; - } - } else { - this._markerOffset = Markers.defaultOffset; - } - - var url = option.url; - if (!url) { - this._markerUrl = Markers["lightOrange"]; - } else if (url.match(/^[a-zA-Z]+$/)) { // un seul mot - this._markerUrl = (Markers[url] !== undefined) ? Markers[url] : Markers["lightOrange"]; - } else { - this._markerUrl = url; - } - } - - /** - * this method is called by the constructor and initialize the projection - * systems. - * getting coordinates in the requested projection : - * see this.onMousePositionProjectionSystemChange() - * - * @private - */ - _initProjectionSystems () { - // on donne la possibilité à l'utilisateur de modifier - // la liste des systèmes à afficher - // Ex. this.options.systems - - // FIXME doit on charger des projections par defaut dans ce composant ? - // chargement des projections par defaut - // CRS.loadByDefault(); - // CRS.overload(); - - // systemes de projection disponible par defaut - var projectionSystemsByDefault = [{ - label : "G\u00e9ographique", - crs : olGetProj("EPSG:4326").getCode(), - type : "Geographical" - }, { - label : "Web Mercator", - crs : olGetProj("EPSG:3857").getCode(), - type : "Metric" - }, { - label : "Lambert 93", - crs : olGetProj("EPSG:2154").getCode(), - type : "Metric", - geoBBox : { - left : -9.86, - bottom : 41.15, - right : 10.38, - top : 51.56 - } - }, { - label : "Lambert II \u00e9tendu", - crs : olGetProj("EPSG:27572").getCode(), - type : "Metric", - geoBBox : { - left : -4.87, - bottom : 42.33, - right : 8.23, - top : 51.14 - } - }]; - - var systems = this.options.systems; - for (var i = 0; i < systems.length; i++) { - /* definition d'un systeme de reference */ - var sys = systems[i]; - this.addSystem(sys); - } - - if (this._projectionSystems.length === 0) { - // on ajoute les systèmes de projections par défaut - for (var j = 0; j < projectionSystemsByDefault.length; j++) { - this.addSystem(projectionSystemsByDefault[j]); - } - } - } - - /** - * this method is called by the constructor and initialize the units. - * getting coordinates in the requested units : - * see this.onMousePositionProjectionUnitsChange() - * - * @private - */ - _initProjectionUnits () { - // on donne la possibilité à l'utilisateur de modifier - // la liste des unités à afficher - // Ex. - // this.options.units : ["DEC", "DMS"] - - // unités disponible par defaut - var projectionUnitsByDefault = { - Geographical : [{ - code : "DEC", - label : "degrés décimaux", - format : MathUtils.coordinateToDecimal - }, { - code : "DMS", - label : "degrés sexagésimaux", - format : MathUtils.coordinateToDMS - }, { - code : "RAD", - label : "radians", - format : MathUtils.coordinateToRad - }, { - code : "GON", - label : "grades", - format : MathUtils.coordinateToGon - }], - Metric : [{ - code : "M", - label : "mètres", - format : MathUtils.coordinateToMeter - }, { - code : "KM", - label : "kilomètres", - format : MathUtils.coordinateToKMeter - }] - }; - - var units = this.options.units; - - for (var type in projectionUnitsByDefault) { - if (projectionUnitsByDefault.hasOwnProperty(type)) { - var found = false; - for (var j = 0; j < projectionUnitsByDefault[type].length; j++) { - var obj = projectionUnitsByDefault[type][j]; - for (var i = 0; i < units.length; i++) { - var unit = units[i]; - if (obj.code === unit) { - found = true; - if (!this._projectionUnits[type]) { - this._projectionUnits[type] = []; - } - this._projectionUnits[type].push(obj); - } - } - } - if (!found) { - this._projectionUnits[type] = projectionUnitsByDefault[type]; - } - } - } - - // au cas où... - if (typeof this._projectionUnits === "object" && Object.keys(this._projectionUnits).length === 0) { - this._projectionUnits = projectionUnitsByDefault; - } - } - - /** - * this method get label from the current projection units - * - * @returns {String} projection information - * - * @private - */ - _getCurrentProjectionInformation () { - var systemInfo = [ - this._currentProjectionSystems.label, - "en" - ]; - - var units = this._projectionUnits[this._currentProjectionType]; - for (var u = 0; u < units.length; ++u) { - if (units[u].code === this._currentProjectionUnits) { - systemInfo.push(units[u].label); - break; - } - } - return systemInfo.join(" "); - } - - // ################################################################### // - // ######################## methods handle dom ####################### // - // ################################################################### // - - /** - * Create control main container (called by MousePosition constructor) - * - * @returns {DOMElement} DOM element - * - * @private - */ - _initContainer () { - // creation du container principal - var container = this._createMainContainerElement(); - - // create ReverseGeocode picto - var picto = this._showMousePositionButton = this._createShowMousePositionPictoElement(); - container.appendChild(picto); - - // panel - var mousePositionPanel = this._panelMousePositionContainer = this._createMousePositionPanelElement(); - var mousePositionPanelDiv = this._createMousePositionPanelDivElement(); - mousePositionPanel.appendChild(mousePositionPanelDiv); - - // header - var panelHeader = this._panelHeaderContainer = this._createMousePositionPanelHeaderElement(); - - // panel title - var panelTitle = this._panelTitleContainer = this._createMousePositionPanelTitleElement(); - panelHeader.appendChild(panelTitle); - - // close picto - var closeDiv = this._panelCloseButton = this._createMousePositionPanelCloseElement(); - panelHeader.appendChild(closeDiv); - mousePositionPanelDiv.appendChild(panelHeader); - - var basic = this._createMousePositionPanelBasicElement( - this.options.displayAltitude, - this.options.displayCoordinates, - this.options.editCoordinates, - this._currentProjectionUnits - ); - mousePositionPanelDiv.appendChild(basic); - - var buttonSettings = this._createShowMousePositionSettingsElement(this.options.displayCoordinates); - mousePositionPanelDiv.appendChild(buttonSettings); - - var settings = this._createMousePositionSettingsElement(); - var systems = this._projectionSystemsContainer = this._createMousePositionSettingsSystemsElement(this._projectionSystems); - var units = this._projectionUnitsContainer = this._createMousePositionSettingsUnitsElement(this._projectionUnits[this._currentProjectionType]); - settings.appendChild(systems); - settings.appendChild(units); - mousePositionPanelDiv.appendChild(settings); - - container.appendChild(mousePositionPanel); - - return container; - } - - /** - * this method is called by this.() - * and it changes the elevation view panel into the dom. - * - * @param {Boolean} active - true:active, false:disable - * @private - */ - _setElevationPanel (active) { - var div = null; - - if (!active) { - div = document.getElementById("GPmousePositionAltitude-" + this._uid); - div.style.display = "none"; - } else { - div = document.getElementById("GPmousePositionAltitude-" + this._uid); - div.style.display = ""; - } - } - - /** - * this method is called by this.() - * and it changes the coordinate view panel into the dom. - * - * @param {Boolean} active - true:active, false:disable - * @private - */ - _setCoordinatesPanel (active) { - var div = document.getElementById("GPmousePositionCoordinate-" + this._uid); - if (!active) { - div.style.display = "none"; - } else { - div.style.display = ""; - } - } - - /** - * this method is called by this.() - * and it changes the settings view panel into the dom. - * - * @param {Boolean} active - true:active, false:disable - * @private - */ - _setSettingsPanel (active) { - var divPicto = document.getElementById("GPshowMousePositionSettingsPicto-" + this._uid); - var divPanel = document.getElementById("GPmousePositionSettings-" + this._uid); - if (!active) { - divPicto.style.display = "none"; - divPanel.style.display = "none"; - } else { - divPicto.style.display = ""; - divPanel.style.display = ""; - } - } - - /** - * this method is called by this.onMousePositionProjectionSystemChange() - * when changes to a metric or a geographical units. - * - * @param {String} type - Geographical or Metric - * @private - */ - _setTypeUnitsPanel (type) { - var container = this._projectionUnitsContainer; - - // on supprime les enfants... - while (container.firstChild) { - container.removeChild(container.firstChild); - } - - var units = this._projectionUnits[type]; - for (var j = 0; j < units.length; j++) { - var obj = units[j]; - var option = document.createElement("option"); - option.value = (obj.code) ? obj.code : j; - option.text = obj.label || j; - // option.label = obj.label; - container.appendChild(option); - } - - var projectionUnits = this._projectionUnits[type][0].code; - - if (this._currentProjectionUnits === "DMS" || projectionUnits === "DMS") { - this._resetCoordinateElements(this.options.editCoordinates, type, projectionUnits); - this._setEditMode(this.editing); - } - - // le nouveau type de system ... - this._currentProjectionType = type; - - // Mise a jour des elements labels et unites - this._resetLabelElements(type); - this._resetUnitElements(projectionUnits); - - // et comme on a changé de type de systeme, - // il faut changer aussi d'unité ! - this._currentProjectionUnits = projectionUnits; - } - - // ################################################################### // - // ##################### handlers events to control ################## // - // ################################################################### // - - /** - * this sends the coordinates to the panel. - * (cf. this.GPdisplayCoords() into the DOM functions) - * - * @param {Array} olCoordinate - ol.Coordinate object [lon, lat] - * @param {Object} crs - coordinate CRS (ol.proj.Projection) - * @private - */ - _setCoordinate (olCoordinate, crs) { - // structure - // ol.Coordinate - // [ - // 4 // lon - // 48 // lat - // ] - - // structure pour les coordonnées en fonctin du type demandé : - // {x:, y:, unit:} ou {lng:, lat:} ou {lon:, lat:} ou {e:, n:, unit:}... - var coordinate = {}; - // on projete le point dans le systeme demandé - var oSrs = this._currentProjectionSystems.crs; - if (!oSrs) { - logger.log("ERROR : system crs not found"); - return; - } - // on reprojette les coordonnées depuis leur CRS d'origine (CRS) vers le CRS demandé (oSrs) - olCoordinate = olTransformProj(olCoordinate, crs, oSrs); - - // type de systeme : Geographical ou Metric - var type = this._currentProjectionSystems.type; - - // on recherche la fonction de formatage dans l'unité demandée - var format = null; - var units = this._projectionUnits[type]; - for (var i = 0; i < units.length; i++) { - if (units[i].code === this._currentProjectionUnits) { - format = units[i].format; - break; - } - } - if (!format || typeof format !== "function") { - logger.log("WARNING : coordinates format function not found"); - return; - } else { - coordinate = format(olCoordinate); - } - - if (!coordinate || Object.keys(coordinate).length === 0) { - return; - } - - this.GPdisplayCoords(coordinate); - } - - /** - * this sends the coordinates to the panel. - * (cf. this.GPdisplayElevation() into the DOM functions) - * - * @param {Array} olCoordinate - ol.Coordinate object [lon, lat] - * @private - */ - _setElevation (olCoordinate) { - // gestion du timer de la requete du service d'altitude - var delay = this.options.altitude.responseDelay; - var noDataValue = this.options.altitude.noDataValue; - var noDataValueTolerance = this.options.altitude.noDataValueTolerance; - this.GPdisplayElevation(olCoordinate, delay, noDataValue, noDataValueTolerance); - } - - /** - * this method is triggered when the mouse or the map is stopped. - * (cf. onMouseMove and onMapMove) - * - * @param {Array} olCoordinate - ol.Coordinate object [lon, lat] - * @param {Object} crs - coordinate CRS (ol.proj.Projection) - * @private - */ - onMoveStopped (olCoordinate, crs) { - // reprojection en CRS:84 (EPSG:4326) pour le calcul alti - var oLatLng = olTransformProj(olCoordinate, crs, "EPSG:4326"); - this._setElevation(oLatLng); - } - - /** - * this method is an handler event to control. The event is 'mousemove' on - * the map. The handler sends the coordinates to the panel. - * (cf. this.GPdisplayCoords() into the DOM functions) - * - * @param {Object} e - HTMLElement - * @private - */ - onMouseMove (e) { - var self = this; - - // info: coordinate = [x, y] - var coordinate = e.coordinate; - if (!e.map || !e.map.getView()) { - return; - } - var crs = e.map.getView().getProjection(); - - this._setCoordinate(coordinate, crs); - - // calcul de l'altitude après un certain délai après l'arrêt du mouvement de la souris - clearTimeout(this._timer); - this._timer = setTimeout(function () { - self.onMoveStopped(coordinate, crs); - }, this.options.altitude.triggerDelay); - } - - /** - * this method is an handler event to control. The event is 'moveend' on - * the map. The handler sends the coordinates to the panel. - * (cf. this.GPdisplayCoords() into the DOM functions) - * - * @private - */ - onMapMove () { - var self = this; - - var map = this.getMap(); - if (!map || !map.getView()) { - return; - } - var view = map.getView(); - var coordinate = view.getCenter(); - var crs = view.getProjection(); - - this._setCoordinate(coordinate, crs); - - // calcul de l'altitude après un certain délai après l'arrêt du mouvement de la souris - clearTimeout(this._timer); - this._timer = setTimeout(function () { - self.onMoveStopped(coordinate, crs); - }, this.options.altitude.triggerDelay); - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - - /** - * this method is called by this.GPdisplayElevation() in the dom, and - * it executes a request to the elevation service. - * - * @param {Object} coordinate - {lat:..., lng:...} - * @param {Function} callback - callback - * @private - */ - onRequestAltitude (coordinate, callback) { - // INFORMATION - // on effectue la requête au service d'altitude... - // on met en place des callbacks afin de recuperer les resultats ou - // les messages d'erreurs du service. - // le resultat est affiché dans une balise du dom. - - if (!coordinate || Object.keys(coordinate).length === 0) { - return; - } - - // si on ne veut pas de calcul d'altitude, on ne continue pas ! - if (!this.options.displayAltitude) { - return; - } - - // on recupere les options du service - var options = this.options.altitude.serviceOptions || {}; - - // gestion du protocole et du timeout - // le timeout est indispensable sur le protocole JSONP. - var _protocol = options.protocol || "XHR"; - var _timeout = options.timeOut || 0; - if (_protocol === "JSONP" && _timeout === 0) { - _timeout = 15000; - } - - // format de sortie si spécifié - var _outputFormat = options.outputFormat || "json"; - - // ainsi que les coordonnées : si l'utilisateur explicite zonly false - var _zonly = true; - // cela permet d'activer l'option measures côté service d'alti (surchargée si zonly = true) - var _zonly; - if (options.zonly === false) { - _zonly = options.zonly; - } else { - _zonly = true; - } - - // récupération d'une réponse complète avec source et précision - var _measures = options.measures || false; - - - var _positions = [{ - lon : coordinate[0], - lat : coordinate[1] - }]; - - // utilisation d'une ressource spécifique - var _resource = options.resource; - - // et les callbacks - var _scope = this; - var _rawResponse = options.rawResponse || false; - var _customOnSuccess = options.onSuccess || null; - var _onSuccess = null; - var _onFailure = null; - - if (!_rawResponse) { - // dans le cas général - // callback onSuccess - _onSuccess = function (results) { - if (results && Object.keys(results).length) { - if (_customOnSuccess) { - _customOnSuccess.call(this, results); - } - callback.call(this, results.elevations[0].z); - } - }; - } else { - // callback onSuccess - _onSuccess = function (results) { - if (_customOnSuccess) { - _customOnSuccess.call(this, results); - } - logger.log("alti service raw response : ", results); - }; - } - - // callback onFailure - _onFailure = function (error) { - logger.log("[getAltitude] ERROR : " + error.message); - }; - - // cas où la clef API n'est pas renseignée dans les options du service, - // on utilise celle renseignée au niveau du controle ou la clé "calcul" par défaut. - var _apiKey = options.apiKey || this.options.apiKey; - - // si l'utilisateur a spécifié le paramètre ssl au niveau du control, on s'en sert - // true par défaut (https) - if (typeof options.ssl !== "boolean") { - if (typeof this.options.ssl === "boolean") { - options.ssl = this.options.ssl; - } else { - options.ssl = true; - } - } - var _ssl = options.ssl; - - Gp.Services.getAltitude({ - apiKey : _apiKey, - protocol : _protocol, - ssl : _ssl, - timeOut : _timeout, - scope : _scope, - outputFormat : _outputFormat, - rawResponse : _rawResponse, - onSuccess : _onSuccess, - onFailure : _onFailure, - zonly : _zonly, - measures : _measures, - resource : _resource, - positions : _positions - }); - } - - /** - * this method is called by event 'click' on 'GPshowMousePositionPicto' tag label - * (cf. this._createShowMousePositionPictoElement), - * and toggles event 'mousemove' on map. - * - * @private - */ - onShowMousePositionClick () { - // checked : true - panel close - // checked : false - panel open - var map = this.getMap(); - // on supprime toutes les interactions - Interactions.unset(map); - var opened = this._showMousePositionButton.ariaPressed; - this.collapsed = !(opened === "true"); - // on génère nous même l'evenement OpenLayers de changement de propriété - // (utiliser mousePosition.on("change:collapsed", function(e) ) pour s'abonner à cet évènement) - this.dispatchEvent("change:collapsed"); - - // evenement declenché à l'ouverture/fermeture du panneau, - // et en fonction du mode : desktop ou tactile ! - if (opened === "false") { - olObservableUnByKey(this.listenerKey); - } else if (!this.editing) { - if (this._isDesktop) { - this.listenerKey = map.on("pointermove", (e) => { this.onMouseMove(e); }); - } else { - this.listenerKey = map.on("moveend", (e) => this.onMapMove(e)); - // on simule un deplacement en mode tactile - this.onMapMove(); - } - } - - // FIXME - // on gère l'affichage des panneaux ici..., même si ce n'est pas l'endroit - // adequate... - this._setElevationPanel(this.options.displayAltitude); - this._setCoordinatesPanel(this.options.displayCoordinates); - if (!this.options.displayCoordinates) { - this._setSettingsPanel(false); - } - } - - /** - * this method is called by event 'click' on 'GPshowMousePositionPicto' tag label - * (cf. this._createShowMousePositionPictoElement), - * and toggles event 'mousemove' on map. - * - * @param {Object} e - HTMLElement - * @private - */ - onShowMousePositionSettingsClick (e) { - if (!this.draggable) { - var opened = e.target.ariaPressed; - if (opened === "true") { - // somme stuff... - } - } - } - - /** - * this method is called by event 'click' on input coordinate - * - * @param {Boolean} editing - editing mode - */ - onMousePositionEditModeClick (editing) { - if (!this.options.editCoordinates) { - return; - } - if (this.editing === editing) { - return; - } - - this.editing = editing; - - // Affichage des outils, input en ecriture - this._setEditMode(this.editing); - - var map = this.getMap(); - if (this._isDesktop) { - if (this.editing) { // Unlisten for 'pointermove' events - // map.un("pointermove", (e) => { this.onMouseMove(e); }); - olObservableUnByKey(this.listenerKey); - } else { // Listen for 'pointermove' events - this.listenerKey = map.on("pointermove", (e) => { this.onMouseMove(e); }); - // on simule un deplacement - this.onMapMove(); - } - } else { - if (this.editing) { // Unlisten for 'moveend' events - // map.un("moveend", (e) => this.onMapMove(e)); - olObservableUnByKey(this.listenerKey); - } else { // Listen for moveend' events - this.listenerKey = map.on("moveend", (e) => this.onMapMove(e)); - // on simule un deplacement - this.onMapMove(); - } - } - - // clear _markerOverlay - if (!this.editing && this._markerOverlay) { - this._markerOverlay.setPosition(undefined); - } - } - - /** - * Get coordinate from inputs and select in decimal degrees - * - * @param {String} coordType - "Lon" or "Lat" - * @returns {undefined} - * @private - */ - getCoordinate (coordType) { - var inputDegrees = document.getElementById(this._addUID("GPmousePosition" + coordType + "Degrees")); - var degrees = inputDegrees.value; - if (!degrees) { - return null; - } - - degrees = degrees.replace(",", "."); - if (!MathUtils.isInteger(degrees)) { - return null; - } - - var result = MathUtils.toInteger(degrees); - if (result < Number(inputDegrees.dataset.min) || result > Number(inputDegrees.dataset.max)) { - return null; - } - - var direction = document.getElementById(this._addUID("GPmousePosition" + coordType + "Direction")).value; - - var inputMinutes = document.getElementById(this._addUID("GPmousePosition" + coordType + "Minutes")); - var minutes = inputMinutes.value; - if (minutes) { - minutes = minutes.replace(",", "."); - if (MathUtils.isInteger(minutes)) { - var mins = MathUtils.toInteger(minutes); - if (mins >= Number(inputMinutes.dataset.min) && mins <= Number(inputMinutes.dataset.max)) { - result += (mins / 60); - } - } - } - - var inputSeconds = document.getElementById(this._addUID("GPmousePosition" + coordType + "Seconds")); - var seconds = inputSeconds.value; - if (seconds) { - seconds = seconds.replace(",", "."); - var secs = MathUtils.toFloat(seconds); - if (secs && secs >= Number(inputSeconds.dataset.min) && secs <= Number(inputSeconds.dataset.max)) { - result += (secs / 3600); - } - } - - if (direction === "O" || direction === "S") { - result = -result; - } - - return result; - } - - /** - * locate DMS coordinates on map - * - * @private - */ - locateDMSCoordinates () { - var lonlat = [ - this.getCoordinate("Lon"), - this.getCoordinate("Lat") - ]; - - if (lonlat[0] === null || lonlat[1] === null) { - return; - } - - var oSrs = this._currentProjectionSystems.crs; - if (!oSrs) { - logger.log("ERROR : system crs not found"); - return; - } - - var view = this.getMap().getView(); - - var coordinate = olTransformProj(lonlat, oSrs, view.getProjection()); - view.setCenter(coordinate); - - if (this._markerOverlay && !this._hideMarker) { - this._markerOverlay.setPosition(coordinate); - } - } - - /** - * locate coordinates on map (not DMS) - * - * @private - */ - locateCoordinates () { - var lon = document.getElementById(this._addUID("GPmousePositionLon")).value; - - lon = lon.replace(",", "."); - lon = MathUtils.toFloat(lon); - if (lon === null) { - return; - } - - var lat = document.getElementById(this._addUID("GPmousePositionLat")).value; - lat = lat.replace(",", "."); - lat = MathUtils.toFloat(lat); - if (lat === null) { - return; - } - - var oSrs = this._currentProjectionSystems.crs; - if (!oSrs) { - logger.log("ERROR : system crs not found"); - return; - } - - var xy; - if (this._currentProjectionSystems.type === "Geographical") { - xy = [this.convert(lon), this.convert(lat)]; - } else { - xy = [this.convert(lat), this.convert(lon)]; - } - var xyWGS84 = olTransformProj(xy, this._currentProjectionSystems.crs, "EPSG:4326"); - - var geoBBox = this._currentProjectionSystems.geoBBox; - if (geoBBox) { // check if coordinates are in the extent - var extent = [geoBBox.left, geoBBox.bottom, geoBBox.right, geoBBox.top]; - if (xyWGS84[0] < extent[0] || xyWGS84[0] > extent[2]) { - return; - } - if (xyWGS84[1] < extent[1] || xyWGS84[1] > extent[3]) { - return; - } - } - - var view = this.getMap().getView(); - - var coordinate = olTransformProj(xy, oSrs, view.getProjection()); - view.setCenter(coordinate); - - if (this._markerOverlay && !this._hideMarker) { - this._markerOverlay.setPosition(coordinate); - } - } - - /** - * locate coordinates on map - * - * @private - */ - onMousePositionEditModeLocateClick () { - if (!this.options.editCoordinates) { - return; - } - if (!this.editing) { - this.onMousePositionEditModeClick(true); - return; - } - - if (this._currentProjectionUnits === "DMS") { - this.locateDMSCoordinates(); - } else { - this.locateCoordinates(); - } - - // fonction - var mapCenterFunction = this.options.mapCenterCallback; - - // execution... - if (typeof mapCenterFunction === "function") { - var view = this.getMap().getView(); - var center = view.getCenter(); - mapCenterFunction.call(this, center); - } - } - - /** - * this method is called by event 'change' on 'GPmousePositionProjectionSystem' - * tag select (cf. this._createMousePositionSettingsElement), - * and selects the system projection. - * - * @param {Object} e - HTMLElement - * @private - */ - onMousePositionProjectionSystemChange (e) { - var idx = e.target.selectedIndex; // index - var value = e.target.options[idx].value; // crs - - this._setCurrentSystem(value); - } - - /** - * this method selects the current system projection. - * - * @param {String} systemCode - inner code (rank in array _projectionSystems) - * @private - */ - _setCurrentSystem (systemCode) { - // si on change de type de systeme, on doit aussi changer le type d'unités ! - var type = null; - for (var i = 0; i < this._projectionSystems.length; ++i) { - if (this._projectionSystems[i].code === Number(systemCode)) { - type = this._projectionSystems[i].type; - break; - } - } - - if (!type) { - logger.log("system not found in projection systems container"); - return; - } - - // on enregistre le systeme courant - this._currentProjectionSystems = this._projectionSystems[Number(systemCode)]; - - if (type !== this._currentProjectionType) { - this._setTypeUnitsPanel(type); - } - - // on simule un deplacement en mode tactile pour mettre à jour les - // resultats - if (!this._isDesktop) { - this.onMapMove(); - } - } - - /** - * this method is called by event 'mouseover' on 'GPmousePositionProjectionSystem' - * tag select (cf. this._createMousePositionSettingsElement), - * and selects the system projection. - * - * @param {Object} e - HTMLElement - * @private - */ - onMousePositionProjectionSystemMouseOver (e) { - logger.trace(e); - - // map infos - var map = this.getMap(); - if (!map || !map.getView()) { - return; - } - var view = map.getView(); - var crs = view.getProjection(); - var mapExtent = view.calculateExtent(map.getSize()); - - // get extent in WGS84 coordinates - mapExtent = olTransformExtentProj(mapExtent, crs, "EPSG:4326"); - - /* clear select */ - var systemList = document.getElementById(this._addUID("GPmousePositionProjectionSystem")); - systemList.innerHTML = ""; - - // add systems whose extent intersects the map extent - for (var j = 0; j < this._projectionSystems.length; j++) { - var proj = this._projectionSystems[j]; - var option = null; - - if (proj.geoBBox) { - /* bboxes intersection test */ - if (mapExtent[0] > proj.geoBBox.right || - mapExtent[1] > proj.geoBBox.top || - mapExtent[2] < proj.geoBBox.left || - mapExtent[3] < proj.geoBBox.bottom - ) { - if (proj === this._currentProjectionSystems) { - option = document.createElement("option"); - option.value = proj.code; - option.text = proj.label || j; - option.setAttribute("selected", "selected"); - option.setAttribute("disabled", "disabled"); - - systemList.appendChild(option); - } - continue; // do not intersect - } - } - - var optionElement = document.createElement("option"); - optionElement.value = proj.code; - optionElement.text = proj.label || j; - - if (proj === this._currentProjectionSystems) { - optionElement.setAttribute("selected", "selected"); - } - systemList.appendChild(optionElement); - } - } - - /** - * this method is called by event 'change' on 'GPmousePositionProjectionUnits' - * tag select (cf. this._createMousePositionSettingsElement), - * and selects the units projection. - * - * @param {Object} e - HTMLElement - * @private - */ - onMousePositionProjectionUnitsChange (e) { - var idx = e.target.selectedIndex; - var value = e.target.options[idx].value; - - var oldProjectionUnits = this._currentProjectionUnits; - this._currentProjectionUnits = value; - - // Mise a jour des elements lebels et unites - this._resetLabelElements(this._currentProjectionType); - this._resetUnitElements(this._currentProjectionUnits); - - // mise a jour des inputs pour les coordonnees - if (oldProjectionUnits === "DMS" || this._currentProjectionUnits === "DMS") { - this._resetCoordinateElements(this.options.editCoordinates, this._currentProjectionType, this._currentProjectionUnits); - this._setEditMode(this.editing); - } - - // on simule un deplacement en mode tactile pour mettre à jour les - // resultats - if (!this._isDesktop) { - this.onMapMove(); - } - } - - /** - * - * @param {Number} value - value to convert (km to meters, radians, grades to decimal degrees) - * @returns {undefined} - * @private - */ - convert (value) { - var result; - if (this._currentProjectionUnits === "M" || this._currentProjectionUnits === "DEC") { - result = value; - } else if (this._currentProjectionUnits === "KM") { - result = value * 1000; - } else if (this._currentProjectionUnits === "RAD") { - var rd = (180 / Math.PI).toFixed(20); - result = (value * rd).toFixed(20); - } else if (this._currentProjectionUnits === "GON") { - var d = (9 / 10).toFixed(20); - result = (value * d).toFixed(20); - } - - return result; - } - - /** - * @param {String} coordType - "Lon" or "Lat" - * @param {String} value - input value - * - * @returns {Boolean} value is within extent - * - * @private - */ - validateExtentCoordinate (coordType, value) { - if (["Lon", "Lat"].indexOf(coordType) === -1) { - return false; - } - - var coord = value.replace(",", "."); - coord = MathUtils.toFloat(coord); - if (coord === null) { - return false; - } - - // convert depending on _currentProjectionUnits - coord = this.convert(coord); - - var geoBBox = this._currentProjectionSystems.geoBBox; - if (geoBBox === undefined) { - return true; - } - - // convert to current projection system - var extent = [geoBBox.left, geoBBox.bottom, geoBBox.right, geoBBox.top]; - extent = olTransformExtentProj(extent, "EPSG:4326", this._currentProjectionSystems.crs); - - // checking if value is in the right interval - if (coordType === "Lat" && (coord < extent[0] || coord > extent[2])) { - return false; - } - if (coordType === "Lon" && (coord < extent[1] || coord > extent[3])) { - return false; - } - - return true; - } - -}; - -// on récupère les méthodes de la classe commune MousePosition -Object.assign(MousePosition.prototype, MousePositionDOM); - -export default MousePosition; - -// Expose MousePosition as ol.control.MousePosition (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.GeoportalMousePosition = MousePosition; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePositionDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePositionDOM.d.ts deleted file mode 100644 index b0bbba28e..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePositionDOM.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -export default MousePositionDOM; -declare namespace MousePositionDOM { - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createShowMousePositionPictoElement(isDesktop: boolean): DOMElement; - function _createMousePositionPanelElement(): DOMElement; - function _createMousePositionPanelDivElement(): HTMLDivElement; - function _createMapCenter(): DOMElement; - function _createMousePositionPanelTitleElement(): DOMElement; - function _createMousePositionPanelHeaderElement(): DOMElement; - function _createMousePositionPanelCloseElement(): DOMElement; - function _createMousePositionPanelBasicElement(displayAltitude?: boolean | undefined, displayCoordinates?: boolean | undefined, editCoordinates?: boolean | undefined, currentProjectionUnits?: boolean | undefined): DOMElement; - function _createCoordinateElement(coordType: string, editCoordinates?: boolean | undefined): any[]; - function _createDMSCoordinateElement(coordType: string, editCoordinates?: boolean | undefined): any[]; - function _createMousePositionPanelBasicCoordinateElement(display?: boolean | undefined, editCoordinates?: boolean | undefined, currentProjectionUnits?: boolean | undefined): DOMElement; - function _createMousePositionPanelBasicAltitudeElement(display?: boolean | undefined): DOMElement; - function _createMousePositionPanelEditToolsElement(editCoordinates?: boolean | undefined): DOMElement; - function _createShowMousePositionSettingsElement(display?: boolean | undefined): DOMElement[]; - function _createMousePositionSettingsElement(display?: boolean | undefined): DOMElement; - function _createMousePositionSettingsSystemsElement(systems: Object[]): DOMElement; - function _createMousePositionSettingsUnitsElement(units: Object[]): DOMElement; - function _resetLabelElements(currentProjectionType?: string | undefined): void; - function _resetUnitElements(currentProjectionUnits: string): void; - function _resetCoordinateElements(editCoordinates: boolean, currentProjectionType: string, currentProjectionUnits: string): void; - function _setEditMode(editing: boolean): void; - function _checkDMSElement(input: DOMElement, isFloat: boolean): boolean; - function _checkDMSDegrees(coordType: string, input: DOMElement): boolean; - function GPdisplayCoords(coordinate: Object): void; - function GPdisplayElevation(coordinate: Object, altitudeTimeoutDelay: number, noDataValue: number, noDataValueTolerance: number): void; - function GPresetElevation(): void; -} -//# sourceMappingURL=MousePositionDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePositionDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePositionDOM.d.ts.map deleted file mode 100644 index 39a66f237..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePositionDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MousePositionDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/MousePosition/MousePositionDOM.js"],"names":[],"mappings":";;IAOc,qCAGT;IAO6B,mDAK7B;IAYsC,8EA2BtC;IAOkC,wDAKlC;IAEqC,+DAIrC;IAOkB,wCAKlB;IAeuC,6DAMvC;IAOwC,8DAMxC;IAOuC,6DAqCvC;IAeuC,iOAiBvC;IAU0B,mGA8B1B;IAS6B,sGAsG7B;IASiD,yLAwDjD;IAO+C,kGAuB/C;IAO2C,sGAkC3C;IAWyC,8FA4BzC;IAYqC,wFAYrC;IAO4C,mFA2B5C;IAO0C,+EAqB1C;IAKqB,+EAOrB;IAKoB,kEAUpB;IAO0B,iIAmC1B;IAOc,8CAoBd;IASkB,wEAmBlB;IAQkB,yEA4BlB;IAWiB,mDAiDjB;IAUoB,uIAqCpB;IAKkB,kCAIlB"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePositionDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePositionDOM.js deleted file mode 100644 index d44dd2424..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/MousePosition/MousePositionDOM.js +++ /dev/null @@ -1,893 +0,0 @@ -var MousePositionDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Main container (DOM) - * - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPmousePosition"); - container.className = "GPwidget gpf-widget gpf-widget-button"; - return container; - }, - - // ################################################################### // - // ################### Methods of main container ##################### // - // ################################################################### // - - /** - * Show mouse position control - * @param {Boolean} isDesktop - specifies if the support is desktop or tactile - * - * @returns {DOMElement} DOM element - */ - _createShowMousePositionPictoElement : function (isDesktop) { - // contexte d'execution - var self = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowMousePositionPicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto gpf-btn gpf-btn-icon gpf-btn-icon-position fr-btn"; - button.title = "Afficher les coordonnées du curseur"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // Close all results and panels when minimizing the widget - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onShowMousePositionClick(); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onShowMousePositionClick(); - }); - } - - return button; - }, - - /** - * Create Container Panel - * - * @returns {DOMElement} DOM element - */ - _createMousePositionPanelElement : function () { - var dialog = document.createElement("dialog"); - dialog.id = this._addUID("GPmousePositionPanel"); - dialog.className = "GPpanel gpf-panel fr-modal"; - return dialog; - }, - - _createMousePositionPanelDivElement : function () { - var div = document.createElement("div"); - div.className = "gpf-panel__body fr-modal__body"; - return div; - }, - - /** - * Map center localisation (tactile use) - * - * @returns {DOMElement} container - */ - _createMapCenter : function () { - var div = document.createElement("div"); - div.id = "GPmapCenter"; - div.className = ""; - return div; - }, - - // ################################################################### // - // ####################### Panel container ########################### // - // ################################################################### // - - /** - * @returns {DOMElement} container - */ - - /** - * Create Header Title Panel - * - * @returns {DOMElement} DOM element - */ - _createMousePositionPanelTitleElement : function () { - var div = document.createElement("div"); - div.className = "GPpanelTitle gpf-panel__title fr-modal__title"; - div.id = this._addUID("GPmousePositionHeaderTitle"); - div.innerHTML = "Coordonnées"; - return div; - }, - - /** - * Create Header Panel - * - * @returns {DOMElement} DOM element - */ - _createMousePositionPanelHeaderElement : function () { - var container = document.createElement("div"); - container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; - // info: on sépare les appels pour la création du picto de retour, - // du titre et de la croix de fermeture pour les récupérer dans le composant - return container; - }, - - /** - * Create Header close div - * - * @returns {DOMElement} DOM element - */ - _createMousePositionPanelCloseElement : function () { - // contexte - var self = this; - - var divClose = document.createElement("button"); - divClose.id = this._addUID("GPmousePositionPanelClose"); - divClose.className = "GPpanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--secondary fr-m-1w"; - divClose.title = "Fermer le panneau"; - - // Link panel close / visibility checkbox - if (divClose.addEventListener) { - divClose.addEventListener("click", function () { - document.getElementById(self._addUID("GPshowMousePositionPicto")).click(); - }, false); - divClose.addEventListener("keydown", function (event) { - if (event.keyCode === 13) { - document.getElementById(self._addUID("GPshowMousePositionPicto")).click(); - } - }, false); - } else if (divClose.attachEvent) { - divClose.attachEvent("onclick", function () { - document.getElementById(self._addUID("GPshowMousePositionPicto")).click(); - }); - divClose.attachEvent("onkeydown", function (event) { - if (event.keyCode === 13) { - document.getElementById(self._addUID("GPshowMousePositionPicto")).click(); - } - }); - } - - var span = document.createElement("span"); - span.className = "GPelementHidden gpf-visible"; // afficher en dsfr - span.innerText = "Fermer"; - - divClose.appendChild(span); - - return divClose; - }, - - /** - * coordinate panel - * @param {Boolean} [displayAltitude] - specifies if the altitude panel must be displayed - * @param {Boolean} [displayCoordinates] - specifies if the coordinates panel must be displayed - * @param {Boolean} [editCoordinates] - specifies if the coordinates edition is allowed - * @param {Boolean} [currentProjectionUnits] - specifies if the current projection units - * - * FIXME - * call this._createMousePositionPanelBasicCoordinateElement - * call this._createMousePositionPanelBasicAltitudeElement - * - * @returns {DOMElement} DOM element - */ - _createMousePositionPanelBasicElement : function (displayAltitude, displayCoordinates, editCoordinates, currentProjectionUnits) { - // default Values - displayAltitude = (typeof displayAltitude === "undefined") ? true : displayAltitude; - displayCoordinates = (typeof displayCoordinates === "undefined") ? true : displayCoordinates; - editCoordinates = (typeof editCoordinates === "undefined") ? false : editCoordinates; - - var container = document.createElement("div"); - container.id = this._addUID("GPmousePositionBasicPanel"); - container.classList.add("fr-mx-1w"); - - // FIXME on devrait decomposer la fonction pour les besoins du controle, - // on ajoutera ces childs à la main... - container.appendChild(this._createMousePositionPanelBasicCoordinateElement(displayCoordinates, editCoordinates, currentProjectionUnits)); - container.appendChild(this._createMousePositionPanelEditToolsElement(editCoordinates)); - container.appendChild(this._createMousePositionPanelBasicAltitudeElement(displayAltitude)); - - return container; - }, - - /** - * create coordinate elements - * - * @param {String} coordType - ("Lon" ou "Lat") - * @param {Boolean} [editCoordinates=false] - specifies if the coordinates edition is allowed - * - * @returns {Array} list of DOM elements - */ - _createCoordinateElement : function (coordType, editCoordinates) { - var context = this; - - if (["Lon", "Lat"].indexOf(coordType) === -1) { - return []; - } - - var list = []; - var input = document.createElement("input"); - input.id = this._addUID("GPmousePosition" + coordType); - input.title = editCoordinates === true ? "Cliquer pour saisir des coordonnées" : ""; - input.readOnly = true; - - if (editCoordinates) { - input.addEventListener("click", function () { - context.onMousePositionEditModeClick(true); - }); - input.addEventListener("change", function (e) { - this.classList.remove("error"); - var valid = context.validateExtentCoordinate(coordType, this.value, e); - valid ? this.classList.remove("error") : this.classList.add("error"); - }); - } - list.push(input); - - var span = document.createElement("span"); - span.className = "GPmousePositionUnits"; - list.push(span); - - return list; - }, - - /** - * - * @param {String} coordType - ("Lon" ou "Lat") - * @param {Boolean} [editCoordinates=false] - specifies if the coordinates edition is allowed - * - * @returns {Array} list of DOM elements - */ - _createDMSCoordinateElement : function (coordType, editCoordinates) { - if (["Lon", "Lat"].indexOf(coordType) === -1) { - return []; - } - - var context = this; - - var list = []; - - var input = document.createElement("input"); - input.id = this._addUID("GPmousePosition" + coordType + "Degrees"); - input.className = "GPSexagesimal"; - input.setAttribute("name", "degrees"); - input.title = editCoordinates === true ? "Cliquer pour saisir des coordonnées" : ""; - input.readOnly = true; - input.dataset.min = 0; - input.dataset.max = (coordType === "Lon") ? 180 : 90; - if (editCoordinates) { - input.addEventListener("click", function () { - context.onMousePositionEditModeClick(true); - }); - input.addEventListener("change", function () { - this.classList.remove("error"); - var valid = context._checkDMSDegrees(coordType, this); - valid ? this.classList.remove("error") : this.classList.add("error"); - }); - } - list.push(input); - - var span = document.createElement("span"); - span.className = "GPmousePositionSexagesimalLabel"; - span.innerHTML = "°"; - list.push(span); - - var input1 = document.createElement("input"); - input1.id = this._addUID("GPmousePosition" + coordType + "Minutes"); - input1.className = "GPSexagesimal"; - input1.setAttribute("name", "minutes"); - input1.title = editCoordinates === true ? "Cliquer pour saisir des coordonnées" : ""; - input1.readOnly = true; - input1.dataset.min = 0; - input1.dataset.max = 59; - if (editCoordinates) { - input1.addEventListener("click", function () { - context.onMousePositionEditModeClick(true); - }); - input1.addEventListener("change", function () { - this.classList.remove("error"); - var valid = context._checkDMSElement(this); - valid ? this.classList.remove("error") : this.classList.add("error"); - }); - } - list.push(input1); - - var span1 = document.createElement("span"); - span1.className = "GPmousePositionSexagesimalLabel"; - span1.innerHTML = "'"; - list.push(span1); - - var input2 = document.createElement("input"); - input2.id = this._addUID("GPmousePosition" + coordType + "Seconds"); - input2.className = "GPSexagesimalsec"; - input2.setAttribute("name", "seconds"); - input2.title = editCoordinates === true ? "Cliquer pour saisir des coordonnées" : ""; - input2.readOnly = true; - input2.dataset.min = 0; - input2.dataset.max = 59; - if (editCoordinates) { - input2.addEventListener("click", function () { - context.onMousePositionEditModeClick(true); - }); - input2.addEventListener("change", function () { - this.classList.remove("error"); - var valid = context._checkDMSElement(this, true); - valid ? this.classList.remove("error") : this.classList.add("error"); - }); - } - list.push(input2); - - var span2 = document.createElement("span"); - span2.className = "GPmousePositionSexagesimalLabel"; - span2.innerHTML = "''"; - list.push(span2); - - var select = document.createElement("select"); - select.id = this._addUID("GPmousePosition" + coordType + "Direction"); - select.className = "GPmousePositionDirection"; - select.setAttribute("name", "direction"); - select.disabled = true; - - var option = document.createElement("option"); - option.value = (coordType === "Lon") ? "E" : "N"; - option.innerHTML = (coordType === "Lon") ? "E" : "N"; - select.appendChild(option); - - var option1 = document.createElement("option"); - option1.value = (coordType === "Lon") ? "O" : "S"; - option1.innerHTML = (coordType === "Lon") ? "O" : "S"; - select.appendChild(option1); - list.push(select); - - return list; - }, - - /** - * @param {Boolean} [display=false] - specifies if the coordinates panel must be displayed - * @param {Boolean} [editCoordinates] - specifies if the coordinates edition is allowed - * @param {Boolean} [currentProjectionUnits] - specifies if the current projection units - * - * @returns {DOMElement} container - */ - _createMousePositionPanelBasicCoordinateElement : function (display, editCoordinates, currentProjectionUnits) { - var div = document.createElement("div"); - div.id = this._addUID("GPmousePositionCoordinate"); - div.style.display = display ? "block" : "none"; - - // latitude - var divLat = document.createElement("div"); - divLat.classList.add("fr-mb-1w"); - - var spanLat = document.createElement("span"); - spanLat.className = "GPmousePositionLabel"; - spanLat.id = this._addUID("GPmousePositionLatLabel"); - spanLat.innerHTML = "Latitude : "; - divLat.appendChild(spanLat); - - var span = document.createElement("span"); - span.id = this._addUID("GPmousePositionLatCoordinate"); - - var arrayCoords; - if (currentProjectionUnits === "DMS") { - arrayCoords = this._createDMSCoordinateElement("Lat", editCoordinates); - } else { - arrayCoords = this._createCoordinateElement("Lat", editCoordinates); - } - for (var i = 0; i < arrayCoords.length; i++) { - span.appendChild(arrayCoords[i]); - } - divLat.appendChild(span); - div.appendChild(divLat); - - // longitude - var divLon = document.createElement("div"); - divLon.classList.add("fr-mb-1w"); - - var spanLon = document.createElement("span"); - spanLon.className = "GPmousePositionLabel"; - spanLon.id = this._addUID("GPmousePositionLonLabel"); - spanLon.innerHTML = "Longitude : "; - divLon.appendChild(spanLon); - - var span1 = document.createElement("span"); - span1.id = this._addUID("GPmousePositionLonCoordinate"); - - var arrayCoords1; - if (currentProjectionUnits === "DMS") { - arrayCoords1 = this._createDMSCoordinateElement("Lon", editCoordinates); - } else { - arrayCoords1 = this._createCoordinateElement("Lon", editCoordinates); - } - for (var j = 0; j < arrayCoords1.length; j++) { - span1.appendChild(arrayCoords1[j]); - } - divLon.appendChild(span1); - div.appendChild(divLon); - - return div; - }, - - /** - * @param {Boolean} [display=false] - specifies if the altitude panel must be displayed - * - * @returns {DOMElement} container - */ - _createMousePositionPanelBasicAltitudeElement : function (display) { - var div = document.createElement("div"); - div.id = this._addUID("GPmousePositionAltitude"); - div.classList.add("fr-mb-1w"); - div.style.display = display ? "block" : "none"; - - var spanLabel = document.createElement("span"); - spanLabel.className = "GPmousePositionLabel"; - spanLabel.innerHTML = "Altitude : "; - div.appendChild(spanLabel); - - var spanAlt = document.createElement("span"); - spanAlt.className = "GPmousePositionCoords"; - spanAlt.id = this._addUID("GPmousePositionAlt"); - spanAlt.innerHTML = "..."; - div.appendChild(spanAlt); - - var spanUnits = document.createElement("span"); - spanUnits.className = "GPmousePositionAltitudeUnits"; - spanUnits.innerHTML = "m"; - div.appendChild(spanUnits); - - return div; - }, - - /** - * @param {Boolean} [editCoordinates=false] - specifies if the coordinates edition is allowed - * - * @returns {DOMElement} container - */ - _createMousePositionPanelEditToolsElement : function (editCoordinates) { - var context = this; - - var div = document.createElement("div"); - div.className = "GPmousePositionPanelEditTools"; - div.id = this._addUID("GPmousePositionPanelEditTools"); - if (!editCoordinates) { - div.style.display = "none"; - } - - var span1 = document.createElement("span"); - span1.className = "GPmousePositionEditTool"; - span1.id = this._addUID("GPmousePositionLocate"); - span1.title = editCoordinates === true ? "Cliquer pour saisir des coordonnées" : ""; - if (editCoordinates) { - span1.addEventListener("click", function () { - context.onMousePositionEditModeLocateClick(); - }); - } - div.appendChild(span1); - - var span2 = document.createElement("span"); - span2.className = "GPmousePositionEditTool"; - span2.id = this._addUID("GPmousePositionCloseEdit"); - span2.title = "Quitter la saisie des coordonnées"; - span2.style.display = "none"; - if (editCoordinates) { - span2.addEventListener("click", function () { - context.onMousePositionEditModeClick(false); - }); - } - div.appendChild(span2); - - return div; - }, - - // ################################################################### // - // #################### Settings container ########################### // - // ################################################################### // - - /** - * @param {Boolean} [display=false] - specifies if the settings panel must be displayed - * - * @returns {DOMElement[]} array containing input and label elements - */ - _createShowMousePositionSettingsElement : function (display) { - // contexte d'execution - var self = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowMousePositionSettings"); - - button.className = "GPshowAdvancedToolPicto GPshowMoreOptionsImage GPshowMoreOptions GPshowMousePositionSettingsPicto gpf-btn fr-btn--sm fr-btn--secondary fr-icon-arrow-down-fill"; - button.title = "Réglages"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // Close all results and panels when minimizing the widget - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onShowMousePositionSettingsClick(e); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onShowMousePositionSettingsClick(e); - }); - } - - return button; - }, - - /** - * settings panel - * @param {Boolean} [display=true] - specifies if the settings panel must be displayed - * - * FIXME - * don't call this._createMousePositionSettingsSystemsElement - * don't call this._createMousePositionSettingsUnitsElement - * - * @returns {DOMElement} DOM element - */ - _createMousePositionSettingsElement : function (display) { - var container = document.createElement("div"); - container.id = this._addUID("GPmousePositionSettings"); - container.style.display = (display === undefined || display) ? "block" : "none"; - container.classList.add("fr-m-1w"); - - var span = document.createElement("span"); - span.className = "GPmousePositionSettingsLabel"; - span.innerHTML = "Système de référence"; - container.appendChild(span); - - return container; - }, - - /** - * @param {Object[]} systems - list of systems - * - * @returns {DOMElement} DOM element select - */ - _createMousePositionSettingsSystemsElement : function (systems) { - // contexte d'execution - var context = this; - - var selectSystem = document.createElement("select"); - selectSystem.id = this._addUID("GPmousePositionProjectionSystem"); - selectSystem.className = "GPselect GPmousePositionSettingsSelect gpf-select fr-select fr-my-1w"; - selectSystem.addEventListener("change", function (e) { - context.onMousePositionProjectionSystemChange(e); - }); - selectSystem.addEventListener("mouseover", function (e) { - // FIXME mettre une condition si target === option - if (e.target.nodeName !== "OPTION") { - context.onMousePositionProjectionSystemMouseOver(e); - } - }); - - for (var i = 0; i < systems.length; i++) { - var obj = systems[i]; - var option = document.createElement("option"); - option.value = obj.code; - option.text = obj.label || i; - // option.label = obj.label; - selectSystem.appendChild(option); - } - - return selectSystem; - }, - - /** - * @param {Object[]} units - list of units - * - * @returns {DOMElement} DOM element select - */ - _createMousePositionSettingsUnitsElement : function (units) { - // contexte d'execution - var context = this; - - var selectUnits = document.createElement("select"); - selectUnits.id = this._addUID("GPmousePositionProjectionUnits"); - selectUnits.className = "GPselect GPmousePositionSettingsSelect gpf-select fr-select"; - selectUnits.addEventListener("change", function (e) { - context.onMousePositionProjectionUnitsChange(e); - }); - - for (var j = 0; j < units.length; j++) { - var obj = units[j]; - var option = document.createElement("option"); - option.value = (obj.code) ? obj.code : j; - option.text = obj.label || j; - // option.label = obj.label; - selectUnits.appendChild(option); - } - - return selectUnits; - }, - - /** - * @param {String} [currentProjectionType="Metric"] - "Geographical" or "Metric" - */ - _resetLabelElements : function (currentProjectionType) { - // Changement des labels dans le formulaire de saisie - var spanLat = document.getElementById(this._addUID("GPmousePositionLatLabel")); - spanLat.innerHTML = currentProjectionType === "Geographical" ? "Latitude :" : "X :"; - - var spanLon = document.getElementById(this._addUID("GPmousePositionLonLabel")); - spanLon.innerHTML = currentProjectionType === "Geographical" ? "Longitude :" : "Y :"; - }, - - /** - * @param {String} currentProjectionUnits - projection units - */ - _resetUnitElements : function (currentProjectionUnits) { - var value = ""; - if (currentProjectionUnits === "M" || currentProjectionUnits === "KM") { - value = currentProjectionUnits.toLowerCase(); - } - - var elts = document.getElementsByClassName("GPmousePositionUnits"); - for (var e = 0; e < elts.length; e++) { - elts[e].innerHTML = value; - } - }, - - /** - * @param {Boolean} editCoordinates - edit coordinates option - * @param {String} currentProjectionType - current projection type - * @param {String} currentProjectionUnits - current projection unit - */ - _resetCoordinateElements : function (editCoordinates, currentProjectionType, currentProjectionUnits) { - // Suppression de tous les enfants de GPmousePositionLatCoordinate - var latElt = document.getElementById(this._addUID("GPmousePositionLatCoordinate")); - while (latElt.firstChild) { - latElt.removeChild(latElt.firstChild); - } - - var arrayCoords; - if (currentProjectionUnits === "DMS") { - arrayCoords = this._createDMSCoordinateElement("Lat", editCoordinates); - } else { - arrayCoords = this._createCoordinateElement("Lat", editCoordinates); - } - for (var i = 0; i < arrayCoords.length; i++) { - latElt.appendChild(arrayCoords[i]); - } - - // Suppression de tous les enfants de GPmousePositionLonCoordinate - var lonElt = document.getElementById(this._addUID("GPmousePositionLonCoordinate")); - while (lonElt.firstChild) { - lonElt.removeChild(lonElt.firstChild); - } - - var arrayCoords1; - if (currentProjectionUnits === "DMS") { - arrayCoords1 = this._createDMSCoordinateElement("Lon", editCoordinates); - } else { - arrayCoords1 = this._createCoordinateElement("Lon", editCoordinates); - } - for (var j = 0; j < arrayCoords1.length; j++) { - lonElt.appendChild(arrayCoords1[j]); - } - - // FIXME on simule un deplacement ? - // this.onMapMove(); - }, - - /** - * Set/unset editing mode - * - * @param {Boolean} editing - active edit coordinates mode - */ - _setEditMode : function (editing) { - var locateElt = document.getElementById(this._addUID("GPmousePositionLocate")); - locateElt.title = editing ? "Aller à la position ..." : "Cliquer pour saisir des coordonnées"; - - var closeEditElt = document.getElementById(this._addUID("GPmousePositionCloseEdit")); - closeEditElt.style.display = editing ? "inline-block" : "none"; - - var selector = "div[id^=" + this._addUID("GPmousePositionCoordinate") + "]"; - var inputs = document.querySelectorAll(selector + " input"); - for (var i = 0; i < inputs.length; i++) { - inputs[i].readOnly = !editing; - if (editing) { - inputs[i].value = ""; - inputs[i].classList.remove("error"); - } - } - var selects = document.querySelectorAll(selector + " select"); - for (var j = 0; j < selects.length; j++) { - selects[j].disabled = !editing; - } - }, - - /** - * - * @param {DOMElement} input - input element - * @param {Boolean} isFloat - check for float value - * - * @returns {Boolean} true if input value is within bounds - */ - _checkDMSElement : function (input, isFloat) { - var b = isFloat !== undefined; - - var value = input.value; - if (b) { - value = value.replace(",", "."); - } - if (isNaN(value)) { - return false; - } - - var v = parseFloat(value); - if (!b && (v | 0) !== v) { // is it an integer - return false; - } - - var min = Number(input.dataset.min); - var max = Number(input.dataset.max); - return (v >= min && v <= max); - }, - - /** - * @param {String} coordType - "Lon" or "Lat" - * @param {DOMElement} input - input element - * - * @returns {Boolean} true if input value is within bounds - */ - _checkDMSDegrees : function (coordType, input) { - if (isNaN(input.value)) { - return false; - } - - var v = parseFloat(input.value); - if ((v | 0) !== v) { // is it an integer - return false; - } - - var min = Number(input.dataset.min); - var max = Number(input.dataset.max); - if (v < min || v > max) { - return false; - } - - var inputMinutes = document.getElementById(this._addUID("GPmousePosition" + coordType + "Minutes")); - var inputSeconds = document.getElementById(this._addUID("GPmousePosition" + coordType + "Seconds")); - - if (v >= max) { - inputMinutes.dataset.max = 0; - inputSeconds.dataset.max = 0; - } else { - inputMinutes.dataset.max = 59; - inputSeconds.dataset.max = 59.9999; - } - - return true; - }, - - // ################################################################### // - // ####################### handlers Event ############################ // - // ################################################################### // - - /** - * Function displaying coordinates from cursor position (desktop) - * or map center (tactile) - * @param {Object} coordinate - coordinates - */ - GPdisplayCoords : function (coordinate) { - // Compute coords in case of cursor position (desktop) - if (coordinate) { - var labelLon = document.getElementById(this._addUID("GPmousePositionLonLabel")); - var labelLat = document.getElementById(this._addUID("GPmousePositionLatLabel")); - - if (coordinate.x || coordinate.y) { - labelLat.innerHTML = "X : "; - labelLon.innerHTML = "Y : "; - } else if (coordinate.e || coordinate.n) { - labelLat.innerHTML = "E : "; - labelLon.innerHTML = "N : "; - } else { - labelLat.innerHTML = "Latitude : "; - labelLon.innerHTML = "Longitude : "; - } - - if (typeof coordinate.lat === "object" && typeof coordinate.lng === "object") { - var parts = { - lng : "Lon", - lat : "Lat" - }; - var units = ["Degrees", "Minutes", "Seconds"]; - for (var p in parts) { - for (var u = 0; u < units.length; ++u) { - var selector = "GPmousePosition" + parts[p] + units[u]; - var elt = document.getElementById(this._addUID(selector)); - var key = units[u].charAt(0).toLowerCase(); - elt.value = coordinate[p][key]; - } - } - // directions - document.getElementById(this._addUID("GPmousePositionLonDirection")).value = coordinate.lng.direction; - document.getElementById(this._addUID("GPmousePositionLatDirection")).value = coordinate.lat.direction; - } else { - var elLat = document.getElementById(this._addUID("GPmousePositionLat")); - var elLon = document.getElementById(this._addUID("GPmousePositionLon")); - - elLat.value = coordinate.x || coordinate.lat || coordinate.e || "0"; - elLon.value = coordinate.y || coordinate.lng || coordinate.lon || coordinate.n || "0"; - - // les unites - var unit = (coordinate.unit === undefined) ? "" : coordinate.unit; - var elements = document.getElementsByClassName("GPmousePositionUnits"); - for (var n = 0; n < elements.length; ++n) { - elements[n].innerHTML = unit; - } - } - } - }, - - /** - * Function displaying altitude from cursor position (desktop) - * or map center (tactile) - * @param {Object} coordinate - coordinates - * @param {Number} altitudeTimeoutDelay - when the mouse stop moving, delay before the altitude request is launched - * @param {Number} noDataValue - the no data value - * @param {Number} noDataValueTolerance - the no data value tolerance - */ - GPdisplayElevation : function (coordinate, altitudeTimeoutDelay, noDataValue, noDataValueTolerance) { - // contexte d'execution - var self = this; - - // Latency for altitude request - var altitudeTimeout; - if (!altitudeTimeoutDelay) { - altitudeTimeoutDelay = 500; - } - - clearTimeout(altitudeTimeout); - document.getElementById(this._addUID("GPmousePositionAlt")).innerHTML = "..."; - - if (noDataValue == null) { - noDataValue = -99999; - } - if (noDataValueTolerance == null) { - noDataValueTolerance = 99980; - } - var maxThreshold = noDataValue + noDataValueTolerance; - var minThreshold = noDataValue - noDataValueTolerance; - - // Compute coords in case of cursor position (desktop) - if (coordinate) { - // If no altitude panel, don't call altitude request - if (document.getElementById(this._addUID("GPmousePositionAltitude"))) { - altitudeTimeout = setTimeout(function () { - self.onRequestAltitude(coordinate, function (z) { - if (minThreshold < z && z < maxThreshold) { - self.GPresetElevation(); - } else { - document.getElementById(self._addUID("GPmousePositionAlt")).innerHTML = z; - } - }); - }, altitudeTimeoutDelay); - } - } - }, - - /** - * Function reseting altitude value - */ - GPresetElevation : function () { - if (document.getElementById(this._addUID("GPmousePositionAltitude"))) { - document.getElementById(this._addUID("GPmousePositionAlt")).innerHTML = "---"; - } - } -}; - -export default MousePositionDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocode.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocode.d.ts deleted file mode 100644 index 6e97639f6..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocode.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -export default ReverseGeocode; -/** - * @classdesc - * - * ReverseGeocode Control. - * - * @constructor - * @alias ol.control.ReverseGeocode - * @type {ol.control.ReverseGeocode} - * @extends {ol.control.Control} - * @param {Object} options - ReverseGeocode control options - * @param {String} [options.apiKey] - API key for services call (reverse geocode service). The key "calcul" is used by default. - * @param {String} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean} [options.collapsed = true] - Specify if widget has to be collapsed (true) or not (false) on map loading. Default is true. - * @param {Boolean} [options.draggable = false] - Specify if widget is draggable - * @param {Object} [options.resources = ["StreetAddress", "PositionOfInterest", "CadastralParcel"]] - resources for geocoding, by default : ["StreetAddress", "PositionOfInterest", "CadastralParcel"]. Possible values are : "StreetAddress", "PositionOfInterest", "CadastralParcel". Resources will be displayed in the same order in widget list. - * @param {Object} [options.delimitations = ["Point", "Circle", "Extent"]] - delimitations for reverse geocoding, by default : ["Point", "Circle", "Extent"]. Possible values are : "Point", "Circle", "Extent". Delimitations will be displayed in the same order in widget list. - * @param {Object} [options.reverseGeocodeOptions = {}] - reverse geocode service options. see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~reverseGeocode Gp.Services.reverseGeocode()} to know all reverse geocode options. - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Saisie (recherche inverse)"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Couche de saisie d'une zone de recherche pour la recherche inverse"] - Layer description to be displayed in LayerSwitcher - * @fires reversegeocode:compute - * @fires reversegeocode:onclickresult - * @example - * var iso = ol.control.ReverseGeocode({ - * "collapsed" : false, - * "draggable" : true, - * "resources" : ["StreetAddress", "PositionOfInterest"], - * "delimitations" : ["Point", "Circle"], - * "reverseGeocodeOptions" : {} - * }); - */ -declare var ReverseGeocode: ol.control.ReverseGeocode; -//# sourceMappingURL=ReverseGeocode.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocode.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocode.d.ts.map deleted file mode 100644 index ad30d19be..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocode.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ReverseGeocode.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/ReverseGeocode/ReverseGeocode.js"],"names":[],"mappings":";AA4CA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,sDAuqDE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocode.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocode.js deleted file mode 100644 index 94ac8a34a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocode.js +++ /dev/null @@ -1,1789 +0,0 @@ -// import CSS -import "../../CSS/Controls/ReverseGeocoding/GPFreverseGeocoding.css"; -// import "../../CSS/Controls/ReverseGeocoding/GPFreverseGeocodingStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -import Overlay from "ol/Overlay"; -import Collection from "ol/Collection"; -import Feature from "ol/Feature"; -import { - Fill, - Icon, - Stroke, - Style, - Circle -} from "ol/style"; -import { - Point, - Polygon -} from "ol/geom"; -import { - Select as SelectInteraction, - Draw as DrawInteraction -} from "ol/interaction"; -import { pointerMove as eventPointerMove } from "ol/events/condition"; -import { transform as olTransformProj } from "ol/proj"; -import VectorLayer from "ol/layer/Vector"; -import VectorSource from "ol/source/Vector"; -// import geoportal library access -import Gp from "geoportal-access-lib"; -// import local -import Utils from "../../Utils/Helper"; -import Logger from "../../Utils/LoggerByDefault"; -import SelectorID from "../../Utils/SelectorID"; -import Markers from "../Utils/Markers"; -import Draggable from "../../Utils/Draggable"; -import Interactions from "../Utils/Interactions"; -// import local with ol dependencies -import LayerSwitcher from "../LayerSwitcher/LayerSwitcher"; -// DOM -import ReverseGeocodeDOM from "./ReverseGeocodeDOM"; - -var logger = Logger.getLogger("reversegeocoding"); - -/** - * @classdesc - * - * ReverseGeocode Control. - * - * @constructor - * @alias ol.control.ReverseGeocode - * @type {ol.control.ReverseGeocode} - * @extends {ol.control.Control} - * @param {Object} options - ReverseGeocode control options - * @param {String} [options.apiKey] - API key for services call (reverse geocode service). The key "calcul" is used by default. - * @param {String} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean} [options.collapsed = true] - Specify if widget has to be collapsed (true) or not (false) on map loading. Default is true. - * @param {Boolean} [options.draggable = false] - Specify if widget is draggable - * @param {Object} [options.resources = ["StreetAddress", "PositionOfInterest", "CadastralParcel"]] - resources for geocoding, by default : ["StreetAddress", "PositionOfInterest", "CadastralParcel"]. Possible values are : "StreetAddress", "PositionOfInterest", "CadastralParcel". Resources will be displayed in the same order in widget list. - * @param {Object} [options.delimitations = ["Point", "Circle", "Extent"]] - delimitations for reverse geocoding, by default : ["Point", "Circle", "Extent"]. Possible values are : "Point", "Circle", "Extent". Delimitations will be displayed in the same order in widget list. - * @param {Object} [options.reverseGeocodeOptions = {}] - reverse geocode service options. see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~reverseGeocode Gp.Services.reverseGeocode()} to know all reverse geocode options. - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Saisie (recherche inverse)"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Couche de saisie d'une zone de recherche pour la recherche inverse"] - Layer description to be displayed in LayerSwitcher - * @fires reversegeocode:compute - * @fires reversegeocode:onclickresult - * @example - * var iso = ol.control.ReverseGeocode({ - * "collapsed" : false, - * "draggable" : true, - * "resources" : ["StreetAddress", "PositionOfInterest"], - * "delimitations" : ["Point", "Circle"], - * "reverseGeocodeOptions" : {} - * }); - */ -var ReverseGeocode = class ReverseGeocode extends Control { - - /** - * See {@link ol.control.ReverseGeocode} - * @module ReverseGeocode - * @alias module:~Controls/ReverseGeocode - * @param {*} options - options - * @example - * import ReverseGeocode from "src/OpenLayers/Controls/ReverseGeocode" - */ - constructor (options) { - options = options || {}; - - // call ol.control.Control constructor - super({ - element : options.element, - target : options.target, - render : options.render - }); - - if (!(this instanceof ReverseGeocode)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - // initialisation du composant - this.initialize(options); - - // Widget main DOM container - this.container = this._initContainer(); - - // ajout du container - (this.element) ? this.element.appendChild(this.container) : this.element = this.container; - - return this; - } - - // ################################################################### // - // ############## public methods (getters, setters) ################## // - // ################################################################### // - - /** - * Returns true if widget is collapsed (minimized), false otherwise - * - * @returns {Boolean} collapsed - true if widget is collapsed - */ - getCollapsed () { - return this.collapsed; - } - - /** - * Collapse or display widget main container - * - * @param {Boolean} collapsed - True to collapse widget, False to display it - */ - setCollapsed (collapsed) { - if (collapsed === undefined) { - logger.log("[ERROR] ReverseGeocode:setCollapsed - missing collapsed parameter"); - return; - } - if ((collapsed && this.collapsed) || (!collapsed && !this.collapsed)) { - return; - } - if (collapsed) { - this._panelCloseButton.click(); - } else { - this._showReverseGeocodingButton.click(); - } - this.collapsed = collapsed; - } - - /** - * Overwrite OpenLayers setMap method - * - * @param {ol.Map} map - Map. - */ - setMap (map) { - if (map) { - // lors de l'ajout à la map, on active la saisie du point ou de la zone de recherche sur la carte, - // mais seulement si le widget est ouvert - this._activateMapInteraction(map); - - // mode "draggable" - if (this.draggable) { - Draggable.dragElement( - this._panelContainer, - this._panelHeaderContainer, - this.options.position ? null : map.getTargetElement() - ); - } - // mode "collapsed" - if (!this.collapsed) { - // this._showReverseGeocodingButton.click(); - this._showReverseGeocodingButton.setAttribute("aria-pressed", true); - } - } else { - var _map = this.getMap(); - // on remet à zéro = on efface les géométries + interactions + valeurs stockées - // suppression des résultats précédents - this._clearResults(); - // on efface les points qui ont pu être saisis précédemment - this._clearInputFeatures(); - // on supprime l'éventuelle précédente interaction - this._removeMapInteraction(_map); - // on retire aussi la couche de saisie de la zone de recherche à la fermeture du widget - if (this._inputFeaturesLayer != null) { - _map.removeLayer(this._inputFeaturesLayer); - this._inputFeaturesLayer = null; - this._inputFeaturesSources = null; - this._inputFeatures = null; - } - } - - // on appelle la méthode setMap originale d'OpenLayers - super.setMap(map); - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - } - - /** - * Get locations data - * - * @returns {Object} data - locations - */ - getData () { - return this._reverseGeocodingLocations; - } - - // ################################################################### // - // ##################### init component ############################## // - // ################################################################### // - - /** - * Initialize ReverseGeocode control (called by ReverseGeocode constructor) - * - * @param {Object} options - constructor options - * @private - */ - initialize (options) { - // ############################################################ // - // ################### Options du composant ################### // - - // check input options format (resources and delimitations arrays) - this._checkInputOptions(options); - - // set default options - this.options = { - collapsed : true, - draggable : false, - resources : ["StreetAddress", "PositionOfInterest", "CadastralParcel"], - delimitations : ["Point", "Circle", "Extent"], - reverseGeocodeOptions : {}, - layerDescription : { - title : "Saisie (recherche inverse)", - description : "Couche de saisie d'une zone de recherche pour la recherche inverse" - } - }; - - // merge with user options - Utils.assign(this.options, options); - - /** {Boolean} specify if reverseGeocoding control is collapsed (true) or not (false) */ - this.collapsed = this.options.collapsed; - - /** {Boolean} specify if reverseGeocoding control is draggable (true) or not (false) */ - this.draggable = this.options.draggable; - - // identifiant du contrôle : utile pour suffixer les identifiants CSS (pour gérer le cas où il y en a plusieurs dans la même page) - this._uid = SelectorID.generate(); - - // #################################################################### // - // ################### informations sur les droits #################### // - - // Type de géocodage sélectionné (StreetAddress, PositionOfInterest, ...) - this._currentGeocodingType = null; - this._initGeocodingType(); - - // Type de délimitation à utiliser pour la requête + pour sélection sur la containerDistance - this._currentGeocodingDelimitation = null; - this._initGeocodingDelimitation(); - - // ################################################################## // - // ################### Elements principaux du DOM ################### // - - // containers principaux - this._showReverseGeocodingButton = null; - // panel - this._panelContainer = null; - this._panelHeaderContainer = null; - this._panelTitleContainer = null; - this._returnPictoContainer = null; - this._panelCloseButton = null; - // form - this._formContainer = null; - // results - this._resultsContainer = null; - this._resultsListContainer = null; - // waiting - this._waitingContainer = null; - - // ###################################################################### // - // ################### informations des points saisis ################### // - - // collection des points saisis sur la carte - this._inputFeatures = null; - // source contenant les features ci-dessus - this._inputFeaturesSource = null; - // couche vectorielle dans laquelle seront saisis les points (features ci-dessus) - this._inputFeaturesLayer = null; - // interaction avec la carte (de type "Point", "Circle" ou "Polygon") - this._mapInteraction = null; - - // #################################################################### // - // ################### informations pour la requête ################### // - - // options pour la requête de géocodage inverse - this._requestOptions = null; - // geometrie de recherche du géocodage inverse qui sera envoyée dans la requête - this._requestGeom = null; - this._requestPosition = null; - // pour savoir si un calcul est en cours ou non - this._waiting = false; - // timer pour cacher la patience après un certain temps - this._timer = null; - - // #################################################################### // - // #################### informations des résultats #################### // - - this._reverseGeocodingLocations = []; - this._reverseGeocodingLocationsMarkers = []; - this._resultsDefaultStyle = new Style({ - image : new Icon({ - src : Markers["lightOrange"], - anchor : [0.5, 1] - }) - }); - this._resultsSelectedStyle = new Style({ - image : new Icon({ - src : Markers["red"], - anchor : [0.5, 1] - }) - }); - this._resultsHoverInteraction = null; - this._resultsSelectInteraction = null; - // container de la popup (affichage des infos au clic sur les markers) - this._popupContent = null; - this._popupDiv = this._initPopupDiv(); - this._popupOverlay = null; - } - - /** - * this method is called by this.initialize() - * and makes sure input options are correctly formated - * - * @param {Object} options - options - * - * @private - */ - _checkInputOptions (options) { - var i; - var j; - - // on vérifie le tableau des resources - if (options.resources) { - var resources = options.resources; - // on vérifie que la liste des ressources de geocodage est bien un tableau - if (Array.isArray(resources)) { - var resourcesList = ["StreetAddress", "PositionOfInterest", "CadastralParcel"]; - var wrongResourcesIndexes = []; - for (i = 0; i < resources.length; i++) { - if (resourcesList.indexOf(resources[i]) === -1) { - // si la resource n'est pas référencée, on stocke son index pour la retirer du tableau (après avoir terminé de parcourir le tableau) - wrongResourcesIndexes.push(i); - logger.log("[ReverseGeocode] options.resources : " + resources[i] + " is not a resource for reverse geocode"); - } - } - // on retire les ressoures non référencées qu'on a pu rencontrer - if (wrongResourcesIndexes.length !== 0) { - for (j = 0; j < wrongResourcesIndexes.length; j++) { - resources.splice(wrongResourcesIndexes[j], 1); - } - } - } else { - logger.log("[ReverseGeocode] 'options.resources' parameter should be an array"); - resources = null; - } - } - - // et le tableau des délimitations - if (options.delimitations) { - var delimitations = options.delimitations; - // on vérifie que la liste des delimitations est bien un tableau - if (Array.isArray(delimitations)) { - var delimitationsList = ["Circle", "Point", "Extent"]; - var wrongDelimitationsIndexes = []; - for (i = 0; i < delimitations.length; i++) { - if (delimitationsList.indexOf(delimitations[i]) === -1) { - // si la delimitations n'est pas référencée, on stocke son index pour la retirer du tableau (après avoir terminé de parcourir le tableau) - wrongDelimitationsIndexes.push(i); - logger.log("[ReverseGeocode] options.delimitations : " + delimitations[i] + " is not a delimitation for reverse geocode"); - } - } - // on retire les ressoures non référencées qu'on a pu rencontrer - if (wrongDelimitationsIndexes.length !== 0) { - for (j = 0; j < wrongDelimitationsIndexes.length; j++) { - delimitations.splice(wrongDelimitationsIndexes[j], 1); - } - } - } else { - logger.log("[ReverseGeocode] 'options.delimitations' parameter should be an array"); - delimitations = null; - } - } - } - - /** - * this method is called by this.initialize() and initialize geocoding type (=resource) - * ("StreetAddress", "PositionOfInterest", "CadastralParcel") - * - * @private - */ - _initGeocodingType () { - // Type de géocodage selectionné - this._currentGeocodingType = "StreetAddress"; // par defaut - - // par defaut - var resources = this.options.resources; - if (!resources || resources.length === 0) { - this.options.resources = ["StreetAddress", "PositionOfInterest", "CadastralParcel"]; - } - - // options utilisateur - if (Array.isArray(resources) && resources.length) { - // récupération du type par défaut - if (resources[0] === "StreetAddress" || resources[0] === "PositionOfInterest" || resources[0] === "CadastralParcel") { - this._currentGeocodingType = resources[0]; - } - } - - // si l'utilisateur a spécifié au moins une ressource dans le service, on surcharge les options du widget - var serviceOptions = this.options.reverseGeocodeOptions; - if (serviceOptions.filterOptions && Array.isArray(serviceOptions.filterOptions.type) && serviceOptions.filterOptions.type.length !== 0) { - this._currentGeocodingType = serviceOptions.filterOptions.type[0]; - } - } - - /** - * this method is called by this.initialize() and initialize geocoding delimitation - * ("Point", "Circle", "Extent") - * - * @private - */ - _initGeocodingDelimitation () { - // Type de délimitation selectionné - this._currentGeocodingDelimitation = "Point"; // par defaut - - // par defaut - var delimitations = this.options.delimitations; - if (!delimitations || delimitations.length === 0) { - this.options.delimitations = ["Point", "Circle", "Extent"]; - } - - // options utilisateur - if (Array.isArray(delimitations) && delimitations.length) { - var d = delimitations[0].toLowerCase(); - if (d === "point" || d === "circle" || d === "extent") { - this._currentGeocodingDelimitation = delimitations[0]; - } - } - } - - /** - * this method is called by this.initialize() and initialize popup div - * (to display results information on marker click) - * - * @return {Object} element - DOM element for popup - * @private - */ - _initPopupDiv () { - var context = this; - var element = document.createElement("div"); - element.className = "gp-feature-info-div"; - var closer = document.createElement("input"); - closer.type = "button"; - closer.className = "gp-styling-button closer"; - // on closer click : remove popup - closer.onclick = function () { - if (context._popupOverlay != null) { - context._popupOverlay.setPosition(undefined); - } - return false; - }; - this._popupContent = document.createElement("div"); - this._popupContent.className = "gp-features-content-div"; - element.appendChild(this._popupContent); - element.appendChild(closer); - - return element; - } - - /** - * Create control main container (DOM initialize) - * - * @returns {DOMElement} DOM element - * - * @private - */ - _initContainer () { - // create main container - var container = this._createMainContainerElement(); - - // create ReverseGeocode picto - var picto = this._showReverseGeocodingButton = this._createShowReverseGeocodingPictoElement(); - container.appendChild(picto); - - // panel - var reverseGeocodingPanel = this._panelContainer = this._createReverseGeocodingPanelElement(); - var reverseGeocodingPanelDiv = this._createReverseGeocodingPanelDivElement(); - reverseGeocodingPanel.appendChild(reverseGeocodingPanelDiv); - - // header - var panelHeader = this._panelHeaderContainer = this._createReverseGeocodingPanelHeaderElement(); - - // return picto (hidden at start) - var returnPicto = this._returnPictoContainer = this._createReverseGeocodingPanelReturnPictoElement(); - panelHeader.appendChild(returnPicto); - // pane title - var panelTitle = this._panelTitleContainer = this._createReverseGeocodingPanelTitleElement(); - panelHeader.appendChild(panelTitle); - // close picto - var closeDiv = this._panelCloseButton = this._createReverseGeocodingPanelCloseElement(); - panelHeader.appendChild(closeDiv); - reverseGeocodingPanelDiv.appendChild(panelHeader); - - // form - var reverseGeocodingForm = this._formContainer = this._createReverseGeocodingPanelFormElement(); - // choices element - reverseGeocodingForm.appendChild(this._createReverseGeocodingFormModeChoiceGeocodingTypeElement(this.options.resources)); - reverseGeocodingForm.appendChild(this._createReverseGeocodingFormModeChoiceGeocodingDelimitationElement(this.options.delimitations)); - - // submit (bouton "Chercher") - var submit = this._createReverseGeocodingSubmitFormElement(); - reverseGeocodingForm.appendChild(submit); - - reverseGeocodingPanelDiv.appendChild(reverseGeocodingForm); - - // waiting - var waiting = this._waitingContainer = this._createReverseGeocodingWaitingElement(); - reverseGeocodingPanelDiv.appendChild(waiting); - - // results (dans le panel) - var resultsPanel = this._resultsContainer = this._createReverseGeocodingResultsPanelElement(); - var reverseGeocodingResultsList = this._resultsListContainer = this._createReverseGeocodingResultsListElement(); - resultsPanel.appendChild(reverseGeocodingResultsList); - reverseGeocodingPanelDiv.appendChild(resultsPanel); - - container.appendChild(reverseGeocodingPanel); - - logger.log(container); - - return container; - } - - // ################################################################### // - // ################### Map interactions management ################### // - // ################################################################### // - - /** - * this method is called by this.setMap, - * or by this.onShowReverseGeocodingClick, - * and calls method corresponding to current delimitation, if widget is not collapsed. - * - * @param {ol.Map} map - control map. - * @private - */ - _activateMapInteraction (map) { - if (!this.collapsed) { - // 1. Creation de la couche vectorielle sur laquelle on va dessiner - if (this._inputFeaturesLayer == null) { - // on crée une collection, qui accueillera les points saisis sur la carte par les interactions, - // sous formes de features (dans une couche vectorielle). - // on les stocke de sorte à pouvoir les supprimer facilement - this._inputFeatures = new Collection(); - - // on crée la couche qui va accueillir les features - this._inputFeaturesSource = new VectorSource({ - features : this._inputFeatures - }); - this._inputFeaturesLayer = new VectorLayer({ - source : this._inputFeaturesSource, - style : new Style({ - fill : new Fill({ - color : "rgba(0, 183, 152, 0.3)" - }), - stroke : new Stroke({ - color : "rgba(0, 183, 152, 0.8)", - width : 3 - }), - image : new Icon({ - src : Markers["turquoiseBlue"], - anchor : [0.5, 1] - }) - }) - }); - // on rajoute le champ gpResultLayerId permettant d'identifier une couche crée par le composant. (pour layerSwitcher par ex) - this._inputFeaturesLayer.gpResultLayerId = "reverseGeocoding"; - // on ajoute la couche à la carte - map.addLayer(this._inputFeaturesLayer); - } - - // 2. Création de l'interaction de dessin, selon le type de délimitation sélectionné - var delimitation = this._currentGeocodingDelimitation.toLowerCase(); - switch (delimitation) { - case "point": - this._activatePointInteraction(map); - break; - case "circle": - this._activateCircleInteraction(map); - break; - case "extent": - this._activateBoxInteraction(map); - break; - default: - break; - } - - // 3. Si un layer switcher est présent dans la carte, on lui affecte des informations pour cette couche - map.getControls().forEach( - (control) => { - if (control instanceof LayerSwitcher) { - // un layer switcher est présent dans la carte - var layerId = this._inputFeaturesLayer.gpLayerId; - // on n'ajoute des informations que s'il n'y en a pas déjà (si le titre est le numéro par défaut) - if (control._layers[layerId].title === layerId) { - control.addLayer( - this._inputFeaturesLayer, { - title : this.options.layerDescription.title, - description : this.options.layerDescription.description - } - ); - control.setRemovable(this._inputFeaturesLayer, false); - } - } - } - ); - } - }; - - /** - * this method is called by this._activateMapInteraction, - * and creates map point drawing interaction. - * - * @param {ol.Map} map - control map. - * @private - */ - _activatePointInteraction (map) { - // interaction permettant de dessiner un point - this._mapInteraction = new DrawInteraction({ - style : new Style({ - image : new Circle({ - radius : 0, - fill : new Fill({ - color : "rgba(0, 183, 152, 0.8)" - }) - }) - }), - type : ("Point"), - source : this._inputFeaturesSource - }); - - this._mapInteraction.on( - "drawstart", - (e) => { - logger.log("on drawstart ", e); - - // on efface les points qui ont pu être saisis précédemment (on vide la collection des features de la couche) - this._inputFeatures.clear(); - - // on récupère les coordonnées du point qui vient d'être saisi - this._onDrawStart(e, "point"); - } - ); - - this._mapInteraction.on( - "drawend", - (e) => { - logger.log("on drawend", e); - - // on récupère le rayon du cercle qui vient d'être tracé - if (e.feature && e.feature.getGeometry) { - this._requestGeom = { - type : "Point", - coordinates : [ - this._requestPosition.lon, - this._requestPosition.lat - ] - }; - } - } - ); - - map.addInteraction(this._mapInteraction); - this._setCursor("crosshair", map); - } - - /** - * this method is called by this._activateMapInteraction, - * and creates map circle drawing interaction. - * - * @param {ol.Map} map - control map. - * @private - */ - _activateCircleInteraction (map) { - // interaction permettant de dessiner un cercle - this._mapInteraction = new DrawInteraction({ - style : new Style({ - fill : new Fill({ - color : "rgba(0, 183, 152, 0.3)" - }), - stroke : new Stroke({ - color : "rgba(0, 183, 152, 0.8)", - width : 3 - }), - image : new Circle({ - radius : 4, - fill : new Fill({ - color : "rgba(0, 183, 152, 0.8)" - }) - }) - }), - type : ("Circle"), - source : this._inputFeaturesSource - }); - - this._mapInteraction.on( - "drawstart", - (e) => { - logger.log("on drawstart ", e); - // on efface les points qui ont pu être saisis précédemment (on vide la collection des features de la couche) - this._inputFeatures.clear(); - // on récupère les coordonnées du centre du cercle = premier point du tracé - this._onDrawStart(e, "circle"); - } - ); - - this._mapInteraction.on( - "drawend", - (e) => { - logger.log("on drawend", e); - - // on récupère le rayon du cercle qui vient d'être tracé - if (e.feature && e.feature.getGeometry) { - var radius = e.feature.getGeometry().getRadius(); - // et on le stocke comme filtre pour la requête - this._requestGeom = {}; - this._requestGeom.type = "Circle"; - this._requestGeom.radius = radius; - if (this._requestPosition) { - this._requestGeom.coordinates = [ - this._requestPosition.lon, - this._requestPosition.lat - ]; - } - logger.log("circle radius : ", radius); - } - } - ); - - map.addInteraction(this._mapInteraction); - } - - /** - * this method is called by this._activateMapInteraction, - * and creates map box drawing interaction. - * - * @param {ol.Map} map - control map. - * @private - */ - _activateBoxInteraction (map) { - // info : il n'y a pas de geometry de type rectangle, donc on va créer un objet de type "LineString", - // avec seulement 2 points qui formeront les extrémités du rectangle. - // on aura donc une géométrie LineString avec 5 coordonnées : start, point2, end, point4, start, - // où les coordonnées de point2 et point4 sont calculées à partir de start et end, et start est répété à la fin pour fermer la géométrie. - - // function to draw rectangle with only 2 points - var geometryFunction = function (coordinates, geometry) { - if (!geometry) { - geometry = new Polygon([]); - } - var start = coordinates[0]; - var end = coordinates[1]; - // on crée les 5 coordonnées de la ligne à partir des 2 points saisis. - geometry.setCoordinates([ - [start, [start[0], end[1]], end, [end[0], start[1]], start] - ]); - return geometry; - }; - - // interaction permettant de dessiner un rectangle (= LineString de 5 points, à partir de 2 points saisis) - this._mapInteraction = new DrawInteraction({ - style : new Style({ - fill : new Fill({ - color : "rgba(0, 183, 152, 0.3)" - }), - stroke : new Stroke({ - color : "rgba(0, 183, 152, 0.8)", - width : 3 - }), - image : new Circle({ - radius : 4, - fill : new Fill({ - color : "rgba(0, 183, 152, 0.8)" - }) - }) - }), - type : ("LineString"), - source : this._inputFeaturesSource, - maxPoints : 2, - geometryFunction : geometryFunction - }); - - this._mapInteraction.on( - "drawstart", - (e) => { - logger.log("on drawstart", e); - // on efface les points qui ont pu être saisis précédemment (on vide la collection des features de la couche) - this._inputFeatures.clear(); - // on récupère les coordonnées du premier point du tracé - this._onDrawStart(e, "polygon"); - } - ); - - this._mapInteraction.on( - "drawend", - (e) => { - logger.log("on drawend", e); - // on va récupérer les coordonnées du rectangle qui vient d'être tracé - this._onBoxDrawEnd(e); - } - ); - - map.addInteraction(this._mapInteraction); - } - - /** - * remove draw interaction from map (if exists) - * - * @param {ol.Map} map - control map. - * @private - */ - _removeMapInteraction (map) { - if (this._mapInteraction != null) { - map.removeInteraction(this._mapInteraction); - this._mapInteraction = null; - } - this._setCursor(); - } - - /** - * this method is called by event 'drawstart' on map point or circle drawing interaction - * (cf. this._activatePointInteraction), and it gets map click coordinates. - * this point is saved as a parameter for reverse Geocode service. - * - * @param {Object} e - HTMLElement - * @param {String} type - geometry type : "point" or "circle" - * @private - */ - _onDrawStart (e, type) { - var coordinate; - if (e.feature && e.feature.getGeometry) { - var geometry = e.feature.getGeometry(); - if (type === "point") { - coordinate = geometry.getCoordinates(); - } - if (type === "circle") { - coordinate = geometry.getCenter(); - } - if (type === "polygon") { - coordinate = geometry.getFirstCoordinate(); - } - } - if (!coordinate) { - return; - } - - var crs; - if (this.options.reverseGeocodeOptions && this.options.reverseGeocodeOptions.srs) { - crs = this.options.reverseGeocodeOptions.srs; - } else { - var map = this.getMap(); - if (!map || !map.getView()) { - return; - } - crs = map.getView().getProjection(); - } - - var geoCoordinate = olTransformProj(coordinate, crs, "EPSG:4326"); - this._requestPosition = { - lon : geoCoordinate[0], - lat : geoCoordinate[1] - }; - logger.log("position coordinates : ", this._requestPosition); - } - - /** - * this method is called by event 'drawend' on map box drawing interaction - * (cf. this._activateBoxInteraction), and it gets geometry coordinates, - * to be saved as a filter parameter for reverse Geocode service. - * - * @param {Object} e - HTMLElement - * @private - */ - _onBoxDrawEnd (e) { - // on va récupérer les coordonnées du rectangle qui vient d'être tracé - if (e.feature && e.feature.getGeometry) { - // info: coordinates est un tableau [start, point2, end, point4, start] - // car c'est une linestring donc on a 5 coordonnées pour boucler - var coordinates = e.feature.getGeometry().getCoordinates()[0]; - var start = coordinates[0]; - var end = coordinates[2]; - - var crs; - if (this.options.reverseGeocodeOptions && this.options.reverseGeocodeOptions.srs) { - crs = this.options.reverseGeocodeOptions.srs; - } else { - var map = this.getMap(); - if (!map || !map.getView()) { - return; - } - crs = map.getView().getProjection(); - } - - // on reprojette les coordonnées des deux extrémités du rectangle (start et end) - var startGeoCoordinate = olTransformProj(start, crs, "EPSG:4326"); - var endGeoCoordinate = olTransformProj(end, crs, "EPSG:4326"); - - var bbox = {}; - // on récupère les valeurs left, right, top et bottom, pour le filtre bbox du service reverseGeocode - if (startGeoCoordinate[0] < endGeoCoordinate[0]) { - bbox.left = startGeoCoordinate[0]; - bbox.right = endGeoCoordinate[0]; - } else { - bbox.left = endGeoCoordinate[0]; - bbox.right = startGeoCoordinate[0]; - } - if (startGeoCoordinate[1] < endGeoCoordinate[1]) { - bbox.bottom = startGeoCoordinate[1]; - bbox.top = endGeoCoordinate[1]; - } else { - bbox.bottom = endGeoCoordinate[1]; - bbox.top = startGeoCoordinate[1]; - } - - this._requestGeom = { - type : "Polygon", - coordinates : [[ - [bbox.left, bbox.top], - [bbox.left, bbox.bottom], - [bbox.right, bbox.bottom], - [bbox.right, bbox.top], - [bbox.left, bbox.top] - ]] - }; - - logger.log("searchGeometry filter : ", this._requestGeom); - } - } - - /** - * this change the cursor of the map when entering a point. - * - * @param {String} cursor - cursor style - * @param {ol.Map} map - control map (optional) - * @private - */ - _setCursor (cursor, map) { - map = map || this.getMap(); - if (!map) { - return; - } - var div = map.getTargetElement(); - - if (cursor) { - div.style.cursor = cursor; - } else { - div.style.cursor = null; - } - } - - // ################################################################### // - // ##################### Reverse Geocoding request ################### // - // ################################################################### // - - /** - * this methode is called by this.onReverseGeocodingSubmit method, - * it generates and sends reverse geocode request, then displays results - * - * @private - */ - _reverseGeocodingRequest () { - var map = this.getMap(); - - // on construit les options pour la requête - this._requestOptions = this._getReverseGeocodingRequestOptions(); - - // retrait de l'interaction sur la map pendant l'attente (et l'affichage des résultats) - this._removeMapInteraction(map); - // affichage d'une patience pendant l'attente - this._displayWaitingContainer(); - - // envoi de la requête - Gp.Services.reverseGeocode(this._requestOptions); - } - - /** - * this methode is called by this._reverseGeocodingRequest method, - * and returns options object for Gp.Services.reverseGeocode request - * - * @returns {Object} requestOptions - reverse geocode options - * @private - */ - _getReverseGeocodingRequestOptions () { - var map = this.getMap(); - - // on recupere les éventuelles options du service passées par l'utilisateur - var reverseGeocodeOptions = this.options.reverseGeocodeOptions; - - // on crée les options pour le service reverseGeocode - var context = this; - if (typeof this.options.ssl !== "boolean") { - this.options.ssl = true; - } - // gestion des callback - var bOnFailure = !!(reverseGeocodeOptions.onFailure !== null && typeof reverseGeocodeOptions.onFailure === "function"); // cast variable to boolean - var bOnSuccess = !!(reverseGeocodeOptions.onSuccess !== null && typeof reverseGeocodeOptions.onSuccess === "function"); - - var requestOptions = { - apiKey : reverseGeocodeOptions.apiKey || this.options.apiKey, - ssl : this.options.ssl, - position : this._requestPosition, - filterOptions : { - type : [this._currentGeocodingType] - }, - srs : "CRS:84", - returnFreeForm : false, - maximumResponses : reverseGeocodeOptions.maximumResponses || 18, - timeOut : reverseGeocodeOptions.timeOut || 30000, - // protocol : reverseGeocodeOptions.protocol || "XHR", - // callback onSuccess - onSuccess : function (response) { - if (response.locations) { - logger.log("reverseGeocode results : ", response.locations); - context._displayGeocodedLocations(response.locations); - } - if (bOnSuccess) { - reverseGeocodeOptions.onSuccess.call(context, response.locations); - } - }, - // callback onFailure - onFailure : function (error) { - // FIXME mise à jour du controle mais le service ne repond pas en 200 !? - - // on cache la patience - context._hideWaitingContainer(); - - // suppression d'éventuels résultats précédents - context._clearResults(); - // on efface les points qui ont été saisis précédemment - context._clearInputFeatures(); - - // et on réactive l'interaction sur la map - context._activateMapInteraction(map); - logger.log(error.message); - - if (bOnFailure) { - reverseGeocodeOptions.onFailure.call(context, error); - } - } - }; - - // on récupère d'éventuels filtres - if (this._requestGeom.type.toLowerCase() === "circle") { - // FIXME : a confirmer en fonction du service ! - if (this._requestGeom.radius > 500) { - logger.log("INFO : initial circle radius (" + this._requestGeom.radius + ") limited to 1000m."); - this._requestGeom.radius = 500; - } - requestOptions.searchGeometry = this._requestGeom; - } else if (this._requestGeom.type.toLowerCase() === "polygon") { - requestOptions.searchGeometry = this._requestGeom; - } else if (this._requestGeom.type.toLowerCase() === "point") { - if (this._currentGeocodingType === "StreetAddress") { - requestOptions.searchGeometry = { - type : "Circle", - radius : 50, - coordinates : this._requestGeom.coordinates - }; - requestOptions.maximumResponses = 1; - } else { - requestOptions.searchGeometry = this._requestGeom; - } - } - - logger.log("reverseGeocode request options : ", requestOptions); - - return requestOptions; - } - - /** - * this method is called by this._reverseGeocodingRequest() (in case of reverse geocode success) - * and display results : in both container list and map - * - * @param {Array} locations - array of geocoded locations (reverse geocode results) - * @private - */ - _displayGeocodedLocations (locations) { - // 1. on vide les résultats précédents - this._clearResults(); - this._reverseGeocodingLocations = locations; - - /** - * event triggered when the compute is finished - * - * @event reversegeocode:compute - * @property {Object} type - event - * @property {Object} target - instance ReverseGeocode - * @example - * ReverseGeocode.on("reversegeocode:compute", function (e) { - * console.log(e.target.getData()); - * }) - */ - this.dispatchEvent({ - type : "reversegeocode:compute" - }); - - // 2. cache de la patience et du formulaire - this._formContainer.className = "GPelementHidden gpf-hidden"; - this._hideWaitingContainer(); - // affichage de la div des résultats (et changement du titre) - this._panelTitleContainer.innerHTML = "Résultats de la recherche"; - this._returnPictoContainer.classList.remove("GPelementHidden"); - this._returnPictoContainer.classList.remove("gpf-hidden"); - this._resultsContainer.className = "GPpanel gpf-panel gpf-panel-reverse"; - - // 3. ajout de la liste des résultats dans le container des resultats - this._fillGeocodedLocationListContainer(locations); - - // 4. affichage des résultats sur la carte (+ zoom ?) - this._displayGeocodedLocationsOnMap(locations); - } - - // ################################################################### // - // ############################# results list ######################## // - // ################################################################### // - - /** - * this method is called by this._displayGeocodedLocations() - * and fills the container with results list - * - * @param {Array} locations - array of geocoded locations (reverse geocode results) - * @private - */ - _fillGeocodedLocationListContainer (locations) { - // ajout de la liste des résultats dans le container des resultats - for (var i = 0; i < locations.length; i++) { - var location = locations[i]; - logger.log(location); - // on récupère la description à afficher dans la liste - var locationDescription = this._fillGeocodedLocationDescription(location); - // on ajoute chaque résutat à la liste - if (locationDescription.length !== 0) { - this._createReverseGeocodingResultElement(locationDescription, i); - } - } - } - - /** - * this method is called by this._fillGeocodedLocationListContainer() - * and fills location description (String), depending on matchType - * - * @param {Object} location - geocoded location (from reverse geocode results) - * @returns {String} locationDescription - geocoded location description to be displayed - * @private - */ - _fillGeocodedLocationDescription (location) { - if (!location || !location.placeAttributes) { - return; - } - var attr = location.placeAttributes; - - var locationDescription = ""; - // on sélectionne les infos à afficher selon le type - switch (location.type) { - case "StreetAddress": - if (attr.street) { - locationDescription += attr.housenumber ? attr.housenumber + " " : ""; - locationDescription += attr.street + ", "; - } - locationDescription += attr.postcode + " " + attr.city; - break; - - case "PositionOfInterest": - locationDescription += attr.toponym; - if (attr.postcode.length === 1) { - locationDescription += ", " + attr.postcode[0]; - } - locationDescription += " (" + attr.category.join(",") + ")"; - break; - - case "CadastralParcel": - locationDescription += attr.id; - locationDescription += attr.city ? " (" + attr.city + ")" : ""; - break; - - default: - locationDescription += attr.city ? attr.city : ""; - break; - }; - - return locationDescription; - } - - // ################################################################### // - // ######################## map results (markers) #################### // - // ################################################################### // - - /** - * this method is called by this._displayGeocodedLocations() - * and display locations in map (markers) - * - * @param {Object} locations - geocoded locations (reverse geocode result) - * @private - */ - _displayGeocodedLocationsOnMap (locations) { - if (this._reverseGeocodingLocations.length !== 0) { - var map = this.getMap(); - - // 1. création de la couche où seront ajoutés les résultats - this._createResultsLayer(); - // ajout de chaque résultat à la couche (marker) - for (var i = 0; i < locations.length; i++) { - this._addResultFeature(locations[i], i); - } - - // 2. Zoom sur l'étendue des résultats (features) - if (this._resultsFeatures.getLength() > 1) { - if (this._resultsFeaturesSource && this._resultsFeaturesSource.getExtent) { - var extent = this._resultsFeaturesSource.getExtent(); - map.getView().fit(extent, map.getSize()); - } - } else { - // dans le cas où on n'a qu'un seul résultat, l'étendue n'est pas définie, on zoome donc sur le résulat - var feature = this._resultsFeatures.item(0); - var coords = feature.getGeometry().getCoordinates(); - map.getView().setCenter(coords); - map.getView().setZoom(17); - } - - // 3. ajout des interactions (survol, click) - // au survol : modification des styles (marker et list) - this._resultsHoverInteraction = new SelectInteraction({ - condition : eventPointerMove, - layers : [this._resultsFeaturesLayer] - }); - this._resultsHoverInteraction.on( - "select", - (e) => this._onResultsFeatureMouseOver(e) - ); - map.addInteraction(this._resultsHoverInteraction); - - // au click : affichage popup - this._resultsSelectInteraction = new SelectInteraction({ - layers : [this._resultsFeaturesLayer] - }); - this._resultsSelectInteraction.on( - "select", - (e) => this._onResultsFeatureSelect(e) - ); - map.addInteraction(this._resultsSelectInteraction); - - // 4. Si un layer switcher est présent dans la carte, on lui affecte des informations pour cette couche - var geocodeType = ""; - switch (this._currentGeocodingType) { - case "StreetAddress": - geocodeType = "adresses"; - break; - case "PositionOfInterest": - geocodeType = "toponymes"; - break; - case "CadastralParcel": - geocodeType = "parcelles cadastrales"; - break; - default: - break; - } - map.getControls().forEach( - (control) => { - if (control instanceof LayerSwitcher) { - // un layer switcher est présent dans la carte - var layerId = this._resultsFeaturesLayer.gpLayerId; - // on n'ajoute des informations que s'il n'y en a pas déjà (si le titre est le numéro par défaut) - if (control._layers[layerId].title === layerId) { - control.addLayer( - this._resultsFeaturesLayer, { - title : "Résultats de la recherche inverse", - description : "Résultats de la recherche inverse sur les " + geocodeType - } - ); - control.setRemovable(this._resultsFeaturesLayer, false); - } - } - } - ); - } - } - - /** - * this method is called by this._displayGeocodedLocations() - * and creates result layer (where geocoded locations will be displayed) - * - * @private - */ - _createResultsLayer () { - var map = this.getMap(); - - this._resultsFeatures = new Collection(); - - // on crée la couche qui va accueillir les features - this._resultsFeaturesSource = new VectorSource({ - features : this._resultsFeatures - }); - this._resultsFeaturesLayer = new VectorLayer({ - source : this._resultsFeaturesSource - }); - // on rajoute le champ gpResultLayerId permettant d'identifier une couche crée par le composant. (pour layerSwitcher par ex) - this._resultsFeaturesLayer.gpResultLayerId = "reverseGeocodingResults"; - // on ajoute la couche à la carte - map.addLayer(this._resultsFeaturesLayer); - } - - /** - * this method is called by this._displayGeocodedLocations() - * and displays locations in map (markers) : add new feature to results layer - * - * @param {Object} location - geocoded location (reverse geocode result) - * @param {Number} i - geocoded location index in response list - * @private - */ - _addResultFeature (location, i) { - var map = this.getMap(); - // récupération de la position - var position = [location.position.lon, location.position.lat]; - if (position.length === 0) { - return; - } - var view = map.getView(); - var mapProj = view.getProjection().getCode(); - if (mapProj !== "EPSG:4326") { - // on retransforme les coordonnées de la position dans la projection de la carte - position = olTransformProj(position, "EPSG:4326", mapProj); - } - - // on ajoute le résultat à la collection de points existantes (composant la couche vectorielle this._inputFeaturesLayer) - var feature = new Feature({ - geometry : new Point(position) - }); - feature.setStyle(this._resultsDefaultStyle); - feature.setId(i); - feature.setProperties({ - location : location, - popupContent : this._fillPopupContent(location) - }); - this._resultsFeatures.push(feature); - } - - /** - * this method is called by this._addResultFeature() - * and fills popup content (to be displayed on marker click) for a given geocoded location - * - * @param {Object} location - geocoded location (reverse geocode result) - * @returns {String} popupContent - text to be displayed in popup - * @private - */ - _fillPopupContent (location) { - var popupContent = "
    "; - - var attributes = location.placeAttributes; - for (var attr in attributes) { - if (attributes.hasOwnProperty(attr)) { - if (attr !== "trueGeometry" && attr !== "extraFields" && attr !== "houseNumberInfos" && attr !== "_count") { - popupContent += "
  • "; - popupContent += "" + attr.toUpperCase() + " : "; - popupContent += attributes[attr]; - popupContent += "
  • "; - } - } - } - popupContent += "
"; - - return popupContent; - } - - /** - * this method is called on 'pointerMove' on this._resultsFeaturesLayer (ol.interaction.Select) - * (cf. this._displayGeocodedLocationsOnMap() ) - * and highlights result in list container - * - * @param {Object} e - on select event - * @private - */ - _onResultsFeatureMouseOver (e) { - var f; - - // si on survole un résultat, on change son style (marker) - if (e.selected.length !== 0) { - // on change le style du marker (red) - f = e.selected[0]; - f.setStyle(this._resultsSelectedStyle); - - // on surligne le résultat correspondant dans la liste des résultats - if (f.getId() != null) { - var selectedResultDiv = document.getElementById("GPreverseGeocodedLocation_" + f.getId() + "-" + this._uid); - if (selectedResultDiv && selectedResultDiv.classList) { - selectedResultDiv.classList.add("GPlocationHighlight"); - } - } - document.getElementById("GPreverseGeocodedLocation_" + f.getId() + "-" + this._uid); - } - - // si on déselectionne un résultat (mouseout), on rétablit un style normal pour le marker - if (e.deselected.length !== 0) { - // on change le style du marker (lightOrange) - f = e.deselected[0]; - f.setStyle(this._resultsDefaultStyle); - - // on rétablit un style normal pour le résultat correspondant dans la liste des résultats - var deSelectedResultDiv = document.getElementById("GPreverseGeocodedLocation_" + f.getId() + "-" + this._uid); - if (deSelectedResultDiv && deSelectedResultDiv.classList) { - deSelectedResultDiv.classList.remove("GPlocationHighlight"); - } - } - } - - /** - * this method is called on 'click' on this._resultsFeaturesLayer (ol.interaction.Select) - * (cf. this._displayGeocodedLocationsOnMap() ) - * and sets a popup with feature information - * - * @param {Object} e - on select event - * @private - */ - _onResultsFeatureSelect (e) { - var map = this.getMap(); - if (e.selected.length !== 0) { - // si on a sélectionné un marker, on lui ajoute une popup - var f = e.selected[0]; - this._popupContent.innerHTML = f.getProperties().popupContent; - - if (!this._popupOverlay) { - // ajout de la popup a la carte comme un overlay - this._popupOverlay = new Overlay({ - element : this._popupDiv, - positioning : "bottom-center", - position : e.mapBrowserEvent.coordinate - }); - map.addOverlay(this._popupOverlay); - } else { - // si l'overlay est déjà créé, on modifie juste sa position - this._popupOverlay.setPosition(e.mapBrowserEvent.coordinate); - } - - /** - * event triggered when an element of the results is clicked - * - * @event reversegeocode:onclickresult - * @property {Object} type - event - * @property {Object} location - location - * @property {Object} target - instance ReverseGeocode - * @example - * Reverse.on("reverse:onclickresult", function (e) { - * console.log(e.location); - * }) - */ - this.dispatchEvent({ - type : "reversegeocode:onclickresult", - location : f.getProperties().location - }); - } else { - // si aucun troncon n'est sélectionné (click à côté du tracé), - // on fait disparaitre la popup si elle existe - if (this._popupOverlay != null) { - this._popupOverlay.setPosition(undefined); - } - } - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - - /** - * this method is called by event 'click' on 'GPshowReverseGeocodingPicto' tag label - * (cf. ReverseGeocodeDOM._createShowReverseGeocodingPictoElement), and it cleans the component - * when it's closed. - * - * @private - */ - onShowReverseGeocodingClick () { - var map = this.getMap(); - if (!map) { - return; - } - // on supprime toutes les interactions - Interactions.unset(map); - var opened = this._showReverseGeocodingButton.ariaPressed; - this.collapsed = !(opened === "true"); - // info : on génère nous même l'evenement OpenLayers de changement de propriété - // (utiliser ol.control.ReverseGeocode.on("change:collapsed", function ) pour s'abonner à cet évènement) - this.dispatchEvent("change:collapsed"); - - if (!this._waiting && !this._reverseGeocodingLocations.length) { - // Cas 1 : input panel (ni en attente, ni sur le panel des résultats) - if (this.collapsed) { - // on remet à zéro = on efface les géométries + interactions + valeurs stockées - // suppression des résultats précédents - this._clearResults(); - // on efface les points qui ont pu être saisis précédemment - this._clearInputFeatures(); - // on supprime l'éventuelle précédente interaction - this._removeMapInteraction(map); - // on retire aussi la couche de saisie de la zone de recherche à la fermeture du widget - if (this._inputFeaturesLayer != null) { - map.removeLayer(this._inputFeaturesLayer); - this._inputFeaturesLayer = null; - this._inputFeaturesSources = null; - this._inputFeatures = null; - } - } else { - // on réactive l'interaction - this._activateMapInteraction(map); - } - } - // info : si on est en attente ou sur le panel des résultats : on ne fait rien. - } - - /** - * this method is called by event 'change' on 'GPreverseGeocodingCode' tag select - * (cf. ReverseGeocodeDOM._createReverseGeocodingFormModeChoiceGeocodingTypeElement). - * this value is saved as a parameter for reverseGeocode service. - * - * @param {Object} e - HTMLElement - * @private - */ - onReverseGeocodingTypeChange (e) { - var idx = e.target.selectedIndex; - var value = e.target.options[idx].value; - - if (!value) { - return; - } - logger.log(value); - this._currentGeocodingType = value; - } - - /** - * this method is called by event 'change' on 'GPreverseGeocodingCode' tag select - * (cf. ReverseGeocodeDOM._createReverseGeocodingFormModeChoiceGeocodingDelimitationElement). - * this value is saved as a parameter for reverseGeocode service. - * - * @param {Object} e - HTMLElement - * @private - */ - onReverseGeocodingDelimitationChange (e) { - var idx = e.target.selectedIndex; - var value = e.target.options[idx].value; - - if (!value) { - return; - } - - logger.log(value); - this._currentGeocodingDelimitation = value; - - // on met à jour l'interaction de la map en fonction de la nouvelle délimitation - var map = this.getMap(); - // on supprime l'interaction précédente, ainsi que les géométries et valeurs stockées (filtres, position) - this._clearInputFeatures(); - // on supprime l'éventuelle précédente interaction - this._removeMapInteraction(map); - // on crée une nouvelle interaction - this._activateMapInteraction(map); - } - - /** - * this method is called by event 'click' on 'GPreverseGeocodingReturnPicto' div - * (cf. ReverseGeocodeDOM._createReverseGeocodingPanelReturnPictoElement), - * and clear geocoded location (from both list container and map) - * - * @private - */ - onGPreverseGeocodingReturnPictoClick () { - // suppression des résultats précédents - this._clearResults(); - // on efface les points qui ont pu être saisis précédemment - this._clearInputFeatures(); - // et on réactive l'interaction sur la map - this._activateMapInteraction(this.getMap()); - } - - /** - * this methode is called by event 'submit' on reverseGeocoding form ('GPreverseGeocodingForm') - * (cf. ReverseGeocodeDOM._createReverseGeocodingPanelFormElement), - * it checks reverse geocode mandatory parameters, - * then call this._reverseGeocodingRequest() to generate and send request - * - * @private - */ - onReverseGeocodingSubmit () { - // le paramètre position est obligatoire - if (!this._requestPosition) { - logger.log("missing position"); - return; - } - - this._reverseGeocodingRequest(); - } - - /** - * this method is called by event 'click' on 'GPreverseGeocodedLocation_' div - * (cf. ReverseGeocodeDOM._createReverseGeocodingResultElement), - * and zoom to location ? - * TODO - * - * @param {Object} e - HTMLElement - * @private - */ - onReverseGeocodingResultClick (e) { - // récupération de l'id du résultat survolé - var tagid = e.target.id; // ex GPreverseGeocodedLocation_21 - var idx = tagid.substring(tagid.indexOf("_") + 1); // ex. 21 - - var f = this._resultsFeaturesSource.getFeatureById(parseInt(idx, 10)); - - this.dispatchEvent({ - type : "reversegeocode:onclickresult", - location : f.getProperties().location - }); - } - - /** - * this method is called by event 'mouseover' on 'GPreverseGeocodedLocation_' div - * (cf. ReverseGeocodeDOM._createReverseGeocodingResultElement), - * and changes style of matching marker on map (selected) - * - * @param {Object} e - HTMLElement - * @private - */ - onReverseGeocodingResultMouseOver (e) { - // récupération de l'id du résultat survolé - var tagid = e.target.id; // ex GPreverseGeocodedLocation_21 - var idx = tagid.substring(tagid.indexOf("_") + 1); // ex. 21 - - // on passe le texte en gras - if (e.target.classList) { - e.target.classList.add("GPlocationHighlight"); - } - - if (!this._resultsFeaturesSource) { - return; - } - - // on récupère l'entité correspondante au résultat survolé - var f = this._resultsFeaturesSource.getFeatureById(parseInt(idx, 10)); - // et on lui affecte un nouveau style - f.setStyle(this._resultsSelectedStyle); - } - - /** - * this method is called by event 'mouseout' on 'GPreverseGeocodedLocation_' div - * (cf. ReverseGeocodeDOM._createReverseGeocodingResultElement), - * and changes style of matching marker on map (default) - * - * @param {Object} e - HTMLElement - * @private - */ - onReverseGeocodingResultMouseOut (e) { - // récupération de l'id du résultat survolé - var tagid = e.target.id; // ex GProuteResultsDetailsInstruction_125 - var idx = tagid.substring(tagid.indexOf("_") + 1); // ex. 125 - - // on repasse le texte en style normal - if (e.target.classList) { - e.target.classList.remove("GPlocationHighlight"); - } - - if (!this._resultsFeaturesSource) { - return; - } - // on récupère l'entité correspondante au résultat qui était survolé - var f = this._resultsFeaturesSource.getFeatureById(parseInt(idx, 10)); - // et on lui réaffecte un style normal - f.setStyle(this._resultsDefaultStyle); - } - - // ################################################################### // - // ################################ clean ############################ // - // ################################################################### // - - /** - * this method clears previous location results - * - * @private - */ - _clearResults () { - var map = this.getMap(); - - this._reverseGeocodingLocations = []; - // on vide le container avec la liste des résultats - if (this._resultsListContainer) { - while (this._resultsListContainer.firstChild) { - this._resultsListContainer.removeChild(this._resultsListContainer.firstChild); - } - } - // on retire la couche des résultats - if (this._resultsFeaturesLayer) { - map.removeLayer(this._resultsFeaturesLayer); - this._resultsFeaturesLayer = null; - } - // on retire l'overlay de la popup de la carte - if (this._popupOverlay != null) { - map.removeOverlay(this._popupOverlay); - this._popupOverlay = null; - } - // on retire les interactions sur les markers (select et mouseover) - if (this._resultsSelectInteraction != null) { - map.removeInteraction(this._resultsSelectInteraction); - this._resultsSelectInteraction = null; - } - if (this._resultsHoverInteraction != null) { - map.removeInteraction(this._resultsHoverInteraction); - this._resultsHoverInteraction = null; - } - } - - /** - * this method clears previous input features (features, layer, position and filters) - * - * @private - */ - _clearInputFeatures () { - // on efface les points qui ont pu être saisis précédemment (on vide la collection des features de la couche) - if (this._inputFeatures) { - this._inputFeatures.clear(); - } - - // on supprime les valeurs stockées - this._requestGeom = null; - this._requestPosition = null; - } - - /** - * this method displays waiting container and sets a timeout - * - * @private - */ - _displayWaitingContainer () { - this._waitingContainer.className = "GPwaitingContainer GPwaitingContainerVisible gpf-waiting gpf-waiting--visible"; - this._waiting = true; - - // mise en place d'un timeout pour réinitialiser le panel (cacher la patience) - // si on est toujours en attente (si la requête est bloquée par exemple) - if (this._timer) { - clearTimeout(this._timer); - this._timer = null; - } - var context = this; - this._timer = setTimeout(function () { - if (context._waiting === true) { - context._hideWaitingContainer(); - } else { - if (context._timer) { - clearTimeout(context._timer); - } - } - }, 16000); - } - - /** - * this method hides waiting container and clears timeout - * - * @private - */ - _hideWaitingContainer () { - if (this._waiting) { - this._waitingContainer.className = "GPwaitingContainer GPwaitingContainerHidden gpf-waiting gpf-waiting--hidden"; - this._waiting = false; - clearTimeout(this._timer); - this._timer = null; - } - } - -}; - -// on récupère les méthodes de la classe commune ReverseGeocodeDOM -Object.assign(ReverseGeocode.prototype, ReverseGeocodeDOM); - -export default ReverseGeocode; - -// Expose ReverseGeocode as ol.control.ReverseGeocode (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.ReverseGeocode = ReverseGeocode; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.d.ts deleted file mode 100644 index 64aa33487..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -export default ReverseGeocodeDOM; -declare namespace ReverseGeocodeDOM { - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createShowReverseGeocodingPictoElement(): DOMElement; - function _createReverseGeocodingWaitingElement(): DOMElement; - function _createReverseGeocodingResultsPanelElement(): DOMElement; - function _createReverseGeocodingResultsListElement(): DOMElement; - function _createReverseGeocodingResultElement(locationDescription: string, id: number): void; - function _createReverseGeocodingPanelElement(): DOMElement; - function _createReverseGeocodingPanelDivElement(): HTMLDivElement; - function _createReverseGeocodingPanelHeaderElement(): DOMElement; - function _createReverseGeocodingPanelReturnPictoElement(): DOMElement; - function _createReverseGeocodingPanelTitleElement(): DOMElement; - function _createReverseGeocodingPanelCloseElement(): DOMElement; - function _createReverseGeocodingPanelFormElement(): DOMElement; - function _createReverseGeocodingFormModeChoiceGeocodingTypeElement(resources: any[]): DOMElement; - function _createReverseGeocodingFormModeChoiceGeocodingDelimitationElement(delimitations: any[]): DOMElement; - function _createReverseGeocodingSubmitFormElement(): DOMElement; -} -//# sourceMappingURL=ReverseGeocodeDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.d.ts.map deleted file mode 100644 index 9bc00b777..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ReverseGeocodeDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.js"],"names":[],"mappings":";;IAOc,qCAGT;IAO6B,mDAK7B;IAWyC,+DA2BzC;IAOuC,6DAYvC;IAO4C,kEAK5C;IAO2C,iEAO3C;IASsC,6FA8CtC;IAWqC,2DAMrC;IAEwC,kEAIxC;IAO2C,iEAM3C;IAOgD,sEA8BhD;IAO0C,gEAM1C;IAO0C,gEAqC1C;IAQyC,+DAqBzC;IAY2D,iGA6D3D;IAQmE,6GA6DnE;IAW0C,gEAQ1C"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.js deleted file mode 100644 index 00599dedb..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ReverseGeocode/ReverseGeocodeDOM.js +++ /dev/null @@ -1,485 +0,0 @@ -var ReverseGeocodeDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Main container (DOM) - * - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPreverseGeocoding"); - container.className = "GPwidget gpf-widget gpf-widget-button"; - return container; - }, - - // ################################################################### // - // ################### Methods of main container ##################### // - // ################################################################### // - - /** - * Show ReverseGeocoding - * - * @returns {DOMElement} DOM element - */ - _createShowReverseGeocodingPictoElement : function () { - // contexte d'execution - var self = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowReverseGeocodingPicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto GPshowReverseGeocodingPicto gpf-btn gpf-btn-icon gpf-btn-icon-reverse fr-btn"; - button.title = "Ouvrir la recherche inverse"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // Close all results and panels when minimizing the widget - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onShowReverseGeocodingClick(); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onShowReverseGeocodingClick(); - }); - } - - return button; - }, - - /** - * Create Waiting Panel - * - * @returns {DOMElement} DOM element - */ - _createReverseGeocodingWaitingElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPreverseGeocodingCalcWaitingContainer"); - div.className = "GPwaitingContainer GPwaitingContainerHidden gpf-waiting gpf-waiting--hidden"; - - var p = document.createElement("p"); - p.className = "GPwaitingContainerInfo gpf-waiting_info"; - p.innerHTML = "Recherche en cours..."; - - div.appendChild(p); - - return div; - }, - - /** - * Reverse geocoding results panel element. - * - * @returns {DOMElement} DOM element - */ - _createReverseGeocodingResultsPanelElement : function () { - var resultsPanelDiv = document.createElement("div"); - resultsPanelDiv.id = this._addUID("GPreverseGeocodingResultsPanel"); - resultsPanelDiv.className = "GPpanel GPelementHidden gpf-panel gpf-panel-reverse gpf-panel--hidden"; - return resultsPanelDiv; - }, - - /** - * Reverse geocoding results list. - * - * @returns {DOMElement} DOM element - */ - _createReverseGeocodingResultsListElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPreverseGeocodingResultsList"); - container.className = "gpf-panel__list"; - container.setAttribute("tabindex", "0"); - // Results are dynamically filled in Javascript by reverse geocoding service - return container; - }, - - /** - * Add Result - * (results dynamically generate !) - * - * @param {String} locationDescription - reverse geocoded location results - * @param {Number} id - ID - */ - _createReverseGeocodingResultElement : function (locationDescription, id) { - // contexte - var context = this; - - var container = document.getElementById(this._addUID("GPreverseGeocodingResultsList")); - - var div = document.createElement("div"); - div.id = this._addUID("GPreverseGeocodedLocation_" + id); - div.setAttribute("tabindex", "0"); - div.className = "GPautoCompleteProposal gpf-panel__items"; - div.innerHTML = locationDescription; - div.title = locationDescription; - - if (div.addEventListener) { - div.addEventListener("mouseover", function (e) { - context.onReverseGeocodingResultMouseOver(e); - }); - div.addEventListener("focus", function (e) { - context.onReverseGeocodingResultMouseOver(e); - }); - div.addEventListener("mouseout", function (e) { - context.onReverseGeocodingResultMouseOut(e); - }); - div.addEventListener("blur", function (e) { - context.onReverseGeocodingResultMouseOut(e); - }); - div.addEventListener("click", function (e) { - if (typeof context.onReverseGeocodingResultClick === "function") { - context.onReverseGeocodingResultClick(e); - } - }); - } else if (div.attachEvent) { - div.attachEvent("onmouseover", function (e) { - context.onReverseGeocodingResultMouseOver(e); - }); - div.attachEvent("onmouseout", function (e) { - context.onReverseGeocodingResultMouseOut(e); - }); - div.attachEvent("onclick", function (e) { - if (typeof context.onReverseGeocodingResultClick === "function") { - context.onReverseGeocodingResultClick(e); - } - }); - } - - container.appendChild(div); - }, - - // ################################################################### // - // ######################### Inputs panel ############################ // - // ################################################################### // - - /** - * Create Container Panel - * - * @returns {DOMElement} DOM element - */ - _createReverseGeocodingPanelElement : function () { - var dialog = document.createElement("dialog"); - dialog.id = this._addUID("GPreverseGeocodingPanel"); - dialog.className = "GPpanel gpf-panel fr-modal"; - - return dialog; - }, - - _createReverseGeocodingPanelDivElement : function () { - var div = document.createElement("div"); - div.className = "gpf-panel__body fr-modal__body"; - return div; - }, - - /** - * Create Header Panel - * - * @returns {DOMElement} DOM element - */ - _createReverseGeocodingPanelHeaderElement : function () { - var container = document.createElement("div"); - container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; - // info: on sépare les appels pour la création du picto de retour, - // du titre et de la croix de fermeture pour les récupérer dans le composant - return container; - }, - - /** - * Create return picto in panel header - * - * @returns {DOMElement} DOM element - */ - _createReverseGeocodingPanelReturnPictoElement : function () { - // contexte - var self = this; - - var buttonNew = document.createElement("button"); - buttonNew.id = this._addUID("GPreverseGeocodingReturnPicto"); - buttonNew.title = "Nouvelle recherche"; - buttonNew.className = "GPreturnPicto GPreverseGeocodingReturnPicto gpf-btn gpf-btn-icon-return fr-btn fr-btn--secondary"; - buttonNew.classList.add("GPelementHidden"); - buttonNew.classList.add("gpf-hidden"); - if (buttonNew.addEventListener) { - buttonNew.addEventListener("click", function (e) { - document.getElementById(self._addUID("GPreverseGeocodingResultsPanel")).className = "GPelementHidden gpf-panel--hidden"; - document.getElementById(self._addUID("GPreverseGeocodingForm")).className = "GPform gpf-panel__content fr-modal__content"; - document.getElementById(self._addUID("GPreverseGeocodingHeaderTitle")).innerHTML = "Recherche inverse"; - document.getElementById(self._addUID("GPreverseGeocodingReturnPicto")).classList.add("GPelementHidden"); - document.getElementById(self._addUID("GPreverseGeocodingReturnPicto")).classList.add("gpf-hidden"); - self.onGPreverseGeocodingReturnPictoClick(e); - }); - } else if (buttonNew.attachEvent) { - buttonNew.attachEvent("onclick", function (e) { - document.getElementById(self._addUID("GPreverseGeocodingResultsPanel")).className = "GPelementHidden gpf-panel--hidden"; - document.getElementById(self._addUID("GPreverseGeocodingForm")).className = "GPform gpf-panel__content fr-modal__content"; - document.getElementById(self._addUID("GPreverseGeocodingHeaderTitle")).innerHTML = "Recherche inverse"; - document.getElementById(self._addUID("GPreverseGeocodingReturnPicto")).classList.add("GPelementHidden"); - document.getElementById(self._addUID("GPreverseGeocodingReturnPicto")).classList.add("gpf-hidden"); - self.onGPreverseGeocodingReturnPictoClick(e); - }); - } - return buttonNew; - }, - - /** - * Create Header Title Panel - * - * @returns {DOMElement} DOM element - */ - _createReverseGeocodingPanelTitleElement : function () { - var div = document.createElement("div"); - div.className = "GPpanelTitle gpf-panel__title fr-modal__title fr-m-1w"; - div.id = this._addUID("GPreverseGeocodingHeaderTitle"); - div.innerHTML = "Recherche inverse"; - return div; - }, - - /** - * Create Header close div - * - * @returns {DOMElement} DOM element - */ - _createReverseGeocodingPanelCloseElement : function () { - // contexte - var self = this; - - var divClose = document.createElement("button"); - divClose.id = this._addUID("GPreverseGeocodingPanelClose"); - divClose.className = "GPpanelClose GPreverseGeocodingPanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--secondary fr-m-1w"; - divClose.title = "Fermer le panneau"; - - // Link panel close / visibility checkbox - if (divClose.addEventListener) { - divClose.addEventListener("click", function () { - document.getElementById(self._addUID("GPshowReverseGeocodingPicto")).click(); - }, false); - divClose.addEventListener("keydown", function (event) { - if (event.keyCode === 13) { - document.getElementById(self._addUID("GPshowReverseGeocodingPicto")).click(); - } - }, false); - } else if (divClose.attachEvent) { - divClose.attachEvent("onclick", function () { - document.getElementById(self._addUID("GPshowReverseGeocodingPicto")).click(); - }); - divClose.attachEvent("onkeydown", function (event) { - if (event.keyCode === 13) { - document.getElementById(self._addUID("GPshowReverseGeocodingPicto")).click(); - } - }); - } - - var span = document.createElement("span"); - span.className = "GPelementHidden gpf-visible"; // afficher en dsfr - span.innerText = "Fermer"; - - divClose.appendChild(span); - - return divClose; - }, - - /** - * Create Form - * see event ! - * - * @returns {DOMElement} DOM element - */ - _createReverseGeocodingPanelFormElement : function () { - // contexte d'execution - var self = this; - - var form = document.createElement("form"); - form.id = this._addUID("GPreverseGeocodingForm"); - form.className = "GPform gpf-panel__content fr-modal__content"; - - if (form.addEventListener) { - form.addEventListener("submit", function (e) { - e.preventDefault(); - self.onReverseGeocodingSubmit(); - }); - } else if (form.attachEvent) { - form.attachEvent("onsubmit", function (e) { - e.preventDefault(); - self.onReverseGeocodingSubmit(); - }); - } - - return form; - }, - - // ################################################################### // - // ####################### Choice mode into form ##################### // - // ################################################################### // - - /** - * Create Container to Mode choice geocoding type - * - * @param {Array} resources - geocoding resources to be displayed (and used) - * @returns {DOMElement} DOM element - */ - _createReverseGeocodingFormModeChoiceGeocodingTypeElement : function (resources) { - // contexte d'execution - var context = this; - - var div = document.createElement("div"); - div.className = "GPflexInput gpf-flex gpf-flex-reverse fr-mb-1w"; - - var label = document.createElement("label"); - label.id = "label-recherche-par"; - label.className = "GPlabel gpf-label fr-label"; - label.innerHTML = "Recherche par"; - label.title = "Recherche par"; - div.appendChild(label); - - var select = document.createElement("select"); - select.setAttribute("aria-labelledby", "label-recherche-par"); - select.className = "GPselect gpf-select fr-select"; - // gestionnaire d'evenement : on stocke la valeur du type de geocodage, - // utilisé dans la requête de géocodage inverse - if (select.addEventListener) { - select.addEventListener("change", function (e) { - context.onReverseGeocodingTypeChange(e); - }); - } else if (select.attachEvent) { - select.attachEvent("onchange", function (e) { - context.onReverseGeocodingTypeChange(e); - }); - } - - // on prend soit les valeurs passées par l'utilisateur, soit des valeurs par défaut - if (!resources || !Array.isArray(resources)) { - resources = ["StreetAddress", "PositionOfInterest", "CadastralParcel"]; - } - for (var i = 0; i < resources.length; i++) { - switch (resources[i]) { - case "PositionOfInterest": - var POIOption = document.createElement("option"); - POIOption.value = "PositionOfInterest"; - POIOption.text = "Lieux/toponymes"; - select.appendChild(POIOption); - break; - case "StreetAddress": - var SAOption = document.createElement("option"); - SAOption.value = "StreetAddress"; - SAOption.text = "Adresses"; - select.appendChild(SAOption); - break; - case "CadastralParcel": - var CPOption = document.createElement("option"); - CPOption.value = "CadastralParcel"; - CPOption.text = "Parcelles cadastrales"; - select.appendChild(CPOption); - break; - default: - break; - } - } - - div.appendChild(select); - - return div; - }, - - /** - * Create Container to Mode choice geocoding delimitation - * - * @param {Array} delimitations - geocoding delimitations to be displayed (and used) - * @returns {DOMElement} DOM element - */ - _createReverseGeocodingFormModeChoiceGeocodingDelimitationElement : function (delimitations) { - // contexte d'execution - var context = this; - - var div = document.createElement("div"); - div.className = "GPflexInput gpf-flex gpf-flex-reverse fr-mb-2w"; - - var label = document.createElement("label"); - label.id = "label-delimitation"; - label.className = "GPlabel gpf-label fr-label"; - label.innerHTML = "Délimitation"; - label.title = "Délimitation"; - div.appendChild(label); - - var select = document.createElement("select"); - select.setAttribute("aria-labelledby", "label-delimitation"); - select.className ="GPselect gpf-select fr-select"; - // gestionnaire d'evenement : on stocke la valeur du type de délimitation, - // et on modifie l'événement de pointage sur la carte en fonction - if (select.addEventListener) { - select.addEventListener("change", function (e) { - context.onReverseGeocodingDelimitationChange(e); - }); - } else if (select.attachEvent) { - select.attachEvent("onchange", function (e) { - context.onReverseGeocodingDelimitationChange(e); - }); - } - - // on prend soit les valeurs passées par l'utilisateur, soit des valeurs par défaut - if (!delimitations || !Array.isArray(delimitations)) { - delimitations = ["Point", "Circle", "Extent"]; - } - for (var i = 0; i < delimitations.length; i++) { - switch (delimitations[i].toLowerCase()) { - case "point": - var pointOption = document.createElement("option"); - pointOption.value = "point"; - pointOption.text = "Pointer un lieu"; - select.appendChild(pointOption); - break; - case "circle": - var circleOption = document.createElement("option"); - circleOption.value = "circle"; - circleOption.text = "Dessiner un cercle"; - select.appendChild(circleOption); - break; - case "extent": - var extentOption = document.createElement("option"); - extentOption.value = "extent"; - extentOption.text = "Dessiner une emprise"; - select.appendChild(extentOption); - break; - default: - break; - } - } - - div.appendChild(select); - - return div; - }, - - // ################################################################### // - // ########################### Submit Form ########################### // - // ################################################################### // - - /** - * Create Submit Form Element - * - * @returns {DOMElement} DOM element - */ - _createReverseGeocodingSubmitFormElement : function () { - var input = document.createElement("input"); - input.id = this._addUID("GPreverseGeocodingSubmit"); - input.className = "GPsubmit gpf-btn fr-btn fr-btn--secondary"; - input.type = "submit"; - input.value = "Rechercher"; - - return input; - } - -}; - -export default ReverseGeocodeDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/Route.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/Route.d.ts deleted file mode 100644 index 11b2c0f20..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/Route.d.ts +++ /dev/null @@ -1,71 +0,0 @@ -export default Route; -/** - * @classdesc - * - * Route Control. - * - * @constructor - * @alias ol.control.Route - * @type {ol.control.Route} - * @extends {ol.control.Control} - * @param {Object} options - route control options - * @param {String} [options.apiKey] - API key for services call (route and autocomplete services). The key "calcul" is used by default. - * @param {Boolean} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean} [options.collapsed = true] - Specify if widget has to be collapsed (true) or not (false) on map loading. Default is true. - * @param {Boolean} [options.draggable = false] - Specify if widget is draggable - * @param {Boolean|Object} [options.export = false] - Specify if button "Export" is displayed. For the use of the options of the "Export" control, see {@link ol.control.Export} - * @param {Object} [options.exclusions = {"toll" : false, "tunnel" : false, "bridge" : false}] - list of exclusions with status (true = checked). By default : no exclusions checked. - * @param {Array} [options.graphs = ["Voiture", "Pieton"]] - list of resources, by default : ["Voiture", "Pieton"]. The first element is selected. - * @param {Object} [options.routeOptions = {}] - route service options. see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~route Gp.Services.route()} to know all route options. - * @param {Object} [options.autocompleteOptions = {}] - autocomplete service options. see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~autoComplete Gp.Services.autoComplete()} to know all autocomplete options - * @param {Object} [options.markersOpts] - options to use your own markers. Object properties can be "departure", "stages" or "arrival". Corresponding value is an object with following properties : - * @param {String} [options.markersOpts.url] - marker base64 encoded url (ex "data:image/png;base64,...""). Mandatory for a custom marker - * @param {Array} [options.markersOpts.offset] - Offsets in pixels used when positioning the overlay. The first element in the array is the horizontal offset. A positive value shifts the overlay right. The second element in the array is the vertical offset. A positive value shifts the overlay down. Default is [0, 0]. (see http://openlayers.org/en/latest/apidoc/ol.Overlay.html) - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Itinéraire"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Itinéraire basé sur un graphe"] - Layer description to be displayed in LayerSwitcher - * @fires route:drawstart - * @fires route:drawend - * @fires route:compute - * @fires export:compute - * @example - * var route = ol.control.Route({ - * "collapsed" : true - * "draggable" : true, - * "export" : false, - * "exclusions" : { - * "toll" : true, - * "bridge" : false, - * "tunnel" : true - * }, - * "graphs" : ['Pieton', 'Voiture'], - * "markersOpts" : { - * "departure" : { - * "url" : "...", - * "offset" : [0,0] - * }, - * "stages" : { - * "url" : "...", - * "offset" : [0,0] - * }, - * "arrival" : { - * "url" : "...", - * "offset" : [0,0] - * } - * } - * "autocompleteOptions" : {}, - * "routeOptions" : {} - * }); - * - * // if you want to pluggued the control Export with options : - * var route = new ol.control.Route({ - * export : { - * name : "export", - * format : "geojson", - * title : "Exporter", - * menu : false - * } - * }); - */ -declare var Route: ol.control.Route; -//# sourceMappingURL=Route.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/Route.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/Route.d.ts.map deleted file mode 100644 index 95025372e..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/Route.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Route.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Route/Route.js"],"names":[],"mappings":";AAqCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,oCAqmEE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/Route.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/Route.js deleted file mode 100644 index b6a941c2c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/Route.js +++ /dev/null @@ -1,2265 +0,0 @@ -// import CSS -import "../../CSS/Controls/Route/GPFroute.css"; -// import "../../CSS/Controls/Route/GPFrouteStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -import { unByKey as olObservableUnByKey } from "ol/Observable"; -import Overlay from "ol/Overlay"; -import VectorLayer from "ol/layer/Vector"; -import VectorSource from "ol/source/Vector"; -// import GeoJSON from "ol/format/GeoJSON"; -import { pointerMove as eventPointerMove } from "ol/events/condition"; -import { Select as SelectInteraction } from "ol/interaction"; -import { - Stroke, - Style -} from "ol/style"; -import { transformExtent as olTransformExtentProj } from "ol/proj"; -// import geoportal library access -import Gp from "geoportal-access-lib"; -// import local -import Logger from "../../Utils/LoggerByDefault"; -import Utils from "../../Utils/Helper"; -import SelectorID from "../../Utils/SelectorID"; -import Markers from "../Utils/Markers"; -import Draggable from "../../Utils/Draggable"; -import Interactions from "../Utils/Interactions"; -// import local with ol dependencies -import LocationSelector from "../LocationSelector/LocationSelector"; -import ButtonExport from "../Export/Export"; -import LayerSwitcher from "../LayerSwitcher/LayerSwitcher"; -import GeoJSONExtended from "../../Formats/GeoJSON"; -// DOM -import RouteDOM from "./RouteDOM"; - -var logger = Logger.getLogger("route"); - -/** - * @classdesc - * - * Route Control. - * - * @constructor - * @alias ol.control.Route - * @type {ol.control.Route} - * @extends {ol.control.Control} - * @param {Object} options - route control options - * @param {String} [options.apiKey] - API key for services call (route and autocomplete services). The key "calcul" is used by default. - * @param {Boolean} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean} [options.collapsed = true] - Specify if widget has to be collapsed (true) or not (false) on map loading. Default is true. - * @param {Boolean} [options.draggable = false] - Specify if widget is draggable - * @param {Boolean|Object} [options.export = false] - Specify if button "Export" is displayed. For the use of the options of the "Export" control, see {@link ol.control.Export} - * @param {Object} [options.exclusions = {"toll" : false, "tunnel" : false, "bridge" : false}] - list of exclusions with status (true = checked). By default : no exclusions checked. - * @param {Array} [options.graphs = ["Voiture", "Pieton"]] - list of resources, by default : ["Voiture", "Pieton"]. The first element is selected. - * @param {Object} [options.routeOptions = {}] - route service options. see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~route Gp.Services.route()} to know all route options. - * @param {Object} [options.autocompleteOptions = {}] - autocomplete service options. see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~autoComplete Gp.Services.autoComplete()} to know all autocomplete options - * @param {Object} [options.markersOpts] - options to use your own markers. Object properties can be "departure", "stages" or "arrival". Corresponding value is an object with following properties : - * @param {String} [options.markersOpts.url] - marker base64 encoded url (ex "data:image/png;base64,...""). Mandatory for a custom marker - * @param {Array} [options.markersOpts.offset] - Offsets in pixels used when positioning the overlay. The first element in the array is the horizontal offset. A positive value shifts the overlay right. The second element in the array is the vertical offset. A positive value shifts the overlay down. Default is [0, 0]. (see http://openlayers.org/en/latest/apidoc/ol.Overlay.html) - * @param {Object} [options.layerDescription = {}] - Layer informations to be displayed in LayerSwitcher widget (only if a LayerSwitcher is also added to the map) - * @param {String} [options.layerDescription.title = "Itinéraire"] - Layer title to be displayed in LayerSwitcher - * @param {String} [options.layerDescription.description = "Itinéraire basé sur un graphe"] - Layer description to be displayed in LayerSwitcher - * @fires route:drawstart - * @fires route:drawend - * @fires route:compute - * @fires export:compute - * @example - * var route = ol.control.Route({ - * "collapsed" : true - * "draggable" : true, - * "export" : false, - * "exclusions" : { - * "toll" : true, - * "bridge" : false, - * "tunnel" : true - * }, - * "graphs" : ['Pieton', 'Voiture'], - * "markersOpts" : { - * "departure" : { - * "url" : "...", - * "offset" : [0,0] - * }, - * "stages" : { - * "url" : "...", - * "offset" : [0,0] - * }, - * "arrival" : { - * "url" : "...", - * "offset" : [0,0] - * } - * } - * "autocompleteOptions" : {}, - * "routeOptions" : {} - * }); - * - * // if you want to pluggued the control Export with options : - * var route = new ol.control.Route({ - * export : { - * name : "export", - * format : "geojson", - * title : "Exporter", - * menu : false - * } - * }); - */ -var Route = class Route extends Control { - - /** - * See {@link ol.control.Route} - * @module Route - * @alias module:~Controls/Route - * @param {*} options - options - * @example - * import Route from "src/OpenLayers/Controls/Route" - */ - constructor (options) { - options = options || {}; - - // call ol.control.Control constructor - super({ - element : options.element, - target : options.target, - render : options.render - }); - - if (!(this instanceof Route)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - // initialisation du composant - this.initialize(options); - - // Widget main DOM container - this._container = this._createMainContainerElement(); - - // ajout du container - (this.element) ? this.element.appendChild(this._container) : this.element = this._container; - - return this; - } - - /** - * Overwrite OpenLayers setMap method - * - * @param {ol.Map} map - Map. - */ - setMap (map) { - if (map) { - // enrichissement du DOM du container - this._container = this._initContainer(map); - this.element = this._container; - - // ajout d'un bouton d'export - if (this.options.export) { - var opts = Utils.assign({ control : this }, this.options.export); - this.export = new ButtonExport(opts); - this.export.render(); - var self = this; - this.export.on("export:compute", (e) => { - self.dispatchEvent({ - type : "export:compute", - content : e.content - }); - }); - } - - // mode "draggable" - if (this.draggable) { - Draggable.dragElement( - this._panelRouteContainer, - this._panelHeaderRouteContainer, - this.options.position ? null : map.getTargetElement() - ); - } - - // mode "collapsed" - if (!this.collapsed) { - this._showRouteButton.setAttribute("aria-pressed", true); - } - } - - // on appelle la méthode setMap originale d'OpenLayers - super.setMap(map); - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - }; - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - - /** - * Returns true if widget is collapsed (minimized), false otherwise - * - * @returns {Boolean} collapsed - true if widget is collapsed - */ - getCollapsed () { - return this.collapsed; - } - - /** - * Collapse or display widget main container - * - * @param {Boolean} collapsed - True to collapse widget, False to display it - */ - setCollapsed (collapsed) { - if (collapsed === undefined) { - logger.log("[ERROR] Route:setCollapsed - missing collapsed parameter"); - return; - } - if ((collapsed && this.collapsed) || (!collapsed && !this.collapsed)) { - return; - } - if (collapsed) { - document.getElementById("GProutePanelClose-" + this._uid).click(); - } else { - this._showRouteButton.click(); - } - this.collapsed = collapsed; - } - - /** - * Get vector layer where geoJson route is drawn - * - * @returns {Object} layer - ol.layer.Vector route layer - */ - getLayer () { - return this._geojsonSections; - } - - /** - * Set vector layer where route geometry is drawn - * - * @param {Object} layer - ol.layer.Vector route layer - */ - setLayer (layer) { - if (!layer) { - this._geojsonSections = null; - return; - } - - if (!(layer instanceof VectorLayer)) { - logger.log("no valid layer given for hosting drawn features."); - return; - } - - // application des styles - layer.setStyle(this._defaultFeatureStyle); - // sauvegarde - this._geojsonSections = layer; - } - - /** - * Get vector layer - * - * @returns {String} geojson - GeoJSON format layer - */ - getGeoJSON () { - return JSON.stringify(this._geojsonObject); - } - - /** - * Set vector layer - * - * @param {String} geojson - GeoJSON format layer - */ - setGeoJSON (geojson) { - try { - this._geojsonObject = JSON.parse(geojson); - } catch (e) { - logger.log("no valid geojson given :" + e.message); - } - } - - /** - * Get route informations - * - * @returns {Object} data - route informations - */ - getData () { - var points = []; - for (let index = 0; index < this._currentPoints.length; index++) { - const p = this._currentPoints[index]; - points.push(p.getCoordinate()); - } - var data = { - type : "route", - points : points, - transport : this._currentTransport, - exclusions : this._currentExclusions, - computation : this._currentComputation, - results : {} - }; - Utils.assign(data.results, this._currentRouteInformations); - return data; - } - - /** - * Set route data - * - * @param {Object} data - control informations - * @param {String} data.transport - transport type - * @param {String} data.computation - computation type - * @param {Array} data.exclusions - list of exclusions - * @param {Array} data.points - list of points : [[lon, lat]] - * @param {Object} data.results - service response - */ - setData (data) { - // INFO - // transmettre toutes les informations necessaires pour reconstruire le panneau de resultats - this._currentTransport = data.transport; - this._currentComputation = data.computation; - this._currentExclusions = data.exclusions; - // INFO - // nettoyer les points du calcul précedent - for (var i = 0; i < this._currentPoints.length; i++) { - var point = this._currentPoints[i]; - if (point.getCoordinate()) { - // clean de l'objet sans declencher les evenements qui suppriment la couche précedente ! - // /!\ point.clear() - point.clearResults(); - // clean du dom - var id = (i + 1) + "-" + this._uid; - document.getElementById("GPlocationOriginCoords_" + id).value = ""; - document.getElementById("GPlocationOrigin_" + id).value = ""; - document.getElementById("GPlocationPoint_" + id).style.cssText = ""; - if (i > 0 && i < 6) { - // on masque les points intermediaires - document.getElementById("GPlocationPoint_" + id).className = "GPflexInput GPelementHidden gpf-flex gpf-hidden "; - } - document.getElementById("GPlocationOriginPointer_" + id).checked = false; - document.getElementById("GPlocationOrigin_" + id).className = "GPelementVisible gpf-visible"; - document.getElementById("GPlocationOriginCoords_" + id).className = "GPelementHidden gpf-hidden"; - } - } - // ajout des nouvelles coordonnnées - for (var j = 0; j < data.points.length; j++) { - const c = data.points[j]; - if (c) { - this._currentPoints[j].setCoordinate(c, "EPSG:4326"); - } - } - this._currentRouteInformations = data.results; - } - - /** - * Get container - * - * @returns {DOMElement} container - */ - getContainer () { - return this._container; - } - - /** - * Get default style - * - * @returns {ol.style} style - */ - getStyle () { - return this._defaultFeatureStyle; - } - - /** - * This method is public. - * It allows to init the control. - */ - init () { - // INFO - // reconstruire le panneau de resultats sans lancer de calcul - // * construire la liste des points (cf. RouteDOM._createRoutePanelFormElement()) - // * construire les resultats - - // init points - for (let index = 0; index < this._currentPoints.length; index++) { - const point = this._currentPoints[index]; - var id = index + 1; - var coordinate = point.getCoordinate(); - if (coordinate) { - var input = document.getElementById("GPlocationOrigin_" + id + "-" + this._uid); - input.value = coordinate[1].toFixed(4) + " / " + coordinate[0].toFixed(4); - if (index > 0 && index < 6) { - document.getElementById("GPlocationPoint_" + id + "-" + this._uid).className = "GPflexInput GPlocationStageFlexInput gpf-flex"; - } - } - } - - // add points into panel - var points = document.getElementsByClassName("GPlocationPoint-" + this._uid); - this._addRouteResultsStagesValuesElement(points); - - // set transport mode - var transportdiv; - if (this._currentTransport === "Pieton") { - transportdiv = document.getElementById("GProuteTransportPedestrian-" + this._uid); - if (transportdiv) { - transportdiv.checked = "true"; - } - } else { - transportdiv = document.getElementById("GProuteTransportCar-" + this._uid); - if (transportdiv) { - transportdiv.checked = "true"; - } - } - - // set computation mode - var computationdiv = document.getElementById("GProuteComputationSelect-" + this._uid); - if (computationdiv) { - computationdiv.value = this._currentComputation; - } - - // set exclusions - var tollInput = document.getElementById("GProuteExclusionsToll-" + this._uid); - if (tollInput) { - if (this._currentExclusions.indexOf("toll") !== -1) { - tollInput.checked = false; - } else { - tollInput.checked = true; - } - } - - var tunnelInput = document.getElementById("GProuteExclusionsTunnel-" + this._uid); - if (tunnelInput) { - if (this._currentExclusions.indexOf("tunnel") !== -1) { - tunnelInput.checked = false; - } else { - tunnelInput.checked = true; - } - } - - var bridgeInput = document.getElementById("GProuteExclusionsBridge-" + this._uid); - if (bridgeInput) { - if (this._currentExclusions.indexOf("bridge") !== -1) { - bridgeInput.checked = false; - } else { - bridgeInput.checked = true; - } - } - - var distance = this._currentRouteInformations.totalDistance; - var duration = this._currentRouteInformations.totalTime; - - // Détails avec simplifications des troncons - var instructions = this._simplifiedInstructions(this._currentRouteInformations.routeInstructions); - - if (instructions) { - this._fillRouteResultsDetailsContainer(distance, duration, instructions); - } - - // affichage du panneau de details du controle ! - this._formRouteContainer.className = "GPelementHidden gpf-hidden gpf-panel__content fr-modal__content"; - this._hideWaitingContainer(); - this._resultsRouteContainer.className = ""; - } - - /** - * Clean UI : reinit control - */ - clean () { - this._currentTransport = null; - this._currentExclusions = []; - this._currentComputation = null; - - for (var i = 0; i < this._currentPoints.length; i++) { - this._currentPoints[i].clear(); - } - - this._removeRouteStepLocations(); - this._clearRouteInputOptions(); - this._clearRouteResultsDetails(); - - this.setLayer(); - - this._formRouteContainer.className = "gpf-panel__content fr-modal__content"; - this._resultsRouteContainer.className = "GPelementHidden gpf-hidden"; - } - - // ################################################################### // - // ##################### init component ############################## // - // ################################################################### // - - /** - * Initialize route control (called by Route constructor) - * - * @param {Object} options - constructor options - * @private - */ - initialize (options) { - this._checkInputOptions(options); - - // set default options - this.options = { - collapsed : true, - draggable : false, - export : false, - graphs : ["Voiture", "Pieton"], - exclusions : { - toll : false, - tunnel : false, - bridge : false - }, - routeOptions : {}, - autocompleteOptions : {}, - layerDescription : { - title : "Itinéraire", - description : "Itinéraire basé sur un graphe" - } - }; - - // merge with user options - Utils.assign(this.options, options); - - // cas particulier des markers par défaut - var defaultMarkersOpts = { - departure : { - url : Markers["red"], - offset : Markers.defaultOffset - }, - stages : { - url : Markers["lightOrange"], - offset : Markers.defaultOffset - }, - arrival : { - url : Markers["darkOrange"], - offset : Markers.defaultOffset - } - }; - // on récupère les options de chaque type de marker si spécifié - this.options.markersOpts = Utils.assign(defaultMarkersOpts, options.markersOpts); - - /** {Boolean} specify if Route control is collapsed (true) or not (false) */ - this.collapsed = this.options.collapsed; - - /** {Boolean} specify if Route control is draggable (true) or not (false) */ - this.draggable = this.options.draggable; - - this._uid = SelectorID.generate(); - - // containers principaux - this._showRouteButton = null; - this._panelRouteContainer = null; - this._panelHeaderRouteContainer = null; - this._waitingContainer = null; - this._formRouteContainer = null; - this._resultsRouteContainer = null; - this._showRouteExclusionsElement = null; - - // liste de points selectionnée - this._currentPoints = []; - - // Mode de transport selectionné : 'Voiture' ou 'Pieton' - this._currentTransport = null; - this._initTransport(); - - // Mode de calcul selectionné : 'Plus rapide' ou 'plus court' - this._currentComputation = null; - this._initComputation(); - - // Exclusions selectionnées : Tunnel, Toll et Bridge - this._currentExclusions = []; - this._initExclusions(); - - // si un calcul est en cours ou non - this._waiting = false; - // timer pour cacher la patience après un certain temps - this._timer = null; - - // la geometrie du parcours - this._geojsonRoute = null; - - // la geometrie des troncons - this._geojsonSections = null; - - // la geometrie des troncons au format GeoJSON - this._geojsonObject = null; - - // bouton export - this.export = null; - - // le container de la popup (pour les troncons selectionnés) - this._popupContent = null; - this._popupDiv = this._initPopupDiv(); - // l'overlay ol.Overlay correspondant à la popup (pour les troncons selectionnés) - this._popupOverlay = null; - - // ol.interaction.Select associées à la couche des résultats (troncons) - this._resultsSelectInteraction = null; - this._resultsHoverInteraction = null; - - // styles pour les sélections des features - this._defaultFeatureStyle = new Style({ - stroke : new Stroke({ - color : "rgba(0,183,152,0.9)", - width : 12 - }) - }); - this._selectedFeatureStyle = new Style({ - stroke : new Stroke({ - color : "rgba(255,102,0,0.9)", - width : 12 - }) - }); - - // reponse du service - // Ex. { - // totalTime, totalDistance, bbox, routeGeometry, - // routeInstructions : [{duration, distance, code, instruction, bbox, geometry}] - // } - this._currentRouteInformations = null; - - // liste des ressources avec droits par service - // Ex. { - // "Route" : { - // key : "ger4g456re45er456t4er5ge5", - // resources : ["Pieton", "Voiture"] - // } - // } - this._resources = {}; - - // listener key for event on pointermove or moveend map - this.listenerKey = null; - } - - /** - * this method is called by this.initialize() - * - * @param {Object} options - options - * - * @private - */ - _checkInputOptions (options) { - // vérification des options - // mode de transport - if (options.graphs) { - // on ne permet pas de passer un tableau vide : on spécifie au moins un graph - if (Array.isArray(options.graphs) && options.graphs.length) { - for (var i = 0; i < options.graphs.length; i++) { - if (typeof options.graphs[i] === "string") { - if (options.graphs[i].toLowerCase() === "pieton") { - options.graphs[i] = "Pieton"; - } - if (options.graphs[i].toLowerCase() === "voiture") { - options.graphs[i] = "Voiture"; - } - } else { - logger.log("[ol.control.Route] ERROR : parameter 'graphs' elements should be of type 'string'"); - options.graphs[i] = null; - } - } - } else { - logger.warn("'graphs' parameter should be an array"); - options.graphs = null; - } - } - - // collapsed - if (options.collapsed === "true") { - options.collapsed = true; - } - if (options.collapsed === "false") { - options.collapsed = false; - } - } - - /** - * initialize component container (DOM) - * - * @param {Object} map - the map - * - * @returns {DOMElement} DOM element - * - * @private - */ - _initContainer (map) { - // get main container - var container = this._container; - - var picto = this._showRouteButton = this._createShowRoutePictoElement(); - container.appendChild(picto); - - var routePanel = this._panelRouteContainer = this._createRoutePanelElement(); - var routePanelDiv = this._createRoutePanelDivElement(); - routePanel.appendChild(routePanelDiv); - - // header form - var routeHeader = this._panelHeaderRouteContainer = this._createRoutePanelHeaderElement(); - routePanelDiv.appendChild(routeHeader); - - // form - var routeForm = this._formRouteContainer = this._createRoutePanelFormElement(); - - // form: menu des points - var points = this._createRoutePanelFormPointsElement(map); - for (var i = 0; i < points.length; i++) { - routeForm.appendChild(points[i]); - } - - // form: menu des modes - var choice = this._createRoutePanelFormModeChoiceElement(); - choice.appendChild(this._createRoutePanelFormModeChoiceTransportElement(this.options.graphs)); - choice.appendChild(this._createRoutePanelFormModeChoiceComputeElement()); - routeForm.appendChild(choice); - - // form: menu des exclusions - this._showRouteExclusionsElement = this._createShowRouteExclusionsPictoElement(); - routeForm.appendChild(this._showRouteExclusionsElement); - var exclusion = this._createRoutePanelFormExclusionsElement(); - exclusion.appendChild(this._createRoutePanelFormExclusionOptionsElement(this.options.exclusions)); - routeForm.appendChild(exclusion); - - var panelFooter = this._createRoutePanelFooterElement(); - routeForm.appendChild(panelFooter); - - var buttonReset = this._createRouteFormResetElement(); - panelFooter.appendChild(buttonReset); - - // form: bouton du calcul - var buttonSubmit = this._createRouteSubmitFormElement(); - panelFooter.appendChild(buttonSubmit); - - routePanelDiv.appendChild(routeForm); - - // results - var routeResults = this._resultsRouteContainer = this._createRoutePanelResultsElement(); - routePanelDiv.appendChild(routeResults); - - // waiting - var waiting = this._waitingContainer = this._createRouteWaitingElement(); - routePanelDiv.appendChild(waiting); - - container.appendChild(routePanel); - // hide autocomplete suggested locations on container click - if (container.addEventListener) { - container.addEventListener("click", (e) => this._hideRouteSuggestedLocations(e)); - } - - return container; - } - - // ################################################################### // - // ####################### init application ########################## // - // ################################################################### // - - /** - * this method is called by the constructor and initialize transport mode - * ("Voiture" ou "Pieton") - * - * @private - */ - _initTransport () { - // Mode de transport selectionné - this._currentTransport = "Voiture"; // par defaut - - // par defaut - var transport = this.options.graphs; - if (!transport || transport.length === 0) { - this.options.graphs = ["Voiture", "Pieton"]; - } - - // option - if (Array.isArray(transport) && transport.length) { - // FIXME pb si le 1er graphe n'est pas une ressource connue ! - if (transport[0] === "Voiture" || transport[0] === "Pieton") { - this._currentTransport = transport[0]; - } - } - - // TODO option sur le service - var serviceOptions = this.options.routeOptions; - if (serviceOptions.graph) { - this._currentTransport = serviceOptions.graph; - } - } - - /** - * this method is called by the constructor and initialize computation mode - * (fastest or shortest) - * - * @private - */ - _initComputation () { - // Mode de calcul selectionné - this._currentComputation = "fastest"; // par defaut - - // TODO option sur le service - var serviceOptions = this.options.routeOptions; - if (serviceOptions.routePreference) { - this._currentComputation = serviceOptions.routePreference; - } - } - - /** - * this method is called by the constructor and initialize exclusions - * - * @private - */ - _initExclusions () { - // Exclusions selectionnées : Tunnel, Toll et Bridge - this._currentExclusions = []; // par defaut - - // par defaut - var exclusion = this.options.exclusions; - if (!exclusion || (typeof exclusion === "object" && Object.keys(exclusion).length === 0)) { - this.options.exclusions = { - toll : false, - tunnel : false, - bridge : false - }; - } - - // option - if (exclusion && typeof exclusion === "object" && Object.keys(exclusion).length) { - for (var k in exclusion) { - if (exclusion.hasOwnProperty(k)) { - if (exclusion[k]) { - this._currentExclusions.push(k); - } - } - } - } - - // TODO option sur le service - var serviceOptions = this.options.routeOptions; - if (Array.isArray(serviceOptions.exclusions)) { - this._currentExclusions = serviceOptions.exclusions; - } - } - - /** - * this method is called by this.initialize() and initialize popup div - * (to display results information on route result click) - * - * @return {Object} element - DOM element for popup - * @private - */ - _initPopupDiv () { - var context = this; - var element = document.createElement("div"); - element.className = "gp-feature-info-div"; - var closer = document.createElement("input"); - closer.type = "button"; - closer.className = "gp-styling-button closer"; - // on closer click : remove popup - closer.onclick = function () { - if (context._popupOverlay != null) { - context._popupOverlay.setPosition(undefined); - } - return false; - }; - this._popupContent = document.createElement("div"); - this._popupContent.className = "gp-features-content-div"; - element.appendChild(this._popupContent); - element.appendChild(closer); - - return element; - } - - // ################################################################### // - // ############################## DOM ################################ // - // ################################################################### // - - /** - * Create List Points - * Overwrite RouteDOM method ! - * - * @param {Object} map - the map - * - * @returns {Array} List DOM element - * @private - */ - _createRoutePanelFormPointsElement (map) { - var points = []; - var count = 1; - - // point de depart - var start = new LocationSelector({ - apiKey : this.options.apiKey || null, - tag : { - id : count, - groupId : this._uid, - markerOpts : this.options.markersOpts["departure"], - label : "Départ", - display : true - }, - autocompleteOptions : this.options.autocompleteOptions || null - }); - start.setMap(map); - // on ajoute des écouteurs d'évènements (en plus de ceux de LocationSelector), - // pour prendre en compte les CSS spécifiques de GProuteForm - this._addFormPointsEventListeners(start); - points.push(start._container); - this._currentPoints.push(start); - - // points intermediaires - for (count = 2; count < 7; count++) { - var step = new LocationSelector({ - apiKey : this.options.apiKey || null, - tag : { - id : count, - groupId : this._uid, - label : "Etape", - markerOpts : this.options.markersOpts["stages"], - display : false, - removeOption : true - }, - autocompleteOptions : this.options.autocompleteOptions || null - }); - step.setMap(map); - this._addFormPointsEventListeners(step); - points.push(step._container); - this._currentPoints.push(step); - } - - // point d'arrivée - var end = new LocationSelector({ - apiKey : this.options.apiKey || null, - tag : { - id : count, - groupId : this._uid, - markerOpts : this.options.markersOpts["arrival"], - label : "Arrivée", - display : true, - addOption : true - }, - autocompleteOptions : this.options.autocompleteOptions || null - }); - end.setMap(map); - this._addFormPointsEventListeners(end); - points.push(end._container); - this._currentPoints.push(end); - - return points; - } - - /** - * Attach events listeners to route form points (locationSelector) - * - * @param {Object} formPoint - route form point (locationSelector) - * @private - */ - _addFormPointsEventListeners (formPoint) { - if (!formPoint) { - return; - } - - if (formPoint._buttonLabel.addEventListener) { - // display form on origin label click - formPoint._buttonLabel.addEventListener( - "click", - (e) => this.onRouteOriginLabelClick(e) - ); - // minimize form on input show pointer, and set map event listeners (see this.onRouteOriginPointerClick) - formPoint._inputShowPointer.addEventListener( - "click", - (e) => this.onRouteOriginPointerClick(e, formPoint) - ); - if (formPoint._removePointElement) { - formPoint._removePointElement.addEventListener( - "click", - (e) => { - logger.trace("click on _removePointElement", e); - // Moving up exclusions picto - // var exclusionsPictoTop = context._showRouteExclusionsElement.style.top; - // context._showRouteExclusionsElement.style.top = (parseInt(exclusionsPictoTop, 10) - 33).toString() + "px"; - } - ); - } - if (formPoint._addPointElement) { - formPoint._addPointElement.addEventListener( - "click", - (e) => { - logger.trace("click on _addPointElement", e); - // Moving down exclusions picto - // var exclusionsPictoTop = context._showRouteExclusionsElement.style.top; - // context._showRouteExclusionsElement.style.top = (parseInt(exclusionsPictoTop, 10) + 33).toString() + "px"; - } - ); - } - } else if (formPoint._buttonLabel.attachEvent) { - // attachEvent: Internet explorer event listeners management - formPoint._buttonLabel.attachEvent( - "onclick", - (e) => this.onRouteOriginLabelClick(e) - ); - formPoint._inputShowPointer.attachEvent( - "onclick", - (e) => this.onRouteOriginPointerClick(e, formPoint) - ); - if (formPoint._removePointElement) { - formPoint._removePointElement.attachEvent( - "onclick", - (e) => { - // Moving up exclusions picto - // var exclusionsPictoTop = context._showRouteExclusionsElement.style.top; - // context._showRouteExclusionsElement.style.top = (parseInt(exclusionsPictoTop, 10) - 33).toString() + "px"; - } - ); - } - if (formPoint._addPointElement) { - formPoint._addPointElement.attachEvent( - "onclick", - (e) => { - // Moving down exclusions picto - // var exclusionsPictoTop = context._showRouteExclusionsElement.style.top; - // context._showRouteExclusionsElement.style.top = (parseInt(exclusionsPictoTop, 10) + 33).toString() + "px"; - } - ); - } - } - } - - // ################################################################### // - // ####################### handlers events to dom #################### // - // ################################################################### // - - /** - * this method is called by event 'submit' on 'GProuteForm' tag form - * (cf. this._createRoutePanelFormElement), and it displays the results. - * - * @param {Object} options - options - * @private - */ - onRouteComputationSubmit (options) { - logger.log("onRouteComputationSubmit", options); - - // FIXME on lance une requête en EPSG:4326, les coordonnées - // doivent donc être du type cad en lat/lon. - // or, BUG du service du calcul d'itineraire car les - // coordonnées envoyées doivent être en lon/lat avec une SRS en EPSG:4326 !? - // sinon, ça plante... - - // Liste des points - var points = this._currentPoints; - - // - point de depart (info: points[0].getCoordinate est du type [lon, lat], en EPSG:4326) - var start; - if (points[0] && points[0].getCoordinate) { - var startCoordinate = points[0].getCoordinate(); - start = { - x : startCoordinate[0], - y : startCoordinate[1] - }; - logger.log("start", start); - } - - // - point d'arrivée - var end; - var endPoint = points[points.length - 1]; - if (endPoint && endPoint.getCoordinate) { - var endCoordinate = endPoint.getCoordinate(); - end = { - x : endCoordinate[0], - y : endCoordinate[1] - }; - logger.log("end", end); - } - - // - les étapes - var step = []; - for (var i = 1; i < points.length - 1; i++) { - if (points[i] && points[i].getCoordinate) { - var iCoordinate = points[i].getCoordinate(); - if (iCoordinate) { - var coordinate = { - x : iCoordinate[0], - y : iCoordinate[1] - }; - logger.log("step", coordinate); - step.push(coordinate); - } - } - } - - // valeurs selectionnées - this._currentTransport = options.transport; - this._currentComputation = options.computation; - this._currentExclusions = options.exclusions; - - // on recupere les éventuelles options du service passées par l'utilisateur - var routeOptions = this.options.routeOptions; - - // OVERLOAD : la resource bd-topo-osrm ne gère pas le calcul piéton en mode fastest - // dans ce cas, on utilise valhalla dans le cas d'une utilisation par défaut du widget - // sans paramétrage de resource explicitement demandé - var routeResource; - if (!routeOptions.resource) { - if (this._currentComputation === "fastest" && this._currentTransport === "Pieton") { - routeResource = "bdtopo-valhalla"; - } - } else { - routeResource = routeOptions.resource; - } - - // gestion du protocole et du timeout - // le timeout est indispensable sur le protocole JSONP. - var _protocol = routeOptions.protocol || "XHR"; - var _timeout = routeOptions.timeOut || 0; - if (_protocol === "JSONP" && _timeout === 0) { - // FIXME le timeout est obligatoire pour ce type de protocole... - _timeout = 15000; - } - - // gestion des callback - var bOnFailure = !!(routeOptions.onFailure !== null && typeof routeOptions.onFailure === "function"); // cast variable to boolean - var bOnSuccess = !!(routeOptions.onSuccess !== null && typeof routeOptions.onSuccess === "function"); - - // on met en place l'affichage des resultats dans la fenetre de resultats. - var context = this; - this._requestRouting({ - startPoint : start, - endPoint : end, - viaPoints : step, - graph : routeOptions.graph || this._currentTransport, - routePreference : routeOptions.routePreference || this._currentComputation, - exclusions : routeOptions.exclusions || this._currentExclusions, - geometryInInstructions : true, - distanceUnit : "m", - timeOut : _timeout, - protocol : _protocol, - resource : routeResource, - // callback onSuccess - onSuccess : function (results) { - logger.log(results); - if (results) { - context._fillRouteResultsDetails(results); - } - if (bOnSuccess) { - routeOptions.onSuccess.call(context, results); - } - }, - // callback onFailure - onFailure : function (error) { - context._hideWaitingContainer(); - context._clearRouteResultsDetails(); - logger.log(error.message); - if (bOnFailure) { - routeOptions.onFailure.call(context, error); - } - } - }); - } - - /** - * this method is called by event 'click' on 'GPlocationOriginLabel' label - * and set 'GProuteForm' CSS class to "" (normal) - * - * @param {Object} routeControl - context : route Control (this) - * @private - */ - onRouteOriginLabelClick () { - this._formRouteContainer.className = "gpf-panel__content fr-modal__content"; - // on désactive l'écouteur d'événements sur la carte (pour ne pas placer un marker au clic) - // map.un( - // "click", - // () => { - // // on ne rétablit pas le mode "normal" si on est dans le panel des résultats (où className = "GProuteComponentHidden") - // if (this._formRouteContainer.className === "GProuteFormMini") { - // this._formRouteContainer.className = "gpf-panel__content fr-modal__content"; - // } - // } - // ); - olObservableUnByKey(this.listenerKey); - this.dispatchEvent("route:drawend"); - } - - /** - * this method is called by event 'click' on 'GPlocationOriginPointerImg' label - * and display or minimize 'GProuteForm', using CSS class ("GProuteFormMini" or "") - * - * @param {Object} e - context : route Control (equivalent to this) - * @param {Object} locationSelector - context : locationSelector input (one of this._currentPoints) - * @private - */ - onRouteOriginPointerClick (e, locationSelector) { - var map = this.getMap(); - if (locationSelector._inputShowPointerContainer.checked) { - // au click sur l'input pour pointer sur la carte: on minimise le formulaire - this._formRouteContainer.className = "GProuteFormMini gpf-panel__content fr-modal__content"; - // et au clic sur la carte, on réaffichera le formulaire "normal" - this.listenerKey = map.on( - "click", - () => { - // on ne rétablit pas le mode "normal" si on est dans le panel des résultats (où className = "GProuteComponentHidden") - if (this._formRouteContainer.className === "GProuteFormMini gpf-panel__content fr-modal__content") { - this._formRouteContainer.className = "gpf-panel__content fr-modal__content"; - } - olObservableUnByKey(this.listenerKey); - /** - * event triggered at the end of drawing input - * - * @event route:drawend - */ - this.dispatchEvent("route:drawend"); - } - ); - /** - * event triggered at the start of drawing input - * - * @event route:drawstart - */ - this.dispatchEvent("route:drawstart"); - } else { - // si on déselectionne le pointer, on rétablit le formulaire en mode normal - this._formRouteContainer.className = ""; - // et on enlève l'écouteur d'évènement sur la carte - // map.un( - // "click", - // () => { - // // on ne rétablit pas le mode "normal" si on est dans le panel des résultats (où className = "GProuteComponentHidden") - // if (this._formRouteContainer.className === "GProuteFormMini") { - // this._formRouteContainer.className = "gpf-panel__content fr-modal__content"; - // } - // } - // ); - olObservableUnByKey(this.listenerKey); - this.dispatchEvent("route:drawend"); - } - } - - /** - * this method is called by event 'click' on 'GPshowRoutePicto' - * tag label (cf. this._createShowRoutePictoElement), - * and it cleans all value of input. - * - * @param {Object} e - HTMLElement - * @private - */ - onShowRoutePanelClick (e) { - var map = this.getMap(); - // on supprime toutes les interactions - Interactions.unset(map); - // clean ! - if (!this._geojsonSections && !this._waiting) { - this._clear(); - } - var opened = this._showRouteButton.ariaPressed; - this.collapsed = !(opened === "true"); - // on génère nous même l'evenement OpenLayers de changement de pté - // (utiliser ol.control.Route.on("change:collapsed", function ) pour s'abonner à cet évènement) - this.dispatchEvent("change:collapsed"); - } - - /** - * this method is called by event 'change' on 'GProuteComputationSelect' tag select - * (cf. this._createRoutePanelFormModeChoiceComputeElement). - * this value is saved as a parameter for the service route. - * - * @param {Object} e - HTMLElement - * @private - */ - onRouteModeComputationChange (e) { - var idx = e.target.selectedIndex; - var value = e.target.options[idx].value; - - if (!value) { - return; - } - - logger.log(value); - this._currentComputation = value; - } - - /** - * this method is called by event 'change' on 'GProuteResultsComputationSelect' tag select - * (cf. this._createRouteResultsElement). - * this value is saved as a parameter for the service route, - * and this launches the route request ! - * - * @param {Object} e - HTMLElement - * @private - */ - onRouteModeComputationChangeAndRun (e) { - // event choice computation - this.onRouteModeComputationChange(e); - - // clean avant un nouveau calcul ! - this._clearRouteResultsDetails(); - this._clearRouteResultsGeometry(); - this._clearRouteResultsFeatureGeometry(); - - // submit request - this.onRouteComputationSubmit({ - computation : this._currentComputation, - transport : this._currentTransport, - exclusions : this._currentExclusions - }); - } - - /** - * this method is called by event 'change' on 'GProuteTransportCar' or 'GProuteTransportPedestrian' tag input - * (cf. this._createRoutePanelFormModeChoiceTransportElement). - * this value is saved as a parameter for the service route. - * - * @param {Object} e - HTMLElement - * @private - */ - onRouteModeTransportChange (e) { - var value = e.target.value; - if (!value) { - return; - } - this._currentTransport = value; - } - - /** - * TODO this method is called by event 'click' on 'GPshowRouteExclusionsPicto' tag input - * (cf. this._createShowRouteExclusionsPictoElement), and it displays the panel options of exclusions. - * - * @param {Object} e - HTMLElement - * @private - */ - onShowRouteExclusionsClick (e) { - logger.log("onShowRouteExclusionsClick", e); - // FIXME not use ?! - } - - /** - * this method is called by event 'change' on 'GProuteExclusionsToll' - * or 'GProuteExclusionsTunnel' or 'GProuteExclusionsBridge' tag input - * (cf. this._createRoutePanelFormExclusionOptionsElement). - * this value is saved as a parameter for the service route. - * - * @param {Object} e - HTMLElement - * @private - */ - onRouteExclusionsChange (e) { - var value = e.target.value; - var checked = e.target.checked; - - if (!value || (typeof value !== "string")) { - return; - } - value = value.toLowerCase(); - - var bFound = false; - var iFound = null; - for (var i = 0; i < this._currentExclusions.length; i++) { - if (this._currentExclusions[i] === value) { - iFound = i; - bFound = true; - } - } - // on l'ajoute si la valeur n'existe pas et est déselectionnée - // info : checked = passage autorisé (ce n'est pas une exclusion) - if (!bFound && !checked) { - this._currentExclusions.push(value); - } - // on la retire si la valeur existe et est selectionnée - if (bFound && checked) { - this._currentExclusions.splice(iFound, 1); - } - } - - /** - * this method is called by event 'click' on 'GProuteReset' - * tag label (cf. this._createRouteFormResetElement), - * and it cleans all route input options and results. - * - * @private - */ - onRouteResetClick () { - // clear points - var currentPoints = this._currentPoints; - for (var i = 0; i < currentPoints.length; i++) { - currentPoints[i].clear(); - } - - // clear results - this._clear(); - - this._clearRouteInputOptions(); - } - - /** - * this method is called by event 'click' on 'GProuteSubmit' - * tag label (cf. this._createRouteSubmitFormElement), - * and it cleans the route geometry. - * - * @private - */ - onShowRouteResultsNewClick () { - // clean avant un nouveau calcul ! - this._clearRouteResultsDetails(); - this._clearRouteResultsGeometry(); - this._clearRouteResultsFeatureGeometry(); - } - - /** - * this method is called by event 'mouseover' on 'GProuteResultsDetailsInstruction_' - * tag label (cf. this._addRouteResultsDetailsElement), - * and it makes a style on feature route. - * - * @param {Object} e - HTMLElement - * @private - */ - onRouteResultsDetailsMouseOver (e) { - // récupération de l'id de l'instruction survolée - var tagid = e.target.id; // ex GProuteResultsDetailsInstruction_125 - var idx = tagid.substring(tagid.indexOf("_") + 1); // ex. 125 - - // on passe le texte en gras - if (e.target.classList) { - e.target.classList.add("GProuteResultsDetailsInstructionHighlight"); - } - - if (!this._geojsonSections) { - return; - } - - // on récupère l'entité correspondante à l'instruction survolée - var f = this._geojsonSections.getSource().getFeatureById(parseInt(idx, 10)); - // et on lui affecte un nouveau style - f.setStyle(this._selectedFeatureStyle); - } - - /** - * this method is called by event 'mouseout' on 'GProuteResultsDetailsInstruction_' - * tag label (cf. this._addRouteResultsDetailsElement), - * and it deletes a style on feature route. - * - * @param {Object} e - HTMLElement - * @private - */ - onRouteResultsDetailsMouseOut (e) { - // récupération de l'id de l'instruction survolée - var tagid = e.target.id; // ex GProuteResultsDetailsInstruction_125 - var idx = tagid.substring(tagid.indexOf("_") + 1); // ex. 125 - - // on repasse le texte en style normal - if (e.target.classList) { - e.target.classList.remove("GProuteResultsDetailsInstructionHighlight"); - } - - if (!this._geojsonSections) { - return; - } - // on récupère l'entité correspondante à l'instruction qui était survolée - var f = this._geojsonSections.getSource().getFeatureById(parseInt(idx, 10)); - // et on lui réaffecte un style normal - f.setStyle(null); - } - - // ################################################################### // - // ########################### Routing ############################### // - // ############## (methods to request and results) ################### // - - /** - * this method is called by this.onRouteComputationSubmit() - * and executes a request to the service. - * - * @param {Object} options - route service request options - * @param {Function} options.onSuccess - callback - * @param {Function} options.onFailure - callback - * @private - */ - _requestRouting (options) { - // on ne fait pas de requête si on n'a pas renseigné de parametres ! - if (!options || (typeof options === "object" && Object.keys(options).length === 0)) { - return; - } - - // on ne fait pas de requête si - // - la parametre 'startPoint' est vide ! - if (!options.startPoint) { - return; - } - // - la parametre 'endPoint' est vide ! - if (!options.endPoint) { - return; - } - - // cas où la clef API n'est pas renseignée dans les options du service, - // on utilise celle renseignée au niveau du controle (calcul par défaut) - options.apiKey = this.options.routeOptions.apiKey || this.options.apiKey; - - // si l'utilisateur a spécifié le paramètre ssl au niveau du control, on s'en sert - // true par défaut (https) - if (typeof options.ssl !== "boolean") { - if (typeof this.options.ssl === "boolean") { - options.ssl = this.options.ssl; - } else { - options.ssl = true; - } - } - logger.log(options); - - // mise en place de la patience - this._displayWaitingContainer(); - - // appel du service de calcul d'itinéraires - Gp.Services.route(options); - } - - /** - * this method is called by this.onRouteComputationSubmit() (in case of route computation success) - * and fills the container of the route instructions list, distance and time - * information, also, constructs the geometry route. - * - * @param {Object} results - results of the route calculation - * - * @private - */ - _fillRouteResultsDetails (results) { - // 1. Affichage des distances et durées - var distance = results.totalDistance; - var duration = results.totalTime; - // Détails avec simplifications des troncons - var instructions = this._simplifiedInstructions(results.routeInstructions); - // var instructions = results.routeInstructions; - - if (instructions) { - this._fillRouteResultsDetailsContainer(distance, duration, instructions); - } - - // 2. Affichage des géométries - // Geometrie simplifiée (si renseignée) - var geometry = results.routeGeometry; - if (geometry) { - this._fillRouteResultsDetailsGeometry(geometry, this._defaultFeatureStyle); - } - - // Geometries des tronçon (si renseignée) - if (instructions && instructions[0].geometry) { - this._fillRouteResultsDetailsFeatureGeometry(instructions, this._defaultFeatureStyle); - } - - // 3. Zoom sur l'emprise de l'itinéraire (si spécifiée) - var bbox = results.bbox; - if (bbox) { - var map = this.getMap(); - var bounds = [bbox.left, bbox.bottom, bbox.right, bbox.top]; - // reprojection dans la projection de la carte (bbox initialement en EPSG:4326) - var mapProj = map.getView().getProjection().getCode(); - if (mapProj !== "EPSG:4326") { - bounds = olTransformExtentProj(bounds, "EPSG:4326", mapProj); - } - map.getView().fit(bounds, map.getSize()); - } - - // sauvegarde de l'etat des resultats - this._currentRouteInformations = results; - - /** - * event triggered when the compute is finished - * - * @event route:compute - * @property {Object} type - event - * @property {Object} target - instance Route - * @example - * Route.on("route:compute", function (e) { - * console.log(e.target.getData()); - * }) - */ - this.dispatchEvent({ - type : "route:compute" - }); - - // mise à jour du controle ! - this._formRouteContainer.className = "GPelementHidden gpf-hidden gpf-panel__content fr-modal__content"; - this._hideWaitingContainer(); - this._resultsRouteContainer.className = ""; - } - - /** - * this method is called by this._fillRouteResultsDetails() - * and fills the container of the route instructions list, distance and time - * information. - * - * @param {Number} distance - distance - * @param {Number} duration - duration - * @param {Object[]} instructions - list of instructions - * - * @private - */ - _fillRouteResultsDetailsContainer (distance, duration, instructions) { - // Distance et Durée - this._resultsRouteValuesContainer = this._addRouteResultsValuesElement(distance, duration, this._convertSecondsToTime); - - // Détails - this._resultsRouteDetailsContainer = this._addRouteResultsDetailsElement(instructions, this._convertSecondsToTime); - } - - /** - * this method is called by this._fillRouteResultsDetails() - * and constructs the geometry route. - * - * @param {Object} geometry - geoJSON object for route geometry - * @param {Object} style - route ol.style.Style object - * @private - */ - _fillRouteResultsDetailsGeometry (geometry, style) { - this._clearRouteResultsGeometry(); - - var map = this.getMap(); - - if (!geometry) { - return; - } - - // création de l'objet geoJSON - var geojsonObject = { - type : "FeatureCollection", - features : [ - { - type : "Feature", - crs : { - type : "name", - properties : { - name : "EPSG:4326" - } - }, - geometry : geometry - } - ] - }; - - var geojsonformat = new GeoJSONExtended({ - defaultDataProjection : "EPSG:4326", - defaultStyle : style - - }); - var features = geojsonformat.readFeatures( - geojsonObject, { - dataProjection : "EPSG:4326", - featureProjection : "EPSG:3857" - } - ); - - // ajout de la géométrie comme nouvelle couche vecteur à la carte - this._geojsonRoute = new VectorLayer({ - source : new VectorSource({ - features : features - }), - style : style - }); - map.addLayer(this._geojsonRoute); - } - - /** - * this method is called by this._fillRouteResultsDetails() - * and constructs the geometries street with informations. - * - * @param {Array} instructions - route instructions list (containing geoJSON geometry) - * @param {Object} style - route ol.style.Style object - * @private - */ - _fillRouteResultsDetailsFeatureGeometry (instructions, style) { - this._clearRouteResultsFeatureGeometry(); - - var map = this.getMap(); - - // 1. création de l'objet geoJSON - this._geojsonObject = { - type : "FeatureCollection", - crs : { - type : "name", - properties : { - name : "EPSG:4326" - } - }, - features : [] - }; - - // 2. Remplissage de l'objet geoJSON : ajout des géométries de chaque instruction - for (var i = 0; i < instructions.length; i++) { - var o = instructions[i]; - var id = i + 1; - - var coords = o.geometry.coordinates; - for (var j = 0; j < coords.length; j++) { - // remarque : les coordonnées sont au format string, à convertir en nombres - if (typeof coords[j][0] === "string") { - coords[j][0] = parseFloat(coords[j][0]); - coords[j][1] = parseFloat(coords[j][1]); - } - } - - this._geojsonObject.features.push({ - type : "Feature", - geometry : o.geometry, - properties : { - popupContent : "(" + id + ") distance : " + this._convertDistance(o.distance) + - " / temps : " + this._convertSecondsToTime(o.duration) - }, - id : id - }); - } - - // Ajout du point de depart du tracé - this._geojsonObject.features.push({ - type : "Feature", - geometry : { - type : "Point", - coordinates : this._currentPoints[0].getCoordinate() - }, - properties : { - description : "Point de départ", - "marker-symbol" : this.options.markersOpts.departure.url - } - }); - - // Ajout des points d'étapes - for (var k = 1; k < this._currentPoints.length - 1; k++) { - if (this._currentPoints[k] && this._currentPoints[k].getCoordinate) { - var coordinates = this._currentPoints[k].getCoordinate(); - if (coordinates) { - this._geojsonObject.features.push({ - type : "Feature", - geometry : { - type : "Point", - coordinates : coordinates - }, - properties : { - description : "Point d'étape", - "marker-symbol" : this.options.markersOpts.stages.url - } - }); - } - } - } - - // Ajout du point d'arrivée du tracé - this._geojsonObject.features.push({ - type : "Feature", - geometry : { - type : "Point", - coordinates : this._currentPoints[this._currentPoints.length - 1].getCoordinate() - }, - properties : { - description : "Point d'arrivée", - "marker-symbol" : this.options.markersOpts.arrival.url - } - }); - - // Création du format GeoJSON, avec reprojection des géométries - var geojsonformat = new GeoJSONExtended({ - defaultDataProjection : "EPSG:4326", - defaultStyle : style - }); - var mapProj = this.getMap().getView().getProjection().getCode(); - var features = geojsonformat.readFeatures( - this._geojsonObject, { - dataProjection : "EPSG:4326", - featureProjection : mapProj - } - ); - - // 3. Ajout du tracé de l'itinéraire (geoJSON) comme nouvelle couche vecteur à la carte - this._geojsonSections = new VectorLayer({ - source : new VectorSource({ - features : features - }), - style : style, - opacity : 0.9 - }); - - var graph; - if (this._currentTransport === "Pieton") { - graph = "piéton"; - this._geojsonSections.gpResultLayerId = "Pieton$OGC:OPENLS;Itineraire"; - } else { - graph = "voiture"; - this._geojsonSections.gpResultLayerId = "Voiture$OGC:OPENLS;Itineraire"; - } - // ajout à la carte - map.addLayer(this._geojsonSections); - - // 4. Si un layer switcher est présent dans la carte, on lui affecte des informations pour cette couche - map.getControls().forEach( - (control) => { - if (control instanceof LayerSwitcher) { - // un layer switcher est présent dans la carte - var layerId = this._geojsonSections.gpLayerId; - // on n'ajoute des informations que s'il n'y en a pas déjà (si le titre est le numéro par défaut) - if (control._layers[layerId].title === layerId) { - control.addLayer( - this._geojsonSections, { - title : this.options.layerDescription.title + " (" + graph + ")", - description : this.options.layerDescription.description - } - ); - } - } - }, - this - ); - - // 5. Ajout de popups aux troncons - // Création de l'interaction : survol des features (=troncons de l'itinéraire) - this._resultsHoverInteraction = new SelectInteraction({ - condition : eventPointerMove, - layers : [this._geojsonSections], - style : this._selectedFeatureStyle - }); - this._resultsHoverInteraction.on( - "select", - (e) => this._onResultsFeatureMouseOver(e) - ); - map.addInteraction(this._resultsHoverInteraction); - - // Création de l'interaction : selection des features (=troncons de l'itinéraire) - this._resultsSelectInteraction = new SelectInteraction({ - layers : [this._geojsonSections], - style : this._selectedFeatureStyle - }); - this._resultsSelectInteraction.on( - "select", - (e) => this._onResultsFeatureSelect(e) - ); - map.addInteraction(this._resultsSelectInteraction); - } - - /** - * this method is called on route features hover - * and highlight instruction label - * - * @param {Object} e - event - * - * @private - */ - _onResultsFeatureMouseOver (e) { - if (e.selected.length !== 0) { - // si on a bien survolé un tronçon, on surligne l'instruction correspondante - var f = e.selected[0]; - var selectedInstruction = document.getElementById("GProuteResultsDetailsInstruction_" + f.getId() + "-" + this._uid); - if (selectedInstruction && selectedInstruction.classList) { - selectedInstruction.classList.add("GProuteResultsDetailsInstructionHighlight"); - } - } - - // si on déselectionne un tronçon (mouseout), on rétablit un style normal pour l'instruction - if (e.deselected.length !== 0) { - var deselectedFeature = e.deselected[0]; - // on repasse l'instruction correspondante en normal - var deSelectedInstruction = document.getElementById("GProuteResultsDetailsInstruction_" + deselectedFeature.getId() + "-" + this._uid); - if (deSelectedInstruction && deSelectedInstruction.classList) { - deSelectedInstruction.classList.remove("GProuteResultsDetailsInstructionHighlight"); - } - } - } - - /** - * this method is called on route features select - * and set a popup with feature information - * - * @param {Object} e - on select event - * @private - */ - _onResultsFeatureSelect (e) { - var map = this.getMap(); - if (e.selected.length !== 0) { - // si on a sélectionné un troncon, on lui ajoute une popup - var f = e.selected[0]; - this._popupContent.innerHTML = f.getProperties().popupContent; - - if (!this._popupOverlay) { - // ajout de la popup a la carte comme un overlay - this._popupOverlay = new Overlay({ - element : this._popupDiv, - positioning : "bottom-center", - position : e.mapBrowserEvent.coordinate - }); - map.addOverlay(this._popupOverlay); - } else { - // si l'overlay est déjà créé, on modifie juste sa position - this._popupOverlay.setPosition(e.mapBrowserEvent.coordinate); - } - } else { - // si aucun troncon n'est sélectionné (click à côté du tracé), - // on fait disparaitre la popup si elle existe - if (this._popupOverlay != null) { - this._popupOverlay.setPosition(undefined); - } - } - } - - // ################################################################### // - // ############################# Clean ############################### // - // ################################################################### // - - /** - * this method is called by this.onShowRoutePanelClick() - * and it clears all elements (reinit). - * - * @private - */ - _clear () { - this._currentTransport = null; - this._currentExclusions = []; - this._currentComputation = null; - - // les resultats - this._clearRouteResultsDetails(); - // la geometrie - this._clearRouteResultsGeometry(); - this._clearRouteResultsFeatureGeometry(); - // les points - for (var i = 0; i < this._currentPoints.length; i++) { - this._currentPoints[i].clear(); - } - // suppression des points intermédiaires - this._removeRouteStepLocations(); - } - - /** - * this method is called by this.onRouteResetClick() - * and it clears all options inputs (reinit). - * - * @private - */ - _clearRouteInputOptions () { - // reinit options to default - this._initTransport(); - this._initComputation(); - this._initExclusions(); - - // set transport mode to default - var transportdiv; - if (this._currentTransport === "Pieton") { - transportdiv = document.getElementById("GProuteTransportPedestrian-" + this._uid); - if (transportdiv) { - transportdiv.checked = "true"; - } - } else { - transportdiv = document.getElementById("GProuteTransportCar-" + this._uid); - if (transportdiv) { - transportdiv.checked = "true"; - } - } - - // set computation mode to default - var computationdiv = document.getElementById("GProuteComputationSelect-" + this._uid); - if (computationdiv) { - computationdiv.value = this._currentComputation; - } - - // set exclusions to default - var tollInput = document.getElementById("GProuteExclusionsToll-" + this._uid); - if (tollInput) { - if (this._currentExclusions.indexOf("toll") !== -1) { - tollInput.checked = false; - } else { - tollInput.checked = true; - } - } - - var tunnelInput = document.getElementById("GProuteExclusionsTunnel-" + this._uid); - if (tunnelInput) { - if (this._currentExclusions.indexOf("tunnel") !== -1) { - tunnelInput.checked = false; - } else { - tunnelInput.checked = true; - } - } - - var bridgeInput = document.getElementById("GProuteExclusionsBridge-" + this._uid); - if (bridgeInput) { - if (this._currentExclusions.indexOf("bridge") !== -1) { - bridgeInput.checked = false; - } else { - bridgeInput.checked = true; - } - } - } - - /** - * this method is called by this._clear() - * and it removes step location inputs (excepted departure and arrival) - * - * @private - */ - _removeRouteStepLocations () { - var points = document.querySelectorAll("div[id^=\"GPlocationPoint\"]"); - if (points.length !== 0) { - var goodPoints = []; - for (var k = 0; k < points.length; k++) { - if (points[k].id.indexOf(this._uid) !== -1) { - goodPoints.push(points[k]); - } - } - // on boucle sur les points intermédiaires - for (var i = 1; i < (goodPoints.length - 1); i++) { - // on va regarder les classes associées - var classList = goodPoints[i].classList; - if (classList.length !== 0) { - for (var j = 0; j < classList.length; j++) { - if (classList[j] === "GPlocationStageFlexInput") { - // si l'élément est visible, on le supprime en simulant un clic sur la croix (x) - document.getElementById(this._addUID("GPlocationStageRemove_" + (i + 1))).click(); - } - } - } - } - } - } - - /** - * this method is called by this.onRouteComputationSubmit() (in case of failure) - * and it clears all route instructions. - * - * @private - */ - _clearRouteResultsDetails () { - this._currentRouteInformations = null; - - // doit on nettoyer le container "GProuteResultsDetails" ? - // il sera de toute façon écrasé par la prochaine requête... - if (this._resultsRouteDetailsContainer) { - var detailsDiv = this._resultsRouteDetailsContainer; - if (detailsDiv.childElementCount) { - while (detailsDiv.firstChild) { - detailsDiv.removeChild(detailsDiv.firstChild); - } - } - } - - if (this._resultsRouteValuesContainer) { - var valuesDiv = this._resultsRouteValuesContainer; - if (valuesDiv.childElementCount) { - while (valuesDiv.firstChild) { - valuesDiv.removeChild(valuesDiv.firstChild); - } - } - } - } - - /** - * this method is called by this.onRouteComputationSubmit() - * and it clears all route geometries. - * - * @private - */ - _clearRouteResultsGeometry () { - var map = this.getMap(); - - if (this._geojsonRoute != null) { - map.removeLayer(this._geojsonRoute); - this._geojsonRoute = null; - } - } - - /** - * this method is called by this.onRouteComputationSubmit() - * and it clears all route geometries. - * - * @private - */ - _clearRouteResultsFeatureGeometry () { - var map = this.getMap(); - - // on retire la couche itinéraire de la carte - if (this._geojsonSections != null) { - map.removeLayer(this._geojsonSections); - this._geojsonSections = null; - this._geojsonObject = null; - } - // on retire l'overlay de la popup de la carte - if (this._popupOverlay != null) { - map.removeOverlay(this._popupOverlay); - this._popupOverlay = null; - } - // et les interactions liées à cette couche - if (this._resultsSelectInteraction != null) { - map.removeInteraction(this._resultsSelectInteraction); - this._resultsSelectInteraction = null; - } - if (this._resultsHoverInteraction != null) { - map.removeInteraction(this._resultsHoverInteraction); - this._resultsHoverInteraction = null; - } - } - - /** - * this method is called by event 'click' on control main container - * and hide suggested Locations (unless target is an autocomplete input) - * - * @param {Object} e - event - * - * @private - */ - _hideRouteSuggestedLocations (e) { - // si on clique sur un input de saisie de locationSelector - if (e.target && e.target.id && e.target.id.indexOf("GPlocationOrigin_") !== -1) { - // on récupère le numéro du point - var pointId = parseInt(e.target.id.split("_")[1][0], 10) - 1; - // et on cache les autres résultats d'autocomplétion (sauf celui sur lequel on clique) - for (var j = 0; j < this._currentPoints.length; j++) { - if (j !== parseInt(pointId, 10)) { - this._currentPoints[j]._hideSuggestedLocation(); - } - } - } else { - // si on clique ailleurs dans le DOM du control, on cache tous les résultats d'autocomplétion - for (var i = 0; i < this._currentPoints.length; i++) { - this._currentPoints[i]._hideSuggestedLocation(); - } - } - } - - /** - * this method displays waiting container and sets a timeout - * - * @private - */ - _displayWaitingContainer () { - this._waitingContainer.className = "GPwaitingContainer GPwaitingContainerVisible gpf-waiting gpf-waiting--visible"; - this._waiting = true; - - // mise en place d'un timeout pour réinitialiser le panel (cacher la patience) - // si on est toujours en attente (si la requête est bloquée par exemple) - // ceci est vrai, uniquement sur le protocole JSONP ! - var opts = this.options.routeOptions; - if (opts && opts.timeOut) { - if (this._timer) { - clearTimeout(this._timer); - this._timer = null; - } - var context = this; - this._timer = setTimeout(function () { - if (context._waiting === true) { - context._hideWaitingContainer(); - } else { - if (context._timer) { - clearTimeout(context._timer); - } - } - }, 16000); - } - } - - /** - * this method hides waiting container and clears timeout - * - * @private - */ - _hideWaitingContainer () { - if (this._waiting) { - this._waitingContainer.className = "GPwaitingContainer GPwaitingContainerHidden gpf-waiting gpf-waiting--hidden"; - this._waiting = false; - var opts = this.options.routeOptions; - if (opts && opts.timeOut) { - clearTimeout(this._timer); - this._timer = null; - } - } - } - - // ################################################################### // - // ########################## Geometry ############################### // - // ################################################################### // - - /** - * simplified instructions - * - * @param {Object[]} instructions - list of instructions - * - * @returns {Object[]} simplified instructions - * - * @private - */ - _simplifiedInstructions (instructions) { - var newInstructions = []; - - // cas où... - var current = instructions[0]; - if (instructions.length === 1) { - newInstructions.push(current); - } - - for (var i = 1; i < instructions.length; i++) { - var o = instructions[i]; - if (o.instruction === current.instruction) { - current.distance = (parseFloat(o.distance) + parseFloat(current.distance)).toString(); - current.duration = (parseFloat(o.duration) + parseFloat(current.duration)).toString(); - for (var j = 1; j < o.geometry.coordinates.length; j++) { - current.geometry.coordinates.push(o.geometry.coordinates[j]); - } - } else { - newInstructions.push(current); - current = o; - // last - if (i === instructions.length - 1) { - newInstructions.push(o); - current = null; - } - } - } - logger.log(newInstructions); - return newInstructions; - } - - // ################################################################### // - // ################# Utils for Distance/Duration ##################### // - // ################################################################### // - - /** - * convert seconds to time : HH:MM:SS - * - * @param {Number} duration - duration in seconds - * - * @returns {String} time in hours/minutes/seconds - * - * @private - */ - _convertSecondsToTime (duration) { - var time = ""; - - duration = Math.round(duration); - var hours = Math.floor(duration / (60 * 60)); - - var divisor4minutes = duration % (60 * 60); - var minutes = Math.floor(divisor4minutes / 60); - // if (!minutes) { - // minutes = "00"; - // } - - // var divisor4seconds = divisor4minutes % 60; - // var seconds = Math.ceil(divisor4seconds); - // if (!seconds) { - // seconds = "00"; - // } - - if (hours) { - time = hours + "h "; - } - time += minutes + " min"; - return time; - } - - /** - * convert distance in meters or kilometers - * - * @param {Number} distance - distance in meters - * - * @returns {String} distance in km - * - * @private - */ - _convertDistance (distance) { - var d = ""; - - var distanceKm = parseInt(distance / 1000, 10); - if (!distanceKm) { - d = parseInt(distance, 10) + " m"; // arrondi ! - } else { - d = distanceKm + " km"; - } - - return d; - } - -}; - -// on récupère les méthodes de la classe commune ReverseGeocodingDOM -Object.assign(Route.prototype, RouteDOM); - -export default Route; - -// Expose Route as ol.control.Route (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.Route = Route; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/RouteDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/RouteDOM.d.ts deleted file mode 100644 index ccc9a7a7e..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/RouteDOM.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -export default RouteDOM; -declare namespace RouteDOM { - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createShowRoutePictoElement(): DOMElement; - function _createRoutePanelElement(): DOMElement; - function _createRoutePanelDivElement(): HTMLDivElement; - function _createRoutePanelHeaderElement(): DOMElement; - function _createRoutePanelFooterElement(): DOMElement; - function _createRoutePanelFormElement(): DOMElement; - function _createRoutePanelResultsElement(): DOMElement; - function _createRouteWaitingElement(): DOMElement; - function _createRouteResultsStagesElement(): DOMElement; - function _addRouteResultsStagesValuesElement(points: DOMElement): void; - function _createRouteResultsElement(): DOMElement; - function _addRouteResultsValuesElement(distance: number, duration: number, fconvert: Function): DOMElement; - function _createRouteShowResultsDetailsElement(): DOMElement; - function _createRouteResultsDetailsElement(): DOMElement; - function _addRouteResultsDetailsElement(instructions: Object[], fconvert: Function): DOMElement; - function _createRoutePanelFormPointElement(n: Integer, text: string, visibility: boolean): DOMElement; - function _createRoutePanelFormRemoveStageElement(n: Integer): DOMElement; - function _createRoutePanelFormAddStageElement(): DOMElement; - function _createRoutePanelFormAutoCompleteListElement(n: Integer): DOMElement; - function _createRouteAutoCompletedLocationElement(location: Object, n: number, id: number): void; - function _createRoutePanelFormModeChoiceElement(): DOMElement; - function _createRoutePanelFormModeChoiceTransportElement(transports: string[]): DOMElement; - function _createRoutePanelFormModeChoiceComputeElement(): DOMElement; - function _createShowRouteExclusionsPictoElement(): DOMElement; - function _createRoutePanelFormExclusionsElement(): DOMElement; - function _createRoutePanelFormExclusionOptionsElement(exclusions: Object[]): DOMElement; - function _createRouteSubmitFormElement(): DOMElement; - function _createRouteFormResetElement(): DOMElement; -} -//# sourceMappingURL=RouteDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/RouteDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/RouteDOM.d.ts.map deleted file mode 100644 index 34535aafa..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/RouteDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"RouteDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Route/RouteDOM.js"],"names":[],"mappings":";;IAac,qCAGT;IAO6B,mDAK7B;IAY8B,oDA8B9B;IAgB0B,gDAU1B;IAE6B,uDAI7B;IAOgC,sDAqChC;IAOgC,sDAKhC;IAQ8B,oDAsF9B;IAOiC,uDA+BjC;IAO4B,kDAY5B;IAYkC,wDAIlC;IAOqC,uEA4BrC;IAQ4B,kDAoD5B;IAY+B,2GAoD/B;IAOuC,6DAKvC;IAOmC,yDAKnC;IAUgC,gGA+DhC;IAiBmC,sGAkHnC;IAWyC,yEA0BzC;IAUsC,4DAkCtC;IAW8C,8EAwB9C;IAa0C,iGAS1C;IAWwC,8DAQxC;IAUiD,2FAqFjD;IAQ+C,qEA0C/C;IAawC,8DA6BxC;IAOwC,8DAYxC;IAU8C,wFAiG9C;IAW+B,qDAQ/B;IAW8B,oDAiB9B"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/RouteDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/RouteDOM.js deleted file mode 100644 index f34aa5c6b..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Route/RouteDOM.js +++ /dev/null @@ -1,1233 +0,0 @@ -import ID from "../../Utils/SelectorID"; -import Logger from "../../Utils/LoggerByDefault"; -import GeocodeUtils from "../../Utils/GeocodeUtils"; - -var logger = Logger.getLogger("RouteDOM"); - -var RouteDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Main container (DOM) - * - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GProute"); - container.className = "GPwidget gpf-widget gpf-widget-button"; - return container; - }, - - // ################################################################### // - // ################# Methods to display Main Panel ################### // - // ################################################################### // - - /** - * Show route control - * see event ! - * - * @returns {DOMElement} DOM element - */ - _createShowRoutePictoElement : function () { - // contexte d'execution - var context = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowRoutePicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto GPshowRoutePicto gpf-btn gpf-btn-icon gpf-btn-icon-route fr-btn"; - button.title = "Ouvrir le calcul d'itinéraire"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // gestionnaire d'evenement : - // on ouvre le menu de saisie du calcul d'itiniraire - // L'ouverture/Fermeture permet de faire le menage - // (reinitialisation) - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowRoutePanelClick(e); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowRoutePanelClick(e); - }); - } - - return button; - }, - - // ################################################################### // - // ################## Methods to display Inputs Panel ################ // - // ################################################################### // - - /** - * Create Container Panel - * - * FIXME - * don't call this._createRoutePanelHeaderElement - * don't call this._createRoutePanelFormElement - * don't call this._createRoutePanelResultsElement - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelElement : function () { - var dialog = document.createElement("dialog"); - dialog.id = this._addUID("GProutePanel"); - dialog.className = "GPpanel gpf-panel fr-modal"; - - // dialog.appendChild(this._createRoutePanelHeaderElement()); - // dialog.appendChild(this._createRoutePanelFormElement()); - // dialog.appendChild(this._createRoutePanelResultsElement()); - - return dialog; - }, - - _createRoutePanelDivElement : function () { - var div = document.createElement("div"); - div.className = "gpf-panel__body fr-modal__body"; - return div; - }, - - /** - * Create Header Panel - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelHeaderElement : function () { - // contexte d'execution - var self = this; - - var container = document.createElement("div"); - container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; - - var div = document.createElement("div"); - div.className = "GPpanelTitle gpf-panel__title fr-modal__title fr-m-1w"; - div.innerHTML = "Calcul d'itinéraire"; - container.appendChild(div); - - var divClose = document.createElement("button"); - divClose.id = this._addUID("GProutePanelClose"); - divClose.className = "GPpanelClose GProutePanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--secondary fr-m-1w"; - divClose.title = "Masquer le panneau"; - - // Link panel close / visibility checkbox - if (divClose.addEventListener) { - divClose.addEventListener("click", function () { - document.getElementById(self._addUID("GPshowRoutePicto")).click(); - }, false); - } else if (divClose.attachEvent) { - divClose.attachEvent("onclick", function () { - document.getElementById(self._addUID("GPshowRoutePicto")).click(); - }); - } - - var span = document.createElement("span"); - span.className = "GPelementHidden gpf-visible"; // afficher en dsfr - span.innerText = "Fermer"; - - divClose.appendChild(span); - - container.appendChild(divClose); - - return container; - }, - - /** - * Create Footer Panel - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelFooterElement : function () { - var container = document.createElement("div"); - container.className = "GPpanelFooter gpf-panel__footer fr-modal__footer"; - - return container; - }, - - /** - * Create Form - * see evenement ! - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelFormElement : function () { - // contexte d'execution - var self = this; - - var form = document.createElement("form"); - form.id = this._addUID("GProuteForm"); - form.className = "gpf-panel__content fr-modal__content"; - form.setAttribute("onkeypress", "return event.keyCode != 13;"); // FIXME hack pour desactiver l'execution via 'enter' au clavier ! - - form.addEventListener("submit", function (e) { - logger.log(e); - e.preventDefault(); - - // points - var points = document.getElementsByClassName(self._addUID("GPlocationPoint")); - - // Must have at least two origin points - var start = points[0].childNodes[0].id; - var end = points[points.length - 1].childNodes[0].id; - var startID = ID.index(start); - var endID = ID.index(end); - - if ((document.getElementById(self._addUID("GPlocationOrigin_" + startID)).value === "" && - document.getElementById(self._addUID("GPlocationOriginCoords_" + startID)).value === "") || - (document.getElementById(self._addUID("GPlocationOrigin_" + endID)).value === "" && - document.getElementById(self._addUID("GPlocationOriginCoords_" + endID)).value === "")) { - return false; - } - - // Send stages to results panel - self._addRouteResultsStagesValuesElement(points); - - // on peut récuperer les valeurs utiles pour les transmettre au service d'iti... - // - le mode de calcul - // - le mode de transport - // - les exclusions - // Les points sont déjà stockés dans l'application. - - // computation mode params - var modeComputation = null; - if (document.getElementById(self._addUID("GProuteComputationSelect"))) { - var select = document.getElementById(self._addUID("GProuteResultsComputationSelect")); - select.selectedIndex = document.getElementById(self._addUID("GProuteComputationSelect")).selectedIndex; - modeComputation = select.options[select.selectedIndex].value; - } - - // transport mode params - var modeTransport = null; - // voiture ? - if (document.getElementById(self._addUID("GProuteTransportCar"))) { - if (document.getElementById(self._addUID("GProuteTransportCar")).checked) { - modeTransport = document.getElementById(self._addUID("GProuteTransportCar")).value; - } - } - // pieton ? - if (document.getElementById(self._addUID("GProuteTransportPedestrian"))) { - if (document.getElementById(self._addUID("GProuteTransportPedestrian")).checked) { - modeTransport = document.getElementById(self._addUID("GProuteTransportPedestrian")).value; - } - } - - // exclusions params - var exclusions = []; - var exclusionsElement = document.getElementsByClassName("GProuteExclusionsOption"); - for (var j = 0; j < exclusionsElement.length; j++) { - var id = exclusionsElement[j].htmlFor; - var el = document.getElementById(id); - if (!el.checked) { - exclusions.push(el.value); - } - } - - self.onRouteComputationSubmit({ - computation : modeComputation, - transport : modeTransport, - exclusions : exclusions - }); - - // FIXME mise à jour du controle dans le composant JS ! - // document.getElementById(self._addUID("GProuteForm")).className = "GPelementHidden"; - // document.getElementById(self._addUID("GProuteResultsPanel")).className = ""; - - return false; - }); - - return form; - }, - - /** - * Create Results Panel - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelResultsElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GProuteResultsPanel"); - container.className = "GPelementHidden gpf-hidden"; - - container.appendChild(this._createRouteResultsStagesElement()); - container.appendChild(this._createRouteResultsElement()); - - var divBorderUp = document.createElement("div"); - divBorderUp.className = "GPfakeBorder GPfakeBorderLeft"; - container.appendChild(divBorderUp); - - container.appendChild(this._createRouteShowResultsDetailsElement()); - - var labelShow = document.createElement("label"); - labelShow.htmlFor = this._addUID("GProuteResultsShowDetails"); - labelShow.innerHTML = "Afficher le détail"; - container.appendChild(labelShow); - - var labelHide = document.createElement("label"); - labelHide.htmlFor = this._addUID("GProuteResultsShowDetails"); - labelHide.innerHTML = "Masquer le détail"; - container.appendChild(labelHide); - - var divBorderDown = document.createElement("div"); - divBorderDown.className = "GPfakeBorder"; - container.appendChild(divBorderDown); - - container.appendChild(this._createRouteResultsDetailsElement()); - - return container; - }, - - /** - * Create Waiting Panel - * - * @returns {DOMElement} DOM element - */ - _createRouteWaitingElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GProuteCalcWaitingContainer"); - div.className = "GPwaitingContainer GPwaitingContainerHidden gpf-waiting gpf-waiting--hidden"; - - var p = document.createElement("p"); - p.className = "GPwaitingContainerInfo gpf-waiting_info"; - p.innerHTML = "Recherche en cours..."; - - div.appendChild(p); - - return div; - }, - - // ################################################################### // - // ############### Methods to the window results ##################### // - // ################################################################### // - - /** - * Create Results Stages - * (results dynamically generate !) - * - * @returns {DOMElement} DOM element - */ - _createRouteResultsStagesElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GProuteResultsStages"); - return div; - }, - - /** - * Add Stages Results - * - * @param {DOMElement} points - list of points - */ - _addRouteResultsStagesValuesElement : function (points) { - document.getElementById(this._addUID("GProuteResultsStages")).innerHTML = ""; - for (var i = 0; i < points.length; i++) { - var tag = points[i].childNodes[0].id; - var id = ID.index(tag); - if (document.getElementById(this._addUID("GPlocationPoint_" + id)).className === "GPflexInput GPlocationStageFlexInput gpf-flex") { - var resultStage = document.createElement("div"); - resultStage.className = "GProuteResultsStages"; - var resultStageLabel = document.createElement("div"); - resultStageLabel.className = "GProuteResultStageLabel"; - resultStageLabel.innerHTML = document.getElementById(this._addUID("GPlocationOriginLabel_" + id)).innerHTML + " :"; - resultStage.appendChild(resultStageLabel); - var resultStageValue = document.createElement("div"); - resultStageValue.className = "GProuteResultStageValue"; - var elementCoords = document.getElementById(this._addUID("GPlocationOriginCoords_" + id)); - var stageCoords = elementCoords.value; - var visible = (elementCoords.className === "GPelementVisible gpf-visible"); - if (stageCoords !== null && stageCoords !== "" && visible) { - resultStageValue.innerHTML = stageCoords; - } else { - resultStageValue.innerHTML = document.getElementById(this._addUID("GPlocationOrigin_" + id)).value; - } - resultStage.appendChild(resultStageValue); - if (resultStageValue.innerHTML !== "") { - document.getElementById(this._addUID("GProuteResultsStages")).appendChild(resultStage); - } - } - } - }, - - /** - * Create Show Results - * see event! - * - * @returns {DOMElement} DOM element - */ - _createRouteResultsElement : function () { - // contexte - var self = this; - - var container = document.createElement("div"); - container.id = this._addUID("GProuteResults"); - - // FIXME Route results are dynamically filled in Javascript by route service - var divValue = document.createElement("div"); - divValue.id = this._addUID("GProuteResultsValues"); - container.appendChild(divValue); - - var divMode = document.createElement("div"); - divMode.id = this._addUID("GProuteResultsMode"); - - var select = document.createElement("select"); - select.id = this._addUID("GProuteResultsComputationSelect"); - select.className = "GPselect"; - // gestionnaire d'evenement : - // on stocke la valeur du mode de calcul, et on relance le calcul d'itiniraire - select.addEventListener("change", function (e) { - self.onRouteModeComputationChangeAndRun(e); - }); - - var computes = [{ - code : "fastest", - label : "Plus rapide" - }, { - code : "shortest", - label : "Plus court" - }]; - - for (var i = 0; i < computes.length; i++) { - var option = document.createElement("option"); - option.value = computes[i].code; - option.text = computes[i].label; - select.appendChild(option); - } - divMode.appendChild(select); - container.appendChild(divMode); - - var divNew = document.createElement("div"); - divNew.id = this._addUID("GProuteResultsNew"); - divNew.title = "Modifier le calcul"; - divNew.addEventListener("click", function (e) { - document.getElementById(self._addUID("GProuteResultsPanel")).className = "GPelementHidden gpf-hidden"; - document.getElementById(self._addUID("GProuteForm")).className = "gpf-panel__content fr-modal__content"; - self.onShowRouteResultsNewClick(e); - }); - container.appendChild(divNew); - - return container; - }, - - /** - * Add Results Duration and Distance - * (results dynamically generate !) - * see event! - * @param {Number} distance - distance - * @param {Number} duration - duration - * @param {Function} fconvert - fconvert - * - * @returns {DOMElement} DOM element - */ - _addRouteResultsValuesElement : function (distance, duration, fconvert) { - var div = document.getElementById(this._addUID("GProuteResultsValues")); - - // clean ! - if (div.childElementCount) { - while (div.firstChild) { - div.removeChild(div.firstChild); - } - } - - var containerDistance = document.createElement("div"); - containerDistance.className = "GProuteResultsValue"; - - var labelDistance = document.createElement("label"); - labelDistance.className = "GProuteResultsValueLabel"; - labelDistance.innerHTML = "Distance :"; - containerDistance.appendChild(labelDistance); - - var distanceLabel = 0; - var isKm = parseInt(distance / 1000, 10); - - if (!isKm) { - distanceLabel = Math.round(distance) + " m"; - } else { - var distanceArrondi = Math.round(distance); - distanceArrondi = distanceArrondi / 1000; - distanceLabel = distanceArrondi + " km"; - } - - var divDistance = document.createElement("div"); - divDistance.id = this._addUID("GProuteResultsValueDist"); - divDistance.innerHTML = distanceLabel; - containerDistance.appendChild(divDistance); - - div.appendChild(containerDistance); - - var containerDuration = document.createElement("div"); - containerDuration.className = "GProuteResultsValue"; - - var labelDuration = document.createElement("label"); - labelDuration.className = "GProuteResultsValueLabel"; - labelDuration.innerHTML = "Durée :"; - containerDuration.appendChild(labelDuration); - - var divDuration = document.createElement("div"); - divDuration.id = this._addUID("GProuteResultsValueDist"); - divDuration.innerHTML = fconvert(duration); - containerDuration.appendChild(divDuration); - - div.appendChild(containerDuration); - - return div; - }, - - /** - * Create Show Results Details - * - * @returns {DOMElement} DOM element - */ - _createRouteShowResultsDetailsElement : function () { - var input = document.createElement("input"); - input.id = this._addUID("GProuteResultsShowDetails"); - input.type = "checkbox"; - return input; - }, - - /** - * Create Results Details - * - * @returns {DOMElement} DOM element - */ - _createRouteResultsDetailsElement : function () { - // - var div = document.createElement("div"); - div.id = this._addUID("GProuteResultsDetails"); - return div; - }, - - /** - * Add Results Details - * (results dynamically generate !) - * @param {Object[]} instructions - instructions - * @param {Function} fconvert - fconvert - * - * @returns {DOMElement} DOM element - */ - _addRouteResultsDetailsElement : function (instructions, fconvert) { - // contexte - var context = this; - - var div = document.getElementById(this._addUID("GProuteResultsDetails")); - - // clean ! - if (div.childElementCount) { - while (div.firstChild) { - div.removeChild(div.firstChild); - } - } - - // calcul des valeurs cumulé ! - var distanceCumul = 0; - var durationCumul = 0; - - /* jshint -W083 */ - for (var i = 0; i < instructions.length; i++) { - var id = i + 1; - - var o = instructions[i]; - - var divNum = document.createElement("div"); - divNum.className = "GProuteResultsDetailsNumber"; - divNum.innerHTML = id + "."; - div.appendChild(divNum); - - durationCumul += parseFloat(o.duration); - distanceCumul += parseFloat(o.distance); - - var distance = 0; - var isCumulKm = parseInt(distanceCumul / 1000, 10); - if (!isCumulKm) { - distance = Math.round(distanceCumul) + " m"; - } else { - var distanceArrondi = Math.round(distanceCumul); - distanceArrondi = distanceArrondi / 1000; - distance = distanceArrondi + " km"; - } - - var divIns = document.createElement("div"); - divIns.className = "GProuteResultsDetailsInstruction"; - divIns.id = this._addUID("GProuteResultsDetailsInstruction_" + id); - divIns.title = "distance : " + distance + " / " + "temps : " + fconvert(durationCumul); - divIns.innerHTML = o.instruction; - - divIns.addEventListener("mouseover", function (e) { - context.onRouteResultsDetailsMouseOver(e); - }); - divIns.addEventListener("mouseout", function (e) { - context.onRouteResultsDetailsMouseOut(e); - }); - divIns.addEventListener("click", function (e) { - // mode mobile ! - if (typeof context.onRouteResultsDetailsClick === "function") { - context.onRouteResultsDetailsClick(e); - } - }); - div.appendChild(divIns); - } - - return div; - }, - - // ################################################################### // - // ################### Methods to the form points #################### // - // ################# OVERWRITTEN BY LOCATIONSELECTOR ! ################# // - - /** - * Create Point - * see event ! - * OVERWRITTEN BY LOCATIONSELECTOR ! - * (version initial without LOCATIONSELECTOR PLUGIN) - * @param {Integer} n - n - * @param {String} text - text - * @param {Boolean} visibility - visibility - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelFormPointElement : function (n, text, visibility) { - // contexte d'execution - var context = this; - - var div = document.createElement("div"); - div.id = "GProutePoint" + n; - div.className = (visibility) ? "GPflexInput GProuteStageFlexInput" : "GPflexInput GProuteStageFlexInputHidden"; - - var labelOrigin = document.createElement("label"); - labelOrigin.id = "GProuteOriginLabel" + n; - labelOrigin.htmlFor = "GProuteOrigin" + n; - labelOrigin.innerHTML = text; - labelOrigin.addEventListener("click", function () { - var i = this.id.charAt(this.id.length - 1); - document.getElementById("GProuteOriginCoords" + i).value = ""; - for (var j = 1; j < 8; j++) { - document.getElementById("GProutePoint" + j).style.display = "flex"; - } - document.getElementById("GProuteForm").className = "gpf-panel__content fr-modal__content"; - document.getElementById("GProuteOriginPointer" + i).checked = false; - document.getElementById("GProuteOrigin" + i).className = "GPelementVisible gpf-visible"; - document.getElementById("GProuteOriginCoords" + i).className = "GPelementHidden gpf-hidden"; - }); - div.appendChild(labelOrigin); - - var inputOrigin = document.createElement("input"); - inputOrigin.id = "GProuteOrigin" + n; - inputOrigin.className = "GPelementVisible gpf-visible"; - inputOrigin.type = "text"; - inputOrigin.placeholder = "Saisir une adresse"; - inputOrigin.addEventListener("keyup", function (e) { - var charCode = e.which || e.keyCode; - if (charCode === 13 || charCode === 10) { - return; - } - var i = this.id.charAt(this.id.length - 1); - if (document.getElementById("GProuteOrigin" + i).value.length > 2) { - document.getElementById("GProuteAutoCompleteList" + i).style.display = "block"; - } else { - document.getElementById("GProuteAutoCompleteList" + i).style.display = "none"; - } - // gestionnaire d'evenement : - // on récupère la valeur de saisie pour une requête sur le service d'autocompletion. - // le resultat de la requête nous permet de recuperer les coordonnées du point... - context.onAutoCompleteSearchText(e); - }); - inputOrigin.addEventListener("blur", function () { - var i = this.id.charAt(this.id.length - 1); - document.getElementById("GProuteAutoCompleteList" + i).style.display = "none"; - }); - div.appendChild(inputOrigin); - - var inputOriginCoord = document.createElement("input"); - inputOriginCoord.id = "GProuteOriginCoords" + n; - inputOriginCoord.className = "GPelementHidden gpf-hidden"; - inputOriginCoord.type = "text"; - inputOriginCoord.disabled = true; - div.appendChild(inputOriginCoord); - - var inputOriginPointer = document.createElement("input"); - inputOriginPointer.id = "GProuteOriginPointer" + n; - inputOriginPointer.type = "checkbox"; - div.appendChild(inputOriginPointer); - - var labelOriginPointer = document.createElement("label"); - labelOriginPointer.id = "GProuteOriginPointerImg" + n; - labelOriginPointer.htmlFor = "GProuteOriginPointer" + n; - labelOriginPointer.className = "GProuteOriginPointerImg"; - labelOriginPointer.title = "Pointer un lieu sur la carte"; - labelOriginPointer.addEventListener("click", function (evt) { - evt.preventDefault(); - evt.stopPropagation(); - var i = this.id.charAt(this.id.length - 1); - var j; - for (j = 1; j < 8; j++) { - if (i !== j) { - document.getElementById("GProuteOriginPointer" + j).checked = false; - if (document.getElementById("GProuteOriginCoords" + j).value === "Pointer un lieu sur la carte") { - document.getElementById("GProuteOriginCoords" + j).value = ""; - document.getElementById("GProuteOrigin" + j).className = "GPelementVisible gpf-visible"; - document.getElementById("GProuteOriginCoords" + j).className = "GPelementHidden gpf-hidden"; - } - } - } - if (document.getElementById("GProuteOriginPointer" + i).checked) { - document.getElementById("GProuteOriginCoords" + i).value = ""; - for (j = 1; j < 8; j++) { - document.getElementById("GProutePoint" + j).style.display = "flex"; - } - document.getElementById("GProuteForm").className = "gpf-panel__content fr-modal__content"; - document.getElementById("GProuteOriginPointer" + i).checked = false; - document.getElementById("GProuteOrigin" + i).className = "GPelementVisible gpf-visible"; - document.getElementById("GProuteOriginCoords" + i).className = "GPelementHidden gpf-hidden"; - } else { - document.getElementById("GProuteOriginCoords" + i).value = "Pointer un lieu sur la carte"; - for (j = 1; j < 8; j++) { - if (i === j) { - document.getElementById("GProutePoint" + j).style.display = "flex"; - } else { - document.getElementById("GProutePoint" + j).style.display = "none"; - } - } - document.getElementById("GProuteForm").className = "GProuteFormMini gpf-panel__content fr-modal__content"; - document.getElementById("GProuteOriginPointer" + i).checked = true; - document.getElementById("GProuteOrigin" + i).className = "GPelementHidden gpf-hidden"; - document.getElementById("GProuteOriginCoords" + i).className = "GPelementVisible gpf-visible"; - } - // gestionnaire d'evenement : - // on stocke la valeur du point, utilisée pour la requête sur le service de calcul d'itiniraire - context.onRouteMapPointClick(evt); - }); - div.appendChild(labelOriginPointer); - - return div; - }, - - /** - * Create Remove Point tag - * see event ! - * OVERWRITTEN BY LOCATIONSELECTOR ! - * (version initial without LOCATIONSELECTOR PLUGIN) - * @param {Integer} n - n - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelFormRemoveStageElement : function (n) { - // contexte d'execution - var context = this; - - var divRm = document.createElement("div"); - divRm.id = "GProuteStageRemove" + n; - divRm.className = "GProuteStageRemove"; - divRm.title = "Supprimer l'étape"; - if (n !== 1 && n !== 7) { - divRm.addEventListener("click", function (e) { - var i = this.id.charAt(this.id.length - 1); - document.getElementById("GProutePoint" + i).className = "GPflexInput GProuteStageFlexInputHidden"; - document.getElementById("GProuteOrigin" + i).value = ""; - document.getElementById("GProuteOrigin" + i).className = "GPelementVisible gpf-visible"; - document.getElementById("GProuteOriginCoords" + i).value = ""; - document.getElementById("GProuteOriginCoords" + i).className = "GPelementHidden gpf-hidden"; - document.getElementById("GProuteStageAdd").style.display = ""; - // Moving up exclusions picto - // var exclusionsPictoTop = document.getElementById("GPshowRouteExclusionsPicto").style.top; - // document.getElementById("GPshowRouteExclusionsPicto").style.top = (parseInt(exclusionsPictoTop, 10) - 33).toString() + "px"; - // gestionnaire d'evenement : - // on supprime le point, utilisé pour la requête sur le service d'itiniraire - context.onRouteRemovePointClick(e); - }); - } - return divRm; - }, - - /** - * Create Add Point tag - * see event ! - * OVERWRITTEN BY LOCATIONSELECTOR ! - * (version initial without LOCATIONSELECTOR PLUGIN) - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelFormAddStageElement : function () { - // contexte d'execution - var context = this; - - var divAdd = document.createElement("div"); - divAdd.id = "GProuteStageAdd"; - divAdd.title = "Ajouter une étape"; - divAdd.addEventListener("click", function (e) { - var lastStage = 1; - var nbStages = 0; - for (var i = 2; i < 7; i++) { - if (document.getElementById("GProutePoint" + i).className === "GPflexInput GProuteStageFlexInputHidden") { - if (lastStage === 1) { - lastStage = i; - } - } else { - nbStages++; - } - } - if (lastStage < 7) { - document.getElementById("GProutePoint" + lastStage).className = "GPflexInput GProuteStageFlexInput"; - // Moving down exclusions picto - // var exclusionsPictoTop = document.getElementById("GPshowRouteExclusionsPicto").style.top; - // document.getElementById("GPshowRouteExclusionsPicto").style.top = (parseInt(exclusionsPictoTop, 10) + 33).toString() + "px"; - } - if (nbStages === 4) { - document.getElementById("GProuteStageAdd").style.display = "none"; - } - // gestionnaire d'evenement : - // on ajoute le point, utilisé pour la requête sur le service d'itiniraire - context.onRouteAddPointClick(e); - }); - - return divAdd; - }, - - /** - * Create Results autocompletion to the point - * see event! - * OVERWRITTEN BY LOCATIONSELECTOR ! - * (version initial without LOCATIONSELECTOR PLUGIN) - * @param {Integer} n - n - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelFormAutoCompleteListElement : function (n) { - // contexte d'execution - var context = this; - - var div = document.createElement("div"); - div.id = "GProuteAutoCompleteList" + n; - div.className = "GPadvancedAutoCompleteList"; - - if (div.addEventListener) { - div.addEventListener("click", function (e) { - context.onAutoCompletedResultsItemClick(e); - document.getElementById("GProuteAutoCompleteList" + n).style.display = "none"; - }, false); - } else if (div.attachEvent) { - div.attachEvent("onclick", function (e) { - context.onAutoCompletedResultsItemClick(e); - document.getElementById("GProuteAutoCompleteList" + n).style.display = "none"; - }); - } - - // Proposals are dynamically filled in Javascript by autocomplete service - //
...
- - return div; - }, - - /** - * Autocompletion result to a point. - * Proposals are dynamically filled in Javascript by autocomplete service - * OVERWRITTEN BY LOCATIONSELECTOR ! - * (version initial without LOCATIONSELECTOR PLUGIN) - * - * - * @param {Object} location - suggested location results - * @param {Number} n - number of the point - * @param {Number} id - ID - */ - _createRouteAutoCompletedLocationElement : function (location, n, id) { - var container = document.getElementById("GProuteAutoCompleteList" + n); - - var div = document.createElement("div"); - div.id = "AutoCompletedLocation" + id; - div.className = "GPautoCompleteProposal"; - div.innerHTML = GeocodeUtils.getSuggestedLocationFreeform(location); - - container.appendChild(div); - }, - - // ################################################################### // - // ############## Methods to the choice mode into form ############### // - // ################################################################### // - - /** - * Create Container to Mode choice transport - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelFormModeChoiceElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GProuteModeChoice"); - - // div.appendChild(this._createRoutePanelFormModeChoiceTransportElement()); - // div.appendChild(this._createRoutePanelFormModeChoiceComputeElement()); - - return div; - }, - - /** - * Create Mode choice transport - * see event ! - * FIXME event not useful - * @param {String[]} transports - transports - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelFormModeChoiceTransportElement : function (transports) { - // contexte d'execution - var context = this; - - var divContainer = document.createElement("div"); - divContainer.id = this._addUID("GProuteTransportChoice"); - - var label = document.createElement("label"); - label.className = "GProuteModeLabel gpf-label fr-label"; - label.innerHTML = "Mode de transport"; - divContainer.appendChild(label); - - /* jshint -W083 */ - for (var i = 0; i < transports.length; i++) { - var transport = transports[i]; - - var div = document.createElement("div"); - div.className = "GProuteTransportChoice gpf-flex gpf-radio-group fr-radio-group fr-my-1w"; - - if (transport === "Voiture") { - var inputCar = document.createElement("input"); - inputCar.id = this._addUID("GProuteTransportCar"); - inputCar.type = "radio"; - inputCar.name = "GProuteTransport"; - inputCar.value = "Voiture"; - if (i === 0) { - inputCar.checked = true; - } - // gestionnaire d'evenement : - // on stocke le mode de transport, - // utilisation pour la requête sur le service de calcul d'itiniraire - if (inputCar.addEventListener) { - inputCar.addEventListener("change", function (e) { - context.onRouteModeTransportChange(e); - }); - } else if (inputCar.attachEvent) { - inputCar.attachEvent("onchange", function (e) { - context.onRouteModeTransportChange(e); - }); - } - div.appendChild(inputCar); - - var labelCar = document.createElement("label"); - labelCar.className = "GProuteTransportImg gpf-label fr-label"; - labelCar.htmlFor = this._addUID("GProuteTransportCar"); - labelCar.title = "Voiture"; - labelCar.innerHTML = "Voiture"; - div.appendChild(labelCar); - } - - if (transport === "Pieton") { - var inputPedestrian = document.createElement("input"); - inputPedestrian.id = this._addUID("GProuteTransportPedestrian"); - inputPedestrian.type = "radio"; - inputPedestrian.name = "GProuteTransport"; - inputPedestrian.value = "Pieton"; - if (i === 0) { - inputPedestrian.checked = true; - } - // gestionnaire d'evenement : - // on stocke le mode de transport, - // utilisation pour la requête sur le service de calcul d'itiniraire - if (inputPedestrian.addEventListener) { - inputPedestrian.addEventListener("change", function (e) { - context.onRouteModeTransportChange(e); - }); - } else if (inputPedestrian.attachEvent) { - inputPedestrian.attachEvent("onchange", function (e) { - context.onRouteModeTransportChange(e); - }); - } - div.appendChild(inputPedestrian); - - var labelPedestrian = document.createElement("label"); - labelPedestrian.className = "GProuteTransportImg gpf-label fr-label"; - labelPedestrian.htmlFor = this._addUID("GProuteTransportPedestrian"); - labelPedestrian.title = "Piéton"; - labelPedestrian.innerHTML = "Piéton"; - div.appendChild(labelPedestrian); - } - - divContainer.appendChild(div); - } - - return divContainer; - }, - - /** - * Create Mode choice computation - * see event! - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelFormModeChoiceComputeElement : function () { - // contexte d'execution - var context = this; - - var div = document.createElement("div"); - div.id = this._addUID("GProuteComputationChoice"); - - var label = document.createElement("label"); - label.htmlFor = this._addUID("GProuteComputationSelect"); - label.innerHTML = "Mode de calcul"; - var span = document.createElement("span"); - span.className = "GProuteModeLabel"; - span.appendChild(label); - div.appendChild(span); - - var select = document.createElement("select"); - select.id = this._addUID("GProuteComputationSelect"); - select.className = "GPselect gpf-select fr-select"; - // gestionnaire d'evenement : - // on stocke la valeur du mode de calcul, - // utilisation pour la requête sur le service de calcul d'itiniraire - select.addEventListener("change", function (e) { - context.onRouteModeComputationChange(e); - }); - - var computes = [{ - code : "fastest", - label : "Plus rapide" - }, { - code : "shortest", - label : "Plus court" - }]; - - for (var i = 0; i < computes.length; i++) { - var option = document.createElement("option"); - option.value = computes[i].code; - option.text = computes[i].label; - select.appendChild(option); - } - div.appendChild(select); - - return div; - }, - - // ################################################################### // - // ################# Methods to the choice exclusions ################ // - // ################################################################### // - - /** - * Label to Exclusions Options - * see event ! - * FIXME event not useful - * - * @returns {DOMElement} DOM element - */ - _createShowRouteExclusionsPictoElement : function () { - // contexte d'execution - var context = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowRouteExclusionsPicto"); - button.className = "GPshowAdvancedToolPicto GPshowMoreOptionsImage GPshowMoreOptions GPshowRouteExclusionsPicto gpf-btn fr-btn--sm fr-btn--secondary fr-icon-arrow-down-fill"; - button.title = "Exclusions"; - // button.style.top = "185px"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // gestionnaire d'evenement : - // on ouvre le menu des options des exclusions - if (button.addEventListener) { - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowRouteExclusionsClick(e); - }); - } else if (button.attachEvent) { - button.attachEvent("onclick", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - context.onShowRouteExclusionsClick(e); - }); - } - - return button; - }, - - /** - * Create Container to Exclusions - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelFormExclusionsElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GProuteExclusions"); - - var label = document.createElement("label"); - label.className = "GProuteExclusionsLabel fr-m-1w"; - label.innerHTML = "Passages autorisés"; - div.appendChild(label); - - // div.appendChild(this._createRoutePanelFormExclusionOptionsElement()); - - return div; - }, - - /** - * Create Exclusions Options - * see event ! - * FIXME event not useful - * @param {Object[]} exclusions - exclusions - * - * @returns {DOMElement} DOM element - */ - _createRoutePanelFormExclusionOptionsElement : function (exclusions) { - // contexte d'execution - var context = this; - - var div = document.createElement("div"); - div.className = "GProuteExclusionsOptions gpf-flex fr-checkbox-group fr-m-1w"; - - /* jshint -W083 */ - for (var value in exclusions) { - if (exclusions.hasOwnProperty(value)) { - var status = exclusions[value]; - switch (value) { - case "toll": - var inputToll = document.createElement("input"); - inputToll.id = this._addUID("GProuteExclusionsToll"); - inputToll.type = "checkbox"; - inputToll.value = "Toll"; - inputToll.checked = !status; - // gestionnaire d'evenement : - // on stocke l'exclusion, - // utilisation pour la requête sur le service de calcul d'itiniraire - if (inputToll.addEventListener) { - inputToll.addEventListener("change", function (e) { - context.onRouteExclusionsChange(e); - }); - } else if (inputToll.attachEvent) { - inputToll.attachEvent("onchange", function (e) { - context.onRouteExclusionsChange(e); - }); - } - div.appendChild(inputToll); - - var labelToll = document.createElement("label"); - labelToll.className = "GProuteExclusionsOption"; - labelToll.htmlFor = this._addUID("GProuteExclusionsToll"); - labelToll.innerHTML = "Péages"; - div.appendChild(labelToll); - break; - - case "tunnel": - var inputTunnel = document.createElement("input"); - inputTunnel.id = this._addUID("GProuteExclusionsTunnel"); - inputTunnel.type = "checkbox"; - inputTunnel.value = "Tunnel"; - inputTunnel.checked = !status; - // gestionnaire d'evenement : - // on stocke l'exclusion, - // utilisation pour la requête sur le service de calcul d'itiniraire - if (inputTunnel.addEventListener) { - inputTunnel.addEventListener("change", function (e) { - context.onRouteExclusionsChange(e); - }); - } else if (inputTunnel.attachEvent) { - inputTunnel.attachEvent("onchange", function (e) { - context.onRouteExclusionsChange(e); - }); - } - div.appendChild(inputTunnel); - - var labelTunnel = document.createElement("label"); - labelTunnel.className = "GProuteExclusionsOption"; - labelTunnel.htmlFor = this._addUID("GProuteExclusionsTunnel"); - labelTunnel.innerHTML = "Tunnels"; - div.appendChild(labelTunnel); - break; - - case "bridge": - var inputBridge = document.createElement("input"); - inputBridge.id = this._addUID("GProuteExclusionsBridge"); - inputBridge.type = "checkbox"; - inputBridge.value = "Bridge"; - inputBridge.checked = !status; - // gestionnaire d'evenement : - // on stocke l'exclusion, - // utilisation pour la requête sur le service de calcul d'itiniraire - if (inputBridge.addEventListener) { - inputBridge.addEventListener("change", function (e) { - context.onRouteExclusionsChange(e); - }); - } else if (inputBridge.attachEvent) { - inputBridge.attachEvent("onchange", function (e) { - context.onRouteExclusionsChange(e); - }); - } - div.appendChild(inputBridge); - - var labelBridge = document.createElement("label"); - labelBridge.className = "GProuteExclusionsOption"; - labelBridge.htmlFor = this._addUID("GProuteExclusionsBridge"); - labelBridge.innerHTML = "Ponts"; - div.appendChild(labelBridge); - break; - } - } - } - - return div; - }, - - // ################################################################### // - // ############################### Submit Form ####################### // - // ################################################################### // - - /** - * Create Submit Form Element - * - * @returns {DOMElement} DOM element - */ - _createRouteSubmitFormElement : function () { - var input = document.createElement("input"); - input.id = this._addUID("GProuteSubmit"); - input.className = "GPsubmit gpf-btn gpf-btn-icon-submit fr-btn fr-btn--secondary"; - input.type = "submit"; - input.value = "Calculer"; - - return input; - }, - - // ################################################################### // - // ############################### Reset picto ####################### // - // ################################################################### // - - /** - * Create Reset Picto Element - * - * @returns {DOMElement} DOM element - */ - _createRouteFormResetElement : function () { - var self = this; - - var buttonReset = document.createElement("button"); - buttonReset.id = this._addUID("GProuteReset"); - buttonReset.title = "Réinitialiser les paramètres"; - buttonReset.className = "GPresetPicto gpf-btn gpf-btn-icon-return fr-btn fr-btn--secondary"; - buttonReset.title = "Réinitialiser les paramètres"; - buttonReset.setAttribute("tabindex", "0"); - buttonReset.setAttribute("aria-pressed", false); - buttonReset.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - self.onRouteResetClick(e); - }); - - return buttonReset; - } -}; - -export default RouteDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngine.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngine.d.ts deleted file mode 100644 index 17063b0f1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngine.d.ts +++ /dev/null @@ -1,115 +0,0 @@ -export default SearchEngine; -/** - * @classdesc - * SearchEngine control - * - * @constructor - * @extends {ol.control.Control} - * @type {ol.control.SearchEngine} - * @alias ol.control.SearchEngine - * @param {Object} options - control options - * @param {String} [options.apiKey] - API key. The key "calcul" is used by default. - * @param {Boolean} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean} [options.collapsed = true] - collapse mode, true by default - * @param {Boolean} [options.opened = false] - force control to be never collapsed, false by default. - * @param {String} [options.direction = "start"] - TODO : position of picto, by default : "start" - * @param {String} [options.placeholder] - Placeholder in search bar. Default is "Rechercher un lieu, une adresse". - * @param {Boolean} [options.displayMarker = true] - set a marker on search result, defaults to true. - * @param {String} [options.markerStyle = "lightOrange"] - Marker style. Currently possible values are "lightOrange" (default value), "darkOrange", "red" and "turquoiseBlue". - * @param {Boolean} [options.displayButtonAdvancedSearch = false] - False to disable advanced search tools (it will not be displayed). Default is false (not displayed) - * @param {Boolean} [options.displayButtonGeolocate = false] - False to disable advanced search tools (it will not be displayed). Default is false (not displayed) - * @param {Boolean} [options.displayButtonCoordinateSearch = false] - False to disable advanced search tools (it will not be displayed). Default is false (not displayed) - * @param {Boolean} [options.displayButtonClose = true] - False to disable advanced search tools (it will not be displayed). Default is true (displayed) - * @param {Object} [options.coordinateSearch] - coordinates search options. - * @param {DOMElement} [options.coordinateSearch.target = null] - TODO : target location of results window. By default under the search bar. - * @param {Array} [options.coordinateSearch.units] - list of coordinates units, to be displayed in control units list. - * Values may be "DEC" (decimal degrees), "DMS" (sexagecimal) for geographical coordinates, - * and "M" or "KM" for metric coordinates - * @param {Array} [options.coordinateSearch.systems] - list of projection systems, default are Geographical ("EPSG:4326"), Web Mercator ("EPSG:3857") and Lambert 93 ("EPSG:2154"). - * Each array element (=system) is an object with following properties : - * @param {String} [options.coordinateSearch.systems.crs] - Proj4 crs alias (from proj4 defs). e.g. : "EPSG:4326". Required - * @param {String} [options.coordinateSearch.systems.label] - CRS label to be displayed in control. Default is crs code (e.g. "EPSG:4326") - * @param {String} [options.coordinateSearch.systems.type] - CRS units type for coordinates conversion : "Geographical" or "Metric". Default: "Geographical" - * @param {Object} [options.advancedSearch] - advanced search options for geocoding (filters). Properties can be found among geocode options.filterOptions (see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~geocode Gp.Services.geocode}) - * @param {DOMElement} [options.advancedSearch.target = null] - TODO : target location of results window. By default under the search bar. - * @param {Object} [options.resources] - resources to be used by geocode and autocompletion services : - * @param {String} [options.resources.geocode = "location"] - resources geocoding, by default : "location" - * @param {Array} [options.resources.autocomplete] - resources autocompletion, by default : ["PositionOfInterest", "StreetAddress"] - * @param {Boolean} [options.resources.search = false] - false to disable search service, by default : "false" - * @param {Object} [options.searchOptions = {}] - options of search service - * @param {Object} [options.searchOptions.serviceOptions] - options of search service - * @param {Sring} [options.searchOptions.serviceOptions.url] - url of service - * @param {String} [options.searchOptions.serviceOptions.index] - index of search, "standard" by default - * @param {String} [options.searchOptions.serviceOptions.fields] - list of search fields, each field is separated by a comma. "title,layer_name" by default - * @param {Number} [options.searchOptions.serviceOptions.size] - number of response in the service. 1000 by default - * @param {String} [options.searchOptions.serviceOptions.services] - list of search services, each field is separated by a comma. "WMTS,WMS" by default - * @param {Number} [options.searchOptions.serviceOptions.maximumResponses] - number of results in the response. 10 by default - * @param {Object} [options.geocodeOptions = {}] - options of geocode service (see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~geocode Gp.Services.geocode}) - * @param {Object} [options.geocodeOptions.serviceOptions] - options of geocode service - * @param {Object} [options.autocompleteOptions = {}] - options of autocomplete service (see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~autoComplete Gp.Services.autoComplete}) - * @param {Object} [options.autocompleteOptions.serviceOptions] - options of autocomplete service - * @param {Boolean} [options.autocompleteOptions.triggerGeocode = false] - trigger a geocoding request if the autocompletion does not return any suggestions, false by default - * @param {Number} [options.autocompleteOptions.triggerDelay = 1000] - waiting time before sending the geocoding request, 1000ms by default - * @param {Sting|Numeric|Function} [options.zoomTo] - zoom to results, by default, current zoom. - * Value possible : auto or zoom level. - * Possible to overload it with a function : - * zoomTo : function (info) { - * // do some stuff... - * return zoom; - * } - * @fires searchengine:autocomplete:click - * @fires searchengine:geocode:click - * @fires searchengine:search:click - * @todo option : direction (start|end) de la position du picto (loupe) - * @todo option : choix du target pour les fenetres geocodage ou recherche par coordonnées - * @example - * var SearchEngine = ol.control.SearchEngine({ - * apiKey : "CLEAPI", - * collapsed : true, - * opened : false, - * displayButtonAdvancedSearch : true, - * displayButtonGeolocate : true, - * displayButtonCoordinateSearch : true, - * resources : { - * geocode : ["StreetAddress", "PositionOfInterest"], - * autocomplete : ["StreetAddress"], - * search : false - * }, - * advancedSearch : { - * target : document.getElementById("dialog"), - * PositionOfInterest : [{name : "municipality", title : "Ville"}], - * StreetAddress : [{...}] - * }, - * coordinateSearch : { - * target : null - * systems : [ - * { - * "crs" : "EPSG:3857", - * "label" : "Web Mercator", - * "type" : "Metric" - * }, - * { - * "crs" : "EPSG:4326", - * "label" : "Géographiques", - * "type" : "Geographical" - * } - * ], - * units : ["DEC", "DMS"] - * }, - * geocodeOptions : {}, - * autocompleteOptions : {}, - * searchOptions : {} - * }); - * - * SearchEngine.on("searchengine:autocomplete:click", function (e) { - * console.warn("autocomplete", e.location); - * }); - * SearchEngine.on("searchengine:search:click", function (e) { - * console.warn("search", e.suggest); - * }); - * SearchEngine.on("searchengine:geocode:click", function (e) { - * console.warn("geocode", e.location); - * }); - */ -declare var SearchEngine: ol.control.SearchEngine; -//# sourceMappingURL=SearchEngine.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngine.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngine.d.ts.map deleted file mode 100644 index 92ae45d3f..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngine.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"SearchEngine.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/SearchEngine/SearchEngine.js"],"names":[],"mappings":";AA+BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+GG;AACH,kDAinEE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngine.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngine.js deleted file mode 100644 index d8a4dc4ba..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngine.js +++ /dev/null @@ -1,2315 +0,0 @@ -// import CSS -import "../../CSS/Controls/SearchEngine/GPFsearchEngine.css"; -// import "../../CSS/Controls/SearchEngine/GPFsearchEngineStyle.css"; -// import OpenLayers -// import Control from "ol/control/Control"; -import Control from "../Control"; -import Overlay from "ol/Overlay"; -import { - transform as olProjTransform, - get as olProjGet, - transformExtent as olProjTransformExtent -} from "ol/proj"; -// import geoportal library access -import Gp from "geoportal-access-lib"; -// import local -import Logger from "../../Utils/LoggerByDefault"; -import Utils from "../../Utils/Helper"; -import Markers from "../Utils/Markers"; -import Interactions from "../Utils/Interactions"; -import SelectorID from "../../Utils/SelectorID"; -import MathUtils from "../../Utils/MathUtils"; -import SearchEngineUtils from "../../Utils/SearchEngineUtils"; -import GeocodeUtils from "../../Utils/GeocodeUtils"; -import CRS from "../../CRS/CRS"; -// Service -import Search from "../../Services/Search"; -// DOM -import SearchEngineDOM from "./SearchEngineDOM"; - -var logger = Logger.getLogger("searchengine"); - -/** - * @classdesc - * SearchEngine control - * - * @constructor - * @extends {ol.control.Control} - * @type {ol.control.SearchEngine} - * @alias ol.control.SearchEngine - * @param {Object} options - control options - * @param {String} [options.apiKey] - API key. The key "calcul" is used by default. - * @param {Boolean} [options.ssl = true] - use of ssl or not (default true, service requested using https protocol) - * @param {Boolean} [options.collapsed = true] - collapse mode, true by default - * @param {Boolean} [options.opened = false] - force control to be never collapsed, false by default. - * @param {String} [options.direction = "start"] - TODO : position of picto, by default : "start" - * @param {String} [options.placeholder] - Placeholder in search bar. Default is "Rechercher un lieu, une adresse". - * @param {Boolean} [options.displayMarker = true] - set a marker on search result, defaults to true. - * @param {String} [options.markerStyle = "lightOrange"] - Marker style. Currently possible values are "lightOrange" (default value), "darkOrange", "red" and "turquoiseBlue". - * @param {Boolean} [options.displayButtonAdvancedSearch = false] - False to disable advanced search tools (it will not be displayed). Default is false (not displayed) - * @param {Boolean} [options.displayButtonGeolocate = false] - False to disable advanced search tools (it will not be displayed). Default is false (not displayed) - * @param {Boolean} [options.displayButtonCoordinateSearch = false] - False to disable advanced search tools (it will not be displayed). Default is false (not displayed) - * @param {Boolean} [options.displayButtonClose = true] - False to disable advanced search tools (it will not be displayed). Default is true (displayed) - * @param {Object} [options.coordinateSearch] - coordinates search options. - * @param {DOMElement} [options.coordinateSearch.target = null] - TODO : target location of results window. By default under the search bar. - * @param {Array} [options.coordinateSearch.units] - list of coordinates units, to be displayed in control units list. - * Values may be "DEC" (decimal degrees), "DMS" (sexagecimal) for geographical coordinates, - * and "M" or "KM" for metric coordinates - * @param {Array} [options.coordinateSearch.systems] - list of projection systems, default are Geographical ("EPSG:4326"), Web Mercator ("EPSG:3857") and Lambert 93 ("EPSG:2154"). - * Each array element (=system) is an object with following properties : - * @param {String} [options.coordinateSearch.systems.crs] - Proj4 crs alias (from proj4 defs). e.g. : "EPSG:4326". Required - * @param {String} [options.coordinateSearch.systems.label] - CRS label to be displayed in control. Default is crs code (e.g. "EPSG:4326") - * @param {String} [options.coordinateSearch.systems.type] - CRS units type for coordinates conversion : "Geographical" or "Metric". Default: "Geographical" - * @param {Object} [options.advancedSearch] - advanced search options for geocoding (filters). Properties can be found among geocode options.filterOptions (see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~geocode Gp.Services.geocode}) - * @param {DOMElement} [options.advancedSearch.target = null] - TODO : target location of results window. By default under the search bar. - * @param {Object} [options.resources] - resources to be used by geocode and autocompletion services : - * @param {String} [options.resources.geocode = "location"] - resources geocoding, by default : "location" - * @param {Array} [options.resources.autocomplete] - resources autocompletion, by default : ["PositionOfInterest", "StreetAddress"] - * @param {Boolean} [options.resources.search = false] - false to disable search service, by default : "false" - * @param {Object} [options.searchOptions = {}] - options of search service - * @param {Object} [options.searchOptions.serviceOptions] - options of search service - * @param {Sring} [options.searchOptions.serviceOptions.url] - url of service - * @param {String} [options.searchOptions.serviceOptions.index] - index of search, "standard" by default - * @param {String} [options.searchOptions.serviceOptions.fields] - list of search fields, each field is separated by a comma. "title,layer_name" by default - * @param {Number} [options.searchOptions.serviceOptions.size] - number of response in the service. 1000 by default - * @param {String} [options.searchOptions.serviceOptions.services] - list of search services, each field is separated by a comma. "WMTS,WMS" by default - * @param {Number} [options.searchOptions.serviceOptions.maximumResponses] - number of results in the response. 10 by default - * @param {Object} [options.geocodeOptions = {}] - options of geocode service (see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~geocode Gp.Services.geocode}) - * @param {Object} [options.geocodeOptions.serviceOptions] - options of geocode service - * @param {Object} [options.autocompleteOptions = {}] - options of autocomplete service (see {@link http://ignf.github.io/geoportal-access-lib/latest/jsdoc/module-Services.html#~autoComplete Gp.Services.autoComplete}) - * @param {Object} [options.autocompleteOptions.serviceOptions] - options of autocomplete service - * @param {Boolean} [options.autocompleteOptions.triggerGeocode = false] - trigger a geocoding request if the autocompletion does not return any suggestions, false by default - * @param {Number} [options.autocompleteOptions.triggerDelay = 1000] - waiting time before sending the geocoding request, 1000ms by default - * @param {Sting|Numeric|Function} [options.zoomTo] - zoom to results, by default, current zoom. - * Value possible : auto or zoom level. - * Possible to overload it with a function : - * zoomTo : function (info) { - * // do some stuff... - * return zoom; - * } - * @fires searchengine:autocomplete:click - * @fires searchengine:geocode:click - * @fires searchengine:search:click - * @todo option : direction (start|end) de la position du picto (loupe) - * @todo option : choix du target pour les fenetres geocodage ou recherche par coordonnées - * @example - * var SearchEngine = ol.control.SearchEngine({ - * apiKey : "CLEAPI", - * collapsed : true, - * opened : false, - * displayButtonAdvancedSearch : true, - * displayButtonGeolocate : true, - * displayButtonCoordinateSearch : true, - * resources : { - * geocode : ["StreetAddress", "PositionOfInterest"], - * autocomplete : ["StreetAddress"], - * search : false - * }, - * advancedSearch : { - * target : document.getElementById("dialog"), - * PositionOfInterest : [{name : "municipality", title : "Ville"}], - * StreetAddress : [{...}] - * }, - * coordinateSearch : { - * target : null - * systems : [ - * { - * "crs" : "EPSG:3857", - * "label" : "Web Mercator", - * "type" : "Metric" - * }, - * { - * "crs" : "EPSG:4326", - * "label" : "Géographiques", - * "type" : "Geographical" - * } - * ], - * units : ["DEC", "DMS"] - * }, - * geocodeOptions : {}, - * autocompleteOptions : {}, - * searchOptions : {} - * }); - * - * SearchEngine.on("searchengine:autocomplete:click", function (e) { - * console.warn("autocomplete", e.location); - * }); - * SearchEngine.on("searchengine:search:click", function (e) { - * console.warn("search", e.suggest); - * }); - * SearchEngine.on("searchengine:geocode:click", function (e) { - * console.warn("geocode", e.location); - * }); - */ -var SearchEngine = class SearchEngine extends Control { - - /** - * See {@link ol.control.SearchEngine} - * @module SearchEngine - * @alias module:~Controls/SearchEngine - * @param {*} options - options - * @example - * import SearchEngine from "src/OpenLayers/Controls/SearchEngine" - */ - constructor (options) { - options = options || {}; - - // call ol.control.Control constructor - super({ - element : options.element, - target : options.target, - render : options.render - }); - - if (!(this instanceof SearchEngine)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - // initialisation du composant - this.initialize(options); - - // // Widget main DOM container - this.container = this._initContainer(); - - // ajout du container - (this.element) ? this.element.appendChild(this.container) : this.element = this.container; - - return this; - } - - // ################################################################### // - // ##################### public methods ############################## // - // ################################################################### // - - /** - * Overwrite OpenLayers setMap method - * - * @param {ol.Map} map - Map. - */ - setMap (map) { - if (!map) { - this._clearResults(); - } - - // mode "collapsed" - if (!this.collapsed) { - this._showSearchEngineButton.setAttribute("aria-pressed", true); - } - - // on appelle la méthode setMap originale d'OpenLayers - super.setMap(map); - - // position - if (this.options.position) { - this.setPosition(this.options.position); - } - } - - /** - * Returns true if widget is collapsed (minimized), false otherwise - * - * @returns {Boolean} collapsed - true if widget is collapsed - */ - getCollapsed () { - return this.collapsed; - } - - /** - * Collapse or display widget main container - * - * @param {Boolean} collapsed - True to collapse widget, False to display it - */ - setCollapsed (collapsed) { - if (collapsed === undefined) { - logger.log("[ERROR] SearchEngine:setCollapsed - missing collapsed parameter"); - return; - } - if ((collapsed && this.collapsed) || (!collapsed && !this.collapsed)) { - return; - } - - this._showSearchEngineButton.click(); - this.collapsed = collapsed; - } - - /** - * Get locations data from geocode service - * - * @returns {Object} data - locations - */ - getData () { - return this._geocodedLocations; - } - - // ################################################################### // - // ##################### init component ############################## // - // ################################################################### // - - /** - * Initialize SearchEngine control (called by SearchEngine constructor) - * - * @param {Object} options - constructor options - * @private - */ - initialize (options) { - this._checkInputOptions(options); - - // define default options - this.options = { - collapsed : true, - opened : false, - zoomTo : "", - resources : { - geocode : "", - autocomplete : [], - search : false - }, - displayButtonClose : true, - displayButtonAdvancedSearch : false, - displayButtonGeolocate : false, - displayButtonCoordinateSearch : false, - advancedSearch : {}, - coordinateSearch : {}, - searchOptions : { - serviceOptions : {} - }, - geocodeOptions : { - serviceOptions : {} - }, - autocompleteOptions : { - serviceOptions : {}, - triggerGeocode : false, - triggerDelay : 1000 - }, - displayMarker : true, - markerStyle : "lightOrange", - placeholder : "Rechercher un lieu, une adresse" - }; - - // merge with user options - Utils.mergeParams(this.options, options); - if (this.options.resources.geocode === "") { - this.options.resources.geocode = "poi,address"; - } - if (this.options.resources.autocomplete.length === 0) { - this.options.resources.autocomplete = ["PositionOfInterest", "StreetAddress"]; - } - if (this.options.resources.search) { - // configuration avec gestion des options surchargées du service - if (this.options.searchOptions.serviceOptions.url) { - Search.setUrl(this.options.searchOptions.serviceOptions.url); - } - if (this.options.searchOptions.serviceOptions.fields) { - Search.setFields(this.options.searchOptions.serviceOptions.fields); - } - if (this.options.searchOptions.serviceOptions.index) { - Search.setIndex(this.options.searchOptions.serviceOptions.index); - } - if (this.options.searchOptions.serviceOptions.size) { - Search.setSize(this.options.searchOptions.serviceOptions.size); - } - if (this.options.searchOptions.serviceOptions.services) { - Search.setFiltersByService(this.options.searchOptions.serviceOptions.services); - } - if (this.options.searchOptions.serviceOptions.maximumResponses) { - Search.setMaximumResponses(this.options.searchOptions.serviceOptions.maximumResponses); - } - // abonnement au service - Search.target.addEventListener("suggest", (e) => { - logger.debug(e); - this._fillSearchedSuggestListContainer(e.detail); - }); - } - - /** {Boolean} specify if searchEngine control is collapsed (true) or not (false) */ - this.collapsed = this.options.collapsed; - - // identifiant du contrôle : utile pour suffixer les identifiants CSS (pour gérer le cas où il y en a plusieurs dans la même page) - this._uid = SelectorID.generate(); - - this._showSearchEngineButton = null; - - // container de l'input de recherche - this._inputSearchContainer = null; - - // container des reponses de l'autocompletion / du service de recherche - this._autocompleteContainer = null; - this._containerResultsLocation = null; - this._containerResultsSuggest = null; - - // listes des reponses de l'autocompletion - this._suggestedLocations = []; - - // container des reponses du geocodage - this._geocodedContainer = null; - - // liste des reponses du geocodage - this._geocodedLocations = []; - - // container des filtres du geocodage - this._filterContainer = null; - - // ressource de geocodage selectionnée pour le geocodage avancé - this._currentGeocodingCode = null; - - // localisant - this._currentGeocodingLocation = null; - - // liste des filtres du geocodage pour le geocodage avancé - this._advancedSearchFilters = {}; - this._initAdvancedSearchFilters(); - - // liste des ressources du geocodage pour le geocodage avancé - this._advancedSearchCodes = []; - this._initAdvancedSearchCodes(); - - // recherche par coordonnées : systemes de projections - this._coordinateSearchSystems = []; - if (this.options.displayButtonCoordinateSearch) { - this._initCoordinateSearchSystems(); - this._currentCoordinateSearchSystems = this._coordinateSearchSystems[0]; // epsg:4326 - this._currentCoordinateSearchType = this._coordinateSearchSystems[0].type; // geographical ou metric - } - - // recherche par coordonnées : unités - this._coordinateSearchUnits = []; - if (this.options.displayButtonCoordinateSearch) { - this._initCoordinateSearchUnits(); - this._currentCoordinateSearchUnits = this._coordinateSearchUnits[this._currentCoordinateSearchType][0].code; // decimal - } - - - this._coordinateSearchLngInput = null; - this._coordinateSearchLatInput = null; - - // marker - this._marker = null; - - // marker style - var _markerStyle = this.options.markerStyle; - this._markerUrl = (Object.keys(Markers).indexOf(_markerStyle) === -1) ? Markers["lightOrange"] : Markers[_markerStyle]; - - // marker display - this._displayMarker = this.options.displayMarker; - - // popup - this._popupContent = null; - this._popupDiv = this._initPopupDiv(); - this._popupOverlay = null; - - // trigger geocode - this._triggerHandler = null; - } - - /** - * this method is called by this.initialize() - * and makes sure input options are correctly formated - * - * @param {Object} options - options - * - * @private - */ - _checkInputOptions (options) { - var i; - - if (options.resources) { - // on vérifie que resources est bien un objet - if (typeof options.resources === "object") { - // ressources de geocodage - var geocodeResources = options.resources.geocode; - if (geocodeResources) { - // on vérifie que la liste des ressources de geocodage est bien un tableau - if (Array.isArray(geocodeResources)) { - var geocodeResourcesList = ["StreetAddress", "PositionOfInterest", "CadastralParcel", "Administratif"]; - for (i = 0; i < geocodeResources.length; i++) { - if (geocodeResourcesList.indexOf(geocodeResources[i]) === -1) { - // si la resource n'est pas référencée, on l'enlève - // geocodeResources.splice(i, 1); - logger.log("[SearchEngine] options.resources.geocode : " + geocodeResources[i] + " is not a resource for geocode"); - } - } - } else { - logger.log("[SearchEngine] 'options.resources.geocode' parameter should be an array"); - geocodeResources = null; - } - } - - // ressources d'autocompletion - var autocompleteResources = options.resources.autocomplete; - if (autocompleteResources) { - // on vérifie que la liste des ressources d'autocompletion est bien un tableau - if (Array.isArray(autocompleteResources)) { - var autocompleteResourcesList = ["StreetAddress", "PositionOfInterest"]; - for (i = 0; i < autocompleteResources.length; i++) { - if (autocompleteResourcesList.indexOf(autocompleteResources[i]) === -1) { - // si la resource n'est pas référencée, on l'enlève - // autocompleteResources.splice(i, 1); - logger.log("[SearchEngine] options.resources.autocomplete : " + autocompleteResources[i] + " is not a resource for autocomplete"); - } - } - } else { - logger.log("[SearchEngine] 'options.resources.autocomplete' parameter should be an array"); - autocompleteResources = null; - } - } - } else { - logger.log("[SearchEngine] 'resources' parameter should be an object"); - options.resources = null; - } - } - } - - /** - * this method is called by this.initialize() - * and initialize the geocoding resources titles. - * - * @private - */ - _initAdvancedSearchCodes () { - // INFORMATION - // on y ajoute les filtres attributaires pour une table de ressources - // selectionnée via un evenement (onchange) de la liste deroulante du - // menu avancé du geocodage. - // cf. onGeocodingAdvancedSearchCodeChange() pour la selection de la - // ressource de geocodage à afficher - - var geocodeResources = this.options.resources.geocode; - if (geocodeResources === "location") { - geocodeResources = ["PositionOfInterest", "StreetAddress", "CadastralParcel"]; - } - if (!Array.isArray(geocodeResources)) { - geocodeResources = [geocodeResources]; - } - for (var i = 0; i < geocodeResources.length; i++) { - switch (geocodeResources[i]) { - case "PositionOfInterest": - this._advancedSearchCodes.push({ - id : "PositionOfInterest", - title : "Lieux/toponymes" - }); - break; - case "StreetAddress": - this._advancedSearchCodes.push({ - id : "StreetAddress", - title : "Adresses" - }); - break; - case "CadastralParcel": - this._advancedSearchCodes.push({ - id : "CadastralParcel", - title : "Parcelles cadastrales" - }); - break; - default: - break; - } - } - // par défaut, au cas où aucune ressource passée en option ne correspond à celles attendues - if (this._advancedSearchCodes.length === 0) { - this._advancedSearchCodes = [{ - id : "StreetAddress", - title : "Adresses" - }, { - id : "PositionOfInterest", - title : "Lieux/toponymes" - }, { - id : "CadastralParcel", - title : "Cadastre" - }]; - } - - logger.log("advancedSearchCodes", this._advancedSearchCodes); - } - - /** - * this method is called by this.onAdd() - * and initialize the advanced geocoding filters. - * - * @private - */ - _initAdvancedSearchFilters () { - // liste des filtres par defauts pour toutes les ressources - this._advancedSearchFilters = SearchEngineUtils.advancedSearchFiltersByDefault; - - // on merge les options avancées avec celles par defaut - var advancedSearchFiltersCustom = this.options.advancedSearch; - Utils.assign(this._advancedSearchFilters, advancedSearchFiltersCustom); - - logger.log("advancedSearchFilters", this._advancedSearchFilters); - } - - /** - * this method is called by the constructor and initialize the projection - * systems. - * getting coordinates in the requested projection : - * see this.onCoordinateSearchSystemChange() - * - * @private - */ - _initCoordinateSearchSystems () { - // on donne la possibilité à l'utilisateur de modifier - // la liste des systèmes à afficher - // Ex. this.options.coordinateSearch.systems - - // systemes de projection disponible par defaut - var projectionSystemsByDefault = [{ - label : "G\u00e9ographique", - crs : "EPSG:4326", - type : "Geographical" - }, { - label : "Web Mercator", - crs : "EPSG:3857", - type : "Metric" - }, { - label : "Lambert 93", - crs : "EPSG:2154", - type : "Metric" - }]; - - var systems = this.options.coordinateSearch.systems; - if (systems) { - // on ajoute les definitions d'un systeme de reference fournies par l'utilisateur - for (var i = 0; i < systems.length; i++) { - var sys = systems[i]; - this._setSystem(sys); - } - } - - // on ajoute les systèmes de projections par défaut - if (this._coordinateSearchSystems.length === 0) { - for (var j = 0; j < projectionSystemsByDefault.length; j++) { - this._setSystem(projectionSystemsByDefault[j]); - } - } - } - - /** - * this method is called by the constructor and initialize the units. - * getting coordinates in the requested units : - * see this.onCoordinateSearchUnitsChange() - * - * @private - */ - _initCoordinateSearchUnits () { - // on donne la possibilité à l'utilisateur de modifier - // la liste des unités à afficher - // Ex. - // this.options.units : ["DEC", "DMS"] - - // unités disponible par defaut - var projectionUnitsByDefault = { - Geographical : [{ - code : "DEC", - label : "degrés décimaux", - format : MathUtils.coordinateToDecimal - }, { - code : "DMS", - label : "degrés sexagésimaux", - format : MathUtils.coordinateToDMS - }], - Metric : [{ - code : "M", - label : "mètres", - format : MathUtils.coordinateToMeter - }, { - code : "KM", - label : "kilomètres", - format : MathUtils.coordinateToKMeter - }] - }; - - var units = this.options.coordinateSearch.units; - if (units) { - for (var type in projectionUnitsByDefault) { - if (projectionUnitsByDefault.hasOwnProperty(type)) { - var found = false; - for (var j = 0; j < projectionUnitsByDefault[type].length; j++) { - var obj = projectionUnitsByDefault[type][j]; - for (var i = 0; i < units.length; i++) { - var unit = units[i]; - if (obj.code === unit) { - found = true; - if (!this._coordinateSearchUnits[type]) { - this._coordinateSearchUnits[type] = []; - } - this._coordinateSearchUnits[type].push(obj); - } - } - } - if (!found) { - this._coordinateSearchUnits[type] = projectionUnitsByDefault[type]; - } - } - } - } - - // au cas où... - if (typeof this._coordinateSearchUnits === "object" && Object.keys(this._coordinateSearchUnits).length === 0) { - this._coordinateSearchUnits = projectionUnitsByDefault; - } - } - - /** - * this method is called by this.initialize() and initialize popup div - * (to display results information on marker click) - * - * @return {Object} element - DOM element for popup - * @private - */ - _initPopupDiv () { - var context = this; - var element = document.createElement("div"); - element.className = "gp-feature-info-div"; - var closer = document.createElement("input"); - closer.type = "button"; - closer.className = "gp-styling-button closer"; - // on closer click : remove popup - closer.onclick = function () { - if (context._popupOverlay != null) { - context._popupOverlay.setPosition(undefined); - } - return false; - }; - this._popupContent = document.createElement("div"); - this._popupContent.className = "gp-features-content-div"; - this._popupContent.style["min-width"] = "200px"; - element.appendChild(this._popupContent); - element.appendChild(closer); - - return element; - } - - // ################################################################### // - // ######################## DOM initialize ########################### // - // ################################################################### // - - /** - * Create control main container - * - * @returns {DOMElement} DOM element - * - * @private - */ - _initContainer () { - // create main container - var container = this._createMainContainerElement(); - - var searchDiv = this._createSearchDivElement(); - // create search engine picto - var picto = this._showSearchEngineButton = this._createShowSearchEnginePictoElement(this.options.opened); - searchDiv.appendChild(picto); - - // only dsfr : on applique un fond blanc sur une barre de recherche fixe - if (this.options.opened) { - container.classList.add("gpf-widget-color", "gpf-widget-padding"); - } - - var search = this._inputSearchContainer = this._createSearchInputElement(this.options.placeholder); - if (this.options.displayButtonClose) { - search.appendChild(this._createSearchResetElement()); - } - - var context = this; - if (search.addEventListener) { - search.addEventListener("click", function () { - context.onAutoCompleteInputClick(); - }); - } else if (search.attachEvent) { - search.attachEvent("onclick", function () { - context.onAutoCompleteInputClick(); - }); - } - searchDiv.appendChild(search); - - container.appendChild(searchDiv); - var buttonsContainer = this._createButtonsElement(); - container.appendChild(buttonsContainer); - - if (this.options.displayButtonAdvancedSearch) { - var advancedShow = this._createShowAdvancedSearchElement(); - buttonsContainer.appendChild(advancedShow); - - // INFO je decompose les appels car j'ai besoin de recuperer le container - // des filtres - var advancedPanel = this._createAdvancedSearchPanelElement(); - var advancedPanelDiv = this._createAdvancedSearchPanelDivElement(); - var advancedHeader = this._createAdvancedSearchPanelHeaderElement(); - var advancedForm = this._createAdvancedSearchPanelFormElement(this._advancedSearchCodes); - var advancedFormFilters = this._filterContainer = this._createAdvancedSearchFormFiltersElement(); - this._setFilter(this._advancedSearchCodes[0].id); // ex "PositionOfInterest" - var advancedFormInput = this._createAdvancedSearchFormInputElement(); - - advancedForm.appendChild(advancedFormFilters); - advancedForm.appendChild(advancedFormInput); - advancedPanelDiv.appendChild(advancedHeader); - advancedPanelDiv.appendChild(advancedForm); - advancedPanel.appendChild(advancedPanelDiv); - container.appendChild(advancedPanel); - } - - if (this.options.displayButtonGeolocate) { - var geolocateShow = this._createShowGeolocateElement(); - buttonsContainer.appendChild(geolocateShow); - } - - if (this.options.displayButtonCoordinateSearch) { - var searchByCoordinateShow = this._createShowSearchByCoordinateElement(); - buttonsContainer.appendChild(searchByCoordinateShow); - - var coordinatePanel = this._createCoordinateSearchPanelElement(); - var coordinatePanelDiv = this._createCoordinateSearchPanelDivElement(); - var coordinateHeader = this._createCoordinateSearchPanelHeaderElement(); - var coordinateForm = this._createCoordinateSearchPanelFormElement(); - - var div = null; - div = this._containerSystems = this.__createCoordinateSearchDivElement(); - coordinateForm.appendChild(div); - var labelSystems = this._createCoordinateSearchSystemsLabelElement(); - var systems = this._setCoordinateSearchSystemsSelectElement(this._coordinateSearchSystems); - div.appendChild(labelSystems); - div.appendChild(systems); - - div = this._containerUnits = this.__createCoordinateSearchDivElement(); - coordinateForm.appendChild(div); - var labelUnits = this._createCoordinateSearchUnitsLabelElement(); - var units = this._setCoordinateSearchUnitsSelectElement(this._coordinateSearchUnits[this._currentCoordinateSearchType]); - div.appendChild(labelUnits); - div.appendChild(units); - - div = this._containerCoordinateLng = this.__createCoordinateSearchDivElement(); - coordinateForm.appendChild(div); - var coordinateLng = this._setCoordinateSearchLngLabelElement(this._currentCoordinateSearchType); - var coordinateInputLng = this._coordinateSearchLngInput = this._setCoordinateSearchLngInputElement(this._currentCoordinateSearchUnits); - div.appendChild(coordinateLng); - div.appendChild(coordinateInputLng); - - div = this._containerCoordinateLat = this.__createCoordinateSearchDivElement(); - coordinateForm.appendChild(div); - var coordinateLat = this._setCoordinateSearchLatLabelElement(this._currentCoordinateSearchType); - var coordinateInputLat = this._coordinateSearchLatInput = this._setCoordinateSearchLatInputElement(this._currentCoordinateSearchUnits); - div.appendChild(coordinateLat); - div.appendChild(coordinateInputLat); - - var submit = this._createCoordinateSearchSubmitElement(); - coordinateForm.appendChild(submit); - - coordinatePanelDiv.appendChild(coordinateHeader); - coordinatePanelDiv.appendChild(coordinateForm); - - coordinatePanel.appendChild(coordinatePanelDiv); - container.appendChild(coordinatePanel); - } - - // INFO je decompose les appels car j'ai besoin de recuperer le container - // des resultats de l'autocompletion - var autocomplete = this._autocompleteContainer = this._createAutoCompleteElement(); - var autocompleteList = this._createAutoCompleteListElement(); - var containerResultsLocation = this._containerResultsLocation = this._createAutoCompletedLocationContainer(); - var containerResultsSuggest = this._containerResultsSuggest = this._createSearchedSuggestContainer(); - autocompleteList.appendChild(containerResultsLocation); - autocompleteList.appendChild(containerResultsSuggest); - autocomplete.appendChild(autocompleteList); - container.appendChild(autocomplete); - - // INFO je decompose les appels car j'ai besoin de recuperer le container - // des resultats du geocodage - var geocode = this._createGeocodeResultsElement(); - var geocodeDiv = this._createGeocodeResultsDivElement(); - geocode.appendChild(geocodeDiv); - var geocodeList = this._geocodedContainer = this._createGeocodeResultsListElement(); - geocodeDiv.appendChild(geocodeList); - container.appendChild(geocode); - - return container; - } - - /** - * this method is called by : - * - this._initContainer() : ... - * - this.onGeocodingAdvancedSearchCodeChoice() : ... - * and initialize or create the filters container HTMLElement - * to the geocoding advanced menu. - * - * @param {String} code - resource geocoding name - * - * @returns {DOMElement} DOM element - * @private - */ - _setFilter (code) { - // INFORMATION - // Nous avons 2 solutions possibles pour la mise en place des filtres. - // 1. Soit on decide de creer tous les filtres pour chaque ressource - // de geocodage à l'initialisation du composant, et on joue sur le - // mode 'hidden' pour n'afficher que la ressource selectionnée. - // 2. Soit on decide de creer à chaque fois les filtres pour la - // ressource selectionnée. - // Chaque solution a ses inconvenients/avantages. - // Implementation du choix 2 car elle offre plus de souplesse pour - // recuperer les 'form-data'... - - var container = this._filterContainer; - - var codeFound = false; - for (var i = 0; i < this._advancedSearchCodes.length; i++) { - if (this._advancedSearchCodes[i].id === code) { - codeFound = true; - break; - } - } - - if (!codeFound) { - // cette ressource n'est pas disponible, - // on supprime les anciens enfants... - while (container.firstChild) { - container.removeChild(container.firstChild); - } - return; - } - - // on sauvegarde la ressource de geocodage sélectionnée - this._currentGeocodingCode = code; - - // on supprime les enfants... - while (container.firstChild) { - container.removeChild(container.firstChild); - } - - var lstAttributs = this._advancedSearchFilters[code]; - if (!lstAttributs || lstAttributs.length === 0) { - // cette ressource n'est pas parametrable - return; - } - - var divTable = this._createAdvancedSearchFiltersTableElement(code, true); - - for (var j = 0; j < lstAttributs.length; j++) { - var divFilter = this._createAdvancedSearchFiltersAttributElement(lstAttributs[j]); - divTable.appendChild(divFilter); - } - - container.appendChild(divTable); - - return container; - } - - // ################################################################### // - // ################ methods to request and results ################### // - // ################################################################### // - - /** - * this method is called by this.onAutoCompleteSearch() - * and executes a request to the service. - * - * @param {Object} settings - service settings - * @param {String} settings.text - text - * @param {Function} settings.onSuccess - callback - * @param {Function} settings.onFailure - callback - * @private - */ - _requestAutoComplete (settings) { - // on ne fait pas de requête si on n'a pas renseigné de parametres ! - if (!settings || (typeof settings === "object" && Object.keys(settings).length === 0)) { - return; - } - - // on ne fait pas de requête si la parametre 'text' est vide ! - if (!settings.text) { - return; - } - - logger.log(settings); - - var options = {}; - // on recupere les options du service - Utils.assign(options, this.options.autocompleteOptions.serviceOptions); - // ainsi que la recherche et les callbacks - Utils.assign(options, settings); - - // on ajoute le paramètre filterOptions.type spécifiant les ressources. - var resources = this.options.resources.autocomplete; - if (resources && Array.isArray(resources)) { - // il se peut que l'utilisateur ait surchargé ce paramètre dans geocodeOptions, - if (!options.type) { - options.type = resources; - } - } - - // cas où la clef API n'est pas renseignée dans les options du service, - // on utilise celle renseignée au niveau du controle ou la clé "calcul" par défaut. - options.apiKey = options.apiKey || this.options.apiKey; - - // si l'utilisateur a spécifié le paramètre ssl au niveau du control, on s'en sert - // true par défaut (https) - if (typeof options.ssl !== "boolean") { - if (typeof this.options.ssl === "boolean") { - options.ssl = this.options.ssl; - } else { - options.ssl = true; - } - } - logger.log(options); - - Gp.Services.autoComplete(options); - } - - /** - * this method is called by this.onAutoCompleteSearchText() (case of success) - * and fills the container of the location list. - * it creates a HTML Element per location - * - * @param {Array} locations - Array of Gp.Services.AutoComplete.SuggestedLocation corresponding to autocomplete results list - * @private - */ - _fillAutoCompletedLocationListContainer (locations) { - if (!locations || locations.length === 0) { - return; - } - - // on vide la liste avant de la construire - var element = this._containerResultsLocation; - if (element.childElementCount) { - while (element.firstChild) { - element.removeChild(element.firstChild); - } - } - element.classList.add("GPelementHidden", "gpf-hidden"); - if (locations.length) { - element.classList.remove("GPelementHidden", "gpf-hidden"); - this._displaySuggestedLocation(); - this._createAutoCompletedLocationTitleElement(); - for (var i = 0; i < locations.length; i++) { - // Proposals are dynamically filled in Javascript by autocomplete service - this._createAutoCompletedLocationElement(locations[i], i); - } - } - } - - /** - * this method is called by this.() (case of success) - * and fills the container of the suggest list. - * it creates a HTML Element per suggest - * - * @param {Array} suggests - Array of suggested corresponding to search results list - * @private - */ - _fillSearchedSuggestListContainer (suggests) { - // on vide la liste avant de la construire - var element = this._containerResultsSuggest; - if (element.childElementCount) { - while (element.firstChild) { - element.removeChild(element.firstChild); - } - } - element.classList.add("GPelementHidden", "gpf-hidden"); - if (suggests.length) { - element.classList.remove("GPelementHidden", "gpf-hidden"); - this._createSearchedSuggestTitleElement(); - for (let i = 0; i < suggests.length; i++) { - const suggest = suggests[i]; - this._createSearchedSuggestElement(suggest, i); - } - } - } - - /** - * this method is called by this.onAutoCompleteSearch() - * and executes a request to the service. - * - * @param {Object} settings - service settings - * @param {String} settings.location - text - * @param {Function} settings.onSuccess - callback - * @param {Function} settings.onFailure - callback - * @private - */ - _requestGeocoding (settings) { - // on ne fait pas de requête si on n'a pas renseigné de parametres ! - if (!settings || (typeof settings === "object" && Object.keys(settings).length === 0)) { - return; - } - - // on ne fait pas de requête si la parametre 'text' est vide ! - if (settings.query === null) { - return; - } - - logger.log(settings); - - var options = {}; - // on recupere les options du service - Utils.assign(options, this.options.geocodeOptions.serviceOptions); - // ainsi que la recherche et les callbacks - Utils.assign(options, settings); - // on redefinie les callbacks si les callbacks de service existent - var self = this; - var bOnFailure = !!(this.options.geocodeOptions.serviceOptions.onFailure !== null && typeof this.options.geocodeOptions.serviceOptions.onFailure === "function"); // cast variable to boolean - var bOnSuccess = !!(this.options.geocodeOptions.serviceOptions.onSuccess !== null && typeof this.options.geocodeOptions.serviceOptions.onSuccess === "function"); - if (bOnSuccess) { - var cbOnSuccess = function (e) { - settings.onSuccess.call(self, e); - self.options.geocodeOptions.serviceOptions.onSuccess.call(self, e); - }; - options.onSuccess = cbOnSuccess; - } - if (bOnFailure) { - var cbOnFailure = function (e) { - settings.onFailure.call(self, e); - self.options.geocodeOptions.serviceOptions.onFailure.call(self, e); - }; - options.onFailure = cbOnFailure; - } - - // on ajoute le paramètre index spécifiant les ressources. - var resources = this.options.resources.geocode; - if (resources) { - // il se peut que l'utilisateur ait surchargé ce paramètre dans geocodeOptions, - // ou qu'il ait déjà été rempli (cas de la recherche avancée) - if (!options.index) { - options.index = resources; - } - } - - // cas où la clef API n'est pas renseignée dans les options du service, - // on utilise celle renseignée au niveau du controle ou la clé "calcul" par défaut - options.apiKey = options.apiKey || this.options.apiKey; - - // si l'utilisateur a spécifié le paramètre ssl au niveau du control, on s'en sert - // true par défaut (https) - if (typeof options.ssl !== "boolean") { - if (typeof this.options.ssl === "boolean") { - options.ssl = this.options.ssl; - } else { - options.ssl = true; - } - } - - logger.log(options); - - Gp.Services.geocode(options); - } - - /** - * this method is called by this.onGeocodingSearch() - * and fills the container of the location results. - * it creates a HTML Element per location - * (cf. this. ...) - * - * @param {Object[]} locations - locations - * - * @private - */ - _fillGeocodedLocationListContainer (locations) { - if (!locations || locations.length === 0) { - this._clearGeocodedLocation(); - return; - } - - // on vide la liste avant de la construire - var element = this._geocodedContainer; - if (element.childElementCount) { - while (element.firstChild) { - element.removeChild(element.firstChild); - } - } - - for (var i = 0; i < locations.length; i++) { - logger.log(locations[i]); - // Proposals are dynamically filled in Javascript by autocomplete service - this._createGeocodedLocationElement(locations[i], i); - } - - // sauvegarde de l'etat des locations - this._geocodedLocations = locations; - } - - // ################################################################### // - // ######################### other methods ########################### // - // ################################################################### // - - /** - * this sends the label to the panel. - * - * @param {String} label - label suggested location - * @private - */ - _setLabel (label) { - document.getElementById("GPsearchInputText-" + this._uid).value = label; - } - - /** - * this method is called by this.on*ResultsItemClick() - * and move/zoom on a position. - * - * @param {Array} position - ol.Coordinate object [lon, lat] (en lat/lon : "EPSG:4326") - * @param {Number} zoom - zoom level - * @private - */ - _setPosition (position, zoom) { - var view = this.getMap().getView(); - view.setCenter(position); - view.setZoom(zoom); - } - - /** - * this method is called by this.on*ResultsItemClick() - * and displays a marker. - * FIXME - * - * @param {Array} position - ol.Coordinate object [lon, lat] ou [x, y] - * @param {Object} info - location information - * @private - */ - _setMarker (position, info) { - var map = this.getMap(); - var context = this; - - // remove previous markers - if (this._marker != null) { - map.removeOverlay(this._marker); - this._marker = null; - } - - if (position) { - // création de l'élément DOM - var markerDiv = document.createElement("img"); - markerDiv.src = this._markerUrl; - - // ajout de l'évènement onclick (pour afficher une popup) - if (markerDiv.addEventListener) { - markerDiv.addEventListener( - "click", - function () { - context._onResultMarkerSelect(info); - } - ); - } else if (markerDiv.attachEvent) { - // Internet Explorer - markerDiv.attachEvent( - "onclick", - function () { - context._onResultMarkerSelect(info); - } - ); - } - - // création du marker (overlay) - this._marker = new Overlay({ - position : position, - offset : [-25.5, -38], - element : markerDiv, - stopEvent : false - }); - map.addOverlay(this._marker); - } - } - - /** - * this method is called by this.on*ResultsItemClick() - * and get zoom to results. - * - * @param {Object} info - info - * - * @returns {Integer} zoom - * @private - */ - _getZoom (info) { - var map = this.getMap(); - var key = this.options.zoomTo; - var zoom = null; - - // les valeurs du zooms sont determinées - // soit par les mots clefs suivants : max, min ou auto - // soit par un niveau de zoom - // soit defini par l'utilisateur via une fonction - - if (typeof key === "function") { - logger.trace("zoom function"); - zoom = key.call(this, info); - } - - if (typeof key === "number") { - logger.trace("zoom level"); - zoom = key; - } - - if (typeof key === "string") { - // if (key === "max") { - // zoom = map.getMaxZoom(); - // } else if (key === "min") { - // zoom = map.getMinZoom(); - // } else - - if (key === "auto") { - logger.trace("zoom auto"); - zoom = SearchEngineUtils.zoomToResultsByDefault(info); - } else { - logger.trace("zoom level parsing"); - var value = parseInt(key, 10); - if (!isNaN(value)) { - logger.trace("zoom parsing"); - zoom = value; - } - } - } - - // polyfill IE - Number.isInteger = Number.isInteger || function (value) { - return typeof value === "number" && - isFinite(value) && - Math.floor(value) === value; - }; - - // test de validité du zoom, - // on prend le zoom courant par defaut ... - if (!zoom || zoom === "" || !Number.isInteger(zoom)) { - logger.trace("zoom not found, current zoom..."); - zoom = map.getView().getZoom(); - } - - // FIXME test si le zoom est dans l'espace de la carte - var min = map.minZoom; // .getMinZoom(); - var max = map.maxZoom; // .getMaxZoom(); - if (zoom < min) { - logger.trace("zoom level min..."); - zoom = min; - } - if (zoom > max) { - logger.trace("zoom level max..."); - zoom = max; - } - - logger.trace("zoom", zoom); - return zoom; - } - - /** - * this method is called on 'click' on this._marker - * (cf. this._setMarker() ) - * and sets a popup with marker information - * - * @param {Object} information - location information - * @private - */ - _onResultMarkerSelect (information) { - var map = this.getMap(); - - var popupContent = ""; - if (typeof information !== "string") { - if (information.service === "GeocodedLocation") { - popupContent = "
    "; - var attributes = information.location.placeAttributes; - for (var attr in attributes) { - if (attributes.hasOwnProperty(attr)) { - if (attr !== "trueGeometry" && attr !== "extraFields" && attr !== "houseNumberInfos" && attr !== "_count") { - popupContent += "
  • "; - popupContent += "" + attr.toUpperCase() + " : "; - popupContent += attributes[attr]; - popupContent += "
  • "; - } - } - } - popupContent += "
"; - } else if (information.service === "SuggestedLocation") { - popupContent = GeocodeUtils.getSuggestedLocationFreeform(information.location); - } else { - popupContent = "sans informations."; - } - } else { - popupContent = information; - } - - this._popupContent.innerHTML = popupContent; - if (!this._popupOverlay) { - // ajout de la popup a la carte comme un overlay - this._popupOverlay = new Overlay({ - element : this._popupDiv, - positioning : "bottom-center", - position : this._marker.getPosition(), - offset : [0, -42] - }); - map.addOverlay(this._popupOverlay); - } else { - // si l'overlay est déjà créé, on modifie juste sa position - this._popupOverlay.setPosition(this._marker.getPosition()); - } - } - - /** - * Set additional projection system - * - * @param {Object} system - projection system - * @param {String} system.crs - Proj4 crs alias (from proj4 defs) e.g. "EPSG:4326" - * @param {String} [system.label] - CRS label to be displayed in control. Default is system.crs alias - * @param {String} [system.type] - CRS units type for coordinates conversion (one of control options.units). Default is "Metric" - */ - _setSystem (system) { - if (typeof system !== "object") { - logger.log("[ERROR] MousePosition:addSystem - system parameter should be an object"); - return; - } - if (!system.crs) { - logger.error("crs not defined !"); - return; - } - if (!system.label) { - logger.warn("crs label not defined, use crs code by default."); - system.label = system.crs; - } - if (!system.type) { - logger.warn("type srs not defined, use 'Metric' by default."); - system.type = "Metric"; - } - - // chargement de la definition de la projection - // même si déjà chargé... - CRS.loadByName(system.crs); - - if (!olProjGet(system.crs)) { - logger.error("crs '{}' not available into proj4 definitions !", system.crs); - return; - } - - // add system to control systems - for (var j = 0; j < this._coordinateSearchSystems.length; j++) { - var obj = this._coordinateSearchSystems[j]; - if (system.crs === obj.crs) { - // warn user - logger.info("crs '{}' already configured", obj.crs); - } - } - system.code = this._coordinateSearchSystems.length; - this._coordinateSearchSystems.push(system); - } - - // ################################################################### // - // ###################### other handlers events ###################### // - // ################################################################### // - - /** - * this method is called by event 'click' on 'GPshowSearchEnginePicto' tag label - * (cf. this._createShowSearchEnginePictoElement), and it cleans the component - * when it's closed. - * - * @private - */ - onShowSearchEngineClick () { - var map = this.getMap(); - // on supprime toutes les interactions - Interactions.unset(map); - var opened = this._showSearchEngineButton.ariaPressed; - this.collapsed = !(opened === "true"); - // on génère nous même l'evenement OpenLayers de changement de propriété - // (utiliser ol.control.SearchEngine.on("change:collapsed", function ) pour s'abonner à cet évènement) - this.dispatchEvent("change:collapsed"); - // on nettoie si on ferme le composant - if (this.collapsed) { - this._clearResults(); - } - } - - /** - * this method is called by event 'click' on 'GPsearchInputReset' tag div - * (cf. this._createSearchInputElement), and it cleans the value of input. - * - * @private - */ - onSearchResetClick () { - this._clearResults(); - } - - /** - * this method is called by event 'click' on 'GPshowGeolocate' tag div - * (cf. this._createShowGeolocateElement) - * - * @private - */ - onShowSearchGeolocateClick () { - if ("geolocation" in navigator) { - /* geolocation is available */ - navigator.geolocation.getCurrentPosition((position) => { - var view = this.getMap().getView(); - var viewProj = view.getProjection().getCode(); - var coordinates = [position.coords.longitude, position.coords.latitude]; - if (viewProj !== "EPSG:4326") { - // on retransforme les coordonnées de la position dans la projection de la carte - coordinates = olProjTransform(coordinates, "EPSG:4326", viewProj); - } - if (isNaN(coordinates[0]) || isNaN(coordinates[1])) { - this._setMarker(); - return; - } - this._setPosition(coordinates, 10); // FIXME zoom fixe ! - if (this._displayMarker) { - this._setMarker(coordinates, "sans information"); - } - }); - } else { - /* geolocation IS NOT available */ - } - } - - /** - * this method is called by event 'click' on 'GPshowSearchByCoordinate' tag div - * (cf. this._createShowSearchByCoordinateElement) - * - * @private - */ - onShowSearchByCoordinateClick () { - var lng = null; - var lat = null; - if (this._coordinateSearchLngInput && this._coordinateSearchLngInput.nodeName === "DIV" && - this._coordinateSearchLatInput && this._coordinateSearchLatInput.nodeName === "DIV" - ) { - lng = this._getCoordinateSearchDMS(this._coordinateSearchLngInput); - lat = this._getCoordinateSearchDMS(this._coordinateSearchLatInput); - } else { - lng = this._coordinateSearchLngInput.value; - lat = this._coordinateSearchLatInput.value; - } - - if (!lng || !lat) { - return; - } - - var coordinates = [lng, lat]; - - var view = this.getMap().getView(); - var viewProj = view.getProjection().getCode(); - if (viewProj !== "EPSG:4326") { - coordinates = olProjTransform(coordinates, "EPSG:4326", viewProj); - } - if (isNaN(coordinates[0]) || isNaN(coordinates[1])) { - this._setMarker(); - return; - } - this._setPosition(coordinates, 10); // FIXME zoom fixe ! - if (this._displayMarker) { - this._setMarker(coordinates, "sans information"); - } - } - - _getCoordinateSearchDMS (dom) { - if (dom && dom.nodeName === "DIV") { - var nodes = dom.querySelectorAll("[name]"); - if (nodes) { - var degrees = MathUtils.toInteger(nodes[0].value); - var minutes = MathUtils.toInteger(nodes[1].value); - var seconds = MathUtils.toInteger(nodes[2].value); - var hemispheres = nodes[3].options[nodes[3].selectedIndex].text; - if (!degrees || !minutes || !seconds || !hemispheres) { - return; - } - return MathUtils.dmsToDecimal(degrees, minutes, seconds, hemispheres); - } - } - } - // ################################################################### // - // ################## handlers events AutoComplete ################### // - // ################################################################### // - - /** - * this method is called by event 'click' on 'GPlocationOrigin' input - * - * @private - */ - onAutoCompleteInputClick () { - var inputSearchTextContainer = document.getElementById("GPsearchInputText-" + this._uid); - if (inputSearchTextContainer && !inputSearchTextContainer.disabled && inputSearchTextContainer.value.length > 2) { - this._displaySuggestedLocation(); - } - } - - /** - * this method is called by event 'keyup' on 'GPsearchInputText' tag input - * (cf. this._createSearchInputElement), and it gets the value of input. - * this value is passed as a parameter for the service autocomplete (text). - * the results of the request are displayed into a drop down menu. - * - * @param {Object} e - HTMLElement - * @private - */ - onAutoCompleteSearchText (e) { - var value = e.target.value; - if (!value) { - return; - } - - // on sauvegarde le localisant - this._currentGeocodingLocation = value; - - // on limite les requêtes à partir de 3 car. saisie ! - if (value.length < 3) { - this._clearSuggestedLocation(); - return; - } - - var _triggerGeocode = this.options.autocompleteOptions.triggerGeocode; - var _triggerDelay = this.options.autocompleteOptions.triggerDelay; - - // INFORMATION - // on effectue la requête au service d'autocompletion. - // on met en place des callbacks afin de recuperer les resultats ou - // les messages d'erreurs du service. - // les resultats sont affichés dans une liste deroulante. - var context = this; - this._requestAutoComplete({ - text : value, - // callback onSuccess - onSuccess : function (results) { - logger.log("request from AutoComplete", results); - if (results) { - // on sauvegarde l'etat des résultats - context._suggestedLocations = results.suggestedLocations; - context._locationsToBeDisplayed = []; - // on vérifie qu'on n'a pas récupéré des coordonnées nulles (par ex recherche par code postal) - for (var i = 0; i < context._suggestedLocations.length; i++) { - var ilocation = context._suggestedLocations[i]; - if (ilocation.position && ilocation.position.x === 0 && ilocation.position.y === 0 && ilocation.fullText) { - // si les coordonnées sont nulles, il faut relancer une requête de géocodage avec l'attribut "fullText" récupéré - context._getGeocodeCoordinatesFromFullText(ilocation, i); - } else { - // sinon on peut afficher normalement le résultat dans la liste - context._locationsToBeDisplayed.push(ilocation); - } - }; - // on affiche les résultats qui n'ont pas des coordonnées nulles - context._fillAutoCompletedLocationListContainer(context._locationsToBeDisplayed); - // on annule eventuellement une requete de geocodage en cours car on obtient des - // de nouveau des resultats d'autocompletion... - if (context._triggerHandler) { - clearTimeout(context._triggerHandler); - context._triggerHandler = null; - logger.warn("Cancel a geocode request !"); - } - } - }, - // callback onFailure - onFailure : function (error) { - // FIXME - // où affiche t on les messages : ex. 'No suggestion matching the search' ? - context._clearSuggestedLocation(); - logger.log(error.message); - // on envoie une requete de geocodage si aucun resultat d'autocompletion - // n'a été trouvé ! Et on n'oublie pas d'annuler celle qui est en cours ! - if (error.message === "No suggestion matching the search" && _triggerGeocode /* && value.length === 5 */) { - if (context._triggerHandler) { - clearTimeout(context._triggerHandler); - logger.warn("Cancel the last geocode request !"); - } - context._triggerHandler = setTimeout( - function () { - logger.warn("Launch a geocode request !"); - context._requestGeocoding({ - location : value, - // callback onSuccess - onSuccess : function (results) { - logger.log("request from Geocoding", results); - if (results) { - context._locationsToBeDisplayed = []; - // on modifie la structure des reponses pour être - // compatible avec l'autocompletion ! - var locations = results.locations; - for (var i = 0; i < locations.length; i++) { - var location = locations[i]; - location.fullText = GeocodeUtils.getGeocodedLocationFreeform(location); - location.position = { - x : location.position.lon, - y : location.position.lat - }; - context._locationsToBeDisplayed.push(location); - } - context._fillAutoCompletedLocationListContainer(locations); - } - }, - // callback onFailure - onFailure : function (error) { - logger.log(error.message); - } - }); - }, _triggerDelay - ); - } - } - }); - - // INFORMATION - // on effectue une requête au service de recherche. - // les resultats sont ajoutées à la suite de l'autocompletion, - // et un abonnement est mis en place pour les récuperer. - if (this.options.resources.search) { - // appel du service (cf. abonnement : Search.target.addEventListener("suggest")) - Search.suggest(value); - } - - var map = this.getMap(); - map.on( - "click", - this._hideSuggestedLocation, - this - ); - map.on( - "pointerdrag", - this._hideSuggestedLocation, - this - ); - } - - /** - * this method is called by Gp.Services.autoComplete callback in case of success - * (cf. this.onAutoCompleteSearchText), for suggested locations with null coordinates - * (case of postalCode research for instance). - * Send a geocode request with suggested location 'fullText' attribute, to get its coordinates and display it in autocomplete results list container. - * - * @param {Gp.Services.AutoCompleteResponse.SuggestedLocation} suggestedLocation - autocompletion result (with null coordinates) to be geocoded - * @param {Number} i - suggestedLocation position in Gp.Services.AutoCompleteResponse.suggestedLocations autocomplete results list - * @private - */ - _getGeocodeCoordinatesFromFullText (suggestedLocation, i) { - var context = this; - Gp.Services.geocode({ - apiKey : this.options.apiKey, - ssl : this.options.ssl, - q : GeocodeUtils.getSuggestedLocationFreeform(suggestedLocation), - index : suggestedLocation.type, - // callback onSuccess - onSuccess : function (response) { - logger.log("request from Geocoding (coordinates null)", response); - if (response.locations && response.locations.length !== 0 && response.locations[0].position) { - // on modifie les coordonnées du résultat en EPSG:4326 donc lat,lon - /// \TODO verifier si l'inversion des coordonnees est necessaire - if (context._suggestedLocations && context._suggestedLocations[i]) { - context._suggestedLocations[i].position = { - lon : response.locations[0].position.y, - lat : response.locations[0].position.x - }; - // et on l'affiche dans la liste - context._locationsToBeDisplayed.unshift(context._suggestedLocations[i]); - context._fillAutoCompletedLocationListContainer(context._locationsToBeDisplayed); - } - } - }, - // callback onFailure - onFailure : function () { - // si on n'a pas réussi à récupérer les coordonnées, on affiche quand même le résultat - if (context._suggestedLocations && context._suggestedLocations[i]) { - context._createAutoCompletedLocationElement(context._suggestedLocations[i], i); - } - } - }); - } - - /** - * this method is called by event 'click' on 'GPautoCompleteResultsList' tag div - * (cf. this._createAutoCompleteListElement), and it selects the location. - * this location displays a marker on the map. - * - * @param {Object} e - HTMLElement - * @private - */ - onAutoCompletedResultsItemClick (e) { - // TODO on souhaite un comportement different pour la selection des reponses - // de l'autocompletion : - // - liste deroulante des reponses, - // - puis possibilité de cliquer sur une suggestion - // - mais aussi de la choisir avec le clavier (arrow up/down), puis valider - // par un return - // cette selection avec les fleches doit mettre à jour le input ! - // (comme un moteur de recherche de navigateur) - - var idx = SelectorID.index(e.target.id); - logger.log(idx); - logger.log(this._locationsToBeDisplayed[idx]); - - if (!idx) { - return; - } - - var position = [ - this._locationsToBeDisplayed[idx].position.x, - this._locationsToBeDisplayed[idx].position.y - ]; - var info = { - service : "SuggestedLocation", - location : this._locationsToBeDisplayed[idx] - }; - - // on ajoute le texte de l'autocomplétion dans l'input - var label = GeocodeUtils.getSuggestedLocationFreeform(this._locationsToBeDisplayed[idx]); - this._setLabel(label); - - // on sauvegarde le localisant - this._currentGeocodingLocation = label; - - // Info : la position est en EPSG:4326, à transformer dans la projection de la carte - var view = this.getMap().getView(); - var mapProj = view.getProjection().getCode(); - if (mapProj !== "EPSG:4326") { - // on retransforme les coordonnées de la position dans la projection de la carte - position = olProjTransform(position, "EPSG:4326", mapProj); - } - // on centre la vue et positionne le marker, à la position reprojetée dans la projection de la carte - var zoom = this._getZoom(info); - this._setPosition(position, zoom); - if (this._displayMarker) { - this._setMarker(position, info); - } - /** - * event triggered when an element of the results is clicked for autocompletion - * - * @event searchengine:autocomplete:click - * @property {Object} type - event - * @property {Object} location - location - * @property {Object} target - instance SearchEngine - * @example - * SearchEngine.on("searchengine:autocomplete:click", function (e) { - * console.log(e.location); - * }) - */ - this.dispatchEvent({ - type : "searchengine:autocomplete:click", - location : this._locationsToBeDisplayed[idx] - }); - } - - /** - * this method is called by event 'click' on '' tag div - * (cf. this.), and it selects the suggest. - * this suggest call an event to added layer on the map. - * - * @param {Object} e - HTMLElement - * @private - */ - onSearchedResultsItemClick (e) { - var idx = SelectorID.index(e.target.id); - - var message = null; - var suggest = Search.getSuggestions()[idx]; - if (!suggest) { - message = "No suggestions found !"; - } - /** - * event triggered when an element of the results is clicked for search service - * - * @event searchengine:search:click - * @property {Object} type - event - * @property {Object} suggest - suggest - * @property {Object} error - error - * @property {Object} target - instance SearchEngine - * @example - * SearchEngine.on("searchengine:search:click", function (e) { - * console.log(e.suggest); - * }) - */ - this.dispatchEvent({ - type : "searchengine:search:click", - suggest : suggest, - error : new Error(message) - }); - } - - // ################################################################### // - // ################### handlers events Geocode ####################### // - // ################################################################### // - - /** - * this method is called by event 'submit' on 'GPsearchInput' tag form - * (cf. this._createSearchInputElement), and it gets the value of input. - * this value is passed as a parameter for the service geocoding. - * the results of the request are displayed into a window. - * - * @param {Object} e - HTMLElement - * @private - */ - onGeocodingSearchSubmit (e) { - var value = e.target[0].value; - if (!value) { - return; - } - - // on sauvegarde le localisant - this._currentGeocodingLocation = value; - - // on met en place l'affichage des resultats dans une fenetre de recherche. - var context = this; - this._requestGeocoding({ - query : value, - // callback onSuccess - onSuccess : function (results) { - logger.log("request from Geocoding", results); - if (results) { - var locations = results.locations; - context._fillGeocodedLocationListContainer(locations); - } - }, - // callback onFailure - onFailure : function (error) { - // FIXME cf. this.onAutoCompleteSearch() - context._clearGeocodedLocation(); - logger.log(error.message); - } - }); - } - - /** - * this method is called by event 'submit' on 'GPgeocodeResultsList' tag div - * (cf. this._createGeocodeResultsListElement), and it selects the location. - * this location displays a marker on the map. - * - * @param {Object} e - HTMLElement - * @private - */ - onGeocodedResultsItemClick (e) { - var idx = SelectorID.index(e.target.id); - - if (!idx) { - return; - } - - var position = [ - this._geocodedLocations[idx].position.lon, - this._geocodedLocations[idx].position.lat - ]; - var info = { - service : "GeocodedLocation", - location : this._geocodedLocations[idx] - }; - - // on ajoute le texte du géocodage dans l'input - var label = GeocodeUtils.getGeocodedLocationFreeform(this._geocodedLocations[idx]); - this._setLabel(label); - - // Info : la position est en EPSG:4326, à transformer dans la projection de la carte - var view = this.getMap().getView(); - var mapProj = view.getProjection().getCode(); - if (mapProj !== "EPSG:4326") { - // on retransforme les coordonnées de la position dans la projection de la carte - position = olProjTransform(position, "EPSG:4326", mapProj); - } - // on centre la vue et positionne le marker, à la position reprojetée dans la projection de la carte - var zoom = this._getZoom(this.options.zoomTo); - this._setPosition(position, zoom); - if (this._displayMarker) { - this._setMarker(position, info); - } - /** - * event triggered when an element of the results is clicked for geocoding - * - * @event searchengine:geocode:click - * @property {Object} type - event - * @property {Object} location - location - * @property {Object} target - instance SearchEngine - * @example - * SearchEngine.on("searchengine:geocode:click", function (e) { - * console.log(e.location); - * }) - */ - this.dispatchEvent({ - type : "searchengine:geocode:click", - location : this._geocodedLocations[idx] - }); - } - - // ################################################################### // - // ############## handlers events Geocode Advanced ################### // - // ################################################################### // - - /** - * this method is called by event 'change' on 'GPadvancedSearchCode' tag select - * (cf. this._createAdvancedSearchFormCodeElement), and it gets the value of - * option selected. - * this value is passed as a parameter to create the attributs container. - * - * @param {Object} e - HTMLElement - * @private - */ - onGeocodingAdvancedSearchCodeChange (e) { - logger.log(e); - var idx = e.target.selectedIndex; - var value = e.target.options[idx].value; - - if (!value) { - return; - } - - // INFORMATION - // le declenchement de l'evenement va creer un container de filtre à la volée... - // l'insertion des containers d'attributs dans le DOM sont : - // - soit GPadvancedSearchFilters > PositionOfInterest - // - soit GPadvancedSearchFilters > StreetAddress - // - soit GPadvancedSearchFilters > CadastralParcel - // cf. _setFilter() pour la creation du container - - this._setFilter(value); - } - - /** - * this method is called by event 'submit' on 'GPadvancedSearchForm' tag form - * (cf. this._createAdvancedSearchPanelFormElement), and it gets the value of all input. - * this value is passed as a parameter for the service geocoding. - * the results of the request are displayed into a window. - * - * @param {Object} e - HTMLElement - * @param {Array} data - [{key: ..., value: ...}] - * @private - */ - onGeocodingAdvancedSearchSubmit (e, data) { - logger.log(data); - if (!data || data.length === 0) { - return; - } - - var _location; - var _filterOptions = {}; - - for (var i = 0; i < data.length; i++) { - var filter = data[i]; - if (filter.value) { - _filterOptions[filter.key] = filter.value; - } - } - - var inputSearchTextContainer = document.getElementById("GPsearchInputText-" + this._uid); - _location = inputSearchTextContainer.value; - - // On ne prend pas en compte ce qu'il y a dans l'input de recherche simple pour la recherche avance de PC - if (this._currentGeocodingCode === "CadastralParcel") { - _location = ""; - } - - // on met en place l'affichage des resultats dans une fenetre de recherche. - var context = this; - this._requestGeocoding({ - query : _location, - index : this._currentGeocodingCode, - filters : _filterOptions, - // callback onSuccess - onSuccess : function (results) { - logger.log(results); - if (results) { - var locations = results.locations; - context._fillGeocodedLocationListContainer(locations); - } - }, - // callback onFailure - onFailure : function (error) { - // FIXME cf. this.onAutoCompleteSearch() - context._clearGeocodedLocation(); - logger.log(error.message); - } - }); - } - - /** - * this method is called by 'onGeocodingAdvancedSearchSubmit' method, - * in case geocoding type is 'CadastralParcel', - * and gets request parameters from inputs - * - * @param {Object} filterOptions - object with inputs value (department, insee, ...) - * @returns {String} location - cadastral parcel number : concatenation of inputs values (e.g. : 940670000D0041 or 94067_____0041) - * @private - */ - _getCadastralParcelRequestParams (filterOptions) { - /* info: - la parcelle cadastrale se compose de 14 chiffres ou lettres, indiquant, de gauche à droite : - - le code du département (2 caractères) - - le code commune (3 caractères). (Remarque : code département + code commune = code INSEE) - - OU le code INSEE de la commune (5 chiffres) (remplace les 2 précédents) - - le code commune absorbée INSEE, ou '000' (3 caractères), - - la section (2 caractères), - - le numéro de parcelle (4 caractères). - Exemple de parcelle : '940670000D0041'. Si l'identifiant est incomplet (par exemple '940670000D'), le service renverra uniquement les 25 premiers résultats pouvant correspondre. - */ - - var _location = ""; - - var l; - // code département (2 caractères) - var dep = filterOptions.department; - if (dep) { - l = dep.length; - if (l === 2) { - _location = dep; - } else if (l === 1) { - // si un seul numéro a été saisi, on présume que c'est un numéro < 10 - _location = "0" + dep; - } else { - _location = dep.substring(0, 2); - } - } else { - _location = "__"; - } - - // code commune insee (3 caractères) - var commune = filterOptions.commune; - if (commune) { - l = commune.length; - if (l === 3) { - _location += commune; - } else if (l === 2) { - _location += "_" + commune; - } else if (l === 1) { - _location += "__" + commune; - } else { // l > 3 - _location += commune.substring(0, 3); - } - } else { - _location += "___"; - } - - // code insee (5 caractères) : surcharge les 2 autres si renseigné - var insee = filterOptions.insee; - if (insee) { - if (insee.length === 5) { - _location = insee; - } - } - - // code commune absorbee INSEE (3 caractères) - var absorbedCity = filterOptions.absorbedCity; - if (absorbedCity) { - l = absorbedCity.length; - if (l === 3) { - _location += absorbedCity; - } else if (l < 3) { - if (l === 2) { - _location += "_" + absorbedCity; - } else if (l === 1) { - _location += "__" + absorbedCity; - } - } else { // l > 3 - _location += absorbedCity.substring(0, 3); - } - } else { - _location += "___"; - } - - // section (2 caractères) - var section = filterOptions.section; - if (section) { - l = section.length; - if (l === 2) { - _location += section; - } else if (l === 1) { - _location += "_" + section; - } else { - _location += section.substring(0, 2); - } - } else { - _location += "__"; - } - - // numéro de parcelle (4 caractères) - var number = filterOptions.number; - if (number) { - l = number.length; - if (l === 4) { - _location += number; - } else if (l === 3) { - _location += "_" + number; - } else if (l === 2) { - _location += "__" + number; - } else if (l === 1) { - _location += "___" + number; - } else { // l > 4 - _location += number.substring(0, 4); - } - } else { - _location += "___"; - } - - logger.log("location : " + _location); - - return _location; - } - - // ################################################################### // - // ############### handlers events Coordinate Search ################# // - // ################################################################### // - - /** - * this method is called by event 'change' on '' - * tag select (cf. this.), - * and selects the system projection. - * - * @param {Object} e - HTMLElement - * @private - */ - onCoordinateSearchSystemChange (e) { - var idx = e.target.selectedIndex; // index - var value = e.target.options[idx].value; // crs - - // on nettoie les coordonnées saisies - this._coordinateSearchLngInput.value = ""; - this._coordinateSearchLatInput.value = ""; - - // INFO - // si on change de type de systeme, on doit aussi changer le type d'unités ! - var type = null; - for (var i = 0; i < this._coordinateSearchSystems.length; ++i) { - if (this._coordinateSearchSystems[i].code === Number(value)) { - type = this._coordinateSearchSystems[i].type; - break; - } - } - - if (!type) { - logger.log("system not found in projection systems container"); - return; - } - - // on enregistre le systeme courant - this._currentCoordinateSearchSystems = this._coordinateSearchSystems[Number(value)]; - - if (type !== this._currentCoordinateSearchType) { - // on met à jour les unités du menu deroulant : Geographique ou Métrique - this._currentCoordinateSearchType = type; - this._currentCoordinateSearchUnits = this._coordinateSearchUnits[type][0].code; - this._containerUnits.appendChild(this._setCoordinateSearchUnitsSelectElement(this._coordinateSearchUnits[type])); - // et on modifie la zone de saisie des coordonnées (label + input) - this._updateCoordinateSearchElements(); - } - } - - /** - * this method is called by event 'change' on '' - * tag select (cf. this.), - * and selects the units projection. - * - * @param {Object} e - HTMLElement - * @private - */ - onCoordinateSearchUnitsChange (e) { - var idx = e.target.selectedIndex; - var value = e.target.options[idx].value; - - // on nettoie les coordonnées saisies - this._coordinateSearchLngInput.value = ""; - this._coordinateSearchLatInput.value = ""; - - // et on modifie la zone de saisie des coordonnées (label + input) - this._currentCoordinateSearchUnits = value; - this._updateCoordinateSearchElements(); - } - - /** - * this method is called by event 'click' on '' - * tag select (cf. this.), - * and clear app. - * - * @private - */ - onCoordinateSearchClose () { - this._setMarker(); - this._coordinateSearchLngInput.value = ""; - this._coordinateSearchLatInput.value = ""; - } - - _updateCoordinateSearchElements () { - var lbl = this._setCoordinateSearchLngLabelElement(this._currentCoordinateSearchType); - var input = this._coordinateSearchLngInput = this._setCoordinateSearchLngInputElement(this._currentCoordinateSearchUnits); - this._containerCoordinateLng.appendChild(lbl); - this._containerCoordinateLng.appendChild(input); - lbl = this._setCoordinateSearchLatLabelElement(this._currentCoordinateSearchType); - input = this._coordinateSearchLatInput = this._setCoordinateSearchLatInputElement(this._currentCoordinateSearchUnits); - this._containerCoordinateLat.appendChild(lbl); - this._containerCoordinateLat.appendChild(input); - } - - // ################################################################### // - // ############################## clean ############################## // - // ################################################################### // - - /** - * this method is called by this.onSearchReset() - * and it clears all results and the marker. - * - * @private - */ - _clearResults () { - var map = this.getMap(); - - this._currentGeocodingLocation = null; - - this._clearSuggestedLocation(); - this._clearGeocodedLocation(); - - this._setMarker(); - // on retire l'overlay de la popup de la carte - if (this._popupOverlay != null) { - map.removeOverlay(this._popupOverlay); - this._popupOverlay = null; - } - } - - /** - * this method is called by this.onAutoCompleteSearchText() - * and it clears all suggested location. - * - * @private - */ - _clearSuggestedLocation () { - this._suggestedLocations = []; - if (this._containerResultsLocation) { - while (this._containerResultsLocation.firstChild) { - this._containerResultsLocation.removeChild(this._containerResultsLocation.firstChild); - } - } - if (this.options.resources.search) { - Search.clear(); - if (this._containerResultsSuggest) { - while (this._containerResultsSuggest.firstChild) { - this._containerResultsSuggest.removeChild(this._containerResultsSuggest.firstChild); - } - } - } - } - - /** - * this method is called to hide suggested locations - * - * @private - */ - _hideSuggestedLocation () { - if (this._autocompleteContainer) { - this._autocompleteContainer.classList.replace("GPelementVisible", "GPelementHidden"); - this._autocompleteContainer.classList.replace("gpf-visible", "gpf-hidden"); - } - } - - /** - * this method is called to display suggested location. - * - * @private - */ - _displaySuggestedLocation () { - if (this._autocompleteContainer) { - this._autocompleteContainer.classList.replace("GPelementHidden", "GPelementVisible"); - this._autocompleteContainer.classList.replace("gpf-hidden", "gpf-visible"); - } - } - - /** - * this method is called by this.onGeocodingAdvancedSearchSubmit() - * and it clears all geocoded location. - * - * @private - */ - _clearGeocodedLocation () { - this._geocodedLocations = []; - if (this._geocodedContainer) { - while (this._geocodedContainer.firstChild) { - this._geocodedContainer.removeChild(this._geocodedContainer.firstChild); - } - } - } - -}; - -// on récupère les méthodes de la classe commune ReverseGeocoding -Object.assign(SearchEngine.prototype, SearchEngineDOM); - -export default SearchEngine; - -// Expose SearchEngine as ol.control.SearchEngine (for a build bundle) -if (window.ol && window.ol.control) { - window.ol.control.SearchEngine = SearchEngine; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngineDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngineDOM.d.ts deleted file mode 100644 index 2e3afee52..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngineDOM.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -export default SearchEngineDOM; -declare namespace SearchEngineDOM { - function _addUID(id: string): string; - function _createMainContainerElement(): DOMElement; - function _createSearchDivElement(): DOMElement; - function _createShowSearchEnginePictoElement(force: boolean): DOMElement; - function _createSearchInputElement(placeholder: string): DOMElement; - function _createSearchResetElement(): HTMLButtonElement; - function _createButtonsElement(): HTMLDivElement; - function _createShowAdvancedSearchElement(): DOMElement; - function _createShowGeolocateElement(): DOMElement; - function _createShowSearchByCoordinateElement(): DOMElement; - function _createAdvancedSearchPanelElement(): DOMElement; - function _createAdvancedSearchPanelDivElement(): HTMLDivElement; - function _createGeocodeResultsElement(): DOMElement; - function _createGeocodeResultsDivElement(): HTMLDivElement; - function _createAutoCompleteElement(): DOMElement; - function _createCoordinateSearchPanelElement(): DOMElement; - function _createCoordinateSearchPanelDivElement(): HTMLDivElement; - function _createAutoCompleteListElement(): DOMElement; - function _createAutoCompletedLocationContainer(): HTMLSelectElement; - function _createAutoCompletedLocationTitleElement(): void; - function _createAutoCompletedLocationElement(location: Object, id: number): void; - function _createSearchedSuggestContainer(): HTMLSelectElement; - function _createSearchedSuggestTitleElement(): void; - function _createSearchedSuggestElement(suggest: Object, id: number): void; - function _createAdvancedSearchPanelHeaderElement(): DOMElement; - function _createAdvancedSearchPanelFormElement(advancedSearchCodes: Object[]): DOMElement; - function _createAdvancedSearchFormCodeElement(codes: Object[]): DOMElement; - function _createAdvancedSearchFormInputElement(): DOMElement; - function _createAdvancedSearchFormFiltersElement(): DOMElement; - function _createAdvancedSearchFiltersTableElement(code: string, display: boolean): DOMElement; - function _createAdvancedSearchFiltersAttributElement(filterAttributes: { - code: string; - name: string; - title: string; - description: string; - value: string; - }): DOMElement; - function _createGeocodeResultsHeaderElement(): DOMElement; - function _createGeocodeResultsListElement(): DOMElement; - function _createGeocodedLocationElement(location: Object, id: number): void; - function _createCoordinateSearchPanelHeaderElement(): HTMLDivElement; - function _createCoordinateSearchPanelFormElement(): HTMLFormElement; - function __createCoordinateSearchDivElement(): HTMLDivElement; - function _createCoordinateSearchSystemsLabelElement(): HTMLLabelElement; - function _setCoordinateSearchSystemsSelectElement(systems: any): HTMLSelectElement; - function _createCoordinateSearchUnitsLabelElement(): HTMLLabelElement; - function _setCoordinateSearchUnitsSelectElement(units: any): HTMLSelectElement; - /** - * update Label - * @param {String} type - Geographical or Metric - * @returns {DOMElement} label - */ - function _setCoordinateSearchLngLabelElement(type: string): DOMElement; - /** - * update Input coordinate - * @param {String} code - ex. DMS : degrés sexadecimaux - * @returns {DOMElement} input - */ - function _setCoordinateSearchLngInputElement(code: string): DOMElement; - function _setCoordinateSearchLngDMSElement(): HTMLDivElement; - /** - * update Label - * @param {String} type - Geographical or Metric - * @returns {DOMElement} label - */ - function _setCoordinateSearchLatLabelElement(type: string): DOMElement; - /** - * update Input coordinate - * @param {String} code - ex. DMS : degrés sexadecimaux - * @returns {DOMElement} input - */ - function _setCoordinateSearchLatInputElement(code: string): DOMElement; - function _setCoordinateSearchLatDMSElement(): HTMLDivElement; - /** - * submit - * @returns {DOMElement} input - */ - function _createCoordinateSearchSubmitElement(): DOMElement; -} -//# sourceMappingURL=SearchEngineDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngineDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngineDOM.d.ts.map deleted file mode 100644 index 50ef2dee2..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngineDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"SearchEngineDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/SearchEngine/SearchEngineDOM.js"],"names":[],"mappings":";;IAUc,qCAGT;IAO6B,mDAK7B;IAUyB,+CAIzB;IAOqC,yEA0CrC;IAQ2B,oEAsI3B;IAE2B,wDAqB3B;IAGuB,iDAIvB;IAOkC,wDAuClC;IAO6B,mDAsB7B;IAOsC,4DAsCtC;IAemC,yDAWnC;IAEsC,gEAItC;IAU8B,oDAY9B;IAEiC,2DAIjC;IAU4B,kDAU5B;IAWqC,2DAWrC;IAEwC,kEAIxC;IAWgC,sDAwBhC;IAED,oEAOC;IACD,0DAMC;IAWqC,iFAuBrC;IAED,8DAOC;IACD,oDAMC;IAU+B,0EAuB/B;IASyC,+DAkDzC;IAOuC,0FAsDvC;IAMsC,2EAsCtC;IAKuC,6DAQvC;IAOyC,+DAIzC;IAW0C,8FAQ1C;IAgB6C;;;;;;mBAuD7C;IASoC,0DAqCpC;IAOkC,wDA8BlC;IAYgC,4EAchC;IAMD,qEA8CC;IACD,oEAcC;IAED,8DAIC;IAED,wEAKC;IACD,mFAyBC;IAED,sEAKC;IACD,+EAyBC;IAED;;;;OAIG;IACH,uEAYC;IACD;;;;OAIG;IACH,uEAsCC;IACD,6DA8CC;IACD;;;;OAIG;IACH,uEAYC;IACD;;;;OAIG;IACH,uEAsCC;IACD,6DA8CC;IAED;;;OAGG;IACH,4DAOC"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngineDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngineDOM.js deleted file mode 100644 index 0032dff5e..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/SearchEngine/SearchEngineDOM.js +++ /dev/null @@ -1,1384 +0,0 @@ -import ID from "../../Utils/SelectorID"; -import GeocodeUtils from "../../Utils/GeocodeUtils"; - -var SearchEngineDOM = { - - /** - * Add uuid to the tag ID - * @param {String} id - id selector - * @returns {String} uid - id selector with an unique id - */ - _addUID : function (id) { - var uid = (this._uid) ? id + "-" + this._uid : id; - return uid; - }, - - /** - * Main container (DOM) - * - * @returns {DOMElement} DOM element - */ - _createMainContainerElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPsearchEngine"); - container.className = "GPwidget gpf-widget"; - return container; - }, - - // ################################################################### // - // ################### Methods of main container ##################### // - // ################################################################### // - - /** - * SElement with picto and search input - * @returns {DOMElement} DOM element - */ - _createSearchDivElement : function () { - var searchDiv = document.createElement("div"); - searchDiv.id = this._addUID("GPshowSearchDiv"); - return searchDiv; - }, - - /** - * Show search engine - * @param {Boolean} force - ... - * @returns {DOMElement} DOM element - */ - _createShowSearchEnginePictoElement : function (force) { - // contexte d'execution - var self = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowSearchEnginePicto"); - button.className = "GPshowOpen GPshowAdvancedToolPicto GPshowSearchEnginePicto gpf-btn gpf-btn-icon-search fr-btn"; - button.title = "Afficher/masquer la recherche par lieux"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", force); - button.disabled = force; - - // Close all results and panels when minimizing the widget - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - if (status) {} - - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("gpf-visible", "gpf-hidden"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-visible", "gpf-hidden"); - var showAdvancedSearch = document.getElementById(self._addUID("GPshowAdvancedSearch")); - if (showAdvancedSearch) { - showAdvancedSearch.style.display = null; - document.getElementById(self._addUID("GPadvancedSearchPanel")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPadvancedSearchPanel")).classList.replace("gpf-visible", "gpf-hidden"); - } - var showGeolocate = document.getElementById(self._addUID("GPshowGeolocate")); - if (showGeolocate) { - showGeolocate.style.display = null; - } - var showCoordinate = document.getElementById(self._addUID("GPshowSearchByCoordinate")); - if (showCoordinate) { - showCoordinate.style.display = null; - } - var id = "#GPsearchInput-" + self._uid; - document.querySelector(id + " input").disabled = false; // FIXME form[id^=GPsearchInput] = #GPsearchInput ? - self.onShowSearchEngineClick(); - }); - - return button; - }, - - /** - * Simple search input - * @param {String} placeholder - placeholder - * - * @returns {DOMElement} DOM element - */ - _createSearchInputElement : function (placeholder) { - // contexte d'execution - var self = this; - - var form = document.createElement("form"); - form.id = this._addUID("GPsearchInput"); - form.className = "gpf-panel__content fr-modal__content"; - // Open geocode results panel when submitting the input - form.addEventListener("submit", function (e) { - e.preventDefault(); - if (document.getElementById(self._addUID("GPsearchInputText")).value === "") { - return false; - } - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementHidden", "GPelementVisible"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-hidden", "gpf-visible"); - - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("gpf-visible", "gpf-hidden"); - // cf. FIXME - // document.querySelector("#GPsearchInput input").blur (); - - // gestionnaire d'evenement : - // on récupère la valeur de saisie pour requête sur le service de geocodage - self.onGeocodingSearchSubmit(e); - return false; - }); - - var input = document.createElement("input"); - input.id = this._addUID("GPsearchInputText"); - input.className = "GPsearchInputText gpf-input fr-input"; - input.type = "text"; - input.placeholder = placeholder; - input.autocomplete = "off"; - // Manage autocomplete list appearance when filling the address input - input.addEventListener("keyup", function (e) { - var charCode = e.which || e.keyCode; - if (charCode === 13 || charCode === 10 || charCode === 38 || charCode === 40) { - return; - } - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-visible", "gpf-hidden"); - if (input.value.length > 2) { - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("GPelementHidden", "GPelementVisible"); - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("gpf-hidden", "gpf-visible"); - } else { - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("gpf-visible", "gpf-hidden"); - } - // gestionnaire d'evenement : - // on récupère la valeur de saisie pour requête sur le service d'autocompletion - self.onAutoCompleteSearchText(e); - }); - - // FIXME ce code interfere avec le click sur la liste des suggested locations ! - // input.addEventListener("blur", function (e) { - // document.getElementById(self._addUID("GPautoCompleteList")).style.display = "none"; - // }); - - input.addEventListener("keydown", function (e) { - // FIXME - // l'action clavier 'enter (13)' lance le submit de la form ! - // Ce comportement n'est pas souhaité car le submit execute un geocodage ! - // Il faut donc trouver le moyen d'eviter le submit sur un return venant - // seulement d'une selection de suggestion... - - var charCode = e.which || e.keyCode; - - var container = document.getElementById(self._addUID("GPautocompleteResults")); - - // si aucun container !? - if (!container) { - return; - } - - var curr = container.getElementsByClassName("GPautoCompleteProposal gpf-panel__items current"); - var list = container.getElementsByClassName("GPautoCompleteProposal gpf-panel__items"); - - // si aucune suggestion, on ne va pas plus loin ! - var length = list.length; - if (!length) { - return; - } - - var current = null; - - // si aucun item courant, on prend le 1er ! - if (!curr.length) { - current = list[0]; - current.className = "GPautoCompleteProposal gpf-panel__items current"; - current.style.color = "#000000"; - current.style["background-color"] = "#CEDBEF"; - return; - } else { - current = curr[0]; - } - - var index = parseInt(ID.index(current.id), 10); - var next = (index === length - 1) ? list[0] : list[index + 1]; - var prev = (index === 0) ? list[length - 1] : list[index - 1]; - - current.style["background-color"] = ""; - current.style.color = ""; - prev.style["background-color"] = ""; - prev.style.color = ""; - next.style["background-color"] = ""; - next.style.color = ""; - - switch (charCode) { - case 38: // arrow up - current.className = "GPautoCompleteProposal gpf-panel__items"; - prev.className = "GPautoCompleteProposal gpf-panel__items current"; - prev.style.color = "#000000"; - prev.style["background-color"] = "#CEDBEF"; - break; - case 40: // arrow down - current.className = "GPautoCompleteProposal gpf-panel__items"; - next.className = "GPautoCompleteProposal gpf-panel__items current"; - next.style.color = "#000000"; - next.style["background-color"] = "#CEDBEF"; - break; - case 13: // enter - // cf. FIXME - e.preventDefault(); - current.click(e); - break; - } - - current.focus(); - current.scrollIntoView(); - }); - - form.appendChild(input); - - return form; - }, - - _createSearchResetElement : function () { - // contexte d'execution - var self = this; - - var buttonReset = document.createElement("button"); - buttonReset.id = this._addUID("GPsearchInputReset"); - buttonReset.className = "GPshowOpen GPsearchInputReset gpf-btn gpf-btn-icon-reset gpf-btn-icon-search-reset fr-btn fr-btn--secondary"; /* not use : fr-btn--close */ - buttonReset.setAttribute("aria-label", "Supprimer la recherche"); - // Reset input - buttonReset.addEventListener("click", function (e) { - // FIXME event déclenché sur la frappe "return" dans la zone de saisie !? - document.getElementById(self._addUID("GPsearchInputText")).value = ""; - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("gpf-visible", "gpf-hidden"); - - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-visible", "gpf-hidden"); - self.onSearchResetClick(); - }); - - return buttonReset; - }, - - - _createButtonsElement : function () { - var div = document.createElement("div"); - div.className = "GPbuttonsContainer"; - return div; - }, - - /** - * Show advanced search panel - * - * @returns {DOMElement} DOM element - */ - _createShowAdvancedSearchElement : function () { - // contexte d'execution - var self = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowAdvancedSearch"); - button.className = "GPshowOpen GPshowAdvancedToolPicto GPshowAdvancedSearch gpf-btn gpf-btn-icon-search-advanced fr-btn fr-btn--secondary fr-m-1w"; - button.title = "Ouvrir la recherche avancée"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // Open advanced search - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - - var id = "#GPsearchInput-" + self._uid; - if (status) { - document.getElementById(self._addUID("GPadvancedSearchPanel")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPadvancedSearchPanel")).classList.replace("gpf-visible", "gpf-hidden"); - document.querySelector(id + " input").disabled = false; - } else { - document.getElementById(self._addUID("GPadvancedSearchPanel")).classList.replace("GPelementHidden", "GPelementVisible"); - document.getElementById(self._addUID("GPadvancedSearchPanel")).classList.replace("gpf-hidden", "gpf-visible"); - document.querySelector(id + " input").disabled = true; - } - - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("gpf-visible", "gpf-hidden"); - - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-visible", "gpf-hidden"); - - document.getElementById(self._addUID("GPcoordinateSearchPanel")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPcoordinateSearchPanel")).classList.replace("gpf-visible", "gpf-hidden"); - document.getElementById(self._addUID("GPshowSearchByCoordinate")).setAttribute("aria-pressed", false); - }); - - return button; - }, - - /** - * Show geolocate button - * - * @returns {DOMElement} DOM element - */ - _createShowGeolocateElement : function () { - // contexte d'execution - var self = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowGeolocate"); - button.className = "GPshowOpen GPshowAdvancedToolPicto GPshowGeolocate gpf-btn gpf-btn-icon-search-geolocate fr-btn fr-btn--secondary fr-m-1w"; - button.title = "Activer la geolocalisation"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // Open advanced search - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - if (status) { - // somme stuff... - } - self.onShowSearchGeolocateClick(); - }); - - return button; - }, - - /** - * Show search by coordinate button - * - * @returns {DOMElement} DOM element - */ - _createShowSearchByCoordinateElement : function () { - // contexte d'execution - var self = this; - - var button = document.createElement("button"); - button.id = this._addUID("GPshowSearchByCoordinate"); - button.className = "GPshowOpen GPshowAdvancedToolPicto GPshowSearchByCoordinate gpf-btn gpf-btn-icon-search-coordinate fr-btn fr-btn--secondary fr-m-1w"; - button.title = "Ouvrir la recherche par coordonnées"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - // Open advanced search - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - var id = "#GPsearchInput-" + self._uid; - if (status) { - document.getElementById(self._addUID("GPcoordinateSearchPanel")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPcoordinateSearchPanel")).classList.replace("gpf-visible", "gpf-hidden"); - document.querySelector(id + " input").disabled = false; - } else { - document.getElementById(self._addUID("GPcoordinateSearchPanel")).classList.replace("GPelementHidden", "GPelementVisible"); - document.getElementById(self._addUID("GPcoordinateSearchPanel")).classList.replace("gpf-hidden", "gpf-visible"); - document.querySelector(id + " input").disabled = true; - } - - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("gpf-visible", "gpf-hidden"); - - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-visible", "gpf-hidden"); - - document.getElementById(self._addUID("GPadvancedSearchPanel")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPadvancedSearchPanel")).classList.replace("gpf-visible", "gpf-hidden"); - document.getElementById(self._addUID("GPshowAdvancedSearch")).setAttribute("aria-pressed", false); - }); - - return button; - }, - - // ################################################################### // - // ################### Methods of advanced search #################### // - // ################################################################### // - - /** - * Advanced search panel - * - * FIXME - * don't call this._createAdvancedSearchPanelHeaderElement - * don't call this._createAdvancedSearchPanelFormElement - * - * @returns {DOMElement} DOM element - */ - _createAdvancedSearchPanelElement : function () { - var div = document.createElement("dialog"); - div.id = this._addUID("GPadvancedSearchPanel"); - div.className = "GPpanel GPelementHidden gpf-panel gpf-hidden fr-modal"; - - // FIXME on decompose la fonction pour les besoins du controle, - // on ajoutera ces childs à la main... - // div.appendChild(this._createAdvancedSearchPanelHeaderElement ()); - // div.appendChild(this._createAdvancedSearchPanelFormElement ()); - - return div; - }, - - _createAdvancedSearchPanelDivElement : function () { - var div = document.createElement("div"); - div.className = "gpf-panel__body fr-modal__body"; - return div; - }, - - /** - * Geocoding results - * - * FIXME - * don't call this._createGeocodeResultsListElement - * - * @returns {DOMElement} DOM element - */ - _createGeocodeResultsElement : function () { - var div = document.createElement("dialog"); - div.id = this._addUID("GPgeocodeResultsList"); - div.className = "GPpanel GPelementHidden gpf-panel gpf-hidden fr-modal"; - - div.appendChild(this._createGeocodeResultsHeaderElement()); - - // FIXME on decompose la fonction pour les besoins du controle, - // on ajoutera ces childs à la main... - // div.appendChild(this._createGeocodeResultsListElement ()); - - return div; - }, - - _createGeocodeResultsDivElement : function () { - var div = document.createElement("div"); - div.className = "gpf-panel__body fr-modal__body"; - return div; - }, - - /** - * Autocompletion results - * - * FIXME - * don't call this._createAutoCompleteListElement - * - * @returns {DOMElement} DOM element - */ - _createAutoCompleteElement : function () { - var div = document.createElement("div"); - div.id = this._addUID("GPautoCompleteList"); - div.className = "GPautoCompleteList GPelementHidden gpf-panel fr-modal gpf-hidden "; // GPpanel ? - - // FIXME on decompose la fonction pour les besoins du controle, - // on ajoutera ces childs à la main... - // div.appendChild(this._createAutoCompleteListElement ()); - - return div; - }, - - /** - * Coordinate search panel - * - * FIXME - * don't call this._createCoordinateSearchPanelHeaderElement - * don't call this._createCoordinateSearchPanelFormElement - * - * @returns {DOMElement} DOM element - */ - _createCoordinateSearchPanelElement : function () { - var div = document.createElement("dialog"); - div.id = this._addUID("GPcoordinateSearchPanel"); - div.className = "GPpanel GPelementHidden gpf-panel gpf-hidden fr-modal"; - - // FIXME on decompose la fonction pour les besoins du controle, - // on ajoutera ces childs à la main... - // div.appendChild(this._createCoordinateSearchPanelHeaderElement ()); - // div.appendChild(this._createCoordinateSearchPanelFormElement ()); - - return div; - }, - - _createCoordinateSearchPanelDivElement : function () { - var div = document.createElement("div"); - div.className = "gpf-panel__body fr-modal__body"; - return div; - }, - - // ################################################################### // - // ################### Autocompletion container ###################### // - // ################################################################### // - - /** - * Autocompletion results list. - * - * @returns {DOMElement} DOM element - */ - _createAutoCompleteListElement : function () { - // contexte d'execution - var self = this; - - var container = document.createElement("div"); - container.id = this._addUID("GPautocompleteResults"); - container.className = ""; - - if (container.addEventListener) { - container.addEventListener("click", function (e) { - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("gpf-visible", "gpf-hidden"); - }, false); - } else if (container.attachEvent) { - container.attachEvent("onclick", function (e) { - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPautoCompleteList")).classList.replace("gpf-visible", "gpf-hidden"); - }); - } - - // Proposals are dynamically filled in Javascript by autocomplete or search service - //
...
- - return container; - }, - - _createAutoCompletedLocationContainer () { - var container = document.createElement("select"); - container.id = this._addUID("GPautocompleteResultsLocation"); - container.className = "GPelementHidden gpf-hidden gpf-select"; - container.size = 6; - container.autofocus = true; - return container; - }, - _createAutoCompletedLocationTitleElement () { - var container = document.getElementById(this._addUID("GPautocompleteResultsLocation")); - var label = document.createElement("option"); - label.className = "GPlabel GPlabelTitle gpf-label fr-label"; - label.innerHTML = "LIEUX & ADRESSES"; - container.appendChild(label); - }, - - /** - * Autocompletion result. - * Proposals are dynamically filled in Javascript by autocomplete service - * - * TODO formaliser le contenu des reponse - * - * @param {Object} location - suggested or geocoded location results - * @param {Number} id - ID - */ - _createAutoCompletedLocationElement : function (location, id) { - // contexte d'execution - var self = this; - - var container = document.getElementById(this._addUID("GPautocompleteResultsLocation")); - - var div = document.createElement("option"); - div.id = this._addUID("AutoCompletedLocation_" + id); - div.className = "GPautoCompleteProposal gpf-panel__items"; - var value = GeocodeUtils.getSuggestedLocationFreeform(location); - div.innerHTML = value; - div.title = value; - if (div.addEventListener) { - div.addEventListener("click", function (e) { - self.onAutoCompletedResultsItemClick(e); - }, false); - } else if (div.attachEvent) { - div.attachEvent("onclick", function (e) { - self.onAutoCompletedResultsItemClick(e); - }); - } - - container.appendChild(div); - }, - - _createSearchedSuggestContainer () { - var container = document.createElement("select"); - container.id = this._addUID("GPautocompleteResultsSuggest"); - container.className = "GPelementHidden gpf-hidden gpf-select"; - container.size = 6; - container.autofocus = true; - return container; - }, - _createSearchedSuggestTitleElement () { - var container = document.getElementById(this._addUID("GPautocompleteResultsSuggest")); - var label = document.createElement("option"); - label.className = "GPlabel GPlabelTitle gpf-label fr-label"; - label.innerHTML = "CARTES & DONNÉES"; - container.appendChild(label); - }, - - /** - * Autocompletion result of search service. - * Proposals are dynamically filled in Javascript by autocomplete service - * - * - * @param {Object} suggest - suggested results - * @param {Number} id - ID - */ - _createSearchedSuggestElement : function (suggest, id) { - // contexte d'execution - var self = this; - - var container = document.getElementById(this._addUID("GPautocompleteResultsSuggest")); - - var div = document.createElement("option"); - div.id = this._addUID("AutoCompletedSuggest_" + id); - div.className = "GPautoCompleteProposal gpf-panel__items"; - div.innerHTML = suggest.title + " (" + suggest.service + ")"; - div.dataset.layer = suggest.name; - div.title = suggest.description; - if (div.addEventListener) { - div.addEventListener("click", function (e) { - self.onSearchedResultsItemClick(e); - }, false); - } else if (div.attachEvent) { - div.attachEvent("onclick", function (e) { - self.onSearchedResultsItemClick(e); - }); - } - - container.appendChild(div); - }, - - // ################################################################### // - // ############### Geocoding with advanced container ################# // - // ################################################################### // - - /** - * @returns {DOMElement} DOM element - */ - _createAdvancedSearchPanelHeaderElement : function () { - // contexte d'execution - var self = this; - - var container = document.createElement("div"); - container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; - - var divTitle = document.createElement("div"); - divTitle.className = "GPpanelTitle gpf-panel__title fr-modal__title"; - divTitle.innerHTML = "Recherche avancée"; - container.appendChild(divTitle); - - var divClose = document.createElement("button"); - divClose.id = this._addUID("GPadvancedSearchClose"); - divClose.className = "GPpanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--secondary fr-m-1w"; - divClose.title = "Fermer la recherche avancée"; - - if (divClose.addEventListener) { - divClose.addEventListener("click", function () { - var id = "#GPsearchInput-" + self._uid; - document.querySelector(id + " input").disabled = false; - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-visible", "gpf-hidden"); - // document.getElementById(self._addUID("GPshowAdvancedSearch")).style.display = "inline-block"; - document.getElementById(self._addUID("GPshowAdvancedSearch")).setAttribute("aria-pressed", false); - document.getElementById(self._addUID("GPadvancedSearchPanel")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPadvancedSearchPanel")).classList.replace("gpf-visible", "gpf-hidden"); - }, false); - } else if (divClose.attachEvent) { - divClose.attachEvent("onclick", function () { - var id = "#GPsearchInput-" + self._uid; - document.querySelector(id + " input").disabled = false; - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-visible", "gpf-hidden"); - // document.getElementById(self._addUID("GPshowAdvancedSearch")).style.display = "inline-block"; - document.getElementById(self._addUID("GPshowAdvancedSearch")).setAttribute("aria-pressed", false); - document.getElementById(self._addUID("GPadvancedSearchPanel")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPadvancedSearchPanel")).classList.replace("gpf-visible", "gpf-hidden"); - }); - } - - var span = document.createElement("span"); - span.className = "GPelementHidden gpf-visible"; // afficher en dsfr - span.innerText = "Fermer"; - - divClose.appendChild(span); - - container.appendChild(divClose); - - return container; - }, - - /** - * @param {Object[]} advancedSearchCodes - codes - * - * @returns {DOMElement} DOM element - */ - _createAdvancedSearchPanelFormElement : function (advancedSearchCodes) { - // contexte d'execution - var self = this; - - var form = document.createElement("form"); - form.id = this._addUID("GPadvancedSearchForm"); - form.className = "gpf-panel__content fr-modal__content"; - form.addEventListener("submit", function (e) { - e.preventDefault(); - // data - var data = []; - // liste des attributs de la ressource de geocodage - var id = "#GPadvancedSearchFilters-" + self._uid; - var matchesFilters = document.querySelectorAll(id + " > div > div > input"); - for (var i = 0; i < matchesFilters.length; i++) { - var element = matchesFilters[i]; - data.push({ - key : element.name, - value : element.value - }); - } - - // gestionnaire d'evenement : - // on récupère les valeurs de saisies pour requête sur le service de geocodage - self.onGeocodingAdvancedSearchSubmit(e, data); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementHidden", "GPelementVisible"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-hidden", "gpf-visible"); - - return false; - }); - - var div = document.createElement("div"); - div.className = "GPflexInput gpf-flex-column "; - - var label = document.createElement("label"); - label.className = "GPadvancedSearchCodeLabel gpf-label fr-label"; - label.innerHTML = "Recherche par"; - div.appendChild(label); - - var select = this._createAdvancedSearchFormCodeElement(advancedSearchCodes); - div.appendChild(select); - - // FIXME on decompose la fonction pour les besoins du controle, - // on ajoutera ces childs à la main... - - // var filters = this._createAdvancedSearchFormFiltersElement (); - // form.appendChild(filters); - - // var input = this._createAdvancedSearchFormInputElement (); - // form.appendChild(input); - - form.appendChild(div); - - return form; - }, - - /** - * @param {Object[]} codes - codes - * @returns {DOMElement} DOM element - */ - _createAdvancedSearchFormCodeElement : function (codes) { - // contexte d'execution - var self = this; - - var select = document.createElement("select"); - select.id = this._addUID("GPadvancedSearchCode"); - select.title = "Choisir un type de recherche"; - select.className = "GPadvancedSearchCode gpf-select fr-select"; - select.addEventListener("change", function (e) { - // var idx = e.target.selectedIndex; - // var value = e.target.options[idx].value; - // gestionnaire d'evenement : - // permet de recuperer des informations diverses... - self.onGeocodingAdvancedSearchCodeChange(e); - }, false); - - // liste statique au cas où des codes n'ont pas été passés en entrée - if (!codes) { - codes = [{ - id : "PositionOfInterest", - title : "Lieux/toponymes" - }, { - id : "StreetAddress", - title : "Adresses" - }, { - id : "CadastralParcel", - title : "Parcelles cadastrales" - }]; - } - - for (var i = 0; i < codes.length; i++) { - var option = document.createElement("option"); - option.value = codes[i].id; - option.text = codes[i].title; - select.appendChild(option); - } - - return select; - }, - - /** - * @returns {DOMElement} DOM element - */ - _createAdvancedSearchFormInputElement : function () { - var input = document.createElement("input"); - input.type = "submit"; - input.id = this._addUID("GPadvancedSearchSubmit"); - input.className = "GPsubmit gpf-btn gpf-btn-icon-submit fr-btn fr-btn--secondary"; - input.value = "Chercher"; - - return input; - }, - - /** - * Filters geocoding. - * - * @returns {DOMElement} DOM element - */ - _createAdvancedSearchFormFiltersElement : function () { - var container = document.createElement("div"); - container.id = this._addUID("GPadvancedSearchFilters"); - return container; - }, - - /** - * Create filter container for resources : - * "PositionOfInterest", "StreetAddress", ... - * - * @param {String} code - code of geocoding resource - * @param {Boolean} display - display - * - * @returns {DOMElement} DOM element - */ - _createAdvancedSearchFiltersTableElement : function (code, display) { - var container = document.createElement("div"); - container.id = this._addUID(code); - if (!display) { - container.style.display = "none"; - } - - return container; - }, - - /** - * Create filter attribut for a resource : - * "PositionOfInterest", "StreetAddress", ... - * Research filters are filled in Javascript depending on developer choice - * - * @param {Object} filterAttributes - filter attributes : - * @param {String} filterAttributes.code - code of geocoding resource - * @param {String} filterAttributes.name - ID - * @param {String} filterAttributes.title - label - * @param {String} filterAttributes.description - description - * @param {String} filterAttributes.value - value - * - * @returns {DOMElement} DOM element - */ - _createAdvancedSearchFiltersAttributElement : function (filterAttributes) { - // INFORMATION - // cette methode peut être appelée si le document n'existe pas, elle - // permet ainsi de creer une div sans insertion dans le container... - - var container = null; - var name = filterAttributes.name; - var title = filterAttributes.title; - var description = filterAttributes.description; - var code = filterAttributes.code; - var value = filterAttributes.value; - - var div = document.createElement("div"); - div.className = "GPflexInput gpf-flex-column "; - - var label = document.createElement("label"); - label.className = "GPadvancedSearchFilterLabel gpf-label fr-label"; - label.htmlFor = name; - label.title = description || title; - label.innerHTML = title; - div.appendChild(label); - - var input = document.createElement("input"); - input.id = name; - input.className = "GPadvancedSearchFilterInput gpf-input fr-input"; - input.type = "text"; - input.name = name; - if (value) { - if (Array.isArray(value)) { - var listId = name + "_list"; - input.setAttribute("list", listId); - var dl = document.createElement("datalist"); - dl.id = listId; - for (var i = 0; i < value.length; ++i) { - var option = document.createElement("option"); - option.value = value[i]; - dl.appendChild(option); - } - div.appendChild(dl); - } else { - input.value = value; - } - } - div.appendChild(input); - - container = document.getElementById(this._addUID(code)); - - if (container) { - container.appendChild(div); - } else { - // le container, c'est la div ! - container = div; - } - - return container; - }, - - // ################################################################### // - // ################## Geocoding results container #################### // - // ################################################################### // - - /** - * @returns {DOMElement} DOM element - */ - _createGeocodeResultsHeaderElement : function () { - var self = this; - - var container = document.createElement("div"); - container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; - - var divTitle = document.createElement("div"); - divTitle.className = "GPpanelTitle gpf-panel__title fr-modal__title"; - divTitle.innerHTML = "Résultats de la recherche"; - container.appendChild(divTitle); - - var divClose = document.createElement("button"); - divClose.id = this._addUID("GPgeocodeResultsClose"); - divClose.className = "GPpanelClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--secondary fr-m-1w"; - divClose.title = "Fermer la fenêtre de résultats"; - - if (divClose.addEventListener) { - divClose.addEventListener("click", function () { - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-visible", "gpf-hidden"); - }, false); - } else if (divClose.attachEvent) { - divClose.attachEvent("onclick", function () { - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-visible", "gpf-hidden"); - }); - } - - var span = document.createElement("span"); - span.className = "GPelementHidden gpf-visible"; // afficher en dsfr - span.innerText = "Fermer"; - - divClose.appendChild(span); - - container.appendChild(divClose); - - return container; - }, - - /** - * Geocoding results list. - * - * @returns {DOMElement} DOM element - */ - _createGeocodeResultsListElement : function () { - // contexte d'execution - var self = this; - - var container = document.createElement("div"); - container.id = this._addUID("GPgeocodeResults"); - container.className = "gpf-panel__list"; - container.setAttribute("tabindex", "0"); - - if (container.addEventListener) { - container.addEventListener("click", function (e) { - if (!e.ctrlKey) { - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-visible", "gpf-hidden"); - } - self.onGeocodedResultsItemClick(e); - }, false); - } else if (container.attachEvent) { - container.attachEvent("onclick", function (e) { - if (!e.ctrlKey) { - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPgeocodeResultsList")).classList.replace("gpf-visible", "gpf-hidden"); - } - self.onGeocodedResultsItemClick(e); - }); - } - // Results are dynamically filled in Javascript by geocoding service - //
...
- - return container; - }, - - /** - * Geocoding result. - * Results are dynamically filled in Javascript by geocoding service - * - * TODO formaliser le contenu des reponses - * FIXME formater la reponse en amont ! - * - * @param {Object} location - suggested or geocoded location results - * @param {Number} id - ID - */ - _createGeocodedLocationElement : function (location, id) { - var container = document.getElementById(this._addUID("GPgeocodeResults")); - - var div = document.createElement("div"); - div.id = this._addUID("GeocodedLocation_" + id); - div.className = "GPautoCompleteProposal gpf-panel__items"; - - if (typeof location === "string") { - div.innerHTML = location; - } else { - div.innerHTML = GeocodeUtils.getGeocodedLocationFreeform(location); - } - - container.appendChild(div); - }, - - // ################################################################### // - // ################## Coordinate search container #################### // - // ################################################################### // - - _createCoordinateSearchPanelHeaderElement () { - // contexte d'execution - var self = this; - - var container = document.createElement("div"); - container.className = "GPpanelHeader gpf-panel__header fr-modal__header"; - - var divTitle = document.createElement("div"); - divTitle.className = "GPpanelTitle gpf-panel__title fr-modal__title"; - divTitle.innerHTML = "Recherche par coordonnées"; - container.appendChild(divTitle); - - var divClose = document.createElement("button"); - divClose.id = this._addUID("GPcoordinateSearchClose"); - divClose.className = "GPpanelClose GPcoordinateSearchClose gpf-btn gpf-btn-icon-close fr-btn--close fr-btn fr-btn--secondary"; - divClose.title = "Fermer la recherche par coordonnées"; - - if (divClose.addEventListener) { - divClose.addEventListener("click", function () { - var id = "#GPsearchInput-" + self._uid; - document.querySelector(id + " input").disabled = false; - document.getElementById(self._addUID("GPshowSearchByCoordinate")).setAttribute("aria-pressed", false); - document.getElementById(self._addUID("GPcoordinateSearchPanel")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPcoordinateSearchPanel")).classList.replace("gpf-visible", "gpf-hidden"); - self.onCoordinateSearchClose(); - }, false); - } else if (divClose.attachEvent) { - divClose.attachEvent("onclick", function () { - var id = "#GPsearchInput-" + self._uid; - document.querySelector(id + " input").disabled = false; - document.getElementById(self._addUID("GPshowSearchByCoordinate")).setAttribute("aria-pressed", false); - document.getElementById(self._addUID("GPcoordinateSearchPanel")).classList.replace("GPelementVisible", "GPelementHidden"); - document.getElementById(self._addUID("GPcoordinateSearchPanel")).classList.replace("gpf-visible", "gpf-hidden"); - self.onCoordinateSearchClose(); - }); - } - - var span = document.createElement("span"); - span.className = "GPelementHidden gpf-visible"; // afficher en dsfr - span.innerText = "Fermer"; - - divClose.appendChild(span); - - container.appendChild(divClose); - - return container; - }, - _createCoordinateSearchPanelFormElement () { - // contexte d'execution - var self = this; - - var form = document.createElement("form"); - form.id = this._addUID("GPcoordinateSearchForm"); - form.className = "gpf-panel__content fr-modal__content"; - form.addEventListener("submit", function (e) { - e.preventDefault(); - self.onShowSearchByCoordinateClick(); - return false; - }); - - return form; - }, - - __createCoordinateSearchDivElement () { - var div = document.createElement("div"); - div.className = "GPflexInput gpf-flex-column "; - return div; - }, - - _createCoordinateSearchSystemsLabelElement () { - var label = document.createElement("label"); - label.className = "GPcoordinateSearchSystemsLabel gpf-label fr-label"; - label.innerHTML = "Système de référence"; - return label; - }, - _setCoordinateSearchSystemsSelectElement (systems) { - if (document.getElementById(this._addUID("GPcoordinateSearchSystem"))) { - document.getElementById(this._addUID("GPcoordinateSearchSystem")).remove(); - } - // contexte d'execution - var context = this; - - var selectSystem = document.createElement("select"); - selectSystem.id = this._addUID("GPcoordinateSearchSystem"); - selectSystem.title = "Choisir un système de réference"; - selectSystem.className = "GPselect GPcoordinateSearchSystemsSelect gpf-select fr-select"; - selectSystem.addEventListener("change", function (e) { - context.onCoordinateSearchSystemChange(e); - }); - - for (var i = 0; i < systems.length; i++) { - var obj = systems[i]; - var option = document.createElement("option"); - option.value = obj.code; - option.text = obj.label || i; - // option.label = obj.label; - selectSystem.appendChild(option); - } - - return selectSystem; - }, - - _createCoordinateSearchUnitsLabelElement () { - var label = document.createElement("label"); - label.className = "GPcoordinateSearchUnitsLabel gpf-label fr-label"; - label.innerHTML = "Unités"; - return label; - }, - _setCoordinateSearchUnitsSelectElement (units) { - if (document.getElementById(this._addUID("GPcoordinateSearchUnits"))) { - document.getElementById(this._addUID("GPcoordinateSearchUnits")).remove(); - } - // contexte d'execution - var context = this; - - var selectUnits = document.createElement("select"); - selectUnits.id = this._addUID("GPcoordinateSearchUnits"); - selectUnits.title = "Choisir un type d'unité"; - selectUnits.className = "GPselect GPcoordinateSearchUnitsSelect gpf-select fr-select"; - selectUnits.addEventListener("change", function (e) { - context.onCoordinateSearchUnitsChange(e); - }); - - for (var j = 0; j < units.length; j++) { - var obj = units[j]; - var option = document.createElement("option"); - option.value = (obj.code) ? obj.code : j; - option.text = obj.label || j; - // option.label = obj.label; - selectUnits.appendChild(option); - } - - return selectUnits; - }, - - /** - * update Label - * @param {String} type - Geographical or Metric - * @returns {DOMElement} label - */ - _setCoordinateSearchLngLabelElement (type) { - // type geographical ou metric - if (document.getElementById(this._addUID("GPcoordinateSearchLngLabel"))) { - document.getElementById(this._addUID("GPcoordinateSearchLngLabel")).remove(); - } - var labelLng = document.createElement("label"); - labelLng.className = "GPcoordinateSearchLabel gpf-label fr-label"; - labelLng.id = this._addUID("GPcoordinateSearchLngLabel"); - labelLng.htmlFor = "coordinate-lng"; - labelLng.innerHTML = (type === "Geographical") ? "Longitude :" : "Y :"; - - return labelLng; - }, - /** - * update Input coordinate - * @param {String} code - ex. DMS : degrés sexadecimaux - * @returns {DOMElement} input - */ - _setCoordinateSearchLngInputElement (code) { - // code DMS ou other - if (document.getElementById(this._addUID("GPcoordinateSearchLngInput"))) { - document.getElementById(this._addUID("GPcoordinateSearchLngInput")).remove(); - } - if (document.getElementById(this._addUID("GPcoordinateSearchLngDMS"))) { - document.getElementById(this._addUID("GPcoordinateSearchLngDMS")).remove(); - } - var input = document.createElement("input"); - input.id = this._addUID("GPcoordinateSearchLngInput"); - input.className = "GPcoordinateSearchInput gpf-input fr-input"; - input.title = "Saisir des coordonnées"; - input.name = "coordinate-lng"; - input.required = ""; - switch (code) { - case "DMS": - input.title += " géographiques (en sexa)"; - input.className = "GPelementHidden gpf-hidden"; - return this._setCoordinateSearchLngDMSElement(); - break; - case "DEC": - input.title += " géographiques (en decimal)"; - input.type = "number"; - input.min = "-180"; - input.max = "180"; - break; - case "M": - input.title += " cartésiennes (en mètre)"; - input.type = "number"; - break; - case "KM": - input.title += " cartésiennes (en kilomètre)"; - input.type = "number"; - break; - default: - break; - } - return input; - }, - _setCoordinateSearchLngDMSElement () { - var div = document.createElement("div"); - div.id = this._addUID("GPcoordinateSearchLngDMS"); - div.innerHTML = ` -
- - - - - - - -
- `; - return div; - }, - /** - * update Label - * @param {String} type - Geographical or Metric - * @returns {DOMElement} label - */ - _setCoordinateSearchLatLabelElement (type) { - // type geographical ou metric - if (document.getElementById(this._addUID("GPcoordinateSearchLatLabel"))) { - document.getElementById(this._addUID("GPcoordinateSearchLatLabel")).remove(); - } - var labelLat = document.createElement("label"); - labelLat.className = "GPcoordinateSearchLabel gpf-label fr-label"; - labelLat.id = this._addUID("GPcoordinateSearchLatLabel"); - labelLat.htmlFor = "coordinate-lat"; - labelLat.innerHTML = (type === "Geographical") ? "Latitude :" : "X :"; - - return labelLat; - }, - /** - * update Input coordinate - * @param {String} code - ex. DMS : degrés sexadecimaux - * @returns {DOMElement} input - */ - _setCoordinateSearchLatInputElement (code) { - // code DMS ou other - if (document.getElementById(this._addUID("GPcoordinateSearchLatInput"))) { - document.getElementById(this._addUID("GPcoordinateSearchLatInput")).remove(); - } - if (document.getElementById(this._addUID("GPcoordinateSearchLatDMS"))) { - document.getElementById(this._addUID("GPcoordinateSearchLatDMS")).remove(); - } - var input = document.createElement("input"); - input.id = this._addUID("GPcoordinateSearchLatInput"); - input.className = "GPcoordinateSearchInput gpf-input fr-input"; - input.title ="Saisir des coordonnées"; - input.name = "coordinate-lat"; - input.required = ""; - switch (code) { - case "DMS": - input.title += " géographiques (en sexa)"; - input.className = "GPelementHidden gpf-hidden"; - return this._setCoordinateSearchLatDMSElement(); - break; - case "DEC": - input.title += " géographiques (en decimal)"; - input.type = "number"; - input.min = "-180"; - input.max = "180"; - break; - case "M": - input.title += " cartésiennes (en mètre)"; - input.type = "number"; - break; - case "KM": - input.title += " cartésiennes (en kilomètre)"; - input.type = "number"; - break; - default: - break; - } - return input; - }, - _setCoordinateSearchLatDMSElement () { - var div = document.createElement("div"); - div.id = this._addUID("GPcoordinateSearchLatDMS"); - div.innerHTML = ` -
- - - - - - - -
- `; - return div; - }, - - /** - * submit - * @returns {DOMElement} input - */ - _createCoordinateSearchSubmitElement () { - var input = document.createElement("input"); - input.type = "submit"; - input.id = this._addUID("GPcoordinateSearchSubmit"); - input.className = "GPsubmit gpf-btn gpf-btn-icon-submit fr-btn fr-btn--secondary"; - input.value = "Chercher"; - return input; - }, -}; - -export default SearchEngineDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBox.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBox.d.ts deleted file mode 100644 index 796e2e405..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBox.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export default MeasureToolBox; -/** - * @type {ol.control.MeasureToolBox} - * MeasureToolBox - Boite à outils (ToolBox) pour les outils de mesures. - * - distance - * - aire - * - azimut - */ -declare var MeasureToolBox: ol.control.MeasureToolBox; -//# sourceMappingURL=MeasureToolBox.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBox.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBox.d.ts.map deleted file mode 100644 index 912d1a7f3..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBox.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MeasureToolBox.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/ToolBoxMeasure/MeasureToolBox.js"],"names":[],"mappings":";AAYA;;;;;;GAMG;AACH,sDAoEE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBox.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBox.js deleted file mode 100644 index 26aaac94b..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBox.js +++ /dev/null @@ -1,92 +0,0 @@ -// import CSS -import "../../CSS/Controls/ToolBoxMeasure/GPFtoolBoxMeasure.css"; -// import "../../CSS/Controls/ToolBoxMeasure/GPFtoolBoxMeasureStyle.css"; -// import local -import Logger from "../../Utils/LoggerByDefault"; -import Utils from "../../Utils/Helper"; -import ID from "../../Utils/SelectorID"; -// DOM -import MeasureToolBoxDOM from "./MeasureToolBoxDOM"; - -var logger = Logger.getLogger("toolbox"); - -/** - * @type {ol.control.MeasureToolBox} - * MeasureToolBox - Boite à outils (ToolBox) pour les outils de mesures. - * - distance - * - aire - * - azimut - */ -var MeasureToolBox = { - - /** - * liste des uid/map (pour chaque toolbox) - * { map : uid } - * Ex. { "map1" : 465456456486845 } - */ - _toolbox : {}, - - /** - * Ajout d'un controle dans la ToolBox. - * Creation de la toolbox si besoin... - * - * @param {ol.Map} map - map - * @param {ol.control.Control} ctrl - objet à ajouter - */ - add : function (map, ctrl) { - logger.trace("ToolBox.add()", ctrl); - - if (!map) { - logger.trace("map doesn't exist !?"); - return; - } - - // contexte d'execution - var context = typeof window !== "undefined" ? window : typeof self !== "undefined" ? self : null; - if (context) { - // Pour info - // l'objet ToolBox devrait être partagé avec les outils de mesures..., - // mais, ce n'est pas le cas pour le mode modules cad un module par extension. - // c'est pourquoi, on l'enregistre dans le contexte, qui lui est partagé (ex. window) - this._toolbox = context.gpShareMeasureToolBox || {}; - } - - var mapContainer = map.getTargetElement(); - var mapDocument = mapContainer.ownerDocument; - var mapId = mapContainer.id; - - if (!this._toolbox || Object.keys(this._toolbox).length === 0) { - this._toolbox = {}; - this._toolbox[mapId] = ID.generate(); - } else { - if (!this._toolbox[mapId]) { - this._toolbox[mapId] = ID.generate(); - } - } - - var uid = this._toolbox[mapId]; - if (!mapDocument.getElementById(this.getToolBoxID(uid))) { - logger.trace("create toolbox !"); - // creation et ajout de la toolbox sur la map - var toolboxContainer = this._createToolBoxContainerElement(uid); - toolboxContainer.style.pointerEvents = "auto"; // ajout pour ol6 - var overlaysContainer = mapContainer.getElementsByClassName("ol-overlaycontainer-stopevent"); - overlaysContainer[0].appendChild(toolboxContainer); - // mapContainer.appendChild(toolboxContainer); - } - - // ajout du widget dans la toolbox - var widgetContainer = mapDocument.getElementById(this.getWidgetID(uid)); - ctrl.setTarget(widgetContainer); - if (context) { - // Pour info - // on partage (enregistre) l'objet ToolBox dans le contexte d'execution ! - context.gpShareMeasureToolBox = this._toolbox; - } - logger.trace("add control to toolbox !"); - } -}; - -Utils.assign(MeasureToolBox, MeasureToolBoxDOM); - -export default MeasureToolBox; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.d.ts deleted file mode 100644 index 4aa59b3e7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -export default MeasureToolBoxDOM; -declare namespace MeasureToolBoxDOM { - let _toolboxId: string; - let _buttonId: string; - let _widgetId: string; - function getToolBoxID(uid: number): string; - function getButtonID(uid: number): string; - function getWidgetID(uid: number): string; - function _createToolBoxContainerElement(uid: number): DOMElement; -} -//# sourceMappingURL=MeasureToolBoxDOM.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.d.ts.map deleted file mode 100644 index e1325ee11..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MeasureToolBoxDOM.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.js"],"names":[],"mappings":";;;;;IAWmB,2CAEd;IAOa,0CAEb;IAOa,0CAEb;IAOgC,iEAkEhC"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.js deleted file mode 100644 index 7107d978f..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/ToolBoxMeasure/MeasureToolBoxDOM.js +++ /dev/null @@ -1,108 +0,0 @@ -var MeasureToolBoxDOM = { - - _toolboxId : "GPtoolbox-measure-main", - _buttonId : "GPtoolbox-measure-button", - _widgetId : "GPtoolbox-measure-widget", - - /** - * get toolBox ID - * @param {Number} uid - uid - * @returns {String} id selector unique - */ - getToolBoxID : function (uid) { - return (uid) ? this._toolboxId + "-" + uid : this._toolboxId; - }, - - /** - * get button ID - * @param {Number} uid - uid - * @returns {String} id selector unique - */ - getButtonID : function (uid) { - return (uid) ? this._buttonId + "-" + uid : this._buttonId; - }, - - /** - * get toolBox Container for widget - * @param {Number} uid - uid - * @returns {String} id selector unique - */ - getWidgetID : function (uid) { - return (uid) ? this._widgetId + "-" + uid : this._widgetId; - }, - - /** - * Main container (DOM) - * @param {Number} uid - uid - * @returns {DOMElement} DOM element - */ - _createToolBoxContainerElement : function (uid) { - //
- // - //
- // - //
- //
- var container = document.createElement("div"); - container.id = this.getToolBoxID(uid); - container.className = "GPshowAdvancedToolPicto"; - - var button = document.createElement("button"); - button.id = this.getButtonID(uid); - button.className = "GPshowOpen GPshowAdvancedToolPicto GPshowToolBoxPicto gpf-btn gpf-btn-icon-toolbox fr-btn"; - button.setAttribute("tabindex", "0"); - button.setAttribute("aria-pressed", false); - - var self = this; - button.addEventListener("click", function (e) { - var status = (e.target.ariaPressed === "true"); - e.target.setAttribute("aria-pressed", !status); - this.blur(); // permet de perdre le focus ! - var widget = document.getElementById(self.getWidgetID(uid)); - if (widget.style.display === "block") { - widget.style.display = "none"; - } else { - widget.style.display = "block"; - } - }); - container.appendChild(button); - - var widget = document.createElement("div"); - widget.id = this.getWidgetID(uid); - widget.addEventListener("click", function () { - - /* - e.preventDefault(); - - // FIXME desactiver tous les outils sur - // l'ouverture/fermeture de la toolbox ? - - var current = e.target.parentNode.getAttribute("for"); - var widgets = this.querySelectorAll("div > input"); - for (var i = 0; i < widgets.length; i++) { - var id = widgets[i].id; - - if (document.getElementById(id) && - document.getElementById(id).checked && - document.querySelector("#" + id + " + label")) { - document.querySelector("#" + id + " + label").click(); - // document.getElementById(id).checked = true; - } - - if (current === id && widgets[i].checked) { - widgets[i].checked = false; - } else if (current === id && !widgets[i].checked) { - widgets[i].checked = true; - } - } - */ - - }, false); - - container.appendChild(widget); - - return container; - } -}; - -export default MeasureToolBoxDOM; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Gfi.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Gfi.d.ts deleted file mode 100644 index 43e8d8967..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Gfi.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -export default Gfi; -declare namespace Gfi { - function getLayerFormat(l: ol.layer.Layer): string; - function displayInfo(map: ol.Map, coords: ol.Coordinate, content: string, contentType?: string | undefined, autoPanOptions: { - autoPan?: boolean | Object | undefined; - autoPanAnimation?: Object | undefined; - autoPanMargin?: number | undefined; - }): boolean; - function features2html(map: ol.Map, features: ol.Features[]): HTMLElement; - function layerGetFeatureAtCoordinates(map: ol.Map, olLayer: ol.layer.Layer, olCoordinate: ol.Coordinate): boolean; - function displayVectorFeatureInfo(map: ol.Map, olCoordinate: ol.Coordinate, olLayers: ol.layer.Layer[], autoPanOptions: Object): boolean; - function displayFeatureInfo(map: ol.Map, olCoordinate: ol.Coordinate, gfiLayers: Object[], proxyOptions?: { - proxyUrl?: string | undefined; - noProxyDomains?: string[] | undefined; - } | undefined, autoPanOptions?: { - autoPan?: boolean | undefined; - autoPanAnimation?: Object | undefined; - autoPanMargin?: number | undefined; - } | undefined): void; - function getPosition(e: any, map: any): any; - function onDisplayFeatureInfo(e: any, gfiObj: any): void; -} -//# sourceMappingURL=Gfi.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Gfi.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Gfi.d.ts.map deleted file mode 100644 index 597f78296..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Gfi.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Gfi.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Utils/Gfi.js"],"names":[],"mappings":";;IA+BqB,mDA+BhB;IAea;;;;gBA6Gb;IASe,0EAmFf;IAY8B,kHAQ9B;IAe0B,yIAuB1B;IAyBoB;;;;;;;yBA+KpB;IAGa,4CAqBb;IAGsB,yDA0DtB"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Gfi.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Gfi.js deleted file mode 100644 index ab814b20a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Gfi.js +++ /dev/null @@ -1,636 +0,0 @@ -// import OpenLayers -import Overlay from "ol/Overlay"; -import VectorTileSource from "ol/source/VectorTile"; -import VectorSource from "ol/source/Vector"; -import TileWMSSource from "ol/source/TileWMS"; -import WMTSSource from "ol/source/WMTS"; -import ImageWMSSource from "ol/source/ImageWMS"; -import { - Select as SelectInteraction, - Modify as ModifyInteraction, - Draw as DrawInteraction -} from "ol/interaction"; -// import geoportal library access -import Gp from "geoportal-access-lib"; -// import local -import Logger from "../../Utils/LoggerByDefault"; -import ProxyUtils from "../../Utils/ProxyUtils"; -// import $__xmldom from "xmldom"; - -var logger = Logger.getLogger("GfiUtils"); - -var Gfi = { - - /** - * Return layer format - * - * @param {ol.layer.Layer} l - layer openlayers - * - * @return {String} format - layer format can be wms, wmts, vector or unknown - * - */ - getLayerFormat : function (l) { - // la fonction 'getType' existe uniquement en mode source es6. - // le bundle ol ne fournit pas cette fonction !? - var type = (typeof l.getType === "function") ? l.getType() : null; - var source = l.getSource(); - if (type) { - if (type === "VECTOR" || type === "VECTOR_TILE") { - return "vector"; - } - if (type === "TILE") { - if (source.tileGrid) { - return "wmts"; - } else { - return "wms"; - } - } - if (type === "IMAGE") { - return "wms"; - } - } else { - if (source instanceof TileWMSSource || source instanceof ImageWMSSource) { - return "wms"; - } - if (source instanceof WMTSSource) { - return "wmts"; - } - if (source instanceof VectorSource || source instanceof VectorTileSource) { - return "vector"; - } - } - return "unknown"; - }, - - /** - * Info Popup creation and display - * - * @param {ol.Map} map - map openlayers - * @param {ol.Coordinate} coords - coordinates where to anchor popup. - * @param {String} content - content to display - * @param {String} [contentType='text/html'] - content mime-type - * @param {Object} autoPanOptions - Auto-pan pop-up options - * @param {Boolean|Object} [autoPanOptions.autoPan] - Specifies whether the map should auto-pan if the pop-up is rendered outside of the canvas (See {@link https://openlayers.org/en/latest/apidoc/module-ol_Overlay.html#~PanIntoViewOptions PanIntoViewOptions}) - * @param {Object} [autoPanOptions.autoPanAnimation] - Used to customize the auto-pan animation. See {@link https://openlayers.org/en/latest/apidoc/module-ol_Overlay.html#~PanOptions PanOptions}. - * @param {Number} [autoPanOptions.autoPanMargin] - Margin (in pixels) between the pop-up and the border of the map when autopanning. Default is 20. - * @return {Boolean} displayed - indicates if something has been displayed - */ - displayInfo : function (map, coords, content, contentType, autoPanOptions) { - logger.trace("[Gfi] : displayInfo..."); - - if (!contentType) { - contentType = "text/html"; - } - - if (content === null) { - return; - } - - var _htmlDoc = null; - var _parser = null; - - var _content = content; - _content = _content.replace(/\n/g, ""); - _content = _content.replace(/(>)\s*(<)/g, "$1$2"); - - var scope = typeof window !== "undefined" ? window : null; - - if (typeof exports === "object" && window === null) { - // code for nodejs - var DOMParser = require("xmldom").DOMParser; - _parser = new DOMParser(); - _htmlDoc = _parser.parseFromString(_content, contentType); - } else if (scope.DOMParser) { - // code for modern browsers - _parser = new scope.DOMParser(); - _htmlDoc = _parser.parseFromString(_content, contentType); - } else if (scope.ActiveXObject) { - // code for old IE browsers - _htmlDoc = new scope.ActiveXObject("Microsoft.XMLDOM"); - _htmlDoc.async = false; - _htmlDoc.loadXML(_content); - } else { - logger.log("Incompatible environment for DOM Parser !"); - return false; - } - - var body = _htmlDoc.getElementsByTagName("body"); - if (body && body.length === 1) { - if (!body[0].hasChildNodes()) { - return false; - } - } - - // Affichage des features. - var element = document.createElement("div"); - element.className = "gp-feature-info-div"; - - var closer = document.createElement("input"); - closer.type = "button"; - closer.className = "gp-styling-button closer"; - - // fait disparaître la popup au clic sur x - closer.onclick = function () { - if (map.featuresOverlay) { - map.removeOverlay(map.featuresOverlay); - map.featuresOverlay = null; - } - return false; - }; - - var contentDiv = document.createElement("div"); - contentDiv.className = "gp-features-content-div"; - contentDiv.innerHTML = content; - /* - if (content instanceof HTMLElement) { - this.logger.trace("[Openlayers] : _displayInfo : pure HTMLElement") ; - contentDiv.appendChild(content) ; - } else { - var parser = new DOMParser() ; - var doc = null ; - try { - doc = parser.parseFromString(content,contentType) ; - this.logger.trace("[Openlayers] : _displayInfo : HTMLElement from parser") ; - // FIXME : avec cette methode, on a une balise html + body qui s'insère... - contentDiv.appendChild(doc.documentElement) ; - } catch (e) { - console.log(e) ; - this.logger.trace("[Openlayers] : _displayInfo : parsing content failed (not HTML)") ; - // en cas d'erreur : on se contente de recopier le contenu. - contentDiv.innerHTML = content ; - } - } - */ - element.appendChild(contentDiv); - element.appendChild(closer); - - if (map.featuresOverlay) { - // fermeture d'une éventuelle popup déjà ouverte. - map.removeOverlay(map.featuresOverlay); - map.featuresOverlay = null; - } - map.featuresOverlay = new Overlay({ - // id : id, - element : element, - autoPan : autoPanOptions.autoPan, - autoPanAnimation : autoPanOptions.autoPanAnimation, - autoPanMargin : autoPanOptions.autoPanMargin, - positioning : "bottom-center", - insertFirst : false, // popup appears on top of other overlays if any - stopEvent : true - }); - map.addOverlay(map.featuresOverlay); - map.featuresOverlay.setPosition(coords); - map.featuresOverlay.render(); - - return true; - }, - - /** - * Gets HTML content from features array - * - * @param {ol.Map} map - map openlayers - * @param {Array.} features - openlayers features Array - * @returns {HTMLElement} HTML content. - */ - features2html : function (map, features) { - var content = document.createElement("div"); - features.forEach(function (f) { - var props = f.getProperties(); - // si la properties 'render' est presente, - // on ajoute directement le rendu HTML dans la balise principale - if (props.hasOwnProperty("render")) { - // content.innerHTML = props["render"].trim(); - // content.appendChild(props["render"]); - content.insertAdjacentHTML("beforeend", props["render"]); - } else { - if (props.hasOwnProperty("name")) { - var nameDiv = document.createElement("div"); - nameDiv.className = "gp-att-name-div"; - // nameDiv.appendChild(document.createTextNode(props["name"])) ; - nameDiv.insertAdjacentHTML("afterbegin", props["name"]); - content.appendChild(nameDiv); - } - if (props.hasOwnProperty("description")) { - var descDiv = document.createElement("div"); - descDiv.className = "gp-att-description-div"; - // descDiv.appendChild(document.createTextNode(props["description"])) ; - descDiv.insertAdjacentHTML("afterbegin", props["description"]); - content.appendChild(descDiv); - } - var p = null; - var others = false; - var oDiv = null; - var ul = null; - var li = null; - // Liste des properties à retirer de la visualisation : - var listForbidden = [ - // styles - "fill", - "fill-opacity", - "stroke", - "stroke-opacity", - "stroke-width", - "marker-symbol", - "marker-color", - "marker-size", - "geometry", // geometrie - "value", - "name", // déjà traité - "description", // déjà traité - "styleUrl", - "extensionsNode_", // extensions GPX - "icon" // ajouté par la 3D en cas de switch - ]; - for (p in props) { - if (props[p] === undefined) { - continue; - } - if (listForbidden.indexOf(p) !== -1) { - continue; - } - if (!others) { - oDiv = document.createElement("div"); - oDiv.className = "gp-att-others-div"; - ul = document.createElement("ul"); - others = true; - } - li = document.createElement("li"); - var span = document.createElement("span"); - span.className = "gp-attname-others-span"; - span.appendChild(document.createTextNode(p + " : ")); - li.appendChild(span); - li.appendChild(document.createTextNode(props[p])); - ul.appendChild(li); - } - if (ul) { - oDiv.appendChild(ul); - content.appendChild(oDiv); - } - } - }, map); - - // pas de contenu ! - if (!content.hasChildNodes()) { - content = null; - } - - return content; - }, - - /** - * Indicates if there is a feature at the given coordinates for the given layer - * - * @param {ol.Map} map - map openlayers - * @param {ol.layer.Layer} olLayer - vector layer openlayers - * @param {ol.Coordinate} olCoordinate - coordinates pointed by user - * - * @return {Boolean} has feature - * - */ - layerGetFeatureAtCoordinates : function (map, olLayer, olCoordinate) { - var pixel = map.getPixelFromCoordinate(olCoordinate); - return map.hasFeatureAtPixel(pixel, function (layer) { - if (layer === olLayer) { - return true; - } - return false; - }); - }, - - /** - * Get information from all the features located at the specified coordinates - * and belonging to the layers list argument. Those information are gathered - * and displayed in an info popup. - * - * @param {ol.Map} map - map openlayers - * @param {ol.Coordinate} olCoordinate - coordinates pointed by user - * @param {Array.} olLayers - layers requested - * @param {Object} autoPanOptions - autopan options - * - * @returns {Boolean} something is displayed - * - */ - displayVectorFeatureInfo : function (map, olCoordinate, olLayers, autoPanOptions) { - var pixel = map.getPixelFromCoordinate(olCoordinate); - - // couches vecteur : on remplit un tableau avec les features à proximité. - var features = []; - map.forEachFeatureAtPixel(pixel, function (feature, layer) { - if (!olLayers || olLayers.indexOf(layer) > -1) { - features.push(feature); - } - }); - if (features.length === 0) { - // no features - return false; - } - var content = this.features2html(map, features); - // pas de contenu ! - if (content === null) { - return false; - } - // Affichage des features. - this.displayInfo(map, olCoordinate, content.innerHTML, "text/html", autoPanOptions); - // this._displayInfo(evt.coordinate,content,"text/html") ; - return true; - }, - - /** - * Method to manage the request of information from a list of layers already added to the map. - * Among the given list of layers only the visible ones are requested. - * The priority is given to the upper layer having a feature at the pointed coordinates. - * If the first (upper) feature encountered is from a vector layer the info popup will - * display the information of the features from all visible vector layers and located at - * the specified coordinates. - * - * @param {ol.Map} map - map openlayers - * @param {ol.Coordinate} olCoordinate - coordinates pointed by user - * @param {Array.} gfiLayers - list of layers which can be requested through the control. Each array element is an object, with following properties : - * @param {ol.layer.Layer} gfiLayers.obj - ol.layer.Layer layer handled by the control (that has been added to map). - * @param {String} [gfiLayers.event] - name of the mouse event triggering getFeatureInfo on this layer (that has been added to map). allowed values are : 'singleclick', 'dblclick' and 'contextmenu' - * @param {String} [gfiLayers.infoFormat] - indicates the format mime-type of the response of GetFeatureInfo requests. - * @param {Object} [proxyOptions] - options for poxy configuration : - * @param {String} [proxyOptions.proxyUrl] - Proxy URL to avoid cross-domain problems, if not already set in mapOptions. Mandatory to import WMS and WMTS layer. - * @param {Array.} [proxyOptions.noProxyDomains] - Proxy will not be used for this list of domain names. Only use if you know what you're doing (if not already set in mapOptions). - * @param {Object} [autoPanOptions] - Auto-pan pop-up options - * @param {Boolean} [autoPanOptions.autoPan = true] - Specifies whether the map should auto-pan if the pop-up is rendered outside of the canvas. Defaults to true. - * @param {Object} [autoPanOptions.autoPanAnimation] - Used to customize the auto-pan animation. See {@link https://openlayers.org/en/latest/apidoc/module-ol_Overlay.html#~PanOptions PanOptions}. - * @param {Number} [autoPanOptions.autoPanMargin] - Margin (in pixels) between the pop-up and the border of the map when autopanning. Default is 20. - * - */ - displayFeatureInfo : function (map, olCoordinate, gfiLayers, proxyOptions, autoPanOptions) { - // Layers orders - var layersOrdered = {}; - for (var j = 0; j < gfiLayers.length; j++) { - var layer = gfiLayers[j]; - var position = layer.obj.getZIndex(); - if (!layersOrdered[position]) { - layersOrdered[position] = []; - } - layersOrdered[position].push(layer); - } - - // affichage de la première popup d'informations en partant du dessus... - var requests = []; - // inversion de l'ordre des layers - var positions = Object.keys(layersOrdered); - positions.sort(function (a, b) { - return b - a; - }); - - // si la 1ere couche affichable est de type vecteur on affiche les infos de toutes - // les couches vecteur qui suivent. Par consequent, une seule requete vecteur suffit - // (celle correspondant au premier objet vecteur rencontre) - var foundFeature = false; - - for (var k = 0; k < positions.length; k++) { - var p = positions[k]; - for (var h = 0; h < layersOrdered[p].length; ++h) { - var l = layersOrdered[p][h].obj; - var infoFormat = layersOrdered[p][h].infoFormat || "text/html"; - var minMaxResolutionOk = true; - if (l.minResolution && - l.minResolution > map.getResolution()) { - minMaxResolutionOk = false; - } - if (minMaxResolutionOk && - l.maxResolution && - l.maxResolution < map.getResolution()) { - minMaxResolutionOk = false; - } - - if (l.getVisible() && minMaxResolutionOk) { - var format = this.getLayerFormat(l); - if (format === "vector") { - if (!foundFeature && this.layerGetFeatureAtCoordinates(map, l, olCoordinate)) { - requests.push({ - format : format, - scope : this, - coordinate : olCoordinate - }); - } - continue; - } else if (format !== "wms" && format !== "wmts") { - logger.log("[ERROR] DisplayFeatureInfo - layer format '" + format + "' not allowed"); - continue; - } - - var _res = map.getView().getResolution(); - var _url = null; - // INFO - // en fonction de la version d'openlayers, la méthode est differente : - // - getGetFeatureInfoUrl en v5 - // - getFeatureInfoUrl en v6 - if (format === "wmts") { - // eslint-disable-next-line no-useless-call - _url = l.getSource().getFeatureInfoUrl.call(l.getSource(), - olCoordinate, - _res, - map.getView().getProjection(), { - INFOFORMAT : infoFormat - } - ); - } else { - // eslint-disable-next-line no-useless-call - _url = l.getSource().getFeatureInfoUrl.call(l.getSource(), - olCoordinate, - _res, - map.getView().getProjection(), { - INFO_FORMAT : infoFormat - } - ); - } - - requests.push({ - // id : _id, - format : infoFormat, - url : ProxyUtils.proxifyUrl(_url, proxyOptions), - scope : this, - coordinate : olCoordinate - }); - } - } - } - - // on recupere les couches vecteur ordonnees (a utiliser dans le cas de l'affichage de donnees vecteur) - var vectorLayersOrdered = null; - - // call request sync - function requestsSync (list, iterator, callback) { - if (list.length === 0) { - return; - } - var nextItemIndex = 0; - // function report next request - function report (displayed) { - nextItemIndex++; - if (displayed || nextItemIndex === list.length) { - callback(); - } else { - iterator(list[nextItemIndex], report); - } - } - // instead of starting all the iterations, we only start the 1st one - iterator(list[0], report); - }; - - var context = this; - - requestsSync(requests, - function (data, report) { - if (data.format === "vector") { - if (!vectorLayersOrdered) { - vectorLayersOrdered = []; - for (var m = 0; m < positions.length; m++) { - var p = positions[m]; - for (var n = 0; n < layersOrdered[p].length; ++n) { - vectorLayersOrdered.push(layersOrdered[p][n].obj); - } - } - } - report(data.scope.displayVectorFeatureInfo(map, data.coordinate, vectorLayersOrdered, autoPanOptions)); - } else { - // var self = data.scope; - Gp.Protocols.XHR.call({ - url : data.url, - method : "GET", - scope : data.scope, - // Handles GFI response - onResponse : function (resp) { - var exception = false; - - // a t on une exception ? - // - // - // - // java.lang.OutOfMemoryError: Java heap space - // Java heap space - // - // - if (resp.trim().length === 0 || - resp.indexOf("ServiceExceptionReport") !== -1 || - resp.indexOf("java.lang.NullPointerException") !== -1 || - resp.indexOf("java.lang.OutOfMemoryError") !== -1 || - resp.indexOf("not queryable") !== -1) { - // rien à afficher - exception = true; - } - - // on affiche la popup GFI ! - var displayed = !exception && context.displayInfo(map, data.coordinate, resp, "text/html", autoPanOptions); - // on reporte sur la prochaine requête... - report(displayed); - }, - // Handles GFI response error - onFailure : function (error) { - logger.log(error); - report(false); - } - }); - } - }, - function () { - logger.trace("Finish sync to GFI !"); - } - ); - }, - - // Function returning the clicked position of an event - getPosition : function (e, map) { - if (e.coordinate) { - return e.coordinate; - } - - var pixel = [0, 0]; - - if (e.offsetX || e.offsetY) { - pixel[0] = e.offsetX; // + document.body.scrollLeft + document.documentElement.scrollLeft; - pixel[1] = e.offsetY; // + document.body.scrollTop + document.documentElement.scrollTop; - } else if (e.pointerType === "touch") { - // a implementer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - // Safari iOS / iPhone en mode Touch (cf. hammer) - var p = e.pointers[0]; - pixel[0] = p.pageX; - pixel[1] = p.pageY; - } - - var coordinate = map.getCoordinateFromPixel(pixel); - return coordinate; - }, - - // onDisplayFeatureInfo - onDisplayFeatureInfo : function (e, gfiObj) { - if (!gfiObj.isActive()) { - return; - } - - logger.trace(e); - - var map = gfiObj.getMap(); - - if (e.type === "contextmenu" || e.type === "dblclick") { - e.preventDefault(); - } else if (e.type === "singleclick") { - var interactions = map.getInteractions().getArray(); - for (var i = 0; i < interactions.length; i++) { - if (interactions[i].getActive() && - (interactions[i] instanceof SelectInteraction || - interactions[i] instanceof ModifyInteraction || - interactions[i] instanceof DrawInteraction) - ) { - // si on a une interaction de dessin ou de sélection en cours, on ne fait rien. - return; - } - } - } - - var proxyOptions = {}; - if (gfiObj._proxyUrl) { - proxyOptions.proxyUrl = gfiObj._proxyUrl; - } - if (gfiObj._noProxyDomains) { - proxyOptions.noProxyDomains = gfiObj._noProxyDomains; - } - - var autoPanOptions = {}; - if (gfiObj._autoPan) { - autoPanOptions.autoPan = gfiObj._autoPan; - } - if (gfiObj._autoPanAnimation) { - autoPanOptions.autoPanAnimation = gfiObj._autoPanAnimation; - } - if (gfiObj._autoPanMargin) { - autoPanOptions.autoPanMargin = gfiObj._autoPanMargin; - } - - var eventLayers = []; - for (var j = 0; j < gfiObj._layers.length; ++j) { - var event = (gfiObj._layers[j].event) ? gfiObj._layers[j].event : gfiObj._defaultEvent; - if (event === e.type) { - var ind = eventLayers.push(gfiObj._layers[j]) - 1; - if (!eventLayers[ind].infoFormat) { - eventLayers[ind].infoFormat = gfiObj._defaultInfoFormat; - } - } - } - - var coords = this.getPosition(e, map); - - this.displayFeatureInfo(map, coords, eventLayers, proxyOptions, autoPanOptions); - } -}; - -export default Gfi; - -// Expose Gfi as ol.gp.GfiUtils (for a build bundle) -if (window.ol) { - if (window.ol.gp) { - window.ol.gp.GfiUtils = Gfi; - } else { - window.ol.gp = { - GfiUtils : Gfi - }; - } -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Interactions.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Interactions.d.ts deleted file mode 100644 index 5c48720a7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Interactions.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export default Interactions; -declare namespace Interactions { - let _extensions: string[]; - namespace _options { - let current: null; - let clean: null; - } - function unset(map: Object, options: Object): void; -} -//# sourceMappingURL=Interactions.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Interactions.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Interactions.d.ts.map deleted file mode 100644 index 1017d6798..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Interactions.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Interactions.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Utils/Interactions.js"],"names":[],"mappings":";;;;;;;IA6EY,mDA0CP"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Interactions.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Interactions.js deleted file mode 100644 index ab0267969..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Interactions.js +++ /dev/null @@ -1,123 +0,0 @@ -// import OpenLayers -import Control from "ol/control/Control"; -import { - Select as SelectInteraction, - Modify as ModifyInteraction, - Draw as DrawInteraction -} from "ol/interaction"; -// import local -import Logger from "../../Utils/LoggerByDefault"; -import Utils from "../../Utils/Helper"; - -var logger = Logger.getLogger("interactions"); - -/** - * @private - * @description - * Pourquoi et comment l'utiliser ? - * Cette classe permet de gérer les interactions entre chaque extension. - * Une extension qui active une interaction avec la carte, doit desactiver - * les autres interactions issues d'autre extensions. - * La désactivation d'une interaction s'accompagne d'actions telles que - * le nettoyage des dessins, l'état du composant graphique, ... - * - * Ex - * // desactive toutes les interactions avec l'opération par defaut : clean - * Interactions.unset(map); - * // desactive les interactions sauf celles de Drawing. On execute des - * // operations particulieres : status, collapse et message - * Interactions.unset(map, { - * current : "Drawing", - * status : false, - * collapse : true, - * messsage : ["WARNING", "Ceci est un avertissement !"] - * }); - * - * Dans le code de l'extension, il faut placer des informations dans l'interaction : - * interaction.setProperties({ - * name : "Drawing", - * source : this - * }); - */ -var Interactions = { - - /** - * Liste des extensions qui utilisent le mécanisme des interactions - */ - _extensions : [ - "Measures", - "ElevationPath", - "Drawing" - ], - - /** - * Options par defaut - * - current : ex. "Drawing" - * c'est l'extension qui demande la desactivation des autres interactions. - * Par defaut, toutes les interactions sont desactivées. - * - clean : - * c'est la suppression des interactions, des dessins de la carte, - * ainsi que la reinitialisation de l'état graphique. - * Les extensions doivent implementer la méthode 'clean()'. - * Par defaut, tous les dessins sont supprimés - */ - _options : { - current : null, - clean : null - }, - - /** - * Permet de desactive les interactions (Draw) de la carte pour les extensions, - * sauf l'interaction courrante (si elle est renseignée avec l'option 'current'). - * Il est possible d'ajouter des fonctionnalités via les options. - * Par defaut, l'option 'clean' est renseignée... - * - * @param {Object} map - the map - * @param {Object} options - options - */ - unset : function (map, options) { - logger.trace("unset()"); - - var opts = {}; - Utils.mergeParams(opts, this._options); - Utils.mergeParams(opts, options); - - var interactions = map.getInteractions().getArray(); - for (var i = 0; i < interactions.length; i++) { - if (interactions[i].getActive() && - (interactions[i] instanceof DrawInteraction || - interactions[i] instanceof SelectInteraction || - interactions[i] instanceof ModifyInteraction)) { - var prop = interactions[i].getProperties(); - var name = prop.name; - if (typeof name !== "undefined" && this._extensions.indexOf(name) > -1) { - // doit on desactiver l'interaction courrante ? - if (opts.current && opts.current === name) { - continue; - } - interactions[i].setActive(false); - // instance de l'extension - var source = prop.source; - if (typeof source !== "undefined" && source instanceof Control) { - // opérations sur le composant graphique - for (var action in opts) { - if (opts.hasOwnProperty(action)) { - if (action === "current") { - continue; - } - if (typeof source[action] === "function") { - var args = Array.isArray(opts[action]) ? opts[action] : [opts[action]]; - source[action].apply(source, args); - } - } - } - } - } else { - interactions[i].setActive(false); - } - } - } - } -}; - -export default Interactions; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Markers.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Markers.d.ts deleted file mode 100644 index 5c376a5ab..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Markers.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export default Marker; -declare namespace Marker { - let lightOrange: string; - let darkOrange: string; - let red: string; - let turquoiseBlue: string; - let defaultOffset: number[]; -} -//# sourceMappingURL=Markers.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Markers.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Markers.d.ts.map deleted file mode 100644 index 9deed88b1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Markers.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Markers.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Utils/Markers.js"],"names":[],"mappings":""} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Markers.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Markers.js deleted file mode 100644 index c1ccee8aa..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/Markers.js +++ /dev/null @@ -1,9 +0,0 @@ -var Marker = { - lightOrange : "data:image/png;base64,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IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczpHSU1QPSJodHRwOi8vd3d3LmdpbXAub3JnL3htcC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgeG1wTU06RG9jdW1lbnRJRD0iZ2ltcDpkb2NpZDpnaW1wOjkyYWVkNjM2LWY3MDMtNDAzOC1hNzM4LWZiYzYxYzZlMTljNCIKICAgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo5NWMzZWI3NC0zYWRmLTRkYzUtOWZjZS1iODQ4NTc3Nzg4ODQiCiAgIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0NjI3ZDg3NC1lZDIyLTRiZTUtYTlkNS00NDlmMzVhZDIxYzgiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICBHSU1QOkFQST0iMi4wIgogICBHSU1QOlBsYXRmb3JtPSJMaW51eCIKICAgR0lNUDpUaW1lU3RhbXA9IjE2ODQ5NDE5Mjc4OTUzMDYiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zMCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDphM2U3ZWQ1MS0xNTI4LTRhYjAtODVjOS0zNzNkNzgxZGM2ZmMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTGludXgpIgogICAgICBzdEV2dDp3aGVuPSIyMDIzLTA1LTI0VDE3OjI1OjI3KzAyOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PofUkY4AAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfnBRgPGRuA4VZTAAAFcElEQVRYw82YW2xbVRaGv7XP8bHjXByHQkNhWigdVX1AikRBMBoQ8wASl4fRqPDAAxIPKAVxeRqQRohHBEVCaoGKUBCl4qHcNKCZVKMRRQxtgTaACLRKqlwB14NzM2ni2D2XvXjgBFXQOnFiA1uy/HB89u9/7bX+vf4l1HnpK57hTNCE0AzqAS5gAAuEID5KiWSiLPf4tp7YUjcSu4yLZzdi2IJyNXANcBlwAdAKzAHTwDhwDKEPywC+GZWHbPi7IKOvZIWguAnlr8BtwJ+AxDJeDYCPgF6Ed0hkh+Weov5mZLTHJMDeBjwYk0itYJtKTOpZML3SbYNfnYz2SBr0buARYENcFytdFvga2AGyT7p14Vcjoz3ShOgdKDuAi+pUewpMIDyCypvSreWGk9HdroOEV2F4A1hfTxGJCX2D5U7U/UzuD6NaXq49NRJhBsOjwMVLEtE4gaL4W5cV3IsxPEoizDT0ZLTHcSH6M/BWLLlVwpQKuPzhb+i8sRkv04Y/e5rvPigxtnM9trKU2k0D28A5LN3RsmXbrbFOU8DtQLpqfJqu97nh6TydmzvwWpOI8VDbxqbrkmz62yk+/Ps6yoe8KkeV/hHHfgrMNyrNEkBX1SAktgRs3T7ApV1rSWayiEkDLmLSJDNZLu1ay9btAyS2BEsEuWuZ99WKyRhgHeCcn8wGw/qbOnAS3jmfOwmP9Td1kNhQDduJcUwjyciS0RJXMMkWkPPUo/z4XFxZRhZII8mEwFCsT+f5xXTE7FAOteduItVaZodyhNPVZDeKccJGkxmsChIMOvTt6aRSzIP+7A9rRKWYp29PJ8GgsyqcVauZSADaj+IDTecWvBlD4e01HKjM07XtOOuuy+A2X0BYmib/8SxfvLWRYm8LdqZaCvkI/SDBci6nld0ze7KCLa4F3gSurR4MB5x1FnMhiCeor9hJiPKmWpbGp3EU2IbJFuTe5XfStbczLxgP7K0IPcCFDWhnJoFuMAek2/oNbWdku/WxHATejT1JPZcPvINysFYiK+gAFkXTK6H+MyhXADeseJ9fmrVDM6X080/+p1M2/yFsD1zjEIauEeMAqNpQE16oaKiqwfjYeLk+fuYl10HDq7DsBTavxs8o6FzFKez/dM3rLx9LjUyVxcb7yVkfzmpXFbACJURHIxgyxkyu1ml6qL0Z4YX4xl7Jfrrgm9Ov9bX/e++x1tHCgkQ11lgELGA4sBp3iHRbH5GDwJPAFLXo6KJnDmTh/aG2w2/3t47VSGQxs1zAE9U2s9pEjx3hXuBloCa7G1rxv8o3f/7SkUz/UFFWMqGRWMpHAqsDbl00KGotIXM7MawF7gKSS5oJJRospI7v+rD96Ikp8aV2EgrkVPW4OnIy6SVL9ZubvZgyaOVyYDfwl2oNqVWiXNEb231oTe+/BrzvK9Gy01MFyoiOKzIEmqsEfjGf/39U1yHgosJFUXhlFMl+z9E/nkvhVNHZsjux+9Caf77RnyzMBaJLmW4RrWAlB3Y4Uh13HLOA4wQjo6O2IRPNxVV4JuG5Et2SSelzjtFLzsZQ0NIZ8/2rx7K9+/paxqbKvyh4Bc4AFQxzau23Dow7FS+nHmfEUz05OqINH8+evXJPJVOuE93XkY4eSziaXcQpB2b+vZNt7+/8IPPl2OxPRMJ4dDsLzIho3hpzamJ6aqJ0ei6qtZAasmZ2OS1RyOMd6egBIzSFVoKj4y1Hnvhv+8cD02ZOkEmgIKITVnXKWDs1ksvNrgbTbRSZ46cypY50aWcllIsyKXvr8GTyi9f6WvePFGVQhO8EPW2NzI+OfV2pF2bDTgbg8D/aJeVUspd1BK3/G24u7/skO3+iYP3h3LdhI/B+AGodUpo8WKwoAAAAAElFTkSuQmCC", - darkOrange : "data:image/png;base64,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czpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczpHSU1QPSJodHRwOi8vd3d3LmdpbXAub3JnL3htcC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgeG1wTU06RG9jdW1lbnRJRD0iZ2ltcDpkb2NpZDpnaW1wOjIxNDZjMzUzLWIxZjItNGVjOC04NzQ3LTIwMGEyYWExM2ViMyIKICAgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2NGViNmI2Ni03Y2I2LTRkZGUtYTI3OS01MGY0ZWFiZGFhODAiCiAgIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo1ODRhM2VjZC1kNGFmLTQ3NjItYjA1ZS04ODk2MGQ4ZTk0Y2MiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICBHSU1QOkFQST0iMi4wIgogICBHSU1QOlBsYXRmb3JtPSJMaW51eCIKICAgR0lNUDpUaW1lU3RhbXA9IjE2ODQ5NDE5MDM3ODI2MTQiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zMCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoxYzNjOGRkZi1kMjVkLTQ4YzQtYTAwYS0yMmU3ZDYwMzg1YjYiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTGludXgpIgogICAgICBzdEV2dDp3aGVuPSIyMDIzLTA1LTI0VDE3OjI1OjAzKzAyOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PuhCAHgAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfnBRgPGQOTjc4FAAAFdklEQVRYw82YW2gcZRTHf+eb2dlkc9lsrFYr2notfSgWxKKiog8VvIFI9UFQEaWtYPFJfREfRRSEeqlttViLD/WGisYXrShWpfWC1WpSN5eN3cZumkuTzWY3c/mOD9lI0WSTTXbVA8M8zMz3n//5zvl/5xyhxqb3ewYvaERpAvUAFzCABUIQH6GAHyvKa76tJbbUjMRW4+LbC7GsQbgCWA+sAs4AWoA8MAxkgEMo32LoxDO98oIN/xdk9IGUYEYvRrgduAW4Gogt4NMA+BroQHkfm+qW3aP6n5HRTSYG9hZga5lEwyKWKZVJvQCmQ3bZ4F8no5skAXov8BiwspwXizUL9APPgOyVXTr5r5HRzdKI1TsRngHOqlHuKTCI8hhG3padWqw7GX3IddDwcixvAefXUkTKhH7HcBfifi8vh1E1H1cfGkGYxPI4cM68RGw5zf3y3S7IuedgeZwgTNZ1Z3Sz46LRNcA7Zcmd25yGgPWP/M7q65toTLZSHBvn6OcFDm07n6g0n9oNAxsR54DsjBYs2251QWAbgFuBREX/tF3rc9+zA6xa3U5jSxwxHmpbueyqOOvvOM7rj67g1JfedFTNagngVtR+B0zUK8xiwLqKTmhcE3Dblk4uXbecRDKFmATgIiZBIpni0nXLuW1LJ41rgnmcvG6B59WiyRhgBeDM+UZipWHthnbcmDf7b8Y81m5oJ7GyErZTxjH1JCPzesu4ghtvBpkjH2X6uXFlAVEg9SMjhEAamFsyp4Yjcuks1s6uXdZacuksU8OVZDcC0mW8OpFRQqBruvqdwwpdDh+9cjaF0QHQv/2wRhRGB6afdzkVkKZxtDoyVaqZBKCHEXygcXafjhi63l3G9tIEGzYe4ZKrksSbzmCqMEz6mzE+eedC+juaiUYqhZCPchgkqKB4SzxntqQEO7oceBu4srIzHIitsMTOBOMJ1leCkxAMmEpRWt6Vg8BGTConOxZeSVdfzmwxHmpvRtkJnFmHcuYksBkxH8tO69e1nJEd1sdhP/BBuUippfnA+3jsr5ZI9TnzV33mFcB/DuEi4LpFr/PPZu3LkanES08fOltWnxe2Ba5xCEPXiHEAVG2oMS9UNFTVINOXKdamn3nQdSC8HMMeYPVS+hkFzQdObl9m2Zu7+xt6hkKx5fXktGumdNXyZQUKiPZGkDbGnFxqp+kh9kaUHeUTezHr6WRkxt/oa/toT39Lby6QqMoci4BJDB8vpTtEdlkflf3A08AQ1ejoTM8cyeRnudYD72Zb+qokMhNZLuCJaqtZaqDLLi0i7EHYDVTV7oZW/J9PNf3wanfycLoki5nQSFnKewKrnW5NNMhtKRDlt6EsB+4G4vM2/UrUNd5w5Pl028FfiuJL9SQUyKrqEXXkaNyLF2o3N9vUYKB0AbAduKFSQWqVKFv0+rYfXdbx4aB3qqQLDk8VKCKaUSQNmi0F/ujAwB9RTYeAMwoXabg2QvZ5jl4ym8Ip6FjgDm7/bdl7bw3Ec/lItEJyWyAS0RJWsmC7I9WM45hJHCfo6e21dZlozlju3pjnSnRT0tMXHdFzT8dQ0EJoTr2eSXXs7W/uG/pnwiswBZQw5NXaYw5knJKXVY8p8VSP9vZo3cezp1v2nniDK9FD7V70RMxoaganGJmJT0+0frbtt+RPfVN/EQnLo9sxYEREB6wxxweHhwYL4/mo2kSqi43c5zRH8GS7Fz1shMZQJTg41PzVU7+2fdNZNHlBTgI5ER20qkPG2qGebHZsSTpULzJH8slCe6ywrWTlrGTM3tw9Ef/xjUzLvp6idIlwQtBxa2Sit6+/VCvMuu0MwIE726RBSqlViaDli6Gm4t6e1MQveet3Z4+F9cD7Ewo4WRJBbaaSAAAAAElFTkSuQmCC", - red : "data:image/png;base64,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293bv2fa/f0ASM5yljz/NiUAAA0aaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczpHSU1QPSJodHRwOi8vd3d3LmdpbXAub3JnL3htcC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgeG1wTU06RG9jdW1lbnRJRD0iZ2ltcDpkb2NpZDpnaW1wOmI5YjA2YTAwLWZkOTQtNDc5MC1hNzIzLTlkMGUwNGRiNTRlNyIKICAgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1MTQ3ZGU5Yi1kOTA0LTRlNWYtYjIyYy0wZmMzOGRmMWI3ZGEiCiAgIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo4YzBjNTI2YS1lYTkyLTQxYWItODM5Yy05OWFhYTM0YjdlYzciCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICBHSU1QOkFQST0iMi4wIgogICBHSU1QOlBsYXRmb3JtPSJMaW51eCIKICAgR0lNUDpUaW1lU3RhbXA9IjE2ODQ5NDE2NDAxNTU0MjYiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zMCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowMjQ4MDc5ZS1kMTYyLTQxZmItOGViYS1lMzY2NTRiNGRjMjYiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTGludXgpIgogICAgICBzdEV2dDp3aGVuPSIyMDIzLTA1LTI0VDE3OjIwOjQwKzAyOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PkaovgIAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfnBRgPFCiKn0kIAAAFfUlEQVRYw82YTWxc1RXHf+e+N2/GH+Px2IEEV02AgqIsIkwgoYS2ahepVGCBUOiCRRdsAAnECthErBBCICGFj4gqRQqBRSABUrVm1URtCSATJ5ASZCPHH0kGgx1/xJl5nvH7uIcFY4iIM/GzZyhHenqL994993/u+f/fOUeos+nNnkHCJoQWRD0UFzCARYhQCVB8NFWWTwNbT99SNxC3GZfIXg9sADYDWxCuRekEskARYQplFPgEOAr045ph6bXRzwKM3pEX5mduQLkHuAvYCqSW8GkIfAT0IBwknT8lH87o/w2M3mpSqL0LeLQKIrOMZSpVUC8hpkf6bPiTg9FbpBn0L8ATwLoqL5ZrFjgNPAeyV47p3E8GRjdLE6r3oTwHXF0n7ikwgfAEIvvlqJYbDkY3uw4a3YLyNrC2niJSBXQG4c+Ie0yORnGSj5OnRhzlUJ4ErrkikBAoAjPVe7ik4F6D8iRxlGvoyegmx4X4NwgHgM6a8fUyIfc8doZbf99Ca66N0uwF+v7tc3DnWoJK6gqep1C2g3NEjsdLlm03GXSbAe4GmmvGZ91vA3Y8P8aN6ztoyaYxxsPaNrbcnmbbvV/x9ONdnPnA+w71otaMcDfYPqDUmDQTUgjdNYPQsSHkgYf62di9mmwujzHNgIsxzWRzeTZ2r+aBh/rp2BDWDLLQjSzpf7VMMIpB6QKcy77Tuc6wdVsHbspbfJspj63bOuhcV8u3g9KFJtufWQbHakfLdQUv3YrI4qwQ+e65616Jr6mknE4KJgIGgctLZnEq5vRgAWsXLyKttZweLFCcqiW7cdVP1DgwQoQwUNPJxIDDG7vXMDszBvqjDWvM7MwYb+xew8SAUzNowgCSDEwyNVMJQU8AAdC06DvBtOG/76xirlLi3u0nufn2HJmWTir+FJ9+PMu7B66nr6eVYLpWCgUoJ0DCGoq3wv/MbXkhmlkN7Ad+XTMY4kBTl6XlKnA8IQ4U/xyUx8wlB3ZpKvcC23Hz49K79Ep6GeWM8VB7J8pfgasaUM6cAx5EzPvSZ4OGljNy1AYIh4C/L6lASWYBcBCHQ0mBJOfM94rk+WjwAsKvgN8te51LK7kPpm3zK89OrZH1v4zaQ9c4RJFrxDgAqjbSlBcpGqlqODoyWq5TP1OtnoU9wPqV9DMKWlRnfJ+/6q3XKpmhSRVbXU8uuhb6Hq1eVsBHdDiGQWPMuZV1mpuMB/aPCK8CXcsMjs6pufCm3/7PPZXs8LhKnJBjMTCH4f2VdIfIcRsgcgh4FpgkiY4u9Mwqc4fn2468M58dSQhkIbNcwBPVNrPSRJdjWgb2AK8BidrdSCX4PGw5/re53IlBK8uZ0EhVyodCq/1uXTTIzfrExZ0oq4H7gfQSmv54IMqcfNFv7/0ilkCSg1CgoKon1ZEv017ar9/cbEvGEFeuQ9mF8IdaBamFuBB7I7tKq3r+EXjnK0tPTxUoIzqqyCBooRIGM2NjX8d1HQIuKFys0cYY2eeJ3riYwinorHUndvmr3nt7Pj1eVNEa5LZALKIVrBTAnopVRx3HzOE44dDwsG3IRHPBxrtTnkv8p5yjLzvoLy72oaC+mvOvz+V79pZbRyYvJbwC80AFQ1GtPevAqFPxCuoxL57ql8ND2vDx7MVW2JTOuMQPdxDvSInmF/yU1ZT+Nd92eGcp97+RH4BE1XHHLDAtomPWmK8mpiYn/AvFOCmRGmLTm53WOOKpDhM/YqApQsLe+dYPnym1f9xvTVGQc8C4iE5Y1Ulj7eRQoTC7Ih1qFJiTQc7vwN9ZUbk6Z+ydp6L0Z2+Ws/uGrAyI8I2gF6yR0vDI6Uq9fDbsZACO3NQuGa3kr3XC7H+ClvJeP1/6IrbBqbNno0b4+xbMlmARngcRbAAAAABJRU5ErkJggg==", - turquoiseBlue : "data:image/png;base64,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/MUi8H5G35QHBm+BvjV3bu1znD4AWZpV+gY4OARGS5S97vHu3u65/XunPb8fN2tyj8UDOK0AAA0aaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczpHSU1QPSJodHRwOi8vd3d3LmdpbXAub3JnL3htcC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgeG1wTU06RG9jdW1lbnRJRD0iZ2ltcDpkb2NpZDpnaW1wOjEwNGNlNWFhLTE1YzctNGI4Yi1iOGU1LTFmYWQyNWFiYzBhZCIKICAgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpkNDMyZTY1Zi0xOThhLTQxM2EtYWYyMy1jNzhlNzczNGRlN2QiCiAgIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDoyNzExODVkMi03MWZiLTRhZDMtYTJmMi1iNjM3OWU3MDc1OTEiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICBHSU1QOkFQST0iMi4wIgogICBHSU1QOlBsYXRmb3JtPSJMaW51eCIKICAgR0lNUDpUaW1lU3RhbXA9IjE2ODQ5NDE4NjYyMzgzMjQiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zMCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo1NGFiYzNkYS1lZWJiLTRlZjctYjdjNS04ZDRjODY5OGVjODMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTGludXgpIgogICAgICBzdEV2dDp3aGVuPSIyMDIzLTA1LTI0VDE3OjI0OjI2KzAyOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Pj0tlUwAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfnBRgPGBru/VeEAAAABmJLR0QA/wD/AP+gvaeTAAAFO0lEQVRYw9WYe2xTVRzHTx97dYS5B1UHa+/tY12dDoOKWyIGlfgHkCkSNTHGwHxA3NiAP/A5x4CMKEzdYL29YyAyBxKQZbI+NvYIaowaH9Ogi2GRbGjcFrbBNrq2a2/9nq5LCFnbbfSOeZJPTs/t6Tm/7/39zu+cU0IiXc7WSImNX0BsZiVYAhigmah5tHklsZrjSYtJSuZtaeSiiJU3gHUwfC9oARfBIHBP1DzaPH1eRuzmp0E6aTgSNX9EWMwSvOkMGPgG+CpguG8a0H7nA78zkMYqye0V0lYXDSHrYUw7cE5TxM04/b+38+vJ+RPRt0eIjVeAAhhyCQizFDKJEBjndaCY49Di4+CRlzFxfwSE3Ciol9i4DSBujoRUy7HIszFxdwSF3CioBy8qm1g5ufhirHwyJqwHrrDGWTlg8hFL1URN2+EF0XFPkyYuSWwhUVgnT2CygXBG3dFcM7bz1/au1u7OK9/93eWidUlHe1dCc810EsUAsXOPQZCI3rGZ6Wb4EXAEM0SCUFnZduz6T/09l4bHXYOCz+f0+XxeWg+7XYM/4vnKtlqHJHSIOrAHlYMFYmawRNCKycaDGZLVfMRdf/nPDpfXM+abotDnpy93dtzXfNgdZg+im2uimJ6h66UTeIMZsrat1jvkdPRRb/imLt4hl6N3DfqFEIPvOMzDJYspJsWfbUKEyFNttcKoyzkKo4UgYoRRt3OE9guT1br984nsmQ7gCWbIipaj4xeu9v/hFQTPlG7B89+u9v9O+4UQQ8f/BSlaVM8kgBOhji4p9mpvwQ+Wfwddjp6bQw2u8g44HT3535/tTUa/0Eccvg4sFDE1m2PBZkx2LVRqVcLQvG/PDDX1/tVxze38x+UZH6O1He28b764qgwtxOcf327eBGLFE9NikiD3qzDZhVBJgCJH3KubDnkfbD4s5Jw74qM1bcvDnxq8/vHt1SrS9InIJ2m7OQ4UYsKhCB9lJqHj0gPsHJzPvsS9w8rRRPDptI40M8PlH9fOJ5M5K008rsZmIwi5gc4QN9Zja8zn+5epch9PTFepU1iGuVunVqeyS9g0iv8zy96l0WiSjIsXx28iJEJhaONkMGB5YP14bkmI1SzIz1T0pRa9VKnNzCjUMcwWUAS2BtgWYLJN+xTo1OyrOhW7xsAwqnSGkd3i+uGjkT5Xw6DLt3AdEKQNB4YXbdtwQpuVuRtG7pwhxWA7vJgRib0nDuSDvtkIkjYcHE3aVWjRLL9/zyyETPK2Vq3OidAaOhiPDLcbxo3MRIik0eReWPnO15pHHiqbpYhS6hkNw7wAz0To6GM5hAzH3wkDa6b7x4bEwnkUfMnP6idX7Nex7GxElIDNerV6hU6jSdbp9RHck2w0w/FaGGoJm7KtnCfmWNlF1fOrK3Q6bekMRFABO7QM8yxewFLUi+5JSxPpAmcxy0gjt1Rytir4NcHKCfJTH/al5j1j1hr0pWEML55YD+x2GP6cVqNZZjQYEvUsG4vP4v8jKju5L1p6qnytxGKa6qogyOorBpVbXvxMe69xdxABb9I0DAGvIIRWp7NsBsJIoWVZKfaXuf+jMKp2b6z8+Adb4aErNwpCCh5J2pnfoH0ga08g7invBfaQjXjjuQifhyEgLdNolJP5UqR17y+QnSwvk1i565OZK6F8RzubvWwvDH8LvKZnmHXY8HKws+sNLJtI5muJ/7hYElOzJ1V+fN9R7CVDClPJOVXuqo06vS4HQjTwgDKDZRXk/1JiD7wrieFLk6T1lczCXUVK7aPZinS9XrTw+Q+Tql7SUmvGuQAAAABJRU5ErkJggg==", - defaultOffset : [-25.5, -32] -}; - -export default Marker; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/MarkersOther.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/MarkersOther.d.ts deleted file mode 100644 index 9a42e9f60..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/MarkersOther.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -export default MarkersOther; -declare namespace MarkersOther { - let drawing_portail: { - src: string; - anchor: number[]; - }[]; - let drawing_api: { - src: string; - anchor: number[]; - }[]; -} -//# sourceMappingURL=MarkersOther.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/MarkersOther.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/MarkersOther.d.ts.map deleted file mode 100644 index 4f86e8ab3..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/MarkersOther.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MarkersOther.d.ts","sourceRoot":"","sources":["../../../../../src/packages/Controls/Utils/MarkersOther.js"],"names":[],"mappings":""} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/MarkersOther.js b/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/MarkersOther.js deleted file mode 100644 index ad00e25c7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Controls/Utils/MarkersOther.js +++ /dev/null @@ -1,214 +0,0 @@ -var MarkersOther = { - /** - * portail icons used by drawing control with a good ratio ! - * - * @example - * image size : [32, 41] - * scale : 32 / Math.min(size[0], size[1]) = 1 - */ - drawing_portail : [ - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAClFBMVEUAAAD//////////////////////////////////////////////////////////fv/+fL//////////////////////////////////////////////////////////////////////////////////////v7//////fr/////+vL//////////////////Pj//////////////////////////////////////////////////////////////////////////v7//////////////////////////////////////v7//////////////////////////////////////////////////////////////////////////////v7/////////////9+v/9ej/9+z/7tT/3q3/y3//v2D/uU//+O7/5L3/xW//piH/mQH/mAD//v7/79f/yXj/oxr/lwD/mQD//fv/58T/tkr/mQL//v3/58P/sTz/79b/tUf/x3X/mQP/5Lv/oRX/ng3/s0H/w2n/u1b/4rf/8Nr/9eb/7tX/pBv/x3P/8d7/3av/79j///7/zH//mgX/2qP//vz/9+3/wGH/qyz/6Mb/vFj/sj//7NH/wGL/rTP/6sr/+fH/yXf/oBP/37H/2aH/6sz/nw//oBT/0pD/+vT/9OX/uE7/pB3/y33/7ND//Pj/26b/mwj/nAn/sT7/w2r/zYL/8+P/ulT/mwb/5Lz/qCj/+/b/1JT/nQz/nQ3/9uj/w2j/mAH/9un/6sv/skH/lwH/3Kf/pB7/pR7/3Kj/nAj/y37/+/f/8t//mQT/rDD/rDH/1JX/7tb/4LT/pR//z4j/z4n/vFn/7dP/4rn//fq31ydlAAAAY3RSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD++P3qw/2N+0j2GMcHYx68BOkMd/x2IKf+pjrS0WDvXxSL+Cy3TEsIdRyhoDXINOSK8rY72mnrhe2jCycJAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+cFGQAhKnVAysoAAAMmSURBVDjLY2AAA0ZGJmYWVjZ2juRkDnY2VhZmJkZGBiTAyMnFzcPLxy+QkpqaIsDPx8vDzcWJpIJRUEhYRDQtPSMzKzs7KzMjPU1URFhIEK6CUUxcIjknNy+/oBAMCvLzcnOSJcTFGGHyklJFxSWlZYWF5WBQWFhWWlJcJCUJUcEoLSNbUVlVDZWFqqmuqqyQlZEGqZCTV6iprStDkQeqKKurrVGQlwMawMWTXN+ALg9S0VCfzMPFyCAorpjW2ASzvQwIYOymxjRFcUEGLqWa5pZCqONa27Ky2lqhji1saa5R4mJQVklpL4M6rKOzq7u7q7MD6uCy9hQVZQZVtZ5eML+woK+/KBkIivr7CiAivT1qqgzqGhPA3MKy7ImTksFg0sRssEMKCyZoqDNoak2GKJ8ydVoyFEybOgUiNllLk0F7+gwwp2zmrGQ4mDUT7KzCGdO1GZJTZkMUzJmLUDB3DkTB7JRkBp3p8yAK5i9AKFgwH6Jg3nQdBt2FiyD2LV5SBJMvWrIYIrZooS6Dnv5SCKesPQ2mIK0dEpyFS/X1GAwMly2H8FasXAWRX7VyBURk+TJDAwYj49VroAG3dt16oC1F69ethQbtmtXGRgwmphs2boKq2Lxl67ZtW7dshspv2rjB1ITBzFxn+44yeGTu3AmPzrId23XMzRg4LSwrdu2GJQdQkoQxd++qsLTgZGC0MrLes3cfZoLZv3ePtZEVMM0x2tjqHDh4CD3JHdp62M7eBpxqOR0cnY4cPYaaaI8dPeLk7MAJSfZyLq4Vx08UIqkoLDx5qsLNRQ6WMQTdPfasO42sYPOZsx6eiKzF6eXtc27HebiKwvM7zvl4e3EiZU5fv+TcC4icdTFX1M8XNXv7yyZfaoEpaLmULBuAIs/AEGivsrAd4ozCze0LVYICUeUZGIND+C63gTJQYVNbMV9oMJoBQBVh4clXroKC+uqV5PAIDHmgCsnIimv7Cgv3Xa+IlMQiDwzyqOiUG1Om3EiJjrLBpgDojBi7mxcu3LSLCcYqD1QRGzft1q1pcbE45IExH59w+3ZCvBUuBUBnJCYlJaI6AABB269xUXFElwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMy0wNS0yNVQwMDoyOTozNyswMDowMEpaoL8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjMtMDUtMjRUMjI6NDM6MjIrMDA6MDB1WI3HAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAABJRU5ErkJggg==", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACplBMVEUAAAD//////////////////////////////////////////////////////////fz/9/P//////////////////////////////////////////////////////////////////////////////////////v7//////Pr/////////////////////+/n//////////////////////////////////////////////////////////////////////////v7//////////////////////////////////////v7//////////////////////////////////////////////////////////////////////////////v7/////////////8+3/8er/9O7/5dj/zrX/s4z/oHH/lmL/9fD/2MT/qX7/ejj/Zxz/Zhn/Zhr//v7/59z/rof/djL/ZBf/Zxv//fz/3Mr/k13/aBz/ZRn//f3/i1D/5tr/kVr/ZRj/rIP//v3/1sL/cy3/byf/jVX/pnn/aB3/mmf/077/6d7/8On/5tn/dzT/q4H/6+H/zbP/lmH/s43/ah//yK3/9O//oXL/gUP/3cz/m2n/jVT/5Nb/onP/hkn/4ND/9vL/rob/cSv/0Ln/x6r/Zxr/Yxb/pXn/8+7/4NH/cCj/ciz/vZz/+PX/7+f/lWH/eDT/sov/49X/+/n/ya//ayH/bCP/jFL/pnr/tJD/7ub/mWb/ZBb/aiD/18P/fj3/+vf/vp//bSX/bib/v5//pXj/8uv/yrD/eDX/eTb/y7H/bCL/soz/7OL/18T/g0b/hEb/v6D/cy7/wKH/9vP/5tv/jlX/59v/0rz/ejf/uJX/nGr/aR//nGv/g0X/1cD//PvyoJNrAAAAYnRSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD4/erD/Y37SPYYxwdjHrwE6Qx3/HYgp/6mOtLRYO9fFIv4LLdMSwh1HKGgNcg05IrytjvaaeuF7djGYAwAAAABYktHRAH/Ai3eAAAAB3RJTUUH5wUZACErAkf6XAAAA0JJREFUOMtjYAADRkYmZhZWNnaOpCQOdjZWFmYmRkYGJMDIycXNw8vHL5CckpIswM/Hy8PNxYmkglFQSFhENDUtPSMzKyszIz0tVVREWEgQroJRTFwiKTsnNy+/oBAICvLzcnOykyTExRhh8pJSRcUlpWWFheVgUFhYVlpSXCQlCVHBKC0jW1FZVV1TjgRqqqsqK2RlpEEq5OQVaivrygrLUUBhWV1lrYK8HNAALp6k+oZGNHmgisaG+iQeLkYGQXHF1KZ8mO2NZWUwtYX5TamK4oIMXErNLa0FEKGatvbMzPa2GoiSgtaWZiUuBmWV5I5GiHxnV3dPb29Pd1cnREVjR7KKMoOqWl9/IcTICROLkoCgaOIEiJWF/X1qqgzqGpPA3MKyycVgeaCK4slgTxXmT9JQZ9AUmAJRPnVaRRIUVEybChGbIqDJoDV9BpjTOHNWEhzMmgl2VuGM6VoMScmzwQrK5sxFKJg7pwysYHZyEoP29HkQE+YvQChYMB9iwrzp2gw6CxeBFRQsXlIEky9ashgcMoWLFuow6OotBXOWLV+xEqZg5Yrly8CalurpMugbrFoNMWLN2nUQ+XVr10AMWL3KQJ/B0Gj9BkhINm7ctBkkv3nTRqjAhvVGhgzGJlu2boMG7fYdO3ft2rljOzTot23dYmLMYGqmvXvPXmgE7i3bt69sLzQ69+7ZrW1mysBpblGx/0AjLLGBAITdeGB/hYU5JwOjpaHVwUOHMRPMkaMHrQwtgWmO0dpGO+VYAXqSK+g4bmtnDU61nPYOjgvaURNdYWP7Kkcne05Ispdzdqk4cbIGSUVhzanTFa7OcrCMIejmfnDTmQKEgoIzZw+6eyCyFqenl/e5PeVwIwrL95zz9vLkRMqcPr5J5y/AHFpYcPG8qK8Pavb2k026dBkaGo2XryTJ+qPIMzAE2KlcXbEN7IyCbR1XVQIDUOUZGIOC+a61VwMtKay+foMvJAjNAKCK0LCkm7dAIX3rZlJYOIY8UIVkRMXtI4WFR25XREhikQcGeWRU8p27d+8lR0VaY1MAdEa0bdr9+2m20UFY5YEqYmJrHzyojY3BIQ+M+bj4hw/j4yxxKQA6IyExMQHVAQBpWLIaKI0lIgAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMy0wNS0yNVQwMDoyOTozNyswMDowMEpaoL8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjMtMDUtMjRUMjI6NDQ6MDYrMDA6MDAh7rXQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAABJRU5ErkJggg==", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACbVBMVEUAAAD/////////////////////////////////////////////////////////+/v/8vL//////////////////////////////////////////////////////////////////////////////////////v7/////+vr/////////////////////+Pj//////////////////////////////////////////////////////////////////////////v7//////////////////////////////////////v7//////////////////////////////////////////////////////////////////////////////v7/////////////6+v/6Oj/7Oz/1NT/ra3/f3//YGD/T0//7u7/vb3/b2//ISH/AQH/AAD//v7/19f/eHj/Ghr/+/v/xMT/Skr/AgL//f3/w8P/PDz/1tb/R0f/dXX/AwP/u7v/FRX/DQ3/QUH/aWn/Vlb/t7f/2tr/5ub/1dX/Gxv/c3P/3t7/q6v/2Nj/BQX/o6P//Pz/7e3/YWH/LCz/xsb/WFj/Pz//0dH/YmL/MzP/ysr/8fH/d3f/ExP/sbH/oaH/zMz/Dw//FBT/kJD/9PT/5eX/Tk7/HR3/fX3/0ND/+Pj/pqb/CAj/CQn/Pj7/amr/goL/4+P/VFT/Bgb/vLz/KCj/9vb/lJT/DAz/aGj/6en/y8v/p6f/Hh7/qKj/fn7/9/f/39//BAT/MDD/MTH/lZX/tLT/Hx//iIj/iYn/WVn/09P/ubn/+vpgzcAPAAAAYnRSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD4/erD/Y37SPYYxwdjHrwE6Qx3/HYgp/6mOtLRYO9fFIv4LLdMSwh1HKGgNcg05IrytjvaaeuF7djGYAwAAAABYktHRAH/Ai3eAAAAB3RJTUUH5wUZACErAkf6XAAAAu1JREFUOMtjYAADRkYmZhZWNnaOpCQOdjZWFmYmRkYGJMDIycXNw8vHL5CckpIswM/Hy8PNxYmkglFQSFhENDUtPSMzKyszIz0tVVREWEgQroJRTFwiKTsnNy+/AAzy83JzspMkxMUYYfKSUoVFxSUFSKCkuKhQShKiglFaRra0rLyiAAVUlJeVyspIg1TIyStUVlUXYIDqqkoFeTmgAVw8STW1BVhAbU0SDxcjg6C4YmpdPTYF9XWpiuKCDFxKlQ2NMLGm5szM5iYYr7GhUomLQVkluQXmsNa29o6O9rZWmINbklWUGVTVOrug3u/uKUwCgsKebmiAdHWqqTKoa/RCuVl9YHmgir4sqJZeDXUGTYEMCK9/wsQkKJg4oR8iliGgyaA1aTKEM2VqEhxMnQIRmzxJiyEpeRqEM30GQsGM6RCxaclJDNqTZkI4s2YjFMyeBRGbOUmbQWfOXAhn3vxCmHzh/HkQsblzdBh09RbAfJ0KU5AKC5kFeroM+gYLF0F4i5cshcgvXbIYIrJooYE+g6HRsuVQ9StWrgLaUrhq5QqowPJlRoYMxiar16yFCqxbv2Hjxg3r10G5a9esNjFmMDXT3rQZEYVbtiDYmzdpm5kycJpblG7dhi26t20ttTDnZGC0NLTavmMnpnzTju1WhpbANMdobaOdsisfXT5/w25bO2twquW0d3Dc04ymIr95j6OTPSck2cs5u5Tu3YeqYN/+UldnOVjGEHRz375yLbL8ugMH3T0QWYvT08v70ObDCPnDmw95e3lyImVOH9+knCMIBUdzRH19ULO3n2zSMXjibjyWJOuPIs/AEGCnMqcF6ox1LXNUAgNQ5RkYg4L5aprBGai+uYgvJAjNAKCK0LCk4ydACk4cTwoLx5AHqpCMKD0JDPKdp0ojJLHIA4M8Mir5dH//6eSoSGtsCoDOiLY9c+TIGdvoIKzyQBUxsRPPnp0YG4NDHhjzcfHnzsXHWeJSAHRGQmJiAqoDAOgCnVLAYqeOAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIzLTA1LTI1VDAwOjI5OjM3KzAwOjAwSlqgvwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMy0wNS0yNFQyMjo0NDoxOSswMDowMBsMxacAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAAElFTkSuQmCC", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACf1BMVEUAAAD//////////////////////////////////////////////////////////P3/9Pn//////////////////////////////////////////////////////////////////////////////////////v7/////+/3/////9fr/////////////////+vz//////////////////////////////////////////////////////////////////////////v7//////////////////////////////////////v7//////////////////////////////////////////////////////////////////////////////v7/////////////7/f/7PX/8Pf/3O7/vd7/mcv/gL//c7n/8fj/yuT/jMX/Tab/NJn/MZj/Mpj//v7/3+//k8n/R6P/L5f/M5n//P3/0Of/brb//f7/z+f/Y7H/MJf/bLX/kcf/yeT/Q6H/PZ7/ZrP/h8P/d7v/xeL/4fD/6/X/3e7/SaT/j8f/5PH/u93/crn//v//mMz/N5r/tdr/gcD/Vqv/0ej/ebz/ZrL/2uz/gsD/XK3/1er/8/n/ksn/QaD/wN//tNn/1ur/P5//QqD/ptL/9vr/6vT/cbj/l8v/+vz/t9v/OJv/Opz/ZLH/iMP/m83/6fP/d7r/N5v/Uqj/Mpn/+Pv/qdT/PJ3/7fb/Z7L/uNz/SqT/S6X/udz/OZz/mMv/5fL/drr/Waz/Wqz/qtT/RKH/q9T/9Pn/3u7/Z7P/w+D/TKX/oM//PZ3/erz/Npr/3O3/x+L/+/0F2pMDAAAAY3RSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD++P3qw/2N+0j2GMcHYx68BOkMd/x2IKf+pjrS0WDvXxSL+Cy3TEsIdRyhoDXINOSK8rY72mnrhe2jCycJAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+cFGQAhKwJH+lwAAAM4SURBVDjLdZNnWxNBFIVnEZGEGpBeROkSuoIUwS4KFkTFQp+wFEWzk+AmEFhEDBZQlA5ioxcRsCDYELADSvlBbnY2kACeTztz3r1znztnAOBEEAYbDDcabTKG0HiT0UbDDQYEAXRECIQmpmbmFpaS7GyJpYW5mamJUKBDECIr6802ZE5uXv6lS/l5uTmkzWZrK9EyQdja2cPLBVeuSinEipJevVJwGdrb2RJa38FRJi+8RiOk4IQQfa1QLnN0wATh5OyiLCqWUgodUdLiIqWLs5OGcN3ipiopZZBCT4gpLVG5bXFlCwhNobxsta8hyuTQVEgAkd1W8rpUezrDSvstvU5utRMB4TZV+Q18PqIqbubn36ygMELdKFdtEwJ3D4ma4X+pvHX7zp3btyr5goxa4uEOPL3uViHsV9+TQVaye9WYQFV3vTyBt899bomYGvkDyOmBvIZrBEnv+3gD3+0PMV5bp4K8VHW1eO/hdl/gR9ZzC6ahES6rsYFrC9WTfgBKmjiAbm5ZAVqaaQ5okkAgJltxhUdtK0DbI1yhlRQD/8dPOIB6+kym9WXPnnKTQU8e+4OAwOe4IVpNagFSTeO954EBICi4vQOvOru6sd/d1Yl3OtqDg0BIaE8vnjRT1dfCniJr6avCo6V6e0JDwI6d/QMv+NEOvhwaHh56OciP/sVA/84dICxcPPKK5i+Qpl+/pmn+OulXI+LwMCDYFaEsf8PH6a0mk2/5UL0pV0bsEgAiMiRq9N3Y2sCMvRuNColkM0dE7xaPq6nVkaPU4zGx0VxqBXv27mtr1g8dYt637du/R4Bj73rgoPLDR90aiPr0WXnogKv2YYgOx432Tejknhr8Mhp3ZOVpCY7GJ0xOKZZLIMXUZEL8UYHO4zx2HBZMaw9B1NcCm+PH9J/3CRf47Tt/CPX9B3Q5qecDkBjr8VON26Amhn56nErU9wGRdNr8129NfJH0t9z8TNKqAixxNhnOzGpGPTsDk8+t8VnC4bxybgyhP3PK8w7r+OzIL1yU/J2f/yu5eCF6PYBtIyVmYXp6ISYlaV2fJVLTVIuLqrTU//jszadnLC1lpEf+D2DbyMzKytRv4B+n7ayGbXJj1gAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMy0wNS0yNVQwMDoyOTozNyswMDowMEpaoL8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjMtMDUtMjRUMjI6NDQ6MjkrMDA6MDCVg8JEAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAABJRU5ErkJggg==", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACslBMVEUAAAD////////////////////////////////////////////////////////+/fz79/T////////////////////////////////////////////////////////////////////////////////////+/v7////9/Pv////79/X////////////////9+/r////////////////////////////////////////////////////////////////////////+/v7////////////////////////////////////+/v7////////////////////////////////////////////////////////////////////////////+/v7////////////58+/48ez69PDz5dzpzr3cspnUoIDQlXP69PHt18rYqIzDeU27ZjS6ZTG6ZTL+/v7059/brpPCdUe6Yy+7ZjP+/fzv29DOkm67ZzS6ZDH+/f3v28/LiWO6YzD05t/OkGy6ZDDarJH+/v3t1snAckO+bj3MjWbUn4DXpYfRmXfr08X16eH48Ovz5t3CdknZqo/26+TozLvQlXL//v7dspi8aTfmyLXUoIHGgFbv3NHSm3m5Yy/LjGby49rVoYLIhVzx39X79vPbrZK/cEHq0MDmxrS6ZjK5Yi/58/Dx4Na+bz/AcULhvab8+Pb47+rPlHHCd0ncsZf9+/rnybe9aji9azrLi2TXpojdtJv37unt18nFfVK7ZTL8+vjivqm+bTziv6n58e3WpIfWpYfx4NXMjWfnyrjCd0rDeEvoyrm9azncsZj27OXRmHbHg1nIg1rt2Mriv6rAckTjwKv79vS8ajm9ajnXpYj05t7r0sPDeUzfuKC+bT3Sm3q8aTbIglns1cf9/Pua7OXrAAAAY3RSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD++P3qw/2N+0j2GMcHYx68BOkMd/x2IKf+pjrS0WDvXxSL+Cy3TEsIdRyhoDXINOSK8rY72mnrhe2jCycJAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+cFGQAhKwJH+lwAAANISURBVDjLY2AAA0ZGJmYWVjZ2juRkDnY2VhZmJkZGBiTAyMnFzcPLxy+QkpqaIsDPx8vDzcWJpIJRUEhYRDQtPSMzKzs7KzMjPU1URFhIEK6CUUxcIjknNy+/oLAICAoL8vNyc5IlxMUYYfKSUsUlpWXlRUUVYFBUVF5WWlIsJQlRwSgtI1tZVV1TW4EEamuqqyplZaRBKuTkFerqGxqLKlBAUWNDfZ2CvBzQAC6e5KbmFjR5oIqW5qZkHi5GBkFxxbTWApjtLY2NMLVFBa1piuKCDFxKbe0dhRCh2s6u7u6uzlqIksKO9jYlLgZllZSeFoh8TW9f/4QJ/X29NRAVLT0pKsoMqmoTJxVBjJw8pTgZCIqnTIZYWTRpopoqg7rGVDC3qHFayfRkMJheMg3sqaKCqRrqDJpaMyDKZ86qS4aCulkzIWIztDQZtNNmgzktc+Ymw8HcOWBnFc1O02ZITpkHVjB/wUKEgoUL5oMVzEtJZtBJWwQxYfEShIIliyEmLErTYdBdugysoHD5imKYfPGK5eCQKVq2VJdBT38lWMGq1T1rYArW9KxeBVawUl+PwcBw7TqIk9dv2AiR37hhPURk3VpDAwYj402bITHdsmXrQqAtxQu3boEEbe3mTcZGDCam27bvgAbtzl279+zZvWsnNOh3bN9masJgZq6zt3c+NALnz585c/58aHTO792rY27GwGlhWblvPzQ5HQClyQPQRLV/X6WlBScDo5WR9cFDhzETzOEjB62NrIBpjtHGVufosUL0JFd4/KidvQ041XI6ODqd6EJNdEUtJ084OTtwQpK9nItr5anTtUgqimrPnK10c5GDZQxBd4+DW88VIhQU7jx/0MMTkbU4vbx9LlysgBtRVHHxgo+3FydS5vT1S869BHNoUeHlK6J+vqjZ2182+eo1aGjUXrueLBuAIs/AEGivcqPnJtgZhbdu31AJCkSVZ2AMDuG7cxKU3otqTpbwhQajGQBUERaefPceKKjv3U0Oj8CQB6qQjKy8f7io6MH9ykhJLPLAII+KTnn46NHDlOgoG2wKgM6IsUt//DjdLiYYqzxQRWxc3ZMndXGxOOSBMR+f8PRpQrwVLgVAZyQmJSWiOgAArqa4BP2YBKMAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDUtMjVUMDA6Mjk6MzcrMDA6MDBKWqC/AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA1LTI0VDIyOjQ0OjQ2KzAwOjAwpaS7KgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAASUVORK5CYII=", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAChVBMVEUAAAD//////////////////////////////////////////////////////////vv//fL//////////////////////////////////////////////////////////////////////////////////////v7//////vr//////////////////////vj//////v///////////////////////////////////////////////////////////////////v7//////////////////////////////////////v7//////////////////////////////////////////////////////////////////////////////v7//////////////Ov/++j//Oz/+dT/863/7X//6mD/50///O7/9r3/62//4SH/3QH/3AD//v7/+df/7Xj/4Br/3QD//vv/98T/5kr/3QL//v3/98P/5Tz/+db/5kf/7HX/3QP/9rv/4BX/3g3/5UH/6WD/62n/6Fb/9bf/+tr/++b/+dX/4Bv/7HP/+t7///7/86v/+dj/3QX/8qP//vz//O3/6mH/4iz/98b/6Fj/5T//+dH/6mL/4zP/+Mr//fH/7Hf/3xP/9LH/8qH/6mn/+Mz/3g//3xT/8JD//fT/++X/507/4B3/7X3/+ND//vj/86b/3Qj/3gn/5T7/62r/7oL/++P/6FT/3Qb/9rz/4ij//fb/8ZT/3gz//Oj/62j/3AH//On/+Mv/86f/4R7/86j/7n7//vf/+t//3QT/4zD/4zH/8JX/3xX/3gj/9bT/4R//74j/74n/6Fn/+dP/9bn//vrsMn7uAAAAYnRSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD4/erD/Y37SPYYxwdjHrwE6Qx3/HYgp/6mOtLRYO9fFIv4LLdMSwh1HKGgNcg05IrytjvaaeuF7djGYAwAAAABYktHRAH/Ai3eAAAAB3RJTUUH5wUZACErAkf6XAAAAxZJREFUOMtjYAADRkYmZhZWNnaOpCQOdjZWFmYmRkYGJMDIycXNw8vHL5CckpIswM/Hy8PNxYmkglFQSFhENDUtPSMzKyszIz0tVVREWEgQroJRTFwiKTsnNy+/AAzy83JzspMkxMUYYfKSUoVFxSVAqVIwADJKiosKpSQhKhilZWTLyisqobJQNZUV5WWyMtIgFXLyClXVNQUo8iBTaqqrFOTlgAZw8STV1qHLg1TU1SbxcDEyCIorptY3IGxHuKShPlVRXJCBS6mqsakAKt3c0tra0gxVUtDUWKXExaCsktwGFahs7+js6ursaIc6uKAtWUWZQVWtuwfML8jv7etPAoL+vt58iEhPt5oqg7rGBDC3oCBrYmESGBROzALbUpA/QUOdQVMgA6J80uQpSVAwZfIkiFiGgCaD1tRpEM70GUlwMGM6RGzaVC2GpOSZEM6s2QgFs2dBxGYmJzFoT50D4cydh1Awby5EbM5UbQad+QsgnIWLCmHyhYsWQsQWzNdh0NVbDPX1klSYgtQlUKHFeroM+gZLl0GUL1+xEiK/csVyiMiypQb6DIZGq1ZD1a9Zuw5oS+G6tWugAqtXGRkyGJus37ARKrBp85atW7ds3gTlbtyw3sSYwdRMe9t2RGTu2IGIzu3btM1MGTjNLcp27oIlB0Rslxbs2llmYc7JwGhpaLV7z17MBNO8Z7eVoSUwzTFa22jv238APckd2HLQ1s4anGo57R0cD7Wgqig40HLI0cmeE5Ls5Zxdyg4fQVZQUHDkaJmrsxwsYwi6ue9euxFJRcGmY8fdPRBZi9PTy/vE9pNwFQUnt5/w9vLkRMqcPr5JOacQOet0jqivD2r29pNNOnMWpuDsmSRZfxR5BoYAO5X5becgcbSpbb5KYACqPANjUDBfbQsoAxU0tBTxhQShGQBUERqWdP4CKKgvnE8KC8eQB6qQjCi7uLegYO+lsghJLPLAII+MSr48adLl5KhIa2wKgM6Itr1y6tQV2+ggrPJAFTGxU65enRIbg0MeGPNx8deuxcdZ4lIAdEZCYmICqgMA6f6os3UKuXAAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDUtMjVUMDA6Mjk6MzcrMDA6MDBKWqC/AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA1LTI0VDIyOjQ0OjU4KzAwOjAwOTHA6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAASUVORK5CYII=", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACr1BMVEUAAAD////////////////////////////////////////////////////////7/v3y+/n////////////////////////////////////////////////////////////////////////////////////+/v7////6/f3////y+/r////////////////4/fz//////v/////////////////////////////////////////////////////////////////+/v7////////////////////////////////////+/v7////////////////////////////////////////////////////////////////////////////+/v7////////////r+ffo+PXs+ffU8+2t591/28tg0r5Pzbju+vi97ORv1sQhwKUBt5gAtpf+/v7X9O942ckavqIAtZYAt5j7/v3E7udKy7UCt5j9/v7D7uY8x7DW8+5Hy7QAtpZ118cDt5i77OQVvKANup1BybJg0b5p1cJWz7q36uLa9PDm9/XV8u4bvqNz18be9fGr59zY8+9/2ssFuJmj5dr8/v7t+fdh0r8sw6rG7+hYz7s/ybHR8uxi0r8zxazK8Onx+/l32MgTvJ+x6N+h5Nlp1MLM8OoPu54UvJ+Q39L0/Prl9/ROzbcdv6N92srQ8ez4/fym5tsIuJoJuZs+yLBq1cOC28zj9/NUz7oGuJq87OMowaf2/PuU4NQMupwNupyU4dTo+PZo1MIBtpdq1cLp+fbL8OoBtpan5tsev6Mev6So5twIuZt+2sv3/Pvf9fJUzroEt5gwxKsxxKuV4NQVvaCV4dTW8+/X8++06eEfv6T7/f2I3c6J3c9Zz7wFuJrT8u256+L6/f3ow7cxAAAAY3RSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD++P3qw/2N+0j2GMcHYx68BOkMd/x2IKf+pjrS0WDvXxSL+Cy3TEsIdRyhoDXINOSK8rY72mnrhe2jCycJAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+cFGQAhKwJH+lwAAAMvSURBVDjLY2AAA0ZGJmYWVjZ2juRkDnY2VhZmJkZGBiTAyMnFzcPLxy+QkpqaIsDPx8vDzcWJpIJRUEhYRDQtPSMzKzs7KzMjPU1URFhIEK6CUUxcIjknNy+/oBAMCvLzcnOSJcTFGGHyklJFxSWlZYWF5WBQWFhWWlJcJCUJUcEoLSNbUVlVDZWFqqmuqqyQlZEGqZCTV6iprStDkQeqKKurrVGQlwMawMWTXN/QiCYPVNHYUJ/Mw8XIICiumNbUDLO9sawMprawuSlNUVyQgUuppqW1EOq4tvaOjvY2qGMLW1tqlLgYlFVSOhuhDuvq7unt7enugjq4sTNFRZlBVa2vH8wvLJgwsSgZCIomTiiAiPT3qakyqGtMAnMLG7Mng+WBKiZngx1SWDBJQ51BU2sKRPnUadOToWD6tKkQsSlamgzaM2aCOY2zZifDwexZYGcVzpyhzZCcMgesoGzuPISCeXPLwArmpCQz6MyYDzFhwUKEgoULICbMn6HDoLtoMcS+JUuLYPJFS5dAxBYv0mXQ018G4ZQtT4MpSFsOiZrCZfp6DAaGK1ZCeKtWr4HIr1m9CiKycoWhAYOR8dp10IBbv2Ej0JaijRvWQ4N23VpjIwYT002bt0BVbN22fceO7du2QuW3bN5kasJgZq6zc1cZLBGU7d5dBksaZbt26pibMXBaWFbs2QtLDqAkCWPu3VNhacHJwGhlZL1v/wHMBHPw0D5rIytgmmO0sdU5fOQoepI7euy4nb0NONVyOjg6nWg/iZpoT7afcHJ24IQkezkX14pTpwuRVBQWnjlb4eYiB8sYgu4e+zacQ1aw9fwFD09E1uL08va5eOkyXEXh5UsXfby9OJEyp69fcu4VRM66mivq54uavf1lk6+1whRcv5EsG4Aiz8AQaK+yaDnEGYVbly9SCQpElWdgDA7hu9kOykCFze23+EKD0QwAqggLT759BxTUd24nh0dgyANVSEbevXegsPDA/buRkljkgUEeFZ3y4OHDBynRUTbYFACdEWP36MqVR3YxwVjlgSpi46Y/fjw9LhaHPDDm4xOePEmIt8KlAOiMxKSkRFQHAAAsgrQ2sknLAAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMy0wNS0yNVQwMDoyOTozNyswMDowMEpaoL8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjMtMDUtMjRUMjI6NDU6MTIrMDA6MDD2yfpjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAABJRU5ErkJggg==", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACfFBMVEUAAAD////////////////////////////////////////////////////////8/vz0/fT////////////////////////////////////////////////////////////////////////////////////+/v7////7/vv////1/fX////////////////6/vr//////v/////////////////////////////////////////////////////////////////+/v7////////////////////////////////////+/v7////////////////////////////////////////////////////////////////////////////+/v7////////////v/O/s++zw/PDc+dy9872Z7ZmA6oBz53Px/PHK9sqM64xN4U003TQx3DEy3DL+/v7f+d+T7ZNH4Ecv3C8z3TP8/vzQ99Bu5m79/v3P989j5WMw3DBs5myR7JHJ9slD4EM93j1m5WaA6YCH64d36HfF9cXh+uHr++vd+d1J4EmP7I/k+uT+//6787ty53KY7Zg33Te18rWB6oFW4lbR99F56Hna+dqC6oJc41zV+NXz/fOS7JJB30HA9MC08rQy3TKH6ofW+NY/3j9C30Km8Kb2/fbq++px53GX7Zfa+Nr6/vq387c43Tg63jpk5WSI64ib7pvp++lS4lL4/fip8ak83jzt/O1n5We487hK4UpL4Uu587k53TmY7pj4/vjl+uV26HZZ41la41qq8KpE30Sr8Kv0/fQ53jne+d7D9cNM4Uyg76B66Ho23TbH9cf7/vts+qXUAAAAY3RSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD++P3qw/2N+0j2GMcHYx68BOkMd/x2IKf+pjrS0WDvXxSL+Cy3TEsIdRyhoDXINOSK8rY72mnrhe2jCycJAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+cFGQAhKwJH+lwAAAM8SURBVDjLdZP3X9NQFMVfFIUWLJRpVcoeYlVEQEUExIUyFFFRcfJqqiyb12paDQQKpQXZorJXARcbFRC3oohb/yHTJIUW8fyU5Hxz7/3cdx4ArDBs2XK7FSvtHSB0sF+5wm75MgwDVsIEQkenVSJnF/mlS3IXZ9EqJ0ehwIrAxK5u7h644vKVnNzcnCuXFbiHu5ureJ7APL1Ww7z8gqtKAjEilFcL8vPgai9PzOJL1qjU166TCGlYIURev6ZWrZFwBLZ2nbf2xk0lobESobx5Q+u9bq2ZkPr4UoVFNNLYCNFFhZSvj5QpIHSC6uLFvpkoVkMnIQbEXn54idLSnWZkeVaW4H5eYiD0p3SlXH9ElOnLy/VlBIcQpTrKXwgCAuUGmv/FWFF561ZlhZEvSBvkgQEgKLiqGnF+TW0dZFRXW8MRqLoqOAiEhNazr4huUKsgK5W6gR0EKetDQ8D6sNsc3niHgryoO43ct9th68EG/C77Qt9rgvNquseOhe7iGwCUN7MAqW9ZAFr0JAs0yyGQ4a1chbb2BaC9javQisvAxo5OFiC6ulUWX9XdxW4GdXZsBJs297CAiezFLQDeS5pYoGfzJhC+pa+fG/n+g4ec//DBfe5Lf9+WcBCx9dFjbtN09cAg00U1OFDNrZZ4/GhrBIiMGhoe4Vc7Ojb+5Mn42Ci/+pHhoahIEL1N9tRI8gdIko2NJMkfJ2l8KtsWDQTbd2h1z/g4mcyZNPGheqbT7tguAFhMxM6Jyal/AzM1ObEzIobJHBa7S/bcQCyOHGF4Hhcfy6ZWkLA7sV1vGzpET7cn7kkQcLGX7t2nffGSMFn//+q1dv9eqeViiA8kTQy8sco9Mfr2XdLBhaslOJSc8v6DZr4J0nx4n5J8SGB1OVPTYP6MZVBEfMz3SEu1vd6HveGnWb4JMfsZeh+x8QFIjw+cM3xhCeLL+Fzg0XRbH2AZx0Rfp83xRcppteh4xqICDHEiE377bl71928w8+Q/PkNITml/TCFU9kN7SrKEz6z8dJb8569fP+VZp2OXApgxzsQpZmYUcWcylvQZ4uw56vdv6tzZ//jMyZ+/8OfPhfMx/wOYMS5mZ1+0HeAvs9msMpv5tz0AAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDUtMjVUMDA6Mjk6MzcrMDA6MDBKWqC/AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA1LTI0VDIyOjQ1OjQxKzAwOjAwj8HumgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAASUVORK5CYII=", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACr1BMVEUAAAD////////////////////////////////////////////////////////9/vv5+/L////////////////////////////////////////////////////////////////////////////////////+/v7////9/fr////5+/P////////////////8/fn////////////////////////////////////////////////////////////////////////+/v7////////////////////////////////////+/v7////////////////////////////////////////////////////////////////////////////+/v7////////////3+uz1+en3+u3t9Nbd6rHK34W912i20lj4+u/j7sDD23ajxyyWvw6VvguVvgz+/v7u9drH3X+gxSWUvgmWvw39/vvm8Me00VP+/v3m8MauzkXu9Nmz0FDG3HyUvgrj7r+exCCbwhqwz0rB2XGWvw+51F7h7Lrv9dz0+Oft9NehxifF3Hrx9t/c6a+201j+//7K3oaYwBHZ56j+/vy+12moyjfn8Mn2+uy61WCwzkns89P3+u6+12qryz7p8c35+/HH3X6dwx7e67XY56aVvg2UvQjq8s6cwhuexB/R45b6/PT0+Oa20leVvgqhxijJ3oT8/fna6KqYwBOZwRavzkfB2XLL34nz+OS41F2UvQmYwBKmyDGWvwz7/PfS5JmawRebwhjT5JrB2XD1+erp8s79/vzb6ayiximixir7/PbJ3oOZwRXK3oTx9+Cpyzuqyzvj7sGexCH5+/KZwBSwz0vu9dng7LijxivO4Y6awRjO4Y+61WGXwBHt89Wpyzri7bz9/frM0I39AAAAY3RSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD++P3qw/2N+0j2GMcHYx68BOkMd/x2IKf+pjrS0WDvXxSL+Cy3TEsIdRyhoDXINOSK8rY72mnrhe2jCycJAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+cFGQAhKwJH+lwAAANESURBVDjLY2AAA0ZGJmYWVjZ2juRkDnY2VhZmJkZGBiTAyMnFzcPLxy+QkpqaIsDPx8vDzcWJpIJRUEhYRDQtPSMzKzs7KzMjPU1URFhIEK6CUUxcIjknNy+/oLAICAoL8vNyc5IlxMUYYfKSUsUlpWXlhUUVYFBUWF5WWlIsJQlRwSgtI1tZVV1QWIEECguqqyplZaRBKuTkFWpq68qLKlBAUXldbY2CvBzQAC6e5PoGdHmQiob6ZB4uRgZBccW0xgKY7U3l5U0wdkFjmqK4IAOXUk1zSyHUca1tWVltrVDHFrY01yhxMSirpLQ3QeQ7Oru6e3q6uzo7ICqa2lNUlBlU1Xr7iiBG9k8oTgaC4gn9ECuL+nrVVBnUNSaCuUXlk0omJ4PB5JJJYEcXFUzUUGfQ1JoCUT512vRkKJg+bSpEbIqWJoN22gwwp2nmrGQ4mDUT7KyiGWnaDMmz54AVlM+dh1Awb245WMGc2ckMOvMXQBQsXIRQsGghRMGC+ToMuouXgBUULl1WDJMvXrYUHDJFSxbrMujpLwdzVqxsT4MpSGtfuQKsabm+HoOB4arVECPWrF0HkV+3dg3EgNWrDA0YjIzXb9gICbhNm+cBbSmet3kTJGg3blhvbMRgYrpl6zZo0G7fsXPXrp07tkODftvWLaYmDGbmOrv3rIQmk5V79+3buxKadFbu2a1jbsbAaWFZ2bwfYknFAVCaPABhb9zfXGlpwcnAaGVkffDQYcwEc+ToQWsjK2CaY7Sx1Uk9Voie5Ap3HreztwGnWk4HR6cTbU0oKoqa2k44OTtwQpK9nIvryVOnNyKpKNp45tRJNxc5WMYQdPc4e+48UrovPH/hoIcnImtxenn7XNxTATeiqGLPRR9vL06kzOnrl5x7CZGzLl8R9fNFzd7+sslHr0JDY+PVo8myASjyDAyB9irX2q+DnVF4vf2aSlAgqjwDY3AIX30bKPkWFdy4yRcajGYAUEVYePKt26Cgvn0rOTwCQx6oQjKy8s7doqK79yojJbHIA4M8Knr2/QcP7s+OjrLBpgDojBi7h48ePbSLCcYqD1QRGzf98ePpcbE45IExH5/w5ElCvBUuBUBnJCYlJaI6AADXv7i4Kd/lawAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMy0wNS0yNVQwMDoyOTozNyswMDowMEpaoL8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjMtMDUtMjRUMjI6NDk6NDUrMDA6MDBhsioHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAABJRU5ErkJggg==", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACnVBMVEUAAAD////////////////////////////////////////////////////////7/fvy+fL////////////////////////////////////////////////////////////////////////////////////+/v7////6/Pr////////////////////4/Pj////////////////////////////////////////////////////////////////////////+/v7////////////////////////////////////+/v7////////////////////////////////////////////////////////////////////////////+/v7////////////r9uvo9Ojs9uzU69St2K1/w39gtWBPrU/u9+694L1vu28hlyEBiAEAhwD+/v7X7Nd4wHgalBoAhgAAiAD7/fvE48RKqkoCiAL9/v3D48M8pDzW7NZHqUd1vnUDiAO737sVkRUNjg1BpkFgtGBpuWkCiQJWsFa33bfa7drm8+bV69UblBtzvXPe796r16vY7Nj+//4FigWj1KP8/fzt9u1htWEsnCzG5Mbr9etYsVg/pT/R6dFitmIzoDPK5srx+PF3wHcTkBOx2rGh06EAhQDM58wPjg8UkRSQy5D0+vTl8uVOrE4dlR19wn3Q6dD4/Pim1aYIiwgJjAk+pD5qumqCxYLj8uNUr1QGiga837womij2+/aUzZQMjQwNjQ1ouGgBhwFquWrp9OnL5ssBhgGn1qcelR4elh6o1qj2+vZ+w373+/ff8N8EiAQwnjAxnjGVzZUVkhUJiwm03LQflh+IyIiJyIlZsVnT6tP8/vy53rn6/Pq97PRtAAAAYnRSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD4/erD/Y37SPYYxwdjHrwE6Qx3/HYgp/6mOtLRYO9fFIv4LLdMSwh1HKGgNcg05IrytjvaaeuF7djGYAwAAAABYktHRAH/Ai3eAAAAB3RJTUUH5wUZACErAkf6XAAAAzFJREFUOMtjYAADRkYmZhZWNnaOpCQOdjZWFmYmRkYGJMDIycXNw8vHL5CckpIswM/Hy8PNxYmkglFQSFhENDUtPSMzKyszIz0tVVREWEgQroJRTFwiKTsnNy+/AAzy83JzspMkxMUYYfKSUoVFxSWlBQVlYFBQUFpSXFQoJQlRwSgtI1teUVkFlYWqqaqsKJeVkQapkJNXqK6pLUWRB6oora2pVpCXAxrAxZNUV48uD1JRX5fEw8XIICiumNrQCLO9FAhg7MaGVEVxQQYupeqm5gKo41pa29paW6COLWhuqlbiYlBWSW4vhQh0dHZ19/R0d3V2QFSUtierKDOoqvX2gfkF+f0TCpOAoHBCfz5EpK9XTZVBXWMimFtQmjVpchIYTJ6UBXZIQf5EDXUGTYEMiPIpU6clQcG0qVMgYhkCmgxa02eAOaUzZyXBwayZYGcVzJiuxZA0ew5Ewdx5CAXz5kIUzJmdxKA9fT5EwYKFCAULF0AUzJ+uzaCzaDHEviVLC2HyhUuXQMQWL9Jh0NVbBuEsb0+FKUhtXw4RW6any6BvsGIlhLdq9RqI/JrVqyAiK1cY6DMYGq1dBwnJ0vUbNgJDYvLGDeuhAuvWGhkyGJts2rwFGrRbt23fsWP7tq3QoN+yeZOJMYOpmfbOXcuhEbi8dPfu0uXQ6Fy+a6e2mSkDp7lF+Z69pbBUUABLd2Wle/eUW5hzMjBaGlrt238AM8Ec3L/PytASmOYYrW20Uw4dRk9yh48ctbWzBqdaTnsHx2Otx1ET7fHWY45O9pyQZC/n7FJ+4mQBkoqCglOny12d5WAZQ9DN/cyGLcgKtp495+6ByFqcnl7e53ddgKsouLDrvLeXJydS5vTxTcq5iMhZl3JEfX1Qs7efbNLlK9DQKL1yOUnWH0WegSHATmVRO8QZBVfbF6kEBqDKMzAGBfPVtYIyUEFjaxFfSBCaAUAVoWFJ166Dgvr6taSwcAx5oArJiPIbBwoKDtwsj5DEIg8M8sio2bemTLk1OyrSGpsCoDOibW9fvHjbNjoIqzxQRUzsnbt378TG4JAHxnxc/L178XGWuBQAnZGQmJiA6gAAFLyvxAL3bxQAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDUtMjVUMDA6Mjk6MzcrMDA6MDBKWqC/AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA1LTI0VDIyOjQ5OjU2KzAwOjAwnPAwBAAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAASUVORK5CYII=", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAClFBMVEUAAAD////////////////////////////////////////////////////////7//3y//n////////////////////////////////////////////////////////////////////////////////////+//7////6//3////y//r////////////////4//z////////////////////////////////////////////////////////////////////////+//7////////////////////////////////////+//7////////////////////////////////////////////////////////////////////////////+//7////////////r//fo//Xs//fU/+6t/95//8tg/79P/7nu//i9/+Rv/8Uh/6YB/5kA/5j+//7X/+94/8ka/6MA/5cA/5n7//3E/+dK/7YC/5n9//7D/+c8/7HW/+9H/7V1/8cD/5m7/+QV/6EN/55B/7Np/8NW/7u3/+La//Dm//XV/+4b/6Rz/8fe//Gr/93Y/+/+//9//8wF/5qj/9r8//7t//dh/8As/6vG/+hY/7w//7LR/+xi/8Az/63K/+rx//l3/8kT/6Cx/9+h/9nM/+oP/58U/6CQ/9L0//rl//RO/7gd/6R9/8vQ/+z4//ym/9sI/5sJ/5w+/7Fq/8OC/83j//NU/7oG/5u8/+Qo/6j2//uU/9QM/50N/53o//Zo/8MB/5jp//bL/+pB/7IB/5en/9we/6Qe/6Wo/9wI/5x+/8v3//vf//IE/5kw/6wx/6yV/9TW/+60/+Af/6WI/8+J/89Z/7zT/+25/+L6//2DMMmrAAAAY3RSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD++P3qw/2N+0j2GMcHYx68BOkMd/x2IKf+pjrS0WDvXxSL+Cy3TEsIdRyhoDXINOSK8rY72mnrhe2jCycJAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+cFGQAhKwJH+lwAAAMmSURBVDjLY2AAA0ZGJmYWVjZ2juRkDnY2VhZmJkZGBiTAyMnFzcPLxy+QkpqaIsDPx8vDzcWJpIJRUEhYRDQtPSMzKzs7KzMjPU1URFhIEK6CUUxcIjknNy+/oBAMCvLzcnOSJcTFGGHyklJFxSWlZYWF5WBQWFhWWlJcJCUJUcEoLSNbUVlVDZWFqqmuqqyQlZEGqZCTV6iprStDkQeqKKurrVGQlwMawMWTXN+ALg9S0VCfzMPFyCAorpjW2ASzvQwIYOymxjRFcUEGLqWa5pZCqONa27Ky2lqhji1saa5R4mJQVklpL4M6rKOzq7u7q7MD6uCy9hQVZQZVtZ5eML+woK+/KBkIivr7CiAivT1qqgzqGhPA3MKy7ImTksFg0sRssEMKCyZoqDNoak2GKJ8ydVoyFEybOgUiNllLk0F7+gwwp2zmrGQ4mDUT7KzCGdO1GZJTZkMUzJmLUDB3DkTB7JRkBp3p8yAK5i9AKFgwH6Jg3nQdBt2FiyD2LV5SBJMvWrIYIrZooS6Dnv5SCKesPQ2mIK0dEpyFS/X1GAwMly2H8FasXAWRX7VyBURk+TJDAwYj49VroAG3dt16oC1F69ethQbtmtXGRgwmphs2boKq2Lxl67ZtW7dshspv2rjB1ITBzFxn+44yeGTu3AmPzrId23XMzRg4LSwrdu2GJQdQkoQxd++qsLTgZGC0MrLes3cfZoLZv3ePtZEVMM0x2tjqHDh4CD3JHdp62M7eBpxqOR0cnY4cPYaaaI8dPeLk7MAJSfZyLq4Vx08UIqkoLDx5qsLNRQ6WMQTdPfasO42sYPOZsx6eiKzF6eXtc27HebiKwvM7zvl4e3EiZU5fv+TcC4icdTFX1M8XNXv7yyZfaoEpaLmULBuAIs/AEGivsrAd4ozCze0LVYICUeUZGIND+C63gTJQYVNbMV9oMJoBQBVh4clXroKC+uqV5PAIDHmgCsnIimv7Cgv3Xa+IlMQiDwzyqOiUG1Om3EiJjrLBpgDojBi7mxcu3LSLCcYqD1QRGzft1q1pcbE45IExH59w+3ZCvBUuBUBnJCYlJaI6AABB269xUXFElwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMy0wNS0yNVQwMDoyOTozNyswMDowMEpaoL8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjMtMDUtMjRUMjI6NTA6MDYrMDA6MDDpi8pqAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAABJRU5ErkJggg==", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACbVBMVEUAAAD////////////////////////////////////////////////////////7///y///////////////////////////////////////////////////////////////////////////////////////+///////6///////////////////////4///////////////////////////////////////////////////////////////////////////+///////////////////////////////////////+///////////////////////////////////////////////////////////////////////////////+///////////////r///o///s///U//+t//9///9g//9P///u//+9//9v//8h//8B//8A///+///X//94//8a///7///E//9K//8C///9///D//88///W//9H//91//8D//+7//8V//8N//9B//9p//9W//+3///a///m///V//8b//9z///e//+r///Y//8F//+j///8///t//9h//8s///G//9Y//8////R//9i//8z///K///x//93//8T//+x//+h///M//8P//8U//+Q///0///l//9O//8d//99///Q///4//+m//8I//8J//8+//9q//+C///j//9U//8G//+8//8o///2//+U//8M//9o///p///L//+n//8e//+o//9+///3///f//8E//8w//8x//+V//+0//8f//+I//+J//9Z///T//+5///6//8Ngdu6AAAAYnRSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD4/erD/Y37SPYYxwdjHrwE6Qx3/HYgp/6mOtLRYO9fFIv4LLdMSwh1HKGgNcg05IrytjvaaeuF7djGYAwAAAABYktHRAH/Ai3eAAAAB3RJTUUH5wUZACErAkf6XAAAAu1JREFUOMtjYAADRkYmZhZWNnaOpCQOdjZWFmYmRkYGJMDIycXNw8vHL5CckpIswM/Hy8PNxYmkglFQSFhENDUtPSMzKyszIz0tVVREWEgQroJRTFwiKTsnNy+/AAzy83JzspMkxMUYYfKSUoVFxSUFSKCkuKhQShKiglFaRra0rLyiAAVUlJeVyspIg1TIyStUVlUXYIDqqkoFeTmgAVw8STW1BVhAbU0SDxcjg6C4YmpdPTYF9XWpiuKCDFxKlQ2NMLGm5szM5iYYr7GhUomLQVkluQXmsNa29o6O9rZWmINbklWUGVTVOrug3u/uKUwCgsKebmiAdHWqqTKoa/RCuVl9YHmgir4sqJZeDXUGTYEMCK9/wsQkKJg4oR8iliGgyaA1aTKEM2VqEhxMnQIRmzxJiyEpeRqEM30GQsGM6RCxaclJDNqTZkI4s2YjFMyeBRGbOUmbQWfOXAhn3vxCmHzh/HkQsblzdBh09RbAfJ0KU5AKC5kFeroM+gYLF0F4i5cshcgvXbIYIrJooYE+g6HRsuVQ9StWrgLaUrhq5QqowPJlRoYMxiar16yFCqxbv2Hjxg3r10G5a9esNjFmMDXT3rQZEYVbtiDYmzdpm5kycJpblG7dhi26t20ttTDnZGC0NLTavmMnpnzTju1WhpbANMdobaOdsisfXT5/w25bO2twquW0d3Dc04ymIr95j6OTPSck2cs5u5Tu3YeqYN/+UldnOVjGEHRz375yLbL8ugMH3T0QWYvT08v70ObDCPnDmw95e3lyImVOH9+knCMIBUdzRH19ULO3n2zSMXjibjyWJOuPIs/AEGCnMqcF6ox1LXNUAgNQ5RkYg4L5aprBGai+uYgvJAjNAKCK0LCk4ydACk4cTwoLx5AHqpCMKD0JDPKdp0ojJLHIA4M8Mir5dH//6eSoSGtsCoDOiLY9c+TIGdvoIKzyQBUxsRPPnp0YG4NDHhjzcfHnzsXHWeJSAHRGQmJiAqoDAOgCnVLAYqeOAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIzLTA1LTI1VDAwOjI5OjM3KzAwOjAwSlqgvwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMy0wNS0yNFQyMjo1MDoyMSswMDowMG4J85kAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAAElFTkSuQmCC", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACu1BMVEUAAAD////////////////////////////////////////////////////////8/f3y9/r////////////////////////////////////////////////////////////////////////////////////+/v7////6/P3////z9/r////////////////5+/z//////v/////////////////////////////////////////////////////////////////+/v7////////////////////////////////////+/v7////////////////////////////////////////////////////////////////////////////+/v7////////////s8/jp8fft9PjW5vCwz+KEtdJno8hXmcLu9fnA2Oh1q80qfrIMa6cJaqYKaqb+/v7Z6PF+sdAkea8HaKULa6f8/f3G3epRlcAJaab9/f7G3OpEjrsHaaXY5/FOlL97rs8Iaab9/v6+2Ocfdq0Yc6tJkb1no8dvqMsIaaUNbKhdncS61ebb6fLn8PbX5vAle7B5rs7f7POuzuGFtdMPbainyt/8/f5oo8g1hbbI3utfnsVHkLzT5O/u9PhppMk8ibjM4Ozx9/p9sNAcda200eSlyN4La6YGaKVwqMvO4e0Zc6wddq2Vv9j0+Pvm8PZWmMIme7GDs9LS5O/+/v/5+/ypy98Rb6kTcKpGj7xxqcyIt9Pk7/VcnMQQbqj7/f0wgbQKaqf3+vyYwdkVcaoWcquZwdpvp8vq8vfN4e1JkL2rzOAnfLEofLGszOH2+vyCs9ITb6mDtNLg7PNbnMQ5h7c5h7jA2egfd66awtry9/pvqMoSb6kMbKe30+UpfbGNutaOutZgn8XV5vC81ub7/P0PF+8/AAAAY3RSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD++P3qw/2N+0j2GMcHYx68BOkMd/x2IKf+pjrS0WDvXxSL+Cy3TEsIdRyhoDXINOSK8rY72mnrhe2jCycJAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+cFGQAhKwJH+lwAAANLSURBVDjLY2AAA0ZGJmYWVjZ2juRkDnY2VhZmJkZGBiTAyMnFzcPLxy+QkpqaIsDPx8vDzcWJpIJRUEhYRDQtPSMzKzs7KzMjPU1URFhIEK6CUUxcIjknNy+/oLAICAoL8vNyc5IlxMUYYfKSUsUlpWXlhUUVYFBUWF5WWlIsJQlRwSgtI1tZVV1QU4EEagqqqyplZaRBKuTkFWrr6huKKlBAUUN9Xa2CvBzQAC6e5MYmdHmQiqbGZB4uRgZBccW05gKY7S3l5S0wdkFzmqK4IAOXUmtbeyFEqKajs6urs6MGoqSwva1ViYtBWSWluwci39vXP2HixAn9fb0QFT3dKSrKDKpqkyYXQYycMrU4GQiKp06BWFk0eZKaKoO6xjQwt6ghuwQsD1RRkg12dFHBNA11Bk2t6RDlM2bOSoaCWTNnQMSma2kyaKfNBnNa5sxNhoO5c1rACmanaTMkp8wDKyifvwChYMH8crCCeSnJDDoLF4EVNCxeglCwZHEDWMGihToMukuXgRUULl9RDJMvXrEcHDJFy5bqMujprwRzVq1ekwZTkLZm9SqwppX6egwGhmvXQYxYv2EjRH7jhvUQA9atNTRgMDLetBns5IqWLVu3bU9O3r5t6xaowOZNxkYMJqY7du6CBG3L7j179+3bu2c3RL5o184dpiYMZuY6+w+shkRg4erygwfLV0OirmL1gf065mYMnBaWh9oOQ/RUHAGlySMQdsvhtkOWFpwMjFZG1kePHcdMMCdOHrU2sgKmOUYbW53UU4XoSa5wzWk7extwquV0cHQ6c7YFRUVRy9kzTs4OnJBkL+fiWnnuPLKKopYLFyvdXORgGUPQ3ePS5SuFCAWFu68e9fBEZC1OL2+fa9cr4EYUVRy45uPtxYmUOX39knNvIHLWzVuifr6o2dtfNvnkbWhotNy+kywbgCLPwBBor3L33n2wMwrvr7mrEhSIKs/AGBzC13j2AdCSogdnS/hCg9EMAKoIC09++AgU1I8eJodHYMgDVUhGHnp8oqjoxJNDkZJY5IFBHhWd8nTGjKcp0VE22BQAnRFj9+zGjWd2McFY5YEqYuNmPX8+Ky4Whzww5uMTXrxIiLfCpQDojMSkpERUBwAAPAa7YJpbYIgAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDUtMjVUMDA6Mjk6MzcrMDA6MDBKWqC/AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA1LTI0VDIyOjUwOjM0KzAwOjAw8JvcoAAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAASUVORK5CYII=", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACzVBMVEUAAAD////////////////////////////////////////////////////////7/Pzy9Pb////////////////////////////////////////////////////////////////////////////////////+/v7////6+/v////////////////////4+fr////////////////////////////////////////////////////////////////////////+/v7////////////////////////////////////+/v7////////////////////////////////////////////////////////////////////////////+/v7////////////r7/Ho7O/s7/LU2+GtusZ/lKdge5JPbIfu8fO9yNFvh5whRWYBK1AAKE8AKU/+/v7X3uR4j6IaP2EAJk0AKlD7/PzEztZKZ4ICK1EAKE79/f3DzdY8XHkAJ03W3eNHZYB1jKADK1EAJ067xtAVO14NNVlBYHxgepHr7vFpgpgCLFFWcou3ws3a4OXm6u3V2+IbQWMBK1Fzip7e4+iruMVPbIbY3uQFLlOjssD8/f3t8PJhe5IsT27Gz9hYc4w/X3vR2d9ifJMzVXPK09vx8/V3jqITOVyxvcmhsL4AKVAAJUzM1NwPNloUOl2QorP09vfl6e1Oa4UdQmN9k6bQ2N/4+fqmtMIIL1QJMVY+XXpqg5mCl6nj6OxUcYoAJkwGL1S8x9EoSmr2+PmUpbUMM1cNNFiUprVogZgBKE5qgpjp7PDL1NsBJ06ntcIeQmQeQ2WotsP29/l9kqUIMVV+k6b3+Pnf5OlUcIoEKlAwUnExUnG9yNKVprYVPF4IMFUJMFVBYH3X3uO0wMwfRGWInK0MNFiJnK5ZdI3T2uEwUnC5xM/6+/yAxxLtAAAAYnRSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD4/erD/Y37SPYYxwdjHrwE6Qx3/HYgp/6mOtLRYO9fFIv4LLdMSwh1HKGgNcg05IrytjvaaeuF7djGYAwAAAABYktHRAH/Ai3eAAAAB3RJTUUH5wUZACErAkf6XAAAA0hJREFUOMtjYAADRkYmZhZWNnaOpCQOdjZWFmYmRkYGJMDIycXNw8vHL5CckpIswM/Hy8PNxYmkglFQSFhENDUtPSMzKyszIz0tVVREWEgQroJRTFwiKTsnNy+/oBAICvLzcnOykyTExRhh8pJSRcUlpWWFheVgUFhYVlpSXCQlCVHBKC0jW1FZVV1TjgRqqqsqK2RlpEEq5OQVauvqGwrLUUBhQ31drYK8HNAALp6kxiZ0eZCKpsYkHi5GBkFxxdTmFpjtrWVlrTB2S3OqorggA5dSbVs7xP7Cmo7Orq7OjhqIkpr2tlolLgZlle6eBoh8b1//hIkTJ/T39UJUNPR0qygzqKpNmgzmF06ZOq0oCQiKpk2dAhGZPElNlUFdY3p+IdhRM2aC5YEqZs4AO7owf7qGOoOmQAZE+azZc5KgYM7sWRCxDAFNBq2588Cc1vkLkuBgwfxWsIJ5c7UYkroXghWULVqMULB4URlYwcLuJAbtuUvAChqWLkMoWLYU7LHCJXO1GXSWrwArKFi5qggmX7RqZQFYwYrlOgy6eqvBCtas7UmFKUjtWbsGrGC1ni6DvsG69RAnb9i4CSK/aeMGiMj6dQb6DIZGm7dAQrp167btQFuKtm/b2goJ6y2bjQwZjE127NwFCdrW3Xv27tu3d89uiHzhrp07TIwZTM209x84CI3AgwcPHTp4EBqdBw/s1zYzZeA0t6g4fKQGlthAAJqojhyusDDnZGC0NLQ6euw4ZoI5cfKolaElMM0xWttop5w6jZ7kTp85a2tnDU61nPYOjuc6z6OoKDzfec7RyZ4TkuzlnF0qLlysQVJRWHPpcoWrsxwsYwi6uV+5eg0p3dfsvn7D3QORtTg9vbxv3roNN6Lw9q2b3l6enEiZ08c3KecOzJLCmrv3RH19ULO3n2zSfWjiLq95cD9J1h9FnoEhwE5lec9DcCQXPOpZrhIYgCrPwBgUzNfYCcpAhS2Pn/CFBKEZAFQRGpb09BkopJ89TQoLx5AHqpCMqHj+orDwxcuKCEks8sAgj4zqfjVr1qvuqEhrbAqAzoi2ff3mzWvb6CCs8kAVMbFz3r6dExuDQx4Y83Hx797Fx1niUgB0RkJiYgKqAwC8prs7Sn3FCAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMy0wNS0yNVQwMDoyOTozNyswMDowMEpaoL8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjMtMDUtMjRUMjI6NTA6NDMrMDA6MDA/+es3AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAABJRU5ErkJggg==", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACfFBMVEUAAAD////////////////////////////////////////////////////////8/P709P3////////////////////////////////////////////////////////////////////////////////////+/v7////7+/7////19f3////////////////6+v7///////7////////////////////////////////////////////////////////////////+/v7////////////////////////////////////+/v7////////////////////////////////////////////////////////////////////////////+/v7////////////v7/zs7Pvw8Pzc3Pm9vfOZme2AgOpzc+fx8fzKyvaMjOtNTeE0NN0xMdwyMtz+/v7f3/mTk+1HR+AvL9wzM938/P7Q0Pdubub9/f7Pz/djY+UwMNxsbOaRkezJyfZDQ+A9Pd5mZuWAgOmHh+t3d+jFxfXh4frr6/vd3flJSeCPj+zk5Pr+/v+7u/NycueYmO03N921tfKBgepWVuLR0fd5eeja2vmCgupcXOPV1fjz8/2SkuxBQd/AwPS0tPIyMt2Hh+rW1vg/P95CQt+mpvD29v3q6vtxceeXl+3a2vj6+v63t/M4ON06Ot5kZOWIiOubm+7p6ftSUuL4+P2pqfE8PN7t7fxnZ+W4uPNKSuFLS+G5ufM5Od2YmO74+P7l5fp2duhZWeNaWuOqqvBERN+rq/D09P05Od7e3vnDw/VMTOGgoO96eug2Nt3Hx/X7+/4Nm4E+AAAAY3RSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD++P3qw/2N+0j2GMcHYx68BOkMd/x2IKf+pjrS0WDvXxSL+Cy3TEsIdRyhoDXINOSK8rY72mnrhe2jCycJAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+cFGQAhKwJH+lwAAAM8SURBVDjLdZP3X9NQFMVfFIUWLJRpVcoeYlVEQEUExIUyFFFRcfJqqiyb12paDQQKpQXZorJXARcbFRC3oohb/yHTJIUW8fyU5Hxz7/3cdx4ArDBs2XK7FSvtHSB0sF+5wm75MgwDVsIEQkenVSJnF/mlS3IXZ9EqJ0ehwIrAxK5u7h644vKVnNzcnCuXFbiHu5ureJ7APL1Ww7z8gqtKAjEilFcL8vPgai9PzOJL1qjU166TCGlYIURev6ZWrZFwBLZ2nbf2xk0lobESobx5Q+u9bq2ZkPr4UoVFNNLYCNFFhZSvj5QpIHSC6uLFvpkoVkMnIQbEXn54idLSnWZkeVaW4H5eYiD0p3SlXH9ElOnLy/VlBIcQpTrKXwgCAuUGmv/FWFF561ZlhZEvSBvkgQEgKLiqGnF+TW0dZFRXW8MRqLoqOAiEhNazr4huUKsgK5W6gR0EKetDQ8D6sNsc3niHgryoO43ct9th68EG/C77Qt9rgvNquseOhe7iGwCUN7MAqW9ZAFr0JAs0yyGQ4a1chbb2BaC9javQisvAxo5OFiC6ulUWX9XdxW4GdXZsBJs297CAiezFLQDeS5pYoGfzJhC+pa+fG/n+g4ec//DBfe5Lf9+WcBCx9dFjbtN09cAg00U1OFDNrZZ4/GhrBIiMGhoe4Vc7Ojb+5Mn42Ci/+pHhoahIEL1N9tRI8gdIko2NJMkfJ2l8KtsWDQTbd2h1z/g4mcyZNPGheqbT7tguAFhMxM6Jyal/AzM1ObEzIobJHBa7S/bcQCyOHGF4Hhcfy6ZWkLA7sV1vGzpET7cn7kkQcLGX7t2nffGSMFn//+q1dv9eqeViiA8kTQy8sco9Mfr2XdLBhaslOJSc8v6DZr4J0nx4n5J8SGB1OVPTYP6MZVBEfMz3SEu1vd6HveGnWb4JMfsZeh+x8QFIjw+cM3xhCeLL+Fzg0XRbH2AZx0Rfp83xRcppteh4xqICDHEiE377bl71928w8+Q/PkNITml/TCFU9kN7SrKEz6z8dJb8569fP+VZp2OXApgxzsQpZmYUcWcylvQZ4uw56vdv6tzZ//jMyZ+/8OfPhfMx/wOYMS5mZ1+0HeAvs9msMpv5tz0AAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDUtMjVUMDA6Mjk6MzcrMDA6MDBKWqC/AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA1LTI0VDIyOjUwOjU2KzAwOjAwoWvEDgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAASUVORK5CYII=", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACTFBMVEUAAAD////////////////////////////////////////////////////////9/v/5+v/////////////////////////////////////////////////////////////////////////////////////+/v/////8/f/////////////////////8/P///////v/////////////////////////////////////////////////////////////////+/v/////////////////////////////////////+/v/////////////////////////////////////////////////////////////////////////////+/v/////////////2+P/09//r8P/Y5P/D1P+1yv+txP/3+f/g6f+7z/+Xtf+Iqv+Hqf/+/v/s8f/A0v+Usv+GqP/9/f/j6/+qwv+kvv+pwf++0f+Gqf/f6P+RsP+Orv+mv/+0yv+5zf+Jq/+wxv/d5//t8v/z9v+Us/+90P/v9P/X4/+Kq//U4P/9/v/2+f+cuP/k7P/1+P+xx/+lv//p7/+2yv+gu//m7f/4+v+Qr//a5P/T3/+FqP/n7f/L2v/6+//y9v+sxP+Vs//C1P/8/P/V4f+LrP+Mrf+6zf/F1f/y9f+vxv+KrP+atv/7/P/N2/+Nrf+Nrv+4zP/W4v+VtP+WtP/6/P/C0/+MrP/D0//w9P+euv+SsP+Ssf/N3P/c5v/I1//q8P/e5//8/f/tCMxjAAAAYnRSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD4/erD/Y37SPYYxwdjHrwE6Qx3/HYgp/6mOtLRYO9fFIv4LLdMSwh1HKGgNcg05IrytjvaaeuF7djGYAwAAAABYktHRAH/Ai3eAAAAB3RJTUUH5wUZACErAkf6XAAAAyFJREFUOMt1k+db01AUxm+U1QKllT0KAlXUInsjoOICRREVFZGRMMrKTSFlBVoKKGgZUqZShiJDUUARFyrrHzPkJrRlnE855/09J+9z7jkAcIFhx47b2NrZO+C4g72drc3xYxgGLAITiR2dnCUuUqKkhJC6SJydHMUiCwKTnXB1cydKy8pVFRWq8rJSwt3N9YRsj8A8PL3wyqrqGhJyQdZUV1XiXp4emKB7+1Dq2jqalbiAkK6rVVM+3ojAfP3kmvoGkld5hmyo18j9fHcJ/4CTVH0jbaWzBN1YT50M8GcbiJ1wddN+fZdoUuNOYgzIPAOJZqE/ZGiaEb7JZiLQUwbEQVRLK+TNaXVtbTotbxa2tlBBYhCsIPQ0KrR3dD57/vxZZ0c7Img9oQgGp06XdkHUsvsFhbNBvehGv4RdpadPgZAzL7kU0hVqnA91BWcaki/PhICz0nKEG3p6BaC3x4Bq5dKz4FyfikuY/lf4XrzqZzhA1XcO4ANGDqAHh8zA0CDnGxoHcKDsG0bAyKgZGB1BwHCfEoSO1aL/vX5DCTr15jWq1Y6FgvNh4ygx6QkBIPQmVBsPOw/CIya0KGudnEL61CQaLdRORISDyKjpt5xlknk3w/kcmnnHF95OR0WC6Jj3s3NotMx848KHDwuN80iHc7PvY6JBbJzy46KJf0AT/ekTbeKf07T4URkXC0TxCZqWz4ywBVDYO5L53KJJiBcBLDEyaWl55eDCfFleSopMZHcOS76gLPkK968c1JekpCZzWytKu3hpVMdYLy2jG710OU2E1t4//Ypm9ZtlDwjXVjVX0/2Fw5Bdu/79x5wl8PPX0vUb5tMSZWTe/L1ovgxILv6+mZkhsjjOW1l41br5star3LNuWZ/3bTm+/IefBvP3Hy6/Y6UDkJ2qGNMjG3BOP6a4m22tAyznnkSt27UBSZ1acj9nXwOWeJCLb6ztjnptA899eEBnCe9Hms0VCFc2NY+8D9HZkT/OGzAaDMaBvMfJhwGsjScpW+vrWylPcg7VWSL/KbW9TT3NP0JnX76gcGensCDxKIC1UVRcXGRt4D+SPpTGEJHXggAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMy0wNS0yNVQwMDoyOTozNyswMDowMEpaoL8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjMtMDUtMjRUMjI6NTE6MDYrMDA6MDAGSaFUAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAABJRU5ErkJggg==", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAClFBMVEUAAAD////////////////////////////////////////////////////////9+//58v/////////////////////////////////////////////////////////////////////////////////////+/v/////9+v/////68v/////////////////8+P/////////////////////////////////////////////////////////////////////////+/v/////////////////////////////////////+/v/////////////////////////////////////////////////////////////////////////////+/v/////////////36//16P/37P/u1P/erf/Lf/+/YP+5T//47v/kvf/Fb/+mIf+ZAf+YAP/+/v/v1//JeP+jGv+XAP+ZAP/9+//nxP+2Sv+ZAv/+/f/nw/+xPP/v1v+1R//Hdf+ZA//ku/+hFf+eDf+zQf/Daf+7Vv/it//w2v/15v/u1f+kG//Hc//x3v/dq//v2P///v/Mf/+aBf/ao//+/P/37f/AYf+rLP/oxv+8WP+yP//s0f/AYv+tM//qyv/58f/Jd/+gE//fsf/Zof/qzP+fD/+gFP/SkP/69P/05f+4Tv+kHf/Lff/s0P/8+P/bpv+bCP+cCf+xPv/Dav/Ngv/z4/+6VP+bBv/kvP+oKP/79v/UlP+dDP+dDf/26P/DaP+YAf/26f/qy/+yQf+XAf/cp/+kHv+lHv/cqP+cCP/Lfv/79//y3/+ZBP+sMP+sMf/Ulf/u1v/gtP+lH//PiP/Pif+8Wf/t0//iuf/9+v/1rAt3AAAAY3RSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD++P3qw/2N+0j2GMcHYx68BOkMd/x2IKf+pjrS0WDvXxSL+Cy3TEsIdRyhoDXINOSK8rY72mnrhe2jCycJAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+cFGQAhKwJH+lwAAAMmSURBVDjLY2AAA0ZGJmYWVjZ2juRkDnY2VhZmJkZGBiTAyMnFzcPLxy+QkpqaIsDPx8vDzcWJpIJRUEhYRDQtPSMzKzs7KzMjPU1URFhIEK6CUUxcIjknNy+/oBAMCvLzcnOSJcTFGGHyklJFxSWlZYWF5WBQWFhWWlJcJCUJUcEoLSNbUVlVDZWFqqmuqqyQlZEGqZCTV6iprStDkQeqKKurrVGQlwMawMWTXN+ALg9S0VCfzMPFyCAorpjW2ASzvQwIYOymxjRFcUEGLqWa5pZCqONa27Ky2lqhji1saa5R4mJQVklpL4M6rKOzq7u7q7MD6uCy9hQVZQZVtZ5eML+woK+/KBkIivr7CiAivT1qqgzqGhPA3MKy7ImTksFg0sRssEMKCyZoqDNoak2GKJ8ydVoyFEybOgUiNllLk0F7+gwwp2zmrGQ4mDUT7KzCGdO1GZJTZkMUzJmLUDB3DkTB7JRkBp3p8yAK5i9AKFgwH6Jg3nQdBt2FiyD2LV5SBJMvWrIYIrZooS6Dnv5SCKesPQ2mIK0dEpyFS/X1GAwMly2H8FasXAWRX7VyBURk+TJDAwYj49VroAG3dt16oC1F69ethQbtmtXGRgwmphs2boKq2Lxl67ZtW7dshspv2rjB1ITBzFxn+44yeGTu3AmPzrId23XMzRg4LSwrdu2GJQdQkoQxd++qsLTgZGC0MrLes3cfZoLZv3ePtZEVMM0x2tjqHDh4CD3JHdp62M7eBpxqOR0cnY4cPYaaaI8dPeLk7MAJSfZyLq4Vx08UIqkoLDx5qsLNRQ6WMQTdPfasO42sYPOZsx6eiKzF6eXtc27HebiKwvM7zvl4e3EiZU5fv+TcC4icdTFX1M8XNXv7yyZfaoEpaLmULBuAIs/AEGivsrAd4ozCze0LVYICUeUZGIND+C63gTJQYVNbMV9oMJoBQBVh4clXroKC+uqV5PAIDHmgCsnIimv7Cgv3Xa+IlMQiDwzyqOiUG1Om3EiJjrLBpgDojBi7mxcu3LSLCcYqD1QRGzft1q1pcbE45IExH59w+3ZCvBUuBUBnJCYlJaI6AABB269xUXFElwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMy0wNS0yNVQwMDoyOTozNyswMDowMEpaoL8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjMtMDUtMjRUMjI6NTE6MjArMDA6MDAnvJMTAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAABJRU5ErkJggg==", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAMAAABjq9sOAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACbVBMVEUAAAD/////////////////////////////////////////////////////////+///8v///////////////////////////////////////////////////////////////////////////////////////v//////+v//////////////////////+P///////////////////////////////////////////////////////////////////////////v///////////////////////////////////////v///////////////////////////////////////////////////////////////////////////////v//////////////6///6P//7P//1P//rf//f///YP//T///7v//vf//b///If//Af//AP///v//1///eP//Gv//+///xP//Sv//Av///f//w///PP//1v//R///df//A///u///Ff//Df//Qf//af//Vv//t///2v//5v//1f//G///c///3v//q///2P//Bf//o////P//7f//Yf//LP//xv//WP//P///0f//Yv//M///yv//8f//d///E///sf//of//zP//D///FP//kP//9P//5f//Tv//Hf//ff//0P//+P//pv//CP//Cf//Pv//av//gv//4///VP//Bv//vP//KP//9v//lP//DP//aP//6f//y///p///Hv//qP//fv//9///3///BP//MP//Mf//lf//tP//H///iP//if//Wf//0///uf//+v8BRUUXAAAAYnRSTlMAAAMQLWqp1fMBEUOe6Pn8/gUukuz+CU3EW9kGUNsCMsvxrzbuePq1/OD4/erD/Y37SPYYxwdjHrwE6Qx3/HYgp/6mOtLRYO9fFIv4LLdMSwh1HKGgNcg05IrytjvaaeuF7djGYAwAAAABYktHRAH/Ai3eAAAAB3RJTUUH5wUZACErAkf6XAAAAu1JREFUOMtjYAADRkYmZhZWNnaOpCQOdjZWFmYmRkYGJMDIycXNw8vHL5CckpIswM/Hy8PNxYmkglFQSFhENDUtPSMzKyszIz0tVVREWEgQroJRTFwiKTsnNy+/AAzy83JzspMkxMUYYfKSUoVFxSUFSKCkuKhQShKiglFaRra0rLyiAAVUlJeVyspIg1TIyStUVlUXYIDqqkoFeTmgAVw8STW1BVhAbU0SDxcjg6C4YmpdPTYF9XWpiuKCDFxKlQ2NMLGm5szM5iYYr7GhUomLQVkluQXmsNa29o6O9rZWmINbklWUGVTVOrug3u/uKUwCgsKebmiAdHWqqTKoa/RCuVl9YHmgir4sqJZeDXUGTYEMCK9/wsQkKJg4oR8iliGgyaA1aTKEM2VqEhxMnQIRmzxJiyEpeRqEM30GQsGM6RCxaclJDNqTZkI4s2YjFMyeBRGbOUmbQWfOXAhn3vxCmHzh/HkQsblzdBh09RbAfJ0KU5AKC5kFeroM+gYLF0F4i5cshcgvXbIYIrJooYE+g6HRsuVQ9StWrgLaUrhq5QqowPJlRoYMxiar16yFCqxbv2Hjxg3r10G5a9esNjFmMDXT3rQZEYVbtiDYmzdpm5kycJpblG7dhi26t20ttTDnZGC0NLTavmMnpnzTju1WhpbANMdobaOdsisfXT5/w25bO2twquW0d3Dc04ymIr95j6OTPSck2cs5u5Tu3YeqYN/+UldnOVjGEHRz375yLbL8ugMH3T0QWYvT08v70ObDCPnDmw95e3lyImVOH9+knCMIBUdzRH19ULO3n2zSMXjibjyWJOuPIs/AEGCnMqcF6ox1LXNUAgNQ5RkYg4L5aprBGai+uYgvJAjNAKCK0LCk4ydACk4cTwoLx5AHqpCMKD0JDPKdp0ojJLHIA4M8Mir5dH//6eSoSGtsCoDOiLY9c+TIGdvoIKzyQBUxsRPPnp0YG4NDHhjzcfHnzsXHWeJSAHRGQmJiAqoDAOgCnVLAYqeOAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIzLTA1LTI1VDAwOjI5OjM3KzAwOjAwSlqgvwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMy0wNS0yNFQyMjo1MTo0MiswMDowMHZMi70AAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAAElFTkSuQmCC", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAQAAAD+fOO3AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfnBRkAISsCR/pcAAADj0lEQVRIx5WWO2xURxSGvzN7H7a0AdFRkFSQBovKqcCyBF0kmlDS0SHRpkJKEYmGEBeENImFRJMoLlLk4caJrCguEDSguMEijYMQAu+uwfZ672v+FHe93nu9fnCmO3P+f87jn7nXGDIBNPiAD5limgk+oglsssoyf/E3/7FBAcZIEzKd0CXd1yslPve+ULm897kSvdJ9XdIJmfaBhzqnu1qTL5QrUVeb2tCGNtVVolyF5LWmuzqnUCPg47qsJalQqi2tq63W0GprXVtKVUjSki5rfIfC+rWP8xlf6GNPSoLf3RruDo6YCIet8CU/s21llCDiU77S6YJtMvZtEgJCxmlgz/mceVLDAY4Jbh4OL3cytinQaW4ygQMnOM4NJv2h8GEKD5Pc4LhwhFzgiifZA9fQqlMkeLjCBUJHk2s6VpBW4EIYITExIVYhMSClQMe4RjPgDNMixVfgJdhhgCjz0yDC8KQ0sGnOBFxUU2S1XsfENAaeBg5Hb4gCMsZQ0y46pnBFZQuiCrykiIkqnRAFOKYcZ0uC4fQj3J7+OyKsEleA46zjpMzXTnMjhmm4WlYeGScd8d7Q0VoY6Y8dvu6rzv0Qv3e0rFaxx48IFb52lsOg5XiGH67N8GQjCbKKVqABnmeOR+YdrgLJSGsUIq1pxeEwzyPHApkjqOWQ0KMYeAp6JLXzAxxkLDie8NRqMzYKenTpss02Xbr0KGpSjzB4yhNHh1nzAWFtZCKj119ZTakQEmCeWTqOlAUWjZhG7draYHRWu+YNYgwWWSB1iJfcsdcBcaWMHZK6fIQjJsBec4eXyBnkLDFjPiKCfUS0C4eICCv4miVyw4HBFj8xZ4oJD6QoH9UIE3PMsWXQF6FY5RtbbhCPuIdV9cU0sH+4x2p5kitrxfOYGVsPR3RieHgxIbbODI/xxoAADHJ+Y5Zk5w0cBQ+JIWGW38ltkNNOx8UaD2zR9V+jupTLV8nJFnnA2u73dahkg2W+5XkwshPl8PiXeyxbxV+ZO3/wvXWiWhll+hHW4Tv+tBpx1Xr8wK+WjhEMKIQRMIal/MKP9DjYhD7RQylRRy211VZLHSWS9FCT4ggmdFUvvLr9f4S2uvLSC109EhyEmrqtd4U21FZbGyqkd7qt5hEJQOiU5pXnequ3yqVc8zp1ZHif4rxWvFKl8tKKzr8XHIQCXfdvvLz8G11X8J4E/U7cUkst3Tqo+v8BGqkQrMMFpyAAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDUtMjVUMDA6Mjk6MzcrMDA6MDBKWqC/AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA1LTI0VDIyOjUyOjAxKzAwOjAwKNkk2QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAASUVORK5CYII=", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAQAAAD+fOO3AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfnBRkAISsCR/pcAAAD/0lEQVRIx5WVP2wcRRTGf29u9/44a5/Pd2cHEagIEgoFRYSQHMtSQkVJOsoICUVKi+gokFIgghubArAipTHCBVL448ZBFiI0caQ4whGKFRoTx3aS89k+fL7b3ZtHcb7zzdkOyWyzOzPf99773jezQsdQgAS9vMIIo7zJqwTAvyyzyG/8zj9UaIBw6FBUNKfn9Kquad3GsY001FAjja2Nta5relXPaU5FO1DSEd3nDT7kAwZiiaixS0gMeCTJkMbHUzaYYpK/iMQlUMjwLp8wHFNli01C3DhJ+snSgwd/8Dk32JV9AoUM7/Opvl6nRInQTa6lDkny5EkhS3zGD00KAYUk7/GFvrbDKtvoUSKhCH28xDHkAR8zQygIqOEtvtbTO6xQ4UiN25n08jLHkNt8xIJYo5DlEqdrrP4vvLlaYZUanOYSWcXgc4bzMSW2D9S9/7gU25SI4Txn8A0BF7SvSsmpXVES9FGgQB8Jh0RQSlTRPi4QeJxktEGZyIELOfKkSAAN6pQodwQQIsr04I1y0uOsBhFbXVoPUSS5B/BJkSbJupPjFoMkAjlrGMHUiBydsxTa8JaNCmTbfgCIqIFhxHDKml2HW8iR6uqGkCLn7FF2sYZThuMqobM5cwDeosg4MyEqHDekwDoLCcyhHjAknG8LkDJYugDW6XunuLaLELCGkuA7C3WiQyiUiLoz4yNQMtwXm3ZqjdiicYCgwZbjFUgjlvuGW8am8RynldnoomiwQdmxmkcaY7llmCXyCZwcYtZYp9qeqbLOGrETP8CHiFmPBe567wywje2wasgaFTL4QMQuOx2roBgG8OAuCx5lJs3bgclSdrKwVKhgWu3qckaWAGOZpGwImWXOp0i669gKYLHt9/34aYr4MMcsoUF5xBV5HDBIoqt9sve47UwwSIA85gqPUCMQc5MxY3MMwBEm2odDnhymwZfcJBYMCOzwPdOeFuh9JkXzRszjKdNMsyMtP6IsMy6LPRRJHkmhQJIiPcifTLDc3Gb2FLbMMyab/RSOOErNzQX6kU3GmMcKbQIQiPmZSannySKHngWhnzxSZ5JfiKVN2lJceco1mUtRJHOgDAUyFEmpzHGNp/v/1458BRb5igd9FLrOJ4BPgV74mwkWOxvrFCxwg28p5+nHdOSgGPrJQ5lv+NX1RbdiNab4KREOEbSVUISAIRIhP/IdNZ5FIPCQCe6kGdxraLN5g6ThDhM87L4tD/RMYJ5xVrIU9+7ABEWysMI4tw9etoc3/TpTUimQxWDIUkAqTHGd5x2KntAZjat6T+9pVTXWGT2hz41vUgzrktVN3VSruqTDLwQHRT29aJ9YtWqf6EX1XpAAFA30spa0pJc1OBr+H/Nbm042akI7AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIzLTA1LTI1VDAwOjI5OjM3KzAwOjAwSlqgvwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMy0wNS0yNFQyMjo1MjoyOCswMDowMP9kZncAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAAElFTkSuQmCC", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAQAAAD+fOO3AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfnBRkAISsCR/pcAAAEJklEQVRIx5XVT2xc1RUG8N+9M2M79tgxJDLR1MHYjosQrdRFVFUKUSToqsuy6xJVqpDYVuy6qMSiKmSTdNHWQmKTqllUon+yIFRRVbohSAQRgRxRJXWwSQzGjpzYnsnMOyzsOPPGNoX7Nk9P9/vO+b7z5yVdJ6Bi2FEnnfI9j6vjrnlX/cu/3bSmQ7LnCZHikXguXo9b0SzarWIzNmIjNqNVFO1oxq14PZ6LRyJFFyp1Ra95ys/9zKPNtOmuVeta6DNoVN2A/vClc2Z97H4qEwQH/NjLTrSsWrTonnKcIQ0No/r4j99420Z6SBAc8FO/iu+u+Z8b1iVlpYEw6AkThqVrfu0vWxSJoM9P/LY49qWP3RL7mSQkRzzlUfkTv3RBK0lE9gO/j+PLPrQk7QvfNtqY7zskvecXrqQiBwe95Piaj/4vnCRZ8pE1jnvJwZDVPOP5phtu98BDKBSix87kthuaPO8ZtazuhRhZdb2kPYSaMVOmjKmVSJJw3aoY8YJ61YxTLQs25S549h2ThlTRds91CwoPa79pwaj+U2aqno36psVS9GTGMYM73+qGDbrWlWOyaFpfPT2bnYy8ZqOUfMOkoS7KZMikRknIhjWRncye7uQ7Jf0V44Z3+T9sXKXkwx2d7OnsSKT1nqv1PYqZ1Hto10VyJOsPnVLx+rsidZ+K/lJBO4L+rEg9gLZiT4JCu4cwUWTLyUAp1bs2SpEeZLbhbknagMRyNpeLsram21q7CFpua/Z4lQtz2bu5GFHbiZkkN833pNs272ZXq4eaEbnwbnYx3T9grCSiac6c1Z0vq+bMaZYEjDkg3Xex6ooP+n501C2drj5bN2fJQQPYdMeKdqlXK47q4wNXqlbMVn54ODfMl3qvbcnS9izYNacNh1UKs1aylosuDZgy0jO2WdLR2X7rho+YMsAlF7WysOjVvHTYjGpP+dL2Uy5nzYzD8pJXLYqcaHvH6UoxboI9OqAMZ8K4Ssdr3tFOMol7/ux8f0wa+1qKwJgn9IfzzruX2N4iYd6ZdHXUtKF9KQJDpo1KHzprfuta3tKqcNnpvNowsc8oQcWEhrzqtMuKLW/yA7u0/d1sbk5qSHvOQtIwKTfN+of2A2t3FmEKX3gjXdpKsldGYNS0oUiXvOGLh//Xh5tU4qrf+WTMpP5dGQyYMsZ/nXW1u7C5+1LibX+0MuGoSlcOoWLc46z4g3+W+yL3BNp0zt9qrWMO7TgRkkOOqbX81Z9s+jqCxKfOen/EkwbZ3sODnjTC+876tHdb9mYgcdkZC4+ZVgVV0x5jwRnv7V62uwjAm87ltUkNWd4q3ppz3vRNT4jxuBDt1Xgr3orViHZciPH4xvgtihNxrYjP4rMoIq7FiW8FJ0Q1Xiw+70Qnis/jxah+SwJC1OOVWI7leCXq+8O/AuFKp/3c1qOQAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIzLTA1LTI1VDAwOjI5OjM3KzAwOjAwSlqgvwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMy0wNS0yNFQyMjo1Mjo0MiswMDowMJ17ML4AAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAAElFTkSuQmCC", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAQAAAD+fOO3AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfnBRkAISsCR/pcAAAER0lEQVRIx5XVS2xV1xXG8d/evrbxC7CpMbVSECGg2qlRU5tXDEVNOmmHzazDqFIVKdOqsw4qZVA1RZGgg7ZWpEyoyqBS+qADgpxSOglYkIQE2aFCIuGNMcEOhsu9Z3WAgXts0yb7zI7O919nfevbeycNK6BJl2/YY69vWa8Tcy4445/+5VOz6iTLrhApuuPFeDOuxL167W4xF7fjdszF3aJei3txJd6MF6M7UjSoUkP1ZgN+4sd67qRZ110xYx5tuq3Tq0t7uOmgMWfdT2VA0Ob7fm503iUf+9iMcp1ugwb1a+PffuUd8+kxIGjzI7+ILTdMmHBLVu40UFht2LCvSVN+6c8PEImgxQ/9unjmgnFT6vLyJik02eJ71svn/Mxh1SQR2bf9rhi54B/OS0/y+KHRNvqB9fJJP3U6FTlY5VUjNxz9v3KS5LyjbjDiVatC1my3l+446ZNF8lAsPLEI8YmT7vCS3ZqzTi/HyosmRIM8FFbYbJttNltRgiRhwkWx0ss6Kzbbe8dHZhusC9mQYWu0oGrahA8VHs9+1kf6dey1ueKF6JxztlQ9222X7kfv1ui1yvES4qxd2jvTC9meIl/zecnnAdsb5A9itN2AaGjkc9cU2Z7s2Vq+Wuq/YsiaRdNI1hhSKflwVS17NltXTzMl73v1LBOlrEdvaR4z6sm6rDXUSoB2LctmoEV7CVATtGZF0lz62ar6soC6aqmxZokim846SoCbbpcqPfyz226WAB0y09lkpVhbAsyZMr8EMG/KXAmwVqUwmb3XVPRpa6iZfeCUakledcoHpai16dNUeC87ku6v9HQpqnOOedflhXfhsncdK9UPT1sp3Xek4rT323duNan26INsxjHn9enCrKs+VS3Vb7ZVO+87XTFjrLJ9Yx50WlNDG/edc25hL5BLySgM2qhSGDOTVR0x3mWHPkXJzCZZTU3WVDKv0GeHLsYdUc3CJa/naxs8r3XR+NLCUx7nCqM2yNe87pLIiZrj9jUXWw2zTALKcr5jSHPdbxxXSzKJL/zJoY4Ysam045bKwyYjOsIhh3yRWPAmXLA/nem3Q88TESH02KFf+tABFx58lh/0qnDCvnxr0PATthK0GDYo37LPCUXyCECi5m/GKveGfVNadi8kA4ZV7hnzd7XHmXnoeLjhrTTeY6evLzEz0G+nnkjj3nLj8f3akI/EGb917hnbdS4BdNpmE/9xwJnGwZaOnsQ7/mDmOUNaGhChxZDnmPF7R8u5WHx23XXQX1dUn7f+kRMh2WDUiqq/+KO7/hcg8ZkDTq31XasXRsdqe/RyygGfLb76lpyeiRP2u7jFTq2g1S5buGi/k0tvzuVv8rcdzLPbDGjSZMCIPOugt33ZFeKpOBy1y/FGvBGXI2pxOJ6KL61/gBiNqXpMxmTUI6Zi9CvJCVGJV4rrtahFcT1eicpXBBCiM16L6ZiO16LzyfL/AjzmtojnBFLlAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIzLTA1LTI1VDAwOjI5OjM3KzAwOjAwSlqgvwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMy0wNS0yNFQyMjo1Mjo1NCswMDowMDIBBRoAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAAElFTkSuQmCC", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAQAAAD+fOO3AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfnBRkAISsCR/pcAAAEXklEQVRIx5XVS2xdxR3H8c/MuX5g/CBGTQzkATIggQt1K7fNgzgI5YVDWmjaRdsdrRQhsa2666ISi6o0m6SLtu6CRYIS1Er0EdGYEKV1GwlbTaxGRYkCgWAiYuKH4kaxfX3PdOHg3HPttDBnNXPm9x39/vObmaCqJci0WGOzLb5orWb8xyVnnfQ3H5pWIVRpQkEe3OUrvq/Piko2G8shR1SXGvKsYtJRB/3TlBSWAhJ1HvFD39N+LUz40EVjptFipQes0a41mXBIv3eUQxGQuMNWP7Zp2rtO+YcrKov0JLPKRht0auHvfuZNN8ItQOIO3/KT9PCoYwaMiUV3EnIrbbPdauG8n/r9AiKQqNfn55UH3/GqIRXR8i2X+arvekR2wY8cNRcEUtTtV3nPv/3WiFhYubYluS/5gUfFYXudCXlMtHlRz6iD/1dOEI04aJQeL2pLojpP2HPNG4Zr5EmuoiJfyEcVYtgbrrHHE+pKmj2ft15wTF7lPUnu9LBVuOK864JbG5c7pkd3a3zeYMlDtkwbNCGrkke9drhXI2Zc9hd/lS8iogmDOrVt8VDJU6l5yqnC6tEe39CxKLjXal/wuwLilG9qbQ5PRZsr8QNXC8436KuSE3Tos6FQjas+UIk2R11z8X2panq9XvfV7EZwn171Vf3kfXNRV9QxH8YKYVnrnmWiFN1jrbxqZMx80BE1JLOFqS0al81Ao5ZCf1aiIcpDjeCG8rKAshs1wEAejWfaCm4/Nl6IzqfFHfdxoTJtMsajc/X5uoLXScOmlwCmDZss1Gad+ty56O26fJ3mqjUzJx03U5DPOO5kIWrN1qnLvR0NKN/t8SpAMOU1h723OPKew14zVWUgedzdlA2UnDHSuv5JQ8pVObviiBEPaMeEi86ZKWS13pNaGXGmZFJ/3dceixu9pVRViVmnnb55FsgK7iu2eExdrt9kNGfAiXa73F+ISZDJlJVlskL1c/fbpZ0TBsxFyWUvZ2NdntVUc/JvfdXbeafndMnGvOyyFAPzBu1ryHttY5kEFNPANr0aKn5h0HwQCVx32JG70k7d0v9AJEm3HdqSI464HrhZm+SS/eFsp11W3RaRJB2e0Sn8ywGXFqbFBbdyQ/ZlUxtt13hbQKPtNsqm7DMkDxYBBOb9SX/97E5fF5c9C9F6O9TN6vdn87cy82nNk6teCSc67Na5xEaSPGi3jhROeMXVsPi7Kh+Bs37pwpf1WbEEsMLTunnXAWert7Vw9QTe9BuTW/VqqEIkDXptZdKvHS9edrV314xD/tg096xHFyuRRF2e0zTnD16tOaa1gMCoA06v9R0rb3pnpW9bw2kHjNY+fUtuz8CQ/T7q8Ywm0GS3Hj6y3/DSl3P5l/x1h7Lpp61XUrLeTtm0Q173WVuSVqejaf5i2pv2pospzaejaXX6zPoFxKZ0vpKG0lCqpHQ+bfpccpJUSi/kn5RTOeWfpBdS6XMCSFJzeimNp/H0Umq+vfy/0JikOgfvvUIAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDUtMjVUMDA6Mjk6MzcrMDA6MDBKWqC/AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA1LTI0VDIyOjUzOjA1KzAwOjAwM1Rr9AAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAASUVORK5CYII=", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAApCAQAAAD+fOO3AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfnBRkAISsCR/pcAAADzElEQVRIx5WVTUxUVxiG33tnhmF0iJ0iCVF+NJpghTSUVNOoTTMrCS1qm4mJZVFSu+h048Jg2dCdSatb3TWkTaw2ISkbBY2waGBBJGmsoggkasEfyDhDsQjM33m6YGjnzgw4fmd1v++8z7nnnPecYykrkCSXylStD/WRGlQjv6RFTWtMv2tIM/pHacnK0lgOuaW31KQ2tSiQci3bcSstySUvPuNOa159+kV/6G9h5QOQPHpHX+lzvR21ZjWhO/pL85ICqtW7qlOlylFMl/WjxpXM/gtJCB+tDEOMQU6xEwtlNYudnGKQGMAwrfjIk7cxYRink20OaXbbRifjGJigLQuBKOEYU0mGacFeVy6ETQvDJGGKY5RkENg0MZpmiEMbitfaIYZIwyhN2KvjB+iG+xwuSi7EYe4DdBNAwkMrCy/owFU0wEUHL2CBVjwiQG+am1TkdSsjSDvtBCnLq1VwkzT0EhD7iUUI5y3WcfqZ5BnPmKSf43mLGyYCMfaLTpO4x/acXT/NQwxrYXjI6RxnbOceJkGnuJZI9eQUj/IgS76KeMDRnEF6SKS4Zqt+xR5Ttq88Cmm3nFa1tFsheRzmG9OKrXpblUlr2tG5TrvkUm64tEt1jsy0kpYqbXmNlh2Fcm1Wodiscsf3sozktWVsbXIUFhUvCIhr0fG9SbZkbEXdqnAUHuu5Y03W5vxcjx2ZCrmlqK0Jr9nrKER1XbE8QEzXFXVk9sprNGHrltfUa4uj1KNLeuXIvNIl9TgyW1Qvr9Et0czSU47k+KyaLm5nvGC4TRfVOT2O8BSWaLaoVG/8g9/0pVYcI/i0Tw2qlDSrMY3m7FSpuvWZvCP6VHg5SXqGUMFzV0JJwXyIGUhzEq+wqGEgyQB7ij7OexggCQPUYAnhppm5JS7gL0pexgWWYI5m3KzuMH6+JT3L1zmHqlCz+IY5SHEG///XqsUOrhgzSvA1CIsgoxjDZXZkvS4ImwPcSXKFmg0BNfxKEv7kAHbuy+ChnfkluihdV+7jO5Zhni/w5Jkdi62cNyuPCOEuKHcT4hFmhfNsxVJ+IBroh0EaCwLeYxAM/TSgdQLxCVNwscAdXcFFgCk+XlcuSZRyhtgC4ZyV8BFmAWJ0UKoNAaKKn4nfJ5j10LgIMg5xfqJqw/EziH2MwFVq/wPUchVghPdfK88g2niS5PuMtf38QBKe0FaUPGPtc7yMcAIPHk4QgZecy7JuEYgq+kjdpZFG7kKKviJmn4M4yGSKG9wgBZMcfCO5Vo0XNpEECUyEcObgviHCz1miRDm70ez/BYYI/lv2W3BZAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIzLTA1LTI1VDAwOjI5OjM3KzAwOjAwSlqgvwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMy0wNS0yNFQyMjo1MzoxNiswMDowMM4WcfcAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAAElFTkSuQmCC", - anchor : [0.5, 1] - } - ], - /** - * api icons used by drawing control with a good ratio ! - * - * @example - * image size : [43, 32] - * scale : 32 / Math.min(size[0], size[1]) = 1 - */ - drawing_api : [ - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACsAAAAgCAYAAACLmoEDAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH5wUZACIosGP4JQAABdtJREFUWMO1mFuMFFUax3/fqarp7ppLdzMDDCwmzAxegrIka7KLF2JkITFGE5NNfFAeNPuwGh8ML2rcbDYbXMNkszFmH7w8qYmYGB92jcuDwkYwQYzILEFmggODgDANc+menkvX0FXn24dqFJZuprrVf1KpTup85/zP/7uc77TQKv4KmNrvKoJHD0IWSAMuEKIEQIlZpsihGKAT+ENrS7otk3WBACHFejzuAjYDG4FeoAOYAwrAUTo5gOUQ9zLMAbTVJaUlq12A0IvyKMpjCL9JYHUI2I3wPsJFnvu5yQ7WbJRbgeeBRwE/ka0CwgLwPoZBLCewKC8mX77ZMBBgHbAT5RHATbxdARQfYTsWH+WPWE7VtpEITpOq5lFeALYjTRC9lrABbgUcDIf4LQH7kpmbZMO+39gW4Al+TGIKILjAk8AWJLlgyci+DCh5lGeIM/16KGCBCAhrb8uNnNwBPIUlz8vJyCZVyKD8Evh1XdfHyaN3rrqz8PC6h518Kp8rLhZLH45+GB0pHOlFkevs4pC4C2ED8CkJYjcZWcEA24BUPaKC2Idufmj6lS2vMJAbaCcOmfbH1z9e3rFvx9RHJz/qrksYUghbgc9q/lhCsaRkhfV140uhP98/89Lml2YHcgMrge/JrsuvW7lz887Z/lx/qa5ugoNwR02MJZE0wYT4ZLpeG4W12bWZDT0buuvMZzau2LisL9eXaeBkAVaSsN43k9XpRh88x3NFpO6CIpLyjNc445VMUgLNlK6ZRtpMLkzOFYPiZL3P08H05ERlYr6hdkIpab1OStYCo8QF6TqywxPD6Tf++4aNNJq9+lOk0ezrQ6/ryMRIpgGhCPimNv+SSFaQtyIo3cADtYJ+DdmqrbqHC4cz5cXyeF+ubz6yUaowXxgf/GKw/OpXr66euzyXakD2MvAmMMTepUtXMgfsQrD0IXyC0F93jILruJHv+bjiOqGG0UJ1gTAKnRusMlaT4lueX5ps0jBQhHFgN41cJhBGoVMOys50ZZpyUHaWIGpR3iXueRM1M8lbkV2AcgvC28CmxHaN8TnCEzd90PuNeymFsRBZg+NYrInPDz8I2Fwo8FrNIHnXtRfYRpm4KtxDfEFpDcq4qZjBNe+uGUrPeF0WsqJkVSVnjHaoSIdAyg1D/MhG4epfyB09XdJck7cLiJvtPwM7AK8Jglf6Aet/lz6wYt/yf7kLToCoq3E4Sm2AIhK3RUqIUjRwXIyOJlf2irpbqQInUW4HBuqe+PVQG+WVvNM9B5d9liq2CYYuFWkXET9+NH6rtovQAdKF0IPQH8Fcc2R/IDwDTAD3IOSTmprAlPJHs/s6T7VfqPW1KrHmtUfit4iCqIiqiIiiHqoXmyd7hfB9fIuLIb7VLh0OlrBjzD/YfTh/TFQ0mT9EUBUVuaAiXzRz3F6LEhHCWyj/RG9QemqapSdSI8u+yg1JJDYBUQGMQgAcNbDHpNPnW7+erAZmKOLzN4TbUH5Vl4SAM+dczA1lD3oz3kKd3QgIqrWtCRbVBeAkIieAc8VMZi5brTZRuv4fHwMPAB6XiJgHtiGkrsr6OL9DFrtGuv6THe4cE5UriRa7FzEgCBqCVIDzKhx2XfdTa+3xB8+cKZzM5S4vn59n5OzZFv/kuBqD4JScvPXtX9TVpxHcqwhH/tn0lyv29+x359wAE6eVqiIil4F5VYqCnhExoxFMqBBWpqai9nweHIdTY2PXxMaPhvesJ2TYEPrha+rp3T+UKff08gPde/xzmUk16gBVoCgil4BxETnnuO55lKq1IVE1UnUd/I4Ovj52rF5E/TTwXvCwrv1dlIn+gcMqsyiz+SO5Pfkj2eM4FIFxVL9TKPjp9MXK4mIgIjiex5pNm9j7zjtLrvGTkQXofLozXVlW+VOUin7vn8/sX7l/+W5TMacRnXJESufa2uZXBQGptjaGR0ebnr/1alAHYToM3JL7d+3W91KT6WK6nJ6qXjgT6NpeVJX7Jyf599RUy/P/D0pQLH84wUhqAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIzLTA1LTI1VDAwOjI4OjU5KzAwOjAwM8i5WwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMy0wNS0yNFQyMzowODoxNiswMDowMJo3/8cAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - }, - { - src : "data:image/png;base64,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", - anchor : [0.5, 1] - } - ] -}; - -export default MarkersOther; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Formats/GPX.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Formats/GPX.d.ts deleted file mode 100644 index 7b0d0bf55..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Formats/GPX.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -export default GPX; -/** - * @classdesc - * - * Extended Styles GPX format to export (internal use only !) - * - * SPEC - * cf. https://www.topografix.com/gpx.asp - * - * - * @constructor - * @alias ol.format.GPXExtended - * @extends {ol.format.GPX} - * @type {ol.format.GPXExtended} - * @param {Object} options - Options - * @param {Object} [options.defaultStyle] - Styles by default - * @param {String} [options.orderBy] - Sort by key the feature before writing. By default, no sorting - * @param {Object} [options.extensions] - Add properties to file root - * @param {function} [options.readExtensions] - Reading extensions (native) - */ -declare var GPX: ol.format.GPXExtended; -//# sourceMappingURL=GPX.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Formats/GPX.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Formats/GPX.d.ts.map deleted file mode 100644 index 268c1b16a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Formats/GPX.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"GPX.d.ts","sourceRoot":"","sources":["../../../../src/packages/Formats/GPX.js"],"names":[],"mappings":";AASA;;;;;;;;;;;;;;;;;;GAkBG;AACH,uCA2dE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Formats/GPX.js b/build/release/geoportal-extensions-openlayers/src/packages/Formats/GPX.js deleted file mode 100644 index f3813ad65..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Formats/GPX.js +++ /dev/null @@ -1,511 +0,0 @@ -// import openlayers -import olGPX from "ol/format/GPX"; -// import Geometry -import MultiLineString from "ol/geom/MultiLineString"; -import LineString from "ol/geom/LineString"; -// import local -import Styling from "./Styling"; -import Parser from "../Utils/Parser"; - -/** - * @classdesc - * - * Extended Styles GPX format to export (internal use only !) - * - * SPEC - * cf. https://www.topografix.com/gpx.asp - * - * - * @constructor - * @alias ol.format.GPXExtended - * @extends {ol.format.GPX} - * @type {ol.format.GPXExtended} - * @param {Object} options - Options - * @param {Object} [options.defaultStyle] - Styles by default - * @param {String} [options.orderBy] - Sort by key the feature before writing. By default, no sorting - * @param {Object} [options.extensions] - Add properties to file root - * @param {function} [options.readExtensions] - Reading extensions (native) - */ -var GPX = class GPX extends olGPX { - - /** - * See {@link ol.format.GPXExtended} - * @module GPXExtended - * @alias module:~Formats/GPXExtended - * @param {*} options - options - * @example - * import GPXExtended from "src/packages/Formats/GPX" - */ - constructor (options) { - super(options); - - if (!(this instanceof GPX)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this.options = options || {}; - - // INFO - // surcharge de la callback : readExtensions - if (this.options.readExtensions && typeof this.options.readExtensions === "function") { - var clbk = this.options.readExtensions; // callback definie par l'utilisateur - this.options.readExtensions = function (feature, node) { - this.readExtensions(feature, node); - clbk.call(this, feature, node); - }; - } else { - this.options.readExtensions = this.readExtensions; - } - - // INFO - // defaultStyle est un objet de type Style - if (this.options.defaultStyle === null || typeof this.options.defaultStyle === "undefined") { - this.options.defaultStyle = {}; - } - - this.source = null; - - return this; - } - - /** - * Read Extend Styles for Features. - * This function overloads ol.format.GPX.readFeatures ... - * - * @see ol.format.GPX.prototype.readFeatures - * @param {Document|Node} source - Source. - * @param {olx.format.ReadOptions=} options - options. - * @return {Array.} Features. - */ - readFeatures (source, options) { - // INFO - // le travail de lecture des extensions du format est porté - // par la callback des options : readExtensions - var features = super.readFeatures(source, options); - - // String ou Dom - if (typeof source === "string") { - this.source = Parser.parse(source); - } else if (source !== null) { - this.source = source; - } - - // INFO - // on applique les styles par defaut definis avec l'option defaultStyle - // sauf sur les features qui possèdent des extensions. - // les features avec extensions sont traité au préalable - // dans la callback des options : readExtensions - var self = this; - features.forEach(function (feature, index, array) { - feature.setId(index + 1); - // HACK : enregistrement de la description de la balise 'desc' du format GPX - var value = feature.getProperties().desc; - if (value) { - feature.setProperties({ - description : value - }); - } - var featureStyleFunction = feature.getStyleFunction(); - if (!featureStyleFunction) { - var styleFunction = Styling.defineStyleFunctionByDefault(self.options.defaultStyle); - if (styleFunction) { - feature.setStyle(styleFunction); - } - } - }); - return features; - } - - /** - * Write Extend Styles for Features. - * This function overloads ol.format.GPX.writeFeatures ... - * - * @see ol.format.GPX.prototype.writeFeatures - * @param {Object[]} features - Features. - * @param {Object} options - Options. - * - * @return {String} Result or null. - */ - writeFeatures (features, options) { - // INFO - // il n'est pas possible de surcharger les parsers d'OpenLayers (private), - // on decide de (re)parser la sortie d'OpenLayers afin d'y placer les balises - // d'extensions - - // on met à jour les properties de styles - features.forEach(function (feature, index, array) { - // HACK : enregistrement de la description dans la balise 'desc' du format GPX - var value = feature.getProperties().description; - if (value) { - feature.setProperties({ - desc : value - }); - } - - Styling.definePropertiesFromStyle(feature); - - // HACK : Le type surfacique n'existe pas au format GPX, - // on doit la transformer en un lineaire. - // Par contre, on garde un trace de la transformation : - // * le style surfacique - // * le type de geometrie initiale - var type = feature.getGeometry().getType(); - if (type === "Polygon") { - // creation d'une copie pour ne pas modifier les features de carte - var fp = feature.clone(); - fp.set("type", type); - fp.setGeometry(new LineString(feature.getGeometry().getCoordinates())); - features.push(fp); - // feature à supprimer de l'export - array.splice(index, 1); - } else if (type === "MultiPolygon") { - // creation d'une copie pour ne pas modifier les features de carte - var fm = feature.clone(); - fm.set("type", type); - fm.setGeometry(new MultiLineString(feature.getGeometry().getCoordinates())); - features.push(fm); - // feature à supprimer de l'export - array.splice(index, 1); - } - }); - - // tri des features en fonction de la balise "number" || "id" || "order" - if (this.options.orderBy !== undefined) { - var key = this.options.orderBy; - if (key) { - var sortFct = function (a, b) { - var cmpA = a.get(key) || 0; - var cmpB = b.get(key) || 0; - return cmpA.toString().localeCompare(cmpB.toString(), undefined, { numeric : true }); - }; - features.sort(sortFct); - } - } - - // nodes - var gpxNode = super.writeFeaturesNode(features, options); - if (gpxNode === null) { - return null; - } - - // on ajoute les extensions à la racine pour les metadonnées de calcul - if (this.options.hasOwnProperty("extensions")) { - this.writeRootExtensions_(gpxNode, this.options.extensions); - } - - // INFO - // à chaque fois qu'un style est trouvé dans un feature, - // on appelle la fonction d'insertion des balises extensions dans le DOM. - this.processExtensions_(gpxNode, features, { - extensions : this.writeExtensions_ - }); - - // dom -> string - var gpxStringExtended = Parser.toString(gpxNode); - if (!gpxStringExtended) { - return null; - } - - // format string - var gpxStringFormatted = Parser.format(gpxStringExtended); - if (gpxStringFormatted === "") { - return null; - } - - return gpxStringFormatted; - } - - /** - * Callback to read extensions from options : readExtensions - * - * @param {*} feature - ... - * @param {*} node - ... - */ - readExtensions (feature, node) { - var _node = node; - // recherche de la properties de type Node ou Element - // si le node n'est pas renseigné... - if (!node) { - var props = feature.getProperties(); - for (const key in props) { - if (Object.hasOwnProperty.call(props, key)) { - const element = props[key]; - if (element instanceof Node) { - _node = element; - break; - } - } - } - } - - if (!_node) { - // eslint-disable-next-line no-console - console.warn("node not found !"); - return; - } - - // ex. de nodes : - // - // medium - // - // #ffffff - // - for (var index = 0; index < _node.childNodes.length; index++) { - var element = _node.childNodes[index]; - if (element.nodeType === 1) { - feature.set(element.nodeName, element.textContent); - } - } - - // cas particulier du format GPX : - // il n'existe pas de surfacique sur ce format, mais il est possible de forcer - // la transformation en polygone pour des besoins particuliers de visualisation - Styling.APPLY_CONVERT_GEOM_GPX = true; - var style = Styling.defineStyleFromProperties(feature); - if (style) { - feature.setStyle(style); - } - } - - /** - * ... - * @param {*} key ... - * @returns {Object} json - * @todo - */ - readRootExtensions (key) { - var value = {}; - // Rechercher : - // - // - // {...} - // - // - - var firstNodeLevelGpx = this.source.childNodes[0]; // gpx - var searchChildNodesMeta = firstNodeLevelGpx.childNodes; // search metadata - for (var k = 0; k < searchChildNodesMeta.length; k++) { - var nodeMeta = searchChildNodesMeta[k]; - if (nodeMeta.nodeName === "metadata") { - var searchChildNodesExt = nodeMeta.childNodes; // search extensions - for (var i = 0; i < searchChildNodesExt.length; i++) { - var nodeExt = searchChildNodesExt[i]; - if (nodeExt.nodeName === "extensions") { - var searchChildNodesData = nodeExt.childNodes; // search data - for (var j = 0; j < searchChildNodesData.length; j++) { - var nodeData = searchChildNodesData[j]; - if (nodeData.nodeName === "data") { - var name = nodeData.attributes[0]; - if (name && name.nodeName === "name") { - if (name.nodeValue === key) { - value = JSON.parse(nodeData.textContent); - break; - } - } - } - } - } - } - } - } - return value; - } - - /** - * ... - * - * @param {*} doc - ... - * @param {*} extensions - ... - * @param {Boolean} [xml=false] - write tag xml or json - */ - writeRootExtensions_ (doc, extensions, xml) { - // TODO namespace ? - var metadata = document.createElement("metadata"); - var extensionsRoot = document.createElement("extensions"); - // INFO - // convert JSON to XML (dom) - // * type string : - // { typestring: "string" } -> string - // - // * type object : - // { typeobject: { typestring1: "string", typestring2: "string" } } - // -> - // string - // string - // - // - // * type array : - // { typearray : ["item1", "item2"] } - // -> - // item1 - // item2 - // - // - // * type array of array - // -> - // - // 1 - // 2 - // - // - // - // * type array of object - // -> - // - // string - // string - // - // - // string - // string - // - // - function toDOM (node, json) { - for (const key in json) { - if (Object.hasOwnProperty.call(json, key)) { - var element = json[key] || ""; // au cas où... - var tag = document.createElement(key); - // eslint-disable-next-line valid-typeof - if (typeof element === "string" || typeof element === "number") { - tag.innerHTML = element; - node.appendChild(tag); - } else if (element instanceof Array) { - tag.setAttribute("type", "array"); - tag.setAttribute("index", element.length); - for (let index = 0; index < element.length; index++) { - var item = element[index] || ""; // au cas où... - var n = document.createElement("value"); - if (typeof item === "string" || typeof item === "number") { - n.innerHTML = item; - tag.appendChild(n); - } else if (item instanceof Array) { - n.setAttribute("type", "array"); - n.setAttribute("index", item.length); - for (let i = 0; i < item.length; i++) { - var value = item[i] || ""; // au cas où... - var k = document.createElement("value"); - if (typeof value === "string" || typeof value === "number") { - k.innerHTML = value; - n.appendChild(k); - } - } - tag.appendChild(n); - } else if (item instanceof Object) { - tag.appendChild(toDOM(n, item)); - } else { - // "Unknown element !" - } - } - node.appendChild(tag); - } else if (element instanceof Object) { - node.appendChild(toDOM(tag, element)); - } else { - // "Unknown element !" - } - } - } - return node; - } - - if (xml) { - // structure xml - toDOM(extensionsRoot, extensions); - } else { - // structure json par defaut - // ex. - // - // - // {...} - // - // - for (const key in extensions) { - if (Object.hasOwnProperty.call(extensions, key)) { - const value = extensions[key]; - var dataElement = document.createElement("data"); - dataElement.setAttribute("name", key); - var data = document.createTextNode(JSON.stringify(value)); - dataElement.appendChild(data); - extensionsRoot.appendChild(dataElement); - } - } - } - metadata.appendChild(extensionsRoot); - // insertion en 1ere place ! - var firstChild = doc.firstChild; - doc.insertBefore(metadata, firstChild); - } - - /** - * ... - * - * @param {Object} feature - ... - * @param {DOMElement} node - ... - * @private - */ - writeExtensions_ (feature, node) { - // creation du DOM - var extensionsNode = document.createElementNS(node.parentNode.namespaceURI, "extensions"); - Styling.getListTags().forEach(key => { - if (feature.get(key)) { - var extension = document.createElementNS(node.parentNode.namespaceURI, key); - extension.innerHTML = feature.get(key); - extensionsNode.appendChild(extension); - } - }); - node.appendChild(extensionsNode); - } - - /** - * ... - * - * @param {DOMElement} doc - ... - * @param {Object} features - ... - * @param {Object} actions - ... - * @private - */ - processExtensions_ (doc, features, actions) { - // INFO - // OpenLayers ne gère pas tous les tags du format GPX : ex. metadata - // Liste des tags : - // * wpt - // * rte - // * trk - // On peut y placer nos balises extensions. - - var index = -1; - var nodes = doc.childNodes; - for (var i = 0; i < nodes.length; i++) { - var node = nodes[i]; - switch (node.nodeName) { - case "wpt": - case "rte": - case "trk": - index++; - var feature = features[index]; - var style = feature.getStyle(); - if (style) { - var fct = actions.extensions; - if (fct && typeof fct === "function") { - fct(feature, node); - } - } - break; - case "metadata": - break; - default: - // on ne devrait jamais passer à ce niveau !? - // eslint-disable-next-line no-console - console.warn("nodename unknown :", node.nodeName); - break; - } - } - } - -}; - -export default GPX; - -// Expose GPX as ol.source.GPXExtended. (for a build bundle) -if (window.ol && window.ol.format) { - window.ol.format.GPXExtended = GPX; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Formats/GeoJSON.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Formats/GeoJSON.d.ts deleted file mode 100644 index d4b42e106..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Formats/GeoJSON.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -export default GeoJSON; -/** - * @classdesc - * - * Extended Styles GeoJSON format to export (internal use only !) - * - * SPEC - * cf. https://github.com/mapbox/simplestyle-spec/ - * cf. https://geojson.org/ - * - * - * @constructor - * @alias ol.format.GeoJSONExtended - * @extends {ol.format.GeoJSON} - * @type {ol.format.GeoJSONExtended} - * @param {Object} options - Options - * @param {Object} [options.defaultStyle] - Styles by default - * @param {Object} [options.extensions] - Add properties to file root - */ -declare var GeoJSON: ol.format.GeoJSONExtended; -//# sourceMappingURL=GeoJSON.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Formats/GeoJSON.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Formats/GeoJSON.d.ts.map deleted file mode 100644 index 3a8c9b571..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Formats/GeoJSON.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"GeoJSON.d.ts","sourceRoot":"","sources":["../../../../src/packages/Formats/GeoJSON.js"],"names":[],"mappings":";AAKA;;;;;;;;;;;;;;;;;GAiBG;AACH,+CAuHE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Formats/GeoJSON.js b/build/release/geoportal-extensions-openlayers/src/packages/Formats/GeoJSON.js deleted file mode 100644 index 0f88ebbf4..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Formats/GeoJSON.js +++ /dev/null @@ -1,150 +0,0 @@ -// import openlayers -import olGeoJSON from "ol/format/GeoJSON"; -// import local -import Styling from "./Styling"; - -/** - * @classdesc - * - * Extended Styles GeoJSON format to export (internal use only !) - * - * SPEC - * cf. https://github.com/mapbox/simplestyle-spec/ - * cf. https://geojson.org/ - * - * - * @constructor - * @alias ol.format.GeoJSONExtended - * @extends {ol.format.GeoJSON} - * @type {ol.format.GeoJSONExtended} - * @param {Object} options - Options - * @param {Object} [options.defaultStyle] - Styles by default - * @param {Object} [options.extensions] - Add properties to file root - */ -var GeoJSON = class GeoJSON extends olGeoJSON { - - /** - * See {@link ol.format.GeoJSONExtended} - * @module GeoJSONExtended - * @alias module:~Formats/GeoJSONExtended - * @param {*} options - options - * @example - * import GeoJSONExtended from "src/OpenLayers/Formats/GeoJSON" - */ - constructor (options) { - super(options); - - if (!(this instanceof GeoJSON)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - this.options = options || {}; - - // INFO - // defaultStyle est un objet de type Style - if (this.options.defaultStyle === null || typeof this.options.defaultStyle === "undefined") { - this.options.defaultStyle = {}; - } - - this.source = null; - - return this; - } - - /** - * Read Extend Styles for Features. - * This function overloads ol.format.GeoJSON.readFeatures ... - * - * @see ol.format.GeoJSON.prototype.readFeatures - * @param {Object|String} source - Source. - * @param {olx.format.ReadOptions} [options] - Options. - * @return {Array.} Features. - */ - readFeatures (source, options) { - var features = super.readFeatures(source, options); - - // String ou Object - if (typeof source === "string") { - this.source = JSON.parse(source); - } else if (source !== null) { - this.source = source; - } - - features.forEach((feature) => { - var featureStyleFunction = feature.getStyleFunction(); - // existe t il déjà une fonction de style ? - // si oui, on l'applique ! - if (featureStyleFunction) { - var styles = featureStyleFunction.call(this, feature, 0); - if (styles && styles.length !== 0) { - feature.setStyle(styles[0]); - } - } else { - // à ce niveau, il n'existe pas de styles, donc : - // soit, on applique les styles par defaut - // soit, on prend en compte les styles definis dans les properties / tag du fichier - // les styles définis ecrasent les styles par defaut... - var style = Styling.defineStyleFromProperties(feature); - if (style) { - feature.setStyle(style); - } else { - // si aucun style disponible, on utilisera le style par defaut defini - // par l'utilisateur ou l'application - var styleFunction = Styling.defineStyleFunctionByDefault(this.options.defaultStyle); - if (styleFunction) { - feature.setStyle(styleFunction); - Styling.definePropertiesFromStyle(feature); - } - } - } - }); - - return features; - } - - /** - * Write Extend Styles for Features. - * This function overloads ol.format.GeoJSON.writeFeatures ... - * - * @see ol.format.GeoJSON.prototype.writeFeatures - * @param {Array.} features - Features. - * @param {Object} [options] - Options. - * - * @return {String} Result. - */ - writeFeatures (features, options) { - // on met à jour les properties de styles - features.forEach(function (feature) { - Styling.definePropertiesFromStyle(feature); - }); - - var geoJSONObject = this.writeFeaturesObject(features, options); - - // ajout des properties à la racine du fichier - // ex. options : { - // extensions : { /* liste des objets à ajouter */ } - // } - if (this.options.hasOwnProperty("extensions")) { - Object.assign(geoJSONObject, this.options.extensions); - } - - return JSON.stringify(geoJSONObject); - } - - /** - * ... - * @param {*} key ... - * @returns {Object} json - */ - readRootExtensions (key) { - return this.source[key]; - } - -}; - -export default GeoJSON; - -// Expose GeoJSON as ol.source.GeoJSONExtended. (for a build bundle) -if (window.ol && window.ol.format) { - window.ol.format.GeoJSONExtended = GeoJSON; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Formats/KML.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Formats/KML.d.ts deleted file mode 100644 index 4deffe7f2..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Formats/KML.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -export default KML; -/** - * @classdesc - * - * Extended Styles KML format to export (internal use only !) - * - * INFO - * only ol.Control is a user-extendable class. - * Everything else requires integration with the original openlayers source and a new ol.js - * to be built with your new classes incorporated. - * - * SPEC - * cf. https://developers.google.com/kml/forum/advanced - * - * ISSUES - * cf. https://github.com/openlayers/openlayers/issues/4829 - * cf. https://github.com/openlayers/openlayers/issues/4460 - * cf. https://github.com/openlayers/openlayers/pull/5590 - * cf. https://github.com/openlayers/openlayers/issues/5229 - * cf. https://github.com/openlayers/openlayers/issues/3371 - * - * @constructor - * @alias ol.format.KMLExtended - * @type {ol.format.KMLExtended} - * @extends {ol.format.KML} - * @param {Object} options - Options - * @param {Object} [options.extensions] - Add properties to file root - */ -declare var KML: ol.format.KMLExtended; -//# sourceMappingURL=KML.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Formats/KML.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Formats/KML.d.ts.map deleted file mode 100644 index d3291ab38..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Formats/KML.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"KML.d.ts","sourceRoot":"","sources":["../../../../src/packages/Formats/KML.js"],"names":[],"mappings":";AAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,uCA8uCE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Formats/KML.js b/build/release/geoportal-extensions-openlayers/src/packages/Formats/KML.js deleted file mode 100644 index 47b2b0f5c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Formats/KML.js +++ /dev/null @@ -1,1316 +0,0 @@ -// import openlayers -import olKML from "ol/format/KML"; -import { - Fill, - Icon, - Stroke, - Style, - Text, - Circle -} from "ol/style"; -// import local -import Styling from "./Styling"; -import Color from "../Utils/ColorUtils"; -import Logger from "../Utils/LoggerByDefault"; -import Parser from "../Utils/Parser"; -import Utils from "../Utils/Helper"; - -var logger = Logger.getLogger("extended KML format"); - -/** - * @classdesc - * - * Extended Styles KML format to export (internal use only !) - * - * INFO - * only ol.Control is a user-extendable class. - * Everything else requires integration with the original openlayers source and a new ol.js - * to be built with your new classes incorporated. - * - * SPEC - * cf. https://developers.google.com/kml/forum/advanced - * - * ISSUES - * cf. https://github.com/openlayers/openlayers/issues/4829 - * cf. https://github.com/openlayers/openlayers/issues/4460 - * cf. https://github.com/openlayers/openlayers/pull/5590 - * cf. https://github.com/openlayers/openlayers/issues/5229 - * cf. https://github.com/openlayers/openlayers/issues/3371 - * - * @constructor - * @alias ol.format.KMLExtended - * @type {ol.format.KMLExtended} - * @extends {ol.format.KML} - * @param {Object} options - Options - * @param {Object} [options.extensions] - Add properties to file root - */ -var KML = class KML extends olKML { - - /** - * See {@link ol.format.KMLExtended} - * @module KMLExtended - * @alias module:~Formats/KMLExtended - * @param {*} options - options - * @example - * import KMLExtended from "src/packages/Formats/KML" - */ - constructor (options) { - super(options); - - if (!(this instanceof KML)) { - throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - } - - options = options || {}; - - // INFO - // source DOM (Document ou Node) - this.source = null; - - // INFO - // gestion des extensions - this.extensions = options.extensions || null; - - // INFO - // defaultStyle est un tableau d'objet de type Style - if (options.defaultStyle && !Array.isArray(options.defaultStyle)) { - options.defaultStyle = [options.defaultStyle]; - } - - if (options.defaultStyle === null || typeof options.defaultStyle === "undefined") { - options.defaultStyle = []; - } - - return this; - } - - /** - * - * En lecture, on surcharge la méthode readFeatures. - * ✔️ In : kml string + features du format original - * ✔️ Out : features étendus avec des styles, et des metadatas (name ou extendData) - * > on modifie les features du format original avec les fonctionnalités non gérées. - * - * En écriture, on surcharge la méthode writeFearures. - * ✔️ In : kml du format original + features étendus - * ✔️ Out : kml étendu avec des styles, et des metadatas (name ou extendData) - * > on modifie le kml généré par le format original avec les fonctionnalités que nous avons ajoutées aux features. - * - * Le principe - * On parse le kml, et on lit (get) ou on ajoute (set) des fonctionnalités. - * - * Les getters vont lire le kml (ex. LabelExtendStyle), et ajouter le style ainsi que le nom du label dans le feature original. - * getLabelIconStyle (appel des 2 fonctions suivantes) - * getLabelExtendStyle (New) - * getHotSpotIconStyle (Bug sur la lecture du hotspot) - * getExtendData (New) - * - * Les setters vont écrire dans le dom du kml original les fonctionnalités ajoutées dans les features. - * setLabelExtendStyle (New) - * setHotSpotIconStyle (Bug sur l'écriture du hotspot) - * setNameData (Bug suppression de cette balise du format par défaut). - * - */ - - /** - * Fonction de lecture du KML avec fonction de traitement en fonction du type - * PlaceMark (Label ou Marker). - * Les traitements sont de 2 types : - * - creation de styles étendus ou correctifs sur le KML - * - ajout de styles étendus sur les features - * - * @param {DOMElement} kmlNode - kml nodes - * @param {Object[]} features - features - * @param {Object} process - process - * - * @example - * // ajoute des fonctionnalités dans le KML - * _processKml(kmlDoc, { - * labelStyle : createStyleLabel, - * iconStyle : createStyleIcon - * }); - * - * // lit des fonctionnalités du KML non impl. par OpenLayers - * _processKml(kmlNode, { - * labelStyle : getStyleToFeatureLabel, - * iconStyle : getStyleToFeatureIcon, - * extendedData : getExtendedData - * }); - */ - _processKml (kmlNode, features, process) { - var firstNodeLevel = (kmlNode.nodeName === "#document") ? kmlNode.childNodes[0].childNodes : kmlNode.childNodes; - - // Si le DOM contient un seul objet, le noeud est directement un PlaceMark - // sinon, c'est un ensemble de noeuds PlaceMark contenus dans le noeud Document. - var nodes = firstNodeLevel; - for (var ik = 0; ik < firstNodeLevel.length; ik++) { - const element = firstNodeLevel[ik]; - if (element.nodeName === "Document") { - nodes = element.childNodes; - break; - } - if (element.nodeName === "Placemark") { - nodes = [element]; - break; - } - } - - // On recherche les PlaceMark de type Point ayant un Style... - // Le style peut être placé directement dans le PlaceMark - // ou lié avec un id (share) - var stylesUrl = {}; // listes des styles - var index = -1; // index du features... - for (var i = 0; i < nodes.length; i++) { - var node = nodes[i]; - switch (node.nodeName) { - case "Style": - // INFO - // pour le traitement des balises Styles liées avec styleUrl, - // elles doivent être toujours déclarées avant les PlaceMark ! - // On ne prend en compte que celles qui sont identifiées via un ID ! - var id = node.attributes[0]; - if (id && id.nodeName === "id") { - var _k = id.nodeValue; - var _v = node; - stylesUrl[_k] = _v; - } - break; - - case "Placemark": - - index++; - var types = node.childNodes; // Point, LineString, Polygon, Style, ... - var point = false; - var line = false; - var poly = false; - var domStyles = null; // dom - var hdlDomStyle = null; // dom - var domExtendedData = null; // dom - var domNameTag = node; // dom - for (var j = 0; j < types.length; j++) { - switch (types[j].nodeName) { - case "Polygon": - poly = true; - break; - case "LineString": - line = true; - break; - case "Point": - point = true; - break; - case "Style": - hdlDomStyle = types[j]; - domStyles = types[j].childNodes; // liste de styles - break; - case "styleUrl": - // style avec lien vers... - var _idStyle = types[j].textContent.slice(1); - if (stylesUrl[_idStyle]) { - domStyles = stylesUrl[_idStyle].childNodes; - } - break; - case "ExtendedData": - domExtendedData = types[j].childNodes; - break; - case "name": - domNameTag = null; - break; - default: - // on ne traite pas les autres informations ... - // car elles seront gérées par defaut par le format standard... - } - } - - // On traite les balises kml:extendedData pour tous les objets ! - if (domExtendedData) { - logger.log("ExtendedData :", domExtendedData); - var fctExtend = process.extendedData; - if (fctExtend && typeof fctExtend === "function") { - fctExtend(features[index], domExtendedData); - } - } - - // On traite la balise kml:name - if (domNameTag) { - logger.log("Name :", domNameTag); - var fctName = process.nameData; - if (fctName && typeof fctName === "function") { - fctName(features[index], domNameTag); - } - } - - // On a un Marker avec un Style. - // Il peut être associé avec un Label ! - // Les markers sans styles ne doivent pas être gérées par les styles par defaut - // car le KML met en place une punaise google ! - if (point && domStyles && domStyles.length !== 0) { - var labelStyleDom = null; - var iconStyleDom = null; - // On recherche le type de Style - for (var k = 0; k < domStyles.length; k++) { - switch (domStyles[k].nodeName) { - case "LabelStyle": - labelStyleDom = domStyles[k]; - break; - case "IconStyle": - iconStyleDom = domStyles[k]; - break; - default: - // on ne traite pas les autres informations ... - } - } - - // Pour un label, il nous faut un titre ! - var labelName = features[index].getProperties().name; - var labelDescription = features[index].getProperties().description; - var value = labelName || labelDescription; - logger.trace(value); - - // C'est uniquement un Label ! - if (!iconStyleDom && labelStyleDom) { - var fctLabel = process.labelStyle; - if (fctLabel && typeof fctLabel === "function") { - fctLabel(features[index], labelStyleDom); - } - // C'est uniquement un marker ! - } else if (iconStyleDom && !labelStyleDom) { - var fctIcon = process.iconStyle; - if (fctIcon && typeof fctIcon === "function") { - fctIcon(features[index], iconStyleDom); - } - // C'est un marker avec un label ! - } else if (iconStyleDom && labelStyleDom) { - var fctIconLabel = process.iconLabelStyle; - if (fctIconLabel && typeof fctIconLabel === "function") { - fctIconLabel(features[index], iconStyleDom, labelStyleDom); - } - } else { - // ... - } - } else { - var feature = features[index]; - var style = feature.getStyle(); - if (style && typeof style === "function") { - var fstyles = style.call(this, feature, 0); - if (fstyles && fstyles.length !== 0) { - style = fstyles[0]; - } - } - - if (poly) { - var fctPoly = process.polygonStyle; - if (fctPoly && typeof fctPoly === "function") { - fctPoly(features[index], domStyles); - } - } - - if (line) { - var fctLine = process.lineStringStyle; - if (fctLine && typeof fctLine === "function") { - fctLine(features[index], domStyles); - } - } - - // INFO - // On est sur un Point mais sans style dans le DOM. - // On regarde le style dans le Feature : Icon ou Circle ? - if (point && style) { - var image = style.getImage(); - if (image && image instanceof Circle) { - var fctCircle = process.circleStyle; - if (fctCircle && typeof fctCircle === "function") { - fctCircle(features[index], hdlDomStyle); - } - } else if (image && image instanceof Icon) { - var fctPoint = process.pointStyle; - if (fctPoint && typeof fctPoint === "function") { - fctPoint(features[index], hdlDomStyle); - } - } else { - // ... - } - } - } - break; - default: - logger.trace("tag is not processing !"); - } - } - } - - /** - * Write Extend for Features. - * This function overloads ol.format.KML.writeFeatures ... - * - * @see ol.format.KML.prototype.writeFeatures - * @param {Object[]} features - Features. - * @param {Object} options - Options. - * - * @return {String} kml string formatted - */ - writeFeatures (features, options) { - logger.log("overload : ol.format.KML.writeFeatures"); - var kmlNode = super.writeFeaturesNode(features, options); - if (kmlNode === null) { - return null; - } - - // on ajoute les extensions à la racine pour les metadonnées de calcul - if (this.hasOwnProperty("extensions")) { - this._writeRootExtensions(kmlNode, this.extensions); - } - - // On ajoute les styles étendus - var kmlStringExtended = this._writeExtendStylesFeatures(kmlNode, features, options); - - // On realise un formattage du KML - var kmlStringFormatted = Parser.format(kmlStringExtended); - if (kmlStringFormatted === "") { - return null; - } - - return kmlStringFormatted; - }; - - /** - * Write Extended Styles for each features - * - * @param {DOMElement} kmlNode - kml nodes - * @param {Object[]} features - features - * @param {Object} options - options - * - * @returns {String} kml string extended - * - * @private - */ - _writeExtendStylesFeatures (kmlNode, features, options) { - // RGB Colors (RRGGBB) To KML Colors (AABBGGRR) - function __convertRGBColorsToKML (data, opacity) { - var strColor = data.toString(16); - - if (strColor.charAt(0) === "#") { - strColor = strColor.slice(1); - } - - opacity = opacity || 1; - opacity = parseInt(opacity * 255, 10); - opacity = opacity.toString(16); - var color = opacity; - color = color + strColor.substr(4, 2); - color = color + strColor.substr(2, 2); - color = color + strColor.substr(0, 2); - return color.toLowerCase(); - } - - /** - * C'est un Label ! - * On va donc y ajouter qq styles sur le Label (police, halo, ...) : - * Insertion : PlaceMark>Style>LabelStyle - * - * @param {Object} feature - feature - * @param {DOMElement} node - node - * - * @example - * - */ - var __createExtendedStyleLabel = function (feature, node) { - logger.trace("label with style :", node); - - if (!feature) { - return; - } - - // Si pas de style defini, c'est donc que l'on va utiliser celui par defaut... - if (feature.getStyle() instanceof Style) { - var textStyle = feature.getStyle().getText(); - if (!textStyle) { - return; - } - - var _fontFamily = "Sans"; - var _fontSize = "16px"; - var _font = textStyle.getFont(); - if (_font) { - var splits = _font.split(" ", 2); - _fontSize = splits[0]; - _fontFamily = splits[1]; - } - - var strokeTextStyle = feature.getStyle().getText().getStroke(); - if (!strokeTextStyle) { - return; - } - if (strokeTextStyle instanceof Stroke) { - var _haloColor = __convertRGBColorsToKML("#FFFFFF"); // Par defaut - var color = strokeTextStyle.getColor(); - // array ? - if (Array.isArray(color)) { - var cf = "rgba("; - cf += color[0] + ","; - cf += color[1] + ","; - cf += color[2] + ","; - cf += color[3] + ")"; - color = cf; - } - if (Color.isRGB(color)) { - var colorHex = Color.rgbaToHex(color); - _haloColor = __convertRGBColorsToKML(colorHex.hex, colorHex.opacity); - } else { - _haloColor = __convertRGBColorsToKML(color); - } - var _haloRadius = strokeTextStyle.getWidth() || "0"; - var _haloOpacity = "1"; // TODO lire param - - if (node && node.getElementsByTagName("LabelStyleSimpleExtensionGroup").length === 0) { - var labelExtended = document.createElementNS(kmlNode.namespaceURI, "LabelStyleSimpleExtensionGroup"); - labelExtended.setAttribute("fontSize", _fontSize); - labelExtended.setAttribute("fontFamily", _fontFamily); - labelExtended.setAttribute("haloColor", _haloColor); - labelExtended.setAttribute("haloRadius", _haloRadius); - labelExtended.setAttribute("haloOpacity", _haloOpacity); - node.appendChild(labelExtended); - } - } - - var fImageStyle = feature.getStyle().getImage(); - if (!fImageStyle) { - return; - } - if (fImageStyle instanceof Circle) { - var strokeColor = null; - var strokeWidth = null; - if (fImageStyle.getStroke()) { - strokeWidth = fImageStyle.getStroke().getWidth(); - strokeColor = fImageStyle.getStroke().getColor(); - // array ? - if (Array.isArray(strokeColor)) { - var cfs = "rgba("; - cfs += strokeColor[0] + ","; - cfs += strokeColor[1] + ","; - cfs += strokeColor[2] + ","; - cfs += strokeColor[3] + ")"; - strokeColor = cfs; - } - if (Color.isRGB(strokeColor)) { - var strokeColorHex = Color.rgbaToHex(strokeColor); - strokeColor = __convertRGBColorsToKML(strokeColorHex.hex, strokeColorHex.opacity); - } else { - strokeColor = __convertRGBColorsToKML(strokeColor); - } - } - - var fillColor = null; - if (fImageStyle.getFill()) { - fillColor = fImageStyle.getFill().getColor(); - // array ? - if (Array.isArray(fillColor)) { - var cff = "rgba("; - cff += fillColor[0] + ","; - cff += fillColor[1] + ","; - cff += fillColor[2] + ","; - cff += fillColor[3] + ")"; - fillColor = cff; - } - if (Color.isRGB(fillColor)) { - var fillColorHex = Color.rgbaToHex(fillColor); - fillColor = __convertRGBColorsToKML(fillColorHex.hex, fillColorHex.opacity); - } else { - fillColor = __convertRGBColorsToKML(fillColor); - } - } - - if (node && node.getElementsByTagName("ObjectSimpleExtensionGroup").length === 0) { - var iconExtended = document.createElementNS(kmlNode.namespaceURI, "ObjectSimpleExtensionGroup"); - iconExtended.setAttribute("type", "circle"); // FIXME type circle only ! - iconExtended.setAttribute("radius", fImageStyle.getRadius()); - iconExtended.setAttribute("fillColor", fillColor); - iconExtended.setAttribute("strokeColor", strokeColor); - iconExtended.setAttribute("strokeWidth", strokeWidth); - node.appendChild(iconExtended); - } - } - } - }; - - /** - * C'est un marker ! - * On va donc ajouter la balise hotspot : - * Traiter le cas où les unités sont de type - * - FRACTION - * - PIXELS - * Insertion du correctif dans le noeud : - */ - var __createExtendedStyleIcon = function (feature, node) { - logger.trace("marker with style (hotspot):", node); - - if (!feature) { - return; - } - - // Si pas de style defini, c'est donc que l'on va utiliser celui par defaut... - if (feature.getStyle() instanceof Style) { - var fImageStyle = feature.getStyle().getImage(); - - if (!fImageStyle) { - return; - } - - if (fImageStyle instanceof Icon) { - var x = 0; - var y = 0; - var xunits = "pixels"; - var yunits = "pixels"; - - var size = fImageStyle.getSize(); - var anchor = fImageStyle.getAnchor(); // pixels ! but anchor_ in the current unit ! - - if (anchor.length) { - x = anchor[0]; - y = anchor[1]; - if (yunits === "fraction") { - y = (y === 1) ? 0 : 1 - y; // cf. fixme contribution à faire ! - } else { - y = (yunits === "pixels" && y === size[1]) ? 0 : size[1] - y; // cf. fixme contribution à faire ! - } - } - - if (node && node.getElementsByTagName("hotSpot").length === 0) { - var hotspot = document.createElementNS(kmlNode.namespaceURI, "hotSpot"); - hotspot.setAttribute("x", x); - hotspot.setAttribute("y", y); - hotspot.setAttribute("xunits", xunits); - hotspot.setAttribute("yunits", yunits); - node.appendChild(hotspot); - } - } - } - }; - - /** - * ... - * @param {*} feature - feature - * @param {DOMElement} node - node - */ - var __createExtendedStyleToCircle = function (feature, node) { - if (!feature) { - return; - } - - // Si pas de style defini, c'est donc que l'on va utiliser celui par defaut... - if (feature.getStyle() instanceof Style) { - var fImageStyle = feature.getStyle().getImage(); - if (!fImageStyle) { - return; - } - if (fImageStyle instanceof Circle) { - var strokeColor = null; - var strokeWidth = null; - if (fImageStyle.getStroke()) { - strokeWidth = fImageStyle.getStroke().getWidth(); - strokeColor = fImageStyle.getStroke().getColor(); - // array ? - if (Array.isArray(strokeColor)) { - var cf = "rgba("; - cf += strokeColor[0] + ","; - cf += strokeColor[1] + ","; - cf += strokeColor[2] + ","; - cf += strokeColor[3] + ")"; - strokeColor = cf; - } - if (Color.isRGB(strokeColor)) { - var colorHex = Color.rgbaToHex(strokeColor); - strokeColor = __convertRGBColorsToKML(colorHex.hex, colorHex.opacity); - } else { - strokeColor = __convertRGBColorsToKML(strokeColor); - } - } - - var fillColor = null; - if (fImageStyle.getFill()) { - fillColor = fImageStyle.getFill().getColor(); - // array ? - if (Array.isArray(fillColor)) { - var cfi = "rgba("; - cfi += fillColor[0] + ","; - cfi += fillColor[1] + ","; - cfi += fillColor[2] + ","; - cfi += fillColor[3] + ")"; - fillColor = cfi; - } - if (Color.isRGB(fillColor)) { - var fillColorImgHex = Color.rgbaToHex(fillColor); - fillColor = __convertRGBColorsToKML(fillColorImgHex.hex, fillColorImgHex.opacity); - } else { - fillColor = __convertRGBColorsToKML(fillColor); - } - } - - if (node && node.getElementsByTagName("ObjectSimpleExtensionGroup").length === 0) { - var labelStyle = document.createElementNS(kmlNode.namespaceURI, "LabelStyle"); - var circleExtended = document.createElementNS(kmlNode.namespaceURI, "ObjectSimpleExtensionGroup"); - circleExtended.setAttribute("type", "circle"); // FIXME type circle only ! - circleExtended.setAttribute("radius", fImageStyle.getRadius()); - circleExtended.setAttribute("fillColor", fillColor); - circleExtended.setAttribute("strokeColor", strokeColor); - circleExtended.setAttribute("strokeWidth", strokeWidth); - labelStyle.appendChild(circleExtended); - node.appendChild(labelStyle); - } - } - } - }; - - /** - * ... - * @param {*} feature - feature - * @param {DOMElement} node - node - */ - var __createExtendedStyleToPoint = function (feature, node) {}; - - // TODO - var __createExtendedStyleToIconLabel = function (feature, nodeIconStyle, nodeLabelStyle) { - logger.trace("write an icon with a label"); - __createExtendedStyleIcon(feature, nodeIconStyle); - __createExtendedStyleLabel(feature, nodeLabelStyle); - }; - - // TODO - var __setNameData = function (feature, tags) { - for (var i = 0; i < tags.length; i++) { - var tag = tags[i]; - if (tag.nodeName === "name") { - return; - } - } - - var labelName = feature.getProperties().name; - if (labelName) { - var name = document.createElement("name"); - name.innerHTML = labelName; - tags.appendChild(name); - } - }; - - // TODO - var _setExtendedDataStyle = function (feature, node) { - if (node && node.length) { - var removeNodes = []; - for (var k = 0; k < node.length; k++) { - const element = node[k]; - if (element.nodeName === "Data") { - var key = element.getAttribute("name"); - if (Styling.getListTags().includes(key)) { - removeNodes.push(element); - } - } - } - if (removeNodes && removeNodes.length) { - removeNodes.forEach(e => { - e.remove(); - }); - } - } - }; - - // On ajoute les styles étendus dans le DOM - this._processKml(kmlNode, features, { - labelStyle : __createExtendedStyleLabel, - iconStyle : __createExtendedStyleIcon, - iconLabelStyle : __createExtendedStyleToIconLabel, - circleStyle : __createExtendedStyleToCircle, - pointStyle : __createExtendedStyleToPoint, - nameData : __setNameData, - extendedData : _setExtendedDataStyle - }); - - // On convertit le DOM en String... - var kmlStringExtended = Parser.toString(kmlNode); - if (!kmlStringExtended) { - return null; - } - - return kmlStringExtended; - }; - - /** - * ... - * - * @param {*} kmlNode - ... - * @param {*} extensions - ... - */ - _writeRootExtensions (kmlNode, extensions) { - var extendDataElement = document.createElementNS(kmlNode.namespaceURI, "ExtendedData"); - // on boucle sur toutes les clefs - for (const key in extensions) { - if (Object.hasOwnProperty.call(extensions, key)) { - const value = extensions[key]; - var dataElement = document.createElementNS(kmlNode.namespaceURI, "Data"); - dataElement.setAttribute("name", key); - var data = document.createTextNode(JSON.stringify(value)); - dataElement.appendChild(data); - extendDataElement.appendChild(dataElement); - } - } - // insertion en 1ere place ! - var firstChild = kmlNode.firstChild; - kmlNode.insertBefore(extendDataElement, firstChild); - } - - /** - * Read Extend for Features. - * This function overloads ol.format.KML.readFeatures ... - * - * @see ol.format.KML.prototype.readFeatures - * @param {Document|Node} source - Source. - * @param {olx.format.ReadOptions=} options - options. - * @return {Array.} Features. - */ - readFeatures (source, options) { - logger.log("overload : ol.format.KML.readFeatures"); - - // String ou Dom - if (typeof source === "string") { - this.source = Parser.parse(source); - } else if (source !== null) { - this.source = source; - } - - var features = this._readExtendStylesFeatures(source, options); - logger.trace("Styles étendus", features); - - // On met à jour les attributs de style dans les features - features.forEach(feature => { - Styling.definePropertiesFromStyle(feature); - }); - - return features; - }; - - /** - * Read Extended Styles for each features - * - * @param {(Document|Node|ArrayBuffer|Object|String)} source - source - * @param {olx.format.ReadOptions=} options - options - * - * @returns {Object[]} features - * - * @private - */ - _readExtendStylesFeatures (source, options) { - var features = super.readFeatures(source, options); - - var kmlDoc = null; - var kmlString = ""; - - if (typeof source === "string") { - kmlString = source; - } else { - kmlString = source.documentElement.outerHTML; - } - - // On 'deformatte' le KML afin d'eviter des pb de parsing... - kmlString = kmlString.replace(/\n/g, ""); - kmlString = kmlString.replace(/(>)\s*(<)/g, "$1$2"); - - // On met en place un Parser sur le KML - kmlDoc = Parser.parse(kmlString); - - if (kmlDoc === null) { - // au cas où... - return features; - } - - // KML Colors (AABBGGRR) To RGB Colors (RRGGBB) - function __convertKMLColorsToRGB (data) { - var color = ""; - color = color + data.substr(6, 2); - color = color + data.substr(4, 2); - color = color + data.substr(2, 2); - var hex = parseInt(color, 16).toString(16); - var comp = ""; - var len = hex.length || 0; - for (var i = 0; i < (6 - len); i++) { - comp += "0"; - } - hex = "#" + comp + hex; - return hex; - } - - /** - * Gestion des styles étendus sur le Label - * - * @param {Object} feature - ol feature - * @param {DOMElement} node - node - * - * @example - * - * Un label - * C'est un label étendu ! - * - * - * 2,48 - * - * - */ - var __getExtendedStyleToFeatureLabel = function (feature, node) { - logger.trace("label with style :", node); - - if (!feature) { - return; - } - - // label - var _text = feature.getProperties().name; - var _color = __convertKMLColorsToRGB("ff000000"); // "#000000" - var _colorHalo = "#FFFFFF"; - var _radiusHalo = 0; - // var _opacityHalo = 1; // TODO - var _font = "Sans"; - var _fontSize = "16px"; - - // cercle - var _circleType = null; - var _circleRadius = 5; - var _circleFillColor = "#000000"; - var _circleStrokeColor = "#ffffff"; - var _circleStrokeWidth = 1; - - // On recherche les balises du Style - var bLabelStyleSimpleExtensionGroup = false; - var bObjectSimpleExtensionGroup = false; - var nodeStyles = node.childNodes; - for (var k = 0; k < nodeStyles.length; k++) { - switch (nodeStyles[k].nodeName) { - case "scale": - // TODO - break; - case "colorMode": - // TODO - break; - case "color": - _color = __convertKMLColorsToRGB(nodeStyles[k].textContent); - break; - case "LabelStyleSimpleExtensionGroup": - bLabelStyleSimpleExtensionGroup = true; - var attributs = nodeStyles[k].attributes; - for (var l = 0; l < attributs.length; l++) { - switch (attributs[l].nodeName) { - case "fontFamily": - _font = attributs[l].nodeValue; - break; - case "fontSize": - _fontSize = attributs[l].nodeValue; - break; - case "haloColor": - _colorHalo = __convertKMLColorsToRGB(attributs[l].nodeValue); - break; - case "haloRadius": - _radiusHalo = parseInt(attributs[l].nodeValue, 10); - break; - case "haloOpacity": - // _opacityHalo = parseFloat(attributs[l].nodeValue); - // TODO opacité ! - // if (_opacityHalo !== 1) { - // _colorHalo = Color.hexToRgba(_colorHalo, _opacityHalo); - // } - break; - default: - } - } - break; - case "ObjectSimpleExtensionGroup": - bObjectSimpleExtensionGroup = true; - var attributsExt = nodeStyles[k].attributes; - for (var ll = 0; ll < attributsExt.length; ll++) { - // type="circle" radius="15" fillColor="7f3737a0" strokeColor="cc000000" strokeWidth="2" - switch (attributsExt[ll].nodeName) { - case "type": - _circleType = attributsExt[ll].nodeValue; - break; - case "radius": - _circleRadius = parseInt(attributsExt[ll].nodeValue, 10); - break; - case "fillColor": - var fillColorValue = attributsExt[ll].nodeValue; - var fillOpacity = Math.round((Color.num(fillColorValue.substr(0, 2)) / 255) * 10) / 10; - var fillColorHexa = __convertKMLColorsToRGB(fillColorValue); - _circleFillColor = Color.hexToRgba(fillColorHexa, fillOpacity); - break; - case "strokeColor": - var strokeColorValue = attributsExt[ll].nodeValue; - var strokeOpacity = Math.round((Color.num(strokeColorValue.substr(0, 2)) / 255) * 10) / 10; - var strokeColorHexa = __convertKMLColorsToRGB(strokeColorValue); - _circleStrokeColor = Color.hexToRgba(strokeColorHexa, strokeOpacity); - break; - case "strokeWidth": - _circleStrokeWidth = parseInt(attributsExt[ll].nodeValue, 10); - break; - default: - } - } - break; - default: - // on ne traite pas les autres informations ... - } - } - - var StyleInstance = null; - if (bObjectSimpleExtensionGroup && _circleType === "circle") { - StyleInstance = new Circle({ - radius : _circleRadius, - fill : new Fill({ - color : _circleFillColor - }), - stroke : new Stroke({ - color : _circleStrokeColor, - width : _circleStrokeWidth - }) - }); - } else if (bLabelStyleSimpleExtensionGroup) { - // INFO - // on ajoute une image magique 1x1 pixel invisible - // afin d'eviter l'affichage d'une punaise google ! - StyleInstance = new Icon({ - src : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNiYAAAAAkAAxkR2eQAAAAASUVORK5CYII=", - size : [51, 38], - anchor : [25.5, 38], - anchorOrigin : "top-left", - anchorXUnits : "pixels", - anchorYUnits : "pixels" - }); - } else { - // ... - } - // On reconstruit le style ! - feature.setStyle(new Style({ - image : StyleInstance, - text : new Text({ - font : _fontSize + " " + _font, - textAlign : "left", - text : _text, - // offsetX : 5, // FIXME valeur arbitraire MAIS esthétique ! - fill : new Fill({ - color : _color - }), - stroke : new Stroke({ - color : _colorHalo, - width : _radiusHalo - }) - }) - })); - }; - - /** - * Gestion des styles étendus sur un Marker - * - * > correctif sur la balise kml:hostSpot - * - problème avec 'hotspot y === 0' (?) - * - * @param {Object} feature - ol feature - * @param {DOMElement} node - node - * - * @example - * - * - * - * 2,48 - * - * - */ - var __getExtendedStyleToFeatureIcon = function (feature, node) { - logger.trace("hotspot :", node); - - // marker - var _src = null; - var _scale = null; - var _color = __convertKMLColorsToRGB("ffffffff"); - - var _bSizeIcon = false; - var _sizeW = 51; - var _sizeH = 38; - - var _bHotSpot = false; - var _anchorX = 25.5; - var _anchorXUnits = "pixels"; - var _anchorY = 38; - var _anchorYUnits = "pixels"; - - var nodeStyles = node.childNodes; - var bIconStyle = false; - for (var k = 0; k < nodeStyles.length; k++) { - switch (nodeStyles[k].nodeName) { - case "Icon": - bIconStyle = true; - var nodes = nodeStyles[k].childNodes; - for (var i = 0; i < nodes.length; i++) { - switch (nodes[i].nodeName) { - case "href": - _src = nodes[i].textContent; - break; - case "gx:w": - _bSizeIcon = true; - _sizeW = parseFloat(nodes[i].textContent); - break; - case "gx:h": - _bSizeIcon = true; - _sizeH = parseFloat(nodes[i].textContent); - break; - default: - } - } - break; - case "hotSpot": - _bHotSpot = true; - var attributs = nodeStyles[k].attributes; - for (var l = 0; l < attributs.length; l++) { - switch (attributs[l].nodeName) { - case "x": - _anchorX = parseFloat(attributs[l].nodeValue); - break; - case "y": - _anchorY = parseFloat(attributs[l].nodeValue); - break; - case "yunits": - _anchorXUnits = attributs[l].nodeValue; - break; - case "xunits": - _anchorYUnits = attributs[l].nodeValue; - break; - default: - } - } - break; - case "scale": - _scale = parseFloat(nodeStyles[k].textContent); - break; - case "color": - _color = __convertKMLColorsToRGB(nodeStyles[k].textContent); - break; - default: - // on ne traite pas les autres informations ... - } - } - - var StyleInstance = null; - if (bIconStyle) { - // une image magique 1x1 pixel invisible - var optionsIcon = { - src : _src || "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNiYAAAAAkAAxkR2eQAAAAASUVORK5CYII=", - color : _color, - crossOrigin : "anonymous", // cf. https://gis.stackexchange.com/questions/121555/wms-server-with-cors-enabled/147403#147403 - scale : _scale || 1 - }; - - if (_bSizeIcon) { - Utils.mergeParams(optionsIcon, { - size : [_sizeW, _sizeH] - }); - } - - if (_bHotSpot) { - Utils.mergeParams(optionsIcon, { - anchor : [_anchorX, _anchorY], - anchorOrigin : "bottom-left", - anchorXUnits : _anchorXUnits || "pixels", - anchorYUnits : _anchorYUnits || "pixels" - }); - } - - StyleInstance = new Icon(optionsIcon); - } - - // existe il déjà le style du label ? - var featureStyleFunction = feature.getStyleFunction(); - if (featureStyleFunction) { - var _styles = featureStyleFunction(feature, 0); - if (_styles && !Array.isArray(_styles)) { - _styles = [_styles]; - } - if (_styles && _styles.length !== 0) { - var _style = (_styles.length === 1) ? _styles[0] : _styles[_styles.length - 1]; - // on écrase l'icone magic du label ! - feature.setStyle(new Style({ - image : StyleInstance, - text : _style.getText() - })); - } - } - }; - - /** - * Gestion de la balise kml:ExtendedData - * - * @param {Object} feature - ol feature - * @param {DOMElement[]} extend - extend - * - * @example - * //--> Marker (Point), LineString, Polygon - * - * - * title - * Titre à concatener avec la valeur de la balise "kml:description" - * - * - * //--> Label - * - * - * PARIS // valeur à remplacer dans "kml:name" - * - * - * title - * Titre à concatener avec la valeur de la balise "kml:description" - * - * - */ - var __getExtendedData = function (feature, extend) { - logger.trace("extendData :", extend); - - if (!feature) { - return; - } - - var props = {}; - - var _fname = feature.get("name") || ""; - var _fdescription = feature.get("description") || ""; - var _ftitle = null; - for (var i = 0; i < extend.length; i++) { - var data = extend[i]; - var name = data.attributes[0]; // 1 seul attribut ! - var nodes = data.childNodes; - if (name.nodeName === "name") { - switch (name.nodeValue) { - // compatibilité ancien geoportail ! - case "label": - _fname = data.textContent; - props.name = _fname; - break; - // compatibilité ancien geoportail ! - case "title": - case "attributetitle": - for (var j = 0; j < nodes.length; j++) { - if (nodes[j].nodeName === "value") { - _ftitle = nodes[j].textContent; - } - } - break; - default: - props[name.nodeValue] = data.textContent; - break; - } - } - } - - // Modification des properties "name" et "description" - if (_ftitle) { - _fdescription = (_fdescription) ? _ftitle + " : " + _fdescription : _ftitle; - props.description = _fdescription; - } - - if (Object.keys(props).length) { - feature.setProperties(props, true); - } - }; - - /** - * TODO - * ... - * - * @param {Object} feature - ol feature - * @param {DOMElement} nodeIconStyle - icon style - * @param {DOMElement} nodeLabelStyle - label style - * @example - * ... - */ - var __getExtendedStyleToFeatureIconLabel = function (feature, nodeIconStyle, nodeLabelStyle) { - logger.trace("display icon and label"); - __getExtendedStyleToFeatureLabel(feature, nodeLabelStyle); - __getExtendedStyleToFeatureIcon(feature, nodeIconStyle); - }; - - // TODO... - var __getStyleToDefaultFeature = function (feature, node) {}; - - // On lit les styles étendus et on les ajoute aux features - this._processKml(kmlDoc, features, { - lineStringStyle : __getStyleToDefaultFeature, - polygonStyle : __getStyleToDefaultFeature, - pointStyle : __getStyleToDefaultFeature, - labelStyle : this.showPointNames_ ? __getExtendedStyleToFeatureLabel : null, - iconStyle : __getExtendedStyleToFeatureIcon, - iconLabelStyle : this.showPointNames_ ? __getExtendedStyleToFeatureIconLabel : __getExtendedStyleToFeatureIcon, - extendedData : __getExtendedData - }); - - return features; - }; - - /** - * ... - * @param {*} key ... - * @returns {Object} json - */ - readRootExtensions (key) { - var value = {}; - // Rechercher le tag avec la clef : geoportail:compute - // - // {...} - // - var firstNodeLevelKml = (this.source.nodeName === "#document") ? this.source.childNodes[0] : this.source; - var childNodesLevel = firstNodeLevelKml.childNodes; - for (var i = 0; i < childNodesLevel.length; i++) { - var node1 = childNodesLevel[i]; - if (node1.nodeName === "ExtendedData") { - var childNodesExtended = node1.childNodes; - for (var j = 0; j < childNodesExtended.length; j++) { - var node2 = childNodesExtended[j]; - if (node2.nodeName === "Data") { - var name = node2.attributes[0]; - if (name && name.nodeName === "name") { - if (name.nodeValue === key) { - value = JSON.parse(node2.textContent); - break; - } - } - } - } - } - } - return value; - } - -}; - -export default KML; - -// Expose KML as ol.source.KMLExtended. (for a build bundle) -if (window.ol && window.ol.format) { - window.ol.format.KMLExtended = KML; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Formats/Styling.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Formats/Styling.d.ts deleted file mode 100644 index fa3db1750..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Formats/Styling.d.ts +++ /dev/null @@ -1,63 +0,0 @@ -export default Styling; -declare namespace Styling { - let APPLY_CONVERT_GEOM_GPX: boolean; - namespace DEFAULT_ICON { - let src: string; - let anchor: number[]; - let scale: number; - } - namespace DEFAULT_CIRCLE { - let radius: number; - namespace fill { - let opacity: number; - let color: number[]; - } - namespace stroke { - export let width: number; - let opacity_1: number; - export { opacity_1 as opacity }; - let color_1: number[]; - export { color_1 as color }; - } - } - namespace DEFAULT_STROKE { - let width_1: number; - export { width_1 as width }; - let opacity_2: number; - export { opacity_2 as opacity }; - let color_2: number[]; - export { color_2 as color }; - } - namespace DEFAULT_FILL { - let opacity_3: number; - export { opacity_3 as opacity }; - let color_3: number[]; - export { color_3 as color }; - } - namespace DEFAULT_TEXT { - export let font: string; - export let textAlign: string; - export namespace stroke_1 { - let color_4: number[]; - export { color_4 as color }; - let width_2: number; - export { width_2 as width }; - export let opactity: number; - } - export { stroke_1 as stroke }; - export namespace fill_1 { - let opacity_4: number; - export { opacity_4 as opacity }; - let color_5: number[]; - export { color_5 as color }; - } - export { fill_1 as fill }; - } - function getListTags(): any[]; - function defineStyleFromProperties(feature: any): any; - function defineStyleFunctionByDefault(defaultStyle: Object): Function; - function definePropertiesFromStyleByType(feature: any): void; - function definePropertiesFromStyle(feature: any): void; - function defineTagFromStyle(style: any, format: string): string; -} -//# sourceMappingURL=Styling.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Formats/Styling.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Formats/Styling.d.ts.map deleted file mode 100644 index 8a1f8b137..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Formats/Styling.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Styling.d.ts","sourceRoot":"","sources":["../../../../src/packages/Formats/Styling.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA0XkB,8BAyBb;IA2C2B,sDAuO3B;IAa8B,sEA8E9B;IAQiC,6DAoBjC;IAyC2B,uDAgB3B;IAkBoB,gEAGpB"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Formats/Styling.js b/build/release/geoportal-extensions-openlayers/src/packages/Formats/Styling.js deleted file mode 100644 index bb3cb6421..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Formats/Styling.js +++ /dev/null @@ -1,878 +0,0 @@ -import Color from "../Utils/ColorUtils"; -import Logger from "../Utils/LoggerByDefault"; -import Markers from "../Controls/Utils/Markers"; -// import ol -import Feature from "ol/Feature"; -// import Style -import Style from "ol/style/Style"; -import CircleStyle from "ol/style/Circle"; -import IconStyle from "ol/style/Icon"; -import FillStyle from "ol/style/Fill"; -import StrokeStyle from "ol/style/Stroke"; -import TextStyle from "ol/style/Text"; -// import geom -import Polygon from "ol/geom/Polygon"; -import MultiPolygon from "ol/geom/MultiPolygon"; - -var logger = Logger.getLogger("styling"); - -Feature.prototype.setPropertyFill = function () { - var style = this.getStyle(); - if (!style) { - return; - } - if (Array.isArray(style) && style.length === 0) { - return; - } - var fill = style.getFill(); - if (fill) { - var colorFill = fill.getColor(); - // array - if (Array.isArray(colorFill)) { - var cf = "rgba("; - cf += colorFill[0] + ","; - cf += colorFill[1] + ","; - cf += colorFill[2] + ","; - cf += colorFill[3] + ")"; - colorFill = cf; - } - if (Color.isRGB(colorFill)) { - var oColorFill = Color.rgbaToHex(colorFill); - this.set("fill", oColorFill.hex); - this.set("fill-opacity", oColorFill.opacity); - } else { - this.set("fill", colorFill); - this.set("fill-opacity", 1); - } - } -}; - -Feature.prototype.setPropertyStroke = function () { - var style = this.getStyle(); - if (!style) { - return; - } - if (Array.isArray(style) && style.length === 0) { - return; - } - var stroke = style.getStroke(); - if (stroke) { - var colorStroke = stroke.getColor(); - // array - if (Array.isArray(colorStroke)) { - var cs = "rgba("; - cs += colorStroke[0] + ","; - cs += colorStroke[1] + ","; - cs += colorStroke[2] + ","; - cs += colorStroke[3] + ")"; - colorStroke = cs; - } - if (Color.isRGB(colorStroke)) { - var oColorStroke = Color.rgbaToHex(colorStroke); - this.set("stroke", oColorStroke.hex); - this.set("stroke-opacity", oColorStroke.opacity); - } else { - this.set("stroke", colorStroke); - this.set("stroke-opacity", 1); - } - this.set("stroke-width", stroke.getWidth()); - } -}; - -Feature.prototype.setPropertyLabel = function () { - var style = this.getStyle(); - if (!style) { - return; - } - if (Array.isArray(style) && style.length === 0) { - return; - } - var isName = this.get("name") !== undefined; - var label = style.getText(); - if (label && isName) { - var fill = style.getText().getFill(); - if (fill) { - var colorFill = fill.getColor(); - // array - if (Array.isArray(colorFill)) { - var cf = "rgba("; - cf += colorFill[0] + ","; - cf += colorFill[1] + ","; - cf += colorFill[2] + ","; - cf += colorFill[3] + ")"; - colorFill = cf; - } - if (Color.isRGB(colorFill)) { - var oColorFill = Color.rgbaToHex(colorFill); - this.set("label-fill", oColorFill.hex); - this.set("label-fill-opacity", oColorFill.opacity); - } else { - this.set("label-fill", colorFill); - this.set("label-fill-opacity", 1); - } - } - var stroke = style.getText().getStroke(); - if (stroke) { - var colorStroke = stroke.getColor(); - // array - if (Array.isArray(colorStroke)) { - var cs = "rgba("; - cs += colorStroke[0] + ","; - cs += colorStroke[1] + ","; - cs += colorStroke[2] + ","; - cs += colorStroke[3] + ")"; - colorStroke = cs; - } - if (Color.isRGB(colorStroke)) { - var oColorStroke = Color.rgbaToHex(colorStroke); - this.set("label-stroke", oColorStroke.hex); - this.set("label-stroke-opacity", oColorStroke.opacity); - } else { - this.set("label-stroke", colorStroke); - this.set("label-stroke-opacity", 1); - } - this.set("label-stroke-width", stroke.getWidth()); - } - this.set("label-font", style.getText().getFont() || Styling.DEFAULT_TEXT.font); - this.set("label-textAlign", style.getText().getTextAlign() || Styling.DEFAULT_TEXT.textAlign); - } -}; - -Feature.prototype.setPropertyMarker = function () { - var style = this.getStyle(); - if (!style) { - return; - } - if (Array.isArray(style) && style.length === 0) { - return; - } - var image = style.getImage(); - if (image) { - // si le tag image est seul... - // c'est soit un marker ou soit un cercle ! - if (image instanceof IconStyle) { - var color = image.getColor(); - // array - if (Array.isArray(color)) { - var c = "rgba("; - c += color[0] + ","; - c += color[1] + ","; - c += color[2] + ","; - c += color[3] + ")"; - color = c; - } - // feature.set("marker-color", ""); // par defaut - if (color) { - var colorIcon = Color.rgbaToHex(color); - this.set("marker-color", colorIcon.hex); - } - var scaleIcon = image.getScale(); - switch (Math.round(scaleIcon * 2) / 2) { - case 0: - case 0.5: - this.set("marker-size", "small"); - break; - case 1: - this.set("marker-size", "medium"); - break; - case 1.5: - case 2: - this.set("marker-size", "large"); - break; - default: - // this.set("marker-size", ""); // par defaut - break; - } - // feature.set("marker-symbol", ""); // par defaut - var srcImage = image.getSrc(); - if (srcImage) { - this.set("marker-symbol", srcImage); - } - // INFO - // cas particulier où un objet est transformé : - // * un cercle est transformé en icone - // > les attributs du cercle sont à supprimer ! - this.unset("circle-fill"); - this.unset("circle-fill-opacity"); - this.unset("circle-stroke"); - this.unset("circle-stroke-width"); - this.unset("circle-stroke-opacity"); - this.unset("circle-radius"); - } else { - var fillImg = image.getFill(); - if (fillImg) { - var colorFillImg = fillImg.getColor(); - // array - if (Array.isArray(colorFillImg)) { - var cfi = "rgba("; - cfi += colorFillImg[0] + ","; - cfi += colorFillImg[1] + ","; - cfi += colorFillImg[2] + ","; - cfi += colorFillImg[3] + ")"; - colorFillImg = cfi; - } - if (Color.isRGB(colorFillImg)) { - var oColorFillImg = Color.rgbaToHex(colorFillImg); - this.set("circle-fill", oColorFillImg.hex); - this.set("circle-fill-opacity", oColorFillImg.opacity); - } else { - this.set("circle-fill", colorFillImg); - this.set("circle-fill-opacity", 1); - } - } - var strokeImg = image.getStroke(); - if (strokeImg) { - var colorStrokeImg = strokeImg.getColor(); - // array - if (Array.isArray(colorStrokeImg)) { - var csi = "rgba("; - csi += colorStrokeImg[0] + ","; - csi += colorStrokeImg[1] + ","; - csi += colorStrokeImg[2] + ","; - csi += colorStrokeImg[3] + ")"; - colorStrokeImg = csi; - } - if (Color.isRGB(colorStrokeImg)) { - var oColorStrokeImg = Color.rgbaToHex(colorStrokeImg); - this.set("circle-stroke", oColorStrokeImg.hex); - this.set("circle-stroke-opacity", oColorStrokeImg.opacity); - } else { - this.set("circle-stroke", colorStrokeImg); - this.set("circle-stroke-opacity", 1); - } - this.set("circle-stroke-width", strokeImg.getWidth()); - } - var radius = image.getRadius(); - this.set("circle-radius", radius); - } - } -}; - -/** - * @module Styling - * @alias Gp.Styling - * @todo ... - * @description - * A simple specification for styling GeoJSON / GPX / KML data. - * - * @see ol.format.GeoJSONExtended - * @see ol.format.KMLExtended - * @see ol.format.GPXExtended - * - * @example - * feature.getStyle(); // null - * feature.getProperties(); // {"stroke": "#ff0000", "stroke-width": 2} - * Styling.defineStyleFromProperties(feature); - * feature.getStyle(); // [Object Style] - * - * feature.getStyle(); // [Object Style] - * feature.getProperties(); // {} - * Styling.definePropertiesFromStyle(feature); - * feature.getProperties(); // {"stroke": "#ff0000", "stroke-width": 2} - * - * var style = feature.getStyle(); // [Object Style] - * var tag = Styling.setTag(style, "GPX"); - * - * ex. output GeoJSON: - * ```json - * "properties": { - * "stroke": "#ff0000", - * "stroke-width": 2 - * } - * ``` - */ -var Styling = { - - /** - * Options to convert geometry - */ - APPLY_CONVERT_GEOM_GPX : true, - - /** - * Default icon style options - */ - DEFAULT_ICON : { - src : Markers["lightOrange"], - anchor : [0.5, 1], - scale : 1 - }, - - /** - * Default circle style options - */ - DEFAULT_CIRCLE : { - radius : 10, - fill : { - opacity : 1, - color : [0, 0, 0, 1] - }, - stroke : { - width : 1, - opacity : 1, - color : [0, 0, 0, 1] - } - }, - - /** - * Default stroke style options - */ - DEFAULT_STROKE : { - width : 5, - opacity : 1, - color : [250, 250, 250, 1] - }, - - /** - * Default fill style options - */ - DEFAULT_FILL : { - opacity : 1, - color : [0, 0, 0, 1] - }, - - /** - * Default text style options - * @see https://openlayers.org/en/v6.15.1/apidoc/module-ol_style_Text-Text.html - */ - DEFAULT_TEXT : { - font : "16px sans", - textAlign : "left", - stroke : { - color : [250, 250, 250, 1], - width : 5, - opactity : 1 - }, - fill : { - opacity : 1, - color : [0, 0, 0, 1] - } - // offsetX - // offsetY - // placement - // scale - // rotation - // justify - // padding - }, - - /** - * All styling tags - * @function getListTags - * @returns {Array} all styling tags - * @example - * "type", // type de geometrie - * "fill", - * "fill-opacity", - * "stroke", - * "stroke-opacity", - * "stroke-width", - * "circle-fill", - * "circle-fill-opacity", - * "circle-stroke", - * "circle-stroke-opacity", - * "circle-stroke-width", - * "circle-radius", - * "marker-symbol", - * "marker-color", - * "marker-size" - */ - getListTags : function () { - return [ - "type", - "fill", - "fill-opacity", - "stroke", - "stroke-opacity", - "stroke-width", - "circle-fill", - "circle-fill-opacity", - "circle-stroke", - "circle-stroke-opacity", - "circle-stroke-width", - "circle-radius", - "marker-symbol", - "marker-color", - "marker-size", - "label-fill", - "label-fill-opacity", - "label-stroke", - "label-stroke-width", - "label-stroke-opacity", - "label-font", - "label-textAlign" - ]; - }, - - /** - * Transform feature properties to a native style - * - * @function defineStyleFromProperties - * @param {*} feature - ... - * @returns {*} style - ... - * @public - * - * @description - * A la lecture du format : - * > tag styling ---> feature properties ---> feature style - * - * Les balises de 'styling' du fichier sont ajoutées dans les properties de chaque features - * (opération native sous OpenLayers): - * - * Ex. avec le format GeoJSON : - * ```json - * "properties": { - * "stroke": "#000000", -> feature.get("stroke"); - * "stroke-width": 13, -> feature.get("stroke-width"); - * "stroke-opacity": 0.8, -> feature.get("stroke-opacity"); - * "fill": "#a03737", -> feature.get("fill"); - * "fill-opacity": 0.5 -> feature.get("fill-opacity"); - * } - * ``` - * - * Ensuite, les properties des features sont transformées dans le style natif : - * - * ```js - * // Ex. - * feature.setStyle(new Style({ - * fill : new FillStyle({ - * color : Color.hexToRgba(feature.get("fill"), feature.get("fill-opacity") || 1) - * }), - * stroke : new StrokeStyle({ - * color : Color.hexToRgba(feature.get("stroke"), feature.get("stroke-opacity")) - * width : feature.get("stroke-width") - * }) - * })); - * ``` - */ - defineStyleFromProperties : function (feature) { - // style - var style = null; - - // les options de styles définis dans le format - var options = {}; - - // properties : - // "marker-size" -> icon - // "marker-symbol" -> icon - // "marker-color" -> icon - var marker = null; - if (feature.get("marker-color") || - feature.get("marker-size") || - feature.get("marker-symbol")) { - marker = {}; - // icone par defaut - marker["src"] = this.DEFAULT_ICON.src; - marker["anchor"] = this.DEFAULT_ICON.anchor; - var symbolMarker = feature.get("marker-symbol"); - if (symbolMarker) { - if (symbolMarker.search("data:image/png;base64") !== -1) { - // icone du portail - marker["src"] = symbolMarker; - } else { - // TODO - // utiliser les symboles de Maki - // (cf. https://labs.mapbox.com/maki-icons/) - } - } - var colorMarker = feature.get("marker-color"); - if (Color.isHex(colorMarker)) { - marker["color"] = Color.hexToRgba(colorMarker, 1); - } - var size = feature.get("marker-size"); - if (size) { - switch (size) { - case "small": - marker["scale"] = 0.5; - break; - case "medium": - marker["scale"] = 1; - break; - case "large": - marker["scale"] = 1.5; - break; - default: - marker["scale"] = this.DEFAULT_ICON.scale; - break; - } - } - } - - // properties : - // "stroke" -> line / polygon - // "stroke-opacity" -> line / polygon - // "stroke-width" -> line / polygon - var stroke = null; - if (feature.get("stroke") || - feature.get("stroke-opacity") || - feature.get("stroke-width")) { - stroke = {}; - stroke["color"] = Color.hexToRgba(feature.get("stroke"), +feature.get("stroke-opacity") || this.DEFAULT_STROKE.opacity); - stroke["width"] = +feature.get("stroke-width") || this.DEFAULT_STROKE.width; - } - - // properties : - // "fill" -> polygon - // "fill-opacity" -> polygon - var fill = null; - if (feature.get("fill") || - feature.get("fill-opacity")) { - fill = {}; - fill["color"] = Color.hexToRgba(feature.get("fill"), +feature.get("fill-opacity") || this.DEFAULT_FILL.opacity); - } - - // properties : - // "label-fill", - // "label-fill-opacity", - // "label-stroke", - // "label-stroke-width", - // "label-stroke-opacity", - // "label-font", - // "label-textAlign" - // "name" -> text - var labelStroke = null; - var labelFill = null; - var isLabel = feature.get("name") !== ""; - if (isLabel) { - if (feature.get("label-fill") || - feature.get("label-fill-opacity")) { - labelFill = {}; - labelFill["color"] = Color.hexToRgba(feature.get("label-fill"), +feature.get("label-fill-opacity") || this.DEFAULT_TEXT.fill.opacity); - } - if (feature.get("label-stroke") || - feature.get("label-stroke-opacity") || - feature.get("label-stroke-width")) { - labelStroke = {}; - labelStroke["color"] = Color.hexToRgba(feature.get("label-stroke"), +feature.get("label-stroke-opacity") || this.DEFAULT_TEXT.stroke.opacity); - labelStroke["width"] = +feature.get("label-stroke-width") || this.DEFAULT_TEXT.stroke.width; - } - } - - // properties : - // "circle-fill" - // "circle-stroke" - // "circle-stroke-width" - // "circle-radius" - var circleRadius = feature.get("circle-radius") || this.DEFAULT_CIRCLE.radius; - var circleStroke = null; - if (feature.get("circle-stroke") || - feature.get("circle-stroke-opacity") || - feature.get("circle-stroke-width")) { - circleStroke = {}; - circleStroke["color"] = Color.hexToRgba(feature.get("circle-stroke"), +feature.get("circle-stroke-opacity") || this.DEFAULT_CIRCLE.stroke.opacity); - circleStroke["width"] = +feature.get("circle-stroke-width") || this.DEFAULT_CIRCLE.stroke.width; - } - var circleFill = null; - if (feature.get("circle-fill") || - feature.get("circle-fill-opacity")) { - circleFill = {}; - circleFill["color"] = Color.hexToRgba(feature.get("circle-fill"), +feature.get("circle-fill-opacity") || this.DEFAULT_CIRCLE.fill.opacity); - } - - // options du Style en fonction du type de geometrie - var type = feature.getGeometry().getType(); - switch (type) { - case "Circle": - case "Point": - case "MultiPoint": - // Cercle - var isCircle = false; - var optionsCircle = {}; - if (circleStroke) { - optionsCircle["stroke"] = new StrokeStyle(circleStroke); - } - if (circleFill) { - optionsCircle["fill"] = new FillStyle(circleFill); - } - if (Object.keys(optionsCircle).length !== 0) { - isCircle = true; - optionsCircle["radius"] = +circleRadius; // Conversion en nombre - options["image"] = new CircleStyle(optionsCircle); - } - // Ponctuel - if (marker) { - options["image"] = new IconStyle(marker); - } - // Label - if (isLabel) { - var optionsText = {}; - - if (labelStroke) { - optionsText["stroke"] = new StrokeStyle(labelStroke); - } - if (labelFill) { - optionsText["fill"] = new FillStyle(labelFill); - } - if (Object.keys(optionsText).length !== 0) { - optionsText["text"] = feature.get("name"); - optionsText["textAlign"] = feature.get("label-textAlign") || this.DEFAULT_TEXT.textAlign; - optionsText["font"] = feature.get("label-font") || this.DEFAULT_TEXT.font; - options["text"] = new TextStyle( - Object.assign({}, - this.DEFAULT_TEXT, - optionsText - )); - } else { - // on applique un style par defaut sur le label - // pour un marker ou un cercle - if (marker || isCircle) { - var styleText = new TextStyle( - Object.assign({}, - this.DEFAULT_TEXT, { - fill : new FillStyle(this.DEFAULT_TEXT.fill), - stroke : new StrokeStyle(this.DEFAULT_TEXT.stroke) - } - ) - ); - if (styleText) { - var cloneStyleText = styleText.clone(); - cloneStyleText.setText(feature.get("name")); - options["text"] = cloneStyleText; - } - } - } - } - break; - - case "Polygon": - case "MultiPolygon": - if (stroke) { - options["stroke"] = new StrokeStyle(stroke); - } - if (fill) { - options["fill"] = new FillStyle(fill); - } - break; - - case "LineString": - case "MultiLineString": - if (stroke) { - options["stroke"] = new StrokeStyle(stroke); - } - if (this.APPLY_CONVERT_GEOM_GPX && fill) { - // INFO - // Lors d'une transformation de type de geometrie, le type est renseigné. - // Pour le format GPX, - // -> on transforme une surface vers ligne lors de l'écriture - // -> on transforme une ligne vers une surface lors de la lecture si le type est précisé ! - var initType = feature.get("type"); - if (initType && (initType === "Polygon" || initType === "MultiPolygon")) { - options["fill"] = new FillStyle(fill); - var f = feature.clone(); - var ClassPoly = (type === "LineString") ? Polygon : MultiPolygon; - feature.setGeometry(new ClassPoly([f.getGeometry().getCoordinates()])); - } - } - break; - - default: - break; - } - - // si aucun style disponible, on utilisera le style par defaut defini - // par l'utilisateur ou l'application - if (Object.keys(options).length !== 0) { - style = new Style(options); - } - - return style; - }, - - /** - * Define a default style function to apply to a feature - * - * @function defineStyleFunctionByDefault - * @param {Object} defaultStyle - ... - * @returns {Function} style function - * @public - * - * @description - * ... - */ - defineStyleFunctionByDefault : function (defaultStyle) { - if (!defaultStyle) { - return []; - } - - if (Object.keys(defaultStyle).length === 0) { - return []; - } - - // les styles par defaut - var styleFunction = (feature, resolution) => { - var style = null; - var type = feature.getGeometry().getType(); - switch (type) { - case "Point": - case "MultiPoint": - // on n'a aucune information sur le type de style à appliquer sur un "Point" : - // * label ou - // * marker ou - // * marker avec label - // donc, c'est en fonction des styles par defaut... - var opts = {}; - if (defaultStyle.getImage()) { - opts["image"] = defaultStyle.getImage(); - } - if (defaultStyle.getText() && feature.get("name")) { - var styleText = defaultStyle.getText().clone(); - styleText.setText(feature.get("name")); - opts["text"] = styleText; - } - style = new Style(opts); - break; - case "Circle": - var optsc = {}; - - var optsCircle = {}; - if (defaultStyle.getFill()) { - optsCircle.fill = defaultStyle.getFill(); - } - if (defaultStyle.getStroke()) { - optsCircle.stroke = defaultStyle.getStroke(); - } - if (defaultStyle.getText() && feature.get("name")) { - var styleTextCircle = defaultStyle.getText().clone(); - styleTextCircle.setText(feature.get("name")); - optsc.text = styleTextCircle; - } - if (Object.keys(optsCircle).length !== 0) { - // FIXME param radius ? - optsCircle.radius = 3; - optsc.image = new CircleStyle(optsCircle); - } - style = new Style(optsc); - break; - case "Polygon": - case "MultiPolygon": - var optsp = {}; - if (defaultStyle.getFill()) { - optsp.fill = defaultStyle.getFill(); - } - if (defaultStyle.getStroke()) { - optsp.stroke = defaultStyle.getStroke(); - } - style = new Style(optsp); - break; - case "LineString": - case "LinearRing": - case "MultiLineString": - var optsl = {}; - if (defaultStyle.getStroke()) { - optsl.stroke = defaultStyle.getStroke(); - } - style = new Style(optsl); - break; - } - return [style]; - }; - return styleFunction; - }, - - /** - * Transform a native style to feature properties by type of geometry - * - * @todo not yet implemented ! - * @param {*} feature - feature - */ - definePropertiesFromStyleByType : function (feature) { - var geomType = feature.getGeometry().getType(); - switch (geomType) { - case "Point": - case "MultiPoint": - feature.setPropertyMarker(); - feature.setPropertyLabel(); - break; - case "LineString": - case "MultiLineString": - feature.setPropertyStroke(); - break; - case "Polygon": - case "MultiPolygon": - feature.setPropertyStroke(); - feature.setPropertyFill(); - break; - default: - break; - } - }, - - /** - * Transform a native style to feature properties - * - * @function definePropertiesFromStyle - * @param {*} feature - ... - * @public - * - * @description - * A l'écriture du format. - * > feature style --> feature properties --> tag styling - * - * Le style natif est récupéré pour chaque feature : - * - * ```js - * // Ex. - * var style = feature.getStyle(); - * ``` - * - * Ensuite, le style natif est transformé en properties pour chaque feature : - * - * ```js - * // Ex. - * var stroke = style.getStroke(); - * var oColorStroke = Color.rgbaToHex(stroke.getColor()); - * feature.set("stroke", oColorStroke.hex); // #000000 - * feature.set("stroke-opacity", oColorStroke.opacity); // 0.8 - * ``` - * - * Et, chaque properties des features sont ecrites dans le format du fichier - * (opération native sous OpenLayers) : - * - * Ex. avec le format GeoJSON : - * ```json - * "properties": { - * "stroke": "#000000", - * "stroke-opacity": 0.8 - * } - * ``` - */ - definePropertiesFromStyle : function (feature) { - var style = feature.getStyle() || feature.getStyleFunction(); - if (style) { - // style ajouté via une fonction, pour les styles par defaut par ex. - if (typeof style === "function") { - var styles = style.call(this, feature, 0); - if (styles && styles.length !== 0) { - style = (Array.isArray(styles)) ? styles[0] : styles; - feature.setStyle(style); - } else { - // au cas où... - return; - } - } - this.definePropertiesFromStyleByType(feature); - } - }, - - /** - * Transform a native style to tags 'styling' into the format - * - * @function defineTagFromStyle - * @param {*} style - ... - * @param {String} format - ... - * @returns {String} tags stringify into the format (json / xml) - * @todo - * @public - * - * @description - * A partir d'un style natif, on le transforme en balise de 'styling' dans le format demandé, - * que l'on peut ensuite inserer dans le fichier. - * > style ---> tag styling - * - */ - defineTagFromStyle : function (style, format) { - logger.trace("todo..."); - return null; - } -}; - -export default Styling; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerMapBox.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerMapBox.d.ts deleted file mode 100644 index d5a9c0647..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerMapBox.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -export default LayerMapBox; -/** - * @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 - * ... - * }); - */ -declare var LayerMapBox: ol.layer.GeoportalMapBox; -//# sourceMappingURL=LayerMapBox.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerMapBox.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerMapBox.d.ts.map deleted file mode 100644 index 89cb557a1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerMapBox.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"LayerMapBox.d.ts","sourceRoot":"","sources":["../../../../src/packages/Layers/LayerMapBox.js"],"names":[],"mappings":";AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,kDAuTE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerMapBox.js b/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerMapBox.js deleted file mode 100644 index dfc3de837..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerMapBox.js +++ /dev/null @@ -1,359 +0,0 @@ -// import openlayers -import VectorTileLayer from "ol/layer/VectorTile"; -import VectorTileSource from "ol/source/VectorTile"; -import TileJSONSource from "ol/source/TileJSON"; -import MVT from "ol/format/MVT"; -import { unByKey as observableUnByKey } from "ol/Observable"; -// import olms : module ES6 -import { applyStyle } from "ol-mapbox-style"; -// import local -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 - * ... - * }); - */ -var LayerMapBox = class LayerMapBox extends VectorTileLayer { - - /** - * See {@link ol.layer.GeoportalMapBox} - * @module LayerMapBox - * @alias module:~Layers/GeoportalMapBox - * @param {*} options - options - * @param {*} [settings] - other settings - * @example - * import LayerMapBox from "src/packages/Layers/LayerMapBox" - */ - 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 - // car le service n'est pas securisé... - - // 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); - if (!layerCfg) { - throw new Error("ERROR : Layer ID not found into the catalogue !?"); - } - - var styleUrl = null; - var styleTitle = ""; - var styleName = options.style; - for (var i = 0; i < layerCfg.styles.length; i++) { - var style = layerCfg.styles[i]; - // si le nom du style est en option, on le recherche... - // sinon, on recherche le style par defaut ! - if (styleName && style.name === styleName) { - styleUrl = style.url; - styleTitle = style.title; - break; - } else { - if (!styleName && style.current) { - styleName = style.name; - styleUrl = style.url; - styleTitle = style.title; - break; - } - } - } - - 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.protocol = protocol; - this.sourceId = options.source; - this.styleUrl = styleUrl; - - // récuperation du style - this.setStyleMapBox(); - - return this; - } - - /** - * Get Style MapBox - * @private - */ - setStyleMapBox () { - 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); - }); - }; - - /** - * Add Style - * @param {*} style - json style - */ - onStyleMapBoxLoad (style) { - // si on a plusieurs sources, on ne peut en prendre qu'une seule... - if (!this.sourceId) { - this.sourceId = Object.keys(style.sources)[0]; - } - - var styleSource = style.sources[this.sourceId]; - if (!styleSource) { - this.onStyleMapBoxError({ - message : "ERROR : Source ID not found !? !" - }); - 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 - }); - var self = this; - var key = vectorTileJson.on("change", function () { - if (vectorTileJson.getState() === "ready") { - var doc = vectorTileJson.getTileJSON(); - if (!doc) { - return; - } - self.set("mapbox-extensions", doc); - var tiles = Array.isArray(doc.tiles) ? doc.tiles : [doc.tiles]; - // protocole : http ou https - for (var i = 0; i < styleSource.tiles.length; i++) { - tiles[i].replace(/(http|https):\/\//, this.protocol); - } - source.setUrls(tiles); - observableUnByKey(key); - } - }); - } - - if (styleSource.tiles) { - // protocole : http ou https - for (var j = 0; j < styleSource.tiles.length; j++) { - styleSource.tiles[j].replace(/(http|https):\/\//, this.protocol); - } - source.setUrls(styleSource.tiles); - } - - applyStyle(this, style, this.sourceId) - .then(() => { - source.setState("ready"); - this.set("mapbox-styles", style); - }) - .catch((error) => { - this.onStyleMapBoxError(error); - }); - }; - - /** - * Error - * @param {*} error - message - */ - onStyleMapBoxError (error) { - var source = this.getSource(); - source.setState("error"); - // eslint-disable-next-line no-console - console.error(error.message); - }; - -}; - -export default LayerMapBox; - -// Expose LayerMapBox as ol.layer.GeoportalMapBox. (for a build bundle) -if (window.ol && window.ol.layer) { - window.ol.layer.GeoportalMapBox = LayerMapBox; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMS.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMS.d.ts deleted file mode 100644 index d8907e041..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMS.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -export default LayerWMS; -/** - * @classdesc - * Geoportal LayerWMS source creation (inherit from ol.layer.Tile) - * - * @constructor - * @extends {ol.layer.Tile} - * @alias ol.layer.GeoportalWMS - * @type {ol.layer.GeoportalWMS} - * @param {Object} GeoportalWMSoptions - options for function call. - * @param {String} options.layer - Layer name (e.g. "ORTHOIMAGERY.ORTHOPHOTOS") - * @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}) - * @param {Object} [options.olParams.sourceParams] - other options for ol.source.TileWMS function (see {@link http://openlayers.org/en/latest/apidoc/ol.source.TileWMS.html ol.source.TileWMS}) - * @example - * var layerWMS = new ol.layer.GeoportalWMS({ - * layer : "ORTHOIMAGERY.ORTHOPHOTOS" - * }); - */ -declare var LayerWMS: ol.layer.GeoportalWMS; -//# sourceMappingURL=LayerWMS.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMS.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMS.d.ts.map deleted file mode 100644 index eb37759d7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMS.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"LayerWMS.d.ts","sourceRoot":"","sources":["../../../../src/packages/Layers/LayerWMS.js"],"names":[],"mappings":";AAYA;;;;;;;;;;;;;;;;;;GAkBG;AACH,4CA4GE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMS.js b/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMS.js deleted file mode 100644 index 2aea5fee2..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMS.js +++ /dev/null @@ -1,147 +0,0 @@ -// import openlayers -import { - get as olGetProj, - transformExtent as olTransformExtentProj -} from "ol/proj"; -import TileLayer from "ol/layer/Tile"; -// import local -import Utils from "../Utils/Helper"; -import Config from "../Utils/Config"; -// import local with ol dependencies -import SourceWMS from "./SourceWMS"; - -/** - * @classdesc - * Geoportal LayerWMS source creation (inherit from ol.layer.Tile) - * - * @constructor - * @extends {ol.layer.Tile} - * @alias ol.layer.GeoportalWMS - * @type {ol.layer.GeoportalWMS} - * @param {Object} GeoportalWMSoptions - options for function call. - * @param {String} options.layer - Layer name (e.g. "ORTHOIMAGERY.ORTHOPHOTOS") - * @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}) - * @param {Object} [options.olParams.sourceParams] - other options for ol.source.TileWMS function (see {@link http://openlayers.org/en/latest/apidoc/ol.source.TileWMS.html ol.source.TileWMS}) - * @example - * var layerWMS = new ol.layer.GeoportalWMS({ - * layer : "ORTHOIMAGERY.ORTHOPHOTOS" - * }); - */ -var LayerWMS = class LayerWMS extends TileLayer { - - /** - * See {@link ol.layer.GeoportalWMS} - * @module LayerWMS - * @alias module:~Layers/GeoportalWMS - * @param {*} options - options - * @example - * import LayerWMS from "src/OpenLayers/Layers/LayerWMS" - */ - constructor (options) { - // if (!(this instanceof LayerWMS)) { - // 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; - } - - // Check if configuration is loaded - if (!Config.isConfigLoaded()) { - throw new Error("ERROR : contract key configuration has to be loaded to load Geoportal layers."); - } - - // création de la source WMS - var olSourceParams; - if (options.olParams && options.olParams.sourceParams) { - olSourceParams = options.olParams.sourceParams; - } - var wmsSource = new SourceWMS({ - layer : options.layer, - ssl : options.ssl, - apiKey : options.apiKey, - olParams : olSourceParams - }); - - var layerTileOptions = { - source : wmsSource - }; - - // 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. - Idem pour les résolutions : il faut connaitre l'unité de la projection (metres ou degrés) pour pouvoir calculer la résolution. - */ - 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 - ]; - layerTileOptions.extent = olTransformExtentProj(geobbox, "EPSG:4326", olSourceParams.projection); - - // récupération des résolutions min et max - var p; - // on récupère tout d'abord la projection - if (typeof olSourceParams.projection === "string") { - p = olGetProj(olSourceParams.projection); - } else if (typeof olSourceParams.projection === "object" && olSourceParams.projection.getCode()) { - p = olGetProj(olSourceParams.projection.getCode()); - } - // puis, selon l'unité de la projection, on calcule la résolution correspondante - if (p && p.getUnits()) { - if (p.getUnits() === "m") { - /* 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 : 1 pixel = 0.00028 m - layerTileOptions.minResolution = (globalConstraints.minScale - 1) * 0.00028; - layerTileOptions.maxResolution = (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); - } - } - } - } - // récupération des autres paramètres passés par l'utilisateur - Utils.mergeParams(layerTileOptions, options.olParams); - - // création d'une ol.layer.Tile avec les options récupérées ci-dessus. - super(layerTileOptions); - - return this; - } - -}; - -export default LayerWMS; - -// Expose LayerWMS as ol.layerGeoportalWMS. (for a build bundle) -if (window.ol && window.ol.layer) { - window.ol.layer.GeoportalWMS = LayerWMS; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMTS.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMTS.d.ts deleted file mode 100644 index f188b41b5..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMTS.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -export default LayerWMTS; -/** - * @classdesc - * Geoportal LayerWMTS source creation (inherit from ol.layer.Tile) - * - * @constructor - * @extends {ol.layer.Tile} - * @alias ol.layer.GeoportalWMTS - * @type {ol.layer.GeoportalWMTS} - * @param {Object} options - options for function call. - * @param {String} options.layer - Layer name (e.g. "ORTHOIMAGERY.ORTHOPHOTOS") - * @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}) - * @param {Object} [options.olParams.sourceParams] - other options for ol.source.WMTS function (see {@link http://openlayers.org/en/latest/apidoc/ol.source.WMTS.html ol.source.WMTS}) - * @example - * var layerWMTS = new ol.layer.GeoportalWMTS({ - * layer : "ORTHOIMAGERY.ORTHOPHOTOS" - * }); - */ -declare var LayerWMTS: ol.layer.GeoportalWMTS; -//# sourceMappingURL=LayerWMTS.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMTS.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMTS.d.ts.map deleted file mode 100644 index 300e51287..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMTS.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"LayerWMTS.d.ts","sourceRoot":"","sources":["../../../../src/packages/Layers/LayerWMTS.js"],"names":[],"mappings":";AASA;;;;;;;;;;;;;;;;;;GAkBG;AACH,8CAwGE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMTS.js b/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMTS.js deleted file mode 100644 index 0f2dcbb7c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/LayerWMTS.js +++ /dev/null @@ -1,140 +0,0 @@ -// import openlayers -import { get as olGetProj } from "ol/proj"; -import TileLayer from "ol/layer/Tile"; -// import local -import Utils from "../Utils/Helper"; -import Config from "../Utils/Config"; -// import local with ol dependencies -import SourceWMTS from "./SourceWMTS"; - -/** - * @classdesc - * Geoportal LayerWMTS source creation (inherit from ol.layer.Tile) - * - * @constructor - * @extends {ol.layer.Tile} - * @alias ol.layer.GeoportalWMTS - * @type {ol.layer.GeoportalWMTS} - * @param {Object} options - options for function call. - * @param {String} options.layer - Layer name (e.g. "ORTHOIMAGERY.ORTHOPHOTOS") - * @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}) - * @param {Object} [options.olParams.sourceParams] - other options for ol.source.WMTS function (see {@link http://openlayers.org/en/latest/apidoc/ol.source.WMTS.html ol.source.WMTS}) - * @example - * var layerWMTS = new ol.layer.GeoportalWMTS({ - * layer : "ORTHOIMAGERY.ORTHOPHOTOS" - * }); - */ -var LayerWMTS = class LayerWMTS extends TileLayer { - - /** - * See {@link ol.layer.GeoportalWMTS} - * @module LayerWMTS - * @alias module:~Layers/GeoportalWMTS - * @param {*} options - options - * @example - * import LayerWMTS from "src/packages/Layers/LayerWMTS" - */ - constructor (options) { - // if (!(this instanceof LayerWMTS)) { - // 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; - } - - // Check if configuration is loaded - if (!Config.isConfigLoaded()) { - throw new Error("ERROR : contract key configuration has to be loaded to load Geoportal layers."); - } - - // création de la source WMTS - var olSourceParams; - if (options.olParams && options.olParams.sourceParams) { - olSourceParams = options.olParams.sourceParams; - } - var wmtsSource = new SourceWMTS({ - layer : options.layer, - ssl : options.ssl, - apiKey : options.apiKey, - olParams : olSourceParams - }); - - var layerTileOptions = { - source : wmtsSource - }; - - // 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) { - /* 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 - // ]; - // layerTileOptions.extent = ol.proj.transformExtent(geobbox, "EPSG:4326", 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); - } - // puis, selon l'unité de la projection, on calcule la résolution correspondante - if (p && p.getUnits()) { - if (p.getUnits() === "m") { - /* 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 : 1 pixel = 0.00028 m - layerTileOptions.minResolution = (globalConstraints.minScale - 1) * 0.00028; - layerTileOptions.maxResolution = (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); - } - } - } - } - - // récupération des autres paramètres passés par l'utilisateur - Utils.mergeParams(layerTileOptions, options.olParams); - - // création d'une ol.layer.Tile avec les options récupérées ci-dessus. - super(layerTileOptions); - - return this; - } - - -}; - -export default LayerWMTS; - -// Expose LayerWMTS as ol.layerGeoportalWMTS. (for a build bundle) -if (window.ol && window.ol.layer) { - window.ol.layer.GeoportalWMTS = LayerWMTS; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMS.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMS.d.ts deleted file mode 100644 index f99d8bd60..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMS.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -export default SourceWMS; -/** - * @classdesc - * Geoportal tile WMS source creation (inherit from ol.source.TileWMS) - * - * @constructor - * @alias ol.source.GeoportalWMS - * @type {ol.source.GeoportalWMS} - * @extends {ol.source.TileWMS} - * @param {Object} options - options for function call. - * @param {String} options.layer - Layer name (e.g. "ORTHOIMAGERY.ORTHOPHOTOS") - * @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 - * @param {Array} [options.metadata] - Metadata objects associated to the layer - * @param {String} [options.title] - title of the layer - * @param {String} [options.description] - description of the layer - * @param {String} [options.quicklookUrl] - quicklookUrl of the layer - * @param {Object} [options.olParams] - other options for ol.source.TileWMS function (see {@link http://openlayers.org/en/latest/apidoc/ol.source.TileWMS.html ol.source.TileWMS}) - * @example - * var sourceWMS = new ol.source.GeoportalWMS({ - * layer : "ORTHOIMAGERY.ORTHOPHOTOS" - * }); - */ -declare var SourceWMS: ol.source.GeoportalWMS; -//# sourceMappingURL=SourceWMS.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMS.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMS.d.ts.map deleted file mode 100644 index 8f6462538..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMS.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"SourceWMS.d.ts","sourceRoot":"","sources":["../../../../src/packages/Layers/SourceWMS.js"],"names":[],"mappings":";AAYA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,8CA8FE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMS.js b/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMS.js deleted file mode 100644 index d222b5f6e..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMS.js +++ /dev/null @@ -1,137 +0,0 @@ -import Gp from "geoportal-access-lib"; -// import OpenLayers -import TileWMSSource from "ol/source/TileWMS"; -// import local -import Utils from "../Utils/Helper"; -import Logger from "../Utils/LoggerByDefault"; -import Config from "../Utils/Config"; -// package.json (extract version) -import Pkg from "../../../package.json"; - -var logger = Logger.getLogger("sourcewms"); - -/** - * @classdesc - * Geoportal tile WMS source creation (inherit from ol.source.TileWMS) - * - * @constructor - * @alias ol.source.GeoportalWMS - * @type {ol.source.GeoportalWMS} - * @extends {ol.source.TileWMS} - * @param {Object} options - options for function call. - * @param {String} options.layer - Layer name (e.g. "ORTHOIMAGERY.ORTHOPHOTOS") - * @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 - * @param {Array} [options.metadata] - Metadata objects associated to the layer - * @param {String} [options.title] - title of the layer - * @param {String} [options.description] - description of the layer - * @param {String} [options.quicklookUrl] - quicklookUrl of the layer - * @param {Object} [options.olParams] - other options for ol.source.TileWMS function (see {@link http://openlayers.org/en/latest/apidoc/ol.source.TileWMS.html ol.source.TileWMS}) - * @example - * var sourceWMS = new ol.source.GeoportalWMS({ - * layer : "ORTHOIMAGERY.ORTHOPHOTOS" - * }); - */ -var SourceWMS = class SourceWMS extends TileWMSSource { - - constructor (options) { - // if (!(this instanceof SourceWMS)) { - // throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - // } - - // check layer params - 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; - } - - // 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"); - - 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 (!Config.configuration.getLayerConf(layerId)) { - throw new Error("ERROR : WMS Layer configuration cannot be found in Geoportal...."); - } - - 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://"; - - var urlParams = { - "gp-ol-ext" : Pkg.olExtVersion || Pkg.version - }; - if (wmsParams.url.includes("/private/")) { - // 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 wmsSourceOptions = { - // tracker extension openlayers - // FIXME : gp-ext version en mode AMD - url : Gp.Helper.normalyzeUrl(wmsParams.url.replace(/(http|https):\/\//, protocol), urlParams, false), - params : { - SERVICE : "WMS", - LAYERS : options.layer, - VERSION : wmsParams.version, - STYLES : wmsParams.styles, - FORMAT : wmsParams.format - } - // , - // attributions : [ - // new ol.Attribution({ - // html : "" - // }) - // ] - }; - - // récupération des autres paramètres passés par l'utilisateur - Utils.mergeParams(wmsSourceOptions, options.olParams); - - // on surcharge les originators (non récupérés depuis configuration de la couche) - if (options.olParams && !wmsParams.originators) { - wmsParams.originators = options.olParams.attributions; - } - - // returns a WMS object, that inherits from ol.source.TileWMS. - super(wmsSourceOptions); - - // save originators (to be updated by Originators control) - this._originators = wmsParams.originators; - - // save legends and metadata (to be added to LayerSwitcher control) - this._legends = options.legends || wmsParams.legends; - this._metadata = options.metadata || wmsParams.metadata; - this._title = options.title || wmsParams.title; - this._description = options.description || wmsParams.description; - this._quicklookUrl = options.quicklookUrl || wmsParams.quicklookUrl; - - return this; - } - -}; - -export default SourceWMS; - -// Expose SourceWMS as ol.source.GeoportalWMTS. (for a build bundle) -if (window.ol && window.ol.source) { - window.ol.source.GeoportalWMS = SourceWMS; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMTS.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMTS.d.ts deleted file mode 100644 index 0f43785da..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMTS.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -export default SourceWMTS; -/** - * @classdesc - * Geoportal WMTS source creation (inherit from ol.source.WMTS) - * - * @constructor - * @alias ol.source.GeoportalWMTS - * @type {ol.source.GeoportalWMTS} - * @extends {WMTSExtended} - * @param {Object} options - options for function call. - * @param {String} options.layer - Layer name (e.g. "ORTHOIMAGERY.ORTHOPHOTOS") - * @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 - * @param {Array} [options.metadata] - Metadata objects associated to the layer - * @param {String} [options.title] - title of the layer - * @param {String} [options.description] - description of the layer - * @param {String} [options.quicklookUrl] - quicklookUrl of the layer - * @param {Object} [options.olParams] - other options for ol.source.WMTS function (see {@link http://openlayers.org/en/latest/apidoc/ol.source.WMTS.html ol.source.WMTS}) - * @example - * var sourceWMTS = new ol.source.GeoportalWMTS({ - * layer : "ORTHOIMAGERY.ORTHOPHOTOS" - * }); - */ -declare var SourceWMTS: ol.source.GeoportalWMTS; -//# sourceMappingURL=SourceWMTS.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMTS.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMTS.d.ts.map deleted file mode 100644 index cebe2a935..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMTS.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"SourceWMTS.d.ts","sourceRoot":"","sources":["../../../../src/packages/Layers/SourceWMTS.js"],"names":[],"mappings":";AAeA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,gDA6FE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMTS.js b/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMTS.js deleted file mode 100644 index 4566650a9..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/SourceWMTS.js +++ /dev/null @@ -1,139 +0,0 @@ -import Gp from "geoportal-access-lib"; -// import OpenLayers -import WMTSTileGrid from "ol/tilegrid/WMTS"; -// import local with ol dependencies -import WMTSExtended from "../Sources/WMTS"; -// import local -import Utils from "../Utils/Helper"; -import LayerUtils from "../Utils/LayerUtils"; -import Logger from "../Utils/LoggerByDefault"; -import Config from "../Utils/Config"; -// package.json (extract version) -import Pkg from "../../../package.json"; - -var logger = Logger.getLogger("sourcewmts"); - -/** - * @classdesc - * Geoportal WMTS source creation (inherit from ol.source.WMTS) - * - * @constructor - * @alias ol.source.GeoportalWMTS - * @type {ol.source.GeoportalWMTS} - * @extends {WMTSExtended} - * @param {Object} options - options for function call. - * @param {String} options.layer - Layer name (e.g. "ORTHOIMAGERY.ORTHOPHOTOS") - * @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 - * @param {Array} [options.metadata] - Metadata objects associated to the layer - * @param {String} [options.title] - title of the layer - * @param {String} [options.description] - description of the layer - * @param {String} [options.quicklookUrl] - quicklookUrl of the layer - * @param {Object} [options.olParams] - other options for ol.source.WMTS function (see {@link http://openlayers.org/en/latest/apidoc/ol.source.WMTS.html ol.source.WMTS}) - * @example - * var sourceWMTS = new ol.source.GeoportalWMTS({ - * layer : "ORTHOIMAGERY.ORTHOPHOTOS" - * }); - */ -var SourceWMTS = class SourceWMTS extends WMTSExtended { - - constructor (options) { - // if (!(this instanceof SourceWMTS)) { - // throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - // } - - // check layer params - 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; - } - - // 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...."); - } - - 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://"; - - var urlParams = { - "gp-ol-ext" : Pkg.olExtVersion || Pkg.version - }; - if (wmtsParams.url.includes("/private/")) { - // 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 wmtsSourceOptions = { - // tracker extension openlayers - // FIXME : gp-ext version en mode AMD - url : Gp.Helper.normalyzeUrl(wmtsParams.url.replace(/(http|https):\/\//, protocol), urlParams, false), - version : wmtsParams.version, - style : wmtsParams.styles, - format : wmtsParams.format, - projection : wmtsParams.projection, - maxZoom : LayerUtils.getZoomLevelFromScaleDenominator(wmtsParams.minScale), - layer : options.layer, - matrixSet : wmtsParams.TMSLink, - tileGrid : new WMTSTileGrid({ - resolutions : wmtsParams.nativeResolutions, - matrixIds : wmtsParams.matrixIds, - origin : [wmtsParams.tileMatrices[0].topLeftCorner.x, wmtsParams.tileMatrices[0].topLeftCorner.y] - }) - }; - - // récupération des autres paramètres passés par l'utilisateur - Utils.mergeParams(wmtsSourceOptions, options.olParams); - - // on surcharge les originators (non récupérés depuis configuration de la couche) - if (options.olParams && !wmtsParams.originators) { - wmtsParams.originators = options.olParams.attributions; - } - - // returns a WMTS object, that inherits from WMTSExtended. - super(wmtsSourceOptions); - - // add originators to layer source (to be updated by Originators control) - this._originators = wmtsParams.originators; - - // add legends and metadata (to be added to LayerSwitcher control) - this._legends = options.legends || wmtsParams.legends; - this._metadata = options.metadata || wmtsParams.metadata; - this._description = options.description || wmtsParams.description; - this._title = options.title || wmtsParams.title; - this._quicklookUrl = options.quicklookUrl || wmtsParams.quicklookUrl; - - return this; - } - -}; - -export default SourceWMTS; - -// Expose SourceWMTS as ol.source.GeoportalWMTS. (for a build bundle) -if (window.ol && window.ol.source) { - window.ol.source.GeoportalWMTS = SourceWMTS; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/WFS.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Layers/WFS.d.ts deleted file mode 100644 index cb632f838..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/WFS.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default WFS; -declare var WFS: {}; -//# sourceMappingURL=WFS.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/WFS.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Layers/WFS.d.ts.map deleted file mode 100644 index dea49d50b..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/WFS.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"WFS.d.ts","sourceRoot":"","sources":["../../../../src/packages/Layers/WFS.js"],"names":[],"mappings":";AAAA,oBAAa"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Layers/WFS.js b/build/release/geoportal-extensions-openlayers/src/packages/Layers/WFS.js deleted file mode 100644 index 1ece8c7b5..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Layers/WFS.js +++ /dev/null @@ -1,3 +0,0 @@ -var WFS = {}; - -export default WFS; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Services/Search.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Services/Search.d.ts deleted file mode 100644 index d1ea9c71a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Services/Search.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -declare namespace _default { - export { target }; - export { suggest }; - export { clear }; - export { getSuggestions }; - export { getNames }; - export { getTitles }; - export { setIndex }; - export { setFields }; - export { setSize }; - export { setUrl }; - export { setMaximumResponses }; - export { setFiltersByService }; -} -export default _default; -/** - * Interface pour les evenements - * @example - * target.dispatchEvent(new CustomEvent("myEvent", { detail : {} })); - * target.addEventListener("myEvent", handler); - */ -declare const target: EventTarget; -/** - * Appel du service de recherche - * @param {*} text - recherche - * @returns {Object} json - * @fire suggest - */ -declare function suggest(text: any): Object; -declare function clear(): void; -declare function getSuggestions(): any[]; -declare function getNames(): any[]; -declare function getTitles(): any[]; -declare function setIndex(value: any): void; -declare function setFields(value: any): void; -declare function setSize(value: any): void; -declare function setUrl(value: any): void; -declare function setMaximumResponses(value: any): void; -declare function setFiltersByService(value: any): void; -//# sourceMappingURL=Search.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Services/Search.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Services/Search.d.ts.map deleted file mode 100644 index c02a3a31d..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Services/Search.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Search.d.ts","sourceRoot":"","sources":["../../../../src/packages/Services/Search.js"],"names":[],"mappings":";;;;;;;;;;;;;;;AA6BA;;;;;GAKG;AACH,kCAAiC;AAEjC;;;;;GAKG;AACH,qCAHa,MAAM,CAwFlB;AAaD,+BAGC;AAGD,yCAEC;AACD,mCAEC;AACD,oCAEC;AAGD,4CAEC;AACD,6CAEC;AACD,2CAEC;AACD,0CAEC;AACD,uDAEC;AACD,uDAEC"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Services/Search.js b/build/release/geoportal-extensions-openlayers/src/packages/Services/Search.js deleted file mode 100644 index bb3ec8ae1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Services/Search.js +++ /dev/null @@ -1,191 +0,0 @@ -/** - * Gestion du service de recherche de couches - * @see https://geoservices.ign.fr/documentation/services/services-geoplateforme/service-geoplateforme-de-recherche - */ - -/** resultats du service */ -let m_suggestions = []; - -/** gestion annulation du fetch */ -let controller = new AbortController(); - -/** index de recherche */ -let m_index = "geoplateforme"; - -/** liste des champs de recherche */ -let m_fields = "title,layer_name"; - -/** nombre de suggestions du service */ -let m_size = "1000"; - -/** nombre maximum de réponses */ -let m_maximumResponses = 10; - -/** liste des filtres sur les services */ -let m_services = ["WMTS", "WMS"]; - -/** url du service (template avec ${m_index}) */ -let m_url = `https://data.geopf.fr/recherche/api/indexes/${m_index}/suggest`; - -/** - * Interface pour les evenements - * @example - * target.dispatchEvent(new CustomEvent("myEvent", { detail : {} })); - * target.addEventListener("myEvent", handler); - */ -const target = new EventTarget(); - -/** - * Appel du service de recherche - * @param {*} text - recherche - * @returns {Object} json - * @fire suggest - */ -const suggest = async (text) => { - // ex. request - // https://data.geopf.fr/recherche/api/indexes/geoplateforme/suggest?text=ORTHO&fields=title - clear(); - - controller = new AbortController(); - - let url = new URL(m_url); - let params = { - text : text, - fields : m_fields, - size : m_size - }; - - Object.keys(params).forEach(key => url.searchParams.append(key, params[key])); - - var response = await fetch(url, { - // FIXME - // signal : controller.signal - }); - - var results = await response.json(); - - if (response.status !== 200) { - throw new Error(response.message); - } - - // ex. response - // [ - // { - // "index": "geoplateforme", - // "score": 3.4832718, - // "source": { - // "id": "fc2af911-d9c2-4fc8-aee7-46034eebf821", - // "offering_id": "faa4c69c-d03b-4502-af87-7f3667411321", - // "index_name": "geoplateforme", - // "layer_name": "nl_bdtopo_allauch", - // "title": "NL - BD Topo : Allauch", - // "description": "Extrait de BD TOPo sur Allauch", - // "type": "WMS", - // "url": "https://data.geopf.fr/wms-v?service=WMS&version=1.3.0&request=GetMap&layers=nl_bdtopo_allauch&bbox={xmin},{ymin},{xmax},{ymax}&styles={styles}&width={width}&height={height}&srs={srs}&format={format}", - // "open": true, - // "publication_date": "2023-11-27", - // "keywords": [ - // "BDTOPO", - // "Recette" - // ], - // "extent": {}, - // "metadata_urls": [], - // "srs": [ - // "EPSG:2154" - // ] - // } - // } - // ] - if (!results || results.length === 0) { - return; - } - - for (let i = 0; i < results.length; i++) { - const result = results[i]; - var services = (m_services.length === 0 || m_services.includes(result.source.type)); - if (services) { - if (unique().length >= m_maximumResponses) { - break; - } - var o = { - name : result.source.layer_name, - title : result.source.title, - description : result.source.description, - service : result.source.type, - url : result.source.url - }; - m_suggestions.push(o); - } - } - - target.dispatchEvent( - new CustomEvent("suggest", { - bubbles : true, - detail : getSuggestions() - }) - ); - - return getSuggestions(); -}; - -const unique = () => { - return m_suggestions.filter((value, index, self) => - index === self.findIndex((t) => ( - t.service === value.service && - t.name === value.name && - t.title === value.title && - t.description === value.description - )) - ); -}; - -const clear = () => { - controller.abort(); - m_suggestions = []; -}; - -// getter (reponse) -const getSuggestions = () => { - return unique(); -}; -const getNames = () => { - return unique().map((o) => { return o.name; }); -}; -const getTitles = () => { - return unique().map((o) => { return o.title; }); -}; - -// setter (conf) -const setIndex = (value) => { - m_index = value; -}; -const setFields = (value) => { - m_fields = value; -}; -const setSize = (value) => { - m_size = parseInt(value); -}; -const setUrl = (value) => { - m_url = eval("`" + value + "`"); // insecure ! -}; -const setMaximumResponses = (value) => { - m_maximumResponses = parseInt(value); -}; -const setFiltersByService = (value) => { - m_services = value === "" ? [] : value.split(","); -}; - -export default { - target, - suggest, - clear, - getSuggestions, - getNames, - getTitles, - setIndex, - setFields, - setSize, - setUrl, - setMaximumResponses, - setFiltersByService -}; \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Sources/WMTS.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Sources/WMTS.d.ts deleted file mode 100644 index 1ef198694..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Sources/WMTS.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -export default WMTS; -/** - * @classdesc - * - * Extended ol.source.WMTS. - * - * @constructor - * @alias ol.source.WMTSExtended - * @type {ol.source.WMTS} - * @extends {ol.source.WMTS} - * @param {Object} options - Options - */ -declare var WMTS: ol.source.WMTS; -//# sourceMappingURL=WMTS.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Sources/WMTS.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Sources/WMTS.d.ts.map deleted file mode 100644 index a391df652..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Sources/WMTS.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"WMTS.d.ts","sourceRoot":"","sources":["../../../../src/packages/Sources/WMTS.js"],"names":[],"mappings":";AAaA;;;;;;;;;;GAUG;AACH,iCAuGE"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Sources/WMTS.js b/build/release/geoportal-extensions-openlayers/src/packages/Sources/WMTS.js deleted file mode 100644 index 0e850f7c5..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Sources/WMTS.js +++ /dev/null @@ -1,135 +0,0 @@ -// import OpenLayers -import WMTSSource from "ol/source/WMTS"; -import { - extend, - createEmpty as olCreateEmpty, - getWidth as olGetWidth, - intersects as olIntersects -} from "ol/extent"; -// import geoportal library access -import Gp from "geoportal-access-lib"; -// import local -import Utils from "../Utils/Helper"; - -/** - * @classdesc - * - * Extended ol.source.WMTS. - * - * @constructor - * @alias ol.source.WMTSExtended - * @type {ol.source.WMTS} - * @extends {ol.source.WMTS} - * @param {Object} options - Options - */ -var WMTS = class WMTS extends WMTSSource { - - constructor (options) { - // if (!(this instanceof WMTS)) { - // throw new TypeError("ERROR CLASS_CONSTRUCTOR"); - // } - - // call constructor - super(options); - } - - /** - * Return the GetFeatureInfo URL for the passed coordinate, resolution, and - * projection. Return `undefined` if the GetFeatureInfo URL cannot be - * constructed. - * @param {ol.Coordinate} coordinate - Coordinate. - * @param {Number} resolution - Resolution. - * @param {ol.proj.Projection} projection - Projection. - * @param {!Object} params - GetFeatureInfo params. `INFOFORMAT` at least should - * be provided. - * @return {String|undefined} GetFeatureInfo URL. - */ - getFeatureInfoUrl (coordinate, resolution, projection, params) { - // INFO - // en fonction de la version d'openlayers, la méthode est differente : - // - getGetFeatureInfoUrl en v5 - // - getFeatureInfoUrl en v6 - var pixelRatio = (this.options && this.options.tilePixelRatio) ? this.options.tilePixelRatio : 1; - - var tileGrid = this.tileGrid; - var tileCoord = this.tileGrid.getTileCoordForCoordAndResolution(coordinate, resolution); - - // this code is duplicated from createFromWMTSTemplate function - var getTransformedTileCoord = function (tileCoord, tileGrid, projection) { - var tmpTileCoord = [0, 0, 0]; /* Note : [z(zoomLevel),x,y] */ - var tmpExtent = olCreateEmpty(); - var x = tileCoord[1]; - var y = tileCoord[2]; - var tileExtent = tileGrid.getTileCoordExtent(tileCoord); - var extent = projection.getExtent(); - - if (extent != null && projection.isGlobal()) { - var numCols = Math.ceil(olGetWidth(extent) / olGetWidth(tileExtent)); - x = x % numCols; - tmpTileCoord[0] = tileCoord[0]; - tmpTileCoord[1] = x; - tmpTileCoord[2] = tileCoord[2]; - tileExtent = tileGrid.getTileCoordExtent(tmpTileCoord, tmpExtent); - } - if (!olIntersects(tileExtent, extent) /* || ol.extent.touches(tileExtent, extent) */) { - return null; - } - return [tileCoord[0], x, y]; - }; - - var tileExtent = tileGrid.getTileCoordExtent(tileCoord); - var transformedTileCoord = getTransformedTileCoord(tileCoord, tileGrid, projection); - - if (tileGrid.getResolutions().length <= tileCoord[0]) { - return undefined; - } - - var tileResolution = tileGrid.getResolution(tileCoord[0]); - var tileMatrix = tileGrid.getMatrixIds()[tileCoord[0]]; - - var baseParams = { - SERVICE : "WMTS", - VERSION : "1.0.0", - REQUEST : "GetFeatureInfo", - LAYER : this.getLayer(), - TILECOL : transformedTileCoord[1], - TILEROW : transformedTileCoord[2], - TILEMATRIX : tileMatrix, - TILEMATRIXSET : this.getMatrixSet(), - FORMAT : this.getFormat() || "image/png", - STYLE : this.getStyle() || "normal" - }; - - Utils.assign(baseParams, params); - - /* var tileSize = tileGrid.getTileSize(); - var x = Math.floor(tileSize*((coordinate[0]-tileExtent[0])/(tileExtent[2]-tileExtent[0]))); - var y = Math.floor(tileSize*((tileExtent[3]-coordinate[1])/(tileExtent[3]-tileExtent[1]))); */ - - var x = Math.floor((coordinate[0] - tileExtent[0]) / (tileResolution / pixelRatio)); - var y = Math.floor((tileExtent[3] - coordinate[1]) / (tileResolution / pixelRatio)); - - /* patch parce que la fonction getTileCoordForCoordAndResolution(coords,res) d'Openlayers peut renvoyer - une tuile dont l'étendue (getTileCoordExtent) ne contient pas le point passé en paramètre (coords) */ - var tileSize = tileGrid.getTileSize(tileCoord[0]); - x = Math.min(x, (tileSize[0] | tileSize) - 1); - y = Math.max(y, 0); - - baseParams["I"] = x; - baseParams["J"] = y; - - var url = this.urls[0]; - - var featureInfoUrl = Gp.Helper.normalyzeUrl(url, baseParams); - - return featureInfoUrl; - }; - -}; - -export default WMTS; - -// Expose WMTS as ol.source.WMTSExtended. (for a build bundle) -if (window.ol && window.ol.source) { - window.ol.source.WMTSExtended = WMTS; -} diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/AutoLoadConfig.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/AutoLoadConfig.d.ts deleted file mode 100644 index 1172478a4..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/AutoLoadConfig.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=AutoLoadConfig.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/AutoLoadConfig.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/AutoLoadConfig.d.ts.map deleted file mode 100644 index 19a72f99d..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/AutoLoadConfig.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"AutoLoadConfig.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/AutoLoadConfig.js"],"names":[],"mappings":""} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/AutoLoadConfig.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/AutoLoadConfig.js deleted file mode 100644 index 47583cefd..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/AutoLoadConfig.js +++ /dev/null @@ -1,48 +0,0 @@ -import Gp from "geoportal-access-lib"; - -(function () { - var scripts = document.getElementsByTagName("script"); - - var key = scripts[scripts.length - 1].getAttribute("data-key"); - var url = scripts[scripts.length - 1].getAttribute("data-url"); - var timeout = scripts[scripts.length - 1].getAttribute("data-timeout"); - - // callback - var success = function () { - // Pas de messages en mode prod - // console.log("GetConfig success!"); - }; - - // callback - var error = function (e) { - throw new Error("Configuration load failed : " + e.message); - }; - - if (!key && !url) { - // pas de message d'information ! - // console.log("WARNING : parameters missing 'data-key' and 'data-url', the loading of configuration can not be done !"); - return; - } - - var options = { - apiKey : key, - sync : true, - onSuccess : success, - onFailure : error - }; - - if (url) { - options.customConfigFile = url; - options.callbackSuffix = ""; - } - - if (timeout) { - options.timeOut = timeout; - } - - // test d'existance de la varibale globale Gp.Config - if (!window.Gp) { - // appel du service - Gp.Services.getConfig(options); - } -})(); diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/ColorUtils.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/ColorUtils.d.ts deleted file mode 100644 index 052062e94..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/ColorUtils.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -export default ColorUtils; -declare namespace ColorUtils { - function hex(number: number): string; - function num(hexa: any): number; - function arrayToRgba(values: any[]): string; - function arrayToHex(values: any[]): Object; - function rgbaToHex(rgba: string): Object; - function hexToRgba(hex: string, opacity: number): string; - function isHex(value: any): boolean; - function isRGB(value: any): boolean; -} -//# sourceMappingURL=ColorUtils.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/ColorUtils.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/ColorUtils.d.ts.map deleted file mode 100644 index b2426b646..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/ColorUtils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ColorUtils.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/ColorUtils.js"],"names":[],"mappings":";;IAsBU,qCAML;IAQK,gCAEL;IASa,4CAUb;IASY,2CAgBZ;IAUW,yCAkBX;IAWW,yDAkBX;IAOO,oCAaP;IAOO,oCAUP"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/ColorUtils.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/ColorUtils.js deleted file mode 100644 index 3274ae342..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/ColorUtils.js +++ /dev/null @@ -1,180 +0,0 @@ -/** - * @module ColorUtils - * @alias Gp.ColorUtils - * @description - * ... - * - * @example - * arrayTorgba(); - * arrayToHex(); - * rgbaToHex(); - * hexToRgba(); - * isHex(); - * isRGB(); - */ -var ColorUtils = { - - /** - * Number to hex conversion - * - * @param {Number} number - 0-255 - * @returns {String} hex value - */ - hex : function (number) { - if (number > 255) { - throw new Error("'" + number + "'' is greater than 255(0xff);"); - } - var str = Number(number).toString(16); - return ("0" + str).slice(-2); - }, - - /** - * Hexa to number conversion - * - * @param {*} hexa 00-FF - * @returns {Number} number value - */ - num : function (hexa) { - return parseInt(hexa, 16); - }, - - /** - * Converts an array ([255,255,255,1]) to rgba string - * - * @function arrayToRgba - * @param {Array} values - array of values - * @returns {String} A color of RGB or RGBA format - */ - arrayToRgba : function (values) { - if (!Array.isArray(values)) { - throw new Error("Not an array !"); - } - var red = values[0]; - var green = values[1]; - var blue = values[2]; - var alpha = values[3] || 1; - var result = "rgba(" + red + ", " + green + ", " + blue + ", " + parseFloat(alpha) + ")"; - return result; - }, - - /** - * Converts an array ([255,255,255,1]) to #RRGGBBAA - * - * @function arrayToHex - * @param {Array} values - array of values - * @returns {Object} hex and opacity formated values - */ - arrayToHex : function (values) { - if (!Array.isArray(values)) { - throw new Error("Not an array !"); - } - var red = values[0]; - var green = values[1]; - var blue = values[2]; - var alpha = values[3]; - var elems = [this.hex(red), this.hex(green), this.hex(blue)]; - var result = {}; - result.hex = "#" + elems.join(""); - if (alpha) { - // elems.push(hex(alpha)); - result.opacity = parseFloat(alpha); - } - return result; - }, - - /** - * Converts rgba string to #RRGGBBAA - * (Code adapted from : https://gist.github.com/mstssk/afda4ce9e5c335fd79cd) - * - * @function rgbaToHex - * @param {String} rgba - A color of RGB or RGBA format. - * @returns {Object} hex and opacity formated values - */ - rgbaToHex : function (rgba) { - var regex = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(0?.?\d+)\s*)?\)/; - var parsed = regex.exec(rgba); - if (!parsed) { - throw new Error("Invalid format: " + rgba); - } - var red = parsed[1]; - var green = parsed[2]; - var blue = parsed[3]; - var alpha = parsed[4]; - var elems = [this.hex(red), this.hex(green), this.hex(blue)]; - var result = {}; - result.hex = "#" + elems.join(""); - if (alpha) { - // elems.push(hex(alpha)); - result.opacity = parseFloat(alpha); - } - return result; - }, - - /** - * Converts hex color and opacity value to rgba string. - * (Code adapted from : http://stackoverflow.com/a/5624139) - * - * @function hexToRgba - * @param {String} hex - A color value on RGB format (hexa). - * @param {Number} opacity - A opacity value. - * @returns {String} A color of RGB or RGBA format - */ - hexToRgba : function (hex, opacity) { - // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") - var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - if (!hex) { - throw new Error("Invalid format"); - } - hex = hex.replace(shorthandRegex, function (m, r, g, b) { - return r + r + g + g + b + b; - }); - - var rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - rgb = rgb ? { - r : parseInt(rgb[1], 16), - g : parseInt(rgb[2], 16), - b : parseInt(rgb[3], 16) - } : null; - var result = rgb ? "rgba(" + rgb.r + ", " + rgb.g + ", " + rgb.b + ", " + opacity + ")" : null; - return result; - }, - - /** - * Determine if value is a correct hexa color. - * @param {*} value - hex color (#FFFFFF) - * @returns {Boolean} True if value is a hexa color - */ - isHex : function (value) { - if (!value) { - return false; - } - if (value.charAt(0) !== "#") { - return false; - } - var regex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i; - var parsed = regex.exec(value); - if (!parsed) { - return false; - } - return true; - }, - - /** - * Determine if value is a correct rgba color. - * @param {*} value - rgba color (rgba(125,125,125,1)) - * @returns {Boolean} True if value is a rgba color - */ - isRGB : function (value) { - if (!value) { - return false; - } - var regex = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(0?.?\d+)\s*)?\)/; - var parsed = regex.exec(value); - if (!parsed) { - return false; - } - return true; - } -}; - -export default ColorUtils; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Config.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Config.d.ts deleted file mode 100644 index f2cf3f749..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Config.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default Config; -declare namespace Config { - let configuration: Object; - function isConfigLoaded(): boolean; -} -//# sourceMappingURL=Config.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Config.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Config.d.ts.map deleted file mode 100644 index 9bf110692..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Config.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Config.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/Config.js"],"names":[],"mappings":";;uBAec,MAAM;IASC,mCAWhB"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Config.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Config.js deleted file mode 100644 index 09e3032b7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Config.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @module Config - * @alias [private] Config - * @description - * ... - * - * @example - * isConfigLoaded(); - */ -var Config = { - - /** - * Config - * - * @public - * @type {Object} - */ - configuration : {}, - - /** - * Check if the configuration is loaded - * - * @returns {Boolean} True if Config is loaded, false otherwise - */ - isConfigLoaded : function () { - // config already loaded ! - if (this.configuration && Object.keys(this.configuration).length !== 0) { - return true; - } - var scope = typeof window !== "undefined" ? window : typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : {}; - if (scope.Gp && scope.Gp.Config && scope.Gp.Config.layers && Object.keys(scope.Gp.Config.layers).length !== 0) { - /** ts-syntax */ (this.configuration) = scope.Gp.Config; - return true; - } - return false; - } - -}; - -export default Config; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Draggable.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Draggable.d.ts deleted file mode 100644 index 7ce40a3d7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Draggable.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default Draggable; -declare namespace Draggable { - function dragElement(element: DOMElement, header: DOMElement, container: DOMElement): void; -} -//# sourceMappingURL=Draggable.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Draggable.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Draggable.d.ts.map deleted file mode 100644 index 83ea17142..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Draggable.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Draggable.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/Draggable.js"],"names":[],"mappings":";;IAuCkB,2FA0Fb"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Draggable.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Draggable.js deleted file mode 100644 index ed33b7028..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Draggable.js +++ /dev/null @@ -1,133 +0,0 @@ -import Logger from "./LoggerByDefault"; - -var logger = Logger.getLogger("draggable"); - -/** - * @module Draggable - * @alias [private] Draggable - * @fixme conflit entre la position et le mode draggable - * @description - * ... - * - * @example - * dragElement(); - */ -var Draggable = { - /** - * A draggable HTML element with JavaScript and CSS. - * - * @function dragElement - * @param {DOMElement} element - element - * @param {DOMElement} header - header (optional) - * @param {DOMElement} container - container (optional) - * @see https://www.w3schools.com/howto/howto_js_draggable.asp - * @see https://stackoverflow.com/questions/52231588/how-to-constrain-div-drag-space-no-jquery - * @example - * // CSS : - * // #element { position: absolute; } - * // HTML : - * //
- * //
- * // - * //
- * // JS : - * var element = document.getElementById("element"); - * Draggable.dragElement(element, header, container); - */ - dragElement : function (element, header, container) { - var offsetX, offsetY; - - var isDragReady = false; - - var dragoffset = { - x : 0, - y : 0 - }; - - if (header) { - header.addEventListener("mousedown", dragMouseDown, true); - } else { - element.addEventListener("mousedown", dragMouseDown, true); - } - - // TODO mettre en place les contraintes - // var constraints = {}; - // if (container) { - // constraints = { - // width : container.clientWidth, - // height : container.clientHeight, - // top : container.offsetTop, - // left : container.offsetLeft - // }; - // } - - function dragMouseDown (e) { - e = e || window.event; - e.preventDefault(); - - isDragReady = true; - - // get the mouse cursor position at startup - e._pageX = e._pageX || e.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft); - e._pageY = e._pageY || e.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); - dragoffset.x = e._pageX - element.offsetLeft; - dragoffset.y = e._pageY - element.offsetTop; - - document.addEventListener("mouseup", closeDragElement, true); - document.addEventListener("mousemove", elementDrag, true); - } - - function closeDragElement () { - /* stop moving when mouse button is released: */ - isDragReady = false; - document.removeEventListener("mouseup", closeDragElement, true); - document.removeEventListener("mousemove", elementDrag, true); - } - - function elementDrag (e) { - e = e || window.event; - // e.preventDefault(); - - // cf. https://jsfiddle.net/nbbg08mg/2/ - if (isDragReady) { - e._pageX = e._pageX || e.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft); - e._pageY = e._pageY || e.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); - - var parentLeft = container ? container.offsetLeft : element.parentElement.offsetLeft; - var parentTop = container ? container.offsetTop : element.parentElement.parentElement.offsetTop; // hack pas jolie ! - logger.trace("parent offset", parentLeft, parentTop); - - // left/right constraint - if (e._pageX - dragoffset.x < 0 - parentLeft) { - offsetX = 0 - parentLeft; - } else if (e._pageX - dragoffset.x + element.clientWidth > document.body.clientWidth) { - offsetX = document.body.clientWidth - element.clientWidth; - } else { - offsetX = e._pageX - dragoffset.x; - } - logger.trace("left/right constraint", offsetX); - - // top/bottom constraint - if (e._pageY - dragoffset.y < 0 - parentTop) { - offsetY = 0 - parentTop; - } else if (e._pageY - dragoffset.y + element.clientHeight > document.body.clientHeight) { - offsetY = document.body.clientHeight - element.clientHeight; - } else { - offsetY = e._pageY - dragoffset.y; - } - logger.trace("top/bottom constraint", offsetY); - - // set the element's new position: - element.style.top = offsetY + "px"; - element.style.bottom = "unset"; - element.style.left = offsetX + "px"; - element.style.right = "unset"; - } - } - } -}; - -export default Draggable; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/GeocodeUtils.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/GeocodeUtils.d.ts deleted file mode 100644 index ea40a52b2..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/GeocodeUtils.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default GeocodeUtils; -declare namespace GeocodeUtils { - function getGeocodedLocationFreeform(geocodedLocation: Object): string; - function getSuggestedLocationFreeform(suggestedLocation: Object): string; -} -//# sourceMappingURL=GeocodeUtils.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/GeocodeUtils.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/GeocodeUtils.d.ts.map deleted file mode 100644 index 97e307ac7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/GeocodeUtils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"GeocodeUtils.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/GeocodeUtils.js"],"names":[],"mappings":";;IAOkC,uEA0B7B;IAQ8B,yEAe9B"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/GeocodeUtils.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/GeocodeUtils.js deleted file mode 100644 index 291c4b00e..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/GeocodeUtils.js +++ /dev/null @@ -1,60 +0,0 @@ -var GeocodeUtils = { - /** - * Return the freeform of a structured geocoded item - * - * @param {Object} geocodedLocation - Geocoded location - * @returns {String} freeform string - */ - getGeocodedLocationFreeform : function (geocodedLocation) { - var attributes = geocodedLocation.placeAttributes; - if (attributes.label) { - return attributes.label; - } else if (geocodedLocation.type === "PositionOfInterest") { - var resultToReturn = attributes.toponym; - if (attributes.category && Array.isArray(attributes.category) && attributes.category.length >= 2 && attributes.category[0] === "administratif") { - // gestion particulière des territoires administratifs - resultToReturn = resultToReturn + ", " + attributes.category[1]; - } else { - // gestion standard des POI non adminsitratifs - if (attributes.postcode) { - resultToReturn = resultToReturn + ", " + attributes.postcode[0]; - if (attributes.city) { - resultToReturn = resultToReturn + " " + attributes.city[0]; - } - } - } - return resultToReturn; - } else if (geocodedLocation.type === "StreetAddress") { - return (attributes.housenumber ? attributes.housenumber + " " : "") + attributes.street + " " + (attributes.postcode ? attributes.postcode + ", " : "") + attributes.city; - } else if (geocodedLocation.type === "CadastralParcel") { - return attributes.id; - } else { - return "..."; - } - }, - - /** - * Return the freeform of a structured suggested item - * - * @param {Object} suggestedLocation - Suggested location - * @returns {String} freeform string - */ - getSuggestedLocationFreeform : function (suggestedLocation) { - if (suggestedLocation.fullText) { - return suggestedLocation.fullText; - } else { - var values = []; - values.push(suggestedLocation.street || ""); - values.push(suggestedLocation.postalCode || ""); - values.push(suggestedLocation.commune || ""); - - if (suggestedLocation.type === "PositionOfInterest") { - values.push(suggestedLocation.poi || ""); - values.push(suggestedLocation.kind || ""); - } - return values.join(" - "); - } - } -}; - -export default GeocodeUtils; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Helper.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Helper.d.ts deleted file mode 100644 index 37466acf7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Helper.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default Helper; -declare namespace Helper { - function detectSupport(): boolean; - function assign(dest: Object, source: Object): Object; - function mergeParams(dest: Object, source: Object, replace: boolean): void; -} -//# sourceMappingURL=Helper.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Helper.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Helper.d.ts.map deleted file mode 100644 index 29a6bcae1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Helper.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Helper.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/Helper.js"],"names":[],"mappings":";;IAqBoB,kCAsBf;IAUQ,sDAQR;IAUa,2EA0Bb"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Helper.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Helper.js deleted file mode 100644 index 63d585354..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Helper.js +++ /dev/null @@ -1,101 +0,0 @@ -/** -* @module Helper -* @alias Gp.HelperUtils -* @description -* ... -* -* @example -* detectSupport(); -* assign(); -* mergeParams(); -*/ -var Helper = { - - /** - * this method is called by the constructor. - * this information is useful to switch to touch mode. - * Detection : test for desktop or tactile - * - * @function detectSupport - * @returns {Boolean} isDesktop - true for desktop userAgent, false for mobile - */ - detectSupport : function () { - var isDesktop = true; - var userAgent = window.navigator.userAgent.toLowerCase(); - - if (userAgent.indexOf("iphone") !== -1 || - userAgent.indexOf("ipod") !== -1 || - userAgent.indexOf("ipad") !== -1 || - userAgent.indexOf("android") !== -1 || - userAgent.indexOf("mobile") !== -1 || - userAgent.indexOf("blackberry") !== -1 || - userAgent.indexOf("tablet") !== -1 || - userAgent.indexOf("phone") !== -1 || - userAgent.indexOf("touch") !== -1) { - isDesktop = false; - } - - if (userAgent.indexOf("msie") !== -1 || - userAgent.indexOf("trident") !== -1) { - isDesktop = true; - } - - return isDesktop; - }, - - /** - * Copies all source object members to dest - * - * @function assign - * @param {Object} dest - destination object where properties and method will be copied - * @param {Object} source - source object from which properties and method will be copied - * @returns {Object} dest - */ - assign : function (dest, source) { - dest = dest || {}; - for (var prop in source) { - if (source.hasOwnProperty(prop)) { - dest[prop] = source[prop]; - } - } - return dest; - }, - - /** - * Merge two objects parameters (deeper than assign) - * - * @function mergeParams - * @param {Object} dest - destination object where properties and method will be merge - * @param {Object} source - source object from which properties and method will be merge - * @param {Boolean} replace - replace destination value by source if exists or not (true by default) - */ - mergeParams : function (dest, source, replace) { - if (!dest || !source) { - return; - } - if (typeof replace === "undefined") { - replace = true; - } - for (var param in source) { - if (source.hasOwnProperty(param)) { - if (typeof source[param] === "object") { - if (dest.hasOwnProperty(param)) { - this.mergeParams(dest[param], source[param], replace); - } else { - dest[param] = source[param]; - } - } else { - if (dest.hasOwnProperty(param)) { - if (replace) { - dest[param] = source[param]; - } - } else { - dest[param] = source[param]; - } - } - } - } - } -}; - -export default Helper; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/LayerUtils.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/LayerUtils.d.ts deleted file mode 100644 index e04ac6d80..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/LayerUtils.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -export default LayerUtils; -declare namespace LayerUtils { - function getZoomLevelFromScaleDenominator(scaleDenominator: number, crs: string): Integer; - function getAttributions(params: { - extent: Float[]; - zoom: number; - crs: string; - visibility: boolean; - originators: Gp.Services.Config.Originator; - }): Object; - function intersects(extent1: Float[], extent2: Float[]): boolean; -} -//# sourceMappingURL=LayerUtils.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/LayerUtils.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/LayerUtils.d.ts.map deleted file mode 100644 index 29b174325..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/LayerUtils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"LayerUtils.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/LayerUtils.js"],"names":[],"mappings":";;IAqBuC,0FAgKlC;IAciB;;;;;;eAsGjB;IAUY,iEAIZ"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/LayerUtils.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/LayerUtils.js deleted file mode 100644 index 59a1bcfae..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/LayerUtils.js +++ /dev/null @@ -1,315 +0,0 @@ -/** -* @module LayerUtils -* @alias Gp.LayerUtils -* @description -* ... -* -* @example -* getZoomLevelFromScaleDenominator(); -* getAttributions(); -* intersects(); -*/ -var LayerUtils = { - - /** - * Obtenir le ZoomLevel à partir du ScaleDenominator - * @function getZoomLevelFromScaleDenominator - * @param {Number} scaleDenominator - the scale denominator - * @param {String} crs - the crs - * - * @returns {Integer} zoom level - */ - getZoomLevelFromScaleDenominator : function (scaleDenominator, crs) { - // ------------------------------------------------- // - // Code issu de l'API Geoportal/Catalogue/Config.js // - // ------------------------------------------------- // - // var configuration = Gp.Config; - // var general = configuration.generalOptions; - // var layers = configuration.layersContext; - // - // for (var tms in general.tileMatrixSets) { - // var tileMatrixSet = general.tileMatrixSets[tms]; - // // IGN's WMTS bug : epsg:nnnn instead of EPSG:nnnn - // var crs = tileMatrixSet.supportedCRS = tileMatrixSet.supportedCRS.replace(/epsg/,"EPSG"); - // - // if (!Geoportal.Catalogue.CRSRESOLUTIONS.hasOwnProperty(crs)) { - // var p= new OpenLayers.Projection(crs); - // Geoportal.Catalogue.CRSRESOLUTIONS[crs]= []; - // var matrixIds= tileMatrixSet.matrixIds; - // for (var i= 0, li= matrixIds.length; i} params.extent - map current geographical extent (EPSG:4326) : [top, left, bottom, right] = [maxy, minx, miny, maxx] - * @param {Number} params.zoom - map current zoom - * @param {String} params.crs - map current projection code (ex "EPSG:2154") - * @param {Boolean} params.visibility - layer visibility - * @param {Gp.Services.Config.Originator} params.originators - resource originators (from Gp.Config.layers[].originators) - * @returns {Object} attributions - associative array, mapping originators url (keys) with their properties : html attributions elements - */ - getAttributions : function (params) { - var zoom = params.zoom; - - var attributions = []; - - if (params.originators != null && params.visibility) { - // drawLogo = boolean, true if attribution should be displayed (zoom, extent), false otherwise - var drawLogo; - for (var j = 0, jl = params.originators.length; j < jl; j++) { - drawLogo = true; - var originator = params.originators[j]; - - var constraints = params.originators[j].constraints || []; - for (var k = 0, kl = constraints.length; k < kl; k++) { - var constraint = constraints[k]; - drawLogo = true; - - var minZoomLevel = this.getZoomLevelFromScaleDenominator(constraint.maxScaleDenominator, params.crs); - var maxZoomLevel = this.getZoomLevelFromScaleDenominator(constraint.minScaleDenominator, params.crs) || 21; - - // min zoom constraints - if (minZoomLevel && (minZoomLevel > zoom)) { - drawLogo = false; - } - - // max zoom constraints - if (drawLogo && maxZoomLevel && (maxZoomLevel < zoom)) { - drawLogo = false; - } - - // bbox constraints - var bbox = constraint.bbox; - if (drawLogo && bbox) { - drawLogo = false; - var viewExtent = params.extent; - if (viewExtent) { - var bounds = [bbox.top, bbox.left, bbox.bottom, bbox.right]; - if (this.intersects(viewExtent, bounds)) { - // at least one constraint matches the map ones - drawLogo = true; - break; - } - } - } - } - - if (drawLogo) { - // on a un originator qui correspond au zoom et à l'étendue. - - var logo = originator.logo; - var url = originator.url; - var name = originator.name ? originator.name : ""; - var text = originator.attribution; - - var container = document.createElement("div"); - container.className = "gp-control-attribution"; - - // on crée un lien dans tous les cas (même s'il ne pointe pas vers une référence), pour avoir accès à la class CSS (pour surcharge) - var link = null; - link = document.createElement("a"); - link.className = "gp-control-attribution-link"; - link.target = "_blank"; - container.appendChild(link); - if (url) { - link.href = url; - } - - var bImage = !!(logo); - var image = null; - // si on a un logo, on l'affiche à l'interieur du lien - if (bImage) { - image = document.createElement("img"); - if (link) { - image.className = "gp-control-attribution-image"; - link.appendChild(image); - } else { - image.className = ""; - container.appendChild(image); - } - image.src = logo; - image.title = text || name; - image.style.height = "30px"; - image.style.width = "30px"; - } else { - // sinon, on affiche le nom de l'originator, ou sa description ou l'url. - if (name) { - link.textContent = name; - } else if (text) { - link.textContent = text; - } else if (url) { - link.textContent = url; - } else { - link.textContent = ""; - } - } - - attributions.push(container.innerHTML + " "); - } - } - } - - return attributions; - }, - - /** - * Determines if one extent (extent1) intersects another (extent2) - * - * @function intersects - * @param {Array.} extent1 - First extent : [top, left, bottom, right] = [maxy, minx, miny, maxx] - * @param {Array.} extent2 - Second extent : [top, left, bottom, right] = [maxy, minx, miny, maxx] - * @return {Boolean} intersects - True if the two extents intersect, false otherwise. - */ - intersects : function (extent1, extent2) { - var intersectsX = (extent1[1] <= extent2[3]) && (extent2[1] <= extent1[3]); - var intersectsY = (extent1[2] <= extent2[0]) && (extent2[2] <= extent1[0]); - return intersectsX && intersectsY; - } -}; - -export default LayerUtils; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/LoggerByDefault.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/LoggerByDefault.d.ts deleted file mode 100644 index faf0a1811..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/LoggerByDefault.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default LoggerByDefault; -declare namespace LoggerByDefault { - function getLogger(name?: string | undefined): Object; - function disableAll(): void; - function enableAll(): void; -} -//# sourceMappingURL=LoggerByDefault.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/LoggerByDefault.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/LoggerByDefault.d.ts.map deleted file mode 100644 index 9ddaa057b..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/LoggerByDefault.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"LoggerByDefault.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/LoggerByDefault.js"],"names":[],"mappings":";;IAqBgB,sDAWX;IAKY,4BAQZ;IAKW,2BAQX"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/LoggerByDefault.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/LoggerByDefault.js deleted file mode 100644 index a0db7e25c..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/LoggerByDefault.js +++ /dev/null @@ -1,62 +0,0 @@ -import * as Log from "loglevel"; - -/** - * @module LoggerByDefault - * @alias [private] LoggerByDefault - * @description - * ... - * - * @example - * getLogger(); - * disableAll(); - * enableAll(); - */ -var LoggerByDefault = { - /** - * creation d'un logger statique - * - * @function getLogger - * @param {String} [name="default"] - the logger name - * @returns {Object} logger - */ - getLogger : function (name) { - // on définit process si non défini dans l'environnement - if (typeof process === "undefined") { - var process = {}; - process.env = { - VERBOSE : false - }; - } - (process.env.VERBOSE) ? Log.enableAll() : Log.disableAll(); - var logname = name || "default"; - return Log.getLogger(logname); - }, - /** - * desactive tous les loggers - * @function disableAll - */ - disableAll : function () { - var loggers = Log.getLoggers(); - for (const key in loggers) { - if (Object.hasOwnProperty.call(loggers, key)) { - const logger = loggers[key]; - logger.disableAll(); - } - } - }, - /** - * active tous les loggers - * @function enableAll - */ - enableAll : function () { - var loggers = Log.getLoggers(); - for (const key in loggers) { - if (Object.hasOwnProperty.call(loggers, key)) { - const logger = loggers[key]; - logger.enableAll(); - } - } - } -}; - -export default LoggerByDefault; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/MathUtils.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/MathUtils.d.ts deleted file mode 100644 index 19e60d595..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/MathUtils.d.ts +++ /dev/null @@ -1,68 +0,0 @@ -export default MathUtils; -declare namespace MathUtils { - function modulo(a: number, b: number): number; - function decimalToDMS(degrees: number, hemispheres: any[], numDigits: number): Object; - /** - * Transform decimal degrees form degrees, minutes, seconds - * - * @function dmsToDecimal - * @param {*} degrees - degrees - * @param {*} minutes - minutes - * @param {*} seconds - seconds - * @param {*} hemispheres - "NS" ou "EO" - * @returns {Number} decimal coordinate - */ - function dmsToDecimal(degrees: any, minutes: any, seconds: any, hemispheres: any): number; - /** - * ol coordinate to decimal - * - * @function coordinateToDecimal - * @param {*} olCoordinate - see ol/coordinate.js - * @returns {Object} - {lat, lng, unit:°} - */ - function coordinateToDecimal(olCoordinate: any): Object; - /** - * ol coordinate to dms - * - * @function coordinateToDMS - * @param {*} olCoordinate - see ol/coordinate.js - * @returns {Object} - {lat, lng, unit:dms} - */ - function coordinateToDMS(olCoordinate: any): Object; - /** - * ol coordinate to rad - * - * @function coordinateToRad - * @param {*} olCoordinate - see ol/coordinate.js - * @returns {Object} - {lat, lng, unit:rad} - */ - function coordinateToRad(olCoordinate: any): Object; - /** - * ol coordinate to gon - * - * @function coordinateToGon - * @param {*} olCoordinate - see ol/coordinate.js - * @returns {Object} - {lat, lng, unit:gon} - */ - function coordinateToGon(olCoordinate: any): Object; - /** - * ol coordinate to meter - * - * @function coordinateToMeter - * @param {*} olCoordinate - see ol/coordinate.js - * @returns {Object} - {x, y, unit:m} - */ - function coordinateToMeter(olCoordinate: any): Object; - /** - * ol coordinate to kilometer - * - * @function coordinateToKMeter - * @param {*} olCoordinate - see ol/coordinate.js - * @returns {Object} - {x, lyng, unit:km} - */ - function coordinateToKMeter(olCoordinate: any): Object; - function toInteger(s: string, base: Numeric): any; - function isInteger(s: string): boolean; - function toFloat(s: string): any; -} -//# sourceMappingURL=MathUtils.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/MathUtils.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/MathUtils.d.ts.map deleted file mode 100644 index 6cfe1cece..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/MathUtils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MathUtils.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/MathUtils.js"],"names":[],"mappings":";;IAuBa,8CAGR;IAYc,sFA4Bd;IAED;;;;;;;;;OASG;IACH,0FAOC;IACD;;;;;;OAMG;IACH,wDAMC;IAED;;;;;;OAMG;IACH,oDAMC;IAED;;;;;;OAMG;IACH,oDASC;IAED;;;;;;OAMG;IACH,oDASC;IAED;;;;;;OAMG;IACH,sDAOC;IAED;;;;;;OAMG;IACH,uDAOC;IAUW,kDAOX;IASW,uCAOX;IASS,iCAMT"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/MathUtils.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/MathUtils.js deleted file mode 100644 index 86010af0f..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/MathUtils.js +++ /dev/null @@ -1,234 +0,0 @@ -/** -* @module MathUtils -* @alias Gp.MathUtils -* @description -* ... -* -* @example -* modulo(); -* decimalToDMS(); -* coordinateTo(); -* toInteger(); -* isInteger(); -* toFloat(); -*/ -var MathUtils = { - /** - * Reste de la division euclidienne - * - * @function modulo - * @param {Number} a - divisor - * @param {Number} b - quotient - * @returns {Number} Modulo - */ - modulo : function (a, b) { - var r = a % b; - return r * b < 0 ? r + b : r; - }, - - /** - * Transform degrees, minutes, seconds form decimal degrees - - * Largely inspired by the private function degreesToStringHDMS from ol/coordinate.js - * - * @function decimalToDMS - * @param {Number} degrees - decimal degrees - * @param {Array} hemispheres - "NS" ou "EO" - * @param {Number} numDigits - number of digits for seconds - * @returns {Object} DMS coordinate - */ - decimalToDMS : function (degrees, hemispheres, numDigits) { - var normalizedDegrees = this.modulo(degrees + 180, 360) - 180; - var x = Math.abs(3600 * normalizedDegrees); - var dflPrecision = numDigits || 0; - var precision = Math.pow(10, dflPrecision); - - var deg = Math.floor(x / 3600); - var min = Math.floor((x - deg * 3600) / 60); - var sec = x - (deg * 3600) - (min * 60); - sec = Math.ceil(sec * precision) / precision; - - if (sec >= 60) { - sec = 0; - min += 1; - } - - if (min >= 60) { - min = 0; - deg += 1; - } - - var direction = hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0); - return { - d : deg, - m : min, - s : sec, - direction : direction - }; - }, - - /** - * Transform decimal degrees form degrees, minutes, seconds - * - * @function dmsToDecimal - * @param {*} degrees - degrees - * @param {*} minutes - minutes - * @param {*} seconds - seconds - * @param {*} hemispheres - "NS" ou "EO" - * @returns {Number} decimal coordinate - */ - dmsToDecimal (degrees, minutes, seconds, hemispheres) { - var dd = degrees + minutes/60 + seconds/(60*60); - - if (hemispheres == "S" || hemispheres == "O") { - dd = dd * -1; - } - return dd; - }, - /** - * ol coordinate to decimal - * - * @function coordinateToDecimal - * @param {*} olCoordinate - see ol/coordinate.js - * @returns {Object} - {lat, lng, unit:°} - */ - coordinateToDecimal (olCoordinate) { - var coordinate = {}; - coordinate.lat = olCoordinate[1].toFixed(6); - coordinate.lng = olCoordinate[0].toFixed(6); - coordinate.unit = "°"; - return coordinate; - }, - - /** - * ol coordinate to dms - * - * @function coordinateToDMS - * @param {*} olCoordinate - see ol/coordinate.js - * @returns {Object} - {lat, lng, unit:dms} - */ - coordinateToDMS (olCoordinate) { - return { - lng : MathUtils.decimalToDMS(olCoordinate[0], "EO", 2), - lat : MathUtils.decimalToDMS(olCoordinate[1], "NS", 2), - unit : "DMS" - }; - }, - - /** - * ol coordinate to rad - * - * @function coordinateToRad - * @param {*} olCoordinate - see ol/coordinate.js - * @returns {Object} - {lat, lng, unit:rad} - */ - coordinateToRad (olCoordinate) { - var coordinate = {}; - var d = 0.01745329251994329577; - coordinate.lng = olCoordinate[0] * d; - coordinate.lng = coordinate.lng.toFixed(8); - coordinate.lat = olCoordinate[1] * d; - coordinate.lat = coordinate.lat.toFixed(8); - coordinate.unit = "rad"; - return coordinate; - }, - - /** - * ol coordinate to gon - * - * @function coordinateToGon - * @param {*} olCoordinate - see ol/coordinate.js - * @returns {Object} - {lat, lng, unit:gon} - */ - coordinateToGon (olCoordinate) { - var coordinate = {}; - var d = 1.11111111111111111111; - coordinate.lng = olCoordinate[0] * d; - coordinate.lng = coordinate.lng.toFixed(8); - coordinate.lat = olCoordinate[1] * d; - coordinate.lat = coordinate.lat.toFixed(8); - coordinate.unit = "gon"; - return coordinate; - }, - - /** - * ol coordinate to meter - * - * @function coordinateToMeter - * @param {*} olCoordinate - see ol/coordinate.js - * @returns {Object} - {x, y, unit:m} - */ - coordinateToMeter (olCoordinate) { - // on recoit toujours des coordonnées metriques - var coordinate = {}; - coordinate.x = olCoordinate[0].toFixed(2); - coordinate.y = olCoordinate[1].toFixed(2); - coordinate.unit = "m"; - return coordinate; - }, - - /** - * ol coordinate to kilometer - * - * @function coordinateToKMeter - * @param {*} olCoordinate - see ol/coordinate.js - * @returns {Object} - {x, lyng, unit:km} - */ - coordinateToKMeter (olCoordinate) { - // on recoit toujours des coordonnées metriques - var coordinate = {}; - coordinate.x = (olCoordinate[0] / 1000).toFixed(2); - coordinate.y = (olCoordinate[1] / 1000).toFixed(2); - coordinate.unit = "km"; - return coordinate; - }, - - /** - * Converts string to Integer - * - * @function toInteger - * @param {String} s - string number - * @param {Numeric} base - between 2 and 36 - * @returns {null|Numeric} result - */ - toInteger : function (s, base) { - var _base = base || 10; - var n = parseInt(s, _base); - if (!isNaN(n) && isFinite(n)) { - return n; - } - return null; - }, - - /** - * check if s represents an integer - * - * @function isInteger - * @param {String} s - string number - * @returns {Boolean} is integer - */ - isInteger : function (s) { - if (isNaN(s)) { - return false; - } - - var v = parseFloat(s); - return ((v | 0) === v); - }, - - /** - * Converts s to float - * - * @function toFloat - * @param {String} s - string number - * @returns {null|Numeric} result - */ - toFloat : function (s) { - var n = parseFloat(s); - if (!isNaN(n) && isFinite(n)) { - return n; - } - return null; - } -}; - -export default MathUtils; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Parser.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Parser.d.ts deleted file mode 100644 index 0591a82fa..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Parser.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default Parser; -declare namespace Parser { - function parse(xml: string): DOMElement; - function toString(doc: DOMElement): string; - function format(xml: string): string; -} -//# sourceMappingURL=Parser.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Parser.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Parser.d.ts.map deleted file mode 100644 index 57d2f1d1a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Parser.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Parser.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/Parser.js"],"names":[],"mappings":";;IAsBY,wCAiCP;IAQU,2CASV;IASQ,qCAoDR"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Parser.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Parser.js deleted file mode 100644 index 82e63c8b1..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Parser.js +++ /dev/null @@ -1,137 +0,0 @@ -import Logger from "./LoggerByDefault"; - -var logger = Logger.getLogger("parser"); - -/** -* @module Parser -* @alias Gp.Parser -* @description -* ... -* -* @example -* parse(); -* toString(); -*/ -var Parser = { - - /** - * ... - * - * @param {String} xml - XML string - * @returns {DOMElement} doc - */ - parse : function (xml) { - var doc = null; - var parser = null; - var scope = typeof window !== "undefined" ? window : null; - - if (typeof exports === "object" && window === null) { - // code for nodejs - var DOMParser = require("xmldom").DOMParser; - parser = new DOMParser(); - doc = parser.parseFromString(xml, "text/xml"); - } else if (scope.DOMParser) { - // code for modern browsers - parser = new scope.DOMParser(); - doc = parser.parseFromString(xml, "text/xml"); - } else if (scope.ActiveXObject) { - // code for old IE browsers - doc = new scope.ActiveXObject("Microsoft.XMLDOM"); - doc.async = false; - doc.loadXML(xml); - } else { - logger.log("Incompatible environment for DOM Parser !"); - } - - var errorNode = doc.querySelector("parsererror"); - if (errorNode) { - // INFO parsing failed - // eslint-disable-next-line no-console - console.error(errorNode); - return null; - } - - logger.trace(doc); - return doc; - }, - - /** - * ... - * - * @param {DOMElement} doc - doc - * @returns {String} XML string - */ - toString : function (doc) { - // TODO - // try catch pour les exceptions ! - // cf. https://developer.mozilla.org/en-US/docs/Web/API/XMLSerializer/serializeToString - var oSerializer = new XMLSerializer(); - var xml = oSerializer.serializeToString(doc); - - logger.trace(xml); - return xml; - }, - - /** - * ... - * cf. https://stackoverflow.com/questions/376373/pretty-printing-xml-with-javascript/ - * - * @param {String} xml - XML string - * @returns {String} XML string formatted - */ - format : function (xml) { - var reg = /(>)\s*(<)(\/*)/g; // updated Mar 30, 2015 - var wsexp = / *(.*) +\n/g; - var contexp = /(<.+>)(.+\n)/g; - xml = xml.replace(reg, "$1\n$2$3").replace(wsexp, "$1\n").replace(contexp, "$1\n$2"); - var formatted = ""; - var lines = xml.split("\n"); - var indent = 0; - var lastType = "other"; - // 4 types of tags - single, closing, opening, other (text, doctype, comment) - 4*4 = 16 transitions - var transitions = { - "single->single" : 0, - "single->closing" : -1, - "single->opening" : 0, - "single->other" : 0, - "closing->single" : 0, - "closing->closing" : -1, - "closing->opening" : 0, - "closing->other" : 0, - "opening->single" : 1, - "opening->closing" : 0, - "opening->opening" : 1, - "opening->other" : 1, - "other->single" : 0, - "other->closing" : -1, - "other->opening" : 0, - "other->other" : 0 - }; - - for (var i = 0; i < lines.length; i++) { - var ln = lines[i]; - var single = Boolean(ln.match(/<.+\/>/)); // is this line a single tag? ex.
- var closing = Boolean(ln.match(/<\/.+>/)); // is this a closing tag? ex. - var opening = Boolean(ln.match(/<[^!].*>/)); // is this even a tag (that's not ) - var type = single ? "single" : closing ? "closing" : opening ? "opening" : "other"; - var fromTo = lastType + "->" + type; - lastType = type; - var padding = ""; - - indent += transitions[fromTo]; - for (var j = 0; j < indent; j++) { - padding += "\t"; - } - if (fromTo === "opening->closing") { - formatted = formatted.substr(0, formatted.length - 1) + ln + "\n"; // substr removes line break (\n) from prev loop - } else { - formatted += padding + ln + "\n"; - } - } - - logger.trace(formatted); - return formatted; - } -}; - -export default Parser; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/ProxyUtils.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/ProxyUtils.d.ts deleted file mode 100644 index 63237a20d..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/ProxyUtils.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default ProxyUtils; -declare namespace ProxyUtils { - function proxifyUrl(url: string, proxyOptions?: { - proxyUrl: string; - noProxyDomains?: string[] | undefined; - } | undefined): string; -} -//# sourceMappingURL=ProxyUtils.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/ProxyUtils.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/ProxyUtils.d.ts.map deleted file mode 100644 index ddb9156b7..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/ProxyUtils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"ProxyUtils.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/ProxyUtils.js"],"names":[],"mappings":";;IAuBiB;;;2BAwBZ"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/ProxyUtils.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/ProxyUtils.js deleted file mode 100644 index 88cf8ac74..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/ProxyUtils.js +++ /dev/null @@ -1,51 +0,0 @@ -import Logger from "./LoggerByDefault"; - -/** -* @module ProxyUtils -* @alias Gp.ProxyUtils -* @description -* ... -* -* @example -* proxifyUrl(); -*/ -var ProxyUtils = { - /** - * Ajoute un proxy aux url des couches vecteurs si besoin. - * - * @function proxifyUrl - * @param {String} url - Url to proxify. - * @param {Object} [proxyOptions] - Object defining proxy options. - * @param {String} proxyOptions.proxyUrl - Proxy URL. - * @param {Array.} [proxyOptions.noProxyDomains] - Proxy will not be used for this list of domain names. - * - * @returns {String} proxy url - */ - proxifyUrl : function (url, proxyOptions) { - // logger - - var logger = Logger.getLogger("proxifyUrl"); - - if (!proxyOptions || - !proxyOptions.hasOwnProperty("proxyUrl") || - proxyOptions.proxyUrl === null || - proxyOptions.proxyUrl.trim().length === 0) { - return url; - } - // on regarde si l'url nest pas dans les domaines sans proxy - if (proxyOptions.noProxyDomains && - Array.isArray(proxyOptions.noProxyDomains) && - proxyOptions.noProxyDomains.length > 0) { - for (var i in proxyOptions.noProxyDomains) { - logger.trace("[ProxyUtils] proxifyUrl : analyzing " + proxyOptions.noProxyDomains[i]); - if (url.indexOf(proxyOptions.noProxyDomains[i]) !== -1) { - logger.info("[ProxyUtils] proxifyUrl : " + url + " found in noProxyDomains list (" + proxyOptions.noProxyDomains[i] + ")."); - return url; - } - } - } - return proxyOptions.proxyUrl + encodeURIComponent(url); - } -}; - -export default ProxyUtils; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Register.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Register.d.ts deleted file mode 100644 index bbca6269d..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Register.d.ts +++ /dev/null @@ -1,441 +0,0 @@ -export default Register; -declare namespace Register { - let isLoaded: boolean; - function get(name: string): Object; - function exist(name: string): boolean; - function load(Proj4: Object): void; - function loadByDefault(Proj4: Object): void; - function loadByName(Proj4: Object, name: string): boolean; - let EPSG: { - 4978: string; - 3857: string; - 3785: string; - 4149: string; - 4150: string; - 4151: string; - 4171: string; - 4230: string; - 4235: string; - 4258: string; - 4275: string; - 4322: string; - 4326: string; - 4467: string; - 4470: string; - 4471: string; - 4474: string; - 4558: string; - 4559: string; - 4621: string; - 4622: string; - 4623: string; - 4624: string; - 4625: string; - 4626: string; - 4627: string; - 4628: string; - 4629: string; - 4630: string; - 4632: string; - 4633: string; - 4634: string; - 4637: string; - 4638: string; - 4640: string; - 4641: string; - 4645: string; - 4687: string; - 4662: string; - 4689: string; - 4690: string; - 4691: string; - 4692: string; - 4698: string; - 4749: string; - 4750: string; - 4807: string; - 2056: string; - 2154: string; - 2213: string; - 2969: string; - 2970: string; - 2971: string; - 2972: string; - 2973: string; - 2975: string; - 2976: string; - 2977: string; - 2978: string; - 2980: string; - 2981: string; - 2982: string; - 2984: string; - 2986: string; - 2987: string; - 2989: string; - 2990: string; - 2995: string; - 3038: string; - 3039: string; - 3040: string; - 3041: string; - 3045: string; - 3046: string; - 3047: string; - 3048: string; - 3049: string; - 3050: string; - 3051: string; - 3034: string; - 3035: string; - 3042: string; - 3043: string; - 3044: string; - 25828: string; - 25829: string; - 25833: string; - 25834: string; - 25835: string; - 25836: string; - 25837: string; - 25838: string; - 3060: string; - 3163: string; - 3164: string; - 3165: string; - 3166: string; - 3169: string; - 3170: string; - 3171: string; - 3172: string; - 3296: string; - 3297: string; - 3298: string; - 3299: string; - 3302: string; - 3303: string; - 3304: string; - 3305: string; - 3306: string; - 3312: string; - 3313: string; - 3336: string; - 3395: string; - 3727: string; - 21781: string; - 25830: string; - 25831: string; - 25832: string; - 27561: string; - 27562: string; - 27563: string; - 27564: string; - 27571: string; - 27572: string; - 27573: string; - 27574: string; - 27581: string; - 27582: string; - 27583: string; - 27584: string; - 27591: string; - 27592: string; - 27593: string; - 27594: string; - 32601: string; - 32602: string; - 32603: string; - 32604: string; - 32605: string; - 32606: string; - 32607: string; - 32608: string; - 32609: string; - 32610: string; - 32611: string; - 32612: string; - 32613: string; - 32614: string; - 32615: string; - 32616: string; - 32617: string; - 32618: string; - 32619: string; - 32620: string; - 32621: string; - 32622: string; - 32623: string; - 32624: string; - 32625: string; - 32626: string; - 32627: string; - 32628: string; - 32629: string; - 32630: string; - 32631: string; - 32632: string; - 32633: string; - 32634: string; - 32635: string; - 32636: string; - 32637: string; - 32638: string; - 32639: string; - 32640: string; - 32641: string; - 32642: string; - 32643: string; - 32644: string; - 32645: string; - 32646: string; - 32647: string; - 32648: string; - 32649: string; - 32650: string; - 32651: string; - 32652: string; - 32653: string; - 32654: string; - 32655: string; - 32656: string; - 32657: string; - 32658: string; - 32659: string; - 32660: string; - 32661: string; - 32662: string; - 32701: string; - 32702: string; - 32703: string; - 32704: string; - 32705: string; - 32706: string; - 32707: string; - 32708: string; - 32709: string; - 32710: string; - 32711: string; - 32712: string; - 32713: string; - 32714: string; - 32715: string; - 32716: string; - 32717: string; - 32718: string; - 32719: string; - 32720: string; - 32721: string; - 32722: string; - 32723: string; - 32724: string; - 32725: string; - 32726: string; - 32727: string; - 32728: string; - 32729: string; - 32730: string; - 32731: string; - 32732: string; - 32733: string; - 32734: string; - 32735: string; - 32736: string; - 32737: string; - 32738: string; - 32739: string; - 32740: string; - 32741: string; - 32742: string; - 32743: string; - 32744: string; - 32745: string; - 32746: string; - 32747: string; - 32748: string; - 32749: string; - 32750: string; - 32751: string; - 32752: string; - 32753: string; - 32754: string; - 32755: string; - 32756: string; - 32757: string; - 32758: string; - 32759: string; - 32760: string; - 32761: string; - 310024802: string; - 310915814: string; - 310486805: string; - 310700806: string; - 310702807: string; - 310706808: string; - 310547809: string; - 310642810: string; - 310032811: string; - 310642812: string; - 310642801: string; - 310642813: string; - 310642901: string; - 5489: string; - 5490: string; - }; - let CRS: { - 84: string; - }; - namespace IGNF { - let AMST63: string; - let CROZ63: string; - let CSG67: string; - let ED50: string; - let ETRS89: string; - let GUAD48: string; - let GUADFM49: string; - let IGN63: string; - let IGN72: string; - let KERG62CAR: string; - let MART38: string; - let MAYO50: string; - let MOOREA87: string; - let NTF: string; - let NUKU72: string; - let REUN47: string; - let RGF93: string; - let RGFG95: string; - let RGM04: string; - let RGNC: string; - let RGPF: string; - let RGR92: string; - let RGSPM06: string; - let RGTAAF07: string; - let RRAF91: string; - let STPL69: string; - let STPM50: string; - let TAHAA: string; - let TAHI79: string; - let TERA50: string; - let WALL78: string; - let WGS72: string; - let WGS84: string; - let AMST63GEO: string; - let CROZ63GEO: string; - let CSG67GEO: string; - let ED50G: string; - let GUAD48GEO: string; - let GUADFM49GEO: string; - let IGN63GEO: string; - let IGN72GEO: string; - let KERG62GEO: string; - let MART38GEO: string; - let MAYO50GEO: string; - let MOOREA87GEO: string; - let NTFG: string; - let NTFP: string; - let NUKU72GEO: string; - let REUN47GEO: string; - let RGF93G: string; - let RGFG95GEO: string; - let RGM04GEO: string; - let RGNCGEO: string; - let RGPFGEO: string; - let RGR92GEO: string; - let RGSPM06GEO: string; - let RGTAAF07G: string; - let STPL69GEO: string; - let STPM50GEO: string; - let TAHAAGEO: string; - let TAHI79GEO: string; - let TERA50G: string; - let WALL78GEO: string; - let WGS72G: string; - let WGS84G: string; - let WGS84RRAFGEO: string; - let XGEO: string; - let AMST63UTM43S: string; - let CROZ63UTM39S: string; - let CSG67UTM21: string; - let CSG67UTM22: string; - let GEOPORTALANF: string; - let GEOPORTALASP: string; - let GEOPORTALCRZ: string; - let GEOPORTALFXX: string; - let GEOPORTALGUF: string; - let GEOPORTALKER: string; - let GEOPORTALMYT: string; - let GEOPORTALNCL: string; - let GEOPORTALPYF: string; - let GEOPORTALREU: string; - let GEOPORTALSPM: string; - let GEOPORTALWLF: string; - let GUAD48UTM20: string; - let GUADFM49U20: string; - let IGN63UTM7S: string; - let IGN72UTM58S: string; - let KERG62UTM42S: string; - let LAMB1: string; - let LAMB1C: string; - let LAMB2: string; - let LAMB2C: string; - let LAMB3: string; - let LAMB3C: string; - let LAMB4: string; - let LAMB4C: string; - let LAMB93: string; - let RGF93CC42: string; - let RGF93CC43: string; - let RGF93CC44: string; - let RGF93CC45: string; - let RGF93CC46: string; - let RGF93CC47: string; - let RGF93CC48: string; - let RGF93CC49: string; - let RGF93CC50: string; - let LAMBE: string; - let MART38UTM20: string; - let MAYO50UTM38S: string; - let MILLER: string; - let MOOREA87U6S: string; - let NUKU72U7S: string; - let RGM04UTM38S: string; - let RGNCUTM57S: string; - let RGNCUTM58S: string; - let RGNCUTM59S: string; - let RGPFUTM5S: string; - let RGPFUTM6S: string; - let RGPFUTM7S: string; - let RGR92UTM40S: string; - let RGSPM06U21: string; - let STPL69UTM43S: string; - let STPM50UTM21: string; - let TAHAAUTM05S: string; - let TAHI51UTM06S: string; - let TAHI79UTM6S: string; - let TERA50STEREO: string; - let UTM01SW84: string; - let UTM20W84GUAD: string; - let UTM20W84MART: string; - let UTM22RGFG95: string; - let UTM39SW84: string; - let UTM42SW84: string; - let UTM43SW84: string; - let WALL78UTM1S: string; - let ETRS89GEO: string; - let ETRS89LAEA: string; - let ETRS89LCC: string; - let UTM26ETRS89: string; - let UTM27ETRS89: string; - let UTM28ETRS89: string; - let UTM29ETRS89: string; - let UTM30ETRS89: string; - let UTM31ETRS89: string; - let UTM32ETRS89: string; - let UTM33ETRS89: string; - let UTM34ETRS89: string; - let UTM35ETRS89: string; - let UTM36ETRS89: string; - let UTM37ETRS89: string; - let UTM38ETRS89: string; - } -} -//# sourceMappingURL=Register.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Register.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Register.d.ts.map deleted file mode 100644 index 2323db8b9..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Register.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Register.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/Register.js"],"names":[],"mappings":";;;IA6BU,mCAsBL;IAWO,sCAsBP;IAOM,mCAgCN;IAoBe,4CAoCf;IAUY,0DAaZ"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Register.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/Register.js deleted file mode 100644 index 94e786e62..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/Register.js +++ /dev/null @@ -1,657 +0,0 @@ -/** - * @module Register - * @alias [private] Register - * @description - * Register definition for IGNF, and EPSG CRS. - * - * @example - * Gp.Register.IGNF.AMST63 - * // return : "+title=Amsterdam 1963 +proj=geocent +towgs84=109.753,-528.133,-362.244,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs" - * Gp.Register.get("IGNF:AMST63") - * // same as Gp.Register.IGNF.AMST63 - */ -var Register = { - - /** - * instance already loaded into proj4 - */ - isLoaded : false, - - /** - * get the definition for a code - * - * @function get - * @param {String} name - ie. EPSG:2154 (Lambert) - * @returns {Object} definition - * @example - * Register.get("EPSG:2154"); - * // "+title=RGF93 / Lambert-93 +proj=lcc +lat_1=49 ..." - */ - get : function (name) { - if (name === "" || name === null || typeof name === "undefined") { - return; - } - - var s = name.split(":"); - if (s.length !== 2) { - return; - } - - var _register = s[0]; - var _code = s[1]; - - if (!this.hasOwnProperty(_register)) { - return; - } - - if (!this[_register].hasOwnProperty(_code)) { - return; - } - - return this[_register][_code]; - }, - - /** - * does projection code exist ? - * - * @function exist - * @param {String} name - ie. EPSG:2154 (Lambert) - * @returns {Boolean} true/false - * @example - * Register.exist("EPSG:2154"); // true - */ - exist : function (name) { - if (name === "" || name === null || typeof name === "undefined") { - return false; - } - - var s = name.split(":"); - if (s.length !== 2) { - return false; - } - - var _register = s[0]; - var _code = s[1]; - - if (!this.hasOwnProperty(_register)) { - return false; - } - - if (!this[_register].hasOwnProperty(_code)) { - return false; - } - - return true; - }, - - /** - * load all defs to proj4 - * @function load - * @param {Object} Proj4 - proj4 instance - */ - load : function (Proj4) { - // un flag pour savoir si le chargement est déjà realisé - // (car ceci peut être couteux !) - if (!this.isLoaded) { - var registers = [ - "IGNF", // exception lors du register IGNF ? - "EPSG", - "CRS" - ]; - for (var i = 0; i < registers.length; i++) { - var _register = registers[i]; - var codes = this[_register]; - for (var _code in codes) { - if (codes.hasOwnProperty(_code)) { - var name = _register + ":" + _code; - Proj4.defs(name, this.get(name)); - // on enlève la dependance à OpenLayers... - // la fonction register est donc à appeller afin d'enregistrer - // les definitions dans OpenLayers : - // import { get } from "ol/proj"; - // import proj4 from "proj4"; - // import { register } from "ol/proj/proj4"; - // Register.load(); - // // Make projections defined in proj4 (with proj4.defs()) available in OpenLayers. - // // see ol/proj/proj4.register (https://openlayers.org/en/latest/apidoc/module-ol_proj_proj4.html) - // register(proj4); - // console.log(get("CRS:84").getCode()); // "CRS:84" - } - } - } - /** ts-syntax */ (this.isLoaded) = true; - } - }, - - /** - * load defs by default to proj4 - * - * include into proj4 : - * - WGS84 - * - ['EPSG:4326'] - * - ['EPSG:3785'], ['EPSG:3857'], GOOGLE, ['EPSG:900913'], ['EPSG:102113'] - * + - * - ["EPSG:2154"], ["EPSG:27571"], ["EPSG:27572"], ["EPSG:27573"], ["EPSG:2757"], - * - ["CRS:84"], - * - ["IGNF:LAMB93"], - * - ["IGNF:LAMBE"], ["IGNF:LAMB1"], ["IGNF:LAMB2"], ["IGNF:LAMB3"], ["IGNF:LAMB4"], - * - ["IGNF:RGF93G"], - * - ["IGNF:WGS84G"] - * - * @function loadByDefault - * @param {Object} Proj4 - proj4 instance - */ - loadByDefault : function (Proj4) { - // la liste de projections par defaut... - var registers = { - EPSG : { - 2154 : Register["EPSG"]["2154"], - 27571 : Register["EPSG"]["27571"], - 27572 : Register["EPSG"]["27572"], - 27573 : Register["EPSG"]["27573"], - 27574 : Register["EPSG"]["27574"] - }, - CRS : { - 84 : Register["CRS"]["84"] - }, - IGNF : { - LAMB93 : Register["IGNF"]["LAMB93"], - LAMBE : Register["IGNF"]["LAMBE"], - LAMB1 : Register["IGNF"]["LAMB1"], - LAMB2 : Register["IGNF"]["LAMB2"], - LAMB3 : Register["IGNF"]["LAMB3"], - LAMB4 : Register["IGNF"]["LAMB4"], - RGF93G : Register["IGNF"]["RGF93G"], - WGS84G : Register["IGNF"]["WGS84G"] - } - }; - - for (var register in registers) { - if (registers.hasOwnProperty(register)) { - var codes = registers[register]; - for (var code in codes) { - if (codes.hasOwnProperty(code)) { - var name = register + ":" + code; - Proj4.defs(name, codes[code]); - } - } - } - } - }, - - /** - * load only a def to proj4 - * - * @function loadByName - * @param {Object} Proj4 - proj4 instance - * @param {String} name - ie. EPSG:2154 (Lambert) - * @returns {Boolean} true/false - */ - loadByName : function (Proj4, name) { - if (!this.exist(name)) { - return false; - } - - try { - Proj4.defs(name, this.get(name)); - } catch (e) { - // FIXME message !? - return false; - } - - return true; - }, - - /** - * definitions EPSG - * @enum - */ - EPSG : { - 4978 : "+proj=geocent +datum=WGS84 +units=m +no_defs ", - 3857 : "+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs", - 3785 : "+title=WGS 84 / Pseudo-Mercator (deprecated) +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs", - 4149 : "+title=CH1903 +proj=longlat +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +no_defs ", - 4150 : "+title=CH1903plus +proj=longlat +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +no_defs ", - 4151 : "+title=CHTRF95 +proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs ", - 4171 : "+title=RGF93 +proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs ", - 4230 : "+title=ED50 +proj=longlat +ellps=intl +no_defs ", - 4235 : "+title=Guyane Francaise +proj=longlat +ellps=intl +no_defs ", - 4258 : "+title=ETRS89 +proj=longlat +ellps=GRS80 +no_defs ", - 4275 : "+title=NTF +proj=longlat +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +no_defs ", - 4322 : "+title=WGS 72 +proj=longlat +ellps=WGS72 +no_defs ", - 4326 : "+title=WGS 84 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ", - 4467 : "+proj=utm +zone=21 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 4470 : "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs ", - 4471 : "+proj=utm +zone=38 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 4474 : "+proj=utm +zone=38 +south +ellps=intl +towgs84=-382,-59,-262,0,0,0,0 +units=m +no_defs ", - 4558 : "+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs ", - 4559 : "+proj=utm +zone=20 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 4621 : "+title=Fort Marigot +proj=longlat +ellps=intl +towgs84=137,248,-430,0,0,0,0 +no_defs ", - 4622 : "+title=Guadeloupe 1948 +proj=longlat +ellps=intl +no_defs ", - 4623 : "+title=CSG67 +proj=longlat +ellps=intl +towgs84=-186,230,110,0,0,0,0 +no_defs ", - 4624 : "+title=RGFG95 +proj=longlat +ellps=GRS80 +towgs84=2,2,-2,0,0,0,0 +no_defs ", - 4625 : "+title=Martinique 1938 +proj=longlat +ellps=intl +no_defs ", - 4626 : "+title=Reunion 1947 +proj=longlat +ellps=intl +no_defs ", - 4627 : "+title=RGR92 +proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs ", - 4628 : "+title=Tahiti 52 +proj=longlat +ellps=intl +towgs84=162,117,154,0,0,0,0 +no_defs ", - 4629 : "+title=Tahaa 54 +proj=longlat +ellps=intl +no_defs ", - 4630 : "+title=IGN72 Nuku Hiva +proj=longlat +ellps=intl +no_defs ", - 4632 : "+title=Combani 1950 +proj=longlat +ellps=intl +towgs84=-382,-59,-262,0,0,0,0 +no_defs ", - 4633 : "+title=IGN56 Lifou +proj=longlat +ellps=intl +no_defs ", - 4634 : "+title=IGN72 Grand Terre +proj=longlat +ellps=intl +no_defs ", - 4637 : "+title=Perroud 1950 +proj=longlat +ellps=intl +towgs84=325,154,172,0,0,0,0 +no_defs ", - 4638 : "+title=Saint Pierre et Miquelon 1950 +proj=longlat +ellps=clrk66 +towgs84=30,430,368,0,0,0,0 +no_defs ", - 4640 : "+title=RRAF 1991 +proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs ", - 4641 : "+title=IGN53 Mare +proj=longlat +ellps=intl +no_defs ", - 4645 : "+title=RGNC 1991 +proj=longlat +ellps=intl +towgs84=0,0,0,0,0,0,0 +no_defs ", - 4687 : "+proj=longlat +ellps=GRS80 +no_defs ", - 4662 : "+title=IGN72 Grande Terre +proj=longlat +ellps=intl +no_defs ", - 4689 : "+title=IGN63 Hiva Oa +proj=longlat +ellps=intl +no_defs ", - 4690 : "+title=Tahiti 79 +proj=longlat +ellps=intl +no_defs ", - 4691 : "+title=Moorea 87 +proj=longlat +ellps=intl +towgs84=215.525,149.593,176.229,-3.2624,-1.692,-1.1571,10.4773 +no_defs ", - 4692 : "+title=Maupiti 83 +proj=longlat +ellps=intl +towgs84=217.037,86.959,23.956,0,0,0,0 +no_defs ", - 4698 : "+title=IGN 1962 Kerguelen +proj=longlat +ellps=intl +towgs84=145,-187,103,0,0,0,0 +no_defs ", - 4749 : "+title=RGNC91-93 +proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs ", - 4750 : "+title=ST87 Ouvea +proj=longlat +ellps=WGS84 +towgs84=-56.263,16.136,-22.856,0,0,0,0 +no_defs ", - 4807 : "+title=NTF (Paris) +proj=longlat +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +no_defs ", - 2056 : "+title=CH1903+ / LV95 +proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +x_0=2600000 +y_0=1200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs ", - 2154 : "+title=RGF93 / Lambert-93 +proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 2213 : "+title=ETRS89 / TM 30 NE +proj=tmerc +lat_0=0 +lon_0=30 +k=0.9996 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs ", - 2969 : "+title=Fort Marigot / UTM zone 20N +proj=utm +zone=20 +ellps=intl +towgs84=137,248,-430,0,0,0,0 +units=m +no_defs ", - 2970 : "+title=Guadeloupe 1948 / UTM zone 20N +proj=utm +zone=20 +ellps=intl +units=m +no_defs ", - 2971 : "+title=CSG67 / UTM zone 22N +proj=utm +zone=22 +ellps=intl +towgs84=-186,230,110,0,0,0,0 +units=m +no_defs ", - 2972 : "+title=RGFG95 / UTM zone 22N +proj=utm +zone=22 +ellps=GRS80 +towgs84=2,2,-2,0,0,0,0 +units=m +no_defs ", - 2973 : "+title=Martinique 1938 / UTM zone 20N +proj=utm +zone=20 +ellps=intl +units=m +no_defs ", - 2975 : "+title=RGR92 / UTM zone 40S +proj=utm +zone=40 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 2976 : "+title=Tahiti 52 / UTM zone 6S +proj=utm +zone=6 +south +ellps=intl +towgs84=162,117,154,0,0,0,0 +units=m +no_defs ", - 2977 : "+title=Tahaa 54 / UTM zone 5S +proj=utm +zone=5 +south +ellps=intl +units=m +no_defs ", - 2978 : "+title=IGN72 Nuku Hiva / UTM zone 7S +proj=utm +zone=7 +south +ellps=intl +units=m +no_defs ", - 2980 : "+title=Combani 1950 / UTM zone 38S +proj=utm +zone=38 +south +ellps=intl +towgs84=-382,-59,-262,0,0,0,0 +units=m +no_defs ", - 2981 : "+title=IGN56 Lifou / UTM zone 58S +proj=utm +zone=58 +south +ellps=intl +units=m +no_defs ", - 2982 : "+title=IGN72 Grand Terre / UTM zone 58S (deprecated) +proj=utm +zone=58 +south +ellps=intl +units=m +no_defs ", - 2984 : "+title=RGNC 1991 / Lambert New Caledonia (deprecated) +proj=lcc +lat_1=-20.66666666666667 +lat_2=-22.33333333333333 +lat_0=-21.5 +lon_0=166 +x_0=400000 +y_0=300000 +ellps=intl +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 2986 : "+title=Terre Adelie 1950 +proj=stere +towgs84=324.9120,153.2820,172.0260 +a=6378388.0000 +rf=297.0000000000000 +lat_0=-90.000000000 +lon_0=140.000000000 +lat_ts=-67.000000000 +k=0.96027295 +x_0=300000.000 +y_0=-2299363.482 +units=m +no_defs", - 2987 : "+title=Saint Pierre et Miquelon 1950 / UTM zone 21N +proj=utm +zone=21 +ellps=clrk66 +towgs84=30,430,368,0,0,0,0 +units=m +no_defs ", - 2989 : "+title=RRAF 1991 / UTM zone 20N +proj=utm +zone=20 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 2990 : "+title=Reunion 1947 / TM Reunion (deprecated) +proj=tmerc +lat_0=-21.11666666666667 +lon_0=55.53333333333333 +k=1 +x_0=50000 +y_0=160000 +ellps=intl +units=m +no_defs ", - 2995 : "+title=IGN53 Mare / UTM zone 58S +proj=utm +zone=58 +south +ellps=intl +units=m +no_defs ", - 3038 : "+proj=utm +zone=26 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3039 : "+proj=utm +zone=27 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3040 : "+proj=utm +zone=28 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3041 : "+proj=utm +zone=29 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - // 3042 : "+proj=utm +zone=30 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - // 3043 : "+proj=utm +zone=31 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - // 3044 : "+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3045 : "+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3046 : "+proj=utm +zone=34 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3047 : "+proj=utm +zone=35 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3048 : "+proj=utm +zone=36 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3049 : "+proj=utm +zone=37 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3050 : "+proj=utm +zone=38 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3051 : "+proj=utm +zone=39 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3034 : "+title=ETRS89 / ETRS-LCC +proj=lcc +lat_1=35 +lat_2=65 +lat_0=52 +lon_0=10 +x_0=4000000 +y_0=2800000 +ellps=GRS80 +units=m +no_defs ", - 3035 : "+title=ETRS89 / ETRS-LAEA +proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs ", - 3042 : "+title=ETRS89 / ETRS-TM30 +proj=utm +zone=30 +ellps=GRS80 +units=m +no_defs ", - 3043 : "+title=ETRS89 / ETRS-TM31 +proj=utm +zone=31 +ellps=GRS80 +units=m +no_defs ", - 3044 : "+title=ETRS89 / ETRS-TM32 +proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs ", - 25828 : "+proj=utm +zone=28 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 25829 : "+proj=utm +zone=29 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - // 25830 : "+proj=utm +zone=30 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - // 25831 : "+proj=utm +zone=31 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - // 25832 : "+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 25833 : "+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 25834 : "+proj=utm +zone=34 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 25835 : "+proj=utm +zone=35 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 25836 : "+proj=utm +zone=36 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 25837 : "+proj=utm +zone=37 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 25838 : "+proj=utm +zone=38 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3060 : "+title=IGN72 Grande Terre / UTM zone 58S +proj=utm +zone=58 +south +ellps=intl +units=m +no_defs ", - 3163 : "+title=RGNC91-93 / Lambert New Caledonia +proj=lcc +lat_1=-20.66666666666667 +lat_2=-22.33333333333333 +lat_0=-21.5 +lon_0=166 +x_0=400000 +y_0=300000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3164 : "+title=ST87 Ouvea / UTM zone 58S +proj=utm +zone=58 +south +ellps=WGS84 +towgs84=-56.263,16.136,-22.856,0,0,0,0 +units=m +no_defs ", - 3165 : "+title=NEA74 Noumea / Noumea Lambert +proj=lcc +lat_1=-22.24469175 +lat_2=-22.29469175 +lat_0=-22.26969175 +lon_0=166.44242575 +x_0=0.66 +y_0=1.02 +ellps=intl +units=m +no_defs ", - 3166 : "+title=NEA74 Noumea / Noumea Lambert 2 +proj=lcc +lat_1=-22.24472222222222 +lat_2=-22.29472222222222 +lat_0=-22.26972222222222 +lon_0=166.4425 +x_0=8.313000000000001 +y_0=-2.354 +ellps=intl +units=m +no_defs ", - 3169 : "+title=RGNC91-93 / UTM zone 57S +proj=utm +zone=57 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3170 : "+title=RGNC91-93 / UTM zone 58S +proj=utm +zone=58 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3171 : "+title=RGNC91-93 / UTM zone 59S +proj=utm +zone=59 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ", - 3172 : "+title=IGN53 Mare / UTM zone 59S +proj=utm +zone=59 +south +ellps=intl +units=m +no_defs ", - 3296 : "+title=RGPF / UTM zone 5S +proj=utm +zone=5 +south +ellps=GRS80 +units=m +no_defs ", - 3297 : "+title=RGPF / UTM zone 6S +proj=utm +zone=6 +south +ellps=GRS80 +units=m +no_defs ", - 3298 : "+title=RGPF / UTM zone 7S +proj=utm +zone=7 +south +ellps=GRS80 +units=m +no_defs ", - 3299 : "+title=RGPF / UTM zone 8S +proj=utm +zone=8 +south +ellps=GRS80 +units=m +no_defs ", - 3302 : "+title=IGN63 Hiva Oa / UTM zone 7S +proj=utm +zone=7 +south +ellps=intl +units=m +no_defs ", - 3303 : "+title=Fatu Iva 72 / UTM zone 7S +proj=utm +zone=7 +south +ellps=intl +towgs84=347.103,1078.12,2623.92,-33.8875,70.6773,-9.3943,186.074 +units=m +no_defs ", - 3304 : "+title=Tahiti 79 / UTM zone 6S +proj=utm +zone=6 +south +ellps=intl +units=m +no_defs ", - 3305 : "+title=Moorea 87 / UTM zone 6S +proj=utm +zone=6 +south +ellps=intl +towgs84=215.525,149.593,176.229,-3.2624,-1.692,-1.1571,10.4773 +units=m +no_defs ", - 3306 : "+title=Maupiti 83 / UTM zone 5S +proj=utm +zone=5 +south +ellps=intl +towgs84=217.037,86.959,23.956,0,0,0,0 +units=m +no_defs ", - 3312 : "+title=CSG67 / UTM zone 21N +proj=utm +zone=21 +ellps=intl +towgs84=-186,230,110,0,0,0,0 +units=m +no_defs ", - 3313 : "+title=RGFG95 / UTM zone 21N +proj=utm +zone=21 +ellps=GRS80 +towgs84=2,2,-2,0,0,0,0 +units=m +no_defs ", - 3336 : "+title=IGN 1962 Kerguelen / UTM zone 42S +proj=utm +zone=42 +south +ellps=intl +towgs84=145,-187,103,0,0,0,0 +units=m +no_defs ", - 3395 : "+title=WGS 84 / World Mercator +proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 3727 : "+title=Reunion 1947 / TM Reunion +proj=tmerc +lat_0=-21.11666666666667 +lon_0=55.53333333333333 +k=1 +x_0=160000 +y_0=50000 +ellps=intl +units=m +no_defs ", - 21781 : "+title=CH1903 / LV03 +proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +x_0=600000 +y_0=200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs ", - 25830 : "+title=ETRS89 / UTM zone 30N +proj=utm +zone=30 +ellps=GRS80 +units=m +no_defs ", - 25831 : "+title=ETRS89 / UTM zone 31N +proj=utm +zone=31 +ellps=GRS80 +units=m +no_defs ", - 25832 : "+title=ETRS89 / UTM zone 32N +proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs ", - 27561 : "+title=NTF (Paris) / Lambert Nord France +proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27562 : "+title=NTF (Paris) / Lambert Centre France +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27563 : "+title=NTF (Paris) / Lambert Sud France +proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.9998774990000001 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27564 : "+title=NTF (Paris) / Lambert Corse +proj=lcc +lat_1=42.16500000000001 +lat_0=42.16500000000001 +lon_0=0 +k_0=0.9999447100000001 +x_0=234.358 +y_0=185861.369 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27571 : "+title=NTF (Paris) / Lambert zone I +proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=1200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27572 : "+title=NTF (Paris) / Lambert zone II +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27573 : "+title=NTF (Paris) / Lambert zone III +proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.9998774990000001 +x_0=600000 +y_0=3200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27574 : "+title=NTF (Paris) / Lambert zone IV +proj=lcc +lat_1=42.16500000000001 +lat_0=42.16500000000001 +lon_0=0 +k_0=0.9999447100000001 +x_0=234.358 +y_0=4185861.369 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27581 : "+title=NTF (Paris) / France I (deprecated) +proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=1200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27582 : "+title=NTF (Paris) / France II (deprecated) +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27583 : "+title=NTF (Paris) / France III (deprecated) +proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.9998774990000001 +x_0=600000 +y_0=3200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27584 : "+title=NTF (Paris) / France IV (deprecated) +proj=lcc +lat_1=42.16500000000001 +lat_0=42.16500000000001 +lon_0=0 +k_0=0.9999447100000001 +x_0=234.358 +y_0=4185861.369 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27591 : "+title=NTF (Paris) / Nord France (deprecated) +proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27592 : "+title=NTF (Paris) / Centre France (deprecated) +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27593 : "+title=NTF (Paris) / Sud France (deprecated) +proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.9998774990000001 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 27594 : "+title=NTF (Paris) / Corse (deprecated) +proj=lcc +lat_1=42.16500000000001 +lat_0=42.16500000000001 +lon_0=0 +k_0=0.9999447100000001 +x_0=234.358 +y_0=185861.369 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ", - 32601 : "+proj=utm +zone=1 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32602 : "+proj=utm +zone=2 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32603 : "+proj=utm +zone=3 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32604 : "+proj=utm +zone=4 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32605 : "+proj=utm +zone=5 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32606 : "+proj=utm +zone=6 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32607 : "+proj=utm +zone=7 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32608 : "+proj=utm +zone=8 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32609 : "+proj=utm +zone=9 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32610 : "+proj=utm +zone=10 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32611 : "+proj=utm +zone=11 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32612 : "+proj=utm +zone=12 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32613 : "+proj=utm +zone=13 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32614 : "+proj=utm +zone=14 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32615 : "+proj=utm +zone=15 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32616 : "+proj=utm +zone=16 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32617 : "+proj=utm +zone=17 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32618 : "+proj=utm +zone=18 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32619 : "+proj=utm +zone=19 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32620 : "+proj=utm +zone=20 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32621 : "+proj=utm +zone=21 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32622 : "+proj=utm +zone=22 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32623 : "+proj=utm +zone=23 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32624 : "+proj=utm +zone=24 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32625 : "+proj=utm +zone=25 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32626 : "+proj=utm +zone=26 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32627 : "+proj=utm +zone=27 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32628 : "+proj=utm +zone=28 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32629 : "+proj=utm +zone=29 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32630 : "+proj=utm +zone=30 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32631 : "+proj=utm +zone=31 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32632 : "+proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32633 : "+proj=utm +zone=33 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32634 : "+proj=utm +zone=34 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32635 : "+proj=utm +zone=35 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32636 : "+proj=utm +zone=36 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32637 : "+proj=utm +zone=37 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32638 : "+proj=utm +zone=38 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32639 : "+proj=utm +zone=39 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32640 : "+proj=utm +zone=40 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32641 : "+proj=utm +zone=41 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32642 : "+proj=utm +zone=42 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32643 : "+proj=utm +zone=43 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32644 : "+proj=utm +zone=44 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32645 : "+proj=utm +zone=45 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32646 : "+proj=utm +zone=46 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32647 : "+proj=utm +zone=47 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32648 : "+proj=utm +zone=48 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32649 : "+proj=utm +zone=49 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32650 : "+proj=utm +zone=50 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32651 : "+proj=utm +zone=51 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32652 : "+proj=utm +zone=52 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32653 : "+proj=utm +zone=53 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32654 : "+proj=utm +zone=54 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32655 : "+proj=utm +zone=55 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32656 : "+proj=utm +zone=56 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32657 : "+proj=utm +zone=57 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32658 : "+proj=utm +zone=58 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32659 : "+proj=utm +zone=59 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32660 : "+proj=utm +zone=60 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32661 : "+proj=stere +lat_0=90 +lat_ts=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32662 : "+title=WGS 84 / Plate Carree +proj=eqc +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32701 : "+proj=utm +zone=1 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32702 : "+proj=utm +zone=2 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32703 : "+proj=utm +zone=3 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32704 : "+proj=utm +zone=4 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32705 : "+proj=utm +zone=5 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32706 : "+proj=utm +zone=6 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32707 : "+proj=utm +zone=7 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32708 : "+proj=utm +zone=8 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32709 : "+proj=utm +zone=9 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32710 : "+proj=utm +zone=10 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32711 : "+proj=utm +zone=11 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32712 : "+proj=utm +zone=12 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32713 : "+proj=utm +zone=13 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32714 : "+proj=utm +zone=14 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32715 : "+proj=utm +zone=15 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32716 : "+proj=utm +zone=16 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32717 : "+proj=utm +zone=17 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32718 : "+proj=utm +zone=18 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32719 : "+proj=utm +zone=19 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32720 : "+proj=utm +zone=20 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32721 : "+proj=utm +zone=21 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32722 : "+proj=utm +zone=22 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32723 : "+proj=utm +zone=23 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32724 : "+proj=utm +zone=24 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32725 : "+proj=utm +zone=25 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32726 : "+proj=utm +zone=26 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32727 : "+proj=utm +zone=27 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32728 : "+proj=utm +zone=28 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32729 : "+proj=utm +zone=29 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32730 : "+proj=utm +zone=30 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32731 : "+proj=utm +zone=31 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32732 : "+proj=utm +zone=32 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32733 : "+proj=utm +zone=33 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32734 : "+proj=utm +zone=34 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32735 : "+proj=utm +zone=35 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32736 : "+proj=utm +zone=36 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32737 : "+proj=utm +zone=37 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32738 : "+proj=utm +zone=38 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32739 : "+proj=utm +zone=39 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32740 : "+proj=utm +zone=40 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32741 : "+proj=utm +zone=41 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32742 : "+proj=utm +zone=42 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32743 : "+proj=utm +zone=43 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32744 : "+proj=utm +zone=44 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32745 : "+proj=utm +zone=45 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32746 : "+proj=utm +zone=46 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32747 : "+proj=utm +zone=47 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32748 : "+proj=utm +zone=48 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32749 : "+proj=utm +zone=49 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32750 : "+proj=utm +zone=50 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32751 : "+proj=utm +zone=51 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32752 : "+proj=utm +zone=52 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32753 : "+proj=utm +zone=53 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32754 : "+proj=utm +zone=54 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32755 : "+proj=utm +zone=55 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32756 : "+proj=utm +zone=56 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32757 : "+proj=utm +zone=57 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32758 : "+proj=utm +zone=58 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32759 : "+proj=utm +zone=59 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32760 : "+proj=utm +zone=60 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 32761 : "+proj=stere +lat_0=-90 +lat_ts=-90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ", - 310024802 : "+title=Geoportail - France metropolitaine +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=46.500000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 310915814 : "+title=Geoportail - Antilles francaises +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=15.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 310486805 : "+title=Geoportail - Guyane +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=4.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 310700806 : "+title=Geoportail - Reunion et dependances +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-21.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 310702807 : "+title=Geoportail - Mayotte +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-12.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 310706808 : "+title=Geoportail - Saint-Pierre et Miquelon +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=47.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 310547809 : "+title=Geoportail - Nouvelle-Caledonie +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-22.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 310642810 : "+title=Geoportail - Wallis et Futuna +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.000000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-14.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 310032811 : "+title=Geoportail - Polynesie francaise +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-15.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 310642812 : "+title=Geoportail - Kerguelen +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-49.500000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 310642801 : "+title=Geoportail - Crozet +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-46.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 310642813 : "+title=Geoportail - Amsterdam et Saint-Paul +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-38.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 310642901 : "+title=Geoportail - Monde +proj=mill +towgs84=0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.000000 +a=6378137.0000 +rf=298.2572221010000 +lon_0=0.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - 5489 : "+title=RGAF09 geographiques (dms) +proj=longlat +nadgrids=@null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137 +rf=298.257222101 +units=m +no_defs", - 5490 : "+title=RGAF09 UTM Nord Fuseau 20 +proj=tmerc +nadgrids=@null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137 +rf=298.257222101 +lat_0=0.000000000 +lon_0=-63.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs" - }, - /** - * definitions CRS - * @enum - */ - CRS : { - 84 : "+title=WGS 84 longitude-latitude +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs " - }, - /** - * definitions IGNF - * @enum - */ - IGNF : { - AMST63 : "+title=Amsterdam 1963 +proj=geocent +towgs84=109.753,-528.133,-362.244,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - CROZ63 : "+title=Crozet 1963 +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - CSG67 : "+title=Guyane CSG67 +proj=geocent +towgs84=-193.0660,236.9930,105.4470,0.4814,-0.8074,0.1276,1.564900 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - ED50 : "+title=ED50 +proj=geocent +towgs84=-84.0000,-97.0000,-117.0000 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - ETRS89 : "+title=Systeme de reference terrestre Europeen (1989) +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - GUAD48 : "+title=Guadeloupe Ste Anne +proj=geocent +towgs84=-472.2900,-5.6300,-304.1200,0.4362,-0.8374,0.2563,1.898400 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - GUADFM49 : "+title=Guadeloupe Fort Marigot +proj=geocent +towgs84=136.5960,248.1480,-429.7890 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - IGN63 : "+title=IGN 1963 (Hiva Oa, Tahuata, Mohotani) +proj=geocent +towgs84=410.7210,55.0490,80.7460,-2.5779,-2.3514,-0.6664,17.331100 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - IGN72 : "+title=IGN 1972 Grande-Terre / Ile des Pins +proj=geocent +towgs84=-11.6400,-348.6000,291.6800 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - KERG62CAR : "+title=Kerguelen - K0 +proj=geocent +towgs84=144.8990,-186.7700,100.9230 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - MART38 : "+title=Martinique Fort-Desaix +proj=geocent +towgs84=126.9260,547.9390,130.4090,-2.7867,5.1612,-0.8584,13.822650 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - MAYO50 : "+title=Mayotte Combani +proj=geocent +towgs84=-599.9280,-275.5520,-195.6650,-0.0835,-0.4715,0.0602,49.281400 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - MOOREA87 : "+title=Moorea 1987 +proj=geocent +towgs84=215.9820,149.5930,176.2290,3.2624,1.6920,1.1571,10.477300 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - NTF : "+title=Nouvelle Triangulation Francaise +proj=geocent +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +units=m +no_defs", - NUKU72 : "+title=IGN 1972 Nuku Hiva +proj=geocent +towgs84=165.7320,216.7200,180.5050,-0.6434,-0.4512,-0.0791,7.420400 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - REUN47 : "+title=Reunion 1947 +proj=geocent +towgs84=789.5240,-626.4860,-89.9040,0.6006,76.7946,-10.5788,-32.324100 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - RGF93 : "+title=Reseau geodesique francais 1993 +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGFG95 : "+title=Reseau geodesique francais de Guyane 1995 +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGM04 : "+title=RGM04 (Reseau Geodesique de Mayotte 2004) +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGNC : "+title=Reseau Geodesique de Nouvelle-Caledonie +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGPF : "+title=RGPF (Reseau Geodesique de Polynesie Francaise) +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGR92 : "+title=Reseau geodesique Reunion 1992 +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGSPM06 : "+title=Reseau Geodesique Saint-Pierre-et-Miquelon (2006) +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGTAAF07 : "+title=Reseau Geodesique des TAAF (2007) +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RRAF91 : "+title=RRAF 1991 (Reseau de Reference des Antilles Francaises) +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - STPL69 : "+title=Saint-Paul 1969 +proj=geocent +towgs84=225.571,-346.608,-46.567,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - STPM50 : "+title=St Pierre et Miquelon 1950 +proj=geocent +towgs84=-95.5930,573.7630,173.4420,-0.9602,1.2510,-1.3918,42.626500 +a=6378206.4000 +rf=294.9786982000000 +units=m +no_defs", - TAHAA : "+title=Raiatea - Tahaa 51-54 (Tahaa, Base Terme Est) +proj=geocent +towgs84=72.4380,345.9180,79.4860,-1.6045,-0.8823,-0.5565,1.374600 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - TAHI79 : "+title=IGN79 (Tahiti) Iles de la Societe +proj=geocent +towgs84=221.5250,152.9480,176.7680,2.3847,1.3896,0.8770,11.474100 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - TERA50 : "+title=Pointe Geologie - Perroud 1950 +proj=geocent +towgs84=324.9120,153.2820,172.0260 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - WALL78 : "+title=Wallis-Uvea 1978 (MOP78) +proj=geocent +towgs84=253.0000,-133.0000,-127.0000 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - WGS72 : "+title=World Geodetic System 1972 +proj=geocent +towgs84=0.0000,12.0000,6.0000 +a=6378135.0000 +rf=298.2600000000000 +units=m +no_defs", - WGS84 : "+title=World Geodetic System 1984 +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - AMST63GEO : "+title=Amsterdam 1963 +proj=longlat +towgs84=109.753,-528.133,-362.244,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - CROZ63GEO : "+title=Crozet 1963 +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - CSG67GEO : "+title=Guyane CSG67 +proj=longlat +towgs84=-193.0660,236.9930,105.4470,0.4814,-0.8074,0.1276,1.564900 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - ED50G : "+title=ED50 +proj=longlat +towgs84=-84.0000,-97.0000,-117.0000 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - GUAD48GEO : "+title=Guadeloupe Ste Anne +proj=longlat +towgs84=-472.2900,-5.6300,-304.1200,0.4362,-0.8374,0.2563,1.898400 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - GUADFM49GEO : "+title=Guadeloupe Fort Marigot +proj=longlat +towgs84=136.5960,248.1480,-429.7890 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - IGN63GEO : "+title=IGN 1963 (Hiva Oa, Tahuata, Mohotani) +proj=longlat +towgs84=410.7210,55.0490,80.7460,-2.5779,-2.3514,-0.6664,17.331100 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - IGN72GEO : "+title=IGN 1972 Grande-Terre / Ile des Pins +proj=longlat +towgs84=-11.6400,-348.6000,291.6800 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - KERG62GEO : "+title=Kerguelen - K0 +proj=longlat +towgs84=144.8990,-186.7700,100.9230 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - MART38GEO : "+title=Martinique Fort-Desaix +proj=longlat +towgs84=126.9260,547.9390,130.4090,-2.7867,5.1612,-0.8584,13.822650 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - MAYO50GEO : "+title=Mayotte Combani +proj=longlat +towgs84=-599.9280,-275.5520,-195.6650,-0.0835,-0.4715,0.0602,49.281400 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - MOOREA87GEO : "+title=Moorea 1987 +proj=longlat +towgs84=215.9820,149.5930,176.2290,3.2624,1.6920,1.1571,10.477300 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - NTFG : "+title=Nouvelle Triangulation Francaise Greenwich degres sexagesimaux +proj=longlat +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +units=m +no_defs", - NTFP : "+title=Nouvelle Triangulation Francaise Paris grades +proj=longlat +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +units=m +no_defs", - NUKU72GEO : "+title=IGN 1972 Nuku Hiva +proj=longlat +towgs84=165.7320,216.7200,180.5050,-0.6434,-0.4512,-0.0791,7.420400 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - REUN47GEO : "+title=Reunion 1947 +proj=longlat +towgs84=789.5240,-626.4860,-89.9040,0.6006,76.7946,-10.5788,-32.324100 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - RGF93G : "+title=Reseau geodesique francais 1993 +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGFG95GEO : "+title=Reseau geodesique francais de Guyane 1995 +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGM04GEO : "+title=RGM04 (Reseau Geodesique de Mayotte 2004) +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGNCGEO : "+title=Reseau Geodesique de Nouvelle-Caledonie +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGPFGEO : "+title=RGPF (Reseau Geodesique de Polynesie Francaise) +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGR92GEO : "+title=Reseau geodesique de la Reunion 1992 +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGSPM06GEO : "+title=Saint-Pierre-et-Miquelon (2006) +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - RGTAAF07G : "+title=Reseau Geodesique des TAAF (2007) (dms) +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - STPL69GEO : "+title=Saint-Paul 1969 +proj=longlat +towgs84=225.571,-346.608,-46.567,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - STPM50GEO : "+title=St Pierre et Miquelon 1950 +proj=longlat +towgs84=-95.5930,573.7630,173.4420,-0.9602,1.2510,-1.3918,42.626500 +a=6378206.4000 +rf=294.9786982000000 +units=m +no_defs", - TAHAAGEO : "+title=Raiatea - Tahaa 51-54 (Tahaa, Base Terme Est) +proj=longlat +towgs84=72.4380,345.9180,79.4860,-1.6045,-0.8823,-0.5565,1.374600 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - TAHI79GEO : "+title=IGN79 (Tahiti) Iles de la Societe +proj=longlat +towgs84=221.5250,152.9480,176.7680,2.3847,1.3896,0.8770,11.474100 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - TERA50G : "+title=Pointe Geologie - Perroud 1950 +proj=longlat +towgs84=324.9120,153.2820,172.0260 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - WALL78GEO : "+title=Wallis - Uvea 1978 (MOP78) +proj=longlat +towgs84=253.0000,-133.0000,-127.0000 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs", - WGS72G : "+title=WGS72 +proj=longlat +towgs84=0.0000,12.0000,6.0000 +a=6378135.0000 +rf=298.2600000000000 +units=m +no_defs", - WGS84G : "+title=World Geodetic System 1984 +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - WGS84RRAFGEO : "+title=Reseau de reference des Antilles francaises (1988-1991) +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - XGEO : "+title=Systeme CIO-BIH +proj=longlat +towgs84=0.0000,0.0000,0.5000,0.0000,0.0000,0.0140,-0.100000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - AMST63UTM43S : "+title=Amsterdam 1963 UTM fuseau 43 Sud +proj=tmerc +towgs84=109.753,-528.133,-362.244,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=75.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - CROZ63UTM39S : "+title=Crozet 1963 +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=51.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - CSG67UTM21 : "+title=Guyane CSG67 UTM fuseau 21 +proj=tmerc +towgs84=-193.0660,236.9930,105.4470,0.4814,-0.8074,0.1276,1.564900 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-57.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - CSG67UTM22 : "+title=Guyane CSG67 UTM fuseau 22 +proj=tmerc +towgs84=-193.0660,236.9930,105.4470,0.4814,-0.8074,0.1276,1.564900 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-51.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - GEOPORTALANF : "+title=Geoportail - Antilles francaises +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=15.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - GEOPORTALASP : "+title=Geoportail - Amsterdam et Saint-Paul +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-38.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - GEOPORTALCRZ : "+title=Geoportail - Crozet +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-46.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - GEOPORTALFXX : "+title=Geoportail - France metropolitaine +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=46.500000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - GEOPORTALGUF : "+title=Geoportail - Guyane +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=4.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - GEOPORTALKER : "+title=Geoportail - Kerguelen +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-49.500000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - GEOPORTALMYT : "+title=Geoportail - Mayotte +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-12.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - GEOPORTALNCL : "+title=Geoportail - Nouvelle-Caledonie +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-22.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - GEOPORTALPYF : "+title=Geoportail - Polynesie francaise +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-15.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - GEOPORTALREU : "+title=Geoportail - Reunion et dependances +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-21.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - GEOPORTALSPM : "+title=Geoportail - Saint-Pierre et Miquelon +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=47.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - GEOPORTALWLF : "+title=Geoportail - Wallis et Futuna +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-14.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - GUAD48UTM20 : "+title=Guadeloupe Ste Anne +proj=tmerc +towgs84=-472.2900,-5.6300,-304.1200,0.4362,-0.8374,0.2563,1.898400 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-63.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - GUADFM49U20 : "+title=Guadeloupe Fort Marigot +proj=tmerc +towgs84=136.5960,248.1480,-429.7890 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-63.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - IGN63UTM7S : "+title=IGN 1963 - Hiva Oa, Tahuata, Mohotani - UTM fuseau 7 Sud +proj=tmerc +towgs84=410.7210,55.0490,80.7460,-2.5779,-2.3514,-0.6664,17.331100 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-141.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - IGN72UTM58S : "+title=IGN 1972 - UTM fuseau 58 Sud +proj=tmerc +towgs84=-11.6400,-348.6000,291.6800 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=165.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - KERG62UTM42S : "+title=Kerguelen 1962 +proj=tmerc +towgs84=144.8990,-186.7700,100.9230 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=69.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - LAMB1 : "+title=Lambert I +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=49.500000000 +lon_0=0.000000000 +k_0=0.99987734 +lat_1=49.500000000 +x_0=600000.000 +y_0=200000.000 +units=m +no_defs", - LAMB1C : "+title=Lambert I Carto +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=49.500000000 +lon_0=0.000000000 +k_0=0.99987734 +lat_1=49.500000000 +x_0=600000.000 +y_0=1200000.000 +units=m +no_defs", - LAMB2 : "+title=Lambert II +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=46.800000000 +lon_0=0.000000000 +k_0=0.99987742 +lat_1=46.800000000 +x_0=600000.000 +y_0=200000.000 +units=m +no_defs", - LAMB2C : "+title=Lambert II Carto +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=46.800000000 +lon_0=0.000000000 +k_0=0.99987742 +lat_1=46.800000000 +x_0=600000.000 +y_0=2200000.000 +units=m +no_defs", - LAMB3 : "+title=Lambert III +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=44.100000000 +lon_0=0.000000000 +k_0=0.99987750 +lat_1=44.100000000 +x_0=600000.000 +y_0=200000.000 +units=m +no_defs", - LAMB3C : "+title=Lambert III Carto +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=44.100000000 +lon_0=0.000000000 +k_0=0.99987750 +lat_1=44.100000000 +x_0=600000.000 +y_0=3200000.000 +units=m +no_defs", - LAMB4 : "+title=Lambert IV +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=42.165000000 +lon_0=0.000000000 +k_0=0.99994471 +lat_1=42.165000000 +x_0=234.358 +y_0=185861.369 +units=m +no_defs", - LAMB4C : "+title=Lambert IV Carto +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=42.165000000 +lon_0=0.000000000 +k_0=0.99994471 +lat_1=42.165000000 +x_0=234.358 +y_0=4185861.369 +units=m +no_defs", - LAMB93 : "+title=Lambert 93 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=46.500000000 +lon_0=3.000000000 +lat_1=44.000000000 +lat_2=49.000000000 +x_0=700000.000 +y_0=6600000.000 +units=m +no_defs", - RGF93CC42 : "+title=Lambert conique conforme Zone 1 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=42.000000000 +lon_0=3.000000000 +lat_1=41.200000000 +lat_2=42.800000000 +x_0=1700000.000 +y_0=1200000.000 +units=m +no_defs", - RGF93CC43 : "+title=Lambert conique conforme Zone 2 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=43.000000000 +lon_0=3.000000000 +lat_1=42.200000000 +lat_2=43.800000000 +x_0=1700000.000 +y_0=2200000.000 +units=m +no_defs", - RGF93CC44 : "+title=Lambert conique conforme Zone 3 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=44.000000000 +lon_0=3.000000000 +lat_1=43.200000000 +lat_2=44.800000000 +x_0=1700000.000 +y_0=3200000.000 +units=m +no_defs", - RGF93CC45 : "+title=Lambert conique conforme Zone 4 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=45.000000000 +lon_0=3.000000000 +lat_1=44.200000000 +lat_2=45.800000000 +x_0=1700000.000 +y_0=4200000.000 +units=m +no_defs", - RGF93CC46 : "+title=Lambert conique conforme Zone 5 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=46.000000000 +lon_0=3.000000000 +lat_1=45.200000000 +lat_2=46.800000000 +x_0=1700000.000 +y_0=5200000.000 +units=m +no_defs", - RGF93CC47 : "+title=Lambert conique conforme Zone 6 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=47.000000000 +lon_0=3.000000000 +lat_1=46.200000000 +lat_2=47.800000000 +x_0=1700000.000 +y_0=6200000.000 +units=m +no_defs", - RGF93CC48 : "+title=Lambert conique conforme Zone 7 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=48.000000000 +lon_0=3.000000000 +lat_1=47.200000000 +lat_2=48.800000000 +x_0=1700000.000 +y_0=7200000.000 +units=m +no_defs", - RGF93CC49 : "+title=Lambert conique conforme Zone 8 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=49.000000000 +lon_0=3.000000000 +lat_1=48.200000000 +lat_2=49.800000000 +x_0=1700000.000 +y_0=8200000.000 +units=m +no_defs", - RGF93CC50 : "+title=Lambert conique conforme Zone 9 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=50.000000000 +lon_0=3.000000000 +lat_1=49.200000000 +lat_2=50.800000000 +x_0=1700000.000 +y_0=9200000.000 +units=m +no_defs", - LAMBE : "+title=Lambert II etendu +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=46.800000000 +lon_0=0.000000000 +k_0=0.99987742 +lat_1=46.800000000 +x_0=600000.000 +y_0=2200000.000 +units=m +no_defs", - MART38UTM20 : "+title=Martinique Fort-Desaix +proj=tmerc +towgs84=126.9260,547.9390,130.4090,-2.7867,5.1612,-0.8584,13.822650 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-63.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - MAYO50UTM38S : "+title=Mayotte Combani +proj=tmerc +towgs84=-599.9280,-275.5520,-195.6650,-0.0835,-0.4715,0.0602,49.281400 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=45.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - MILLER : "+title=Geoportail - Monde +proj=mill +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lon_0=0.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs", - MOOREA87U6S : "+title=Moorea 1987 - UTM fuseau 6 Sud +proj=tmerc +towgs84=215.9820,149.5930,176.2290,3.2624,1.6920,1.1571,10.477300 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-147.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - NUKU72U7S : "+title=IGN 1972 Nuku Hiva - UTM fuseau 7 Sud +proj=tmerc +towgs84=165.7320,216.7200,180.5050,-0.6434,-0.4512,-0.0791,7.420400 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-141.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - // REUN47GAUSSL : "+title=Reunion Gauss Laborde +proj=gstmerc +towgs84=789.5240,-626.4860,-89.9040,0.6006,76.7946,-10.5788,-32.324100 +a=6378388.0000 +rf=297.0000000000000 +lat_0=-21.116666667 +lon_0=55.533333333 +k_0=1.00000000 +x_0=160000.000 +y_0=50000.000 +units=m +no_defs", - RGM04UTM38S : "+title=UTM fuseau 38 Sud (Reseau Geodesique de Mayotte 2004) +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=45.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - RGNCUTM57S : "+title=Reseau Geodesique de Nouvelle-Caledonie - UTM fuseau 57 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=159.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - RGNCUTM58S : "+title=Reseau Geodesique de Nouvelle-Caledonie - UTM fuseau 58 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=165.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - RGNCUTM59S : "+title=Reseau Geodesique de Nouvelle-Caledonie - UTM fuseau 59 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=171.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - RGPFUTM5S : "+title=RGPF - UTM fuseau 5 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-153.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - RGPFUTM6S : "+title=RGPF - UTM fuseau 6 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-147.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - RGPFUTM7S : "+title=RGPF - UTM fuseau 7 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-141.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - RGR92UTM40S : "+title=RGR92 UTM fuseau 40 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=57.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - RGSPM06U21 : "+title=Saint-Pierre-et-Miquelon (2006) UTM Fuseau 21 Nord +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-57.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - STPL69UTM43S : "+title=Saint-Paul 1969 UTM fuseau 43 Sud +proj=tmerc +towgs84=225.571,-346.608,-46.567,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=75.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - STPM50UTM21 : "+title=St Pierre et Miquelon 1950 +proj=tmerc +towgs84=-95.5930,573.7630,173.4420,-0.9602,1.2510,-1.3918,42.626500 +a=6378206.4000 +rf=294.9786982000000 +lat_0=0.000000000 +lon_0=-57.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - TAHAAUTM05S : "+title=Tahaa 1951 +proj=tmerc +towgs84=72.4380,345.9180,79.4860,-1.6045,-0.8823,-0.5565,1.374600 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-153.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - TAHI51UTM06S : "+title=Tahiti-Terme Nord UTM fuseau 6 Sud +proj=tmerc +towgs84=162.0000,117.0000,154.0000 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-147.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - TAHI79UTM6S : "+title=Tahiti 1979 +proj=tmerc +towgs84=221.5250,152.9480,176.7680,2.3847,1.3896,0.8770,11.474100 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-147.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - TERA50STEREO : "+title=Terre Adelie 1950 +proj=stere +towgs84=324.9120,153.2820,172.0260 +a=6378388.0000 +rf=297.0000000000000 +lat_0=-90.000000000 +lon_0=140.000000000 +lat_ts=-67 +k=0.96027295 +x_0=300000.000 +y_0=-2299363.482 +units=m +no_defs", - UTM01SW84 : "+title=World Geodetic System 1984 UTM fuseau 01 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-177.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - UTM20W84GUAD : "+title=World Geodetic System 1984 UTM fuseau 20 Nord-Guadeloupe +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-63.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM20W84MART : "+title=World Geodetic System 1984 UTM fuseau 20 Nord-Martinique +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-63.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM22RGFG95 : "+title=RGFG95 UTM fuseau 22 Nord-Guyane +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-51.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM39SW84 : "+title=World Geodetic System 1984 UTM fuseau 39 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=51.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - UTM42SW84 : "+title=World Geodetic System 1984 UTM fuseau 42 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=69.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - UTM43SW84 : "+title=World Geodetic System 1984 UTM fuseau 43 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=75.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - WALL78UTM1S : "+title=Wallis-Uvea 1978 (MOP78) UTM 1 SUD +proj=tmerc +towgs84=253.0000,-133.0000,-127.0000 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-177.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs", - ETRS89GEO : "+title=ETRS89 geographiques (dms) +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs", - ETRS89LAEA : "+title=ETRS89 Lambert Azimutal Equal Area +proj=laea +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=52.000000000 +lon_0=10.000000000 +x_0=4321000.000 +y_0=3210000.000 +units=m +no_defs", - ETRS89LCC : "+title=ETRS89 Lambert Conformal Conic +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=52.000000000 +lon_0=9.999999995 +lat_1=35.000000000 +lat_2=65.000000000 +x_0=4000000.000 +y_0=2800000.000 +units=m +no_defs", - UTM26ETRS89 : "+title=Europe - de 30d a 24d Ouest +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-27.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM27ETRS89 : "+title=Europe - de 24d a 18d Ouest +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-21.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM28ETRS89 : "+title=Europe - de 18d a 12d Ouest +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-15.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM29ETRS89 : "+title=Europe - de 12d a 6d Ouest +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-9.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM30ETRS89 : "+title=Europe - de -6d a 0d Ouest +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-3.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM31ETRS89 : "+title=Europe - de 0d a 6d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=3.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM32ETRS89 : "+title=Europe - de 6d a 12d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=9.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM33ETRS89 : "+title=Europe - de 12d a 18d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=15.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM34ETRS89 : "+title=Europe - de 18d a 24d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=21.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM35ETRS89 : "+title=Europe - de 24d a 30d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=27.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM36ETRS89 : "+title=Europe - de 30d a 36d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=33.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM37ETRS89 : "+title=Europe - de 36d a 42d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=39.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs", - UTM38ETRS89 : "+title=Europe - de 42d a 48d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=45.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs" - } -}; - -export default Register; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/SearchEngineUtils.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/SearchEngineUtils.d.ts deleted file mode 100644 index ea28c5b5a..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/SearchEngineUtils.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -export default SearchEngineUtils; -declare namespace SearchEngineUtils { - namespace advancedSearchFiltersByDefault { - let PositionOfInterest: ({ - name: string; - title: string; - value: string[]; - } | { - name: string; - title: string; - value?: undefined; - })[]; - let StreetAddress: { - name: string; - title: string; - }[]; - let CadastralParcel: { - name: string; - title: string; - description: string; - }[]; - } - function zoomToResultsByDefault(info: Object): Integer; -} -//# sourceMappingURL=SearchEngineUtils.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/SearchEngineUtils.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/SearchEngineUtils.d.ts.map deleted file mode 100644 index 0eb430ef5..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/SearchEngineUtils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"SearchEngineUtils.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/SearchEngineUtils.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;IAwG6B,uDA4CxB"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/SearchEngineUtils.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/SearchEngineUtils.js deleted file mode 100644 index 7c2508318..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/SearchEngineUtils.js +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @module SearchEngineUtils - * @alias [private] SearchEngineUtils - * @description - * ... - * - * @example - * advancedSearchFiltersByDefault(); - * zoomToResultsByDefault(); - */ -var SearchEngineUtils = { - /** - * Advanced Search Filters by default - * @function advancedSearchFiltersByDefault - */ - advancedSearchFiltersByDefault : { - PositionOfInterest : [ - { - name : "category", - title : "Type", - value : [ - "cimetière", - "aérodrome", - "réservoir", - "administratif", - "construction linéaire", - "construction ponctuelle", - "construction surfacique", - "cours d'eau", - "détail hydrographique", - "détail orographique", - "équipement de transport", - "plan d'eau", - "poste de transformation", - "terrain de sport", - "transport par câble", - "zone d'activité ou d'intérêt", - "zone d'habitation", - "lieu-dit non habité" - ] - }, { - name : "postcode", - title : "Code postal" - }, { - name : "citycode", - title : "Code INSEE" - } - ], - StreetAddress : [ - { - name : "city", - title : "Ville" - }, { - name : "postcode", - title : "Code postal" - }, { - name : "citycode", - title : "Code INSEE" - } - ], - CadastralParcel : [ - { - name : "departmentcode", - title : "Code département (INSEE)", - description : "Code INSEE du département (ex: 01, 94)" - }, { - name : "municipalitycode", - title : "Code commune (INSEE)", - description : "Code INSEE de la commune : 3 chiffres (ex: 067)" - }, { - name : "city", - title : "Nom commune", - description : "Nom de la commune" - }, { - name : "oldmunicipalitycode", - title : "Commune absorbée", - description : "Commune absorbée : 3 chiffres (ex: 000, 001)" - }, { - name : "districtcode", - title : "Arrondissement", - description : "Arrondissement : 3 chiffres (ex: 004, 012)" - }, { - name : "section", - title : "Section", - description : "Section Cadastrale : 2 caractères (chiffre et/ou lettre)" - }, { - name : "number", - title : "Numéro", - description : "Numéro de la parcelle : 4 chiffres (ex: 0041, 0250)" - }, { - name : "sheet", - title : "Feuille", - description : "Numéro de la feuille cadastrale" - } - ] - }, - - /** - * Provides default zoom based on results. - * - * @function zoomToResultsByDefault - * @param {Object} info - location information - * @returns {Integer} zoom level - */ - zoomToResultsByDefault : function (info) { - // FIXME - // la classification du geocodage est differente de l'importance de l'autocompletion ! - - var zoom = 15; - - var service = info.service; - var fields = info.fields; - var type = info.type; - - var importance = { - 1 : 11, - 2 : 12, - 3 : 13, - 4 : 14, - 5 : 15, - 6 : 16, - 7 : 17, - 8 : 17 - }; - - // AutoCompletion POI - if (service === "SuggestedLocation") { - if (type === "PositionOfInterest") { - zoom = importance[fields.classification]; - } - } - - // Geocodage POI - if (service === "GeocodedLocation") { - if (type === "PositionOfInterest") { - zoom = importance[fields.importance] || 14; // au cas où la recherche est en freeform ! - } - } - - if (type === "StreetAddress") { - zoom = 17; - } - - if (type === "CadastralParcel") { - zoom = 17; - } - - return zoom; - } -}; - -export default SearchEngineUtils; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/SelectorID.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/Utils/SelectorID.d.ts deleted file mode 100644 index 3841c84b0..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/SelectorID.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default SelectorID; -declare namespace SelectorID { - function generate(): number; - function name(id: string): string; - function index(id: string): string; - function uuid(id: string): string; -} -//# sourceMappingURL=SelectorID.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/SelectorID.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/Utils/SelectorID.d.ts.map deleted file mode 100644 index 3ffb359bf..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/SelectorID.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"SelectorID.d.ts","sourceRoot":"","sources":["../../../../src/packages/Utils/SelectorID.js"],"names":[],"mappings":";;IAqBe,4BAEN;IASE,kCAWN;IASO,mCAYP;IASM,kCASN"} \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/Utils/SelectorID.js b/build/release/geoportal-extensions-openlayers/src/packages/Utils/SelectorID.js deleted file mode 100644 index 1b70589ef..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/Utils/SelectorID.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @module SelectorID - * @alias [private] SelectorID - * @description - * formalisme d'un tag ID : - * -> NAME(_ORDER)-1460636385836 - * - * @example - * Ex. - * GProutePoints-1460636385836 - * GProutePoint_10-1460636385836 - */ -var SelectorID = { - - /** - * Construction d'un identifiant statique basé sur le timestamp, - * et qui s'incremente de +1 à chaque appel - * @function generate - */ - generate : (function () { - var timestamp = Math.floor(Date.now()); - return function () { - return timestamp++; - }; - })(), - - /** - * nom du tag - * @function name - * @param {String} id - the id - * @returns {String} index - */ - name : function (id) { - var name = null; - - var i = id.lastIndexOf("-"); - if (i === -1) { - name = id; - } else { - name = id.substring(0, i); - } - - return name; - }, - - /** - * numero d'identifiant du tag - * - * @function index - * @param {String} id - the id - * @returns {String} index - */ - index : function (id) { - var index = null; - - var name = this.name(id); - // if (name !== id) { - var i = name.lastIndexOf("_"); - if (i !== -1) { - index = name.substring(i + 1); - } - // } - - return index; - }, - - /** - * uuid du tag - * - * @function uuid - * @param {String} id - the id - * @returns {String} uuid - */ - uuid : function (id) { - var uuid = null; - - var i = id.lastIndexOf("-"); - if (i !== -1) { - uuid = parseInt(id.substring(i + 1), 10); - } - - return uuid; - } - -}; - -export default SelectorID; diff --git a/build/release/geoportal-extensions-openlayers/src/packages/bundle.d.ts b/build/release/geoportal-extensions-openlayers/src/packages/bundle.d.ts deleted file mode 100644 index 42c19024e..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/bundle.d.ts +++ /dev/null @@ -1,105 +0,0 @@ -/** Version */ -export const version: any; -/** Publication date */ -export const date: any; -export var Services: any; -export var Error: any; -export var Helper: any; -export var Protocols: any; -export var servicesDate: any; -export var servicesVersion: any; -import HelperUtils from "./Utils/Helper"; -import LayerUtils from "./Utils/LayerUtils"; -import ProxyUtils from "./Utils/ProxyUtils"; -import ColorUtils from "./Utils/ColorUtils"; -import MathUtils from "./Utils/MathUtils"; -import Logger from "./Utils/LoggerByDefault"; -declare namespace Ol { - namespace gp { - export { GfiUtils }; - } - let includeProjections: () => void; - namespace style { - export { Editor }; - export namespace editor { - export { Style }; - export { Filter }; - export { Layer }; - export { Legend }; - export { Group }; - export { Themes }; - export { Search }; - } - } - namespace format { - export { KML as KMLExtended }; - export { GPX as GPXExtended }; - export { GeoJSON as GeoJSONExtended }; - } - namespace source { - export { WMTS as WMTSExtended }; - export { SourceWMTS as GeoportalWMTS }; - export { SourceWMS as GeoportalWMS }; - } - namespace layer { - export { LayerWMTS as GeoportalWMTS }; - export { LayerWMS as GeoportalWMS }; - export { LayerMapBox as GeoportalMapBox }; - } - namespace control { - export { LayerSwitcher }; - export { GeoportalAttribution }; - export { GetFeatureInfo }; - export { SearchEngine }; - export { Route }; - export { Isocurve }; - export { MousePosition as GeoportalMousePosition }; - export { Drawing }; - export { ReverseGeocode }; - export { LayerImport }; - export { MeasureLength }; - export { MeasureArea }; - export { MeasureAzimuth }; - export { Markers as DefaultMarkers }; - export { ElevationPath }; - export { LocationSelector }; - export { ButtonExport as Export }; - } -} -import GfiUtils from "./Controls/Utils/Gfi"; -import Editor from "./Controls/Editor/Editor"; -import Style from "./Controls/Editor/Style"; -import Filter from "./Controls/Editor/Filter"; -import Layer from "./Controls/Editor/Layer"; -import Legend from "./Controls/Editor/Legend"; -import Group from "./Controls/Editor/Group"; -import Themes from "./Controls/Editor/Themes"; -import Search from "./Controls/Editor/Search"; -import KML from "./Formats/KML"; -import GPX from "./Formats/GPX"; -import GeoJSON from "./Formats/GeoJSON"; -import WMTS from "./Sources/WMTS"; -import SourceWMTS from "./Layers/SourceWMTS"; -import SourceWMS from "./Layers/SourceWMS"; -import LayerWMTS from "./Layers/LayerWMTS"; -import LayerWMS from "./Layers/LayerWMS"; -import LayerMapBox from "./Layers/LayerMapBox"; -import LayerSwitcher from "./Controls/LayerSwitcher/LayerSwitcher"; -import GeoportalAttribution from "./Controls/Attribution/GeoportalAttribution"; -import GetFeatureInfo from "./Controls/GetFeatureInfo/GetFeatureInfo"; -import SearchEngine from "./Controls/SearchEngine/SearchEngine"; -import Route from "./Controls/Route/Route"; -import Isocurve from "./Controls/Isocurve/Isocurve"; -import MousePosition from "./Controls/MousePosition/MousePosition"; -import Drawing from "./Controls/Drawing/Drawing"; -import ReverseGeocode from "./Controls/ReverseGeocode/ReverseGeocode"; -import LayerImport from "./Controls/LayerImport/LayerImport"; -import MeasureLength from "./Controls/Measures/MeasureLength"; -import MeasureArea from "./Controls/Measures/MeasureArea"; -import MeasureAzimuth from "./Controls/Measures/MeasureAzimuth"; -import Markers from "./Controls/Utils/Markers"; -import ElevationPath from "./Controls/ElevationPath/ElevationPath"; -import LocationSelector from "./Controls/LocationSelector/LocationSelector"; -import ButtonExport from "./Controls/Export/Export"; -export { HelperUtils, LayerUtils, ProxyUtils, ColorUtils, MathUtils, Logger, Ol as olExtended }; -//# sourceMappingURL=bundle.d.ts.map \ No newline at end of file diff --git a/build/release/geoportal-extensions-openlayers/src/packages/bundle.d.ts.map b/build/release/geoportal-extensions-openlayers/src/packages/bundle.d.ts.map deleted file mode 100644 index feaf2da4f..000000000 --- a/build/release/geoportal-extensions-openlayers/src/packages/bundle.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../../src/packages/bundle.js"],"names":[],"mappings":"AAiKA,cAAc;AACd,0BAAmC;AACnC,uBAAuB;AACvB,uBAA6B;AAzC7B,yBAA2B;AAC3B,sBAAqB;AACrB,uBAAuB;AACvB,0BAA6B;AAE7B,6BAAmC;AACnC,gCAAyC;wBAtBjB,gBAAgB;uBACjB,oBAAoB;uBACpB,oBAAoB;uBACnB,oBAAoB;sBACtB,mBAAmB;mBACtB,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA/CvB,sBAAsB;mBAwCxB,0BAA0B;kBAP3B,yBAAyB;mBACxB,0BAA0B;kBAC3B,yBAAyB;mBAExB,0BAA0B;kBAC3B,yBAAyB;mBAFxB,0BAA0B;mBAG1B,0BAA0B;gBArC7B,eAAe;gBACf,eAAe;oBACX,mBAAmB;iBAEtB,gBAAgB;uBACV,qBAAqB;sBACtB,oBAAoB;sBACpB,oBAAoB;qBACrB,mBAAmB;wBAChB,sBAAsB;0BAEpB,wCAAwC;iCAUjC,6CAA6C;2BATnD,0CAA0C;yBAC5C,sCAAsC;kBAG7C,wBAAwB;qBACrB,8BAA8B;0BAHzB,wCAAwC;oBAC9C,4BAA4B;2BAGrB,0CAA0C;wBAE7C,oCAAoC;0BAIlC,mCAAmC;wBACrC,iCAAiC;2BAC9B,oCAAoC;oBAJ3C,0BAA0B;0BACpB,wCAAwC;6BAJrC,8CAA8C;yBAQlD,0BAA0B"} \ No newline at end of file diff --git a/build/release/package.js b/build/release/package.js new file mode 100644 index 000000000..c766335aa --- /dev/null +++ b/build/release/package.js @@ -0,0 +1,96 @@ +/* eslint-disable no-console */ +const fse = require("fs-extra"); +const path = require("path"); +const child_process = require("child_process"); + +async function main () { + // creation du répertoire de build + const builddir = "dist/package"; + fse.removeSync(path.join(builddir)); + fse.mkdirSync(path.join(builddir), { recursive : true }); + console.log("✔ correctly mkdir package dir !"); + + // copie des sources + const copyFilter = (src, dest) => { + if (src.includes("bundle")) { + return false; + } + return true; + }; + fse.removeSync(path.join(builddir, "src")); + fse.mkdirSync(path.join(builddir, "src"), { recursive : true }); + console.log("✔ correctly mkdir src dir !"); + + fse.copySync("src", path.join(builddir, "src"), { filter : copyFilter }); + console.log("✔ correctly copy src dir !"); + + // generation des definitions + var typescmd = "npm run generate-types"; + try { + child_process.execSync(`${typescmd}`); + console.log("✔ correctly generate types dir !"); + } catch (e) { + console.error(e); + process.exit(1); + } + + fse.copySync(path.join("dist", "src"), path.join(builddir, "src"), { filter : copyFilter }); + console.log("✔ correctly copy types dir !"); + + // copie de la doc + fse.mkdirSync(path.join(builddir, "doc"), { recursive : true }); + fse.copySync("doc", path.join(builddir, "doc")); + console.log("✔ correctly copy doc dir !"); + + // copie des ressources annexes + fse.copySync("README.md", path.join(builddir, "README.md")); + fse.copySync("LICENCE.md", path.join(builddir, "LICENCE.md")); + console.log("✔ correctly copy resources files !"); + + // creation du package.json + const pkg = fse.readJsonSync("./package.json"); + delete pkg.scripts; + delete pkg.devDependencies; + fse.writeJsonSync(path.join(builddir, "package.json"), pkg, { spaces : 2 }); + console.log("✔ correctly create package.json !"); + + // creation du .npmignore + fse.outputFileSync(path.join(builddir, ".npmignore"), "*.tgz"); + console.log("✔ correctly create git ignore !"); + + // copie et/ou generation des themes + fse.removeSync(path.join(builddir, "css")); + fse.mkdirSync(path.join(builddir, "css"), { recursive : true }); + console.log("✔ correctly mkdir css dir !"); + + if (!fse.pathExistsSync(path.join("dist", "bundle"))) { + var bundlecmd = "npm run build:bundle"; + try { + child_process.execSync(`${bundlecmd}`); + console.log("✔ correctly generate bundle dir !"); + } catch (e) { + console.error(e); + process.exit(1); + } + } + fse.copySync(path.join("dist", "bundle", "Dsfr.css"), path.join(builddir, "css", "Dsfr.css")); + fse.copySync(path.join("dist", "bundle", "Classic.css"), path.join(builddir, "css", "Classic.css")); + console.log("✔ correctly copy css files !"); + + // creation du package tgz + var packcmd = "npm pack"; + try { + child_process.execSync(`${packcmd}`, { cwd : path.join(builddir) }); + console.log("✔ correctly create package tgz !"); + } catch (e) { + console.error(e); + process.exit(1); + } +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); + +process.exit(0); \ No newline at end of file diff --git a/build/webpack/README.md b/build/webpack/README.md new file mode 100644 index 000000000..3b25d164d --- /dev/null +++ b/build/webpack/README.md @@ -0,0 +1,66 @@ +# Information + +> construction du package des bundles + +## config webpack + + + +## bundles par modules + +> on n'expose pas la variable **Gp** +> car on expose le nom du module + +Les **externals** sont ajoutés pour gèrer les dependances des autres modules + +Ex. de commande : + +```sh +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=GeoportalAttribution --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=Drawing --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=Editor --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=ElevationPath --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=Export --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=GetFeatureInfo --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=Isocurve --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=LayerImport --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=LayerSwitcher --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=LocationSelector --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=MousePosition --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=ReverseGeocode --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=Route --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=SearchEngine --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=MeasureArea --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=MeasureLength --mode=development +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=MeasureAzimuth --mode=development + +./node_modules/.bin/webpack --config build/webpack/formats.webpack.config.js --mode=development +./node_modules/.bin/webpack --config build/webpack/layers.webpack.config.js --mode=development +./node_modules/.bin/webpack --config build/webpack/crs.webpack.config.js --mode=development +``` + +ou + +```sh +./node_modules/.bin/webpack --config build/webpack/modules.webpack.config.js --mode=development +``` + +ou + +```sh +./node_modules/.bin/webpack --config build/webpack/controls.webpack.config.js --env entry=GeoportalAttribution,Drawing,Editor,ElevationPath,Export,GetFeatureInfo,Isocurve,LayerImport,LayerSwitcher,LocationSelector,MousePosition,ReverseGeocode,Route,SearchEngine,MeasureArea,MeasureLength,MeasureAzimuth --mode=development +``` + +## bundle complet + +> on expose la variable **Gp* + +TODO : proj4 doit il être exposé ? + +```sh +./node_modules/.bin/webpack --config build/webpack/bundle.webpack.config.js +``` + +## CSS par thèmes + +chaque process (packages ou modules) extrait les css par thème diff --git a/build/webpack/bundle.webpack.config.js b/build/webpack/bundle.webpack.config.js new file mode 100644 index 000000000..67b0ac113 --- /dev/null +++ b/build/webpack/bundle.webpack.config.js @@ -0,0 +1,209 @@ +/* global module, __dirname */ + +// -- modules +var fs = require("fs"); +var path = require("path"); +var webpack = require("webpack"); +var header = require("string-template"); + +// -- plugins +var ESLintWebpackPlugin = require("eslint-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var BannerWebPackPlugin = webpack.BannerPlugin; +var EnvWebPackPlugin = webpack.EnvironmentPlugin; +var TerserJsWebPackPlugin = require("terser-webpack-plugin"); +var OptimizeCSSWebPackPlugin = require("css-minimizer-webpack-plugin"); +var JsDocWebPackPlugin = require("../scripts/webpackPlugins/jsdoc-plugin"); + +// -- variables +var rootdir = path.join(__dirname, "../.."); +var pkg = require(path.join(rootdir, "package.json")); + +module.exports = (env, argv) => { + // env transmis pour la config des samples + env["type"] = "bundle"; + + var isDevelopment = (argv.mode === "development"); + return { + extends : isDevelopment ? [ + path.resolve(__dirname, "./extend.themes.webpack.js"), + path.resolve(__dirname, "./extend.samples.webpack.js"), + path.resolve(__dirname, "./extend.banners.webpack.js") + ] : [ + path.resolve(__dirname, "./extend.themes.webpack.js"), + path.resolve(__dirname, "./extend.banners.webpack.js") + ], + entry : { + "GpfExtOL" : path.join(rootdir, "src", "packages", "bundle.js") + }, + output : { + path : path.join(rootdir, "dist", "bundle"), + filename : "[name].js", + library : "Gp" + }, + resolve : { + alias : {} + }, + externals : [ + function ({ context, request }, callback) { + if (/^ol\/.+$/.test(request)) { + // liste des modules ES6 à garder dans le code... + if ([ + "ol/events/EventType", + "ol/events/EventType.js", + "ol/events", + "ol/events.js", + "ol/render/Feature", + "ol/render/Feature.js" + ].includes(request)) { + return callback(); + } + const replacedWith = request.replace(/\.js$/g, "").replace(/\//g, "."); + return callback(null, replacedWith); + } + callback(); + }, + { + ol : { + commonjs : "ol", + commonjs2 : "ol", + amd : "ol", + root : "ol" + }, + request : { + commonjs2 : "request", + commonjs : "request", + amd : "require" + }, + xmldom : { + commonjs2 : "xmldom", + commonjs : "xmldom", + amd : "require" + } + } + ], + devtool : "source-map", + stats : "normal", + devServer : { + https : true, + watchFiles : { + paths : ["src/**/*"], + options : { + usePolling : true, + }, + }, + devMiddleware : { + index : true, + mimeTypes : { phtml : "text/html" }, + publicPath : "/dist/packages/", + serverSideRender : true, + writeToDisk : true, + }, + + }, + optimization : { + /** MINIFICATION */ + minimizer : [ + new TerserJsWebPackPlugin({ + extractComments : false, + terserOptions : { + output : { + comments : false, + }, + mangle : true + } + }), + new OptimizeCSSWebPackPlugin({}) + ] + }, + module : { + rules : [ + { + test : /\.js$/, + include : [ + path.join(rootdir, "src", "packages") + ], + exclude : /node_modules/, + use : [ + { + loader : "babel-loader", + options : { + presets : ["@babel/preset-env"] + } + } + ] + }, + // { + // test : require.resolve("proj4"), + // use : [{ + // loader : "expose-loader", + // options : { + // exposes : "proj4" + // } + // }] + // }, + // { + // test : require.resolve("eventbusjs"), + // use : [{ + // loader : "expose-loader", + // options : { + // exposes : "eventbus" + // } + // }] + // }, + // { + // test : require.resolve("ol-mapbox-style"), + // use : [{ + // loader : "expose-loader", + // options : { + // exposes : "olms" + // } + // }] + // }, + { + test : /\.css$/, + include : [ + path.join(rootdir, "src", "packages", "CSS"), + /node_modules\/@gouvfr\/dsfr\/dist/, + ], + use : [ + MiniCssExtractPlugin.loader, + "css-loader" + ] + }, + { + test : /\.(png|jpg|gif|svg|woff|woff2)$/, + type : "asset/inline" + } + ] + }, + plugins : [ + /** EXECUTION DU LINTER */ + new ESLintWebpackPlugin({ + + }), + /** GENERATION DE LA JSDOC */ + new JsDocWebPackPlugin({ + conf : path.join(rootdir, "build/jsdoc/jsdoc.json") + }), + /** CSS avec IMAGES en base64 */ + new MiniCssExtractPlugin({ + filename : "[name].css" + }), + /** LOGGER */ + new EnvWebPackPlugin({ + VERBOSE : isDevelopment + }), + /** AJOUT DES LICENCES */ + new BannerWebPackPlugin({ + banner : header(fs.readFileSync(path.join(rootdir, "build/licences", "licence-ign.tmpl"), "utf8"), { + __BRIEF__ : pkg.name, + __VERSION__ : pkg.version, + __DATE__ : pkg.date + }), + raw : true, + entryOnly : true + }) + ] + }; +}; diff --git a/build/webpack/controls.webpack.config.js b/build/webpack/controls.webpack.config.js new file mode 100644 index 000000000..c093b53da --- /dev/null +++ b/build/webpack/controls.webpack.config.js @@ -0,0 +1,106 @@ +var path = require("path"); + +var rootdir = path.join(__dirname, "../.."); + +module.exports = (env, argv) => { + // argv + var isDevelopment = (argv.mode === "development"); + // env transmis pour la config des samples + env["type"] = "modules"; + + // entries & externals + var entries = {}; + var externals = []; + + var names = env.entry.split(","); + for (let index = 0; index < names.length; index++) { + var name = names[index]; + var moduledir = name; + var key = name; + + switch (name) { + case "GeoportalAttribution": + moduledir = "Attribution"; + // ras + break; + case "Drawing": + externals.push({ "./src/packages/Controls/LayerSwitcher/LayerSwitcher.js" : "LayerSwitcher" }); + // formats + break; + case "Isocurve": + externals.push({ "./src/packages/Controls/LayerSwitcher/LayerSwitcher.js" : "LayerSwitcher" }); + externals.push({ "./src/packages/Controls/LocationSelector/LocationSelector.js" : "LocationSelector" }); + externals.push({ "./src/packages/Controls/Export/Export.js" : "Export" }); + // formats + break; + case "ElevationPath": + externals.push({ "./src/packages/Controls/LayerSwitcher/LayerSwitcher.js" : "LayerSwitcher" }); + externals.push({ "./src/packages/Controls/Export/Export.js" : "Export" }); + // formats + break; + case "Export": + // formats + break; + case "GetFeatureInfo": + // ras + break; + case "LayerImport": + externals.push({ "./src/packages/Controls/LayerSwitcher/LayerSwitcher.js" : "LayerSwitcher" }); + externals.push({ "./src/packages/Controls/Route/Route.js" : "Route" }); + externals.push({ "./src/packages/Controls/Isocurve/Isocurve.js" : "Isocurve" }); + externals.push({ "./src/packages/Controls/ElevationPath/ElevationPath.js" : "ElevationPath" }); + // formats + break; + case "LayerSwitcher": + // ras + break; + case "LocationSelector": + // ras + break; + case "MousePosition": + key = "GeoportalMousePosition"; + // crs + break; + case "ReverseGeocode": + externals.push({ "./src/packages/Controls/LayerSwitcher/LayerSwitcher.js" : "LayerSwitcher" }); + break; + case "Route": + externals.push({ "./src/packages/Controls/LayerSwitcher/LayerSwitcher.js" : "LayerSwitcher" }); + externals.push({ "./src/packages/Controls/Export/Export.js" : "Export" }); + externals.push({ "./src/packages/Controls/LocationSelector/LocationSelector.js" : "LocationSelector" }); + // formats + break; + case "SearchEngine": + // crs + break; + case "MeasureArea": + case "MeasureLength": + case "MeasureAzimuth": + // ras + moduledir = "Measures"; + break; + case "Editor": + // ras + break; + default: + break; + } + + entries["GpfExtOl" + key] = path.join(rootdir, "src", "packages", "Controls", moduledir, name + ".js"); + console.log("####", key, entries[key]); + } + + return { + extends : isDevelopment ? [ + path.resolve(__dirname, "./extend.themes.webpack.js"), + path.resolve(__dirname, "./extend.base.webpack.js"), + path.resolve(__dirname, "./extend.samples.webpack.js") + ] : [ + path.resolve(__dirname, "./extend.themes.webpack.js"), + path.resolve(__dirname, "./extend.base.webpack.js") + ], + entry : entries, + externalsType : "var", + externals : externals + }; +}; \ No newline at end of file diff --git a/build/webpack/crs.webpack.config.js b/build/webpack/crs.webpack.config.js new file mode 100644 index 000000000..cade74b4f --- /dev/null +++ b/build/webpack/crs.webpack.config.js @@ -0,0 +1,23 @@ +var path = require("path"); + +var rootdir = path.join(__dirname, "../.."); + +module.exports = (env, argv) => { + // env transmis pour la config des samples + env["type"] = "modules"; + // argv + var isDevelopment = (argv.mode === "development"); + + return { + extends : isDevelopment ? [ + path.resolve(__dirname, "./extend.base.webpack.js"), + path.resolve(__dirname, "./extend.samples.webpack.js") + ] : [ + path.resolve(__dirname, "./extend.base.webpack.js") + ], + entry : { + "GpfExtOl-CRS" : path.join(rootdir, "src", "packages", "CRS", "AutoLoadCRS.js") + }, + externalsType : "var", + }; +}; \ No newline at end of file diff --git a/build/webpack/extend.banners.webpack.js b/build/webpack/extend.banners.webpack.js new file mode 100644 index 000000000..818f033a4 --- /dev/null +++ b/build/webpack/extend.banners.webpack.js @@ -0,0 +1,42 @@ +var fs = require("fs"); +var path = require("path"); +var webpack = require("webpack"); +var header = require("string-template"); + +var BannerWebPackPlugin = webpack.BannerPlugin; + +var rootdir = path.join(__dirname, "../.."); +var pkg = require(path.join(rootdir, "package.json")); + +module.exports = (env, argv) => { + return { + /** AJOUT DES LICENCES */ + plugins : [ + new BannerWebPackPlugin({ + banner : header(fs.readFileSync(path.join(rootdir, "build/licences", "licence-proj4js.tmpl"), "utf8"), { + __VERSION__ : pkg.dependencies["proj4"], + }), + raw : true + }), + new BannerWebPackPlugin({ + banner : header(fs.readFileSync(path.join(rootdir, "build/licences", "licence-eventbusjs.tmpl"), "utf8"), { + __VERSION__ : pkg.dependencies["eventbusjs"], + }), + raw : true + }), + new BannerWebPackPlugin({ + banner : header(fs.readFileSync(path.join(rootdir, "build/licences", "licence-sortablejs.tmpl"), "utf8"), { + __VERSION__ : pkg.dependencies["sortablejs"], + }), + raw : true + }), + new BannerWebPackPlugin({ + banner : header(fs.readFileSync(path.join(rootdir, "build/licences", "licence-olms.tmpl"),"utf8"), { + __VERSION__ : pkg.dependencies["ol-mapbox-style"], + }), + raw : true, + entryOnly : true + }), + ] + }; +}; \ No newline at end of file diff --git a/build/webpack/extend.base.webpack.js b/build/webpack/extend.base.webpack.js new file mode 100644 index 000000000..707a1c5c1 --- /dev/null +++ b/build/webpack/extend.base.webpack.js @@ -0,0 +1,148 @@ +/* eslint-disable indent */ +/* global module, __dirname */ + +// -- modules +var fs = require("fs"); +var path = require("path"); +var webpack = require("webpack"); +var header = require("string-template"); + +// -- plugins +var ESLintWebpackPlugin = require("eslint-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var BannerWebPackPlugin = webpack.BannerPlugin; +var EnvWebPackPlugin = webpack.EnvironmentPlugin; +var TerserJsWebPackPlugin = require("terser-webpack-plugin"); +var OptimizeCSSWebPackPlugin = require("css-minimizer-webpack-plugin"); + +// -- variables +var rootdir = path.join(__dirname, "../.."); +var pkg = require(path.join(rootdir, "package.json")); + +module.exports = (env, argv) => { + var isDevelopment = (argv.mode === "development"); + return { + output : { + path : path.join(rootdir, "dist", "modules"), + filename : "[name].js", + libraryExport : "default", + libraryTarget : "assign", + library : "[name]" + }, + resolve : {}, + externals : [ + function ({ context, request }, callback) { + if (/^ol\/.+$/.test(request)) { + // liste des modules ES6 à garder dans le code... + if ([ + "ol/events/EventType", + "ol/events/EventType.js", + "ol/events", + "ol/events.js", + "ol/render/Feature", + "ol/render/Feature.js", + ].includes(request)) { + return callback(); + } + const replacedWith = request.replace(/\.js$/g, "").replace(/\//g, "."); + return callback(null, replacedWith); + } + callback(); + }, + { + ol : { + commonjs : "ol", + commonjs2 : "ol", + amd : "ol", + root : "ol" + }, + request : { + commonjs2 : "request", + commonjs : "request", + amd : "require" + }, + xmldom : { + commonjs2 : "xmldom", + commonjs : "xmldom", + amd : "require" + } + } + ], + devtool : "source-map", + stats : "normal", + optimization : { + /** MINIFICATION */ + minimizer : [ + new TerserJsWebPackPlugin({ + extractComments : false, + terserOptions : { + output : { + comments : false, + }, + mangle : true + } + }), + new OptimizeCSSWebPackPlugin({}) + ] + }, + module : { + rules : [ + { + test : /\.js$/, + include : [ + path.join(rootdir, "src", "packages") + ], + exclude : /node_modules/, + use : [ + { + loader : "babel-loader", + options : { + presets : ["@babel/preset-env"] + } + } + ] + }, + { + test : /\.css$/, + include : [ + path.join(rootdir, "src", "packages", "CSS"), + /node_modules\/@gouvfr\/dsfr\/dist/, + ], + use : [ + MiniCssExtractPlugin.loader, + "css-loader" + ] + }, + { + test : /\.(png|jpg|gif|svg|woff|woff2)$/, + type : "asset/inline" + } + ], + noParse : [require.resolve("typescript/lib/typescript.js")] + }, + plugins : [ + /** EXECUTION DU LINTER */ + new ESLintWebpackPlugin({ + + }), + /** CSS avec IMAGES en base64 */ + new MiniCssExtractPlugin({ + filename : "[name].css" + }), + /** LOGGER */ + new EnvWebPackPlugin({ + VERBOSE : isDevelopment + }), + /** AJOUT DES LICENCES */ + new BannerWebPackPlugin({ + banner : header(fs.readFileSync(path.join(rootdir, "build/licences", "licence-ign.tmpl"), "utf8"), { + __BRIEF__ : pkg.name, + __VERSION__ : pkg.version, + __DATE__ : pkg.date + }), + raw : true, + entryOnly : true + }) + ] + }; +}; diff --git a/build/webpack/extend.samples.webpack.js b/build/webpack/extend.samples.webpack.js new file mode 100644 index 000000000..0f131f9be --- /dev/null +++ b/build/webpack/extend.samples.webpack.js @@ -0,0 +1,83 @@ +var path = require("path"); +var glob = require("glob"); + +var HandlebarsPlugin = require("../scripts/webpackPlugins/handlebars-plugin"); +var HandlebarsLayoutPlugin = require("handlebars-layouts"); +var CopyWebpackPlugin = require("copy-webpack-plugin"); + +var rootdir = path.join(__dirname, "../.."); +var pkg = require(path.join(rootdir, "package.json")); + +module.exports = (env, argv) => { + var type = env["type"]; // modules ou packages + return { + /** HANDLEBARS TEMPLATES */ + plugins : [ + /** TEMPLATES SAMPLES */ + new HandlebarsPlugin( + { + entry : { + path : path.join(rootdir, "samples-src", "pages", "tests"), + pattern : "**/*-" + type + "-*.html" + }, + output : { + path : path.join(rootdir, "samples", "tests"), + flatten : false, + filename : "[name].html" + }, + helpers : [ + HandlebarsLayoutPlugin + ], + partials : [ + path.join(rootdir, "samples-src", "templates", "packages", "*.hbs"), + path.join(rootdir, "samples-src", "templates", "partials", "*.hbs"), + path.join(rootdir, "samples-src", "templates", "partials", "packages", "*.hbs") + ], + context : [ + path.join(rootdir, "samples-src", "config.json"), + { + version : pkg.dependencies["ol"] === "latest" ? pkg.dependencies["ol"] : "v" + pkg.dependencies["ol"].match(/(\d+\.\d+\.\d+)/)[0] + } + ] + } + ), + /** TEMPLATES INDEX */ + new HandlebarsPlugin( + { + entry : path.join(rootdir, "samples-src", "pages", "index.html"), + output : { + path : path.join(rootdir, "samples"), + filename : "[name]-"+ type + ".html" + }, + context : { + samples : () => { + var root = path.join(rootdir, "samples-src", "pages", "tests"); + var list = glob.sync(path.join(root, "**", "*-" + type + "-*.html")); + list = list.map(function (filePath) { + var relativePath = path.relative(root, filePath); + var label = relativePath.replace("/", " -- "); + var pathObj = path.parse(relativePath); + return { + filePath : path.join("tests", pathObj.dir, pathObj.name.concat(pathObj.ext)), + label : label + }; + }); + return list; + } + } + } + ), + /* RESOURCES COPY FOR SAMPLES */ + new CopyWebpackPlugin({ + patterns : [ + { + from : path.join(rootdir, "samples-src", "resources"), + to : path.join(rootdir, "samples", "resources"), + context : path.join(rootdir, "samples-src", "resources"), + force : true + } + ] + }), + ] + }; +}; \ No newline at end of file diff --git a/build/webpack/extend.themes.webpack.js b/build/webpack/extend.themes.webpack.js new file mode 100644 index 000000000..5b6269b8d --- /dev/null +++ b/build/webpack/extend.themes.webpack.js @@ -0,0 +1,58 @@ +var path = require("path"); +var rootdir = path.join(__dirname, "../.."); + +module.exports = (env, argv) => { + return { + entry : { + // CSS themes portail + "Classic" : [ + path.join(rootdir, "src", "packages", "CSS", "GPFwaiting.css"), + path.join(rootdir, "src", "packages", "CSS", "GPFgeneralWidget.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Drawing", "GPFdrawingStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Attribution", "GPFattributionStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Editor", "GPFeditorStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/ElevationPath", "GPFelevationPathStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Export", "GPFexportStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/GetFeatureInfo", "GPFgetFeatureInfoStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Isochron", "GPFisochronStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/LayerImport", "GPFlayerImportStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/LayerSwitcher", "GPFlayerSwitcherStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/LocationSelector", "GPFlocationStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Measures", "GPFmeasureAreaStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Measures", "GPFmeasureLengthStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Measures", "GPFmeasureAzimuthStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Measures", "GPFmeasureToolTip.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/MousePosition", "GPFmousePositionStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/ReverseGeocoding", "GPFreverseGeocodingStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Route", "GPFrouteStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/SearchEngine", "GPFsearchEngineStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/ToolBoxMeasure", "GPFtoolBoxMeasureStyle.css") + ], + // CSS themes dsfr + "Dsfr" : [ + // INFO dépendances externes ! + // path.join(rootdir, "node_modules/@gouvfr/dsfr/dist/dsfr.css"), + // path.join(rootdir, "node_modules/@gouvfr/dsfr/dist/utility/icons/icons.css"), + path.join(rootdir, "src", "packages", "CSS", "DSFRgeneralWidget.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Drawing", "DSFRdrawingStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Attribution", "DSFRattributionStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Editor", "DSFReditorStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/ElevationPath", "DSFRelevationPathStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Export", "DSFRexportStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/GetFeatureInfo", "DSFRgetFeatureInfoStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Isochron", "DSFRisochronStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/LayerImport", "DSFRlayerImportStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/LayerSwitcher", "DSFRlayerSwitcherStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/LocationSelector", "DSFRlocationStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Measures", "DSFRmeasureAreaStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Measures", "DSFRmeasureLengthStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Measures", "DSFRmeasureAzimuthStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/MousePosition", "DSFRmousePositionStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/ReverseGeocoding", "DSFRreverseGeocodingStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/Route", "DSFRrouteStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/SearchEngine", "DSFRsearchEngineStyle.css"), + path.join(rootdir, "src", "packages", "CSS", "Controls/ToolBoxMeasure", "DSFRtoolBoxMeasureStyle.css") + ], + } + }; +}; \ No newline at end of file diff --git a/build/webpack/formats.webpack.config.js b/build/webpack/formats.webpack.config.js new file mode 100644 index 000000000..dbde91237 --- /dev/null +++ b/build/webpack/formats.webpack.config.js @@ -0,0 +1,27 @@ +var path = require("path"); + +var rootdir = path.join(__dirname, "../.."); + +module.exports = (env, argv) => { + // env pour les samples + env["type"] = "modules"; + // argv + var isDevelopment = (argv.mode === "development"); + + return { + extends : isDevelopment ? [ + path.resolve(__dirname, "./extend.base.webpack.js"), + path.resolve(__dirname, "./extend.samples.webpack.js") + ] : [ + path.resolve(__dirname, "./extend.base.webpack.js") + ], + entry : { + "GpfExtOl-Formats" : [ + path.join(rootdir, "src", "packages", "Formats", "GeoJSON.js"), + path.join(rootdir, "src", "packages", "Formats", "KML.js"), + path.join(rootdir, "src", "packages", "Formats", "GPX.js") + ] + }, + externalsType : "var", + }; +}; \ No newline at end of file diff --git a/build/webpack/layers.webpack.config.js b/build/webpack/layers.webpack.config.js new file mode 100644 index 000000000..d0e6d8ebd --- /dev/null +++ b/build/webpack/layers.webpack.config.js @@ -0,0 +1,30 @@ +var path = require("path"); + +var rootdir = path.join(__dirname, "../.."); + +module.exports = (env, argv) => { + // env transmis pour la config des samples + env["type"] = "modules"; + // argv + var isDevelopment = (argv.mode === "development"); + + return { + extends : isDevelopment ? [ + path.resolve(__dirname, "./extend.base.webpack.js"), + path.resolve(__dirname, "./extend.samples.webpack.js") + ] : [ + path.resolve(__dirname, "./extend.base.webpack.js") + ], + entry : { + "GpfExtOl-Layers" : [ + path.join(rootdir, "src", "packages", "Sources", "WMTS.js"), + path.join(rootdir, "src", "packages", "Layers", "LayerWMS.js"), + path.join(rootdir, "src", "packages", "Layers", "LayerWMTS.js"), + path.join(rootdir, "src", "packages", "Layers", "SourceWMS.js"), + path.join(rootdir, "src", "packages", "Layers", "SourceWMTS.js"), + path.join(rootdir, "src", "packages", "Layers", "LayerMapBox.js"), + ] + }, + externalsType : "var", + }; +}; \ No newline at end of file diff --git a/build/webpack/modules.webpack.config.js b/build/webpack/modules.webpack.config.js new file mode 100644 index 000000000..2132d70a4 --- /dev/null +++ b/build/webpack/modules.webpack.config.js @@ -0,0 +1,237 @@ +/* global module, __dirname */ + +// -- modules +var fs = require("fs"); +var path = require("path"); +var webpack = require("webpack"); +var header = require("string-template"); + +// -- plugins +var ESLintWebpackPlugin = require("eslint-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var BannerWebPackPlugin = webpack.BannerPlugin; +var EnvWebPackPlugin = webpack.EnvironmentPlugin; +var TerserJsWebPackPlugin = require("terser-webpack-plugin"); +var OptimizeCSSWebPackPlugin = require("css-minimizer-webpack-plugin"); + +// -- variables +var rootdir = path.join(__dirname, "../.."); +var pkg = require(path.join(rootdir, "package.json")); + +module.exports = (env, argv) => { + // env transmis pour la config des samples + env["type"] = "modules"; + + var isDevelopment = (argv.mode === "development"); + return { + extends : isDevelopment ? [ + path.resolve(__dirname, "./extend.themes.webpack.js"), + path.resolve(__dirname, "./extend.samples.webpack.js") + ] : [ + path.resolve(__dirname, "./extend.themes.webpack.js") + ], + entry : { + // Widgets + "GpfExtOlDrawing" : path.join(rootdir, "src", "packages", "Controls/Drawing", "Drawing.js"), + "GpfExtOlEditor" : path.join(rootdir, "src", "packages", "Controls/Editor", "Editor.js"), + "GpfExtOlElevationPath" : path.join(rootdir, "src", "packages", "Controls/ElevationPath", "ElevationPath.js"), + "GpfExtOlGetFeatureInfo" : path.join(rootdir, "src", "packages", "Controls/GetFeatureInfo", "GetFeatureInfo.js"), + "GpfExtOlIsocurve" : path.join(rootdir, "src", "packages", "Controls/Isocurve", "Isocurve.js"), + "GpfExtOlLayerImport" : path.join(rootdir, "src", "packages", "Controls/LayerImport", "LayerImport.js"), + "GpfExtOlLayerSwitcher" : path.join(rootdir, "src", "packages", "Controls/LayerSwitcher", "LayerSwitcher.js"), + "GpfExtOlLocationSelector" : path.join(rootdir, "src", "packages", "Controls/LocationSelector", "LocationSelector.js"), + "GpfExtOlGeoportalMousePosition" : path.join(rootdir, "src", "packages", "Controls/MousePosition", "MousePosition.js"), + "GpfExtOlGeoportalAttribution" : path.join(rootdir, "src", "packages", "Controls/Attribution", "GeoportalAttribution.js"), + "GpfExtOlReverseGeocode" : path.join(rootdir, "src", "packages", "Controls/ReverseGeocode", "ReverseGeocode.js"), + "GpfExtOlRoute" : path.join(rootdir, "src", "packages", "Controls/Route", "Route.js"), + "GpfExtOlSearchEngine" : path.join(rootdir, "src", "packages", "Controls/SearchEngine", "SearchEngine.js"), + "GpfExtOlExport" : path.join(rootdir, "src", "packages", "Controls/Export", "Export.js"), + "GpfExtOlMeasureArea" : path.join(rootdir, "src", "packages", "Controls", "Measures", "MeasureArea.js"), + "GpfExtOlMeasureAzimuth" : path.join(rootdir, "src", "packages", "Controls", "Measures", "MeasureAzimuth.js"), + "GpfExtOlMeasureLength" : path.join(rootdir, "src", "packages", "Controls", "Measures", "MeasureLength.js"), + // Formats étendus + "GpfExtOlFormats" : [ + path.join(rootdir, "src", "packages", "Formats", "GeoJSON.js"), + path.join(rootdir, "src", "packages", "Formats", "KML.js"), + path.join(rootdir, "src", "packages", "Formats", "GPX.js") + ], + // Couches + "GpfExtOlLayers" : [ + path.join(rootdir, "src", "packages", "Sources", "WMTS.js"), + path.join(rootdir, "src", "packages", "Layers", "LayerWMS.js"), + path.join(rootdir, "src", "packages", "Layers", "LayerWMTS.js"), + path.join(rootdir, "src", "packages", "Layers", "SourceWMS.js"), + path.join(rootdir, "src", "packages", "Layers", "SourceWMTS.js"), + path.join(rootdir, "src", "packages", "Layers", "LayerMapBox.js"), + ], + // Projections + "GpfExtOlCRS" : path.join(rootdir, "src", "packages", "CRS", "AutoLoadCRS.js"), + }, + output : { + path : path.join(rootdir, "dist", "modules"), + filename : "[name].js", + libraryExport : "default", + libraryTarget : "assign", + library : "[name]" + }, + resolve : {}, + externals : [ + function ({ context, request }, callback) { + if (/^ol\/.+$/.test(request)) { + // liste des modules ES6 à garder dans le code... + if ([ + "ol/events/EventType", + "ol/events/EventType.js", + "ol/events", + "ol/events.js", + "ol/render/Feature", + "ol/render/Feature.js" + ].includes(request)) { + return callback(); + } + const replacedWith = request.replace(/\.js$/g, "").replace(/\//g, "."); + return callback(null, replacedWith); + } + callback(); + }, + { + ol : { + commonjs : "ol", + commonjs2 : "ol", + amd : "ol", + root : "ol" + }, + request : { + commonjs2 : "request", + commonjs : "request", + amd : "require" + }, + xmldom : { + commonjs2 : "xmldom", + commonjs : "xmldom", + amd : "require" + } + } + ], + devtool : "source-map", + devServer : { + https : true, + watchFiles : { + paths : ["src/**/*"], + options : { + usePolling : true, + }, + }, + devMiddleware : { + index : true, + mimeTypes : { phtml : "text/html" }, + publicPath : "/dist/modules/", + serverSideRender : true, + writeToDisk : true, + }, + + }, + stats : "normal", + optimization : { + /** MINIFICATION */ + minimizer : [ + new TerserJsWebPackPlugin({ + extractComments : false, + terserOptions : { + output : { + comments : false, + }, + mangle : true + } + }), + new OptimizeCSSWebPackPlugin({}) + ] + }, + module : { + rules : [ + { + test : /\.js$/, + include : [ + path.join(rootdir, "src", "packages") + ], + exclude : /node_modules/, + use : [ + { + loader : "babel-loader", + options : { + presets : ["@babel/preset-env"] + } + } + ] + }, + // { + // test : require.resolve("proj4"), + // use : [{ + // loader : "expose-loader", + // options : { + // exposes : "proj4" + // } + // }] + // }, + // { + // test : require.resolve("eventbusjs"), + // use : [{ + // loader : "expose-loader", + // options : { + // exposes : "eventbus" + // } + // }] + // }, + // { + // test : require.resolve("ol-mapbox-style"), + // use : [{ + // loader : "expose-loader", + // options : { + // exposes : "olms" + // } + // }] + // }, + { + test : /\.css$/, + include : [ + path.join(rootdir, "src", "packages", "CSS"), + /node_modules\/@gouvfr\/dsfr\/dist/, + ], + use : [ + MiniCssExtractPlugin.loader, + "css-loader" + ] + }, + { + test : /\.(png|jpg|gif|svg|woff|woff2)$/, + type : "asset/inline" + } + ], + noParse : [require.resolve("typescript/lib/typescript.js")] + }, + plugins : [ + /** EXECUTION DU LINTER */ + new ESLintWebpackPlugin({ + + }), + /** CSS avec IMAGES en base64 */ + new MiniCssExtractPlugin({ + filename : "[name].css" + }), + /** LOGGER */ + new EnvWebPackPlugin({ + VERBOSE : isDevelopment + }), + /** AJOUT DES LICENCES */ + new BannerWebPackPlugin({ + banner : header(fs.readFileSync(path.join(rootdir, "build/licences", "licence-ign.tmpl"), "utf8"), { + __BRIEF__ : pkg.name, + __VERSION__ : pkg.version, + __DATE__ : pkg.date + }), + raw : true, + entryOnly : true + }) + ] + }; +}; diff --git a/build/webpack/webpack.config.modules.js b/build/webpack/webpack.config.modules.js deleted file mode 100644 index 30df1088d..000000000 --- a/build/webpack/webpack.config.modules.js +++ /dev/null @@ -1,448 +0,0 @@ -/* global module, __dirname */ - -// -- modules -var fs = require("fs"); -var path = require("path"); -var webpack = require("webpack"); -var header = require("string-template"); -var glob = require("glob"); - -// -- plugins -var ESLintWebpackPlugin = require('eslint-webpack-plugin'); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var BannerWebPackPlugin = webpack.BannerPlugin; -var EnvWebPackPlugin = webpack.EnvironmentPlugin; -var TerserJsWebPackPlugin = require("terser-webpack-plugin"); -var OptimizeCSSWebPackPlugin = require("css-minimizer-webpack-plugin"); -var JsDocWebPackPlugin = require("../scripts/webpackPlugins/jsdoc-plugin"); -var HandlebarsPlugin = require("../scripts/webpackPlugins/handlebars-plugin"); -var HandlebarsLayoutPlugin = require("handlebars-layouts"); -var CopyWebpackPlugin = require("copy-webpack-plugin"); - -// -- variables -var ROOT = path.join(__dirname, "../.."); -var pkg = require(path.join(ROOT, "package.json")); - -module.exports = (env, argv) => { - var debug = false; - // par defaut - var devMode = false; - var logMode = false; - var suffixOutput = ""; - if (argv.mode === "production") { - suffixOutput = ""; - logMode = false; - devMode = false; - } - if (argv.mode === "development") { - suffixOutput = "-map"; - logMode = true; - devMode = true; - } - if (argv.mode === "none") { - suffixOutput = "-src"; - logMode = true; - devMode = false; - } - // env - var jsdocEnv = true; - if (env.jsdoc === "no") { - jsdocEnv = false; - } - var linterEnv = true; - if (env.linter === "no") { - linterEnv = false; - } - var samplesEnv = true; - if (env.samples === "no") { - samplesEnv = false; - } - - return { - entry : { - // CSS themes portail - "Portail" : [ - path.join(ROOT, "src", "packages", "CSS", "GPFwaiting.css"), - path.join(ROOT, "src", "packages", "CSS", "GPFgeneralWidget.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Drawing", "GPFdrawingStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Attribution", "GPFattributionStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Editor", "GPFeditorStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/ElevationPath", "GPFelevationPathStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Export", "GPFexportStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/GetFeatureInfo", "GPFgetFeatureInfoStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Isochron", "GPFisochronStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/LayerImport", "GPFlayerImportStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/LayerSwitcher", "GPFlayerSwitcherStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/LocationSelector", "GPFlocationStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "GPFmeasureAreaStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "GPFmeasureLengthStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "GPFmeasureAzimuthStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "GPFmeasureToolTip.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/MousePosition", "GPFmousePositionStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/ReverseGeocoding", "GPFreverseGeocodingStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Route", "GPFrouteStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/SearchEngine", "GPFsearchEngineStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/ToolBoxMeasure", "GPFtoolBoxMeasureStyle.css") - ], - // CSS themes dsfr - "Dsfr" : [ - // INFO dépendances externes ! - // path.join(ROOT, "node_modules/@gouvfr/dsfr/dist/dsfr.css"), - // path.join(ROOT, "node_modules/@gouvfr/dsfr/dist/utility/icons/icons.css"), - path.join(ROOT, "src", "packages", "CSS", "DSFRgeneralWidget.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Drawing", "DSFRdrawingStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Attribution", "DSFRattributionStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Editor", "DSFReditorStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/ElevationPath", "DSFRelevationPathStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Export", "DSFRexportStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/GetFeatureInfo", "DSFRgetFeatureInfoStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Isochron", "DSFRisochronStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/LayerImport", "DSFRlayerImportStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/LayerSwitcher", "DSFRlayerSwitcherStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/LocationSelector", "DSFRlocationStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "DSFRmeasureAreaStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "DSFRmeasureLengthStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "DSFRmeasureAzimuthStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/MousePosition", "DSFRmousePositionStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/ReverseGeocoding", "DSFRreverseGeocodingStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Route", "DSFRrouteStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/SearchEngine", "DSFRsearchEngineStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/ToolBoxMeasure", "DSFRtoolBoxMeasureStyle.css") - ], - // Widgets - "Drawing" : path.join(ROOT, "src", "packages", "Controls/Drawing", "Drawing.js"), - "Editor" : path.join(ROOT, "src", "packages", "Controls/Editor", "Editor.js"), - "ElevationPath" : path.join(ROOT, "src", "packages", "Controls/ElevationPath", "ElevationPath.js"), - "GetFeatureInfo" : path.join(ROOT, "src", "packages", "Controls/GetFeatureInfo", "GetFeatureInfo.js"), - "Isocurve" : path.join(ROOT, "src", "packages", "Controls/Isocurve", "Isocurve.js"), - "LayerImport" : path.join(ROOT, "src", "packages", "Controls/LayerImport", "LayerImport.js"), - "LayerSwitcher" : path.join(ROOT, "src", "packages", "Controls/LayerSwitcher", "LayerSwitcher.js"), - "LocationSelector" : path.join(ROOT, "src", "packages", "Controls/LocationSelector", "LocationSelector.js"), - "GeoportalMousePosition" : path.join(ROOT, "src", "packages", "Controls/MousePosition", "MousePosition.js"), - "GeoportalAttribution" : path.join(ROOT, "src", "packages", "Controls/Attribution", "GeoportalAttribution.js"), - "ReverseGeocode" : path.join(ROOT, "src", "packages", "Controls/ReverseGeocode", "ReverseGeocode.js"), - "Route" : path.join(ROOT, "src", "packages", "Controls/Route", "Route.js"), - "SearchEngine" : path.join(ROOT, "src", "packages", "Controls/SearchEngine", "SearchEngine.js"), - "Export" : path.join(ROOT, "src", "packages", "Controls/Export", "Export.js"), - "MeasureArea" : path.join(ROOT, "src", "packages", "Controls", "Measures", "MeasureArea.js"), - "MeasureAzimuth" : path.join(ROOT, "src", "packages", "Controls", "Measures", "MeasureAzimuth.js"), - "MeasureLength" : path.join(ROOT, "src", "packages", "Controls", "Measures", "MeasureLength.js"), - // Formats étendus - "Formats" : [ - path.join(ROOT, "src", "packages", "Formats", "GeoJSON.js"), - path.join(ROOT, "src", "packages", "Formats", "KML.js"), - path.join(ROOT, "src", "packages", "Formats", "GPX.js") - ], - // Couches - "Layers" : [ - path.join(ROOT, "src", "packages", "Sources", "WMTS.js"), - path.join(ROOT, "src", "packages", "Layers", "LayerWMS.js"), - path.join(ROOT, "src", "packages", "Layers", "LayerWMTS.js"), - path.join(ROOT, "src", "packages", "Layers", "SourceWMS.js"), - path.join(ROOT, "src", "packages", "Layers", "SourceWMTS.js"), - path.join(ROOT, "src", "packages", "Layers", "LayerMapBox.js"), - ], - // Projections - "CRS" : path.join(ROOT, "src", "packages", "CRS", "AutoLoadCRS.js"), - }, - output : { - path : path.join(ROOT, "dist", "modules"), - filename : "[name]" + suffixOutput + ".js", - libraryExport : 'default', - libraryTarget : 'assign', - library : "[name]" // FIXME comment peupler la variable globale 'Gp' ? - }, - resolve : {}, - externals : [ - function({ context, request }, callback) { - if (/^ol\/.+$/.test(request)) { - // liste des modules ES6 à garder dans le code... - if ([ - "ol/events/EventType", - "ol/events/EventType.js", - "ol/events", - "ol/events.js", - "ol/render/Feature", - "ol/render/Feature.js", - // "ol/obj", - // "ol/css", - // "ol/dom", - // "ol/transform", - // "ol/asserts", - // "ol/AssertionError", - // "ol/util", - // "ol/render/canvas/LabelCache", - // "ol/structs/LRUCache", - // "ol/events/Event", - // "ol/events/Target", - // "ol/Disposable", - // "ol/functions", - // "ol/proj/transforms" - ].includes(request)) { - if (debug) { - console.log("#### MODULE ES6 ONLY : " + request + " (" + context + ")"); - } - return callback(); - } - if (debug) { - console.log("#### OL : " + request + " (" + context + ")"); - } - const replacedWith = request.replace(/\.js$/g, '').replace(/\//g, '.'); - if (debug) { - console.log(">>> : ", replacedWith); - } - return callback(null, replacedWith); - } - if (debug) { - console.log("#### OTHER : " + request + " (" + context + ")"); - } - callback(); - }, - /** - * FIXME - * configuration uniquement valable en mode umd !? - * mais à tester lors de l'import dans le SDK... - */ - { - ol : { - commonjs : "ol", - commonjs2 : "ol", - amd : "ol", - root : "ol" - }, - request : { - commonjs2 : "request", - commonjs : "request", - amd : "require" - }, - xmldom : { - commonjs2 : "xmldom", - commonjs : "xmldom", - amd : "require" - } - } - ], - devtool : (devMode) ? "eval-source-map" : false, - devServer : { - https: true, - watchFiles: { - paths: ['src/**/*'], - options: { - usePolling: true, - }, - }, - devMiddleware: { - index: true, - mimeTypes: { phtml: 'text/html' }, - publicPath: '/dist/packages/modules/', - serverSideRender: true, - writeToDisk: true, - }, - - }, - stats : (devMode) ? "errors-warnings" : "normal", - optimization : { - /** FIXME ça ne marche pas !? MINIFICATION */ - minimizer: [ - new TerserJsWebPackPlugin({ - extractComments: false, - terserOptions: { - output: { - // FIXME avec les banner ! - comments: false, - // drop_console: true - }, - mangle: true - } - }), - new OptimizeCSSWebPackPlugin({}) - ], - /** EXTRACT CSS INTO SINGLE FILE */ - // splitChunks : { - // cacheGroups : { - // styles : { - // name : "GpPluginOpenLayers", - // test : /\.css$/, - // chunks : "all", - // enforce : true - // } - // } - // } - }, - module : { - rules : [ - { - test : /\.js$/, - include : [ - path.join(ROOT, "src", "packages") - ], - exclude : /node_modules/, - use : [ - { - loader : "babel-loader", - options : { - presets : ["@babel/preset-env"] - } - }, - { - loader : 'string-replace-loader', - options : { - search: '__PRODUCTION__', - replace(match, p1, offset, string) { - console.log(`Replace "${match}" in file "${this.resource}".`) - return `${logMode}` - } - } - } - ] - }, - { - /** FIXME ça marche ? proj4 est exposé en global : proj4 ! */ - test : require.resolve("proj4"), - use : [{ - loader : "expose-loader", - options : { - exposes : "proj4" - } - }] - }, - { - /** FIXME ça marche ? eventbusjs est exposé en global : eventbus ! */ - test : require.resolve("eventbusjs"), - use : [{ - loader : "expose-loader", - options : { - exposes : "eventbus" - } - }] - }, - { - /** FIXME ça marche ? ol-mapbox-style est exposé en global : olms ! */ - test : /node_modules\/ol-mapbox-style\/dist\/olms\.js$/, - use : [{ - loader : "exports-loader", - options : "olms" - }] - }, - { - test : /\.css$/, - include : [ - path.join(ROOT, "src", "packages", "CSS"), - /node_modules\/@gouvfr\/dsfr\/dist/, - ], - use : [ - MiniCssExtractPlugin.loader, - "css-loader" - // https://github.com/webpack-contrib/sass-loader/ - // { - // loader: "sass-loader", - // options: { sassOptions: { outputStyle: "expanded" }} - // } - ] - }, - { - test : /\.(png|jpg|gif|svg|woff|woff2)$/, - type: 'asset/inline' - } - ], - noParse: [require.resolve("typescript/lib/typescript.js")] - }, - plugins : [ - /** EXECUTION DU LINTER */ - (linterEnv) ? new ESLintWebpackPlugin({}) : "", - /** GENERATION DE LA JSDOC */ - (jsdocEnv) ? new JsDocWebPackPlugin({ - conf : path.join(ROOT, "build/jsdoc/jsdoc.json") - }) : "", - /** CSS avec IMAGES en base64 */ - new MiniCssExtractPlugin({ - filename : "[name]" + suffixOutput + ".css" - }), - /** LOGGER */ - new EnvWebPackPlugin({ - VERBOSE : logMode - }) - ] - /** AJOUT DES LICENCES */ - .concat([ - new BannerWebPackPlugin({ - banner : header(fs.readFileSync(path.join(ROOT, "build/licences", "licence-ign.tmpl"), "utf8"), { - __BRIEF__ : pkg.name, - __VERSION__ : pkg.version, - __DATE__ : pkg.date - }), - raw : true, - entryOnly : true - }) - ]) - /** HANDLEBARS TEMPLATES */ - .concat((samplesEnv) ? [ - /** TEMPLATES SAMPLES */ - new HandlebarsPlugin( - { - entry : { - path : path.join(ROOT, "samples-src", "pages", "tests"), - pattern : "**/*-modules-*.html" - }, - output : { - path : path.join(ROOT, "samples", "tests"), - flatten : false, - filename : "[name]" + suffixOutput + ".html" - }, - helpers : [ - HandlebarsLayoutPlugin - ], - partials : [ - path.join(ROOT, "samples-src", "templates", "packages", "*.hbs"), - path.join(ROOT, "samples-src", "templates", "partials", "*.hbs"), - path.join(ROOT, "samples-src", "templates", "partials", "packages", "*.hbs") - ], - context : [ - path.join(ROOT, "samples-src", "config.json"), - { - mode : suffixOutput, - version : pkg.dependencies["ol"] === 'latest' ? pkg.dependencies["ol"] : 'v' + pkg.dependencies["ol"].match(/(\d+\.\d+\.\d+)/)[0] - } - ] - } - ), - /** TEMPLATES INDEX */ - new HandlebarsPlugin( - { - entry : path.join(ROOT, "samples-src", "pages", "index.html"), - output : { - path : path.join(ROOT, "samples"), - filename : "[name]" + "-modules" + suffixOutput + ".html" - }, - context : { - samples : () => { - var root = path.join(ROOT, "samples-src", "pages", "tests"); - var list = glob.sync(path.join(root, "**", "*-modules-*.html")); - list = list.map(function (filePath) { - var relativePath = path.relative(root, filePath); - var label = relativePath.replace("/", " -- "); - var pathObj = path.parse(relativePath); - return { - filePath : path.join("tests", pathObj.dir, pathObj.name.concat(suffixOutput).concat(pathObj.ext)), - label : label - }; - }); - return list; - } - } - } - ), - /* RESOURCES COPY FOR SAMPLES */ - new CopyWebpackPlugin({ - patterns: [ - { - from : path.join(ROOT, "samples-src", "resources"), - to : path.join(ROOT, "samples", "resources"), - context : path.join(ROOT, "samples-src", "resources"), - force: true - } - ] - }), - ] : []) - } -}; diff --git a/build/webpack/webpack.config.packages.js b/build/webpack/webpack.config.packages.js deleted file mode 100644 index 9f90b20f8..000000000 --- a/build/webpack/webpack.config.packages.js +++ /dev/null @@ -1,423 +0,0 @@ -/* global module, __dirname */ - -// -- modules -var fs = require("fs"); -var path = require("path"); -var webpack = require("webpack"); -var header = require("string-template"); -var glob = require("glob"); - -// -- plugins -var ESLintWebpackPlugin = require('eslint-webpack-plugin'); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var BannerWebPackPlugin = webpack.BannerPlugin; -var EnvWebPackPlugin = webpack.EnvironmentPlugin; -var TerserJsWebPackPlugin = require("terser-webpack-plugin"); -var OptimizeCSSWebPackPlugin = require("css-minimizer-webpack-plugin"); -var JsDocWebPackPlugin = require("../scripts/webpackPlugins/jsdoc-plugin"); -var HandlebarsPlugin = require("../scripts/webpackPlugins/handlebars-plugin"); -var HandlebarsLayoutPlugin = require("handlebars-layouts"); -var CopyWebpackPlugin = require("copy-webpack-plugin"); - -// -- variables -var ROOT = path.join(__dirname, "../.."); -var pkg = require(path.join(ROOT, "package.json")); - -module.exports = (env, argv) => { - var debug = false; - // par defaut - var devMode = false; - var logMode = false; - var suffixOutput = ""; - if (argv.mode === "production") { - suffixOutput = ""; - logMode = false; - devMode = false; - } - if (argv.mode === "development") { - suffixOutput = "-map"; - logMode = true; - devMode = true; - } - if (argv.mode === "none") { - suffixOutput = "-src"; - logMode = true; - devMode = false; - } - // env - var jsdocEnv = true; - if (env.jsdoc === "no") { - jsdocEnv = false; - } - var linterEnv = true; - if (env.linter === "no") { - linterEnv = false; - } - var samplesEnv = true; - if (env.samples === "no") { - samplesEnv = false; - } - - return { - entry : { - "Widgets" : path.join(ROOT, "src", "packages", "bundle.js"), - // CSS themes portail - "Portail" : [ - path.join(ROOT, "src", "packages", "CSS", "GPFwaiting.css"), - path.join(ROOT, "src", "packages", "CSS", "GPFgeneralWidget.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Drawing", "GPFdrawingStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Attribution", "GPFattributionStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Editor", "GPFeditorStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/ElevationPath", "GPFelevationPathStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Export", "GPFexportStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/GetFeatureInfo", "GPFgetFeatureInfoStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Isochron", "GPFisochronStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/LayerImport", "GPFlayerImportStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/LayerSwitcher", "GPFlayerSwitcherStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/LocationSelector", "GPFlocationStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "GPFmeasureAreaStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "GPFmeasureLengthStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "GPFmeasureAzimuthStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "GPFmeasureToolTip.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/MousePosition", "GPFmousePositionStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/ReverseGeocoding", "GPFreverseGeocodingStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Route", "GPFrouteStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/SearchEngine", "GPFsearchEngineStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/ToolBoxMeasure", "GPFtoolBoxMeasureStyle.css") - ], - // CSS themes dsfr - "Dsfr" : [ - // INFO dépendances externes ! - // path.join(ROOT, "node_modules/@gouvfr/dsfr/dist/dsfr.css"), - // path.join(ROOT, "node_modules/@gouvfr/dsfr/dist/utility/icons/icons.css"), - path.join(ROOT, "src", "packages", "CSS", "DSFRgeneralWidget.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Drawing", "DSFRdrawingStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Attribution", "DSFRattributionStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Editor", "DSFReditorStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/ElevationPath", "DSFRelevationPathStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Export", "DSFRexportStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/GetFeatureInfo", "DSFRgetFeatureInfoStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Isochron", "DSFRisochronStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/LayerImport", "DSFRlayerImportStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/LayerSwitcher", "DSFRlayerSwitcherStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/LocationSelector", "DSFRlocationStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "DSFRmeasureAreaStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "DSFRmeasureLengthStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Measures", "DSFRmeasureAzimuthStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/MousePosition", "DSFRmousePositionStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/ReverseGeocoding", "DSFRreverseGeocodingStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/Route", "DSFRrouteStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/SearchEngine", "DSFRsearchEngineStyle.css"), - path.join(ROOT, "src", "packages", "CSS", "Controls/ToolBoxMeasure", "DSFRtoolBoxMeasureStyle.css") - ], - }, - output : { - path : path.join(ROOT, "dist", "packages"), - filename : "[name]" + suffixOutput + ".js", - library : "Gp" - }, - resolve : {}, - externals : [ - function({ context, request }, callback) { - if (/^ol\/.+$/.test(request)) { - // liste des modules ES6 à garder dans le code... - if ([ - "ol/events/EventType", - "ol/events/EventType.js", - "ol/events", - "ol/events.js", - "ol/render/Feature", - "ol/render/Feature.js", - // "ol/obj", - // "ol/css", - // "ol/dom", - // "ol/transform", - // "ol/asserts", - // "ol/AssertionError", - // "ol/util", - // "ol/render/canvas/LabelCache", - // "ol/structs/LRUCache", - // "ol/events/Event", - // "ol/events/Target", - // "ol/Disposable", - // "ol/functions", - // "ol/proj/transforms" - ].includes(request)) { - if (debug) { - console.log("#### MODULE ES6 ONLY : " + request + " (" + context + ")"); - } - return callback(); - } - if (debug) { - console.log("#### OL : " + request + " (" + context + ")"); - } - const replacedWith = request.replace(/\.js$/g, '').replace(/\//g, '.'); - if (debug) { - console.log(">>> : ", replacedWith); - } - return callback(null, replacedWith); - } - if (debug) { - console.log("#### OTHER : " + request + " (" + context + ")"); - } - callback(); - }, - /** - * FIXME - * configuration uniquement valable en mode umd !? - * mais à tester lors de l'import dans le SDK... - */ - { - ol : { - commonjs : "ol", - commonjs2 : "ol", - amd : "ol", - root : "ol" - }, - request : { - commonjs2 : "request", - commonjs : "request", - amd : "require" - }, - xmldom : { - commonjs2 : "xmldom", - commonjs : "xmldom", - amd : "require" - } - } - ], - devtool : (devMode) ? "eval-source-map" : false, - stats : (devMode) ? "errors-warnings" : "normal", - optimization : { - /** FIXME ça ne marche pas !? MINIFICATION */ - minimizer: [ - new TerserJsWebPackPlugin({ - extractComments: false, - terserOptions: { - output: { - // FIXME avec les banner ! - comments: false, - // drop_console: true - }, - mangle: true - } - }), - new OptimizeCSSWebPackPlugin({}) - ], - /** EXTRACT CSS INTO SINGLE FILE */ - // splitChunks : { - // cacheGroups : { - // styles : { - // name : "GpPluginOpenLayers", - // test : /\.css$/, - // chunks : "all", - // enforce : true - // } - // } - // } - }, - module : { - rules : [ - { - test : /\.js$/, - include : [ - path.join(ROOT, "src", "packages") - ], - exclude : /node_modules/, - use : [ - { - loader : "babel-loader", - options : { - presets : ["@babel/preset-env"] - } - }, - { - loader : 'string-replace-loader', - options : { - search: '__PRODUCTION__', - replace(match, p1, offset, string) { - console.log(`Replace "${match}" in file "${this.resource}".`) - return `${logMode}` - } - } - } - ] - }, - { - /** FIXME ça marche ? proj4 est exposé en global : proj4 ! */ - test : require.resolve("proj4"), - use : [{ - loader : "expose-loader", - options : { - exposes : "proj4" - } - }] - }, - { - /** FIXME ça marche ? eventbusjs est exposé en global : eventbus ! */ - test : require.resolve("eventbusjs"), - use : [{ - loader : "expose-loader", - options : { - exposes : "eventbus" - } - }] - }, - { - /** FIXME ça marche ? ol-mapbox-style est exposé en global : olms ! */ - test : /node_modules\/ol-mapbox-style\/dist\/olms\.js$/, - use : [{ - loader : "exports-loader", - options : "olms" - }] - }, - { - test : /\.css$/, - include : [ - path.join(ROOT, "src", "packages", "CSS"), - /node_modules\/@gouvfr\/dsfr\/dist/, - ], - use : [ - MiniCssExtractPlugin.loader, - "css-loader" - // https://github.com/webpack-contrib/sass-loader/ - // { - // loader: "sass-loader", - // options: { sassOptions: { outputStyle: "expanded" }} - // } - ] - }, - { - test : /\.(png|jpg|gif|svg|woff|woff2)$/, - type: 'asset/inline' - } - ] - }, - plugins : [ - /** EXECUTION DU LINTER */ - (linterEnv) ? new ESLintWebpackPlugin({}) : "", - /** GENERATION DE LA JSDOC */ - (jsdocEnv) ? new JsDocWebPackPlugin({ - conf : path.join(ROOT, "build/jsdoc/jsdoc.json") - }) : "", - /** CSS avec IMAGES en base64 */ - new MiniCssExtractPlugin({ - filename : "[name]" + suffixOutput + ".css" - }), - /** LOGGER */ - new EnvWebPackPlugin({ - VERBOSE : logMode - }) - ] - /** AJOUT DES LICENCES */ - .concat([ - new BannerWebPackPlugin({ - banner : header(fs.readFileSync(path.join(ROOT, "build/licences", "licence-proj4js.tmpl"), "utf8"), { - __VERSION__ : pkg.dependencies["proj4"], - }), - raw : true - }), - new BannerWebPackPlugin({ - banner : fs.readFileSync(path.join(ROOT, "build/licences", "licence-es6promise.txt"), "utf8"), - raw : true - }), - new BannerWebPackPlugin({ - banner : header(fs.readFileSync(path.join(ROOT, "build/licences", "licence-eventbusjs.tmpl"), "utf8"), { - __VERSION__ : pkg.dependencies["eventbusjs"], - }), - raw : true - }), - new BannerWebPackPlugin({ - banner : header(fs.readFileSync(path.join(ROOT, "build/licences", "licence-sortablejs.tmpl"), "utf8"), { - __VERSION__ : pkg.dependencies["sortablejs"], - }), - raw : true - }), - new BannerWebPackPlugin({ - banner : header(fs.readFileSync(path.join(ROOT, "build/licences", "licence-olms.tmpl"),"utf8"), { - __VERSION__ : pkg.dependencies["ol-mapbox-style"], - }), - raw : true, - entryOnly : true - }), - new BannerWebPackPlugin({ - banner : header(fs.readFileSync(path.join(ROOT, "build/licences", "licence-ign.tmpl"), "utf8"), { - __BRIEF__ : pkg.name, - __VERSION__ : pkg.version, - __DATE__ : pkg.date - }), - raw : true, - entryOnly : true - }) - ]) - /** HANDLEBARS TEMPLATES */ - .concat((samplesEnv) ? [ - /** TEMPLATES SAMPLES */ - new HandlebarsPlugin( - { - entry : { - path : path.join(ROOT, "samples-src", "pages", "tests"), - pattern : "**/*-packages-*.html" - }, - output : { - path : path.join(ROOT, "samples", "tests"), - flatten : false, - filename : "[name]" + suffixOutput + ".html" - }, - helpers : [ - HandlebarsLayoutPlugin - ], - partials : [ - path.join(ROOT, "samples-src", "templates", "packages", "*.hbs"), - path.join(ROOT, "samples-src", "templates", "partials", "*.hbs"), - path.join(ROOT, "samples-src", "templates", "partials", "packages", "*.hbs") - ], - context : [ - path.join(ROOT, "samples-src", "config.json"), - { - mode : suffixOutput, - version : pkg.dependencies["ol"] === 'latest' ? pkg.dependencies["ol"] : 'v' + pkg.dependencies["ol"].match(/(\d+\.\d+\.\d+)/)[0] - } - ] - } - ), - /** TEMPLATES INDEX */ - new HandlebarsPlugin( - { - entry : path.join(ROOT, "samples-src", "pages", "index.html"), - output : { - path : path.join(ROOT, "samples"), - filename : "[name]" + "-packages" + suffixOutput + ".html" - }, - context : { - samples : () => { - var root = path.join(ROOT, "samples-src", "pages", "tests"); - var list = glob.sync(path.join(root, "**", "*-packages-*.html")); - list = list.map(function (filePath) { - var relativePath = path.relative(root, filePath); - var label = relativePath.replace("/", " -- "); - var pathObj = path.parse(relativePath); - return { - filePath : path.join("tests", pathObj.dir, pathObj.name.concat(suffixOutput).concat(pathObj.ext)), - label : label - }; - }); - return list; - } - } - } - ), - /* RESOURCES COPY FOR SAMPLES */ - new CopyWebpackPlugin({ - patterns: [ - { - from : path.join(ROOT, "samples-src", "resources"), - to : path.join(ROOT, "samples", "resources"), - context : path.join(ROOT, "samples-src", "resources"), - force: true - } - ] - }), - ] : []) - } -}; diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md deleted file mode 100644 index 2734f1d60..000000000 --- a/doc/CHANGELOG.md +++ /dev/null @@ -1,2035 +0,0 @@ -# CHANGELOG EXTENSION GEOPORTAL - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - - - -- [Extension Geoportail OpenLayers3, version 0.10.0](#extension-geoportail-openlayers3-version-0100) - * [Changelog](#changelog) -- [Extension Geoportail OpenLayers3, version 0.11.0](#extension-geoportail-openlayers3-version-0110) - * [Summary](#summary) - * [New Features :](#new-features-) - + [Additional widgets :](#additional-widgets-) - + [Others features](#others-features) - * [ChangeLog](#changelog) -- [Extension Geoportail OpenLayers3, version 0.12.0](#extension-geoportail-openlayers3-version-0120) - * [Summary](#summary-1) - * [New Features :](#new-features--1) - + [Additional widgets :](#additional-widgets--1) - + [Others features](#others-features-1) - + [Breaking changes](#breaking-changes) -- [Extension Geoportail OpenLayers, version 1.0.0](#extension-geoportail-openlayers-version-100) - * [Summary](#summary-2) - * [Changelog](#changelog-1) -- [Extension Geoportail OpenLayers, version 1.1.0](#extension-geoportail-openlayers-version-110) - * [Summary](#summary-3) - * [Changelog](#changelog-2) -- [Extension Geoportail OpenLayers, version 2.0.0](#extension-geoportail-openlayers-version-200) - * [Summary](#summary-4) -- [Extension Geoportail OpenLayers, version 2.1.0](#extension-geoportail-openlayers-version-210) - * [Summary](#summary-5) - * [Changelog](#changelog-3) -- [Extension Géoportail OpenLayers, version 2.1.2](#extension-geoportail-openlayers-version-212) - * [Summary](#summary-6) -- [Extension Geoportail OpenLayers, version 3.0.1](#extension-geoportail-openlayers-version-301) - * [Summary](#summary-7) - * [Changelog](#changelog-4) -- [Extension Geoportail OpenLayers, version 3.0.2](#extension-geoportail-openlayers-version-302) - * [Summary](#summary-8) - * [Changelog](#changelog-5) -- [Extension Geoportail OpenLayers, version 3.0.3](#extension-geoportail-openlayers-version-303) - * [Summary](#summary-9) - * [Changelog](#changelog-6) -- [Extension Geoportail OpenLayers, version 3.0.4](#extension-geoportail-openlayers-version-304) - * [Summary](#summary-10) - * [Changelog](#changelog-7) -- [Extension Geoportail OpenLayers, version 3.0.5](#extension-geoportail-openlayers-version-305) - * [Summary](#summary-11) - * [Changelog](#changelog-8) -- [Extension Geoportail OpenLayers, version 3.0.6](#extension-geoportail-openlayers-version-306) - * [Summary](#summary-12) - * [Changelog](#changelog-9) -- [Extension Geoportail OpenLayers, version 3.0.7](#extension-geoportail-openlayers-version-307) - * [Summary](#summary-13) - * [Changelog](#changelog-10) -- [Extension Geoportail OpenLayers, version 3.0.8](#extension-geoportail-openlayers-version-308) - * [Summary](#summary-14) - * [Changelog](#changelog-11) -- [Extension Geoportail OpenLayers, version 3.0.9](#extension-geoportail-openlayers-version-309) - * [Summary](#summary-15) - * [Changelog](#changelog-12) -- [Extension Geoportail OpenLayers, version 3.0.10](#extension-geoportail-openlayers-version-3010) - * [Summary](#summary-16) - * [Changelog](#changelog-13) -- [Extension Geoportail OpenLayers, version 3.0.11](#extension-geoportail-openlayers-version-3011) - * [Summary](#summary-17) - * [Changelog](#changelog-14) -- [Extension Geoportail OpenLayers, version 3.0.14](#extension-geoportail-openlayers-version-3014) - * [Summary](#summary-18) - * [Changelog](#changelog-15) -- [Extension Geoportail OpenLayers, version 3.0.16](#extension-geoportail-openlayers-version-3016) - * [Summary](#summary-19) - * [Changelog](#changelog-16) -- [Extension Geoportail OpenLayers, version 3.0.17](#extension-geoportail-openlayers-version-3017) - * [Summary](#summary-20) - * [Changelog](#changelog-17) -- [Extension Geoportail OpenLayers, version 3.0.18](#extension-geoportail-openlayers-version-3018) - * [Summary](#summary-21) - * [Changelog](#changelog-18) -- [Extension Geoportail OpenLayers, version 3.0.19](#extension-geoportail-openlayers-version-3019) - * [Summary](#summary-22) - * [Changelog](#changelog-19) -- [Extension Geoportail OpenLayers, version 3.1.0](#extension-geoportail-openlayers-version-310) - * [Summary](#summary-23) - * [Changelog](#changelog-20) -- [Extension Geoportail OpenLayers, version 3.2.0](#extension-geoportail-openlayers-version-320) - * [Summary](#summary-24) - * [Changelog](#changelog-21) -- [Extension Geoportail OpenLayers, version 3.2.1](#extension-geoportail-openlayers-version-321) - * [Summary](#summary-25) - * [Changelog](#changelog-22) -- [Extension Geoportail OpenLayers, version 3.2.2](#extension-geoportail-openlayers-version-322) - * [Summary](#summary-26) - * [Changelog](#changelog-23) -- [Extension Geoportail OpenLayers, version 3.2.3](#extension-geoportail-openlayers-version-323) - * [Summary](#summary-27) - * [Changelog](#changelog-24) -- [Extension Geoportail OpenLayers, version 3.2.4](#extension-geoportail-openlayers-version-324) - * [Summary](#summary-28) - * [Changelog](#changelog-25) -- [Extension Geoportail OpenLayers, version 3.2.5](#extension-geoportail-openlayers-version-325) - * [Summary](#summary-29) - * [Changelog](#changelog-26) -- [Extension Geoportail OpenLayers, version 3.2.6](#extension-geoportail-openlayers-version-326) - * [Summary](#summary-30) - * [Changelog](#changelog-27) -- [Extension Geoportail OpenLayers, version 3.2.7](#extension-geoportail-openlayers-version-327) - * [Summary](#summary-31) - * [Changelog](#changelog-28) -- [Extension Geoportail OpenLayers, version 3.2.8](#extension-geoportail-openlayers-version-328) - * [Summary](#summary-32) - * [Changelog](#changelog-29) -- [Extension Geoportail OpenLayers, version 3.2.9](#extension-geoportail-openlayers-version-329) - * [Summary](#summary-33) - * [Changelog](#changelog-30) -- [Extension Geoportail OpenLayers, version 3.2.10](#extension-geoportail-openlayers-version-3210) - * [Summary](#summary-34) - * [Changelog](#changelog-31) -- [Extension Geoportail OpenLayers, version 3.2.11](#extension-geoportail-openlayers-version-3211) - * [Summary](#summary-35) - * [Changelog](#changelog-32) -- [Extension Geoportail OpenLayers, version 3.2.12](#extension-geoportail-openlayers-version-3212) - * [Summary](#summary-36) - * [Changelog](#changelog-33) -- [Extension Geoportail OpenLayers, version 3.2.13](#extension-geoportail-openlayers-version-3213) - * [Summary](#summary-37) - * [Changelog](#changelog-34) -- [Extension Geoportail OpenLayers, version 3.2.14](#extension-geoportail-openlayers-version-3214) - * [Summary](#summary-38) - * [Changelog](#changelog-35) -- [Extension Geoportail OpenLayers, version 3.2.15](#extension-geoportail-openlayers-version-3215) - * [Summary](#summary-39) - * [Changelog](#changelog-36) -- [Extension Geoportail OpenLayers, version 3.2.16](#extension-geoportail-openlayers-version-3216) - * [Summary](#summary-40) - * [Changelog](#changelog-37) -- [Extension Geoportail OpenLayers, version 3.2.18](#extension-geoportail-openlayers-version-3218) - * [Summary](#summary-41) - * [Changelog](#changelog-38) -- [Extension Geoportail OpenLayers, version 3.2.19](#extension-geoportail-openlayers-version-3219) - * [Summary](#summary-42) - * [Changelog](#changelog-39) -- [Extension Geoportail OpenLayers, version 3.2.20](#extension-geoportail-openlayers-version-3220) - * [Summary](#summary-43) - * [Changelog](#changelog-40) -- [Extension Geoportail OpenLayers, version 3.2.21](#extension-geoportail-openlayers-version-3221) - * [Summary](#summary-44) - * [Changelog](#changelog-41) -- [Extension Geoportail OpenLayers, version 3.2.22](#extension-geoportail-openlayers-version-3222) - * [Summary](#summary-45) - * [Changelog](#changelog-42) -- [Extension Geoportail OpenLayers, version 3.3.0](#extension-geoportail-openlayers-version-330) - * [Summary](#summary-46) - * [Changelog](#changelog-43) - * [Avant :](#avant-) - * [Maintenant :](#maintenant-) -- [Extension Geoportail OpenLayers, version 3.3.1](#extension-geoportail-openlayers-version-331) - * [Summary](#summary-47) - * [Changelog](#changelog-44) -- [Extension Geoportail OpenLayers, version 3.3.2](#extension-geoportail-openlayers-version-332) - * [Summary](#summary-48) - * [Changelog](#changelog-45) -- [Extension Geoportail OpenLayers, version 3.3.3](#extension-geoportail-openlayers-version-333) - * [Summary](#summary-49) - * [Changelog](#changelog-46) -- [Extension Geoportail OpenLayers, version 3.3.4](#extension-geoportail-openlayers-version-334) - * [Summary](#summary-50) - * [Changelog](#changelog-47) -- [Extension Geoportail OpenLayers, version 3.4.0-beta](#extension-geoportail-openlayers-version-340-beta) - * [Summary](#summary-51) - * [Changelog](#changelog-48) -- [Extension Geoportail OpenLayers, version 3.4.0-beta2](#extension-geoportail-openlayers-version-340-beta2) - * [Summary](#summary-52) - * [Changelog](#changelog-49) -- [Extension Geoportail OpenLayers, version 3.4.0-beta3](#extension-geoportail-openlayers-version-340-beta3) - * [Summary](#summary-53) - * [Changelog](#changelog-50) -- [Extension Geoportail OpenLayers, version 3.4.0-beta4](#extension-geoportail-openlayers-version-340-beta4) - * [Summary](#summary-54) - * [Changelog](#changelog-51) - - - ---- - -# Extension Geoportail OpenLayers3, version 0.10.0 - -**08/06/2016 : 0.10.0** release of the Geoportal Extension for OL3 - -## Changelog - -**Provides** : -- ol.layer.GeoportalWMS layer class -- ol.layer.GeoportalWMS layer class -- ol.source.GeoportalWMS source class -- ol.source.GeoportalWMS source class -- ol.control.LayerSwitcher control class -- ol.control.GeoportalMousePosition control class -- ol.control.SearchEngine control class -- ol.control.ReverseSearch control class -- ol.control.Route control class -- ol.control.Isocurve control class -- ol.control.GeoportalAttribution control class -- ol.control.Drawing control class - -**Compatible with** : -- OpenLayers v3.14+ releases -- not yet tested with previous OpenLayers 3 releases (TODO) - ---- - -# Extension Geoportail OpenLayers3, version 0.11.0 - -**04/12/2016 : 0.11.0** release of the Geoportal Extension for OL3 - -## Summary - -## New Features : - -### Additional widgets : -- [ol.control.LayerImport](http://ignf.github.io/geoportal-extensions/ol3-latest/jsdoc/ol.control.LayerImport.html) -- [ol.control.MeasureArea](http://ignf.github.io/geoportal-extensions/ol3-latest/jsdoc/ol.control.MeasureArea.html) -- [ol.control.MeasureLength](http://ignf.github.io/geoportal-extensions/ol3-latest/jsdoc/ol.control.MeasureLength.html) -- [ol.control.MeasureAzimuth](http://ignf.github.io/geoportal-extensions/ol3-latest/jsdoc/ol.control.MeasureAzimuth.html) -- [ol.control.ElevationPath](http://ignf.github.io/geoportal-extensions/ol3-latest/jsdoc/ol.control.ElevationPath.html) - -### Others features -- [#78] : configurable zoom function on search engine results -- Mouse Position aware of CRS extents -- [#36] : adding IGNF register to proj4 CRS definitions -- [#65] : adding extra parameter to track extension use - -... and several bugfixes - -## ChangeLog -- proposer un outil de calcul de profil altimétrique [#64](https://github.com/IGNF/geoportal-extensions/issues/64) -- zoom moteur de recherche -[#78](https://github.com/IGNF/geoportal-extensions/issues/78) -- gestion des emprise des differents systemes de projection pour un affichage dynamique dans le widget mouse position des systems en fonction de l'emprise de la vue. -- fix [#76] : ol.control.layerimport - define default styles for KML and GPX imports [#79](https://github.com/IGNF/geoportal-extensions/pull/79) -- fix [#61] : ol.control.LayerImport - display WMS enclosed child layers [#62](https://github.com/IGNF/geoportal-extensions/pull/62) -- fix [#52] : ol.control.LayerImport : extent mal récupérée pour les couches en EPSG:4326 [#60](https://github.com/IGNF/geoportal-extensions/pull/60) -- proposer un outil de mesure de surface -[#57](https://github.com/IGNF/geoportal-extensions/issues/57) -- proposer un outil de mesure de distance -[#56](https://github.com/IGNF/geoportal-extensions/issues/56) -- proposer un outil de mesure d'azimuth -[#55](https://github.com/IGNF/geoportal-extensions/issues/55) -- fix [#50] : ol.control.GeoportalAttribution : affichage attributions de type text sous Safari -- fix [#53] : correction titre des outils d'edition -- fix [#51] : try ol.proj.get(crs.toUpperCase()) (e.g. if crs="epsg:3857") [#54](https://github.com/IGNF/geoportal-extensions/pull/54) -- Suppression de codes EPSG en doublons -[#38](https://github.com/IGNF/geoportal-extensions/pull/38) -- Feature register proj4 -[#37](https://github.com/IGNF/geoportal-extensions/pull/37) -- Rajout des définitions du registre IGNF et enrichissement des définitions EPSG dans les extensions [#36](https://github.com/IGNF/geoportal-extensions/issues/36) -- PB de Compatibilité IE10 (extension OL3 et Leaflet) [#30](https://github.com/IGNF/geoportal-extensions/issues/30) -- Fix ie10 compatibility -[#41](https://github.com/IGNF/geoportal-extensions/pull/41) -- Gérer l'import d'un KML créé via le portail -[#47](https://github.com/IGNF/geoportal-extensions/issues/47) -- Surcharge de ol.format.KML pour la gestion des styles sur les outils … -[#46](https://github.com/IGNF/geoportal-extensions/pull/46) -- Evolutions widgets itinéraires et isochrones (ol.control.Route et ol.control.Isocurve) -[#43](https://github.com/IGNF/geoportal-extensions/issues/43) -- ol : route & isocurve enhancements -[#44](https://github.com/IGNF/geoportal-extensions/pull/44) -- Compatibilité IE10 : calculs d'itinéraires et isochrones non fonctionnels [#40](https://github.com/IGNF/geoportal-extensions/issues/40) -- Compatibilité IE10 : css des widgets Route et Isochrone [#39](https://github.com/IGNF/geoportal-extensions/issues/39) -- ol.control.LayerSwitcher : addLayer with zIndex param [#29](https://github.com/IGNF/geoportal-extensions/issues/29) -- ol.control.GeoportalAttribution: ne pas créer d'éléments de liste (
  • ) vide [#35](https://github.com/IGNF/geoportal-extensions/issues/35) -- Feature ol3 layerimport [#28](https://github.com/IGNF/geoportal-extensions/pull/28) -- layerswitcher ol3 : gestion des changements de zindex [#26](https://github.com/IGNF/geoportal-extensions/pull/26) -- mise en place du controle d'import de couches (OL3) [#24](https://github.com/IGNF/geoportal-extensions/pull/24) -- ol.control.LayerImport : encodeURIComponent() lorsqu'on utilise un proxy [#34](https://github.com/IGNF/geoportal-extensions/issues/34) -- Support IE9 envisageable pour OL3 ? [#13](https://github.com/IGNF/geoportal-extensions/issues/13) -- fix [#29] : LayerSwitcher - addLayer with zIndex param [#33](https://github.com/IGNF/geoportal-extensions/pull/33) - -[Full Changelog](https://github.com/IGNF/geoportal-extensions/compare/ol3-0.10.0...ol3-0.11.0) - ---- - -# Extension Geoportail OpenLayers3, version 0.12.0 - -**27/07/2017 : 0.12.0** release of the Geoportal Extension for OL3 - -## Summary - -## New Features : - -### Additional widgets : -- [ol.control.GetFeatureInfo](http://ignf.github.io/geoportal-extensions/ol3-latest/jsdoc/ol.control.GetFeatureInfo.html) : permet d'accéder aux informations attributaires des objets des couches vecteur et d'interroger les couches raster (WMS et WMTS) via une requête GetFeatureInfo : [#104] - -### Others features -- [#74], [#90] : Modification des identifiants dans le DOM des widgets LayerSwitcher, MousePosition et des outils de mesure, de façon à permettre leur duplication dans une même page -- [#77], [#92] : Ajout du format GeoJSON dans le widget d'import de données (LayerImport) -- [#96] : Préfixage de la classe CSS tooltip du widget d'outils de mesures (GPmeasureToolTip.css) -- [#91], [#98], https://github.com/IGNF/geoportal-extensions/commit/34807394a57faa6572bf87197b2454bf090f8754 : Rationalisation de la gestion des styles dans les KML -- [#101] : Gestion des collisions des interactions entre les widgets -- [#106] : Mise en conformité des extensions avec OpenLayers v4 -- https://github.com/IGNF/geoportal-extensions/commit/5ce83b2be7db61259b0d56001fe1d071b138a7eb : Evolution des outils de mesure : possibilité d'annuler les derniers points saisis -- https://github.com/IGNF/geoportal-extensions/commit/d4af3c52e391b272abd71036d1fea0568dbec639 : Modification du paramétrage des styles des couches vecteurs importées dans le widget d'import -- [#114], [#115] : Mise en place du paramétrage de la méthode de calcul de l'azimuth -- https://github.com/IGNF/geoportal-extensions/commit/b51a85af5ee6e5970fb4c79027fc324ab0656c16 : l'export d'un croquis vide n'est plus autorisée dans le widget d'outils de dessin -- [#117], [#122] : Possibilité de rechercher des coordonnées en éditant les coordonnées du widget d'affichage des coordonnées de la souris (MousePosition) -- https://github.com/IGNF/geoportal-extensions/commit/7c312121c740c51f2ecf85d11747e3adc4a09c48 : utilisation du mode XHR par défaut pour les requêtes de calcul d'altimétrie du widget d'affichage des coordonnées de la souris (MousePosition) -- [#133] : Mise à jour de la bibliothèque d'accès (geoportal-access-lib) -- [#95], [#58], [#93], [#97], https://github.com/IGNF/geoportal-extensions/commit/cee8cde9b85131e4d3560c7b553b826358b18e12, [#107], [#108], [#102], [#110], [#124], [#131], [#134], [#135] : divers corrections de bugs - -[Changelog complet](https://github.com/IGNF/geoportal-extensions/compare/ol3-0.11.0...ol3-0.12.0) - -### Breaking changes - -Les changements suivants apportent des modifications des interfaces ou éléments du DOM, et peuvent impacter votre application : -- [#74] : Modification des identifiants dans le DOM des widgets LayerSwitcher, MousePosition et des outils de mesure : à prendre en compte par exemple si vous surchargez les CSS de ces widgets -- [#96] : Préfixage de la classe CSS tooltip du widget d'outils de mesures (GPmeasureToolTip.css) : idem -- d4af3c5 : Modification de la structure des options de paramétrage des styles des couches vecteurs importées dans le widget d'import : à prendre en compte si vous utilisiez ce paramétrage - -Merci à @pprev94 pour son importante contribution à [#117], à @sylvainpolletvillard pour ses contributions à [#97], à @iamvdo pour son aide pour [#108], et à @F3L1X79 pour ses remarques et son intérêt à notre projet ! - ---- - -# Extension Geoportail OpenLayers, version 1.0.0 - -**11/12/2017 : 1.1.0** Release Extension Geoportail OpenLayers - -## Summary - -- Publication dans les [dépots NPM](https://www.npmjs.com/package/geoportal-extensions-openlayers) -- version 1.1.0 de la bibliothèque d'accès -- compilation sous windows -- gestion templatisée des exemples avec handlebarjs -- gestion du mécanisme d'autopan pour les popups avec le controle getfeatureinfo - -- debugs divers ... - -Merci à @ojathelonius pour sa contribution sur [#172] - -## Changelog - -- Compilation sous Windows : régression \(path.join\) [\#167](https://github.com/IGNF/geoportal-extensions/issues/167) -- Leaflet et OL3 - SearchBar : décalages dans le positionnement avec l'autcompletion [\#151](https://github.com/IGNF/geoportal-extensions/issues/151) -- ol.control.GeoportalAttribution : suppression des attributions des couches non Géoportail [\#146](https://github.com/IGNF/geoportal-extensions/issues/146) -- ol.control.SearchEngine : postalcode autocompletion returns null coordinates \[0,0\] [\#107](https://github.com/IGNF/geoportal-extensions/issues/107) - -- Autopan à l'ouverture de pop-ups [\#170](https://github.com/IGNF/geoportal-extensions/issues/170) -- Dependance à geoportal-access-lib depuis NPM [\#128](https://github.com/IGNF/geoportal-extensions/issues/128) -- Compilation sous windows [\#119](https://github.com/IGNF/geoportal-extensions/issues/119) -- Upgrade Geoportal access lib to 1.1 [\#178](https://github.com/IGNF/geoportal-extensions/pull/178) ([gcebelieu](https://github.com/gcebelieu)) -- Add npm installation instructions to READMEs [\#177](https://github.com/IGNF/geoportal-extensions/pull/177) ([gcebelieu](https://github.com/gcebelieu)) -- Ajout du paramètre autoPanOptions pour permettre le recentrage automatique des pop-up [\#172](https://github.com/IGNF/geoportal-extensions/pull/172) ([ojathelonius](https://github.com/ojathelonius)) -- Recentrage de la pop-up lorsqu'elle apparaît en dehors du canvas [\#171](https://github.com/IGNF/geoportal-extensions/pull/171) ([ojathelonius](https://github.com/ojathelonius)) -- Automatisation des publications [\#166](https://github.com/IGNF/geoportal-extensions/pull/166) ([lowzonenose](https://github.com/lowzonenose)) -- Feature template samples [\#161](https://github.com/IGNF/geoportal-extensions/pull/161) ([lowzonenose](https://github.com/lowzonenose)) -- Feature dependency npm [\#160](https://github.com/IGNF/geoportal-extensions/pull/160) ([lowzonenose](https://github.com/lowzonenose)) -- Debug CSS rules based on dje remarks [\#155](https://github.com/IGNF/geoportal-extensions/pull/155) ([gcebelieu](https://github.com/gcebelieu)) -- fix \#146 : clean previous attributions only for Geoportal Layers [\#147](https://github.com/IGNF/geoportal-extensions/pull/147) ([lboulanger](https://github.com/lboulanger)) - -- drawing tools conflicts with openlayers popups [\#143](https://github.com/IGNF/geoportal-extensions/issues/143) -- Edition des coordonnées \(MousePosition\) : gestion du cas où displayCoordinates = false [\#140](https://github.com/IGNF/geoportal-extensions/issues/140) - -- MousePosition coordinates edition : bug fixes [\#141](https://github.com/IGNF/geoportal-extensions/pull/141) ([lboulanger](https://github.com/lboulanger)) - ---- - -# Extension Geoportail OpenLayers, version 1.1.0 - -**09/04/2018 : 1.1.0** Release Extension Geoportail OpenLayers - -## Summary - -- version 1.2.0 de la bibliothèque d'accès -- personnalisation et enrichissement des contrôles searchEngine, elevationPath et drawing -- debugs divers ... - -## Changelog - -- [contrôle searchEngine] Ajout d'options pour la personnalisation de l'extension (placeholder/marker) [\#180](https://github.com/IGNF/geoportal-extensions/pull/180) -- [outils de mesure] Nettoyage des tooltips [\#182](https://github.com/IGNF/geoportal-extensions/pull/182) -- [contrôle getFeatureInfo] bug fix : désabonnement aux événements lors de la suppression du contrôle -- [contrôle elevationPath] Mise en place de champs calculés pour un affichage personnalisé du profil altimétrique [\#188](https://github.com/IGNF/geoportal-extensions/pull/188) [\#158](https://github.com/IGNF/geoportal-extensions/issues/158) -- [contrôle searchEngine] Exécution d'un geocodage si aucun résultats sur l'autocompletion [\#185](https://github.com/IGNF/geoportal-extensions/pull/185) [\#163](https://github.com/IGNF/geoportal-extensions/issues/163) -- [contrôle drawing] Ajout d'une option pour obtenir des mesures sur les objets saisis [\#189](https://github.com/IGNF/geoportal-extensions/pull/189) [\#103](https://github.com/IGNF/geoportal-extensions/issues/103) -- [extension layers] Gestion du protocole http|https [\#195](https://github.com/IGNF/geoportal-extensions/pull/195) -- Mise à jour de l'entête UMD du bundle pour une compatibilité avec cjs, amd, es6 module [\#197](https://github.com/IGNF/geoportal-extensions/pull/197) - ---- - -# Extension Geoportail OpenLayers, version 2.0.0 - -**10/04/2018 : 2.0.0** Release Extension Geoportail OpenLayers - -**Edit du 16/04/2018** : Mise à jour de l'archive contenant les fichiers compilés (JS et CSS), avec le bon numéro de version + mise à jour des liens vers la JSDOC et les binaires (ci-dessous). - -## Summary - -Migration du projet sous [Webpack](http://webpack.github.io/) ainsi que les sources en [ES6 modules](http://exploringjs.com/es6/ch_modules.html). - -**BREAKING CHANGES** - -Le nom du bundle a été modifié : -> GpPluginOl3 vers GpPluginOpenLayers - -La documentation technique (JSDoc) de la version 2.0.0 de l'extension Géoportail pour OpenLayers se trouve désormais ici : -> * http://ignf.github.io/geoportal-extensions/openlayers-2.0.0/jsdoc/ -> ou -> * http://ignf.github.io/geoportal-extensions/openlayers-latest/jsdoc/ - -Les binaires de la version 2.0.0 se trouvent désormais ici : -> * versions minifiées (production) : -> * http://ignf.github.io/geoportal-extensions/openlayers-latest/dist/GpPluginOpenLayers.js -> * http://ignf.github.io/geoportal-extensions/openlayers-latest/dist/GpPluginOpenLayers.css -> * versions non minifiées (développement) : -> * http://ignf.github.io/geoportal-extensions/openlayers-latest/dist/GpPluginOpenLayers-src.js -> * http://ignf.github.io/geoportal-extensions/openlayers-latest/dist/GpPluginOpenLayers-src.css - ---- - -# Extension Geoportail OpenLayers, version 2.1.0 - -**09/08/2018 : 2.1.0** Release Extension Geoportail OpenLayers - -## Summary - -- [Version 2.1.0](https://github.com/IGNF/geoportal-access-lib/releases/tag/v2.1.0) de la bibliothèque d'accès -- Améliorations des configurations Webpack -- Correctifs et améliorations des widgets proposés - -## Changelog - -Correctifs et améliorations des widgets proposés : -* [#205] : Correctif du contrôle GetFeatureInfo : prise en compte des couches Tile Vector (cf. [#203]) -* [#208] Correctifs des outils de mesures (extension OpenLayers) dans le cas où 2 cartes sont affichées sur une même page -* [#210] Correctifs de l'outil MousePosition : coordonnées sexagésimales tronquées ([#202]), problème d'affichage ([#159]) -* [#215] Correctifs du LayerSwitcher : suppression des écouteurs d'événements associés à une couche lors de sa suppression -* [#216] Ajout de titre et description par défaut aux couches créées par les outils de croquis, de mesures, et de profil altimétrique -* [#218] Amélioration de l'outil d'import pour les couches WMS : affichage de l'arborescence des couches WMS lorsqu'elles sont organisées en catégories dans le GetCapabilities - -Structure du projet : -* [#207] Modifications syntaxiques (validation ESLint) -* [#211] Factorisation / optimisation des configurations webpack -* Mise en place de la couverture de code -* Ajout d'outils d'analyse (maintenance) : cartographie des sources et dépendances, et ajout du mode source du bundle -* Mise à jour de la version d'OpenLayers en dépendances npm (4.4.2) - -Documentation : -* Mise à jour de la documentation des fichiers README : version des releases, liens d'accès direct - ---- - -# Extension Géoportail OpenLayers, version 2.1.2 - -**18/02/2019 : 2.1.2** -> Release Extension Géoportail OpenLayers - -## Summary - -Version 2.1.2 de l'extension Géoportail pour OpenLayers : -- #229 Requêtes aux services en HTTPS par défaut, paramétrable avec paramètre "ssl" -- Utilisation de geoportal-access-lib en 2.1.2 - ---- - -# Extension Geoportail OpenLayers, version 3.0.1 - -**05/09/2019 : version 3.0.1** -> Release Extension Geoportail OpenLayers - -## Summary - -* Migration d'OpenLayers en version 5.3.0 -* Nouvelle fonctionnalité avec l'import de couche au format *vecteur tuilé* (MapBox) -* Correctifs suite au passage ES6 -* Migration Webpack en version > 4.0.0 - -[semver] : - - OpenLayers : increment semver MAJOR version (proj4/sortable/ol5/es6) - -**Remarques sur les projections** - -Les projections chargées par défaut dans les extensions *OpenLayers* sont les suivantes : - * ['EPSG:4326'], - * ['EPSG:3785'], ['EPSG:3785'], ['EPSG:900913'], ['EPSG:102113'], - * ["EPSG:2154"], - * ["EPSG:27571"], ["EPSG:27572"], ["EPSG:27573"], ["EPSG:2757"], - * ["CRS:84"], - * ["IGNF:LAMB93"], - * ["IGNF:LAMBE"], - * ["IGNF:LAMB1"], ["IGNF:LAMB2"], ["IGNF:LAMB3"], ["IGNF:LAMB4"], - * ["IGNF:RGF93G"], - * ["IGNF:WGS84G"] - -> Les projections sont disponibles dans les variables globales : *proj4()* et *ol.proj.get()* - -Il est possible d'étendre la liste via la fonction : -`Gp.olExtended.includeProjections()` - -> Les projections sont disponibles dans la variable globale : *proj4()* - -## Changelog - -* [Changed] - - - Mise à jour du package *geoportal-access-lib* en version 2.1.3 - - Mise à jour du package *proj4* en version 2.5.0 - - Mise à jour du package *sortable* en version 1.8.4 - - Mise à jour du package *backstopjs* en version 4.0.3 - - - Déplacement des CSS dans les sources - - - Mise à jour des licences - - - [dev-workflow] Mise en place du répertoire *build* - - [dev-workflow] Livraison des sources (via *npm*) - - [dev-workflow] Modification de la procédure de livraison - -* [Added] - - - Nouvelle fonctionnalité sur l'import de couche : le format *vecteur tuilé* (MapBox) - - Nouveau Widget : *Editeur* de styles pour le *vecteur tuilé* - - Description plus précise de la variable globale **Gp** dans la jsdoc - - Fenêtres des widgets *OpenLayers* en mode **draggable** - - Chargement de *projections* par défaut (cf. Summary) - - - [dev-workflow] Ajout du package *ol-mapbox-style* en version 4.2.1 - - [dev-workflow] Mise en place d'un *CHANGELOG* (historique des modifications) - - [dev-workflow] Mise en place de *HOWTO* à destination des developpeurs - -* [Deprecated] - - - [dev-workflow] Mise en place du protocole *HTTPS* par defaut sur les exemples - -* [Removed] - - - [dev-workflow] Suppression du mode de construction des bundles dit *"mixte"* - (La construction est portée par le projet *geoportal-sdk*) - -* [Fixed] - - - [#221](https://github.com/IGNF/geoportal-extensions/issues/221) - Résolution du problème - d’exécution du plugin *jsdoc* pour *webpack* sur l'environnement Windows - - [#237](https://github.com/IGNF/geoportal-extensions/pull/237) - Ajout du plugin - *jsdoc* pour *webpack* en local - - - [#222](https://github.com/IGNF/geoportal-extensions/pull/222) - Ajout du format *vecteur tuilé* (MapBox) sur l'import de couche du widget *OpenLayers* - - [#223](https://github.com/IGNF/geoportal-extensions/issues/223) - Conflit entre les widgets Route et Iso sur le widget *OpenLayers* - - [#217](https://github.com/IGNF/geoportal-extensions/issues/217) - Mise à jour d'OpenLayers > 5.3.0 - - [#234](https://github.com/IGNF/geoportal-extensions/issues/234) - Gestion des icônes sur les écrans *Retina* sur les widgets *Leaflet* - - [#232](https://github.com/IGNF/geoportal-extensions/issues/232) - **TODO** Problème de logger en configuration production suite au module *uglifyjs* de *Webpack* 3 - - - Test d'existence des projections sur le widget *MousePosition* - - -* [Security] - - - [dev-workflow] Mise à jour des dependances de dev (faille de sécurité) - ---- - -# Extension Geoportail OpenLayers, version 3.0.2 - -**09/09/2019 : version 3.0.2** -> Release Extension Geoportail OpenLayers - -## Summary - -* Compatibilité des extensions avec le Front End Angular. - -## Changelog - -* [Changed] - - - maj dependance *geoportal-access-lib* en version 2.1.4 - -* [Fixed] - - - [#242](https://github.com/IGNF/geoportal-extensions/issues/242) - Compatibilité - des extensions avec le Front End Angular. - ---- - -# Extension Geoportail OpenLayers, version 3.0.3 - -"**24/09/2019 : version 3.0.3** -> Release Extension Geoportail OpenLayers - -## Summary - -* Correctif sur le mode Draggable -* maj dependance - -## Changelog - -* [Added] - - - option 'draggable' (false par defaut) sur les extensions. - -* [Changed] - - - maj dependance *geoportal-access-lib* en version 2.1.5 - -* [Fixed] - - - [dev-workflow] correctifs sur les fichiers Webpack - ---- - -# Extension Geoportail OpenLayers, version 3.0.4 - -**16/10/2019** -> Release Extension Geoportail OpenLayers - -## Summary - -* mise à jour *geoportal-access-lib* en version 2.1.6 - -## Changelog - -* [Added] - - - [#246] nouvelle méthode publique sur le widget Isocurve qui permet de prépositionner un point sur la carte et de faire un traitement isochrone ou isodistance. - -* [Fixed] - - - correctifs sur l'editeur de styles (mapbox) - - [#230](https://github.com/IGNF/geoportal-extensions/issues/230) - largeur des popup d'information sur la recherche inversée. - - correction du calcul de surface de l'outil de dessin. - ---- - -# Extension Geoportail OpenLayers, version 3.0.5 - -**18/11/2019** -> Release Extension Geoportail OpenLayers - -## Summary - -* Divers correctifs sur les controles MousePosition et getFeatureInfo - -## Changelog - -* [Added] - - - enregistrement auto des projections dans le contrôle MousePosition - - surcharge de la fonction *ol.proj.proj4.register* afin de corriger les projections geocentriques (creation de la classe *CRS/Proj4.js*) : - > la release 2.6.0 semble corriger les projections (https://github.com/proj4js/proj4js/releases/tag/2.6.0) : fix a priori temporaire - -* [Changed] - - - Adaptation des exemples pour pointer sur la version courante d'openlayers - -* [Fixed] - - - correctifs sur l'editeur de styles (mapbox) - - correctifs sur le contrôle GetFeatureInfo - - correctifs CSS sur le contrôle MousePosition - ---- - -# Extension Geoportail OpenLayers, version 3.0.6 - -**17/12/2019** -> Release Extension Geoportail OpenLayers - -## Summary - -* Compatibilité IE sur l'API Fetch -* Mise à jour sécurité des dépendances -* Correctif sur le widget GetFeatureInfo - -## Changelog - -* [Added] - - - ajout du bundle ol en mode "deminifié" dans les exemples - -* [Fixed] - - - [#249] Gestion de la comptabilité IE 10/11 sur l'API Fetch (polyfill) - - Correctif sur le getFeatureInfo d'une couche WMS de type POI - -* [Security] - - - Mise à jour des dépendances de sécurités" - ---- - -# Extension Geoportail OpenLayers, version 3.0.7 - -**24/01/2020** -> Release Extension Geoportail OpenLayers - -## Summary - -* Correctif sur le widget de dessin - -## Changelog - -* [Fixed] - - - Correctif sur le widget Drawing - ---- - -# Extension Geoportail OpenLayers, version 3.0.8 - -**31/03/2020** -> Release Extension Geoportail OpenLayers - -## Summary - -* correctif sur les widgets -* correctif sur l'éditeur de styles (mapbox) -* fix sur les versions des dépendances (mapbox) - -## Changelog - -* [Added] - - - gestion des icônes dans l’éditeur MapBox ([\#261](https://github.com/IGNF/geoportal-extensions/pull/261)) - -* [Changed] - - - mise à jour du plugin de minification : "terser-webpack-plugin" ([\#261](https://github.com/IGNF/geoportal-extensions/pull/261)) - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - widget "mouseposition" : - - fix sur le retrait de la carte - - correctif sur l'inversion affichage lon/lat - - - fix sur la gestion des evenements du widget "drawing" - - - utilisation de la version "13.11.0" de la dépendance "@mapbox/mapbox-gl-style-spec" ([\#261](https://github.com/IGNF/geoportal-extensions/pull/261)) - -* [Security] - -**BREAKING CHANGES** - -> compilation du projet avec une version nodejs > 8.9.0 - ---- - -# Extension Geoportail OpenLayers, version 3.0.9 - -**01/04/2020** -> Release Extension Geoportail OpenLayers - -## Summary - -* hotfix sur la gestion des sprites des couches mapbox - -## Changelog - -* [Fixed] - - - meilleure gestion et fetch des sprites avec CORB - -**BREAKING CHANGES** - -> compilation du projet avec une version nodejs > 8.9.0 - ---- - -# Extension Geoportail OpenLayers, version 3.0.10 - -**02/04/2020** -> Release Extension Geoportail OpenLayers - -## Summary - -* Second hotfix sur la gestion des sprites des couches mapbox et versions des dépendances fixées - -## Changelog - -* [Changed] - - - versions des dépendances fixées dans le package.json - -* [Fixed] - - - correction de la gestion des sprites - ---- - -# Extension Geoportail OpenLayers, version 3.0.11 - -**29/06/2020** -> Release Extension Geoportail OpenLayers - -## Summary - -* evolution du widget de dessin sur la gestion des popups -* saisie de polygones avec trous dans l'outil de dessin -* mise à jour des dépendances (#263) - -## Changelog - -* [Added] - - - ajout de la commande : npm run eslint (#263) - - ajout d'un guide sur les bonnes pratiques de dev (0e396cce78ccbcb0691f9a4f2f73cd7a43d57b5f) - -* [Changed] - - - versions des dépendances fixées dans le package.json (#263) - - [DRAWING] faire des polygones à trous (#270) - - [DRAWING] choix d'afficher ou non les popups après chaque saisie (#269) - - [DRAWING] possibilité de surcharger le style des popups (#269) - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - fix des tests unitaires sur mouseposition (#264) - - fix getFeatureInfo (4aa57fea565d65cd5cb10927ab76179aa8a84ae5) - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.0.14 - -**12/02/2021** -> Release Extension Geoportail OpenLayers - -## Summary - -Nouveau widget de profil altimétrique et correctif sur le SearchEngine - -## Changelog - -* [Added] - -* [Changed] - - - nouvel affichage du profil altimétrique par défaut (DISPLAY_PROFILE_BY_DEFAULT) - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - fix sur la prise en compte du paramètre ssl=false pour les controles qui interrogent les services (a71811bb85785af93759a77de793be0c9d313fbf) - - fix sur l'interface des options données au controle SearchEngine (ee5130f376f83702328d55659ad73bd30f561a02) - - correctif sur l'export de la version en mode module - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.0.16 - -**11/05/2021** -> Release Extension Geoportail openLayers - -## Summary - -Correctifs sur le profil altimétriques - -## Changelog - -* [Added] - -* [Changed] - - Adaptation du style du profil alti par défaut - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - Correctif sur les clics multiple en fin de saisie du profil altimétrique (#298) - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.0.17 - -**16/06/2021** -> Release Extension Geoportail openlayers - -## Summary - -Correction sur le profil altimétrique - -## Changelog - -* [Added] - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - fix sur la saisie à main levée du profil altimetrique (#299) - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.0.18 - -**22/06/2021** -> Release Extension Geoportail openlayers - -## Summary - -Ajout de la gestion de projections geocentriques - -## Changelog - -* [Added] - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - Gestion des projections geocentriques (ex. EPSG:4978) (#303) - - Correction sur le DOM du profil-alti (#302) - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.0.19 - -**29/06/2021** -> Release Extension Geoportail openlayers - -## Summary - -De nouvelles corrections sur le profil alti - -## Changelog - -* [Added] - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - fix sur la vignette du profil altimétrique (#305) - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.1.0 - -**02/08/2021** -> Release Extension Geoportail openlayers - -## Summary - -Mise à jour de l'extension Géoportail pour OpenLayers 6.3.1 - -Upgrade des dependances : -- openLayers@6.3.1 -- ol-mapbox-style@6.3.2 - -## Changelog - -* [Added] - -* [Changed] - - - mise à jour de la dépendance openlayers en versio 6.3.1 (#280) - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.0 - -**03/11/2021** -> Release Extension Geoportail openlayers - -## Summary - -## Changelog - -* [Added] - -* [Changed] - - - utilisation de l'itinéraire V2 via geoportal-access-lib 3.0.1 (#312) - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.1 - -**08/11/2021** -> Release Extension Geoportail openlayers - -## Summary - -Mise à jour access-lib pour utilisation de l'itinéraire v2 - -## Changelog - -* [Added] - -* [Changed] - - - utilisation de l'itinéraire V2 via geoportal-access-lib 3.0.1 (#312) - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.2 - -**10/11/2021** -> Release Extension Geoportail openlayers - -## Summary - -Mise à jour de l'access-lib geoportail en version 3.0.2 - -## Changelog - -* [Added] - -* [Changed] - - - met à jour l'access-lib en version 3.0.2 pour correction géométrie itinéraire - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.3 - -**10/11/2021** -> Release Extension Geoportail openlayers - -## Summary - -Mise à jour de l'access-lib geoportail en version 3.0.3 - -## Changelog - -* [Added] - -* [Changed] - - - met à jour l'access-lib en version 3.0.3 pour correction géométrie itinéraire - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.4 - -**03/12/2021** -> Release Extension Geoportail openlayers - -## Summary - -Utilisation de plusieurs clefs - -## Changelog - -* [Added] - -* [Changed] - -- possibilité d'utiliser une liste de clés dans le tag data-key : - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.5 - -**13/01/2022** -> Release Extension Geoportail openlayers - -## Summary - -Changements mineurs sur les problématiques d'accessibilité - -## Changelog - -* [Added] - -* [Changed] - - - merge feature-accessibilite (#313) - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.6 - -**17/01/2022** -> Release Extension Geoportail openlayers - -## Summary - -* upgrade d'OpenLayers : 6.9.0 -* upgrade olms : 6.7.0 - -## Changelog - -* [Added] - - * MousePosition : Ajouter un callback au centrage de la carte sur des coordonnées [#315](https://github.com/IGNF/geoportal-extensions/issues/315) - - * Ajout du mecanisme de desactivation des interactions sur tous les widgets [developpez.com](https://www.developpez.net/forums/d2123362/applications/sig-systeme-d-information-geographique/ign-api-geoportail/utilisation-outils-mesures-gptoolbox-autres-widgets-conflit-fonctionnement/) - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - - * Fix sur l'affichage des pictogrammes du vecteur tuilé - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.7 - -**28/01/2022** -> Release Extension Geoportail openlayers - -## Summary - -Evolution de la documentation et correction du layerswitcher - -## Changelog - -* [Added] - -* [Changed] - - - Mise à jour de la documentation pour l'utilisation de clefs multiples (#318) - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - Correction du drag&drop sur le LayerSwitcher sous Chrome 97 (138aecced48a3f91503b6d3ec33e917d4cb16e04) - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.8 - -**11/02/2022** -> Release Extension Geoportail openlayers - -## Summary - -* fonctionnalités sur l'outil de dessins -* gestion des styles sur les formats GPX et GeoJSON -* gestion des evenements de fin de traitements sur les widgets - -## Changelog - -* [Added] - - - gestion des geometries de type *Multi* dans l'outil de dessins - - ajout de l'export au format GPX et GeoJSON dans l'outil de dessins - - gestion des styles au format GPX et GeoJSON (specification MapBox) - - ajoute d'evenements et de callback de fin de traitement pour les widgets ElevationPath, Route, IsoCurve, SearchEngine et ReverseGeocode. - ```js - // Exemple - var iso = new ol.control.Isocurve({ - isocurveOptions : { - // utilisation de la callback du service - onSuccess : function(e) { - console.warn("Resultat du calcul", e); - // { - // distance: null - // geometry: {type: 'Polygon', coordinates: Array(1)} - // id: null - // location: {x: '2.8926909677185058', y: '48.76818760957548'} - // message: null - // srs: "EPSG:4326" - // time: "3600" - // } - }, - onFailure : function(e) { - console.warn(e); - } - } - }); - // ou utilisation de l'evenement du widget - iso.on("isocurve:compute", function (e) { - // interface : getData() - console.warn(e.target.getData()); - }); - ``` - -* [Changed] - - - Retrait de la limitation d'affichage des reponses de l'autocompletion sur le Widget *SearchEngine* (cf. ) - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.9 - -**15/02/2022** -> Release Extension Geoportail openlayers - -## Summary - -* fonctionnalités sur l'outil de dessins -* gestion des styles sur les formats GPX et GeoJSON -* gestion des evenements de fin de traitements sur les widgets - -## Changelog - -* [Added] - - - gestion des geometries de type *Multi* dans l'outil de dessins - - ajout de l'export au format GPX et GeoJSON dans l'outil de dessins - - gestion des styles au format GPX et GeoJSON (specification MapBox) - - ajoute d'evenements et de callback de fin de traitement pour les widgets ElevationPath, Route, IsoCurve, SearchEngine et ReverseGeocode. - ```js - // Exemple - var iso = new ol.control.Isocurve({ - isocurveOptions : { - // utilisation de la callback du service - onSuccess : function(e) { - console.warn("Resultat du calcul", e); - // { - // distance: null - // geometry: {type: 'Polygon', coordinates: Array(1)} - // id: null - // location: {x: '2.8926909677185058', y: '48.76818760957548'} - // message: null - // srs: "EPSG:4326" - // time: "3600" - // } - }, - onFailure : function(e) { - console.warn(e); - } - } - }); - // ou utilisation de l'evenement du widget - iso.on("isocurve:compute", function (e) { - // interface : getData() - console.warn(e.target.getData()); - }); - ``` - -* [Changed] - - - Retrait de la limitation d'affichage des reponses de l'autocompletion sur le Widget *SearchEngine* (cf. ) - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.10 - -**23/03/2022** -> Release Extension Geoportail openlayers - -## Summary - -## Changelog - -* [Added] - -* [Changed] - - - DOM widget d'import : "Tuiles vectorielles" au lieu de "Vecteur tuilé" - - utilisation du service isochrone v2, access-lib 3.1.0 (#326) - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.11 - -**31/03/2022** -> Release Extension Geoportail openlayers - -## Summary - -## Changelog - -* [Added] - - - Ajout du menu des couleurs et de la taille des pictogramme dans l'outil de dessin - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - Amélioration du rendu vecteur des formats GPX et GeoJSON - - Gestion du nom d'une couche importée dans le gestionnaire et dans l'outil de dessin - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.12 - -**29/04/2022** -> Release Extension Geoportail openlayers - -## Summary - -## Changelog - -* [Added] - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - Permettre la saisie sous la tooltip sur les outils de mesures - - Correctif du style des elements en cours d'édition lors de l'export / enregistrement des croquis sur l'outil de dessin - - Desactivation des interactions à la fermeture de l'outil de dessin [#323](https://github.com/IGNF/geoportal-extensions/issues/323) - - Nettoyage des tooltips des outils de mesures - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.13 - -**11/05/2022** -> Release Extension Geoportail openlayers - -## Summary - -Fix sur l'outil de dessin - -## Changelog - -* [Added] - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - Exception sur l'export des features en cours d'édition sur l'outil de dessin - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.14 - -**01/08/2022** -> Release Extension Geoportail openlayers - -## Summary - -Correctifs sur l'editeur de styles MapBox et le controle d'import des données MapBox - -## Changelog - -* [Added] - - - Ajout d'options de tri dans l'editeur de style MapBox (9dcf64acebacf812b2a2642a47db4b719f3b1e30) - -* [Changed] - - - Passage en mode Feature (vs FeatureRender) pour l'import du vecteur tuilé (0a863d90d2d19fe41911b3fddb66c3f104216e90) - - mise à jour du Readme (b7bb7fc5b216c04e4bee7bb4ef2f9510dbe23d33) - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - Fix sur la gestion des imports de type MapBox (#328) - - Fix sur les legendes MapBox (#328) - - Fix sur le rendu sous FireFox des legendes MapBox (a9eada8fcfc020a603909ee6d0da8d4af2aa4248) - - Fix sur le tri alpha des couches MapBox (a9eada8fcfc020a603909ee6d0da8d4af2aa4248) - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.15 - -**27/09/2022** -> Release Extension Geoportail openlayers - -## Summary - -Correction sur la gestion des projections pour les imports WMS - -## Changelog - -* [Added] - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - Pour une couche WMS issue d'un import, on prend en priorité la projection de la carte si elle est gérée par le serveur WMS (#338) - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.16 - -**04/10/2022** -> Release Extension Geoportail openlayers - -## Summary - -Utilisation du Geocodage v2 - -## Changelog - -* [Added] - -* [Changed] - - - mise à jour pour utilisation du service de Geocodage v2 (#279) - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.18 - -**18/11/2022** -> Release Extension Geoportail openlayers - -## Summary - -## Changelog - -* [Added] - - - Ajout des "@types declaration" pour publication - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - Ajout des evenements (map) : "render:success" / "render:failure" pour l'application du rendu des styles MapBox - - Ajout de l'evenement (map) : "editor:loaded" pour le chargement de l'editeur de style - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.19 - -**17/01/2023** -> Release Extension Geoportail openlayers - -## Summary - -Mise à jour de l'access-lib en version 3.2.1 - -## Changelog - -* [Added] - -* [Changed] - - - mise à jour access-lib en version 3.2.1 (15f864e905c4549e43b7ec53d4369bbc9683ec2e) - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.20 - -**21/02/2023** -> Release Extension Geoportail openlayers - -## Summary - -Ajout d'écouteurs sur les controles de Géocodage direct en inverse - -## Changelog - -* [Added] - - - Ajout d'evenements sur le contrôle SearchEngine lors de la selection d'un résultat (#348) - - Ajout d'evenements sur le contrôle ReverseGeocode lors de la selection d'un résultat (#356) - - Ajout de méthodes publiques sur les contrôles Iso et Route (#343) : - - getGeoJSON() : fournit le tracé au format GeoJSON - - getData() : fournit la configuration du calcul - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - Faute d'ortographe description couche Isocurve - - Ajout des modules dans la JSDoc (#349) - - Mise à jour des clefs des services (#352) - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.21 - -**23/03/2023** -> Release Extension Geoportail openlayers - -## Summary - -Amélioration du traitement pour les couches vecteur tuilé (documentation, légendes, ajout simplifié) - -## Changelog - -* [Added] - - - Ajout simplifié d'une couche vecteur tuilé IGN : - ```js - var LayerMapBox = new ol.layer.GeoportalMapBox({ - layer : "PLAN.IGN", - style : "gris" - }); - ``` - -* [Changed] - - - GFI : ignore la propriété "icon" lors de la construction de la pop-up (05bbfa0ab8ccd09b32954aabad421b00f6faec35) - - Vecteur tuilé : évolution sur la construction et l'affichage des légendes (#362) - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.2.22 - -**01/06/2023** -> Release Extension Geoportail openlayers - -## Summary - -- Ajout du widget *Export* -- Import des couches de calculs (itineraire, isochrone et profil altimétrique) - -## Changelog - -* [Added] - - - Widget d'export des tracés et des calculs au format GPX, KML et GeoJSON sur les contôles d'itineraire, d'isochrone et de profil altimétrique (#363) : - - ``` js - // exemple - var route = new ol.control.Route(); - map.addControl(route); - var exportRoute = new ol.control.Export({ - control : route, - format : "GPX" - }); - map.addControl(exportRoute); - ``` - - - Import des couches de calculs (itineraire, isochrone et profil altimétrique) au format GPX, KML et GeoJSON (#363). - - Widget d'export des tracés et calculs des contrôles d'itineraire, d'isochrone et de profil altimétrique (#357). - -* [Changed] - - - Mise à jour doc elevationPathControl (#365) - - transmission paramètre outputFormat=json par défaut pour mousePosition et elevationPath OpenLayers (#365) - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - Fix sur le format KML avec l'affichage des labels - - Fix sur le profil altimétrique qui permet de construire le profil même si le panneau d'affichage est masqué (calcul en arrière plan). - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.3.0 - -**07/06/2023** -> Release Extension Geoportail openlayers - -## Summary - -Retrait total de l'utilisation du service d'autoconfiguration et utilisation de fichiers de configuration json générés quotidiennement à partir des getCapabilities des services du Geoportail. - -L'ensemble des services de calcul appelés via la bibliothèque d'accès sont désormais appelés avec la clé "calcul" par défaut dans la bibliothèque d'accès. Le paramètre "apiKey" n'est donc plus nécessaire pour appeler les services de géocodage, d'itinéraire, d'isochrone, d'altimétrie et d'autocomplétion, que ce soit directement depuis la bibli -othèque d'accès ou via les widgets des extensions Géoportail. - -L'autoconfiguration n'est plus appelée par les API. Pour la remplacer, nous générons quotidiennement, à partir des getCapabilities des services WMS et WMTS, des fichiers de configuration en JSON appelables par les API JavaScript Géoportail. Il y a un fichier par clé générique. L'avantage de ce nouveau processus (en plus de s'adapter au futur arrêt du service d'autoconfiguration) est que les fichiers de configuration JSON sont directement au format attendu par les API : il n'y a plus besoin de les parser pour en extraire les informations utiles puis pour les introduire dans une structure adéquate. -Par exemple, en renseignant "cartes" au paramètre apiKey, c'est le fichier cartesConfig.json qui sera chargé et directement utilisé par les API. - -A noter que le multiKeys est toujours géré, c'est à dire qu'il est possible de renseigner plusieurs clés dans le paramètre apiKey. - -Il est également possible de générer son propre fichier de configuration à partir d'une ou plusieurs clés. L'utilitaire est temporairement disponible ici : https://geoportal-configuration.onrender.com. Le paramètre permettant ensuite de charger sa configuration personnelle à partir du fichier local généré s'appelle désormais **customConfigFile**, auquel on associera le chemin vers le fichier de configuration json à charger. - -## Changelog - -* [Added] - -* [Changed] - - - mise à jour de la bibliothèque d'accès aux services Geoportail en version 3.3.0 (#364) - - **BC** : paramètre "customConfigFile" pour appeler un fichier de configuration local (#364) - -##### Avant : - -```html - -``` - -OU - -```javascript -Gp.Services.getConfig({ - serverUrl : "chemin/vers/mon/autoconf/AutoConf.js", - timeOut : 20000, - onSuccess : createMap -}); -``` - -##### Maintenant : - -```html - -``` - -OU - -```javascript -Gp.Services.getConfig({ - customConfigFile: "chemin/vers/ma/config/customConfig.json", - timeOut: 20000, - onSuccess: createMap -}); - -* [Deprecated] - -* [Removed] - - - **BC** : les originators ne sont plus renvoyés dans la configuration. Il faut les ajouter manuellement aux couches. - -```javascript - var gpOrtho = new ol.layer.Tile({ - source: new ol.source.GeoportalWMTS({ - layer: "ORTHOIMAGERY.ORTHOPHOTOS", - olParams: { - attributions: [{ - name: "Nom raccourci originator", - constraints: [{ - minScaleDenominator: 20000, - maxScaleDenominator: 1000000, - bbox: { - left: -10, - top: 50, - right: 10, - bottom: 40 - } - }, - { - bbox: { - left: 120, - top: 50, - right: 150, - bottom: 35 - } - } - ] - }, - { - url: "http://www.url-vers-le-site-du-producteur.fr", - constraints: [{ - minScaleDenominator: 20000, - maxScaleDenominator: 400000 - }] - }, - { - logo: "https://lien-vers-le-logo.png" - }, - { - attribution: "Titre complet originator", - constraints: [{ - minScaleDenominator: 100000, - maxScaleDenominator: 800000 - }] - }] - } - }) - }); -``` - - - **BC** : Les metadatas sont utilisées dans les API par le contrôle gestionnaire de couches (LayerSwitcher). Celui-ci va lire les metadatas des couches ajoutées à la carte et les afficher dans l'encart d'information dédié du LayerSwitcher. **Pour les couches WMTS uniquement**, désormais, pour que les metadatas apparaissent dans l'onglet "informations" du LayerSwitcher, il faudra les renseigner manuellement à la configuration de la couche Géoportail lors de son ajout à la carte. - - -```javascript -new ol.layer.Tile({ - source: new ol.source.GeoportalWMTS({ - layer: "ORTHOIMAGERY.ORTHOPHOTOS", - metadata: [ - { - format: "xml", - url: "lien/Vers/Une/MetaDonnee.xml" - } - ], - }) -}) -``` - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.3.1 - -**07/06/2023** -> Release Extension Geoportail openlayers - -## Summary - -## Changelog - -* [Added] - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.3.2 - -**21/07/2023** -> Release Extension Geoportail openlayers - -## Summary - -Ajout d'exemples avec l'appel de *Gp.Services.getConfig()* et ajout de methodes de nettoyage sur les widgets de calcul - -## Changelog - -* [Added] - - - ajout de méthodes de nettoyage pour les controles d'itineraire, d'isochrone, et de profil alti - -* [Changed] - - - Ajout d'exemples avec l'appel de *Gp.Services.getConfig()* - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.3.3 - -**04/08/2023** -> Release Extension Geoportail openlayers - -## Summary - -Correctifs sur le layerSwitcher et le profil Altimétrique. Mise à jour de la bibliothèque d'accès aux services Géoportail. - -## Changelog - -* [Added] - -* [Changed] - - - access-lib 3.3.3 (#369) - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - ajout couche ol au LS avec userId (#369) - - fix méthode clean profil alti (8f393fa96491444d99fdd6fe0c3b354ea3dd21ef) - - fix gestion multiples profils alti (f71ffd85ddff26a82534d81a88033464ed6a8b17 -) -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.3.4 - -**28/08/2023** -> Release Extension Geoportail openlayers - -## Summary - -Correctif mineur sur le chargement et l'affichage des styles de flux de tuiles vectorielles - -## Changelog - -* [Added] - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - Copie des styles vecteur tuilés dans l'outil d'import (3efee51392414c2858df86bb765bd4a81c8fb2f3) - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.4.0-beta - -**21/09/2023** -> Release Extension Geoportail openlayers - -## Summary - -Mise à jour de la bibliothèque d'accès aux services Géoportail. - -## Changelog - -* [Added] - -* [Changed] - - - access-lib 3.3.4 - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.4.0-beta2 - -**27/10/2023** -> Release Extension Geoportail openlayers - -## Summary - -Utilisation du service de Geocodage de la Geoplateforme - -## Changelog - -* [Added] - -* [Changed] - - - les widgets utilisent désormais par défaut les services d'autocomplétion et de geocodage direct et inverse de la Geoplateforme - - le paramétrage d'un proxy pour utiliser le control d'import de couches est rendu facultatif - - utilisation de la version 3.4.0-beta2 de la bibliothèque d'accès - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.4.0-beta3 - -**21/11/2023** -> Release Extension Geoportail openlayers - -## Summary - -Ajout possible de couches à accès restreint via une fichier de configuration custom - -## Changelog - -* [Added] - -* [Changed] - - - possibilité d'ajout automatique de couches IGN à accès restreint - -* [Deprecated] - -* [Removed] - -* [Fixed] - -* [Security] - ---- -# Extension Geoportail OpenLayers, version 3.4.0-beta4 - -**14/12/2023** -> Release Extension Geoportail openlayers - -## Summary - -## Changelog - -* [Added] - -* [Changed] - -* [Deprecated] - -* [Removed] - -* [Fixed] - - - fix : incompatibilité css lorsque la map est dans une div ayant pour classe "container" (958b687ec91c712fd958d7e54437776958c37610) - -* [Security] - ---- diff --git a/doc/README.md b/doc/README.md index cc119dc43..8af66c0eb 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,6 +1,8 @@ +**version provisoire** + # Extension Géoplateforme pour OpenLayers -![GitHub package.json version](https://img.shields.io/github/package-json/v/IGNF/geoportal-extensions?filename=build%2Fscripts%2Frelease%2Fpackage-openlayers.json) +![GitHub package.json version](https://img.shields.io/github/package-json/v/IGNF/geoportal-extensions-openlayers?filename=package.json) @@ -122,27 +124,97 @@ L'utilisation de l'extension Géoplateforme pour OpenLayers se fait via les éta * [Configuration de l'accès à la Géoplateforme](#config) -Une documentation technique (**jsdoc**), une **demo** et un **generateur de carte** sont disponibles [ici](https://ignf.github.io/geoportal-extensions/). +Une documentation technique (**jsdoc**), une **demo** et un **generateur de carte** sont disponibles [ici](https://ignf.github.io/geoportal-extensions-openlayers/). ### Téléchargement -Vous pouvez récupérer l'extension Géoplateforme pour OpenLayers soit par [téléchargement direct](#download-direct), soit en utilisant le [gestionnaire de dépendances javascript NPM](#download-npm). - -L'extension Géoplateforme pour OpenLayers comprend l'arborescence de fichiers suivante : - -``` - / - GpPluginOpenLayers.js - (version minifiée du code javascript pour une utilisation en production) - GpPluginOpenLayers.css - (version minifiée des css pour une utilisation en production) - GpPluginOpenLayers-src.js - (version non minifiée du code javascript pour une utilisation en développement) - GpPluginOpenLayers-src.css - (version non minifiée des css pour une utilisation en développement) -``` +Vous pouvez récupérer les extensions Géoplateforme pour OpenLayers soit par [téléchargement direct](#download-direct), soit en utilisant le [gestionnaire de dépendances javascript NPM](#download-npm). + +Les extensions Géoplateforme pour OpenLayers peuvent être récupérées sous 2 formats : + +* toutes les extensions dans un seul fichier : + +```text + . + ├── Dsfr.css + ├── Classic.css + ├── GpfExtOL.css + ├── GpfExtOL.js + └── GpfExtOL.js.map +``` + +* ou une extension par fichier JS avec la CSS associée : + +```text + . + ├── GpfExtOl-CRS.js + ├── GpfExtOl-CRS.js.map + ├── GpfExtOl-Drawing.css + ├── GpfExtOl-Drawing.js + ├── GpfExtOl-Drawing.js.map + ├── Dsfr.css + ├── GpfExtOl-Editor.css + ├── GpfExtOl-Editor.js + ├── GpfExtOl-Editor.js.map + ├── GpfExtOl-ElevationPath.css + ├── GpfExtOl-ElevationPath.js + ├── GpfExtOl-ElevationPath.js.map + ├── GpfExtOl-Export.css + ├── GpfExtOl-Export.js + ├── GpfExtOl-Export.js.map + ├── GpfExtOl-Formats.js + ├── GpfExtOl-Formats.js.map + ├── GpfExtOl-GeoportalAttribution.css + ├── GpfExtOl-GeoportalAttribution.js + ├── GpfExtOl-GeoportalAttribution.js.map + ├── GpfExtOl-GeoportalMousePosition.css + ├── GpfExtOl-GeoportalMousePosition.js + ├── GpfExtOl-GeoportalMousePosition.js.map + ├── GpfExtOl-GetFeatureInfo.css + ├── GpfExtOl-GetFeatureInfo.js + ├── GpfExtOl-GetFeatureInfo.js.map + ├── GpfExtOl-Isocurve.css + ├── GpfExtOl-Isocurve.js + ├── GpfExtOl-Isocurve.js.map + ├── GpfExtOl-LayerImport.css + ├── GpfExtOl-LayerImport.js + ├── GpfExtOl-LayerImport.js.map + ├── GpfExtOl-Layers.js + ├── GpfExtOl-Layers.js.map + ├── GpfExtOl-LayerSwitcher.css + ├── GpfExtOl-LayerSwitcher.js + ├── GpfExtOl-LayerSwitcher.js.map + ├── GpfExtOl-LocationSelector.css + ├── GpfExtOl-LocationSelector.js + ├── GpfExtOl-LocationSelector.js.map + ├── GpfExtOl-MeasureArea.css + ├── GpfExtOl-MeasureArea.js + ├── GpfExtOl-MeasureArea.js.map + ├── GpfExtOl-MeasureAzimuth.css + ├── GpfExtOl-MeasureAzimuth.js + ├── GpfExtOl-MeasureAzimuth.js.map + ├── GpfExtOl-MeasureLength.css + ├── GpfExtOl-MeasureLength.js + ├── GpfExtOl-MeasureLength.js.map + ├── Classic.css + ├── GpfExtOl-ReverseGeocode.css + ├── GpfExtOl-ReverseGeocode.js + ├── GpfExtOl-ReverseGeocode.js.map + ├── GpfExtOl-Route.css + ├── GpfExtOl-Route.js + ├── GpfExtOl-Route.js.map + ├── GpfExtOl-SearchEngine.css + ├── GpfExtOl-SearchEngine.js + └── GpfExtOl-SearchEngine.js.map + +``` + +Il existe 2 thèmes pour les extensions : + +* DSFR +* Classic Les scripts d'OpenLayers s'obtiennent sur [la page de téléchargement d'OpenLayers](https://openlayers.org/download/). @@ -152,7 +224,10 @@ Les scripts d'OpenLayers s'obtiennent sur [la page de téléchargement d'OpenLay #### Téléchargement direct -Vous pouvez télécharger la dernière version de l'extension Géoplateforme pour OpenLayers directement sur [la page des releases des extensions Géoplateforme](https://github.com/IGNF/geoportal-extensions/releases). +> **TODO** +> bundle ou bundles par modules + thèmes + +Vous pouvez télécharger la dernière version de l'extension Géoplateforme pour OpenLayers directement sur [la page des releases des extensions Géoplateforme](https://github.com/IGNF/geoportal-extensions-openlayers/releases). L'archive téléchargée (.zip) comprend l'arborescence décrite ci-dessus. @@ -162,26 +237,24 @@ L'archive téléchargée (.zip) comprend l'arborescence décrite ci-dessus. #### Récupération avec NPM +> **TODO** +> sources ou modules ES6 uniquement + L'extension Géoplateforme pour OpenLayers est aussi disponible dans les dépôts [NPM](https://www.npmjs.com/package/geoportal-extensions-openlayers). Prérequis : [NodeJS](https://nodejs.org/en/) et [npm](https://www.npmjs.com/) installés. -``` +```sh npm i geoportal-extensions-openlayers ``` -L'arborescence décrite ci-dessus sera alors accessible dans le répertoire `node_modules/geoportal-extensions-openlayers/dist/` de votre projet. - - #### Accès direct Vous pouvez aussi choisir d'utiliser des fichiers hébergés en ligne, pour y accéder directement, lors de vos tests par exemple. Cependant, pour une utilisation en production, nous vous conseillons de télécharger ces fichiers et de les héberger vous-même, sur le même serveur qui héberge votre application. Par exemple sur Github Pages : -``` -http://ignf.github.io/geoportal-extensions/openlayers-latest/dist/GpPluginOpenLayers.js -http://ignf.github.io/geoportal-extensions/openlayers-latest/dist/GpPluginOpenLayers.css -http://ignf.github.io/geoportal-extensions/openlayers-latest/dist/GpPluginOpenLayers-src.js -http://ignf.github.io/geoportal-extensions/openlayers-latest/dist/GpPluginOpenLayers-src.css + +```text +todo : liste des bundles ! ```

    (back to top)

    @@ -200,8 +273,8 @@ Intégrez l'extension géoplateforme pour OpenLayers dans votre page web classiq - - + + ```

    (back to top)

    @@ -210,6 +283,9 @@ Intégrez l'extension géoplateforme pour OpenLayers dans votre page web classiq ### Configuration de l'accès à la Géoplateforme +> **TODO** +> valider le mécanisme des clefs ! + L'extension Géoplateforme pour OpenLayers exploite les services web exposés par la Géoplateforme. Ceux-ci sont en libre accès. Vous pouvez cependant paramétrer l'utilisation de l'extension avec une ou plusieurs thématiques Géoplateforme qui correspondent à vos besoins en générant un fichier de configuration local à partir de [cette interface](https://geoplateforme-configuration.onrender.com/) ou en passant par le paramètre apiKey. @@ -221,13 +297,13 @@ Vous pouvez configurer les extensions des manières suivantes : **Méthode 1** : Au chargement de l'extension en utilisant l'attribut "data-key" de la balise **script** de chargement de l'extension : ``` html - + ``` Thèmes multiples : Si vous devez utiliser plusieurs thématiques, il est possible de mettre une liste de thèmes dans l'attribut data-key : ``` html - + ``` Votre utilisation des fonctionnalités de l'extension Géoplateforme sera alors simplement conditionnée par la réception de l'événement onload de la page web, comme sur l'exemple suivant : @@ -239,8 +315,8 @@ Votre utilisation des fonctionnalités de l'extension Géoplateforme sera alors - - + + - - + + - - + + + ``` Votre utilisation des fonctionnalités de l'extension Géoplateforme sera alors simplement conditionnée par la réception de l'événement onload de la page web, comme sur l'exemple suivant : @@ -328,7 +403,7 @@ Votre utilisation des fonctionnalités de l'extension Géoplateforme sera alors ... - + - - - - + + + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Attributions/pages-ol-attributions-modules-osm.html b/samples-src/pages/tests/Attributions/pages-ol-attributions-modules-osm.html index 4880f7dd1..db464af97 100644 --- a/samples-src/pages/tests/Attributions/pages-ol-attributions-modules-osm.html +++ b/samples-src/pages/tests/Attributions/pages-ol-attributions-modules-osm.html @@ -2,11 +2,11 @@ {{#content "vendor"}} - - - - - + + + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Default/pages-ol-packages-default.html b/samples-src/pages/tests/Default/pages-ol-bundle-default.html similarity index 60% rename from samples-src/pages/tests/Default/pages-ol-packages-default.html rename to samples-src/pages/tests/Default/pages-ol-bundle-default.html index fec5ae3f3..28d92fdb8 100644 --- a/samples-src/pages/tests/Default/pages-ol-packages-default.html +++ b/samples-src/pages/tests/Default/pages-ol-bundle-default.html @@ -1,8 +1,8 @@ -{{#extend "ol-sample-modules-layout"}} +{{#extend "ol-sample-bundle-layout"}} {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} @@ -46,32 +46,62 @@

    Ajout de tous les widgets

    }) }); - var drawing = new ol.control.Drawing(); + var drawing = new ol.control.Drawing({ + position : "bottom-left" + }); map.addControl(drawing); - var iso = new ol.control.Isocurve(); + var iso = new ol.control.Isocurve({ + position : "bottom-left" + }); map.addControl(iso); - var layerImport = new ol.control.LayerImport(); + var layerImport = new ol.control.LayerImport({ + position : "bottom-left" + }); map.addControl(layerImport); - var layerSwitcher = new ol.control.LayerSwitcher(); + var layerSwitcher = new ol.control.LayerSwitcher({ + options :{ + position : "bottom-right" + } + }); map.addControl(layerSwitcher); - var mp = new ol.control.GeoportalMousePosition(); + var mp = new ol.control.GeoportalMousePosition({ + position : "bottom-right" + }); map.addControl(mp); - var route = new ol.control.Route(); + var route = new ol.control.Route({ + position : "bottom-right" + }); map.addControl(route); - var reverse = new ol.control.ReverseGeocode({}); + var reverse = new ol.control.ReverseGeocode({ + position : "top-right" + }); map.addControl(reverse); - var search = new ol.control.SearchEngine({}); + var search = new ol.control.SearchEngine({ + position : "top-right" + }); map.addControl(search); - var feature = new ol.control.GetFeatureInfo({}); + var feature = new ol.control.GetFeatureInfo({ + options :{ + position : "top-right" + } + }); map.addControl(feature); - var measureLength = new ol.control.MeasureLength(); + var measureLength = new ol.control.MeasureLength({ + position : "top-left" + }); map.addControl(measureLength); - var measureArea = new ol.control.MeasureArea(); + var measureArea = new ol.control.MeasureArea({ + position : "top-left" + }); map.addControl(measureArea); - var measureAzimuth = new ol.control.MeasureAzimuth(); + var measureAzimuth = new ol.control.MeasureAzimuth({ + position : "top-left" + }); map.addControl(measureAzimuth); - var measureProfil = new ol.control.ElevationPath(); + var measureProfil = new ol.control.ElevationPath({ + position : "top-left" + }); map.addControl(measureProfil); var attributions = new ol.control.GeoportalAttribution(); diff --git a/samples-src/pages/tests/Default/pages-ol-packages-dsfr-default.html b/samples-src/pages/tests/Default/pages-ol-bundle-dsfr-default.html similarity index 59% rename from samples-src/pages/tests/Default/pages-ol-packages-dsfr-default.html rename to samples-src/pages/tests/Default/pages-ol-bundle-dsfr-default.html index 472227829..eb8c2dd6f 100644 --- a/samples-src/pages/tests/Default/pages-ol-packages-dsfr-default.html +++ b/samples-src/pages/tests/Default/pages-ol-bundle-dsfr-default.html @@ -1,8 +1,8 @@ -{{#extend "ol-sample-modules-dsfr-layout"}} +{{#extend "ol-sample-bundle-dsfr-layout"}} {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} @@ -46,32 +46,62 @@

    Ajout de tous les widgets

    }) }); - var drawing = new ol.control.Drawing(); + var drawing = new ol.control.Drawing({ + position : "bottom-left" + }); map.addControl(drawing); - var iso = new ol.control.Isocurve(); + var iso = new ol.control.Isocurve({ + position : "bottom-left" + }); map.addControl(iso); - var layerImport = new ol.control.LayerImport(); + var layerImport = new ol.control.LayerImport({ + position : "bottom-left" + }); map.addControl(layerImport); - var layerSwitcher = new ol.control.LayerSwitcher(); + var layerSwitcher = new ol.control.LayerSwitcher({ + options :{ + position : "bottom-right" + } + }); map.addControl(layerSwitcher); - var mp = new ol.control.GeoportalMousePosition(); + var mp = new ol.control.GeoportalMousePosition({ + position : "bottom-right" + }); map.addControl(mp); - var route = new ol.control.Route(); + var route = new ol.control.Route({ + position : "bottom-right" + }); map.addControl(route); - var reverse = new ol.control.ReverseGeocode({}); + var reverse = new ol.control.ReverseGeocode({ + position : "top-right" + }); map.addControl(reverse); - var search = new ol.control.SearchEngine({}); + var search = new ol.control.SearchEngine({ + position : "top-right" + }); map.addControl(search); - var feature = new ol.control.GetFeatureInfo({}); + var feature = new ol.control.GetFeatureInfo({ + options :{ + position : "top-right" + } + }); map.addControl(feature); - var measureLength = new ol.control.MeasureLength(); + var measureLength = new ol.control.MeasureLength({ + position : "top-left" + }); map.addControl(measureLength); - var measureArea = new ol.control.MeasureArea(); + var measureArea = new ol.control.MeasureArea({ + position : "top-left" + }); map.addControl(measureArea); - var measureAzimuth = new ol.control.MeasureAzimuth(); + var measureAzimuth = new ol.control.MeasureAzimuth({ + position : "top-left" + }); map.addControl(measureAzimuth); - var measureProfil = new ol.control.ElevationPath(); + var measureProfil = new ol.control.ElevationPath({ + position : "top-left" + }); map.addControl(measureProfil); var attributions = new ol.control.GeoportalAttribution(); 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 16e7c7d7c..fb5c59b5a 100644 --- a/samples-src/pages/tests/Default/pages-ol-modules-default.html +++ b/samples-src/pages/tests/Default/pages-ol-modules-default.html @@ -1,37 +1,37 @@ {{#extend "ol-sample-modules-layout"}} {{#content "vendor"}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{/content}} {{#content "head"}} 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 ae2d2e4ce..aca4be526 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 @@ -2,37 +2,37 @@ {{#content "vendor"}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-default.html b/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-default.html index c71c4dd45..3c6a26567 100644 --- a/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-default.html +++ b/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-default.html @@ -1,9 +1,10 @@ {{#extend "ol-sample-modules-layout"}} {{#content "vendor"}} - - - + + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-display-measure.html b/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-display-measure.html index b9674a644..3be3c14b7 100644 --- a/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-display-measure.html +++ b/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-display-measure.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-dsfr-default.html b/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-dsfr-default.html index 700cc081b..2aab81346 100644 --- a/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-dsfr-default.html +++ b/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-dsfr-default.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-export.html b/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-export.html index e2863f1e7..86ac9910f 100644 --- a/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-export.html +++ b/samples-src/pages/tests/Drawing/pages-ol-drawing-modules-export.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Editor/pages-ol-editor-bundle-multi-editor.html b/samples-src/pages/tests/Editor/pages-ol-editor-modules-multi-editor.html similarity index 97% rename from samples-src/pages/tests/Editor/pages-ol-editor-bundle-multi-editor.html rename to samples-src/pages/tests/Editor/pages-ol-editor-modules-multi-editor.html index 1870a6408..4dc367df8 100644 --- a/samples-src/pages/tests/Editor/pages-ol-editor-bundle-multi-editor.html +++ b/samples-src/pages/tests/Editor/pages-ol-editor-modules-multi-editor.html @@ -1,4 +1,9 @@ -{{#extend "ol-sample-bundle-multikeys-layout"}} +{{#extend "ol-sample-modules-layout"}} + +{{#content "vendor"}} + + +{{/content}} {{#content "head"}} Sample openlayers Themes Mapbox diff --git a/samples-src/pages/tests/Editor/pages-ol-editor-bundle-options-icon.html b/samples-src/pages/tests/Editor/pages-ol-editor-modules-options-icon.html similarity index 90% rename from samples-src/pages/tests/Editor/pages-ol-editor-bundle-options-icon.html rename to samples-src/pages/tests/Editor/pages-ol-editor-modules-options-icon.html index d979eff45..2ea10e70a 100644 --- a/samples-src/pages/tests/Editor/pages-ol-editor-bundle-options-icon.html +++ b/samples-src/pages/tests/Editor/pages-ol-editor-modules-options-icon.html @@ -1,4 +1,9 @@ -{{#extend "ol-sample-bundle-multikeys-layout"}} +{{#extend "ol-sample-modules-layout"}} + +{{#content "vendor"}} + + +{{/content}} {{#content "head"}} Sample openlayers Themes Mapbox diff --git a/samples-src/pages/tests/Editor/pages-ol-editor-bundle-options-sort.html b/samples-src/pages/tests/Editor/pages-ol-editor-modules-options-sort.html similarity index 95% rename from samples-src/pages/tests/Editor/pages-ol-editor-bundle-options-sort.html rename to samples-src/pages/tests/Editor/pages-ol-editor-modules-options-sort.html index 767fc1218..92285c6a8 100644 --- a/samples-src/pages/tests/Editor/pages-ol-editor-bundle-options-sort.html +++ b/samples-src/pages/tests/Editor/pages-ol-editor-modules-options-sort.html @@ -1,4 +1,9 @@ -{{#extend "ol-sample-bundle-multikeys-layout"}} +{{#extend "ol-sample-modules-layout"}} + +{{#content "vendor"}} + + +{{/content}} {{#content "head"}} Sample openlayers Group & Sort Mapbox diff --git a/samples-src/pages/tests/Editor/pages-ol-editor-bundle-options-themes.html b/samples-src/pages/tests/Editor/pages-ol-editor-modules-options-themes.html similarity index 91% rename from samples-src/pages/tests/Editor/pages-ol-editor-bundle-options-themes.html rename to samples-src/pages/tests/Editor/pages-ol-editor-modules-options-themes.html index 07f0b1a26..4dd941528 100644 --- a/samples-src/pages/tests/Editor/pages-ol-editor-bundle-options-themes.html +++ b/samples-src/pages/tests/Editor/pages-ol-editor-modules-options-themes.html @@ -1,4 +1,9 @@ -{{#extend "ol-sample-bundle-multikeys-layout"}} +{{#extend "ol-sample-modules-layout"}} + +{{#content "vendor"}} + + +{{/content}} {{#content "head"}} Sample openlayers Themes Mapbox diff --git a/samples-src/pages/tests/Editor/pages-ol-editor-bundle-sprites.html b/samples-src/pages/tests/Editor/pages-ol-editor-modules-sprites.html similarity index 95% rename from samples-src/pages/tests/Editor/pages-ol-editor-bundle-sprites.html rename to samples-src/pages/tests/Editor/pages-ol-editor-modules-sprites.html index 4dc6515ac..0df72e26f 100644 --- a/samples-src/pages/tests/Editor/pages-ol-editor-bundle-sprites.html +++ b/samples-src/pages/tests/Editor/pages-ol-editor-modules-sprites.html @@ -1,4 +1,9 @@ -{{#extend "ol-sample-bundle-multikeys-layout"}} +{{#extend "ol-sample-modules-layout"}} + +{{#content "vendor"}} + + +{{/content}} {{#content "head"}} Sample openlayers Themes Mapbox diff --git a/samples-src/pages/tests/Editor/pages-ol-editor-modules-test.html b/samples-src/pages/tests/Editor/pages-ol-editor-modules-test.html index 55176e51e..2a869b93b 100644 --- a/samples-src/pages/tests/Editor/pages-ol-editor-modules-test.html +++ b/samples-src/pages/tests/Editor/pages-ol-editor-modules-test.html @@ -1,9 +1,8 @@ {{#extend "ol-sample-modules-layout"}} {{#content "vendor"}} - - - + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Editor/pages-ol-filters-bundle-test.html b/samples-src/pages/tests/Editor/pages-ol-filters-modules-test.html similarity index 91% rename from samples-src/pages/tests/Editor/pages-ol-filters-bundle-test.html rename to samples-src/pages/tests/Editor/pages-ol-filters-modules-test.html index fff65a9c6..da772a964 100644 --- a/samples-src/pages/tests/Editor/pages-ol-filters-bundle-test.html +++ b/samples-src/pages/tests/Editor/pages-ol-filters-modules-test.html @@ -1,4 +1,9 @@ -{{#extend "ol-sample-bundle-multikeys-layout"}} +{{#extend "ol-sample-modules-layout"}} + +{{#content "vendor"}} + + +{{/content}} {{#content "head"}} Sample openlayers Filters Mapbox diff --git a/samples-src/pages/tests/Editor/pages-ol-layers-bundle-test.html b/samples-src/pages/tests/Editor/pages-ol-layers-modules-test.html similarity index 97% rename from samples-src/pages/tests/Editor/pages-ol-layers-bundle-test.html rename to samples-src/pages/tests/Editor/pages-ol-layers-modules-test.html index c1f493907..2815473d6 100644 --- a/samples-src/pages/tests/Editor/pages-ol-layers-bundle-test.html +++ b/samples-src/pages/tests/Editor/pages-ol-layers-modules-test.html @@ -1,4 +1,9 @@ -{{#extend "ol-sample-bundle-multikeys-layout"}} +{{#extend "ol-sample-modules-layout"}} + +{{#content "vendor"}} + + +{{/content}} {{#content "head"}} Sample openlayers Layers Mapbox diff --git a/samples-src/pages/tests/Editor/pages-ol-legends-bundle-test.html b/samples-src/pages/tests/Editor/pages-ol-legends-modules-test.html similarity index 99% rename from samples-src/pages/tests/Editor/pages-ol-legends-bundle-test.html rename to samples-src/pages/tests/Editor/pages-ol-legends-modules-test.html index 845ce6fa6..1242489fb 100644 --- a/samples-src/pages/tests/Editor/pages-ol-legends-bundle-test.html +++ b/samples-src/pages/tests/Editor/pages-ol-legends-modules-test.html @@ -1,4 +1,9 @@ -{{#extend "ol-sample-bundle-multikeys-layout"}} +{{#extend "ol-sample-modules-layout"}} + +{{#content "vendor"}} + + +{{/content}} {{#content "head"}} Sample openlayers Legend Mapbox diff --git a/samples-src/pages/tests/Editor/pages-ol-styles-bundle-test.html b/samples-src/pages/tests/Editor/pages-ol-styles-modules-test.html similarity index 95% rename from samples-src/pages/tests/Editor/pages-ol-styles-bundle-test.html rename to samples-src/pages/tests/Editor/pages-ol-styles-modules-test.html index ece6a19c5..9d65f966f 100644 --- a/samples-src/pages/tests/Editor/pages-ol-styles-bundle-test.html +++ b/samples-src/pages/tests/Editor/pages-ol-styles-modules-test.html @@ -1,4 +1,9 @@ -{{#extend "ol-sample-bundle-multikeys-layout"}} +{{#extend "ol-sample-modules-layout"}} + +{{#content "vendor"}} + + +{{/content}} {{#content "head"}} Sample openlayers Styles Mapbox diff --git a/samples-src/pages/tests/Editor/pages-ol-themes-bundle-test.html b/samples-src/pages/tests/Editor/pages-ol-themes-modules-test.html similarity index 96% rename from samples-src/pages/tests/Editor/pages-ol-themes-bundle-test.html rename to samples-src/pages/tests/Editor/pages-ol-themes-modules-test.html index dabc700a7..7a4a80677 100644 --- a/samples-src/pages/tests/Editor/pages-ol-themes-bundle-test.html +++ b/samples-src/pages/tests/Editor/pages-ol-themes-modules-test.html @@ -1,4 +1,9 @@ -{{#extend "ol-sample-bundle-multikeys-layout"}} +{{#extend "ol-sample-modules-layout"}} + +{{#content "vendor"}} + + +{{/content}} {{#content "head"}} Sample openlayers Themes Mapbox diff --git a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-all-options.html b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-all-options.html index 371b1905b..f95ddf550 100644 --- a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-all-options.html +++ b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-all-options.html @@ -1,10 +1,10 @@ {{#extend "ol-sample-modules-layout"}} {{#content "vendor"}} - - - - + + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-amcharts.html b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-amcharts.html index be9250cbf..c7059e9bf 100644 --- a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-amcharts.html +++ b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-amcharts.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} diff --git a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-d3.html b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-d3.html index adfb14b4e..cb988fab3 100644 --- a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-d3.html +++ b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-d3.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} diff --git a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-dsfr-amcharts.html b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-dsfr-amcharts.html index fb7b30fa6..b4dd0fe89 100644 --- a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-dsfr-amcharts.html +++ b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-dsfr-amcharts.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} diff --git a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-dsfr-d3.html b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-dsfr-d3.html index b47f95c73..e61db12b9 100644 --- a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-dsfr-d3.html +++ b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-dsfr-d3.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} diff --git a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-dsfr-raw.html b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-dsfr-raw.html index 4b76de013..4df1e3681 100644 --- a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-dsfr-raw.html +++ b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-dsfr-raw.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-raw-target.html b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-raw-target.html index cb73c110a..03a352a6f 100644 --- a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-raw-target.html +++ b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-raw-target.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-raw.html b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-raw.html index 12878e0ff..588faf3d1 100644 --- a/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-raw.html +++ b/samples-src/pages/tests/ElevationPath/pages-ol-elevationpath-modules-raw.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Export/pages-ol-export-modules-default.html b/samples-src/pages/tests/Export/pages-ol-export-modules-default.html index ce234540f..303a96d45 100644 --- a/samples-src/pages/tests/Export/pages-ol-export-modules-default.html +++ b/samples-src/pages/tests/Export/pages-ol-export-modules-default.html @@ -2,20 +2,20 @@ {{#content "vendor"}} - - - - - - - - - - - - - + + + + + + + + + + + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Export/pages-ol-export-modules-dsfr-default.html b/samples-src/pages/tests/Export/pages-ol-export-modules-dsfr-default.html index 8201be05b..9f819d607 100644 --- a/samples-src/pages/tests/Export/pages-ol-export-modules-dsfr-default.html +++ b/samples-src/pages/tests/Export/pages-ol-export-modules-dsfr-default.html @@ -2,20 +2,20 @@ {{#content "vendor"}} - - - - - - - - - - - - - - + + + + + + + + + + + + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Formats/pages-ol-geojsonextended-modules-default.html b/samples-src/pages/tests/Formats/pages-ol-geojsonextended-modules-default.html index 4e464dca8..817ab2978 100644 --- a/samples-src/pages/tests/Formats/pages-ol-geojsonextended-modules-default.html +++ b/samples-src/pages/tests/Formats/pages-ol-geojsonextended-modules-default.html @@ -1,8 +1,8 @@ {{#extend "ol-sample-modules-layout"}} {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Formats/pages-ol-gpxextended-modules-default.html b/samples-src/pages/tests/Formats/pages-ol-gpxextended-modules-default.html index 1d4f93374..2f09147eb 100644 --- a/samples-src/pages/tests/Formats/pages-ol-gpxextended-modules-default.html +++ b/samples-src/pages/tests/Formats/pages-ol-gpxextended-modules-default.html @@ -1,8 +1,8 @@ {{#extend "ol-sample-modules-layout"}} {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Formats/pages-ol-kmlextended-modules-default.html b/samples-src/pages/tests/Formats/pages-ol-kmlextended-modules-default.html index 7b5a5ab07..8a2868f77 100644 --- a/samples-src/pages/tests/Formats/pages-ol-kmlextended-modules-default.html +++ b/samples-src/pages/tests/Formats/pages-ol-kmlextended-modules-default.html @@ -1,8 +1,8 @@ {{#extend "ol-sample-modules-layout"}} {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/GetFeatureInfo/pages-ol-getfeatureinfo-modules-default.html b/samples-src/pages/tests/GetFeatureInfo/pages-ol-getfeatureinfo-modules-default.html index bc56f7b15..83f08c2f2 100644 --- a/samples-src/pages/tests/GetFeatureInfo/pages-ol-getfeatureinfo-modules-default.html +++ b/samples-src/pages/tests/GetFeatureInfo/pages-ol-getfeatureinfo-modules-default.html @@ -2,10 +2,10 @@ {{#content "vendor"}} - - - - + + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/GetFeatureInfo/pages-ol-getfeatureinfo-modules-options.html b/samples-src/pages/tests/GetFeatureInfo/pages-ol-getfeatureinfo-modules-options.html index 182b0557e..1f657673d 100644 --- a/samples-src/pages/tests/GetFeatureInfo/pages-ol-getfeatureinfo-modules-options.html +++ b/samples-src/pages/tests/GetFeatureInfo/pages-ol-getfeatureinfo-modules-options.html @@ -2,12 +2,12 @@ {{#content "vendor"}} - - - - - - + + + + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Isocurve/pages-ol-isocurve-modules-default.html b/samples-src/pages/tests/Isocurve/pages-ol-isocurve-modules-default.html index 39c247129..42bfbd114 100644 --- a/samples-src/pages/tests/Isocurve/pages-ol-isocurve-modules-default.html +++ b/samples-src/pages/tests/Isocurve/pages-ol-isocurve-modules-default.html @@ -2,10 +2,10 @@ {{#content "vendor"}} - - - - + + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Isocurve/pages-ol-isocurve-modules-dsfr-default.html b/samples-src/pages/tests/Isocurve/pages-ol-isocurve-modules-dsfr-default.html index 29c11ee79..9c34909fb 100644 --- a/samples-src/pages/tests/Isocurve/pages-ol-isocurve-modules-dsfr-default.html +++ b/samples-src/pages/tests/Isocurve/pages-ol-isocurve-modules-dsfr-default.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/LayerImport/pages-ol-layerimport-modules-default.html b/samples-src/pages/tests/LayerImport/pages-ol-layerimport-modules-default.html index 050b2f1aa..df588dd39 100644 --- a/samples-src/pages/tests/LayerImport/pages-ol-layerimport-modules-default.html +++ b/samples-src/pages/tests/LayerImport/pages-ol-layerimport-modules-default.html @@ -2,10 +2,10 @@ {{#content "vendor"}} - - - - + + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/LayerImport/pages-ol-layerimport-modules-dsfr-default.html b/samples-src/pages/tests/LayerImport/pages-ol-layerimport-modules-dsfr-default.html index 45b69873c..8dcfea30a 100644 --- a/samples-src/pages/tests/LayerImport/pages-ol-layerimport-modules-dsfr-default.html +++ b/samples-src/pages/tests/LayerImport/pages-ol-layerimport-modules-dsfr-default.html @@ -2,10 +2,10 @@ {{#content "vendor"}} - - - - + + + + {{/content}} {{#content "head"}} 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 6053ab5a1..d0ba371c9 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 @@ -2,9 +2,9 @@ {{#content "vendor"}} - - - + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-default.html b/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-default.html index 651bbca43..7c006e6db 100644 --- a/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-default.html +++ b/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-default.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} 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 516ddc4d9..157694a57 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 @@ -2,9 +2,9 @@ {{#content "vendor"}} - - - + + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-dsfr-default.html b/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-dsfr-default.html index 8c6e88d30..405d337ca 100644 --- a/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-dsfr-default.html +++ b/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-dsfr-default.html @@ -2,8 +2,8 @@ {{#content "vendor"}} - - + + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-removelayers.html b/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-removelayers.html index ba97a9ccf..b24bc5e4d 100644 --- a/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-removelayers.html +++ b/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-removelayers.html @@ -2,9 +2,9 @@ {{#content "vendor"}} - - - + + + {{/content}} {{#content "head"}} 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 ccf79b0b4..c2c310ee8 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,7 +1,7 @@ {{#extend "ol-sample-modules-layout"}} {{#content "vendor"}} - + {{/content}} {{#content "head"}} diff --git a/samples-src/pages/tests/Layers/pages-ol-layermapbox-modules-editor.html b/samples-src/pages/tests/Layers/pages-ol-layermapbox-modules-editor.html index 62b9d01a2..6141f1d32 100644 --- a/samples-src/pages/tests/Layers/pages-ol-layermapbox-modules-editor.html +++ b/samples-src/pages/tests/Layers/pages-ol-layermapbox-modules-editor.html @@ -8,8 +8,8 @@ - - + +