Source: widgets/SpwBaseMapChooser.js

Retour à la documentation
/**
 * @class spw.widgets.SpwBaseMapChooser
 */
define([
    "dojo/_base/declare", "spw/api/SpwBaseTemplatedWidget", "dojo/text!./templates/SpwBaseMapGallery.html",
    "dojo/text!./templates/SpwOptionalBaseMapGalleryWidget.html", "spw/api/ConfigLoader", "spw/api/Utils",
    "dijit/layout/ContentPane", "dijit/TitlePane", "dojo/_base/array",
    "dojo/_base/lang", "dojo/dom-construct", "dojo/dom-class", "dojo/on", "dijit/form/CheckBox",
    "dojo/dom-geometry", "dojo/i18n!./nls/SpwBaseMapChooser", "dojo/dom-attr", "dijit/Dialog",
    "spw/api/StateManager", "dojo/dom-style", "dijit/registry", "dojo/topic",
    "dojox/layout/FloatingPane", "spw/widgets/SpwTimeTravel", "dojo/touch", "spw/api/MessageManager", "dijit/ConfirmDialog"
], function(declare, SpwBaseTemplatedWidget, template, optTemplate, ConfigLoader, Utils,
        ContentPane, TitlePane, array, lang, domConstruct, domClass, on, CheckBox, domGeom, labels, domAttr,
        Dialog, StateManager, domStyle, registry, topic, FloatingPane, SpwTimeTravel, touch, MessageManager, ConfirmDialog) {

    var SpwBaseMapGallery = declare("spw.widgets.SpwBaseMapChooser", [SpwBaseTemplatedWidget], /** @lends spw.widgets.SpwBaseMapChooser.prototype */{

        templateString: template,
        labels: labels,

        timeTravelWidth: '500px',
        timeTravelHeight: '220px',

        confirmDialogStyle: 'width: 400px;',
        confirmDialogTitle: 'Avertissement',
        confirmDialogMessage: "Conformément aux conditions d'utilisation de Google, l'activation du fond de plan fermera l'outil \"StreetView\".",
        confirmDialogConfirmLabel: 'Continuer',
        confirmDialogCancelLabel: 'Annuler',

        confirmDialogMessageImajnet : 'L\'activation du fond de plan fermera l\'outil Imajnet',

        // default style
        style: {
            width: '440px'
        },

        baseMapConfig: null,
        baseMapNodes: null,

        /** Selected DOM node */
        selected: null,

        alphaChangedHandler: null,

        optionsFullHeight: false,

        timeTravelPosition: null,
        timeTravelMobile: null,
        _changeFromImajnet : null,

        /**
         * @constructs
         * @param config
         */
        constructor: function() {
            StateManager.getInstance().register(StateManager.BASEMAP_ID,
                lang.hitch(this, this.getBaseMapsState));
        },

        postCreate: function() {
            this.inherited(arguments);

            this.baseMapConfig = ConfigLoader.getInstance().get('baseMap');
            this.baseMapNodes = [];
            if(this.spwViewer.get('spwMap').get('loaded')){
                this.createBaseMapNodes();
            } else {
            	this.spwViewer.get('spwMap').on(this.spwViewer.get('spwMap').events.MapLoaded, lang.hitch(this, function(){
                    this.createBaseMapNodes();
            	}));
            }

            topic.subscribe('SPWBASEMAPCHOOSER_LOCK_BASEMAP', lang.hitch(this, this.lockBaseMap));
            topic.subscribe('SPWBASEMAPCHOOSER_CHANGE_BASEMAP', lang.hitch(this, this.changeBaseMap));
            topic.subscribe('SPWBASEMAPCHOOSER_CHANGE_FROM_IMAJNET', lang.hitch(this, function(evt) {
                this._changeFromImajnet = evt;
            }));
        },

        changeBaseMap: function(basemap) {
            var baseMapNodeToSelect = this.baseMapNodes.filter(function(baseMapNode) {
                if (baseMapNode.baseMapId && basemap.baseMapId) {
                    return baseMapNode.baseMapId === basemap.baseMapId;
                }
                return baseMapNode.baseMapName === basemap.baseMapName;
            });

            if (baseMapNodeToSelect == null || baseMapNodeToSelect.length < 1) {
                return false;
            }

            this.select(baseMapNodeToSelect[0], true);
            return true;
        },

        lockBaseMap: function(basemap) {
            this._locked = this.changeBaseMap(basemap);
        },

        close: function() {
            this.inherited(arguments);
        },

        onClose: function() {
            this.inherited(arguments);
        },

        onActivate: function() {
            this.inherited(arguments);

            this.placeBaseMapNodes();

            // if i do this, it will close the time traval popup when this widget loses focus...
            if (this.selected && this.selected.type === 'TIMER' && !this.spwViewer.mobile) {
                this.showTimeTravel(this.selected);
            }
            else {
                this.clearTimeTravel();
            }
        },

        onDeactivate: function() {
            this.inherited(arguments);
        },

        createBaseMapNodes: function() {
            var baseMaps = this.spwViewer.get('spwMap').getMapServices({
                isBaseMap: true, visible: true, checked: false
            });

            var onMap = null;

            if (baseMaps.length > 0) {
                onMap = baseMaps[0];
            }

            array.forEach(this.baseMapConfig, lang.hitch(this, function(basemap){
                var baseMapNode = new BaseMapNode(lang.mixin(basemap, { controller: this }));
                this.baseMapNodes.push(baseMapNode);

                if (onMap && basemap.services && basemap.services.length > 0 && basemap.selected) {
                    baseMapNode.selected = true;
                }
                else {
                    baseMapNode.selected = false;
                }

                if(baseMapNode.selected) {
                    domStyle.set(this.metadataButton.domNode, 'display', basemap.metadataUrl ? '' : 'none');
                    this.metadataButton.set('disabled', !basemap.metadataUrl);

                    if (this.selected) {
                        domClass.remove(this.selected.domNode, "selected");
                    }

                    domClass.add(baseMapNode.domNode, "selected");
                    this.setDetails(basemap);

                    this.selected = baseMapNode;
                }
            }));

            if (this.selected == null) {
                this.select(this.baseMapNodes[0]);
            }
        },

        placeBaseMapNodes: function() {
            if (this._placed) {
                return;
            }
            array.forEach(this.baseMapNodes, lang.hitch(this, function(baseMapNode) {
                baseMapNode.placeAt(this.basemapGallery);
            }));
            this._placed = true;
        },

        select: function(basemap, fromTopic) {
            if(basemap == this.selected) {
                if (basemap.type === 'TIMER') {
                    this.showTimeTravel(this.selected);
                }
                return;
            }

            if (this._locked && !fromTopic) {
                var confirmDialog = null;
                if (this._changeFromImajnet) {
                    confirmDialog = new ConfirmDialog({
                        title: this.confirmDialogTitle,
                        content: this.confirmDialogMessageImajnet,
                        closable: false,
                        style: this.confirmDialogStyle,
                        buttonOk: this.confirmDialogConfirmLabel,
                        buttonCancel: this.confirmDialogCancelLabel
                    });
                } else {
                    confirmDialog = new ConfirmDialog({
                        title: this.confirmDialogTitle,
                        content: this.confirmDialogMessage,
                        closable: false,
                        style: this.confirmDialogStyle,
                        buttonOk: this.confirmDialogConfirmLabel,
                        buttonCancel: this.confirmDialogCancelLabel
                    });
                }

                confirmDialog.on('execute', lang.hitch(this, function() {
                    this._locked = false;
                    this.select(basemap);
                }));

                confirmDialog.show();
                return;
            }
            else {
                this._locked = false;
            }

            this.showLoading();

            this.spwViewer.get('spwMap').removeBaseMaps();
            this.spwViewer.get('spwMap').createBaseMapsFromConfig([basemap, this.selected])
                .then(lang.hitch(this, function(idx) {
                    if (idx === 0) {
                        if(this.selected){
                            domClass.remove(this.selected.domNode, "selected");
                        }

                        this.selected = basemap;
                    }
                    else {
                        MessageManager.getInstance().notifyWarning('Le fond de plan sélectionné n\'est pas disponible pour l\'instant. Veuillez réeesayer plus tard.');
                    }

                    domClass.add(this.selected.domNode, "selected");

                    // has to be after this.selected = basemap
                    this.clearTimeTravel();

                    this.setDetails(this.selected);

                    if (this.selected.type === 'TIMER') {
                        domStyle.set(this.metadataButton.domNode, 'display', 'none');
                        this.metadataButton.set('disabled', true);

                        this.selected.alpha = !isNaN(this.selected.alpha) ? this.selected.alpha : 100;
                        this.showTimeTravel(this.selected);
                    }
                    else {
                        domStyle.set(this.metadataButton.domNode, 'display', this.selected.metadataUrl ? '' : 'none');
                        this.metadataButton.set('disabled', !this.selected.metadataUrl);
                    }

                    this.spwViewer.trackEvent(this.declaredClass, 'BaseMap selected', this.selected.baseMapName);
                    topic.publish('SPWBASEMAPCHOOSER_BASEMAP_CHANGED', this.selected);

                    this.hideLoading();
                }), lang.hitch(this, function(err) {
                    this.hideLoading();
                    topic.publish('SPWBASEMAPCHOOSER_BASEMAP_CHANGED', this.selected);
                }));
        },

        clearTimeTravel: function() {
            if (this.timeTravel) {
                this.timeTravel.hide();
                this.timeTravel.destroy();
                this.timeTravel = null;
            }
        },

        showTimeTravel: function(basemap) {
            if (this.timeTravel && this.timeTravel.get('basemap') === basemap) {
                this.timeTravel.show();
            }
            else {
                this.clearTimeTravel();

                this.timeTravel = new SpwTimeTravel({
                    basemap: basemap,
                    spwViewer: this.spwViewer,
                    width: this.timeTravelWidth,
                    height: this.timeTravelHeight,
                    position: this.timeTravelPosition || 'panel-light',
                    mobile: this.timeTravelMobile
                });

                this.timeTravel.show();
            }
        },

        setDetails: function(basemap) {
            domConstruct.empty(this.tbodyNode);

            if (basemap.hideOptions) {
                domStyle.set(this.detailsNode.domNode, 'display', 'none');
                return;
            }

            // on affiche les détails
            domStyle.set(this.detailsNode.domNode, 'display', '');

            // noir & blanc
            var trBlack = domConstruct.create('tr', null, this.tbodyNode);
            var tdBlack = domConstruct.create('td', null, trBlack);

            var cbBlackAndWhite = new CheckBox({
                disabled: !(basemap.activateBlackAndWhite),
                checked: basemap.activateBlackAndWhite && basemap.blackAndWhiteByDefault
            });

            var styleLabel = 'style="opacity: 0.3"';

            if (basemap.activateBlackAndWhite) {
                lang.mixin(basemap, {chbBw: cbBlackAndWhite});
                styleLabel = '';
            }

            domConstruct.place(cbBlackAndWhite.domNode, tdBlack, 'first');
            domConstruct.place('<label for="' + cbBlackAndWhite.get('id') + '"' + styleLabel + '> ' + labels.blackAndWhite + '</label>', tdBlack, 'last');

            this.own(cbBlackAndWhite.on('change', lang.hitch(this, this.activateBlackAndWhite, basemap)));
            cbBlackAndWhite.startup();

            // transparency
            this.transparencyBar.set('disabled', !basemap.activateTransparency);
            this.transparencyBar.set('value', isNaN(basemap.alpha) ? 100 : basemap.alpha);

            if (!basemap.activateTransparency) {
                domStyle.set(this.transparencyLabel, 'opacity', '0.3');
            }
            else {
                domStyle.set(this.transparencyLabel, 'opacity', '');
            }

            if (this.alphaChangedHandler) {
                this.alphaChangedHandler.remove();
            }

            this.alphaChangedHandler = this.transparencyBar.on('change', lang.hitch(this, function(value) {
                this.alphaChanged(basemap, value);
            }));

            this.own(this.alphaChangedHandler);

            // services en plus (annotation et relief)
            array.forEach(basemap.optionalServices, lang.hitch(this, function(service) {
                var ckBox = new CheckBox({
                    checked: service.checked
                });

                var lbl = domConstruct.create('label', {
                    innerHTML: ' ' + service.label,
                    'for': ckBox.get('id')
                });

                var tr = domConstruct.create('tr', null, this.tbodyNode, 'last');
                var td = domConstruct.create('td', null, tr, 'first');

                domConstruct.place(ckBox.domNode, td, 'first');
                domConstruct.place(lbl, td, 'last');

                lang.mixin(service, {chbOption: ckBox});
                this.own(ckBox.on('change', lang.hitch(this, this.optionnalChecked, basemap, service, ckBox)));

                ckBox.startup();
            }));
        },

        alphaChanged: function(basemap, value){
            basemap.alpha = value;
            this.setBaseMapAlpha(basemap, value);
        },

        activateBlackAndWhite: function(basemap) {
            if (basemap.activateBlackAndWhite === 'filter') {
                var val = basemap.chbBw.get('checked') ? 100 : null;

                array.forEach(basemap.services, lang.hitch(this, function(service) {
                    var s = this.spwViewer.get('spwMap').getMapServiceById(service.serviceId);
                    s.set('grayscale', val);
                }));

                array.forEach(basemap.optionalServices, lang.hitch(this, function(service) {
                    var s = this.spwViewer.get('spwMap').getMapServiceById(service.serviceId);
                    s.set('grayscale', val);
                }));
            }
            else {
                this.changeMap(basemap, basemap);
            }
            this.spwViewer.trackEvent(this.declaredClass, 'Black and white BaseMap activated', basemap.baseMapName);
        },

        optionnalChecked: function(basemap, service, ckbox){
            service.checked = ckbox.get('checked');
            this.changeMap(basemap, basemap);
            this.spwViewer.trackEvent(this.declaredClass, 'Optionnal BaseMap checked', service.label);
        },

        changeMap: function(oldBaseMap, newBaseMap){
            if(oldBaseMap){
                this.removeServices(oldBaseMap);
            }
            this.addServices(newBaseMap);
        },

        removeServices: function(baseMap){
            array.forEach(baseMap.services, lang.hitch(this, function(service) {
                if(baseMap.chbBw) {
                    var serviceId = "black-and-white-" + service.serviceId;
                    var mapService = this.spwViewer.get('spwMap').getMapServiceById(serviceId);

                    if(mapService){
                        mapService.set('visible', false);
                    }
                }

                var mapService = this.spwViewer.get('spwMap').getMapServiceById(service.serviceId);

                if(mapService){
                    mapService.set('visible', false);
                }
            }));

            if(baseMap.optionalServices && baseMap.optionalServices.length > 0) {
                array.forEach(baseMap.optionalServices, lang.hitch(this, function(service) {

                    if(baseMap.chbBw){
                        var serviceId = "black-and-white-" + service.serviceId;
                        var mapService = this.spwViewer.get('spwMap').getMapServiceById(serviceId);

                        if(mapService){
                            mapService.set('visible', false);
                        }
                    }

                    var mapService = this.spwViewer.get('spwMap').getMapServiceById(service.serviceId);

                    if(mapService){
                        mapService.set('visible', false);
                    }
                }));
            }
        },

        addServices: function(baseMap){
            var index = 0;

            array.forEach(baseMap.services, lang.hitch(this, function(service) {
                var serviceCloned = lang.mixin({}, service);
                // shallow copy is enough
                //var serviceCloned = lang.clone(service);

                if(baseMap.chbBw && baseMap.chbBw.get("checked") && baseMap.activateBlackAndWhite === true) {
                    serviceCloned.url = serviceCloned.urlBlackAndWhite;
                    serviceCloned.serviceId = "black-and-white-" + serviceCloned.serviceId;
                }

                var mapService = this.spwViewer.get('spwMap').getMapServiceById(serviceCloned.serviceId);

                if(mapService) {
                    mapService.checked = serviceCloned.checked; // to be sure
                    mapService.set('visible', true);
                } else {
                    mapService = this.spwViewer.get('spwMap').addBaseMap(serviceCloned, true);
                }

                this.spwViewer.get('spwMap').setMapServiceOrder(mapService.get('serviceId'), index++);
            }));

            if(baseMap.optionalServices && baseMap.optionalServices.length > 0) {

                array.forEach(baseMap.optionalServices, lang.hitch(this, function(service) {

                    if(service.chbOption && service.chbOption.get('checked')) {
                        var serviceCloned = lang.mixin({}, service);
                        // shallow copy is enough
                        //var serviceCloned = lang.clone(service);

                        if(baseMap.chbBw && baseMap.chbBw.get("checked") && baseMap.activateBlackAndWhite === true) {
                            serviceCloned.url = serviceCloned.urlBlackAndWhite;
                            serviceCloned.serviceId = "black-and-white-" + serviceCloned.serviceId;
                        }

                        var mapService = this.spwViewer.get('spwMap').getMapServiceById(serviceCloned.serviceId);

                        if(mapService) {
                            mapService.checked = serviceCloned.checked; // to be sure
                            mapService.set('visible', true);
                        } else {
                            mapService = this.spwViewer.get('spwMap').addBaseMap(serviceCloned, true);
                        }

                        this.spwViewer.get('spwMap').setMapServiceOrder(mapService.get('serviceId'), index++);
                    }
                }));
            }

            this.setBaseMapAlpha(baseMap, baseMap.alpha ? baseMap.alpha : 100);
        },

        setBaseMapAlpha: function(basemap, value) {

            basemap.alpha = value;

            array.forEach(basemap.services, lang.hitch(this, function(service) {
                var alpha = value;

                if(basemap.chbBw && basemap.chbBw.get('checked') && basemap.activateBlackAndWhite === true) {
                    var alphaBw = alpha;
                    var serviceId = "black-and-white-" + service.serviceId;
                    var mapService = this.spwViewer.get('spwMap').getMapServiceById(serviceId);

                    if(mapService) {
                        if (!isNaN(mapService.alphaTimer)) {
                            alphaBw *= Math.abs(mapService.alphaTimer);
                        }
                        mapService.set('alpha', alphaBw);
                    }
                }

                var mapService = this.spwViewer.get('spwMap').getMapServiceById(service.serviceId);

                if(mapService) {
                    if (!isNaN(mapService.alphaTimer)) {
                        alpha *= Math.abs(mapService.alphaTimer);
                    }
                    mapService.set('alpha', alpha);
                }
            }));

            if(basemap.optionalServices && basemap.optionalServices.length > 0) {
                var alpha = value;

                array.forEach(basemap.optionalServices, lang.hitch(this, function(service) {

                    if(basemap.chbBw && basemap.chbBw.get('checked') && basemap.activateBlackAndWhite) {
                        var serviceId = "black-and-white-" + service.serviceId;
                        var mapService = this.spwViewer.get('spwMap').getMapServiceById(serviceId);

                        if(mapService) {
                            if (!isNaN(mapService.alphaTimer)) {
                                alpha *= Math.abs(mapService.alphaTimer);
                            }
                            mapService.set('alpha', value * (service.alpha ? service.alpha : 100)  / 100);
                        }
                    }

                    var mapService = this.spwViewer.get('spwMap').getMapServiceById(service.serviceId);

                    if(mapService) {
                        if (!isNaN(mapService.alphaTimer)) {
                            alpha *= Math.abs(mapService.alphaTimer);
                        }
                        mapService.set('alpha', value * (service.alpha ? service.alpha : 100)  / 100);
                    }
                }));
            }
        },

        /**
         * Obtenir l'état des services sur base des fonds de plan
         * @returns {String} état des services des fonds de plan
         */
        getBaseMapsState: function(){
            var baseMapServices = this.spwViewer.get('spwMap').getMapServices({
                isBaseMap: true
            });

            var arrayOfCfg = [];

            array.forEach(baseMapServices, lang.hitch(this,
                function(bService){
                    if(bService.get('visible')) {
                        var cfg = bService.getServiceConfig(['serviceId', 'alpha', 'checked', 'alphaTimer', 'selected', 'grayscale']);
                        if (this.selected && this.selected.type === 'TIMER') {
                            cfg.alpha = this.selected.alpha;
                        }
                        arrayOfCfg.push(cfg);
                    }
                })
            );
            if (this.selected && this.selected.services) {
                array.forEach(this.selected.services, lang.hitch(this, function(service) {
                    array.some(arrayOfCfg, lang.hitch(this, function(cfgService) {
                        if (cfgService.serviceId == service.serviceId) {
                            cfgService.activateBlackAndWhite = this.selected.activateBlackAndWhite;
                        }
                    }))
                }))
            }

            return JSON.stringify(arrayOfCfg);
        },

        handleOnMetadataClick: function() {
            if (this.selected && this.selected.metadataUrl) {
                if(this.selected.metadataPopup){
                    var width = this.selected.metadataPopup.width != null ? this.selected.metadataPopup.width : "750px";
                    var height = this.selected.metadataPopup.height != null ? this.selected.metadataPopup.height : "800px";

                    new Dialog({
                        title: "",
                        content: "<iframe width=\""+width+"\" height=\""+height+"\" src=\""+this.selected.metadataUrl+"></iframe>"
                    }).show();
                }
                else {
                    window.open(this.selected.metadataUrl, '_blank');
                }
            }
        }
    });

    var BaseMapNode = declare("spw.widgets.SpwMapDataController.tools", [SpwBaseTemplatedWidget], {
        templateString: "<li class='spwBaseMapNode'><img class='thumbnail' src='${imagePath}' data-dojo-attach-point='thumbnailNode' /><div class='labelContainer'><span>${baseMapName}</span></div>"+
        "<div class='baseMapOptions' data-dojo-attach-point='baseMapOptions'></div></li>",

        controller: null,

        imagePath: '',

        buildRendering: function(){
            this.inherited(arguments);

            this.own(on(this.thumbnailNode, touch.press, lang.hitch(this, this.basemapNodeClicked)));
        },

        basemapNodeClicked: function(){
            this.controller.select(this);
        }
    });

    return SpwBaseMapGallery;
});