UNPKG

test-github-actions-geoportal-sdk-3d

Version:

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

949 lines (874 loc) 38.2 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 { itownsExtended } from "geoportal-extensions-itowns"; /** * Associate a function to trigger when an event is received. * * @param {String} eventId - The map's event listened. Possible values are : 'loaded', 'failure', 'geolocated', 'located', 'zoomchanged', 'azimuthchanged', 'tiltchanged', 'dragstart', 'drag', 'dragend', 'projectionchanged', 'layerchanged', 'controlchanged'. * * | eventId | description | * |-|-| * | mapLoaded | fired when map has finished loading | * | mapFailure | fired when map has problem loading | * | geolocated | fired when map has finished centering by geolocation | * | located | fired when map has finished centering by geocoding | * | configured | fired when map has finished loading geoportal configuration | * | centerChanged | fired when map center has changed | * | zoomChanged | fired when map zoom has changed | * | azimuthChanged | fired when map orientation has changed | * | tiltChanged | fired when map tilt has changed | * | projectionChanged | fired when map projection has changed | * | layerChanged | fired when map's layer(s) has changed someway | * | controlChanged | fired when map's control(s) has changed | * * @param {Function} action - The function to execute when the event occures. * @param {Object} context - The object that will be used as "this" in the action function */ ItMap.prototype.listen = function (eventId, action, context) { this.logger.trace("[ItMap] : listen..."); // verifications de base de la classe mère if (!IMap.prototype.listen.apply(this, arguments)) { return; } context = context || this; var map = this; var key = null; switch (eventId) { case "mapFailure" : break; case "mapLoaded" : case "located" : case "geolocated" : case "configured" : // handled in IMap break; case "centerChanged" : var callBackCenterChanged = function (itEvent) { var centerChangedEvt = {}; if (!itEvent) { return; } if (itEvent.previous) { centerChangedEvt.oldCenter = { x : itEvent.previous.x, y : itEvent.previous.y }; } if (itEvent.new) { centerChangedEvt.newCenter = { x : itEvent.new.x, y : itEvent.new.y }; } action.call(context, centerChangedEvt); }; key = map.libMap.listen(itownsExtended.GlobeViewExtended.EVENTS.CENTER_CHANGED, callBackCenterChanged); break; case "zoomChanged" : var callbackZoomchange = function (itEvent) { // si le zoom n'a pas changé, on sort if (itEvent.new === itEvent.previous) { return; } action.call(context, { oldZoom : itEvent.previous, newZoom : itEvent.new }); }; key = map.libMap.listen(itownsExtended.GlobeViewExtended.EVENTS.RANGE_CHANGED, callbackZoomchange); break; case "azimuthChanged" : var callbackAzimuthChange = function (itEvent) { if (itEvent.new.heading === itEvent.previous.heading) { return; } action.call(context, { oldAzimuth : itEvent.previous.heading, newAzimuth : itEvent.new.heading }); }; key = map.libMap.listen(itownsExtended.GlobeViewExtended.EVENTS.ORIENTATION_CHANGED, callbackAzimuthChange); break; case "tiltChanged" : var callbackTiltChange = function (itEvent) { if (itEvent.new.tilt === itEvent.previous.tilt) { return; } action.call(context, { oldTilt : itEvent.previous.tilt, newTilt : itEvent.new.tilt }); }; key = map.libMap.listen(itownsExtended.GlobeViewExtended.EVENTS.ORIENTATION_CHANGED, callbackTiltChange); break; case "projectionChanged" : // TODO : interet ? break; case "layerChanged" : var callbackLayerAdded = function (itevt) { var ladded = itevt; var layerIndex; var layerOpts = map._getLayerOpts(ladded.layerId); var itColorLayer = map.libMap.getColorLayerById(Object.keys(layerOpts)[0]); if (itColorLayer && itColorLayer.sequence >= 0) { layerIndex = itColorLayer.sequence; } else { // if itColorLayer is not defined, the layer is an MNT : we set its layerIndex to -1 layerIndex = -1; } if (!layerOpts) { map.logger.trace("[ItMap] listen : enregistrement d'une couche 'inconnue'."); // layerOpts = map._registerUnknownLayer(ladded) ; } // if itColorLayer is undefined, it is an MNT : the sequence is set to -1 action.call(context, { layerAdded : layerOpts, position : layerIndex }); }; key = map.libMap.listen(itownsExtended.GlobeViewExtended.EVENTS.LAYER_ADDED, callbackLayerAdded); map._registerEvent(key, eventId, action, context); var callbackLayerRemoved = function (itevt) { var lremoved = itevt; var layerOpts = map._getLayerOpts(lremoved.layerId) || map._getLayerOpts(lremoved.layerId, map._layersRemoved); action.call(context, { layerRemoved : layerOpts }); }; key = map.libMap.listen(itownsExtended.GlobeViewExtended.EVENTS.LAYER_REMOVED, callbackLayerRemoved); map._registerEvent(key, eventId, action, context); // abonnement à un changement de propriete sur chaque couche for (var obsProperty in ItMap.LAYERPROPERTIES) { map.libMap.getColorLayers().forEach(function (itLayer) { var layerOpts = map._getLayerOpts(itLayer.id); var callbackLayerChanged = function (itevt) { var layerEvtinfos = map.libMap.getLayerEventInfos(itevt); var k = layerEvtinfos.propertyName; var oldItObj = {}; oldItObj[k] = layerEvtinfos.previousValue; var oldCommonProp = map._getCommonLayerParams(oldItObj); var newItObj = {}; newItObj[k] = layerEvtinfos.newValue; var newCommonProp = map._getCommonLayerParams(newItObj); action.call(context, { property : ItMap.LAYERPROPERTIES[k], oldValue : oldCommonProp[ItMap.LAYERPROPERTIES[k]], newValue : newCommonProp[ItMap.LAYERPROPERTIES[k]], layerChanged : layerOpts }); }; var type = (obsProperty === "visible") ? itownsExtended.GlobeViewExtended.EVENTS.VISIBLE_PROPERTY_CHANGED : (obsProperty === "opacity") ? itownsExtended.GlobeViewExtended.EVENTS.OPACITY_PROPERTY_CHANGED : itownsExtended.GlobeViewExtended.EVENTS.SEQUENCE_PROPERTY_CHANGED; key = map.libMap.addLayerListener(itLayer, type, callbackLayerChanged); map._registerEvent(key, eventId, action, context); }); }; key = null; break; case "controlChanged" : break; default : this.logger.info("unhandled event : " + eventId); } ; if (key) { // ajout de l'evenement au tableau des événements this._registerEvent(key, eventId, action, context); } }; /** * Cancel an event listening. * * @param {String} eventId - The map's event to forget. Possible values are : * * | eventId | description | * |-|-| * | mapLoaded | fired when map has finished loading | * | mapFailure | fired when map has problem loading | * | geolocated | fired when map has finished centering by geolocation | * | located | fired when map has finished centering by geocoding | * | configured | fired when map has finished loading geoportal configuration | * | centerChanged | fired when map center has changed | * | zoomChanged | fired when map zoom has changed | * | azimuthChanged | fired when map orientation has changed | * | tiltChanged | fired when map tilt has changed | * | projectionChanged | fired when map projection has changed | * | layerChanged | fired when map's layer(s) has changed someway | * | controlChanged | fired when map's control(s) has changed | * * @param {Function} action - The function associated to the event. */ ItMap.prototype.forget = function (eventId, action) { this.logger.trace("[ItMap] : forget..."); // verifications de base de la classe mère if (!IMap.prototype.forget.apply(this, arguments)) { return; } // on cherche l'enregistrement de l'evenement var rEvents = this._events[eventId]; if (!rEvents) { this.logger.info("nothing to forget for : " + eventId); return; } var evKey = null; for (var i = rEvents.length - 1; i >= 0; i--) { if (rEvents[i].action === action) { evKey = rEvents[i].key; rEvents.splice(i, 1); this.logger.trace("[ItMap] : forgetting : " + eventId + " (" + evKey + ")"); this.libMap.forgetByKey(evKey); } } }; /** * Action triggered when map is clicked * * @param {Object} evt - evenement sent on map click * * @private */ ItMap.prototype._onMapClick = function (evt) { this.logger.trace("[ItMap] : _onMapClick..."); this._removeInfoDivs(); var visibleFeatures = this.libMap.getFeaturesAtMousePosition(evt); if (visibleFeatures.length === 0) { // no visible features return; } var content = this._features2html(visibleFeatures); // Affichage des features. var position = { x : evt.layerX, y : evt.layerY }; this._displayInfo(position, content.innerHTML); }; /** * Remove all the feature info PopUp displayed on the map. * * @private */ ItMap.prototype._removeInfoDivs = function () { var featureInfoDivs = document.getElementsByClassName("gp-feature-info-div-it"); if (featureInfoDivs.length > 0) { for (var i = 0; i < featureInfoDivs.length; i++) { featureInfoDivs[i].parentNode.removeChild(featureInfoDivs[i]); } } }; /** * Gets HTML content from features array * * @param {Array} features - itowns features Array * @returns {String} HTML content. * * @private */ ItMap.prototype._features2html = function (features) { this.logger.trace("[ItMap] : _features2html..."); var content = document.createElement("div"); features.forEach(function (f) { var props = {}; if (f.geometry.properties) { props = f.geometry.properties; } var nameDiv; nameDiv = document.createElement("div"); nameDiv.className = "gp-att-name-div"; if (props.hasOwnProperty("name")) { nameDiv.innerHTML = props.name; content.appendChild(nameDiv); } if (props.hasOwnProperty("description")) { var descDiv = document.createElement("div"); descDiv.className = "gp-att-description-div"; descDiv.innerHTML = props["description"]; content.appendChild(descDiv); } var p = null; var others = false; var oDiv = null; var ul = null; var li = null; for (p in props) { if (p === "name" || p === "description" || p === "styleUrl" || p === "styleHash") { continue; } // patch en attendant que les proprietes de style et autres attributs indesirables soient dissocies des autres proprietes dans itowns if (p === "stroke" || p === "stroke-opacity" || p === "stroke-width" || p === "fill" || p === "fill-opacity" || p === "_idx" || p === "_meshIdx" || p === "coordTimes" || p === "style") { continue; } if (!others) { oDiv = document.createElement("div"); oDiv.className = "gp-att-others-div"; ul = document.createElement("ul"); others = true; } li = document.createElement("li"); var span = document.createElement("span"); span.className = "gp-attname-others-span"; span.innerHTML = p + " : "; li.appendChild(span); li.appendChild(document.createTextNode(props[p])); ul.appendChild(li); } if (ul) { oDiv.appendChild(ul); content.appendChild(oDiv); } }, this); return content; }; /** * Info Popup creation and display * * @param {Object} position - position on the screen where to display the popUp * @param {HTMLElement} content - content to display * * @private */ ItMap.prototype._displayInfo = function (position, content) { this.logger.trace("[ItMap] : _displayInfo..."); // Affichage des features. var element = document.createElement("div"); element.className = "gp-feature-info-div-it"; var closer = document.createElement("input"); closer.type = "button"; closer.className = "gp-styling-button closer"; closer.onclick = function (evt) { element.parentNode.removeChild(element); return false; }; closer.addEventListener("mouseup", function (evt) { // to not fire _onMapClick function evt.stopPropagation(); }, false); var contentDiv = document.createElement("div"); var mapDiv = document.getElementById(this.div.id); contentDiv.className = "gp-features-content-div-it"; contentDiv.innerHTML = content; element.appendChild(contentDiv); element.appendChild(closer); // You can use native DOM methods to insert the fragment: mapDiv.appendChild(element); var posX = mapDiv.offsetWidth / 2 - parseInt(element.offsetWidth, 10) / 2; var posY = mapDiv.offsetHeight / 2 - parseInt(element.offsetHeight, 10) / 2; element.style.left = posX + "px"; element.style.top = posY + "px"; }; /** * 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, projection : "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 "GEOJSON": this.logger.trace("ajout d'une couche GEOJSON"); layer.source = new FileSource({ url : layerOpts.url, projection : "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 } }; break; case "GPX": this.logger.trace("ajout d'une couche GPX"); layer.source = new FileSource({ url : layerOpts.url, projection : "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; } if (layer) { // le controle geoportalAttribution exploite la propriete _originators if (layerOpts.hasOwnProperty("originators")) { layer._originators = layerOpts.originators; } // Dans le cas où aucune visibilité n'est spécifiée if (!layerOpts.hasOwnProperty("visibility") || typeof layerOpts.visibility === "undefined") { // on la règle à "true" par défaut layerOpts.visibility = true; } 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, projection : "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, projection : 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) { // le controle geoportalAttribution exploite la propriete options.originators if (layerOpts.hasOwnProperty("originators")) { layer.source.attribution = layerOpts.originators; } // Dans le cas où aucune opacité n'est spécifiée if (!layerOpts.hasOwnProperty("opacity") || typeof layerOpts.opacity === "undefined") { // on la règle à 1 par défaut layerOpts.opacity = 1; } // Dans le cas où aucune visibilité n'est spécifiée if (!layerOpts.hasOwnProperty("visibility") || typeof layerOpts.visibility === "undefined") { // on la règle à "true" par défaut layerOpts.visibility = true; } // 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é _urlDefaultOrSelected = layerOpts.url; 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 vectorTileSource = new VectorTilesSource({ style : _urlDefaultOrSelected, filter : function (layer) { // Array.includes() -> pas compatibilité IE 11 ! return ["fill", "line"].includes(layer.type); }, zoom : { min : 2, max : 16 } }); var vectorTileLayer = {}; vectorTileLayer = new ColorLayer(layerId, { // FIXME wait for next itowns release to remove this isValidData : function () { return false; }, source : vectorTileSource // fx : 2.5, }); // definition de l'opacité et de la visibilité de la couche vectorTileLayer.visible = (layerOpts.visibility === undefined) ? true : layerOpts.visibility; vectorTileLayer.opacity = (layerOpts.opacity === undefined) ? 1 : 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 dans autoconf... // 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) { layerObj[layerId].url = layerConf.getServerUrl(layerConf.apiKeys[0]); layerObj[layerId].outputFormat = layerObj[layerId].outputFormat || layerConf.getDefaultFormat(); 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.getTMSID(); layerObj[layerId].tileMatrixSetLimits = layerObj[layerId].tileMatrixSetLimits || layerConf.wmtsOptions.tileMatrixSetLimits; layerObj[layerId].layer = layerId || layerConf.getName(); layerObj[layerId].styleName = layerObj[layerId].styleName || layerConf.getStyles()[0].name; } } // Ajout de la couche avec iTowns via l'interface du SDK this._addRasterLayer(layerObj); };