Retour à la documentation
define([
"dojo/_base/declare", "dijit/_WidgetBase", "dojo/_base/lang",
"dojo/_base/array", "dojo/Evented", "esri/request",
"spw/api/ClusterLayer","spw/api/HeatLayer", "dojo/dom-construct",
"spw/api/ConfigLoader", "spw/api/MapServiceLayer", "dojo/on", "dojo/dom-style",
"dojo/sniff", "dojo/aspect", "dojo/Deferred"
],
function(declare, _WidgetBase, lang, array, Evented, esriRequest,
ClusterLayer, HeatLayer, domConstruct, ConfigLoader, MapServiceLayer, on, domStyle,
has, aspect, Deferred) {
var MapService = null;
/**
* @class spw.api.MapService
* @classdesc Classe abstraite à partir de laquelle il est possible de créer des services affichables sur la carte
*/
MapService = declare("spw.api.MapService", [_WidgetBase, Evented], /** @lends spw.api.MapService.prototype */{
/**
* Le serviceId doit être unique dans le fichier de configuration et représente l'identifiant du service.
* @type String
*/
serviceId: null,
/**
* Le label correspond au nom du service qui sera affiché dans l'application.
* @type String
*/
label: null,
/**
* Le type de service. AGS_TILED, AGS_DYNAMIC, FEATURE_LAYER, WMS, STATIC_IMAGE.
* @type String
*/
type: null,
/**
* L'URL vers les données descriptives de ce service.
* @type String
*/
metadataUrl:null,
/**
* Cet object permet de fixer la taille de la popup si on ne désire pas ouvrir le lien 'metadataUrl' dans une nouvelle fenêtre.
* @type String
* @property metadataPopup.width {Number} largeur en pixel
* @property metadataPopup.height {Number} hauteur en pixel
*/
metadataPopup:null,
/**
* L'url du service.
* @type String
*/
url: null,
/**
* Active/désactive le caching des images du service côté client.
* @type Boolean
*/
disableClientCache: true,
/**
* Ce paramètre permet de déterminer si un service est par défaut visible quand celui-ci est ajouté sur la carte.
* @type Boolean
*/
visible: false,
/**
* Spécifie si le service possède une légende et si celle-ci doit être chargée.
* @type Boolean
*/
hasLegend: true,
/**
* L'opacité initiale du service [0;100].
* @type Number
*/
alpha: 100,
/**
* L'opacité pour un fond de plan de type Voyage dans le temps [0;1].
* @type Number
*/
alphaTimer: 1,
/**
* Ce service est-il sélectionné dans le BaseMapChooser
* @type {Boolean}
*/
checked: false,
/**
* Cette propriété permet de définir un tableau afin de pouvoir configurer de façon spécifique les couches du service de cartes.
* @type Array.<Object>
*/
layers: null,
/**
* Permet d'établir l'ordre dans lequel le layer sera dessiné (order supérieur = layer au-dessus)
* @type {Integer}
*/
order: null,
/**
* Ce paramètre permet de définir si le service est identifiable. Si c'est le cas, toutes les couches de ce service seront identifiables à moins qu'une configuration spécifique soit définie au niveau du tableau 'layers'.
* @type Boolean
*/
identifiable: true,
/**
* La liste des attributs à ignorer lors de l'affichage des résultats de l'identify.
* @type Array.<String>
*/
ignoreAttributes: null,
/**
* Permet au service de s'afficher en dessous de son échelle minimum définie en redéfinissant la dernière image disponible. Pour s'activer, le serveur fournissant l'image doit renvoyer une erreur 404.
* @type Boolean
*/
resampling: true,
/**
* Permet de déterminer si le service doit être ajouté par défaut (lors du chargement du viewer) à la carte.
* @type Boolean
*/
toLoad: false,
/**
* Echelle maximum du service.
*/
maxScale: -1,
/**
* Echelle minimum du service.
*/
minScale: -1,
/**
* Permet de déterminer si le service est visible dans la toc ou non
* @type {Boolean}
*/
inTOC: true,
/**
* Indique si le service est un fond de plan.
* @type Boolean
*/
isBaseMap: false,
/**
* Indique si le service est chargé.
* @type Boolean
*/
loaded: false,
/**
* Indique si le service est en erreur.
* @type Boolean
*/
inError: false,
errorMessage: null,
/**
* Indique si le service a été ajouté à la carte.
* @type Boolean
*/
added: false,
/**
* Indique si les légendes du services sont chargées.
* @type Boolean
*/
legendLoaded: false,
/**
* Les objets layers encapsulés. Il s'agit des couches définies dans le service.
* @type Array.<spw.api.MapServiceLayer>
*/
mapServiceLayers: null,
/**
* Permet de fournir une "where clause" par couche du service. Voir "layerDefinition" Esri.
* @type Array.<String>
*/
layerDefinitions: [],
/**
* Référence vers l'objet original représentant le service Esri.
* @type esri.Layer
*/
layer: null,
/**
* Définit les niveaux auquels le service doit s'afficher.
* @type Array.<Number>
*/
displayLevels: null,
/**
*
* @type Boolean
*/
changeVisibility: true,
/**
* TODO
*/
heatLayers: null,
/**
* TODO
*/
clusterLayers: null,
/**
* Indique si le service est sécurisé via le système de token ArcGIS Server et s'il doit passer par le serveur de sécurisation pour les différents appels REST.
* @type Boolean
*/
tokenSecured: false,
/**
* Indique si le service est sécurisé via le réseau (intranet) et s'il doit passer par le serveur de sécurisation pour les différents appels REST.
* @type Boolean
*/
networkSecured: false,
_propertiesToKeep: [
'serviceId', 'label', 'alpha', 'toLoad', 'visible', 'type', 'metadataUrl', 'metadataPopup',
'url', 'hasLegend', 'checked', 'order', 'inTOC', 'identifiable', 'expanded', 'layersExpanded', 'description', 'ruleLabel'
],
visibleLayersIds: null,
visibleLayers: null,
removable: null,
/**
* Permet d'appliquer un filtre niveaux de gris sur le service
*/
grayscale: null,
expanded: null,
layersExpanded: null,
mapName: null,
/**
* Le construteur ne doit pas être appelé directement, il faut passer par la classe MapServiceFactory
* pour instancier un service
* @classdesc Classe encapsulant les types standard de "Layers" Esri.
* @constructs
* @param {Object} service
* @param {String|Number} service.serviceId {@link spw.api.MapService#serviceId}
* @param {String} service.label {@link spw.api.MapService#label}
* @param {String} service.url {@link spw.api.MapService#url}
* @param {Boolean} service.disableClientCache {@link spw.api.MapService#disableClientCache}
* @param {Boolean} service.visible {@link spw.api.MapService#visible}
* @param {Boolean} service.hasLegend {@link spw.api.MapService#hasLegend}
* @param {Number} service.alpha {@link spw.api.MapService#alpha}
* @param {Array.<Object>} service.layers {@link spw.api.MapService#layers}
* @param {Boolean} service.identifiable {@link spw.api.MapService#identifiable}
* @param {Array.<String>} service.ignoreAttributes {@link spw.api.MapService#ignoreAttributes}
* @param {Boolean} service.resampling {@link spw.api.MapService#resampling}
* @param {Object} service.wmsParameters {@link spw.api.MapService#wmsParameters}
* @param {Boolean} service.toLoad {@link spw.api.MapService#toLoad}
*/
constructor: function(service) {
this.inError = false;
lang.mixin(this, {events: MapService.events});
this.mapServiceLayers = {};
this.heatLayers = [];
this.clusterLayers = [];
service.layersExpanded = service.layersExpanded || {};
},
postMixInProperties: function() {
var viewerConfig = ConfigLoader.getInstance().get('viewer');
if (this.url && this.url.indexOf(viewerConfig.secureServerUrl) != 0) {
if(this.tokenSecured && viewerConfig.secureServerUrl){
this.url = viewerConfig.secureServerUrl + "?service=" + this.url;
} else if(this.networkSecured && viewerConfig.secureServerUrl){
this.url = viewerConfig.secureServerUrl + "?noToken=true&service=" + this.url;
}
}
if(this.range){
if(typeof(this.range[0]) != "undefined" && typeof(this.range[1]) != "undefined"){
this.displayLevels = new Array();
for(var i=this.range[0];i<this.range[1]+1;i++){
this.displayLevels.push(i);
}
}
}
this.createMapLayer();
this.own(
on(this.spwMap, this.spwMap.events.LayerReorder, lang.hitch(this, function(event) {
if (this.get('layer') == null || event.layer == null) {
return;
}
if (event.layer.id === this.get('layer').id) {
this.order = event.index + 1;
}
}))
);
},
reset: function(esriMap) {
this.removeFromMap(esriMap);
this.loaded = false;
this.inError = false;
this.errorMessage = null;
this.added = false;
this.createMapLayer();
if (this.mapDataControllerService) {
this.mapDataControllerService = null;
}
},
/**
* Crée le layer Esri sur base de la configuration du MapService.
*/
createMapLayer: function(){
this._enableGrayscaleForIE();
if(this.layer && !this.get("isBaseMap")){
this.layer.on("load", lang.hitch(this, this.layerLoaded));
}
else{
this.layer.on("load", lang.hitch(this, this.baseMapLayerLoaded));
}
if(this.layer) {
this.layer.on("error", lang.hitch(this, this.layerError));
}
},
addClusterAndHeatLayers: function(){
var canvas = document.createElement("canvas");
if(this.layers && canvas && canvas.getContext){
for(var i=0;i<this.layers.length;i++){
if(this.layers[i].clusterLayerOptions){
var options = lang.mixin({"id":this.serviceId+"_cluster"+this.layers[i].layerId,"fields":[],"serviceURL":this.url+"/"+this.layers[i].layerId,"visible":false, "originService": this, "originLayer": this.layers[i]},this.layers[i].clusterLayerOptions);
var clusterLayer = new ClusterLayer(options);
var clusterLayerInfo = {"clusterLayer":clusterLayer,"layerId":this.layers[i].layerId,"options":options};
this.clusterLayers.push(clusterLayerInfo);
this.layers[i].clusterLayer = clusterLayer;
}
if(this.layers[i].heatLayerOptions){
var options = lang.mixin({"id":this.serviceId+"_heat"+this.layers[i].layerId,"serviceURL":this.url+"/"+this.layers[i].layerId,"visible":false, "originService": this, "originLayer": this.layers[i]},this.layers[i].heatLayerOptions);
// TODO: new HeatLayer...mais faut réécrire HeatLayer.js alors...
var heatLayer = new spw.api.HeatLayer(options);
var heatLayerInfo = {"heatLayer":heatLayer,"layerId":this.layers[i].layerId,"options":options};
this.heatLayers.push(heatLayerInfo);
this.layers[i].heatLayer = heatLayer;
}
}
}
},
/**
* Ajoute le service courant à la carte.
* @param {esri.Map} esriMap l'objet carte d'esri.
*/
addToMap: function(esriMap) {
if(!esriMap){
return;
}
if(this.get('isBaseMap')) {
esriMap.addLayer(this.get('layer'), 0);
return;
}
this.get('layer').visible = this.get('visible') != null ? this.get('visible') : true;
var handler = null;
handler = esriMap.on("layer-add-result", lang.hitch(this, function(evt) {
if(evt.layer == this.get('layer')){
if(handler) {
handler.remove();
}
this.set("added", true);
if (this.spwMap) {
this.spwMap.mapServiceAddedToMap(this);
}
}
}));
esriMap.addLayer(this.get('layer'));
for(var i = 0; i < this.clusterLayers.length; i++) {
esriMap.addLayer(this.clusterLayers[i].clusterLayer);
}
for(var i = 0; i < this.heatLayers.length; i++) {
esriMap.addLayer(this.heatLayers[i].heatLayer);
}
},
/**
* Supprime le service courant de la carte.
* @param {esri.Map} esriMap l'objet carte d'esri.
*/
removeFromMap: function(esriMap){
if (this.get('layer')) {
esriMap.removeLayer(this.get('layer'));
}
for(var i=0;i<this.clusterLayers.length;i++){
esriMap.removeLayer(this.clusterLayers[i].clusterLayer);
}
for(var i=0;i<this.heatLayers.length;i++){
esriMap.removeLayer(this.heatLayers[i].heatLayer);
}
},
/**
* Appelée lorsqu'un service est en erreur.
* @param error L'erreur déclenchée par le service.
*/
layerError: function(error) {
if (this.get('inError')) {
return;
}
if (this.get('loaded')) {
if (error.error && error.error.message && error.error.message.indexOf('Unable to load tile') > -1) {
return;
}
}
if (typeof(error) === 'string') {
this.set('errorMessage', error);
}
this.set('inError', true);
this.emit(this.events.MapServiceError, this, error);
},
/**
* Appelé lorsque le layer principal est chargé avec succés.
* @param loadedEvent
*/
layerLoaded: function(loadedEvent) {
array.forEach(loadedEvent.layer.layerInfos, lang.hitch(this, function(layerInfo){
this._mergeLayerInfo(layerInfo);
}));
this._afterLayerLoaded();
},
_enableGrayscaleForIE: function() {
// var proxy = this.spwMap.spwViewer.get('grayscaleProxy');
//
// // IE ou Edge
// if (has('ie') < 11) {
// if (this.layer.getTileUrl) {
// var old = this.layer.getTileUrl;
// this.layer.getTileUrl = lang.hitch(this, function() {
// var url = old.apply(this.layer, arguments);
// return this.grayscale ? (proxy + '?' + url) : url;
// });
// }
// else if (this.layer.getImageUrl) {
// var old = this.layer.getImageUrl;
// this.layer.getImageUrl = lang.hitch(this, function(e, w, h, cb) {
// lang.hitch(this.layer, old)(e, w, h, function(url) {
// cb(this.grayscale ? (proxy + '?' + url) : url);
// });
// });
// }
// }
},
/**
* Appelé après la méthode layerLoaded
*/
_afterLayerLoaded: function() {
this.refreshLayersVisibility();
if(this.maxScale == -1 || this.minScale == -1){
this._updateScale();
} else {
this.get('layer').setScaleRange(this.minScale,this.maxScale);
}
this.set('loaded', true);
this.emit(this.events.MapServiceLoaded, this);
if(this.spwMap){
this.spwMap.mapServiceLoaded(this);
}
if(this.hasLegend){
this.loadLegend();
}
if(this.copyright){
this.layer.copyright = this.copyright;
}
this.set('grayscale', this.grayscale);
},
_mergeLayerInfo: function(layerInfo){
// Get layer configuration if present
var layerConfig = {};
if(this.layers) {
for(var i = 0; i < this.layers.length; i++) {
if(this.layers[i].layerId == layerInfo.id) {
layerConfig = this.layers[i];
// Apply min and max scales to associated heat and cluster layers
// if(typeof(layerInfo.minScale) != "undefined" && typeof(layerInfo.maxScale) != "undefined") {
// if(typeof(layerConfig.heatLayer) != "undefined" && typeof(layerConfig.heatLayerOptions.minScale) == "undefined" && typeof(layerConfig.heatLayerOptions.maxScale) == "undefined"){
// layerConfig.heatLayer.setMinScale(layerInfo.minScale);
// layerConfig.heatLayer.setMaxScale(layerInfo.maxScale);
// }
// if(typeof(layerConfig.clusterLayer) != "undefined" && typeof(layerConfig.clusterLayerOptions.minScale) == "undefined" && typeof(layerConfig.clusterLayerOptions.maxScale) == "undefined"){
// layerConfig.clusterLayer.setMinScale(layerInfo.minScale);
// layerConfig.clusterLayer.setMaxScale(layerInfo.maxScale);
// }
// }
break;
}
}
}
if(typeof(layerInfo.identifiable) != 'undefined') {
layerConfig.identifiable = layerInfo.identifiable;
}
if (this.visibleLayers) {
layerConfig.defaultVisibility = this.visibleLayers.find(function(lId){ return lId == layerInfo.id; }) != undefined;
}
// debugger;
// if(!this.checkIfLayerIsAlreadyContained(layerInfo) || this.isBaseMap){
this.mapServiceLayers[layerInfo.id] = new this.MapServiceLayer(lang.mixin(this._layerInfoToLayer(layerInfo),{"identifiable":this.identifiable},layerConfig));
if(this.mapServiceLayers[layerInfo.parentLayerId] != undefined){
this.mapServiceLayers[layerInfo.parentLayerId].addChildLayer(this.mapServiceLayers[layerInfo.id]);
}
// }
},
getLayerExtent: function(layerId) {
var def = new Deferred();
def.resolve(null);
return def;
},
checkIfLayerIsAlreadyContained: function(layer) {
var alreadyContained = false;
if(this.mapServiceLayers && Object.keys(this.mapServiceLayers).length > 0){
array.forEach(Object.keys(this.mapServiceLayers), lang.hitch(this, function(key){
// debugger;
if(this.mapServiceLayers[key].name == layer.name){
alreadyContained = true;
}
}))
}
return alreadyContained;
},
_setGrayscaleAttr: function(value) {
this.grayscale = value;
if (this.layer == null) {
return;
}
if (this.layer.loaded) {
if (this.layer.getMap() == null) {
var h = on(this.spwMap, this.spwMap.events.LayerAdd, lang.hitch(this, function(evt) {
if (evt.layer === this.layer) {
this._setGrayscale(evt.layer.getNode(), value);
// if (has('ie') || (window.navigator.appName === 'Netscape' && window.navigator.userAgent.indexOf('Trident') > -1)) {
// this.layer.refresh();
// }
h.remove();
}
}));
}
else {
this._setGrayscale(this.layer.getNode(), value);
// if (has('ie') || (window.navigator.appName === 'Netscape' && window.navigator.userAgent.indexOf('Trident') > -1)) {
// this.layer.refresh();
// }
}
}
else {
on.once(this.layer, 'load', lang.hitch(this, function() {
if (this.layer.getMap() == null) {
var h = on(this.spwMap, this.spwMap.events.LayerAdd, lang.hitch(this, function(evt) {
if (evt.layer === this.layer) {
this._setGrayscale(evt.layer.getNode(), value);
// if (has('ie') || (window.navigator.appName === 'Netscape' && window.navigator.userAgent.indexOf('Trident') > -1)) {
// this.layer.refresh();
// }
h.remove();
}
}));
}
else {
this._setGrayscale(this.layer.getNode(), value);
// if (has('ie') || (window.navigator.appName === 'Netscape' && window.navigator.userAgent.indexOf('Trident') > -1)) {
// this.layer.refresh();
// }
}
}));
}
},
_setGrayscale: function(node, value) {
if (node == null) {
return;
}
if (value == null) {
// domStyle.set(node, '-webkit-filter', '');
// domStyle.set(node, '-moz-filter', '');
// domStyle.set(node, '-ms-filter', '');
// domStyle.set(node, '-o-filter', '');
// domStyle.set(node, 'filter', '');
domStyle.set(node, 'filter', '');
}
else {
// domStyle.set(node, '-webkit-filter', 'grayscale(' + (value / 100) + ')');
// domStyle.set(node, '-moz-filter', 'grayscale(' + (value / 100) + ')');
// domStyle.set(node, '-ms-filter', 'grayscale(' + (value / 100) + ')');
// domStyle.set(node, '-o-filter', 'grayscale(' + (value / 100) + ')');
domStyle.set(node, 'filter', 'grayscale(' + (value / 100) + ')');
// domStyle.set(node, 'filter', 'gray');
}
},
/**
* Appelé lorsque le layer principal d'une baseMap est chargé avec succès.
* @param loadedEvent
*/
baseMapLayerLoaded: function(loadedEvent) {
if(this.copyright) {
this.layer.copyright = this.copyright;
}
else{
this.layer.copyright = this.layer.copyright;
}
if(this.maxScale != null && this.maxScale > -1) {
this.layer.maxScale=this.maxScale;
}
if(this.minScale != null && this.minScale > -1) {
this.layer.minScale=this.minScale;
}
if (loadedEvent) {
array.forEach(loadedEvent.layer.layerInfos, lang.hitch(this, function(layerInfo){
this._mergeLayerInfo(layerInfo);
}));
}
this.refreshLayersVisibility();
this.set('grayscale', this.grayscale);
},
/**
* Met à jour les échelles du service courant en fonction des sous layers chargés.
*/
_updateScale: function() {
var greaterMaxScale = -1;
var greaterMinScale = -1;
var mapServiceLayers = this.getParentMapServiceLayers();
if(mapServiceLayers && mapServiceLayers.length > 0){
array.some(mapServiceLayers, lang.hitch(this, function(subLayer){
//Compute min scale
var minScale = subLayer.get('minScale');
if (minScale == null) {
minScale = 0;
}
if(greaterMinScale == -1 || minScale === 0 || (greaterMinScale > 0 && minScale > greaterMinScale)){
greaterMinScale = minScale;
}
//Compute max scale
var maxScale = subLayer.get('maxScale');
if (maxScale == null) {
maxScale = 0;
}
if(greaterMaxScale == -1 || (maxScale >= 0 && maxScale < greaterMaxScale)) {
greaterMaxScale = maxScale;
}
//If scales are at max possible value, break loop
return (greaterMaxScale === 0 && greaterMinScale === 0);
}));
}
else if(!isNaN(this.layer.minScale) && !isNaN(this.layer.maxScale)) {
greaterMaxScale = this.layer.maxScale;
greaterMinScale = this.layer.minScale;
}
if(this.maxScale != -1){
greaterMaxScale = this.maxScale;
}
if(this.minScale != -1){
greaterMinScale = this.minScale;
}
this.set('maxScale', greaterMaxScale);
this.set('minScale', greaterMinScale);
this.get('layer').setScaleRange(greaterMinScale,greaterMaxScale);
if(greaterMinScale == -1 || greaterMaxScale == -1){
console.error("Error when computing map service scales.");
}
},
/**
* Charge les légendes du service.
*/
loadLegend: function() {
if (this.get('url') == null || this.get('inError')) {
this.legendLoadedSuccess();
}
else {
this._requestLegend(this.get('url'))
}
},
_requestLegend: function(legendUrl) {
legendUrl += "/legend";
esriRequest({
url: legendUrl,
content: {
f: "json"
},
handleAs: "json",
callbackParamName: "callback"
}).then(lang.hitch(this, this.legendLoadedSuccess), lang.hitch(this, this.legendLoadedError));
},
/**
* Handler appelé lorsque les légendes du services sont chargées.
* @param response Object contenant les informations des légendes.
*/
legendLoadedSuccess: function(response) {
if (response) {
array.forEach(response.layers, lang.hitch(this, function(layer){
if(this.mapServiceLayers[layer.layerId] && layer.legend && layer.legend.length > 0){
this.mapServiceLayers[layer.layerId].set('legends', layer.legend);
}
}));
}
this.set('legendLoaded', true);
this.emit(this.events.MapServiceLegendLoaded, this);
},
/**
* Handler appelé lorsque les légendes du services ont rencontré une erreur lors du chargement.
* @param response Object contenant les informations des légendes.
*/
legendLoadedError: function(error) {
console.log("Error loading legend : ", error.message, this);
this.set('legendLoaded', false);
this.emit(this.events.MapServiceLegendError, this);
},
/**
* Transforme un objet layerInfo Esri (esri.LayerInfo) en objet nécessaire à la contruction du MapServiceLayer
* @param {esri.LayerInfo} layerInfo
* @returns {Object}
*/
_layerInfoToLayer: function(layerInfo) {
return {
defaultVisibility: layerInfo.defaultVisibility,
layerId: layerInfo.id,
maxScale: layerInfo.maxScale,
minScale: layerInfo.minScale,
name: layerInfo.name,
inTOC: layerInfo.inTOC == null ? true : layerInfo.inTOC,
mapService: this
};
},
_setAlphaAttr: function(alpha) {
this.alpha = alpha;
this.get('layer') && this.get('layer').setOpacity(this.alpha/100);
},
_setVisibleAttr: function(visible){
this.visible = visible;
if(this.visible){
this.show();
} else {
this.hide();
}
},
_getMapServiceLayersAttr: function(){
var layers = [];
for(key in this.mapServiceLayers){
layers.push(this.mapServiceLayers[key]);
}
return layers;
},
getMapServiceLayer: function(key){
return this.mapServiceLayers[key];
},
getParentMapServiceLayers: function(){
var layers = [];
for(key in this.mapServiceLayers){
if(!this.mapServiceLayers[key].get('parentLayer')){
layers.push(this.mapServiceLayers[key]);
}
}
return layers;
},
_getIdentifiableAttr: function(){
if(!this.identifiable){
for(key in this.mapServiceLayers){
if(this.mapServiceLayers[key].get('identifiable')){
return true;
}
}
return false;
}
return this.identifiable;
},
/**
* Détermine si le service possède des layers identifiables à l'échelle donnée.
* @param scale Le niveau d'échelle
* @returns {Boolean}
*/
hasIdentifiableVisibleLayers: function(scale){
for(key in this.mapServiceLayers){
if(this.mapServiceLayers[key].get('identifiable') && this.mapServiceLayers[key].isVisible() && this.mapServiceLayers[key].visibleAtScale(scale)){
return true;
}
}
return false;
},
/**
* Affiche le service sur la carte
*/
show: function() {
this.visible = true;
if (this.get('layer')) {
this.get('layer').show();
}
for(var i=0;i<this.clusterLayers.length;i++){
this.clusterLayers[i].clusterLayer.show();
}
for(var i=0;i<this.heatLayers.length;i++){
this.heatLayers[i].heatLayer.show();
}
this.emit(this.events.MapServiceVisibilityChanged, this);
if(this.spwMap){
this.spwMap.mapServiceVisibilityChanged(this);
}
},
/**
* Cache le service de la carte
*/
hide: function() {
this.visible = false;
if (this.get('layer')) {
this.get('layer').hide();
}
for(var i=0;i<this.clusterLayers.length;i++){
this.clusterLayers[i].clusterLayer.hide();
}
for(var i=0;i<this.heatLayers.length;i++){
this.heatLayers[i].heatLayer.hide();
}
this.emit(this.events.MapServiceVisibilityChanged, this);
if(this.spwMap){
this.spwMap.mapServiceVisibilityChanged(this);
}
},
isGraphics: function() {
var map = this.spwMap.get('esriMap');
return index = map.graphicsLayerIds.indexOf(this.serviceId) > -1;
},
isFirst: function() {
if (this.get('inError')) {
return false;
}
var map = this.spwMap.get('esriMap');
var index = map.layerIds.indexOf(this.serviceId);
if (index < 0) {
index = map.graphicsLayerIds.indexOf(this.serviceId);
}
return index === 0;
},
isLast: function() {
if (this.get('inError')) {
return false;
}
var map = this.spwMap.get('esriMap');
var index = map.layerIds.indexOf(this.serviceId);
if (index < 0) {
index = map.graphicsLayerIds.indexOf(this.serviceId);
return index === (map.graphicsLayerIds.length - 1);
}
return index === (map.layerIds.length - 1);
},
moveLayer: function(delta){
if(this.spwMap){
var map = this.spwMap.get('esriMap');
var index = map.layerIds.indexOf(this.serviceId);
if (index < 0) {
index = map.graphicsLayerIds.indexOf(this.serviceId);
}
map.reorderLayer(this.get('layer'), index + delta);
}
},
moveUp: function(){
this.moveLayer(1);
},
moveDown: function(){
this.moveLayer(-1);
},
/**
* Rafraichit la visibilité des layers
*/
refreshLayersVisibility: function() {
if(this.get('layer') && this.get('layer').setVisibleLayers /*&& !this.get('layer').isInstanceOf(WMSLayer)*/){
// var visibleLayersIds = [];
// var allVisibleLayersIds = [];
//
// for(var key in this.mapServiceLayers){
// if(this.mapServiceLayers[key].isVisible()) {
// if (this.mapServiceLayers[key].get('subLayers').length == 0
// && (this.mapServiceLayers[key].defaultVisibility)) {
// visibleLayersIds.push(this.mapServiceLayers[key].get('layerId'));
// }
// allVisibleLayersIds.push(this.mapServiceLayers[key].get('layerId'));
// }
// }
//
// if(visibleLayersIds.length > 0){
// this.get('layer').setVisibleLayers(visibleLayersIds);
// } else {
// this.get('layer').setVisibleLayers([-1]);
// }
//
// this.visibleLayersIds = allVisibleLayersIds;
var visibleLayersIds = [];
var allVisibleLayers = [];
for (var key in this.mapServiceLayers) {
var layer = this.mapServiceLayers[key];
var par = layer.parentLayer, layerVisibility = layer.get('visible');
while(par && layerVisibility){
if(!par.get('visible')){
layerVisibility = false;
break;
} else {
par = par.parentLayer;
}
}
if(layer.get('visible')) {
allVisibleLayers.push(layer.get('layerId'));
}
if (layerVisibility) {
if(this.groupLayersIdMustBeAddedInURL(layer)) {
visibleLayersIds.push(layer.get('layerId'));
}
}
}
if(visibleLayersIds.length > 0){
this.effectivelyUpdateLayersVisibility(visibleLayersIds);
} else {
this.effectivelyUpdateLayersVisibility([-1]);
}
this.visibleLayersIds = allVisibleLayers;
this.emit(this.events.MapServiceLayersVisibilityChanged, this);
if(this.spwMap){
this.spwMap.mapServiceVisibilityChanged(this);
}
}
},
groupLayersIdMustBeAddedInURL: function(layer) {
if (layer.subLayers && layer.subLayers.length > 0) {
var atLeastOneSubLayerIsVisible = array.some(layer.subLayers, lang.hitch(this, function(sub) {
return sub.get('visible');
}));
if(!atLeastOneSubLayerIsVisible) {
return atLeastOneSubLayerIsVisible;
}
return !atLeastOneSubLayerIsVisible;
} else {
return true;
}
},
effectivelyUpdateLayersVisibility: function(visibleLayersIds) {
if (this.refreshTimeout) {
clearTimeout(this.refreshTimeout);
}
this.refreshTimeout = setTimeout(lang.hitch(this, function() {
this.get('layer').setVisibleLayers(visibleLayersIds);
}, 50))
},
getServiceConfig: function(toKeep) {
toKeep = toKeep || this._propertiesToKeep;
var cfg = null;
for (var property in this) {
if (toKeep.indexOf(property) < 0) {
continue;
}
cfg = cfg || {};
cfg[property] = this[property];
}
cfg.layers = [];
array.forEach(this.get('mapServiceLayers'), lang.hitch(this, function(mapServiceLayer) {
cfg.layers.push({
layerId: mapServiceLayer.get('layerId'),
defaultVisibility: mapServiceLayer.get('visible'),
inTOC: mapServiceLayer.get('inTOC')
});
}));
return cfg;
},
/**
* Obtient les légendes d'un service en fonction de la visibilité de ses couches à une échelle donnée.
* @param scale Le niveau d'échelle
* @returns {Object} Mapping entre le label du service et les objets légende des layers.
*/
getMapServiceLegend: function(scale){
if(this.visible && this.legendLoaded){
var mapServiceLegend = {"mapServiceLabel" : this.get('label'), "layers": new Array()};
var layersAdded = 0;
array.forEach(this.get('MapServiceLayers'),lang.hitch(this,function(mapServiceLayer){
var layerLegend = mapServiceLayer.getLayerLegend(scale);
if(layerLegend){
layersAdded++;
mapServiceLegend.layers.push(layerLegend);
}
}));
if(layersAdded > 0)
return mapServiceLegend;
}
return null;
},
getAdditionnalLayers: function(){
var additionnalLayers = new Array();
for(var i=0;i<this.clusterLayers.length;i++){
additionnalLayers.push(this.clusterLayers[i].clusterLayer);
}
for(var i=0;i<this.heatLayers.length;i++){
additionnalLayers.push(this.heatLayers[i].heatLayer);
}
return additionnalLayers;
},
identify: function(options, success, error){
if (typeof(error) === 'function') {
error("Unidentifiable service type", this);
}
},
exportData: function() {
return {};
},
MapServiceLayer: MapServiceLayer
});
MapService.events = {
/**
* Evènement déclenché lorsque le MapService est chargé.
* @event spw.api.MapService#MapServiceLoaded
*/
"MapServiceLoaded" : "MapServiceLoaded",
/**
* Evènement déclenché lorsque le MapService est en erreur.
* @event spw.api.MapService#MapServiceError
*/
"MapServiceError" : "MapServiceError",
/**
* Evènement déclenché lorsque les légendes du MapService sont chargées.
* @event spw.api.MapService#MapServiceLegendLoaded
*/
"MapServiceLegendLoaded":"MapServiceLegendLoaded",
/**
* Evènement déclenché lorsque les légendes du MapService sont en erreur.
* @event spw.api.MapService#MapServiceLegendError
*/
"MapServiceLegendError":"MapServiceLegendError",
/**
* Evènement déclenché lorsque la visibilité du MapService change.
* @event spw.api.MapService#MapServiceVisibilityChanged
*/
"MapServiceVisibilityChanged":"MapServiceVisibilityChanged",
/**
* Evènement déclenché lorsque la visibilité de tous les layers du MapService est changée.
* @event spw.api.MapService#MapServiceLayersVisibilityChanged
*/
"MapServiceLayersVisibilityChanged":"MapServiceLayersVisibilityChanged",
/**
* Evènement déclenché lorsque la visibilité d'un layer du MapService est changée.
* @event spw.api.MapService#MapServiceLayerVisibilityChanged
*/
"MapServiceLayerVisibilityChanged" : "MapServiceLayerVisibilityChanged"
};
return MapService;
});