Source: widgets/SpwSpatialQuery.js

Retour à la documentation
/**
 * @class spw.widgets.SpwSpatialQuery
 */
define(["dojo/_base/declare", "spw/api/SpwBaseTemplatedWidget", "dojo/text!./templates/SpwSpatialQuery.html",
    "dojo/i18n!./nls/SpwSpatialQuery", "dojo/_base/lang", "esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters",
    "spw/api/MessageManager", "dojo/_base/array", "dojo/on", "dojo/dom-class","esri/geometry/Extent",
    "esri/request", "dojo/store/Memory", "spw/api/ProjectionManager",

    "dijit/form/FilteringSelect", "dijit/layout/ContentPane", "dijit/form/Button", "dijit/form/CheckBox", "dijit/layout/TabContainer",
    "dijit/layout/BorderContainer"],
        function(declare, SpwBaseTemplatedWidget, tmpl, labels, lang, IdentifyTask, IdentifyParameters, MessageManager,
                array, on, domClass, Extent, Request, Memory, ProjectionManager) {
            return declare("spw.widgets.SpwSpatialQuery", [SpwBaseTemplatedWidget], {

                templateString: tmpl,
                labels: labels,

                /* START Config */
                geolocalisationUrl: "//geoservices.wallonie.be/geolocalisation",
                insCommunesRequestServiceUrl: "http://geoservices.wallonie.be/arcgis/rest/services/IGN/LIMITES_ADMINISTRATIVES/MapServer/0",
                /* END Config */

                _initialPanelWidth: null,
                _currentGeom: null,

                _promises : null,

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

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

                	if(!this.widgets){
                		this.widgets = [ { "className": "spw/widgets/SpwIdentifyResult", "config": { "widgetTitle": "Résultat de l'identification", "allowUseSelectionIdentify":false, "exportCsvServerUrl":"/geoviewer/ExportCSV", "inToolbar": false, "position": "bottom", "resizable": true, "activated":false, "widgets": [ { "className": "spw/widgets/SpwIdentifyResultTable", "config": { "inToolbar": false, "position": "none", "activated":false, "widgets": [ { "className": "spw/widgets/SpwIdentifyResultRow", "config": { "inToolbar": false, "position": "none", "activated":false } } ] } } ] } } ];
                	}

                    this.loadResultWidget();
                },

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

                    this._promises = {};
                    this.watch("provinceList", this.onProvinceListChange);
                    this.watch("communeList", this.onCommuneListChange);
                    this._btnApplyFilter.on("click",lang.hitch(this,"onApplyFilter"));
                    this._selectProvince.watch("value",lang.hitch(this,"onSelectedProvinceChange"));
                    this._selectCommune.watch("value",lang.hitch(this,"onSelectedCommuneChange"));
                    this.loadAllCommuneList();
                    this.loadProvinceList();
                },

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

                    this.mainBorderContainer.resize();
                },

                startup: function(){
                    this.inherited(arguments);
                    if (this.get("advancedFilterCloseAtStartup")){
                        this.set("advancedFilterCloseAtStartup",false);
                    }
                },

                onDeactivate: function() {
                    this.inherited(arguments);
                    this.clearFilter();
                    for(promiseKey in this._promises){
                        if(this._promises[promiseKey] !== null){
                            var promise = this._promises[promiseKey];
                            this._promises[promiseKey] = null;
                            promise.cancel();
                        }
                    }

                    this.get("identifyResultWidget").onDeactivate();
                },

                loadProvinceList:function(){
                    this.displayLoadingImage();
                	this._promises.requestProvinceList = Request({
                		url : this.get("geolocalisationUrl")+"/rest/getListeProvincesRW", headers:{"Content-type":null}
                	}).then( lang.hitch(this,function(restResponse){
                    	this.set("provinceList", array.map(restResponse.provinces, function(p){return { name: p.nom }; }).sort(function(a,b){return a.name > b.name ? -1 : (a.name < b.name ? 1 : 0);}));
                        this.hideLoadingImage();
                    }));
                },

                loadAllCommuneList:function(){
                    this.displayLoadingImage();
                    this._promises.requestAllCommuneList = Request({
                    	url: this.get("geolocalisationUrl")+"/rest/getListeCommunes", headers:{"Content-type":null}
                    }).then( lang.hitch(this,function(restResponse){
                        this.set("allCommuneList", restResponse.communes);
                        this.hideLoadingImage();
                    }));
                },
                loadCommuneList:function(){
                    var province = this._selectProvince.get("value");
                    if(!province) return;

                    this.displayLoadingImage();
                    this._promises.requestCommuneList = Request({
                    	url: this.get("geolocalisationUrl")+"/rest/getListeCpsByProvince/"+province, headers:{"Content-type":null}
                	}).then( lang.hitch(this,function(restResponse){
                        var communes = this.get("allCommuneList"), communeList = [];
            			array.forEach(communes, function(c){
                    		array.some(restResponse.resultats, function(cp){
                				if(c.cps.indexOf(cp) > -1) { communeList.push({ name:c.nom, ins:c.ins }); return true; }
                			});
                		});
                        this.set("communeList", communeList.sort(function(a,b){return a.name > b.name ? -1 : (a.name < b.name ? 1 : 0);}));
                        this.hideLoadingImage();
                    }));
                },

                loadResultWidget: function(){
                    array.forEach(this.widgets, lang.hitch(this, function(widget){
                        if(widget.className == "spw/widgets/SpwIdentifyResult"){
                            require([widget.className], lang.hitch(this, function(widgetClass){
                                lang.mixin(widget.config, {spwViewer: this.spwViewer});
                                this.set("identifyResultWidget", new widgetClass(widget.config));
                            }));
                        }
                    }));
                },

                onProvinceListChange:function(){
                    var options = new Array();

                    for (var i = this.get("provinceList").length - 1; i >= 0; i--) {
                        var province = this.get("provinceList")[i],
                        name = province.name;
                        options.push({
                            label:name,
                            value:name
                        });
                    };

                    this._selectProvince.set("store", new Memory({
                        data: options,
                        idProperty: 'label'
                    }));
                },

                onSelectedProvinceChange:function(){
                    if (this._selectProvince.get("value") == null){
                	   this._selectCommune.set("disabled", true);
                    } else {
                        this._selectCommune.set("disabled", false);
                        this.loadCommuneList();
                    }
                	this._selectCommune.set('displayedValue', '');
                },

                onSelectedCommuneChange: function(){
                	this._currentGeom = null;
                    var ins = this._selectCommune.get("item") ? this._selectCommune.get("item").value : null;

                    this.requestCommuneByIns(ins, lang.hitch(this, function(restResponse){
                        var feature = restResponse&&restResponse.features&&restResponse.features[0];
                        feature.geometry.spatialReference = restResponse.spatialReference;
                        this._currentGeom = esri.geometry.fromJson(feature.geometry);

                        if (feature.geometry.spatialReference.wkid !== this.spwViewer.get('spatialReference').wkid) {
                            this._currentGeom = ProjectionManager.getInstance().transform(this.communesSrid, this.spwViewer.get('spatialReference').wkid, this._currentGeom);
                        }
                    }));
                },

                onCommuneListChange:function(){
                	var options = new Array();

                    for (var i = this.get("communeList").length - 1; i >= 0; i--) {
                        var commune = this.get("communeList")[i],
                        name = commune.name,
                        ins = commune.ins;
                        options.push({
                            label:name,
                            value:ins
                        });
                    }
                    this._selectCommune.set("store", new Memory({
                        data: options,
                        idProperty: 'label'
                    }));
                },

                onApplyFilter:function(){
                    this.displayLoadingImage();
                    this.filterToWhereClause();
                },

                filterToWhereClause:function(){
                    var ins = this._selectCommune.get("item") ? this._selectCommune.get("item").value : null;

                    if (ins!=null){
                        if(this._currentGeom){
                            this.requestServicesIdByGeom();
                        } else {
                        	this.watch('_currentGeom', lang.hitch(this, this.requestServicesIdByGeom));
                        }
                    }
                },
                requestCommuneByIns:function(ins, callback, error){
                    this._promises.requestAllCommuneList = Request({
                    	url: this.get("insCommunesRequestServiceUrl") + "/query?f=pjson&outFields=*&where=INS%3D" + ins, headers:{"Content-type":null}
                    }).then(callback);
                },
                requestServicesIdByGeom:function(){
                    var mapServices = this.spwViewer.get('spwMap').getMapServices({ visible: true, isBaseMap: false });
                    this.set("requestedServices",mapServices);
                    this.set("pendingRequestedServicesForId",mapServices.length);
                    this.identify(mapServices);
                },
                zoomToExtent:function(extent){
                    this.spwViewer.get('spwMap').zoomToExtent(extent);
                },
                identify:function(mapServices){
                    this.set("identifyTaskQueue",new Array());
                    if(this.get("identifyResultWidget")){
                        this.get("identifyResultWidget").clearResults();
                        if(this.get("identifyResultWidget").get('activated')){
                            this.get("identifyResultWidget").onDeactivate();
                        }
                        this.get("identifyResultWidget").displayLoadingImage();
                        this.set("resultFound",false);
                    }
                    this.displayLoadingImage();
                    this.set("currentResultExtent",null);
                    //Create identifyTasks for visible map services
                    for(var i=0; i<mapServices.length; i++){
                        var mapService=mapServices[i],
                        layers = mapService.getParentMapServiceLayers(),
                        identifiablesLayers=new Array();
                        for (var j = 0; j <= layers.length - 1; j++) {
                            var layer = layers[j];
                            if (layer.get("identifiable")){
                                layers = layers.concat(layer.get("subLayers"));
                                identifiablesLayers.push(layer);
                            }
                            /*else {
                                var layerDef = "", layerDefinitions = layer.mapService.layer.layerDefinitions||new Array();
                                layerDef = "1=2";
                                layerDefinitions[layer.layerId]=layerDef;
                                layer.mapService.layer.setLayerDefinitions(layerDefinitions);
                            }*/
                        };
                        this.pushIdentifyTaskInQueue(mapService, identifiablesLayers);
                    }
                    this.executeIdentify();
                },

                pushIdentifyTaskInQueue: function(mapService, layers) {
                    var identifyParams = new IdentifyParameters();
                    identifyParams.tolerance = 0;
                    identifyParams.returnGeometry = true;
                    identifyParams.spatialReference = this.spwViewer.get("spatialReference");
                    var j=0;
                    var arrayIds= new Array();
                    var tabLayers = new Array();
                    var layerDefinitions=new Array();

                    for (var i = layers.length - 1; i >= 0; i--)
                    {
                        var layer = layers[i];
                        if (layer.isVisible()) {
                            tabLayers.push({layer:layer});
                            arrayIds.push(layer.get('layerId'));
                            layerDefinitions[layer.get('layerId')]=this.getLayerDefinitionForLayer(layer);
                        }
                    }
                    if (arrayIds.length>0){
                        identifyParams.layerIds = arrayIds;
                        identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_ALL;
                        identifyParams.width  = this.spwViewer.get('spwMap').get('esriMap').width;
                        identifyParams.height = this.spwViewer.get('spwMap').get('esriMap').height;

                        identifyParams.geometry = this._currentGeom;

                        identifyParams.mapExtent = this.spwViewer.get('spwMap').get('esriMap').extent;
                        //Will work only with a ArcGIS Server 10 MapService (ESRI limitation)
                        identifyParams.layerDefinitions = layerDefinitions;
                        var identifyTask = new IdentifyTask(mapService.get('url'));
                        this.get("identifyTaskQueue").push({identifyTask:identifyTask,identifyParams:identifyParams,layers:tabLayers});
                    }
                },

                getLayerDefinitionForLayer:function(layer){
                    var layerDef = null,
                    queryFields=layer.get("queryFields");
                    if (queryFields){
                        for (var i = queryFields.length - 1; i >= 0; i--) {
                            var queryField = queryFields[i],
                            esriField=queryField.get("esriField"),
                            value=queryField.get("value");
                            if(value!=="" && (value || value===0)){
                                layerDef=(layerDef==null?"":layerDef+" AND ");
                                switch(esriField.type){
                                    case "esriFieldTypeString":
                                        escaped_value = value.replace("'","''");
                                        if(esriField.name == 'NAME' || esriField.name == 'LOCALITE'){
                                            layerDef+="LOWER("+esriField.name+") LIKE '"+escaped_value.toLowerCase()+"'";
                                        }else{
                                            layerDef+="LOWER("+esriField.name+") LIKE '%"+escaped_value.toLowerCase()+"%'";
                                        }
                                        break;
                                    case "esriFieldTypeDate":
//                                      layerDef+="("+ esriField.name+">=TO_DATE('"+(value.getDate()+"-"+(value.getMonth()+1)+"-"+value.getFullYear() + " 00:00:00")+"', 'DD-MM-YYYY HH24:MI:SS') AND " + esriField.name+"<=TO_DATE('"+(value.getDate()+"-"+(value.getMonth()+1)+"-"+value.getFullYear() + " 23:59:59")+"', 'DD-MM-YYYY HH24:MI:SS'))";
                                        layerDef+= esriField.name + " like '" + (value.getDate()>9 ? value.getDate() : "0"+value.getDate())+"/"+((value.getMonth()+1) > 9 ? (value.getMonth()+1) : "0"+(value.getMonth()+1))+"/"+((value.getFullYear()+"").substring(2))+"%'";
                                        break;
                                    case "esriFieldTypeSmallInteger":
                                    case "esriFieldTypeOID":
                                    case "esriFieldTypeInteger":
                                    case "esriFieldTypeSingle":
                                    case "esriFieldTypeDouble":
                                    default:
                                        layerDef+=this.getCriteriaValue(queryField);
                                }

                            }
                        };
                    }
                    return layerDef;

                },

                executeIdentify:function(){
                    if (this.get("identifyTaskQueue").length>0){
                        var current = this.get("identifyTaskQueue").pop();
                        try{
                            current.identifyTask.execute(current.identifyParams,
                                lang.hitch(this,function(results) {
                                    this.onResultIdentifyReceived(results,current.layers);
                                    this.set("identifyPending",false);

                                    if (!this.executeIdentify()){
                                        if(this.get("identifyResultWidget")){
                                            this.get("identifyResultWidget").hideLoadingImage();
                                        }
                                        this.hideLoadingImage();
                                    }
                                }),
                                lang.hitch(this,function(error){
                                    MessageManager.getInstance().notifyError("Erreur lors de l'identification : " + error.toString());
                                    this.hideLoadingImage();
                                    if(this.get("identifyResultWidget")){
                                        this.get("identifyResultWidget").hideLoadingImage();
                                    }
                                })
                            );
                        }catch(e){
                            console.error(e);
                        }
                        return true;
                    }
                    this.hideLoadingImage();
                    return false;
                },

                onResultIdentifyReceived:function(results,opts){

                    var j=0;
                    while(j<opts.length){
                        var i = 0;
                        var tabResults = new Array();

                        while (i<results.length){

                            if (opts[j].layer.get('layerId')==results[i].layerId){
                                tabResults.push(results[i]);
                            }
                            i++;
                        }
                        if(this.get("identifyResultWidget")){
                            if(this._cbShowInResultTable.get("checked") && tabResults.length>0){
                                this.updateExtentFromResults(tabResults);
                                this.get("identifyResultWidget").onActivate();
                                this.get("identifyResultWidget").addResults(tabResults,opts[j].layer);
                            }

                        }
                        this.updateResultOnMap(tabResults,opts[j].layer);
                        j++;
                    }

                },
                updateResultOnMap:function(results,layer){

                    if (layer.get("featureDefinition")){
                        var layerDef = "",
                        layerDefinitions = layer.mapService.layer.layerDefinitions||new Array(),
                        ids=new Array(),
                        featureDefinition=layer.get("featureDefinition"),
                        idField=this.getIdField(featureDefinition.fields);

                        for (var i = results.length - 1; i >= 0; i--) {
                            var result = results[i],
                            attributes=result.feature.attributes;
                            id = attributes[idField.alias];
                            ids.push(id);
                        };
                        layerDef = ids.length>0?idField.name+" IN("+ids.join()+")":"1=2";

                        layerDefinitions[layer.layerId]=layerDef;
                        layer.mapService.layer.setLayerDefinitions(layerDefinitions);
                    }else{
                        this.loadFeatureDefinition(layer,lang.hitch(this,function(){
                            this.updateResultOnMap(results,layer);
                        }));
                    }
                },
                loadFeatureDefinition:function(layer,callback){
                    this._promises.requestFeatureDefinition = Request({
                    	url:layer.mapService.get("url")+"/"+layer.get("layerId")+"?f=pjson", headers:{"Content-type":null}
                    }).then( lang.hitch(this,function(restResponse){
                        layer.set("featureDefinition",restResponse);
                        callback();
                    }));
                },
                getIdField:function(fields){
                    var idField = {name:"OBJECTID",alias:"OBJECTID",type: "esriFieldTypeOID"};

                    if(fields){
                        for (var i = fields.length - 1; i >= 0; i--) {
                            if (fields[i].type=="esriFieldTypeOID"){
                                return fields[i];
                            }
                        };
                    }
                    return idField;
                },
                clearFilter:function(){
                    var mapServices = this.spwViewer.get('spwMap').getMapServices({ visible: true, isBaseMap: false });
                    for (var i = mapServices.length - 1; i >= 0; i--) {
                        var mapService=mapServices[i];
                        mapService.layer.setLayerDefinitions([]);
                    };
                },
                filterServices:function(){

                },
                identifyFeatures:function(){

                },
                displayLoadingImage: function() {
                    this.showLoading();
                },

                hideLoadingImage: function() {
                    this.hideLoading();
                },
                updateExtentFromResults:function(results){
                    var extent = this.get("currentResultExtent");
                    for (var i = results.length - 1; i >= 0; i--) {
                        var result = results[i],
                        geom = esri.geometry.fromJson(result.feature.geometry),
                        geomExtent = null;
                        switch(geom.type){
                            case "point":
                                geomExtent = new Extent(geom.x-200,geom.y-200,geom.x+200,geom.y+200,this.spwViewer.get('spwMap').get('esriMap').spatialReference);
                                break;
                            case "polygon":
                            case "multipoint":
                            case "polyline":
                                geomExtent = geom.getExtent();
                                break;
                            case "extent":
                                geomExtent = geom;
                                break;
                        }
                        if (extent){
                            extent=extent.union(geomExtent);
                        }else{
                            extent=geomExtent;
                        }
                    };
                    extent=extent.setSpatialReference(this.spwViewer.get('spwMap').get('esriMap').spatialReference);
                    this.set("currentResultExtent",extent);
                    this.zoomToExtent(extent);
                }
            });
        });