geopf-extensions-openlayers
Version:
French Geoportal Extensions for OpenLayers libraries
1,245 lines (1,130 loc) • 148 kB
JavaScript
// 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];