UNPKG

@ignf-geoportal/sdk-3d

Version:

French Geoportal SDK based on OpenLayers (2D) and iTowns (3D) libraries

1,126 lines (1,061 loc) 41.3 kB
import { ItMap } from "./ItMapBase"; import { IMap } from "../Interface/IMap"; import { Extent, WMSSource, WMTSSource, FileSource, VectorTilesSource, ElevationLayer, ColorLayer, Fetcher, KMLParser, GeoJsonParser, GpxParser } from "itowns"; import { Helper } from "geoportal-extensions-itowns"; /** * Proprietes observables des couches pour le SDK */ ItMap.LAYERPROPERTIES = { visible : "visibility", opacity : "opacity", sequence : "position" }; /** * Removes of the map the layers given as parameters * * @param {Array.<String>} layerIds - A list of layer's id or null. */ ItMap.prototype.removeLayers = function (layerIds) { if (!IMap.prototype.removeLayers.apply(this, arguments)) { return; } if (!Array.isArray(layerIds)) { layerIds = [layerIds]; } // ici on sait que layerIds est un tableau layerIds.forEach(function (_layerId) { if (this._getLayersObj(_layerId) && Array.isArray(this._getLayersObj(_layerId)) && this._getLayersObj(_layerId).length > 0) { this.libMap.removeLayer(_layerId); } else { this.logger.info("[ItMap] : Impossible to remove " + _layerId + " - not Found"); } }, this); }; /** * Modifies the listed layers'options of the map * * @param {Object} layersOptions - Layers to add to the map and their options. Associative array mapping official name of the Geoportal layer or the id of a personal layer (keys) with their properties (values given as {@link Gp.LayerOptions}). */ ItMap.prototype.modifyLayers = function (layersOptions) { if (!IMap.prototype.modifyLayers.apply(this, arguments)) { return; } var layerIds = Object.keys(layersOptions); // on recupere les objets correspondants dejà sur la carte var _layerObjs = this._getLayersObj(layerIds); _layerObjs.forEach(function (_layerObj) { this.logger.trace("[IMap] modifyLayers : modifying : [" + _layerObj.id + "]"); // traduction options ahn => options ItMap var commonOpts = this._applyCommonLayerParams(layersOptions[_layerObj.id]); // application des options IT aux couches IT // l'objet _layerObj.options sera mis à jour par le mécanisme des evenements. if (commonOpts.hasOwnProperty("opacity")) { this.logger.trace("[IMap] modifyLayers : setting opacity of : [" + _layerObj.id + "] to : " + commonOpts.opacity); this.libMap.setLayerOpacity(_layerObj.id, commonOpts.opacity); } if (commonOpts.hasOwnProperty("visible")) { this.logger.trace("[IMap] modifyLayers : setting visible of : [" + _layerObj.id + "] to : " + commonOpts.visible); this.libMap.setLayerVisibility(_layerObj.id, commonOpts.visible); } if (commonOpts.hasOwnProperty("zIndex")) { this.logger.trace("[IMap] modifyLayers : setting zIndex of : [" + _layerObj.id + "] to : " + commonOpts.zIndex); this.libMap.moveLayerToIndex(_layerObj.id, commonOpts.zIndex); } /* TODO A compléter if (commonOpts.hasOwnProperty("minResolution")) { this.logger.trace("[IMap] modifyLayers : setting minResolution of : [" + _layerObj.id + "] to : " + commonOpts.minResolution) ; _layerObj.obj.setMinResolution(commonOpts.minResolution) ; } if (commonOpts.hasOwnProperty("maxResolution")) { this.logger.trace("[IMap] modifyLayers : setting maxResolution of : [" + _layerObj.id + "] to : " + commonOpts.maxResolution) ; _layerObj.obj.setMaxResolution(commonOpts.maxResolution) ; } */ }, this); }; /** * Finds the layerOpts object corresponding to the IT layer * * @param {String} layerId - layer id * @param {Object[]} layersStack - list of layers * @returns {Object} layerOpts - layer options * * @private */ ItMap.prototype._getLayerOpts = function (layerId, layersStack) { var layerOpts = null; layersStack = layersStack || this._layers; for (var i = 0; i < layersStack.length; i++) { var l = layersStack[i]; if (l.id === layerId) { this.logger.trace("[ItMap] : found layer : " + l.id); layerOpts = {}; layerOpts[l.id] = l.options; break; } } return layerOpts; }; /** * Registers unknown unregistered layer * * @param {Object} layerObj - IT layer * @returns {Object} - new layer index in this._layers * * @private */ ItMap.prototype._registerUnknownLayer = function (layerObj) { // couches de résultat (itineraire, isochrone) /* var layerId = "unknownLayer" ; if (layerObj.hasOwnProperty("gpResultLayerId")) { // isochrones : [GraphName]$GEOPORTAIL :GPP :Isocurve // itineraire : [GraphName]$GEOPORTAIL :GPP :Itineraire layerId = layerObj.gpResultLayerId ; } // on rajoute un timestamp layerId += "-" + Date.now() ; this._layers.push({ id : layerId, obj : layerObj, options : {} }) ; var layerOpts = {} ; layerOpts[layerId] = {} ; */ return {}; }; /** * Gets layer parameterss from IT layer params * opacity, visibility, sequence * * @param {Object} itlayerOpts - options of the layer * @returns {Gp.LayerOptions} - object with common options * * @private */ ItMap.prototype._getCommonLayerParams = function (itlayerOpts) { var commonOpts = {}; this.logger.trace("[ItMap] : _getCommonLayerParams "); if (itlayerOpts.hasOwnProperty("opacity")) { this.logger.trace("[ItMap] : _getCommonLayerParams - opacity : " + itlayerOpts.opacity); commonOpts.opacity = itlayerOpts.opacity; } if (itlayerOpts.hasOwnProperty("visible")) { this.logger.trace("[ItMap] : _getCommonLayerParams - visibility : " + itlayerOpts.visible); commonOpts.visibility = itlayerOpts.visible; } if (itlayerOpts.hasOwnProperty("sequence")) { this.logger.trace("[ItMap] : _getCommonLayerParams - position : " + itlayerOpts.sequence); commonOpts.position = itlayerOpts.sequence; } return commonOpts; }; /** * Applies params common to all kind of layers : * opacity, visibility, minZoom, maxZoom * * @param {Gp.LayerOptions} layerOpts - options of the layer * @returns {Object} a itowns Layer constructor options object * * @private */ ItMap.prototype._applyCommonLayerParams = function (layerOpts) { var commonOpts = {}; this.logger.trace("[ItMap] : _applyCommonLayerParams "); if (layerOpts.hasOwnProperty("opacity")) { this.logger.trace("[ItMap] : _applyCommonLayerParams - opacity : " + layerOpts.opacity); commonOpts.opacity = layerOpts.opacity; } if (layerOpts.hasOwnProperty("visibility")) { this.logger.trace("[ItMap] : _applyCommonLayerParams - visibility : " + layerOpts.visibility); commonOpts.visible = layerOpts.visibility; } if (layerOpts.hasOwnProperty("position")) { this.logger.trace("[ItMap] : _applyCommonLayerParams - position : " + layerOpts.position); commonOpts.zIndex = layerOpts.position; } /* TODO à compléter if (layerOpts.hasOwnProperty("maxZoom") && layerOpts.maxZoom >= 0 && layerOpts.maxZoom <= 20 ) { var minRes = this._getResolutionFromZoomLevel(layerOpts.maxZoom) ; this.logger.trace("[Ol] : _applyCommonLayerParams - minRes : " + minRes) ; commonOpts.minResolution = minRes ; } if (layerOpts.hasOwnProperty("minZoom") && layerOpts.minZoom >= 0 && layerOpts.minZoom <= 20 ) { var maxRes = this._getResolutionFromZoomLevel(layerOpts.minZoom) ; this.logger.trace("[Ol] : _applyCommonLayerParams - maxRes : " + maxRes) ; commonOpts.maxResolution = maxRes ; } */ return commonOpts; }; /** * Retrieves max TMSLimits with its id * * @param {String} TMSID - Id of the tileMatrixSet * @returns {Object} TMSLimits - limits of the tileMatrixSet * * @private */ ItMap.prototype._getTMSLimits = function (TMSID) { var TMSlimits; if (TMSID === "PM") { TMSlimits = { 0 : { minTileRow : "0", maxTileRow : "1", minTileCol : "0", maxTileCol : "1" }, 1 : { minTileRow : "0", maxTileRow : "2", minTileCol : "0", maxTileCol : "2" }, 2 : { minTileRow : "0", maxTileRow : "4", minTileCol : "0", maxTileCol : "4" }, 3 : { minTileRow : "0", maxTileRow : "8", minTileCol : "0", maxTileCol : "8" }, 4 : { minTileRow : "0", maxTileRow : "16", minTileCol : "0", maxTileCol : "16" }, 5 : { minTileRow : "0", maxTileRow : "32", minTileCol : "0", maxTileCol : "32" }, 6 : { minTileRow : "0", maxTileRow : "64", minTileCol : "0", maxTileCol : "64" }, 7 : { minTileRow : "0", maxTileRow : "128", minTileCol : "0", maxTileCol : "128" }, 8 : { minTileRow : "0", maxTileRow : "256", minTileCol : "0", maxTileCol : "256" }, 9 : { minTileRow : "0", maxTileRow : "512", minTileCol : "0", maxTileCol : "512" }, 10 : { minTileRow : "0", maxTileRow : "1024", minTileCol : "0", maxTileCol : "1024" }, 11 : { minTileRow : "0", maxTileRow : "2048", minTileCol : "0", maxTileCol : "2048" }, 12 : { minTileRow : "0", maxTileRow : "4096", minTileCol : "0", maxTileCol : "4096" }, 13 : { minTileRow : "0", maxTileRow : "8192", minTileCol : "0", maxTileCol : "8192" }, 14 : { minTileRow : "0", maxTileRow : "16384", minTileCol : "0", maxTileCol : "16384" }, 15 : { minTileRow : "0", maxTileRow : "32768", minTileCol : "0", maxTileCol : "32768" }, 16 : { minTileRow : "0", maxTileRow : "65536", minTileCol : "0", maxTileCol : "65536" }, 17 : { minTileRow : "0", maxTileRow : "131072", minTileCol : "0", maxTileCol : "131072" }, 18 : { minTileRow : "0", maxTileRow : "262144", minTileCol : "0", maxTileCol : "262144" }, 19 : { minTileRow : "0", maxTileRow : "524288", minTileCol : "0", maxTileCol : "524288" }, 20 : { minTileRow : "0", maxTileRow : "1048576", minTileCol : "0", maxTileCol : "1048576" }, 21 : { minTileRow : "0", maxTileRow : "2097152", minTileCol : "0", maxTileCol : "2097152" } }; return TMSlimits; } if (TMSID === "WGS84G") { TMSlimits = { 0 : { minTileRow : 0, maxTileRow : 1, minTileCol : 0, maxTileCol : 2 }, 1 : { minTileRow : 0, maxTileRow : 2, minTileCol : 0, maxTileCol : 4 }, 2 : { minTileRow : 0, maxTileRow : 4, minTileCol : 0, maxTileCol : 8 }, 3 : { minTileRow : 0, maxTileRow : 8, minTileCol : 0, maxTileCol : 16 }, 4 : { minTileRow : 0, maxTileRow : 16, minTileCol : 0, maxTileCol : 32 }, 5 : { minTileRow : 0, maxTileRow : 32, minTileCol : 0, maxTileCol : 64 }, 6 : { minTileRow : 0, maxTileRow : 64, minTileCol : 0, maxTileCol : 128 }, 7 : { minTileRow : 0, maxTileRow : 128, minTileCol : 0, maxTileCol : 256 }, 8 : { minTileRow : 0, maxTileRow : 256, minTileCol : 0, maxTileCol : 512 }, 9 : { minTileRow : 0, maxTileRow : 512, minTileCol : 0, maxTileCol : 1024 }, 10 : { minTileRow : 0, maxTileRow : 1024, minTileCol : 0, maxTileCol : 2048 }, 11 : { minTileRow : 0, maxTileRow : 2048, minTileCol : 0, maxTileCol : 4096 }, 12 : { minTileRow : 0, maxTileRow : 4096, minTileCol : 0, maxTileCol : 8192 }, 13 : { minTileRow : 0, maxTileRow : 8192, minTileCol : 0, maxTileCol : 16384 }, 14 : { minTileRow : 0, maxTileRow : 16384, minTileCol : 0, maxTileCol : 32768 }, 15 : { minTileRow : 0, maxTileRow : 32768, minTileCol : 0, maxTileCol : 65536 }, 16 : { minTileRow : 0, maxTileRow : 65536, minTileCol : 0, maxTileCol : 131072 }, 17 : { minTileRow : 0, maxTileRow : 131072, minTileCol : 0, maxTileCol : 262144 } }; return TMSlimits; } this.logger.trace("[ItMap] : no TMS Limits found for this TMS id"); }; /* Adds a vector Layer to the map * * @param {Object} layerObj - geoportalLayer to add. * @param {Gp.LayerOptions} layerObj.geoportalLayerID - options of the layer * * @private */ ItMap.prototype._addVectorLayer = function (layerObj) { // FIXME : ajout d'un parametre projection pour les donnees var layerId = Object.keys(layerObj)[0]; var layerOpts = layerObj[layerId]; var layer = {}; var layerStyleOptions = layerOpts.styleOptions || {}; var defaultMapOptions = this.mapOptions.defaultFeaturesStyle || {}; var defaultOptions = IMap.DEFAULT_VECTORLAYERS_STYLES; layerOpts.format = layerOpts.format.toLowerCase(); switch (layerOpts.format.toUpperCase()) { case "KML": this.logger.trace("ajout d'une couche KML"); layer.source = new FileSource({ url : layerOpts.url, fetchedData : layerOpts.data, crs : "EPSG:4326", fetcher : Fetcher.xml, parser : KMLParser.parse }); // extractStyles from layerOpts is prioritary (if true, itowns will automatically retrieve the KML style) if (layerOpts.extractStyles === false) { layer.style = { fill : { color : layerStyleOptions.polyFillColor || defaultMapOptions.polyFillColor || defaultOptions.polyFillColor, opacity : layerStyleOptions.polyFillOpacity || defaultMapOptions.polyFillOpacity || defaultOptions.polyFillOpacity }, stroke : { color : layerStyleOptions.strokeColor || defaultMapOptions.strokeColor || defaultOptions.strokeColor, opacity : layerStyleOptions.strokeOpacity || defaultMapOptions.strokeOpacity || defaultOptions.strokeOpacity, width : layerStyleOptions.strokeWidth || defaultMapOptions.strokeWidth || defaultOptions.strokeWidth } }; } break; case "COMPUTE": case "GEOJSON": this.logger.trace("ajout d'une couche GEOJSON"); layer.source = new FileSource({ url : layerOpts.url, fetchedData : layerOpts.data, crs : "EPSG:4326", fetcher : Fetcher.json, parser : GeoJsonParser.parse }); layer.style = { fill : { color : layerStyleOptions.polyFillColor || defaultMapOptions.polyFillColor || defaultOptions.polyFillColor, opacity : layerStyleOptions.polyFillOpacity || defaultMapOptions.polyFillOpacity || defaultOptions.polyFillOpacity }, stroke : { color : layerStyleOptions.strokeColor || defaultMapOptions.strokeColor || defaultOptions.strokeColor, opacity : layerStyleOptions.strokeOpacity || defaultMapOptions.strokeOpacity || defaultOptions.strokeOpacity, width : layerStyleOptions.strokeWidth || defaultMapOptions.strokeWidth || defaultOptions.strokeWidth }, point : { color : layerStyleOptions.pointColor || defaultMapOptions.pointColor || defaultOptions.pointColor, opacity : layerStyleOptions.pointOpacity || defaultMapOptions.pointOpacity || defaultOptions.pointOpacity, radius : layerStyleOptions.pointRadius || defaultMapOptions.pointRadius || defaultOptions.pointRadius } }; break; case "GPX": this.logger.trace("ajout d'une couche GPX"); layer.source = new FileSource({ url : layerOpts.url, fetchedData : layerOpts.data, crs : "EPSG:4326", fetcher : Fetcher.xml, parser : GpxParser.parse }); layer.visible = (layerOpts.visibility === undefined) ? true : layerOpts.visibility; layer.opacity = (layerOpts.opacity === undefined) ? 1 : layerOpts.opacity; layer.style = { stroke : { color : layerStyleOptions.strokeColor || defaultMapOptions.strokeColor || defaultOptions.strokeColor, opacity : layerStyleOptions.strokeOpacity || defaultMapOptions.strokeOpacity || defaultOptions.strokeOpacity, width : layerStyleOptions.strokeWidth || defaultMapOptions.strokeWidth || defaultOptions.strokeWidth } }; break; case "GEORSS": // TODO GeoRSS break; case "WFS": // TODO ??? break; case "DRAWING": // TODO ?? break; default: break; } // le controle geoportalAttribution exploite la propriete _originators if (layerOpts.hasOwnProperty("originators")) { layer._originators = layerOpts.originators; } // set default layerOptions for visibility if none specified layerOpts = this._setDefaultVisibilityOptions(layerOpts); this._layers.push({ id : layerId, obj : layer, options : layerOpts }); var LSControl = this.getLibMapControl("layerswitcher"); // if the LS already exists, we have to save the conf of the layer to add it to the LS if (LSControl) { LSControl._addedLayerConf[layerId] = layerOpts; } // we add the layer and refresh the itowns viewer // this will launch the addedLayer callback (dans "ItMap._onLayerChanged") var vectorLayerOptions = { name : layer.id, transparent : true, addLabelLayer : true, crs : "EPSG:4326", source : layer.source }; if (layer.style) { vectorLayerOptions.style = layer.style; } var vectorLayer = new ColorLayer(layerId, vectorLayerOptions); this.libMap.getGlobeView().addLayer(vectorLayer); }; /* Adds a Raster Layer to the map * * @param {Object} layerObj - raster layer to add. * @param {Gp.LayerOptions} layerObj.geoportalLayerID - options of the layer * * @private */ ItMap.prototype._addRasterLayer = function (layerObj) { var layerId = Object.keys(layerObj)[0]; var layerOpts = layerObj[layerId]; var layerNames; var boundingBox; // itowns needs a bbox to display the layer // if the layer is in PM, the bbox needs to be in planar coordinates if (layerOpts.bbox && layerOpts.projection === "EPSG:3857") { boundingBox = new Extent("EPSG:4326", layerOpts.bbox.left, layerOpts.bbox.right, layerOpts.bbox.bottom, layerOpts.bbox.top).as(layerOpts.projection); } else if (layerOpts.bbox && layerOpts.projection === "EPSG:4326") { boundingBox = new Extent(layerOpts.projection, layerOpts.bbox.left, layerOpts.bbox.right, layerOpts.bbox.bottom, layerOpts.bbox.top); } else if (!layerOpts.bbox && layerOpts.projection === "EPSG:3857") { // world bbox in PM (EPSG:3857) boundingBox = new Extent(layerOpts.projection, -20026376.39, 20026376.39, -20048966.10, 20048966.10); } else { // world bbox in WGS84 (EPSG:4326) boundingBox = new Extent("EPSG:4326", -180, 180, -90, 90); } layerOpts.format = layerOpts.format.toLowerCase(); switch (layerOpts.format.toUpperCase()) { case "WMS" : // FIXME : ajout d'un parametre projection pour les donnees this.logger.trace("ajout d'une couche WMS"); if (layerOpts.layers && Array.isArray(layerOpts.layers)) { // external wms layer case layerNames = layerOpts.layers.toString(); } else if (layerOpts.layers) { // external wms layer case if it the user didnt give an array as layers parameter layerNames = layerOpts.layers; layerOpts.layers = [layerOpts.layers]; } else { // geoportal wms layer case layerNames = layerId; layerOpts.layers = [layerId]; } var layer = {}; layer.type = "color"; layer.id = layerId; layer.title = (layerOpts.title === undefined) ? layerId : layerOpts.title; layer.visible = (layerOpts.visibility === undefined) ? true : layerOpts.visibility; layer.opacity = (layerOpts.opacity === undefined) ? 1 : layerOpts.opacity; if (layerOpts.minZoom) { layer.maxScaleDenominator = this._getResolutionFromZoomLevel(layerOpts.minZoom) / 0.00028; } if (layerOpts.maxZoom) { layer.minScaleDenominator = this._getResolutionFromZoomLevel(layerOpts.maxZoom) / 0.00028; } // itowns only handles EPSG:4326 and EPSG:3857 if (!layerOpts.projection || (layerOpts.projection.toUpperCase() !== "EPSG:4326" && layerOpts.projection.toUpperCase() !== "EPSG:3857")) { // EPSG:4326 by default layerOpts.projection = "EPSG:4326"; } else { // iTowns is case sensitive layerOpts.projection = layerOpts.projection.toUpperCase(); } layer.source = new WMSSource({ protocol : layerOpts.format, version : layerOpts.version || "1.3.0", url : layerOpts.url, name : layerNames, crs : layerOpts.projection, style : layerOpts.styleName || "", heightMapWidth : 256, transparent : true, waterMask : false, featureInfoMimeType : "", dateTime : "", networkOptions : { crossOrigin : "omit" }, updateStrategy : { type : 0, options : {} }, format : layerOpts.outputFormat, zoom : { min : layerOpts.minZoom || 1, max : layerOpts.maxZoom || 21 }, extent : boundingBox }); break; case "WMTS" : this.logger.trace("ajout d'une couche WMTS"); // chargement des options par defaut var lOpts = this._getWMTSDefaultOpts(); // surcharge avec les options utilisateurs for (var opt in layerOpts) { lOpts[opt] = layerOpts[opt]; } layerOpts = lOpts; if (!layerOpts.tileMatrixSetLimits) { layerOpts.tileMatrixSetLimits = this._getTMSLimits(layerOpts.tileMatrixSet); } layer = {}; layer.type = "color"; layer.id = layerId; layer.title = (layerOpts.title === undefined) ? layerId : layerOpts.title; layer.visible = (layerOpts.visibility === undefined) ? true : layerOpts.visibility; layer.opacity = (layerOpts.opacity === undefined) ? 1 : layerOpts.opacity; // set min and max zoom regarding the layerOpts and the TMS Limits var minZoom, maxZoom; if (layerOpts.minZoom && layerOpts.maxZoom) { minZoom = layerOpts.minZoom; maxZoom = layerOpts.maxZoom; } else if (layerOpts.minZoom && !layerOpts.maxZoom) { minZoom = layerOpts.minZoom; maxZoom = Math.max.apply(null, (Object.keys(layerOpts.tileMatrixSetLimits).map(Number))); } else if (!layerOpts.minZoom && layerOpts.maxZoom) { minZoom = Math.min.apply(null, (Object.keys(layerOpts.tileMatrixSetLimits).map(Number))); maxZoom = layerOpts.maxZoom; } else { minZoom = Math.min.apply(null, (Object.keys(layerOpts.tileMatrixSetLimits).map(Number))); maxZoom = Math.max.apply(null, (Object.keys(layerOpts.tileMatrixSetLimits).map(Number))); } // compute max and minScaleDenominator layer.maxScaleDenominator = this._getResolutionFromZoomLevel(minZoom) / 0.00028; layer.minScaleDenominator = this._getResolutionFromZoomLevel(maxZoom) / 0.00028; layer.updateStrategy = {}; // depends on the levelsToLoad option if (layerOpts.levelsToLoad) { layer.updateStrategy = { type : 0, options : { groups : layerOpts.levelsToLoad } }; } else { layer.updateStrategy = { type : 0, options : {} }; }; // itowns only handles EPSG:4326 and EPSG:3857 if (!layerOpts.projection || (layerOpts.projection.toUpperCase() !== "EPSG:4326" && layerOpts.projection.toUpperCase() !== "EPSG:3857")) { // EPSG:4326 by default layerOpts.projection = "EPSG:4326"; } else { // iTowns is case sensitive layerOpts.projection = layerOpts.projection.toUpperCase(); } layer.source = new WMTSSource({ protocol : layerOpts.format.toLowerCase(), version : layerOpts.version, url : layerOpts.url, projection : layerOpts.projection, networkOptions : { crossOrigin : "omit" }, tileMatrixSet : layerOpts.tileMatrixSet, tileMatrixSetLimits : layerOpts.tileMatrixSetLimits, format : layerOpts.outputFormat, name : layerOpts.layer, style : layerOpts.styleName, zoom : { min : minZoom || 1, max : maxZoom || 21 }, extent : boundingBox }); break; default : } if (layer) { // ajout de la version du sdk dans les requêtes image layer.source.url = Helper.normalyzeUrl(layer.source.url, { // eslint-disable-next-line no-undef "gp-sdk" : Gp.sdkVersion }, false); // le controle geoportalAttribution exploite la propriete options.originators if (layerOpts.hasOwnProperty("originators")) { layer.source.attribution = layerOpts.originators; } // set default layerOptions for visibility and opacity if none specified layerOpts = this._setDefaultOpacityOptions(layerOpts); layerOpts = this._setDefaultVisibilityOptions(layerOpts); // on met à jour le tableau des couches this._layers.push({ id : layerId, options : layerOpts, obj : layer }); if (layerOpts.type && layerOpts.type.toUpperCase() === "ELEVATION") { layer.type = "elevation"; // we add the noDataValue if it is given if (layerOpts.noDataValue) { layer.noDataValue = layerOpts.noDataValue; } } else { var LSControl = this.getLibMapControl("layerswitcher"); // if the LS already exists, we have to save the conf of the layer to add it to the LS if (LSControl) { LSControl._addedLayerConf[layerId] = layerOpts; } } // we add the layer and refresh the itowns viewer // this will launch the addedLayer callback (dans "ItMap._onLayerChanged") switch (layer.type.toUpperCase()) { case "ELEVATION" : this.libMap.getGlobeView().addLayer(new ElevationLayer(layer.id, layer)); break; case "COLOR" : this.libMap.getGlobeView().addLayer(new ColorLayer(layer.id, layer)); break; default : }; } }; /** * Adds a mapbox Layer to the globe * * @param {Object} layerObj - vectorLayer layer to add. * @param {Gp.LayerOptions} layerObj.geoportalLayerID - options of the layer * * @private */ ItMap.prototype._addMapBoxLayer = function (layerObj) { var layerId = Object.keys(layerObj)[0]; var layerOpts = layerObj[layerId]; // si les mapbox options ne sont pas données par les options de la couche, // on crée quand même la propriété if (!layerOpts.hasOwnProperty("mapboxOptions") || typeof layerOpts.mapboxOptions === "undefined") { layerOpts.mapboxOptions = {}; } // déclaration des variables style par défaut var _url; var _thumbnail; var _name; var _description; var _urlDefaultOrSelected = layerOpts.url; /* Gestion de l'url selectionnée : // Les options nous donnent l'url du style par defaut. // Mais, il faut aussi gerer le cas où un theme est sélectionné via les options, // car c'est bien l'url du style (ou theme) sélectionné qui doit être utilisé par la suite ! // De plus, on recherche si le style par defaut a été placé dans la liste des themes. // Si le style par defaut n'existe pas dans la liste des themes, on l'ajoute pour simplifier // les traitements ulterieurs... */ if (Array.isArray(layerOpts.styles)) { var foundDefaultStyle = false; // recherche du style par defaut var foundSelectedStyle = false; // recherche du theme sélectionné for (var i = 0; i < layerOpts.styles.length; i++) { var t = layerOpts.styles[i]; // algo assez simpliste... car on compare juste les urls // mais les urls devraient être uniques... if (t.url === layerOpts.url) { // le theme par defaut est dans la liste, // on prend donc en compte les valeurs // "name", "thumbnail", "url", "description" de la liste des // themes (à defaut des options "defaultStyle*") ! foundDefaultStyle = true; } if (t.selected) { // l'url selectionnée devient l'url par defaut _urlDefaultOrSelected = t.url; foundSelectedStyle = true; } } // le style par defaut n'est pas dans la liste, alors on l'ajoute dans // dans la liste des themes... if (!foundDefaultStyle) { _url = layerOpts.url; _thumbnail = layerOpts.defaultStyleThumbnail || null; _name = layerOpts.defaultStyleName || "Style par défaut"; _description = layerOpts.defaultStyleDescription || "Style par défaut"; layerOpts.styles.unshift({ thumbnail : _thumbnail, name : _name, url : _url, description : _description, selected : !foundSelectedStyle }); } } else { // pas de styles spécifiés en options : nous ajouton l'url de la couche comme style par défaut // en réglant le paramètre "selected" à true (seul style, donc selectionné) _url = layerOpts.url; _thumbnail = layerOpts.defaultStyleThumbnail || null; _name = layerOpts.defaultStyleName || "Style par défaut"; _description = layerOpts.defaultStyleDescription || "Style par défaut"; layerOpts.styles = [ { thumbnail : _thumbnail, name : _name, url : _url, description : _description, selected : true } ]; } // Ajout couche Vecteur tuilé par itowns (fx: 2.5 => transparent) var vectorTileSourceOpts = { style : _urlDefaultOrSelected, // filter : function (layer) { // // Array.includes() -> pas compatibilité IE 11 ! // return ["fill", "line"].includes(layer.type); // }, zoom : { min : 2, max : 16 } }; if (layerOpts.sprite) { vectorTileSourceOpts.sprite = layerOpts.sprite; } // affichage des labels associés à la couche à true par défaut if (!layerOpts.showLabels) { layerOpts.showLabels = true; } // set default layerOptions for visibility and opacity if none specified layerOpts = this._setDefaultOpacityOptions(layerOpts); layerOpts = this._setDefaultVisibilityOptions(layerOpts); var vectorTileSource = new VectorTilesSource(vectorTileSourceOpts); var vectorTileLayer = {}; vectorTileLayer = new ColorLayer(layerId, { // FIXME wait for next itowns release to remove this isValidData : function () { return false; }, noTextureParentOutsideLimit : true, addLabelLayer : layerOpts.showLabels, source : vectorTileSource }); // definition de l'opacité et de la visibilité de la couche vectorTileLayer.visible = layerOpts.visibility; vectorTileLayer.opacity = layerOpts.opacity; var LSControl = this.getLibMapControl("layerswitcher"); // if the LS already exists, we have to save the conf of the layer to add it to the LS if (LSControl) { LSControl._addedLayerConf[layerId] = layerOpts; } // on met à jour le tableau des couches this._layers.push({ id : layerId, options : layerOpts, obj : vectorTileLayer }); this.libMap.getGlobeView().addLayer(vectorTileLayer); }; /** * Adds a geoportal Layer to the map * * @param {Object} layerObj - geoportalLayer to add. * @param {Object} layerConf - layer configuration. * @param {Gp.LayerOptions} layerObj.geoportalLayerID - options of the layer * * @private */ ItMap.prototype._addGeoportalLayer = function (layerObj, layerConf) { // FIXME à faire ailleurs var layerId = Object.keys(layerObj)[0]; // FIXME verrue pour gestion projection MNT = IGNF:WGS84... // itowns ne gere que 3857 et 4326 if (layerConf && layerConf.defaultProjection !== "EPSG:3857") { layerConf.defaultProjection = "EPSG:4326"; } // Si on a bien un objet layerConf passé, on ajoute les params spécifiques iTowns if (layerConf) { // on prend la première et unique url layerObj[layerId].url = layerConf.serviceParams.serverUrl[Object.keys(layerConf.serviceParams.serverUrl)[0]]; layerObj[layerId].outputFormat = layerObj[layerId].outputFormat || layerConf.formats[0].name; layerObj[layerId].projection = layerObj[layerId].projection || layerConf.defaultProjection; layerObj[layerId].bbox = layerObj[layerId].bbox || layerConf.globalConstraint.bbox; // Paramètres spécifiques aux couches WMS pour ajout avec iTowns if (layerObj[layerId].format === "WMS") { layerObj[layerId].version = layerObj[layerId].version || layerConf.serviceParams.version; layerObj[layerId].stylesName = layerObj[layerId].stylesName || layerConf.styles; } // Paramètres spécifiques aux couches WMTS pour ajout avec iTowns if (layerObj[layerId].format === "WMTS") { layerObj[layerId].tileMatrixSet = layerObj[layerId].tileMatrixSet || layerConf.wmtsOptions.tileMatrixSetLink; layerObj[layerId].tileMatrixSetLimits = layerObj[layerId].tileMatrixSetLimits || layerConf.wmtsOptions.tileMatrixSetLimits; layerObj[layerId].layer = layerId || layerConf.name; layerObj[layerId].styleName = layerObj[layerId].styleName || layerConf.styles[0].name; } } // Ajout de la couche avec iTowns via l'interface du SDK this._addRasterLayer(layerObj); }; /** * Adds the markers to _markers array * * @param {Array.<Gp.MarkerOptions>} markersOptions - Markers to save in the _markers array * @private */ ItMap.prototype._addMarkers = function (markersOptions) { this.logger.trace("[ItMap] : _addMarkers"); if (!Array.isArray(markersOptions)) { this.logger.info("Can not process markersOptions. It is not an Array."); return; } var mo = null; var ii = 0; for (ii = 0; ii < markersOptions.length; ii++) { mo = markersOptions[ii]; // update _markers array with the marker options saved in case of switch to 2D this._markers.push(mo); } }; /** * set default layerOpts for visibility if none specified * * @param {Object} opts - visibility options * @returns {Object} opts - visibility options * @private */ ItMap.prototype._setDefaultVisibilityOptions = function (opts) { // Dans le cas où aucune visibilité n'est spécifiée if (!opts.hasOwnProperty("visibility") || typeof opts.visibility === "undefined") { // on la règle à "true" par défaut opts.visibility = true; } return opts; }; /** * set default layerOpts for opacity if none specified * * @param {Object} opts - opacity options * @returns {Object} opts - opacity options * @private */ ItMap.prototype._setDefaultOpacityOptions = function (opts) { // Dans le cas où aucune opacité n'est spécifiée if (!opts.hasOwnProperty("opacity") || typeof opts.opacity === "undefined") { // on la règle à 1 par défaut opts.opacity = 1; } return opts; }; /** * Empties _markers array * * @private */ ItMap.prototype._removeMarkers = function () { // empty overlays SDK array this._markers = []; }; /** * Gets the markers options saved in _markers array * @returns {Array} - markers array */ ItMap.prototype.getMarkersOptions = function () { return this._markers; }; /** * Replaces the overlays already saved in _markers with the given markersOptions * * @param {Array.<Gp.MarkerOptions>} markersOptions - Markers to add to the Map. */ ItMap.prototype.setMarkersOptions = function (markersOptions) { // 1 - remove all current overlays this._removeMarkers(); // 2 - add specified overlays this._addMarkers(markersOptions); };