Source: api/FeatureMapService.js

Retour à la documentation
define([
        'dojo/_base/declare',
        'dojo/_base/lang',
        'dojo/_base/Color',
        'spw/api/DataBaseMapService',
        'esri/layers/FeatureLayer',
        'esri/tasks/IdentifyTask',
        'esri/renderers/SimpleRenderer',
        'esri/symbols/SimpleFillSymbol',
        'esri/symbols/SimpleLineSymbol',
        'spw/api/MapServiceLayer',
        'dojo/dom-construct',
        'dojo/_base/array',
        "esri/symbols/TextSymbol",
        "esri/layers/LabelClass", "dojo/Deferred",
        "esri/tasks/QueryTask",
        "esri/tasks/query",
        "esri/request",
        "dojo/promise/all",
        "esri/geometry/Extent"
    ],
    function(declare, lang, Color, MapService, FeatureLayer, IdentifyTask,
             SimpleRenderer, SimpleFillSymbol, SimpleLineSymbol, MapServiceLayer, domConstruct,
             array, TextSymbol, LabelClass, Deferred, QueryTask, Query, xhr, all, Extent) {

        /**
         * @class spw.api.FeatureMapService
         * @classdesc Service du viewer correspondant à un FeatureLayer d'ESRI
         * @extends {spw.api.MapService}
         */
        var FeatureMapService = declare('spw.api.FeatureMapService', [MapService], /** @lends spw.api.FeatureMapService.prototype */ {

            _simpleLineWidth: 0.5,
            _featureMode: FeatureLayer.MODE_ONDEMAND,

            constructor: function() {},

            /**
             * Crée le layer Esri sur base de la configuration du MapService.
             * @memberOf spw.api.MapService
             */
            createMapLayer: function() {
                this.layer = this._createFeatureLayer({
                    url: this.get('url'),
                    id: this.get('serviceId'),
                    mode: this._featureMode,
                    outFields: ['*']
                });

                this.inherited(arguments);
            },

            _createFeatureLayer: function(config){
                var layer = new FeatureLayer(config.url, {
                    id: config.id,
                    mode: config.mode,
                    outFields: config.outFields
                });

                if(this.labeling) {
                    var fieldLabel = new TextSymbol().setColor(this.labeling.textColor ? new Color(this.labeling.textColor) : new Color("black"));
                    fieldLabel.font.setSize(this.labeling.textSize ? this.labeling.textSize : "12pt");
                    fieldLabel.font.setFamily(this.labeling.textFamily ? this.labeling.textFamily : "arial");

                    var labelClass = new LabelClass(lang.mixin({}, this.labeling));
                    labelClass.symbol = fieldLabel; // symbol also can be set in LabelClass' json
                    layer.setLabelingInfo([ labelClass ]);
                }
                layer.on("load", lang.hitch(this, function() {
                    if(this.get('renderer')) {
                        var r = lang.mixin({}, this.get('renderer'));

                        var renderer = new SimpleRenderer(
                            new SimpleFillSymbol().setOutline(new SimpleLineSymbol().setWidth(this._simpleLineWidth)));

                        lang.mixin(renderer, {
                            label: r.title,
                            description: r.description
                        });

                        renderer.setColorInfo({
                            field: r.field,
                            minDataValue: r.minDataValue,
                            maxDataValue: r.maxDataValue,
                            colors: [
                                new Color(r.color1),
                                new Color(r.color2)
                            ]
                        });

                        layer.setRenderer(renderer);
                    }


                }));

                return layer;
            },

            identify: function(options, success, error) {
                var def = new Deferred();
                var query = new Query();
                query.where = '1=1';
                query.returnGeometry = true;
                query.geometry = options.mapPoint ? options.mapPoint : options.geometry;
                query.distance = options.tolerance ? (options.tolerance * 10) : 100;
                query.outFields = ['*'];
                var url = this.get('url');
                var queryTask = new QueryTask(url);
                var lastIndexOfSlash = url.lastIndexOf('/');
                var layerId = Number(url.substring(lastIndexOfSlash+1));
                queryTask.execute(query).then(lang.hitch(this, function(res){
                    if (res && res.features && res.features.length > 0) {
                        var promises = [];
                        array.forEach(res.features, lang.hitch(this, function(feat) {
                            promises.push(this.transformResult(layerId, options, feat));
                        }));
                        if (promises.length > 0) {
                            all(promises).then(lang.hitch(this, function(res) {
                                if (res && res.length > 0) {
                                    var results = array.map(res, function(r) {
                                        return r.result;
                                    });
                                    var datas = array.map(res, function(r) {
                                        return r.data;
                                    });
                                    if (success) {
                                        success(results, this, datas);
                                    }
                                    def.resolve(results, this,datas);
                                } else {
                                    if (success) {
                                        success([], this, []);
                                    }
                                    def.resolve([], this, []);
                                }
                            }))
                        } else {
                            if (success) {
                                success([], this, []);
                            }
                            def.resolve([], this, []);
                        }
                    } else {
                        if (success) {
                            success([], this, []);
                        }
                        def.resolve([], this, []);
                    }
                }));
                return def;
            },

            transformResult: function(layerId, options, result) {
                var def = new Deferred();
                var spwLayer = this.mapServiceLayers[layerId];
                if (spwLayer) {
                    if (spwLayer.fields) {
                        this.buildResults(spwLayer, options, result, def);
                    } else {
                        this.loadServiceInfos().then(lang.hitch(this, function() {
                            this.buildResults(spwLayer, options, result, def);
                        }))
                    }
                }
                return def;
            },

            buildResults: function(spwLayer, options, result, def) {
                var allConstructedFields = [];
                array.forEach(spwLayer.fields, lang.hitch(this, function(field){
                    if(this.fieldMustBeShownInResults(field, options)){
                        var fieldValue = this.constructFieldValue(field, result);
                        allConstructedFields.push(fieldValue);
                    }
                }));
                var res = {layerId: spwLayer.layerId, feature: result};
                var attributes = {};
                array.forEach(allConstructedFields, lang.hitch(this, function(k) {
                    attributes[k.key] = k.value;
                }));
                var data = {layerId: spwLayer.layerId, data: attributes};
                def.resolve({result: res, data: data});
            },

            fieldMustBeShownInResults: function(field, options) {
                return options.ignoreFields.indexOf(field.name.toUpperCase()) == -1
                    && (field.identifiable == null || field.identifiable == true);
            },

            constructFieldValue: function(field, result) {
                var key = field.alias ? field.alias : field.name;
                return {key: key, value: result.attributes[field.name]}
            },


            loadServiceInfos: function(){
                var def = new Deferred();
                xhr({ url: this.get('url'), content: {f:'json'}, handleAs: "json" }).then(lang.hitch(this, function(res) {
                    var layerId = res.id;
                    var spwLayer = this.mapServiceLayers[layerId];
                    if (!spwLayer.fields) {
                        spwLayer.fields = res.fields;
                    }
                    def.resolve();
                }));
                return def;
            },

            loadLayerInfos: function(){
                return xhr({ url: this.get('url')+'/', content: {f:'json'}, handleAs: "json" });
            },

            getLayerInfoAndSetLayerInfoAsJson: function(layerId) {
                var def = new Deferred();
                this.loadLayerInfos().then(lang.hitch(this,
                    function(res){
                        if(this['layerInfoAsJson'] == null){
                            this['layerInfoAsJson'] = [];
                        }
                        this['layerInfoAsJson'].push(res);
                        def.resolve(res);
                    }),
                    lang.hitch(this, function(err) {
                        def.reject();
                    })
                );
                return def;
            },

            getLayerExtent: function(layerId) {
                var def = new Deferred();
                if (this.layerInfoAsJson && this.layerInfoAsJson[layerId]) {
                    var extent = new Extent(this.layerInfoAsJson[layerId].extent);
                    def.resolve(extent);
                } else {
                    this.getLayerInfoAndSetLayerInfoAsJson(layerId).then(lang.hitch(this, function (res) {
                        def.resolve(new Extent(res.extent));
                    }))
                }
                return def;
            },

            /**
             * Appelé lorsque le layer principal est chargé avec succés.
             * @param loadedEvent
             * @memberOf spw.api.MapService
             */
            layerLoaded: function(loadedEvent) {
                var l = {};

                for(var k in loadedEvent.layer) {
                    if (typeof(loadedEvent.layer[k]) !== 'function') {
                        l[k] = loadedEvent.layer[k];
                    }
                }

                this._mergeLayerInfo(lang.mixin(l, {
                    parentLayerId: -1,
                    id: loadedEvent.layer.layerId
                }));

                this._afterLayerLoaded();
            },

            /**
             * Permet de charger la légende du service
             * @memberOf spw.api.MapService
             */
            loadLegend: function() {
                var legendUrl = this.get('url');

                if(legendUrl[legendUrl-1] == '/'){
                    legendUrl = legendUrl.substring(0, legendUrl-2);
                }

                legendUrl = legendUrl.substring(0, legendUrl.lastIndexOf('/'));

                this._requestLegend(legendUrl);
            },

            MapServiceLayer: declare('spw.api.FeatureMapServiceLayer', [MapServiceLayer], {

                generateHtmlLegend: function() {
                    var wrapper = domConstruct.create("div", {});
                    if(this.mapService.get('layer').renderer
                        && this.mapService.get('layer').renderer.colorInfo && this.mapService.get('layer').renderer.colorInfo.maxDataValue && !!document.createElement("canvas").getContext){
                        var container = domConstruct.create("div", {style:"position:relative;"}, wrapper);
                        var ctx = domConstruct.create("canvas", {width:"20px", height:"80px", style:"border: 1px solid lightgrey;"}, container).getContext("2d");
                        var grd = ctx.createLinearGradient(0,0,0,80);
                        var c1 = this.mapService.get('layer').renderer.colorInfo.colors[0];
                        var c2 = this.mapService.get('layer').renderer.colorInfo.colors[1];
                        grd.addColorStop(0,"rgb("+c2.r+","+c2.g+","+c2.b+")");
                        grd.addColorStop(1,"rgb("+c1.r+","+c1.g+","+c1.b+")");
                        ctx.fillStyle=grd;
                        ctx.fillRect(0,0,20,80);
                        domConstruct.create("div", { innerHTML: this.mapService.get('layer').renderer.label, style: "margin-bottom: 5px;"}, container, "first");
                        domConstruct.create("div", { innerHTML: this.mapService.get('layer').renderer.colorInfo.maxDataValue, style: "position:absolute;top:14px;left:26px;"}, container, "last");
                        domConstruct.create("div", { innerHTML: this.mapService.get('layer').renderer.colorInfo.minDataValue, style: "position:absolute;bottom:0px;left:26px;"}, container, "last");
                    } else {
                        var table = domConstruct.create("table", {style:"width:100%;"}, wrapper);
                        array.forEach(this.legends, lang.hitch(this, function(legend){
                            var row = domConstruct.create("tr", {}, table);
                            domConstruct.create("img", {
                                src: "data:"+legend.contentType+";base64,"+legend.imageData,
                                alt:legend.label, title: legend.label,
                                style: "vertical-align: middle;"
                            }, domConstruct.create("td", {}, row), 'first');
                            domConstruct.create("span", { innerHTML: legend.label }, domConstruct.create("td", { style: "width:100%;" }, row), "last");
                        }));
                    }
                    return wrapper;
                }

            })

        });

        return FeatureMapService;

    });