Source: api/DataLayer.js

Retour à la documentation
define(["dojo/_base/declare", "esri/layers/GraphicsLayer", "dojo/_base/lang",
        "dojo/_base/array", "esri/graphic", "esri/renderers/jsonUtils",
        "spw/api/GeometryConverter", "esri/InfoTemplate", "esri/request",
        "spw/api/ProjectionManager", "esri/graphicsUtils", "esri/SpatialReference", "dojo/_base/Color",
        "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/jsonUtils"
    ],
    function(declare, GraphicsLayer, lang, array, Graphic, jsonRenderer,
        GeometryConverter, InfoTemplate, request, ProjectionManager, graphicsUtils, SpatialReference,
             Color, SimpleMarkerSymbol, SimpleLineSymbol, jsonSymbolUtils) {

        return declare("spw.api.DataLayer", [GraphicsLayer], /** @lends spw.api.DataLayer.prototype */{

            //START : options
            _options: null,

            //url des données
            url: null,

            //features: tableau de features
            features: null,

            //format des données cartographique : ESRIJSON;GEOJSON;WKT; (TODO GML)
            format: null,

            //style options to configure rendering of graphics on map
            style: null,
            //END   : options

            /**
             * @constructs
             */
            constructor: function(options) {
                this._options = options;
                lang.mixin(this, {
                    format: "GEOJSON"
                }, options);
                if(!this.style){
                	this.style = {};
                }
                //this.loaded = false;
            },

            getExtent: function() {
                return graphicsUtils.graphicsExtent(this.graphics);
            },

            // override esri/layers/GraphicsLayer methods
            _setMap: function(map, surface) {
                // GraphicsLayer will add its own listener here
                var div = this.inherited(arguments);

                this.spwMap = map;
                //get all data by url or by property
                this.fetchData();

                return div;
            },

            fetchData: function() {
                if (this.url) {
                    request({
                        url: this.url,
                        handleAs: "json"
                    }).then(lang.hitch(this, function(data) {
                        this.features = data.features ? data.features : data;
                        this.processFeatures();
                    }), lang.hitch(this, function(err) {
                        this.emit('error', lang.mixin(err, {
                            type: 'loadError'
                        }));
                    }));
                } else if (this.features) {
                    this.processFeatures();
                } else if (this.graphicsJSON && typeof this.graphicsJSON == 'string') {
                    this.jsonToGraphics(this.graphicsJSON);
                } else {
                    this.dataLoaded = true;
                    this.onLoad(this);
                    
                    this.emit("dataLoaded", {
                        layer: this
                    });
                }
            },

            _getRendererTypeBasedOnGeometryType: function(geometryType) {
                switch (geometryType) {
                    case 'point':
                    case 'multipoint':
                        return this._buildRenderer('point', this.style.fillColor);
                        break;
                    case 'line':
                    case 'polyline':
                        return this._buildRenderer('line', this.style.fillColor);
                        break;
                    case 'polygon':
                        return this._buildRenderer('polygon', this.style.fillColor);
                        break;
                }
            },

            _configureRenderer: function() {
                if (this.style.fillColor) {
                    array.forEach(this.graphics, lang.hitch(this, function(g) {
                        g.symbol = null;
                    }))
                }
                var allGeometriesAreOfSameType = true;
                var firstGeometryType = null;
                if (this.graphics && this.graphics.length > 0) {
                    firstGeometryType = this.graphics[0].geometry.type;
                    array.some(this.graphics, lang.hitch(this, function(g) {
                        var geometry = g.geometry;
                        if (firstGeometryType != geometry.type) {
                            allGeometriesAreOfSameType = false;
                            return false;
                        }
                    }))
                }

                //If all geometries are of the same type, use renderer
                if (allGeometriesAreOfSameType) {
                    var defaultRenderer = null;
                    if (firstGeometryType) {
                        defaultRenderer = this._getRendererTypeBasedOnGeometryType(firstGeometryType);
                    }
                    if (this.rendererConfig || defaultRenderer) {
                        var renderer = jsonRenderer.fromJson(this.rendererConfig ? this.rendererConfig : defaultRenderer);
                        this.setRenderer(renderer);
                    } else {
                        console.error("DataLayer has no renderer !");
                    }
                } else {
                    //else, set symbol on each graphics
                    array.forEach(this.graphics, lang.hitch(this, function(g) {
                        if (!g.symbol) {
                            var geometryType = g.geometry.type;
                            var defaultRendererConfig = this._getRendererTypeBasedOnGeometryType(geometryType);
                            var renderer = jsonRenderer.fromJson(defaultRendererConfig);
                            g.setSymbol(renderer.getSymbol());
                        }
                    }));
                }
                this.redraw();
            },

            _buildRenderer: function(geometryType, color) {
                color = color ? new Color(color) : [0, 38, 115, 255];
                switch (geometryType) {
                    case 'point':
                        return {
                            "type": "simple",
                            "symbol": {
                                "type": "esriSMS",
                                "style": "esriSMSCircle",
                                "color": color,
                                "width": 0.4
                            },
                            "label": "",
                            "description": ""
                        };
                    case 'line':
                        return {
                            "type": "simple",
                            "symbol": {
                                "type": "esriSLS",
                                "style": "esriSLSSolid",
                                "color": color,
                                "width": 2
                            }
                        };
                    case 'polygon':
                        return {
                            "type": "simple",
                            "symbol": {
                                "type": "esriSFS",
                                "style": "esriSFSSolid",
                                "color": color,
                                "outline": {
                                    "type": "esriSLS",
                                    "style": "esriSLSSolid",
                                    "color": color,
                                    "width": 2
                                }
                            }
                        };
                }
            },

            processFeatures: function() {
                var info = this.infoTemplate ? new InfoTemplate(this.infoTemplate) : null;
                array.forEach(this.features, lang.hitch(this, function(d) {
                    if (d.geometry) {
                        var geom = this.processGeometry(d.geometry, d.srid);
                        if((!geom.rings || (geom.rings && geom.rings.length > 0)) || (geom.paths && geom.paths.length > 0)){
	                        var g = new Graphic(
	                            geom, 
	                            null,
	                            d.properties,
	                            info
	                        );
	                        if (d.symbol) {
	                            g.symbol = jsonSymbolUtils.fromJson(d.symbol);
                            }
	                        this.add(g);
                        }
                    }
                }));

                this._configureRenderer();

                this.dataLoaded = true;
                this.onLoad(this);
                
                this.emit("dataLoaded", {
                    layer: this
                });
            },

            importData: function(geoJsonFeatures) {
                if (typeof geoJsonFeatures == 'string') {
                    geoJsonFeatures = JSON.parse(geoJsonFeatures);
                }
                if (geoJsonFeatures.layer && this.parentLayer) {
                    this.parentLayer.set('label', geoJsonFeatures.layer);
                }
                if (geoJsonFeatures.type == "FeatureCollection") {
                    var features = geoJsonFeatures.features;
                    var crs = geoJsonFeatures.crs;
                    var srid = 4326;
                    if (crs && crs.properties && crs.properties.code) {
                        srid = crs.properties.code;
                    }
                    array.forEach(features, lang.hitch(this, function(feature) {
                        var esriGeom = this.processGeometry(feature.geometry, srid);
                        var symbol = null;
                        if (feature.symbol) {
                            symbol = jsonSymbolUtils.fromJson(feature.symbol);
                        }
                        var graph = new Graphic(esriGeom, symbol, feature.properties);
                        this.add(graph);
                    }))
                    this._configureRenderer();
                }
            },

            processGeometry: function(geometry, srid) {
                var geom;
                switch (this.format) {
                    case "GEOJSON":
                        geom = GeometryConverter.geoJSONToEsri(geometry, {sr: srid});
                        break;
                    case "ESRIJSON":
                        geom = GeometryConverter.instanciateEsriGeometry(geometry);
                        break;
                    case "WKT":
                        geom = GeometryConverter.wktToEsri(geometry, {sr: srid});
                        break;
                    case "SHAPE":
                        geom = GeometryConverter.geoJSONToEsri(geometry, {sr: srid});
                        break;
                    case "NATIVE":
                        geom = geometry;

                        // if (srid) {
                        //     geom.setSpatialReference(new SpatialReference({wkid: srid}));
                        // }
                        break;
                    default:
                        this.emit('error', lang.mixin(new Error('unknow format: ' + this.format), {
                            type: 'loadError'
                        }));
                }
                var spatialReference = this.spwMap.spatialReference ? this.spwMap.spatialReference : this.spwMap.getSpatialReference();
                var mapWkid = spatialReference.wkid;
                if (geom && this.inSrId && mapWkid != this.inSrId) {
                    geom = ProjectionManager.getInstance().transform(this.inSrId, this.spwMap.spatialReference.wkid, geom);
                }
                else if (geom && geom.spatialReference && geom.spatialReference.wkid != mapWkid) {
                    geom = ProjectionManager.getInstance().transform(geom.spatialReference.wkid, mapWkid, geom);
                }

                geom.setSpatialReference(spatialReference);

                return geom;
            },
            /**
             * Ajoute des données representées en JSON sur le service
             * @param graphics les données à ajouter au format JSON
             * @param spwMap la référence à SpwMap
             */
            jsonToGraphics: function(graphics) {

                // this.clear();

                // spwMap = spwMap || this.spwMap;

                this.graphics = [];

                var data = JSON.parse(graphics);

                // var viewerSrid = spwMap.getSpatialReferenceSRID();
                var viewerSrid = this.spwMap.spatialReference.wkid;

                array.forEach(data, lang.hitch(this, function(d) {

                    var g = new Graphic(d);

                    if (g.geometry.spatialReference.wkid !== viewerSrid) {
                        g.geometry = ProjectionManager.getInstance().transform(g.geometry.spatialReference.wkid, viewerSrid, g.geometry);
                    }

                    this.add(g);

                    if (d._buffers) {
                        g._buffers = array.map(d._buffers, lang.hitch(this, function(buf) {
                            var tmp = new Graphic(buf);

                            if (tmp.geometry.spatialReference.wkid !== viewerSrid) {
                                tmp.geometry = ProjectionManager.getInstance().transform(tmp.geometry.spatialReference.wkid, viewerSrid, tmp.geometry);
                            }

                            if (buf.associatedMesure) {
                                tmp.associatedMesure = new Graphic(buf.associatedMesure);
                                tmp.associatedMesure.associatedGraphic = tmp;

                                if (tmp.associatedMesure.geometry.spatialReference.wkid !== viewerSrid) {
                                    tmp.associatedMesure.geometry = ProjectionManager.getInstance().transform(tmp.associatedMesure.geometry.spatialReference.wkid, viewerSrid, tmp.associatedMesure.geometry);
                                }

                                this.add(tmp.associatedMesure);
                            }

                            tmp._buffer = g;
                            this.add(tmp);
                            return tmp;
                        }));

                        g._bufferValue = d._bufferValue;
                        g._repetitionValue = d._repetitionValue;
                        g._bufferLabels = d._bufferLabels;
                    }

                    if (d._coordinates) {
                        g._coordinates = new Graphic(d._coordinates);
                        g._coordinates.associatedGraphic = g;

                        if (g._coordinates.geometry.spatialReference.wkid !== viewerSrid) {
                            g._coordinates.geometry = ProjectionManager.getInstance().transform(g._coordinates.geometry.spatialReference.wkid, viewerSrid, g._coordinates.geometry);
                        }

                        this.add(g._coordinates);
                    }

                    if (d.associatedMesure) {
                        g.associatedMesure = new Graphic(d.associatedMesure);
                        g.associatedMesure.associatedGraphic = g;
                        g.associatedMesure.selectedValue = d.selectedMesureValue;

                        if (g.associatedMesure.geometry.spatialReference.wkid !== viewerSrid) {
                            g.associatedMesure.geometry = ProjectionManager.getInstance().transform(g.associatedMesure.geometry.spatialReference.wkid, viewerSrid, g.associatedMesure.geometry);
                        }

                        this.add(g.associatedMesure);
                    }

                    if (d.associatedArea) {
                        g.associatedArea = new Graphic(d.associatedArea);
                        g.associatedArea.associatedGraphic = g;
                        g.associatedArea.selectedValue = d.selectedAreaValue;

                        if (g.associatedArea.geometry.spatialReference.wkid !== viewerSrid) {
                            g.associatedArea.geometry = ProjectionManager.getInstance().transform(g.associatedArea.geometry.spatialReference.wkid, viewerSrid, g.associatedArea.geometry);
                        }

                        this.add(g.associatedArea);
                    }
                }));

                this._configureRenderer();

                this.dataLoaded = true;
                this.onLoad(this);
                
                this.emit("dataLoaded", {
                    layer: this
                });
            },

            add: function(graphic) {
                this.inherited(arguments);
                this.graphicsJSON = this.graphicsToJson();
            },

            /**
             * Convertir les données du service au format JSON
             * @return les données au format JSON
             */
            graphicsToJson: function() {
                var data = [];
                array.forEach(this.graphics, lang.hitch(this, function(g) {
                    if (g._buffer) {
                        return;
                    }

                    if (g.associatedGraphic) {
                        return;
                    }

                    var _json = g.toJson();

                    if (g._buffers) {
                        lang.mixin(_json, {
                            _buffers: array.map(g._buffers, function(buf) {
                                var tmp = buf.toJson();

                                if (buf.associatedMesure) {
                                    tmp.associatedMesure = buf.associatedMesure.toJson();
                                }

                                return tmp;
                            }),
                            _bufferValue: g._bufferValue,
                            _repetitionValue: g._repetitionValue,
                            _bufferLabels: g._bufferLabels
                        });
                    }

                    if (g._coordinates) {
                        lang.mixin(_json, {
                            _coordinates: g._coordinates.toJson()
                        });
                    }

                    if (g.associatedMesure) {
                        lang.mixin(_json, {
                            associatedMesure: g.associatedMesure.toJson(),
                            selectedMesureValue: g.associatedMesure.selectedValue
                        });
                    }

                    if (g.associatedArea) {
                        lang.mixin(_json, {
                            associatedArea: g.associatedArea.toJson(),
                            selectedAreaValue: g.associatedArea.selectedValue
                        });
                    }

                    data.push(_json);
                }));
                return JSON.stringify(data);
            }

        });
    });