Retour à la documentation
define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct", "dijit/_WidgetBase",
"esri/layers/LayerDrawingOptions", "esri/renderers/SimpleRenderer"],
function(declare, lang, array, domConstruct, _WidgetBase, LayerDrawingOptions, SimpleRenderer) {
var MapServiceLayer = declare("spw.api.MapServiceLayer", [_WidgetBase], /** @lends spw.api.MapServiceLayer.prototype */{
/**
* Identifiant de la couche définie au niveau du service
* @memberof spw.api.MapServiceLayer
* @instance
*/
layerId: null,
/**
* Nom de la couche
* @memberof spw.api.MapServiceLayer
* @instance
*/
name: "NO_NAME",
/**
* Echelle maximum
* @memberof spw.api.MapServiceLayer
* @instance
*/
maxScale: 0,
/**
* Echelle minimum
* @memberof spw.api.MapServiceLayer
* @instance
*/
minScale: 0,
/**
* Stock les anciennes visibilités des sous layers au moment du changement de visibilité
* @memberof spw.api.MapServiceLayer
* @instance
*/
sublayersVisibilityState: {},
/**
* Le changement de visibilité est demandé depuis un layer parent
* @memberof spw.api.MapServiceLayer
* @instance
*/
fromParent: false,
/**
* La visibilité du service a été changée manuellement par l'utilisateur
* @memberof spw.api.MapServiceLayer
* @instance
*/
touched: null,
/**
* Visibilité effective de la couche: est-elle visible actuellement sur la carte ?
* @memberof spw.api.MapServiceLayer
* @instance
*/
visible: true,
/**
* Visibilité de la couche telle que choisir par l'utilisateur (via la TOC par exemple)
* @memberof spw.api.MapServiceLayer
* @instance
*/
visibility: null,
/**
* Visibilité par défaut de la couche, configurée au niveau du Mapserver mais overridable par l'utilisateur via config
* @memberof spw.api.MapServiceLayer
* @instance
*/
defaultVisibility: true,
/**
* Référence vers le spw.api.MapServiceLayer parent
* @memberof spw.api.MapServiceLayer
* @instance
*/
parentLayer: null,
/**
* Tableau des spw.api.MapServiceLayer enfants
* @memberof spw.api.MapServiceLayer
* @instance
*/
subLayers: null,
/**
* Référence vers le spw.api.MapService
* @memberof spw.api.MapServiceLayer
* @instance
*/
mapService: null,
/**
* Information des légendes de la couche.
* @memberof spw.api.MapServiceLayer
* @instance
*/
legends: null,
/**
* Indique si la couche est identifiable
* @memberof spw.api.MapServiceLayer
* @instance
*/
identifiable: false,
/**
*
*/
clusterLayer: null,
/**
*
*/
heatLayer: null,
fields: null,
restrictToFields: true,
alpha: null,
inTOC: true,
queryableFields: null,
queryableTemplate: null,
queryableLabel: null,
queryableOrder: null,
/**
* @constructs spw.api.MapServiceLayer
* @param config
* @param {Number} config.layerId {@link spw.api.MapServiceLayer#layerId}
* @param {String} config.name {@link spw.api.MapServiceLayer#name}
* @param {Number} config.maxScale {@link spw.api.MapServiceLayer#maxScale}
* @param {Number} config.minScale {@link spw.api.MapServiceLayer#minScale}
* @param {Boolean} config.defaultVisibility {@link spw.api.MapServiceLayer#defaultVisibility}
* @param {Boolean} config.identifiable {@link spw.api.MapServiceLayer#identifiable}
*/
constructor: function(config) {
this.subLayers = [];
},
postCreate: function() {
if (this.minScale == null) {
this.minScale = 0;
}
if (this.maxScale == null) {
this.maxScale = 0;
}
},
postMixInProperties: function() {
this.set('visibility',this.defaultVisibility);
},
_setAlphaAttr: function(alpha) {
this.alpha = alpha;
/* TODO -> if dynamicLayers enabled on service, do this
var optionsArray = [];
var drawingOptions = new LayerDrawingOptions();
drawingOptions.transparency = alpha;
optionsArray[this.layerId] = drawingOptions;
this.mapService.get('layer').setLayerDrawingOptions(optionsArray);
*/
},
/**
* Ajoute un spw.api.MapServiceLayer enfant au spw.api.MapServiceLayer courant.
* @memberof spw.api.MapServiceLayer
* @instance
* @param subLayer
*/
addChildLayer: function(subLayer) {
//if(subLayer.id != this.id){
this.subLayers.push(subLayer);
subLayer.set('parentLayer', this);
//}
},
_setMaxScaleAttr: function(value){
if(value != undefined){
this.maxScale = value;
if(this.get('parentLayer')){
this.get('parentLayer')._updateScaleByChilds();
}
}
},
_setMinScaleAttr: function(value){
if(value != undefined){
this.minScale = value;
if(this.get('parentLayer')){
this.get('parentLayer')._updateScaleByChilds();
}
}
},
_setParentLayerAttr: function(value){
this.parentLayer = value;
if(value){
this.parentLayer._updateScaleByChilds();
this._setVisibilityAttr(this.get('visibility'));
}
},
_getIdentifiableAttr: function(){
if(!this.identifiable){
if(this.fields && this.fields.length > 0){
for(var i=0;i<this.fields.length;i++){
if(this.fields[i].identifiable)
return true;
}
return false;
}
}
return this.identifiable;
},
/**
* Met à jour l'échelle du spw.api.MapServiceLayer courant en fonction de l'échelle définie dans les sous layers.
* @memberof spw.api.MapServiceLayer
* @instance
*/
_updateScaleByChilds: function() {
var greaterMaxScale = -1;
var greaterMinScale = -1;
array.some(this.get('subLayers'), 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);
}));
// TODO: si les 2 sont à 0 et qu'on a un minScale/maxScale sur le layer, que faire ?
// override ? recalcul ? ...
this.set('maxScale', greaterMaxScale);
this.set('minScale', greaterMinScale);
},
/**
* Indique si le spw.api.MapServiceLayer courant est visible.
* @memberof spw.api.MapServiceLayer
* @instance
* @returns {Boolean}
*/
isVisible: function() {
// console.log(this.name + ' - defaultVisibility:', this.get('defaultVisibility'));
// if(!this.get('defaultVisibility')){
// return false;
// }
//
// var parentVisibility = true;
// var parentLayer = this.parentLayer;
// while(parentLayer){
// if(!parentLayer.get('defaultVisibility')){
// parentVisibility = false;
// break;
// }
// parentLayer = parentLayer.parentLayer;
// }
// console.log(this.name + ' - ' + 'isVisible():' + parentVisibility);
// return parentVisibility;
return this.get('visible');
},
shouldBeIdentified: function() {
var layerVisible = this.allLayersOverAreVisible(this)
&& this.visibleAtScale(this.mapService.spwMap.getCurrentScale());
return this.get('identifiable')
&& this.get('subLayers').length == 0
&& layerVisible;
},
allLayersOverAreVisible: function(layer) {
if (!layer.parentLayer) {
return this.isVisible();
} else {
if (layer.parentLayer && !layer.parentLayer.isVisible()) {
return false;
} else {
return this.isVisible() && this.allLayersOverAreVisible(layer.parentLayer);
}
}
},
_setDefaultVisibilityAttr: function(value) {
this.defaultVisibility = value;
},
/**
* Affiche le layer courant
* @memberof spw.api.MapServiceLayer
* @instance
*/
show: function(fromParent) {
if (this.touched == null && fromParent == null) {
this.touched = true;
}
this.fromParent = fromParent ? true : false;
this.set('visibility', true);
},
_getVisibleAttr: function() {
return this.visible;
},
_setVisibilityAttr: function(value) {
if (value === null) {
return;
}
this.visibility = value;
this.set('visible', this.visibility);
// if (this.parentLayer) {
// if (this.fromParent) {
// if (this.touched == null) {
// this.visibility = (this.parentLayer.visible && value && this.defaultVisibility);
// } else {
// this.visibility = (this.parentLayer.visible && value && this.parentLayer.sublayersVisibilityState[this.layerId]);
// }
// } else {
// this.visibility = (this.parentLayer.visible && value);
// }
// } else {
// this.visibility = value;
// }
// if (this.get('visibility')) {
// this.set('visible',this.visibleAtCurrentScale());
// } else {
// this.set('visible',false);
// }
// if (this.subLayers && this.subLayers.length > 0) {
// array.forEach(this.subLayers, lang.hitch(this, function(sublayer) {
// this.get('visible') ? sublayer.show(true) : sublayer.hide(true);
// }))
// }
if (this.mapService) {
this.mapService.refreshLayersVisibility();
}
},
_setVisibleAttr: function(value) {
this.visible = value;
// this.mapService.refreshLayersVisibility();
this.emit(MapServiceLayer.events.MapServiceLayerVisibilityChanged, this);
},
/**
* Cache le layer courant
* @memberof spw.api.MapServiceLayer
* @instance
*/
hide: function(fromParent) {
if (this.touched == null && fromParent == null) {
this.touched = true;
}
// if (!this.fromParent) {
// this.sublayersVisibilityState[this.layerId] = this.visibility;
// array.forEach(this.subLayers, lang.hitch(this, function(sublayer) {
// sublayer.saveSublayersVisibilityStateOnHide();
// }))
// }
this.fromParent = fromParent ? true : false;
this.set('visibility', false);
// if (this.subLayers && this.subLayers.length > 0) {
// array.forEach(this.subLayers, lang.hitch(this, function(sublayer){
// sublayer.hide(true);
// }))
// }
},
saveSublayersVisibilityStateOnHide: function() {
array.forEach(this.subLayers, lang.hitch(this, function(sublayer) {
this.sublayersVisibilityState[sublayer.layerId] = sublayer.visibility;
if(sublayer.subLayers.length > 0) {
sublayer.saveSublayersVisibilityStateOnHide();
}
}))
},
/**
* Détermine si le layer courant est visible à l'échelle donnée.
* @memberof spw.api.MapServiceLayer
* @instance
* @param scale le niveau d'échelle
* @returns {Boolean}
*/
visibleAtScale: function(scale){
if(this.get('maxScale') != undefined && this.get('minScale')!= undefined){
if(this.get('maxScale') == 0 || this.get('maxScale') <= scale){
if(this.get('minScale') == 0 || this.get('minScale') >= scale){
return true;
}
}
return false;
}
return true;
},
/**
* Détermine si le layer courant est visible à l'échelle actuelle.
* @memberof spw.api.MapServiceLayer
* @instance
* @returns {Boolean}
*/
visibleAtCurrentScale: function(){
// if(this.mapService && this.mapService.get('layer') && this.mapService.get('layer')._map){
// return this.visibleAtScale(this.mapService.get('layer')._map.getScale());
// }
return this.visibleAtScale(require("spw/api/SpwViewer").getInstance().get('spwMap').esriMap.getScale());
/*if(this.mapService && this.mapService.get('layer') && this.mapService.spwMap){
var scale = this.mapService.spwMap.get('esriMap').getScale();
return this.mapService.get('layer').visible && this.visibleAtScale(scale);
}*/
// return false;
},
/**
* Récupére la légende spécifique au spw.api.MapServiceLayer courant en fonction de l'échelle donnée.
* @memberof spw.api.MapServiceLayer
* @instance
* @param scale le niveau d'échelle
* @returns
*/
getLayerLegend: function(scale){
if(this.subLayers && this.subLayers.length >0){
var parentLayer = {"layerName":this.get('name'),"subLayer": new Array()};
var subLayerAdded = 0;
array.forEach(this.subLayers,lang.hitch(this,function(subLayer){
var subLayerLegend = subLayer.getLayerLegend(scale);
if(subLayerLegend){
parentLayer.subLayer.push(subLayerLegend);
subLayerAdded++;
}
}));
if(subLayerAdded > 0)
return parentLayer;
}
else{
if(this.legends && this.isVisible() && this.visibleAtScale(scale)){
return {"layerName":this.get('name'),"legend":this.get('legends')};
}
}
return null;
},
generateHtmlLegend: function(){
var wrapper = domConstruct.create("div", null);
var table = domConstruct.create("table", {
style:"width:100%;"
}, wrapper);
array.forEach(this.legends, lang.hitch(this, function(legend){
var row = domConstruct.create("tr", null, table);
domConstruct.create("img", {
src: "data:" + legend.contentType + ";base64," + legend.imageData,
alt:legend.label,
title: legend.label,
style: "vertical-align: middle;"
}, domConstruct.create("td", null, row), 'first');
domConstruct.create("span", {
innerHTML: legend.label
}, domConstruct.create("td", { style: "width:100%;" }, row), "last");
}));
return wrapper;
}
});
MapServiceLayer.events = {
/**
* Evènement déclenché lorsque la visibilité d'un layer du MapService est changée.
* @event spw.api.MapService#MapServiceLayerVisibilityChanged
*/
"MapServiceLayerVisibilityChanged": "MapServiceLayerVisibilityChanged"
};
return MapServiceLayer;
});