Retour à la documentation
/**
* @class spw.widgets.SpwQuerySearch
*/
define(["dojo/_base/declare", "spw/api/SpwBaseTemplatedWidget", "dojo/text!./templates/SpwQuerySearch.html",
"dijit/form/FilteringSelect", "esri/tasks/query", "esri/tasks/QueryTask", "dojo/_base/lang",
"dojo/store/Memory", "dojo/store/util/SimpleQueryEngine", "spw/api/Utils", "dojo/_base/array", "esri/request",
"spw/api/MessageManager", "dojo/i18n!./nls/SpwQuerySearch", "dojo/dom-style", "dojo/dom-construct", "spw/api/GeometryConverter", "spw/api/ConfigLoader",
"dijit/form/Button"],
function(declare, SpwBaseTemplatedWidget, template,
FilteringSelect, Query, QueryTask, lang,
Memory, SimpleQueryEngine, Utils, array, request,
MessageManager, labels, domStyle, domConstruct, GeometryConverter, ConfigLoader) {
return declare("spw.widgets.SpwQuerySearch", [SpwBaseTemplatedWidget], /** @lends spw.widgets.SpwQuerySearch.prototype */{
templateString: template,
labels: labels,
searchLabel: null,
comboBoxServiceFields: null,
orderByField: null,
displayFieldsTemplate: null,
queryServiceUrl: null,
searchFilteringSelect: null,
serviceMainField: null,
configurationValide: false,
resultFeature: null,
maxRecordCountService:100,
esriOIDField: null,
distinctValues: true,
_layerInfo: null,
/**
* @constructs
* @param config
*/
constructor: function(config){
if (config == null) {
MessageManager.getInstance().notifyError("L'outil de query ne fonctionnera pas car il manque des paramètres obligatoires.");
this.configurationValide = false;
return;
}
var viewerConfig = ConfigLoader.getInstance().get('viewer');
if(config.tokenSecured && viewerConfig.secureServerUrl){
config.queryServiceUrl = viewerConfig.secureServerUrl + "?service=" + config.queryServiceUrl;
} else if(config.networkSecured && viewerConfig.secureServerUrl){
config.queryServiceUrl = viewerConfig.secureServerUrl + "?noToken=true&service=" + config.queryServiceUrl;
}
if (config.layer && config.layer.mapService && config.layer.mapService.type === "WMS") {
config.serviceType = "WMS";
config.queryServiceUrl = config.layer.mapService.get('url').replace("/wms", "/ows");
config.searchLabel = config.layer.queryableLabel;
config.comboBoxServiceFields = config.layer.queryableFields;
config.displayFieldsTemplate = config.layer.queryableTemplate;
config.orderByField = config.layer.queryableOrder;
config.distinctValues = config.layer.distinctValues == null ? true : config.layer.distinctValues;
if(!config.layer.queryableFields){
this.configurationValide = false;
return;
}
} else if(config.layer){
config.queryServiceUrl = config.layer.mapService.get('url') + "/" + config.layer.layerId;
config.searchLabel = config.layer.queryableLabel;
config.comboBoxServiceFields = config.layer.queryableFields;
config.displayFieldsTemplate = config.layer.queryableTemplate;
config.orderByField = config.layer.queryableOrder;
config.distinctValues = config.layer.distinctValues == null ? true : config.layer.distinctValues;
}
if (config.queryServiceUrl == null) {
MessageManager.getInstance().notifyError("L'outil de query ne fonctionnera pas car il manque des paramètres obligatoires.");
this.configurationValide = false;
return;
}
if (config.comboBoxServiceFields != null) {
this.comboBoxServiceFields = config.comboBoxServiceFields;
}
else {
this.comboBoxServiceFields = null;
}
if (config.searchLabel != null) {
this.searchLabel = config.searchLabel;
} else {
this.searchLabel = "Données";
}
if (config.orderByField != null) {
this.orderByField = config.orderByField;
} else {
this.orderByField = this.comboBoxServiceFields == null ? null : this.comboBoxServiceFields[0];
}
if (config.displayFieldsTemplate != null) {
this.displayFieldsTemplate = config.displayFieldsTemplate;
} else {
this.displayFieldsTemplate = null;
}
this.configurationValide = true;
},
postCreate: function() {
this.inherited(arguments);
this.searchFilteringSelect = new FilteringSelect({
hasDownArrow: true,
autoComplete: false
}, this.searchFilteringSelectDiv);
if (this.configurationValide) {
// get the max number of records return by services
this.showLoading(null, labels.dataLoading);
this.getJSON(this.queryServiceUrl,
lang.hitch(this, function(response) {
this._layerInfo = response;
if(response.maxRecordCount) {
this.maxRecordCountService = response.maxRecordCount;
}
if(!this.esriOIDField) {
this.esriOIDField = this.parseEsriOIDField(response);
}
this.getAllResults();
}),
lang.hitch(this,function(error){
this.hideLoading();
this.enableForm(false);
console.info("[SpwQuerySearch] getJSON service failed");
// MessageManager.getInstance().notifyError("L'outil de query ne fonctionnera pas car le service ne répond pas. ["+this.queryServiceUrl+"]");
})
);
} else {
this.enableForm(false);
}
},
parseEsriOIDField: function(response) {
var esriFieldTypeOID = "OBJECTID";
if(response && response.fields && response.fields.length > 0) {
array.some(response.fields, function(field) {
if(field.type == "esriFieldTypeOID") {
esriFieldTypeOID = field.name;
return true;
}
return false;
});
}
return esriFieldTypeOID;
},
linkQueryResultsToSelect: function(featureSet){
var resultFeatures = featureSet.features;
if(!this.serviceMainField){
this.serviceMainField = featureSet.displayFieldName;
}
var dataSelect = [];
if (this.comboBoxServiceFields == null) {
this.displayLabelNode.innerHTML = this.serviceMainField + ' : ';
}
for (var i=0, il = resultFeatures.length; i < il; i++) {
resultFeatures[i].attributes.displayLabel = this.displayFieldsTemplate == null ?
resultFeatures[i].attributes[this.serviceMainField] : this.displayFieldsTemplate;
resultFeatures[i].attributes.searchLabel = "";
if (this.comboBoxServiceFields == null) {
resultFeatures[i].attributes.searchLabel = resultFeatures[i].attributes[this.serviceMainField];
}
else {
for (var j = 0; j < this.comboBoxServiceFields.length; j++) {
resultFeatures[i].attributes.displayLabel = resultFeatures[i].attributes.displayLabel.replace("${"+this.comboBoxServiceFields[j]+"}", resultFeatures[i].attributes[this.comboBoxServiceFields[j]]);
resultFeatures[i].attributes.searchLabel += resultFeatures[i].attributes[this.comboBoxServiceFields[j]]+" - ";
}
resultFeatures[i].attributes.searchLabel = resultFeatures[i].attributes.searchLabel.substring(0, resultFeatures[i].attributes.searchLabel.length-3);
}
resultFeatures[i].attributes.searchValue = Utils.removeAccent(resultFeatures[i].attributes.searchLabel);
resultFeatures[i].attributes.serviceMainField = resultFeatures[i].attributes[this.serviceMainField];
dataSelect[i] = resultFeatures[i].attributes;
dataSelect[i].feature = resultFeatures[i];
}
var memoryStore = new Memory({
data: dataSelect
});
if (this.displayFieldsTemplate != null) {
memoryStore.queryEngine = lang.hitch(this, this.createQueryEngine);
}
else {
this.searchFilteringSelect.set('fetchProperties', {
sort: [{
attribute: 'displayLabel'
}]
});
}
this.searchFilteringSelect.set('store', memoryStore);
this.searchFilteringSelect.set('searchAttr', 'searchLabel');
this.searchFilteringSelect.set('labelAttr', 'displayLabel');
this.searchFilteringSelect.set('labelType', 'html');
this.searchFilteringSelect.set('queryExpr', '${0}*');
this.hideLoading();
},
createQueryEngine: function(query, options) {
var qS = query.searchLabel;
qS.compile(Utils.removeAccent(qS.source));
var filteringFunction = function(object){
return qS.test(object.searchValue);
};
var orderField = this.orderByField;
var execute = function(arr) {
var ar = array.filter(arr, filteringFunction);
ar.sort(function(a,b){
if (a[orderField] == b[orderField]) return 0;
if (a[orderField] < b[orderField]) return -1;
return 1;
});
return ar;
};
execute.matches = filteringFunction;
return execute;
},
showLoading: function(node, msg) {
this.inherited(arguments);
this.loadingText.innerHTML = msg;
},
hideLoading: function() {
this.inherited(arguments);
this.loadingText.innerHTML = '';
},
buttonGoClicked: function(){
if(this.searchFilteringSelect.item && this.searchFilteringSelect.item.feature && this.searchFilteringSelect.item.feature.geometry){
this.displayResultAndZoom({features: [this.searchFilteringSelect.item.feature]});
return;
}
var queryFieldUsed = this.serviceMainField;
if(this.queryField) {
queryFieldUsed = this.queryField;
}
if(this.searchFilteringSelect.item != null && this.searchFilteringSelect.item[queryFieldUsed] != null){
this.showLoading(null, labels.searchingTxt);
var query = new Query();
query.returnGeometry = true;
query.outFields = ["*"];
if(this.getFieldItemType(queryFieldUsed) == 'esriFieldTypeString'){
query.where = queryFieldUsed + "='"+this.searchFilteringSelect.item[queryFieldUsed].toString().replace(/'/gim, "''")+"'";
} else {
query.where = queryFieldUsed + "="+this.searchFilteringSelect.item[queryFieldUsed];
}
var queryTask = new QueryTask(this.queryServiceUrl);
queryTask.execute(query,lang.hitch(this, this.displayResultAndZoom));
}
else {
MessageManager.getInstance().notifyError(this.labels.invalidSelection);
}
},
getFieldItemType: function(queryField){
var type = '';
if(this._layerInfo && this._layerInfo.fields && this._layerInfo.fields.length > 0){
array.some(this._layerInfo.fields, function(field){
if(field.name == queryField){
type = field.type;
return true;
}
return false;
});
}
return type;
},
displayResultAndZoom: function(featureSet){
this.hideLoading();
if(this.resultFeature){
this.spwViewer.get('spwMap').removeFeature(this.resultFeature);
}
if(featureSet.features.length > 0){
this.resultFeature = featureSet.features[0];
this.spwViewer.get('spwMap').showFeature(this.resultFeature);
this.spwViewer.get('spwMap').zoomToFeature(this.resultFeature);
}
},
onDeactivate: function() {
this.inherited(arguments);
if(this.resultFeature){
this.spwViewer.get('spwMap').removeFeature(this.resultFeature);
}
if(this.searchFilteringSelect && this.searchFilteringSelect.closeDropDown){
this.searchFilteringSelect.closeDropDown();
}
},
getJSON: function(url,success,error){
if(this.serviceType === "WMS"){
request({
url: url,
content: { request: 'GetFeature', version:'1.3.0', service:'WFS', outputFormat:'application/json', typeName: this.layer.layerId, srsName:"EPSG:"+this.spwViewer.get('spatialReference').wkid },
handleAs: "json",
timeout: 40000
}).then(lang.hitch(this, function(data) {
var fc = {
features: array.map(data.features, lang.hitch(this, function(f){
var f = lang.mixin({attributes: lang.mixin({}, f.properties)}, {geometry: GeometryConverter.geoJSONToEsri(f.geometry)});
f.geometry.setSpatialReference(this.spwViewer.get('spatialReference'));
return f;
}))
};
this.linkQueryResultsToSelect(fc);
}), error);
} else {
request({
url: url,
content: {f:'pjson'},
handleAs: "json",
timeout: 4000
}).then(success, error);
}
},
getAllResults: function(){
var query = new Query();
query.where = '1=1';
var queryTask = new QueryTask(this.queryServiceUrl);
queryTask.executeForIds(query, lang.hitch(this, lang.hitch(this, function(result){
if(result) {
result = result.sort(function(a,b){
if (parseInt(a) == parseInt(b)) return 0;
if (parseInt(a) < parseInt(b)) return -1;
return 1;
});
var numberQueries = Math.ceil(result.length / this.maxRecordCountService);
var queriesInProgress = numberQueries;
var featureSet = null;
var alreadyPushed = [];
var queryFromIdsFunc = function(results) {
if (results) {
if (this.distinctValues === true) {
if (featureSet == null) {
featureSet = lang.mixin(lang.clone(results), {
features: []
});
}
array.forEach(results.features, lang.hitch(this, function(feature) {
var value = feature.attributes[featureSet.displayFieldName];
if (this.comboBoxServiceFields && this.comboBoxServiceFields.length > 0) {
value = lang.replace('{' + this.comboBoxServiceFields.join('} {') + '}', feature.attributes);
}
if (value == null || alreadyPushed.indexOf(value) === -1) {
alreadyPushed.push(value);
featureSet.features.push(feature);
}
}));
}
else {
if (featureSet == null) {
featureSet = results;
}
else {
featureSet.features = featureSet.features.concat(results.features);
}
}
}
queriesInProgress--;
if (queriesInProgress < 1) {
this.linkQueryResultsToSelect(featureSet);
}
};
for(var i=0; i < numberQueries; i++) {
var firstIndex = i * this.maxRecordCountService;
var lastIndex = result[(((i + 1) * this.maxRecordCountService) - 1)] ?
(((i + 1) * this.maxRecordCountService) - 1) : (result.length - 1);
this.queryFromIds(result[firstIndex], result[lastIndex], queryFromIdsFunc);
}
}
else {
this.hideLoading();
this.enableForm(false);
}
})),
lang.hitch(this,function(error){
console.error(error);
this.hideLoading();
this.enableForm(false);
})
);
},
enableForm: function(b) {
if (!b) {
var greyOverlay = domConstruct.create('div', {
style: "pointer-events:none;position:absolute;top:0px;left:0;bottom:0;right:0;background-color:black;opacity:0.2;filter: alpha(opacity = 20);"
}, this.domNode);
domStyle.set(this.loadingText, 'color', 'red');
this.loadingText.innerHTML = 'Cet outil n\'est pas utilisable avec cette couche !';
}
domStyle.set(this.searchFilteringSelect.domNode, 'disabled', b ? '' : 'true');
this.searchFilteringSelect.set('disabled', !b);
this.goButton.set('disabled', !b);
},
queryFromIds: function(firstId, lastId, functionToExecute){
var query = new Query();
query.returnGeometry = false;
query.outFields = this.comboBoxServiceFields;
query.returnDistinctValues = this.distinctValues;
query.where = this.esriOIDField + '>=' + firstId + ' AND ' + this.esriOIDField + '<=' + lastId;
var queryTask = new QueryTask(this.queryServiceUrl);
queryTask.execute(query, lang.hitch(this, functionToExecute),
lang.hitch(this,function(error){
console.error(error);
this.enableForm(false);
})
);
}
});
});