geoportal-extensions-openlayers
Version:

1,210 lines (1,090 loc) • 137 kB
JavaScript
// import CSS
import "../CSS/Controls/LayerImport/GPimportOpenLayers.css";
// import OpenLayers
import Control from "ol/control/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";
import Markers from "./Utils/Markers";
import Draggable from "../../Common/Utils/Draggable";
import Interactions from "./Utils/Interactions";
import Utils from "../../Common/Utils";
import Logger from "../../Common/Utils/LoggerByDefault";
import SelectorID from "../../Common/Utils/SelectorID";
import ProxyUtils from "../../Common/Utils/ProxyUtils";
import LayerImportDOM from "../../Common/Controls/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";
import Route from "./Route";
import Isocurve from "./Isocurve";
import ElevationPath from "./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.<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
* })
* })
* }
* }
* });
*/
var LayerImport = (function (Control) {
/**
* See {@link ol.control.LayerImport}
* @module LayerImport
* @alias module:~Controls/LayerImport
* @param {*} options - options
* @example
* import LayerImport from "src/OpenLayers/Controls/LayerImport"
*/
function LayerImport (options) {
options = options || {};
if (!(this instanceof LayerImport)) {
throw new TypeError("ERROR CLASS_CONSTRUCTOR");
}
this._initialize(options);
// init control DOM container
var container = this._container = this._initContainer(options);
// call ol.control.Control constructor
Control.call(this, {
element : container,
target : options.target,
render : options.render
});
};
// Inherits from ol.control.Control
if (Control) LayerImport.__proto__ = Control;
/**
* Default styles applyied to KML, GPX and GeoJSON features.
*
* @private
*/
LayerImport.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
})
})
};
/**
* @lends module:LayerImport
*/
LayerImport.prototype = Object.create(Control.prototype, {});
// on récupère les méthodes de la classe commune LayerImportDOM
Utils.assign(LayerImport.prototype, LayerImportDOM);
/**
* Constructor (alias)
*
* @private
*/
LayerImport.prototype.constructor = LayerImport;
// ################################################################### //
// ############## public methods (getters, setters) ################## //
// ################################################################### //
/**
* Overwrite OpenLayers setMap method
*
* @param {ol.Map} map - Map.
*/
LayerImport.prototype.setMap = function (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,
map.getTargetElement()
);
// panneau draggable pour les resultats ?
Draggable.dragElement(
this._getCapPanel,
this._getCapPanelHeader,
map.getTargetElement()
);
Draggable.dragElement(
this._mapBoxPanel,
this._mapBoxPanelHeader,
map.getTargetElement()
);
}
}
// on appelle la méthode setMap originale d'OpenLayers
Control.prototype.setMap.call(this, map);
};
/**
* Returns true if widget is collapsed (minimized), false otherwise
*
* @returns {Boolean} collapsed - true if widget is collapsed
*/
LayerImport.prototype.getCollapsed = function () {
return this.collapsed;
};
/**
* Collapse or display widget main container
*
* @param {Boolean} collapsed - True to collapse widget, False to display it
*/
LayerImport.prototype.setCollapsed = function (collapsed) {
if (collapsed === undefined) {
logger.error("[ERROR] LayerImport:setCollapsed - missing collapsed parameter");
return;
}
if ((collapsed && this.collapsed) || (!collapsed && !this.collapsed)) {
return;
}
if (collapsed) {
document.getElementById("GPimportPanelClose-" + this._uid).click();
} else {
document.getElementById("GPshowImport-" + this._uid).click();
}
this.collapsed = collapsed;
};
/**
* Returns content of a static import (KML, GPX or GeoJSON)
*
* @returns {String} contentStatic - content static
*/
LayerImport.prototype.getStaticImportContent = function () {
return this.contentStatic;
};
/**
* Returns content of a service import (GetCapabilities)
*
* @returns {String} contentService - content service
*/
LayerImport.prototype.getServiceImportContent = function () {
return this.contentService;
};
/**
* Returns layer name
*
* @returns {String} name - layer name
*/
LayerImport.prototype.getName = function () {
return this._name;
};
// ################################################################### //
// ##################### init component ############################## //
// ################################################################### //
/**
* Initialize LayerImport control (called by LayerImport constructor)
*
* @param {Object} options - constructor options
* @private
*/
LayerImport.prototype._initialize = function (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._showImportInput = null;
this._importPanel = 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
*/
LayerImport.prototype._checkInputOptions = function (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
*/
LayerImport.prototype._initDefaultStyles = function () {
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
*/
LayerImport.prototype._initImportTypes = function () {
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
*/
LayerImport.prototype._initContainer = function () {
// create main container
var container = this._createMainContainerElement();
// create show Import element
var inputShow = this._showImportInput = this._createShowImportElement();
container.appendChild(inputShow);
// mode "collapsed"
if (!this.collapsed) {
inputShow.checked = true;
}
// create Import picto
var picto = this._createShowImportPictoElement();
container.appendChild(picto);
// panel
var importPanel = this._importPanel = this._createImportPanelElement();
// header
var panelHeader = this._importPanelHeader = this._createImportPanelHeaderElement();
importPanel.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();
importPanel.appendChild(importForm);
container.appendChild(importPanel);
// 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);
container.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);
container.appendChild(mapBoxPanel);
// waiting
var waiting = this._waitingContainer = this._createImportWaitingElement();
container.appendChild(waiting);
return container;
};
/**
* Create control main container (DOM initialize)
*
* @private
* @returns {DOMElement} importForm - form main container
*/
LayerImport.prototype._initInputFormElement = function () {
// 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
*/
LayerImport.prototype._onShowImportClick = function () {
var map = this.getMap();
// on supprime toutes les interactions
Interactions.unset(map);
// on affiche les resultats d'une couche MapBox
if (this._hasMapBoxResults) {
this._mapBoxPanel.style.display = "block";
}
// 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 = this._showImportInput.checked;
this.dispatchEvent("change:collapsed");
};
/**
* this method is called by event 'change' on 'GPimportType' tag form
* (cf. LayerImportDOM._createImportTypeLineElement),
* and change current import type
*
* @param {Object} e - HTMLElement
* @private
*/
LayerImport.prototype._onImportTypeChange = function (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
*/
LayerImport.prototype._onStaticImportTypeChange = function (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
*/
LayerImport.prototype._onGetCapPanelClose = function () {
// 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
*/
LayerImport.prototype._onMapBoxPanelClose = function () {
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
*/
LayerImport.prototype._onMapBoxReturnPictoClick = function (e) {
// on bascule sur l'icone d'ouverture du composant
this._mapBoxPanel.style.display = "none";
this._showImportInput.checked = false;
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
*/
LayerImport.prototype._onImportSubmit = function () {
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
*/
LayerImport.prototype._importStaticLayer = function () {
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
*/
LayerImport.prototype._importStaticLayerFromUrl = function (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
*/
LayerImport.prototype._importStaticLayerFromLocalFile = function (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 = function (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 = function () {
logger.log("onprogress");
};
/** on load start */
fReader.onloadstart = function () {
// affichage d'une patience le temps du chargement
context._displayWaitingContainer();
logger.log("onloadstart");
};
/** on readAsText abort */
fReader.onabort = function () {
// en cas d'erreur, on revient au panel initial et on cache la patience
context._hideWaitingContainer();
logger.log("onabort");
};
// on readAsText loadend
fReader.onloadend = function (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 = function (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
*/
LayerImport.prototype._addFeaturesFromImportStaticLayer = function (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?" +