UNPKG

geopf-extensions-openlayers

Version:

French Geoportal Extensions for OpenLayers libraries

1,245 lines (1,130 loc) 148 kB
// import CSS import "../../CSS/Controls/LayerImport/GPFlayerImport.css"; // import "../../CSS/Controls/LayerImport/GPFlayerImportStyle.css"; // import OpenLayers // import Control from "ol/control/Control"; import Widget from "../Widget"; import Control from "../Control"; import Map from "ol/Map"; 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, updateMapboxLayer as updateMapboxLayerOlms } 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. * * @alias ol.control.LayerImport * @module LayerImport */ class LayerImport extends Control { /** * @constructor * @fires layerimport:mapbox:added * @fires layerimport:vector:added * @fires layerimport:service:added * @fires editor:loaded * @fires render:success * @fires render:failure * @param {Object} options - options for function call. * @param {Number} [options.id] - Ability to add an identifier on the widget (advanced option) * @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.<String>} [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 * }) * }) * } * } * }); */ constructor (options) { options = options || {}; // call ol.control.Control constructor super(options); /** * Nom de la classe (heritage) * @private */ this.CLASSNAME = "LayerImport"; 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 {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.classList.replace("GPelementVisible", "GPelementHidden"); self._mapBoxPanel.classList.replace("gpf-visible", "gpf-hidden"); } } } }, self ); // mode "draggable" if (this.draggable) { Draggable.dragElement( this._importPanel, this._importPanelHeader, 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); } // reunion du bouton avec le précédent if (this.options.gutter === false) { this.getContainer().classList.add("gpf-button-no-gutter"); } } /** * 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; } /** * Get container * * @returns {HTMLElement} container */ getContainer () { return this._container; } // ################################################################### // // ##################### 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); /** * @type {Boolean} * specify if LayerImport control is collapsed (true) or not (false) */ this.collapsed = this.options.collapsed; /** * @type {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 = this.options.id || SelectorID.generate(); /** * @private * si une requête est en cours ou non */ this._waiting = false; /** * @private * 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 ?) /** @private */ this._showImportButton = null; /** @private */ this._importPanel = null; /** @private */ this._panelCloseButton = null; /** @private */ this._importPanelHeader = null; /** @private */ this._importPanelTitle = null; /** @private */ this._importPanelReturnPicto = null; /** @private */ this._formContainer = null; /** @private */ this._staticLocalImportInput = null; /** @private */ this._staticUrlImportInput = null; /** @private */ this._serviceUrlImportInput = null; /** @private */ this._getCapPanel = null; /** @private */ this._getCapPanelHeader = null; /** @private */ this._getCapResultsListContainer = null; /** @private */ this._mapBoxPanel = null; /** @private */ this._mapBoxPanelHeader = null; /** @private */ this._mapBoxResultsListContainer = null; /** @private */ this._waitingContainer = null; /** @private */ this._loadingContainer = null; // ################################################################## // // ################ Interrogation du GetCapabilities ################ // /** @private */ this._hasGetCapResults = false; /** @private */ this._getCapRequestUrl = null; /** @private */ this._getCapResponseWMS = null; /** @private */ this._getCapResponseWMSLayers = []; /** @private */ this._getCapResponseWMTS = null; /** @private */ this._getCapResponseWMTSLayers = []; // ################################################################## // // ########################### MapBox ############################### // /** @private */ this._hasMapBoxResults = false; // ################################################################## // // ########################### file or url ########################## // /** @private */ this.contentStatic = null; /** @private */ this._url = null; /** @private */ this._file = null; /** @private */ 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 {HTMLElement} 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(); // return var panelReturn = this._importPanelReturnPicto = this._createImportPanelReturnPictoElement(); panelHeader.appendChild(panelReturn); // panel title var panelTitle = this._importPanelTitle = 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 {HTMLElement} 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) * * @param { Event } e évènement associé au clic * @private */ _onShowImportClick (e) { var opened = this._showImportButton.ariaPressed; if (opened === "true") { this.onPanelOpen(); } 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) this.collapsed = !(opened === "true"); this.dispatchEvent("change:collapsed"); // on recalcule la position if (this.options.position && !this.collapsed) { this.updatePosition(this.options.position); } // on affiche les resultats d'une couche MapBox // car on garde la possibilité de modifier la configuration des layers if (this._hasMapBoxResults) { this._mapBoxPanel.classList.replace("GPelementHidden", "GPelementVisible"); this._mapBoxPanel.classList.replace("gpf-hidden", "gpf-visible"); this._hideFormContainer(); } else if (this._hasGetCapResults) { this._getCapPanel.classList.replace("GPelementHidden", "GPelementVisible"); this._getCapPanel.classList.replace("gpf-hidden", "gpf-visible"); this._hideFormContainer(); } else { this._getCapPanel.classList.replace("GPelementVisible", "GPelementHidden"); this._getCapPanel.classList.replace("gpf-visible", "gpf-hidden"); this._mapBoxPanel.classList.replace("GPelementVisible", "GPelementHidden"); this._mapBoxPanel.classList.replace("gpf-visible", "gpf-hidden"); this._displayFormContainer(); } } /** * this method is called by event 'change' on 'GPimportType' tag form * (cf. LayerImportDOM._createImportTypeLineElement), * and change current import type * * @param {Event} 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 {Event} 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._importPanelReturnPicto.classList.replace("GPelementVisible", "GPelementHidden"); this._importPanelReturnPicto.classList.replace("gpf-visible", "gpf-hidden"); this._mapBoxPanel.classList.replace("GPelementVisible", "GPelementHidden"); this._mapBoxPanel.classList.replace("gpf-visible", "gpf-hidden"); } /** * this method is called by event 'click' on 'GPimportPanelReturnPicto' tag form * (cf. LayerImportDOM._createImportMapBoxPanelHeaderElement), * and return to information * * @param {Event} e - HTMLElement * @private */ _onReturnPictoClick (e) { // on bascule sur l'icone d'ouverture du composant this._onGetCapPanelClose(); this._onMapBoxPanelClose(); 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) { // on ferme le widget à l'import d'une couche statique this.setCollapsed(true); 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); // enregistrement initial map.set("mapbox-style", _glStyles); // 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];