Source: api/MapServiceLayer.js

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;
    });