Retour à la documentation
/**
* @class spw.widgets.SpwFileImporter
*/
define(["dojo/_base/declare", "spw/api/SpwBaseTemplatedWidget", "dojo/dom-construct", "dojo/_base/array", "dojo/_base/lang",
"dojo/text!./templates/SpwFileImporter.html", "dojo/dom-style", "dojo/query", "dojo/on", "dijit/Tooltip",
"dojox/data/CsvStore","esri/InfoTemplate", "esri/layers/FeatureLayer", "dojo/dom-class", "esri/toolbars/edit",
"dojo/_base/event", "esri/renderers/SimpleRenderer", "esri/symbols/PictureMarkerSymbol",
"esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "dojo/_base/Color", "dojo/i18n!./nls/SpwFileImporter",
"esri/request", "esri/geometry/Point", "esri/renderers/UniqueValueRenderer", "esri/geometry/Multipoint"],
function(declare, SpwBaseTemplatedWidget, domConstruct, array, lang, template,
domStyle, query, on, Tooltip, CsvStore, InfoTemplate, FeatureLayer, domClass, Edit, event, SimpleRenderer,
PictureMarkerSymbol, SimpleMarkerSymbol, SimpleLineSymbol, Color, labels, esriRequest, Point, UniqueValueRenderer,
Multipoint){
var spwFileImporter = null;
spwFileImporter = declare("spw.widgets.SpwFileImporter", [SpwBaseTemplatedWidget], /** @lends spw.widgets.SpwFileImporter.prototype */{
templateString: template,
labels: labels,
usedDropZone: null,
/**
* Nom du champ contenant la valeur x dans le fichier
* @private
* @type String
*/
xField: "x",
/**
* Nom du champ contenant la valeur y dans le fichier
* @private
* @type String
*/
yField: "y",
/**
* Texte libre affiché dans la zone de dépôt.
* @private
* @type String
*/
tooltip: null,
/**
* Définition du renderer utilisé pour la symbologie
* @private
* @type Object
*/
rendererConfig: null,
/**
* Détermine si l'édition est possible
* @private
* @type boolean
*/
isEditable: false,
/**
* Détermine si la sauvegarde csv est possible
* @private
* @type boolean
*/
isSaveable: false,
/**
* Le store contenant les données du ficheir CSV
* @private
* @type dojox/data/CsvStore
*/
csvStore:null,
/**
* Le serveur permettant d'uploader et de renvoyer le contenu du fchier CSV pour les vieux navigateurs
* @private
* @type String
*/
uploadServerUrl:null,
_featureLayer:null,
/**
* Le serveur permettant de sauver le contenu du fchier CSV et de le télécharger
* @private
* @type String
*/
saveServerUrl:null,
_dropMode:true,
/**
* @constructs
*/
constructor : function(config) {
if(config.dropOnMap){
this.usedDropZone = config.spwViewer.get('spwMap');
} else {
this.usedDropZone = this;
}
if(config.tooltip)
{
this.tooltip = config.tooltip;
}
if(config.uploadServerUrl)
{
this.uploadServerUrl = config.uploadServerUrl;
}
if(config.saveServerUrl)
{
this.saveServerUrl = config.saveServerUrl;
}
if(config.xField)
{
this.xField = config.xField;
}
if(config.yField)
{
this.yField = config.yField;
}
if(config.renderer)
{
this.rendererConfig = config.renderer;
}
this.isEditable = config.isEditable;
this.isSaveable = config.isSaveable;
this.iconClass = "SpwFileImporterWidgetIcon";
this.widgetTitle = "Chargement CSV";
this.height = "200px";
this.width = "200px";
this.resizable = false;
this._dropMode = window.File && window.FileReader;
},
postCreate: function(){
this.inherited(arguments);
if (!this._dropMode) {
domStyle.set(this.uploadForm, "display", "");
domStyle.set(this.dropZone, "display", "none");
query("input", this.uploadForm).forEach(lang.hitch(this, function(node){
on(node, "change", lang.hitch(this, function(){
this.displayInTreatment();
esriRequest({
url: this.uploadServerUrl,
form: this.uploadForm,
handleAs:"text",
load: lang.hitch(this, function(data){
this.processCsvData(data);
}),
error: function(error){
console.log(error);
}
});
}));
}));
} else {
on(this.usedDropZone.domNode, "dragenter", lang.hitch(this, function (evt) {
evt.preventDefault();
domClass.add(this.dropZone, "fileOver");
this.dropZone.innerHTML = "Déposez ici";
}));
on(this.usedDropZone.domNode, "dragleave", lang.hitch(this, function (evt) {
domClass.remove(this.dropZone, "fileOver");
this.dropZone.innerHTML = "Zone de dépôt";
}));
on(this.usedDropZone.domNode, "dragover", lang.hitch(this, function (evt) {
evt.preventDefault();
}));
on(this.usedDropZone.domNode, "drop", lang.hitch(this, this.handleFileDrop));
}
if(this.tooltip != null && this.tooltip != "") {
var tooltipDiv = domConstruct.create("div", {
"class":"fileImporterTooltipHelper"
}, this.domNode);
var tooltip = new Tooltip({
connectId: [tooltipDiv],
label: this.tooltip,
showDelay: 20,
position:["after","below"]
});
tooltip._onUnHover = function(){
if(tooltip.timeOut){
clearTimeout(tooltip.timeOut);
tooltip.timeOut=null;
}
tooltip.timeOut= setTimeout(function () {
tooltip.close();
tooltip.timeOut = null;
}, 1000);
};
}
},
handleFileDrop: function(evt){
evt.preventDefault();
this.displayInTreatment();
var files = evt.dataTransfer.files;
if (files && files.length === 1) {
var file = files[0];
if (file.name.indexOf(".csv") !== -1) {
this.handleCsv(file);
}
}
},
handleCsv: function (file) {
var reader = new FileReader();
reader.onload = lang.hitch(this, function () {
this.processCsvData(reader.result);
});
reader.readAsText(file);
},
processCsvData: function(data) {
this.csvStore = new CsvStore({
data: data,
separator: this.getSeparator(lang.trim(data.substr(0, data.indexOf("\n"))))
});
this.csvStore.fetch({
onComplete: lang.hitch(this, this.storeFetchComplete),
onError: function (error) {
console.error("Error fetching items from CSV store: ", error);
}
});
},
storeFetchComplete: function (items, request){
var featureCollection = this.createFeatureCollectionTemplateCsv(items);
var popupInfo = this.generateDefaultPopupInfo(featureCollection);
var infoTemplate = new InfoTemplate(this.buildInfoTemplate(popupInfo));
this.csvToGraphics(items, featureCollection);
if(this._featureLayer)
this.removeLayer(this._featureLayer);
this._featureLayer = new FeatureLayer(featureCollection, {
infoTemplate: infoTemplate,
id: 'csvLayer',
mode: FeatureLayer.MODE_SELECTION
});
this._featureLayer.__popupInfo = popupInfo;
this._featureLayer.setRenderer(this.createRenderer());
this.spwViewer.get('spwMap').get('esriMap').addLayer(this._featureLayer);
if(this.isEditable){
this.makeLayerEditable(this._featureLayer);
}
this.zoomToData(this._featureLayer);
this.displayFileTreated(this._featureLayer, items);
},
displayInTreatment: function() {
if (!this._dropMode) {
domStyle.set(this.uploadForm, "display", "none");
domStyle.set(this.dropZone, "display", "");
}
domClass.remove(this.dropZone, "fileOver");
this.dropZone.innerHTML = this.labels["treatment"];
},
displayWaitToDrop: function() {
if (!this._dropMode) {
domStyle.set(this.uploadForm, "display", "");
domStyle.set(this.dropZone, "display", "none");
}
domClass.remove(this.dropZone, "fileDisplayed");
this.dropZone.innerHTML = this.labels["dropZoneLabel"];
},
displayFileTreated: function(featureLayer, items){
this.dropZone.innerHTML = this.labels["displayed"];
var removeDiv = domConstruct.create(
"div", {
style:
this.usedDropZone == this ?
"margin-bottom: 0; background-color: white; border: 1px solid #A7C8E2; border-radius: 7px 7px 7px 7px; bottom: 10px; cursor: pointer; font-size: 12px; margin: 4px 0 0 28px; opacity: 0.85; padding: 0; text-align: center; width: 120px; z-index: 10000;":
"cursor:pointer;margin-bottom: 20px;z-index: 10000; opacity: 0.85; bottom: 10px; text-align: center; width: 120px; height: 51px; background-color: white; border: 1px solid rgb(167, 200, 226); border-radius: 7px 7px 7px 7px;",
innerHTML:"<br />Effacer les points"
},
this.usedDropZone == this ? this.dropZone : domConstruct.create("div", {style:"position:absolute; bottom:0; left:0;"}, this.spwViewer.get('spwMap').domNode),
this.usedDropZone == this ? "last":"first"
);
domClass.add(this.dropZone, "fileDisplayed");
domConstruct.create("img", {src: this.imagesPath + "eraser.png"}, removeDiv, "first");
on(removeDiv, "click", lang.hitch(this, function(){
this.removeLayer(featureLayer);
domConstruct.destroy(removeDiv);
domConstruct.destroy("saveDiv");
this.displayWaitToDrop();
}));
if(this.isSaveable){
this.displaySaveButton(featureLayer, items);
}
},
removeLayer: function(featureLayer){
this.spwViewer.get('spwMap').get('esriMap').removeLayer(featureLayer);
},
displaySaveButton: function(featureLayer, items){
var saveDiv = domConstruct.create(
"form", {
id:"saveDiv",
style:
this.usedDropZone == this ?
"display:block; background-color: white; border: 1px solid #A7C8E2; border-radius: 7px 7px 7px 7px; bottom: 10px; cursor: pointer; font-size: 12px; margin: 4px 0 0 28px; opacity: 0.85; padding: 0; text-align: center; width: 120px; z-index: 10000;":
"display:block;cursor:pointer;margin-bottom: 20px;z-index: 10000; opacity: 0.85; bottom: 10px; text-align: center; width: 120px; height: 51px; background-color: white; border: 1px solid rgb(167, 200, 226); border-radius: 7px 7px 7px 7px;",
innerHTML:"<input type='hidden' value='' name='csvFileContent' /><br />Sauver le fichier",
target:"_blank"
},
this.usedDropZone == this ? this.dropZone : domConstruct.create("div", {style:"position:absolute; bottom:0; left:0;"}, this.spwViewer.get('spwMap').domNode),
this.usedDropZone == this ? "last":"first"
);
domConstruct.create("img", { src:this.imagesPath + "save.png" }, saveDiv, "first");
var csvStore = this.csvStore;
var ctxt = this;
on(saveDiv, "click", lang.hitch(this, function(){
var csvFile = "";
var attr = csvStore.getAttributes(items[0]);
array.forEach(attr, function(at){
csvFile += at+";";
});
csvFile.substring(0, csvFile.length-1);
csvFile += "\r\n";
array.forEach(featureLayer.graphics, function(item){
array.forEach(attr, function(at){
csvFile += item.attributes[at]+";";
});
csvFile.substring(0, csvFile.length-1);
csvFile += "\r\n";
});
this.uploadForm.action = this.saveServerUrl;
this.uploadForm.method = "POST";
this.uploadForm.csvFileContent.value = csvFile;
this.uploadForm.submit();
}));
},
csvToGraphics: function(items, featureCollection){
var objectId = 0;
var latField, longField;
var ctxt = this;
var fieldNames = this.csvStore.getAttributes(items[0]);
array.forEach(fieldNames, function (fieldName) {
if (ctxt.yField.toLowerCase() == fieldName.toLowerCase()) {
latField = fieldName;
}
if (ctxt.xField.toLowerCase() == fieldName.toLowerCase()) {
longField = fieldName;
}
});
var csvStore = this.csvStore;
array.forEach(items, lang.hitch(this, function (item, index) {
var attrs = csvStore.getAttributes(item),
attributes = {};
// Read all the attributes for this record/item
array.forEach(attrs, function (attr) {
var value = Number(csvStore.getValue(item, attr));
if (isNaN(value)) {
attributes[attr] = csvStore.getValue(item, attr);
} else {
attributes[attr] = value;
}
});
attributes["__OBJECTID"] = objectId;
objectId++;
var latitude = parseFloat(attributes[latField]);
var longitude = parseFloat(attributes[longField]);
if (isNaN(latitude) || isNaN(longitude)) {
return;
}
var geometry = new Point(longitude, latitude);
geometry.spatialReference = this.spwViewer.get('spwMap').get('esriMap').spatialReference;
var feature = {
"geometry": geometry.toJson(),
"attributes": attributes
};
featureCollection.featureSet.features.push(feature);
}));
},
makeLayerEditable: function(featureLayer) {
var editToolbar = new Edit(this.spwViewer.get('spwMap').get('esriMap'));
editToolbar.on("deactivate", lang.hitch(this, function(tool,graphic) {
graphic.attributes[this.xField] = graphic.geometry.x;
graphic.attributes[this.yField] = graphic.geometry.y;
featureLayer.applyEdits(null, [graphic], null);
}));
var editingEnabled = false;
featureLayer.on("dbl-click", this, function(evt) {
event.stopEvent(evt);
this.spwViewer.get('spwMap').hideInfoWindow();
if (editingEnabled === false) {
editingEnabled = true;
editToolbar.activate(Edit.MOVE , evt.graphic);
} else {
editToolbar.deactivate();
editingEnabled = false;
}
});
featureLayer.on("click", this, function(evt) {
event.stopEvent(evt);
if (evt.ctrlKey === true) { //delete feature if ctrl key is depressed
featureLayer.applyEdits(null,null,[evt.graphic]);
editToolbar.deactivate();
editingEnabled=false;
}
});
},
getSeparator: function(string) {
var separators = [",", " ", ";", "|"];
var maxSeparatorLength = 0;
var maxSeparatorValue = "";
array.forEach(separators, function (separator) {
var length = string.split(separator).length;
if (length > maxSeparatorLength) {
maxSeparatorLength = length;
maxSeparatorValue = separator;
}
});
return maxSeparatorValue;
},
createFeatureCollectionTemplateCsv: function(items) {
var fields = this.createFieldsForLayer(this.csvStore.getAttributes(items[0]), items);
return {
"layerDefinition": this.createLayerDefinition(fields),
"featureSet": {
"features": [],
"geometryType": "esriGeometryPoint"
}
};
},
createLayerDefinition: function(fields){
return {
"geometryType": "esriGeometryPoint",
"objectIdField": "__OBJECTID",
"type": "Feature Layer",
"typeIdField": "",
"fields": fields,
"types": [],
"capabilities": "Query",
"extent": {
"xmin": 30000,
"ymin": 15000,
"xmax": 310000,
"ymax": 200000,
"spatialReference": {"wkid": 31370}
}
};
},
createFieldsForLayer: function(fieldAttributes, items){
var fields = [];
fields.push(this.createOIDField());
array.forEach(fieldAttributes, lang.hitch(this, function (field) {
var value = this.csvStore.getValue(items[0], field);
var parsedValue = Number(value);
var layerField = null;
if (isNaN(parsedValue)) {
layerField = this.createStringField(field);
} else {
layerField = this.createDoubleField(field);
}
fields.push(layerField);
}));
return fields;
},
createOIDField: function(){
var field = this.createField("__OBJECTID", false);
field.type = "esriFieldTypeOID";
return field;
},
createDoubleField: function(name){
var field = this.createField(name, true);
field.type = "esriFieldTypeDouble";
return field;
},
createStringField: function(name){
var field = this.createField(name, true);
field.type = "esriFieldTypeString";
return field;
},
createField: function(name, editable){
return {
"name": name,
"alias": name,
"type": null,
"editable": editable,
"domain": null
};
},
createRenderer: function(){
if(this.rendererConfig != null && this.rendererConfig.type == "simple"){
return this.createSimpleRenderer();
} else if(this.rendererConfig != null && this.rendererConfig.type == "uniqueValue"){
return this.createUniqueValueRenderer();
} else if(this.rendererConfig != null && this.rendererConfig.type == "classBreak"){
return this.createUniqueValueRenderer();
} else {
return this.createDefaultRenderer();
}
},
createSimpleRenderer: function(){
var symbol = this.createEsriSymbol(this.rendererConfig.symbol);
return new SimpleRenderer(symbol);
},
createDefaultRenderer: function(){
var symbUrl = 'http://static.arcgis.com/images/Symbols/Basic/RedSphere.png';
if(this.spwViewer.get('proxyPageUrl')){
symbUrl = this.spwViewer.get('proxyPageUrl') + "?" + symbUrl;
}
var symbol = new PictureMarkerSymbol(symbUrl, 24, 24);
return new SimpleRenderer(symbol);
},
createUniqueValueRenderer: function(){
var defaultSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_X, 12, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color("black"), 2), new Color("blue"));
if(typeof(this.rendererConfig.defaultSymbol) != 'undefined' && this.rendererConfig.defaultSymbol != "") {
defaultSymbol = this.createEsriSymbol(this.rendererConfig.defaultSymbol);
}
var render = new UniqueValueRenderer(defaultSymbol, this.rendererConfig.field);
var ctxt = this;
array.forEach(this.rendererConfig.symbolesValues, function(item){
if(typeof(item.val) != 'undefined' && item.val != ""){
render.addValue(item.val, ctxt.createEsriSymbol(item.symb));
} else {
defaultSymbol = ctxt.createEsriSymbol(item.symb);
}
});
return render;
},
getBorderStyle: function(symbol){
var borderStyle = SimpleLineSymbol.STYLE_NULL;
if(typeof(symbol.borderStyle) != 'undefined' && symbol.borderStyle != "")
{
if(symbol.borderStyle == "solid")
{
borderStyle = SimpleLineSymbol.STYLE_SOLID;
}
else if(symbol.borderStyle == "dash")
{
borderStyle = SimpleLineSymbol.STYLE_DASH;
}
else if(symbol.borderStyle == "dashdot")
{
borderStyle = SimpleLineSymbol.STYLE_DASHDOT;
}
else if(symbol.borderStyle == "dashdotdot")
{
borderStyle = SimpleLineSymbol.STYLE_DASHDOTDOT;
}
else if(symbol.borderStyle == "dot")
{
borderStyle = SimpleLineSymbol.STYLE_DOT;
}
else if(symbol.borderStyle == "none")
{
borderStyle = SimpleLineSymbol.STYLE_NULL;
}
}
return borderStyle;
},
getBorderColor: function(symbol){
var borderColor = new Color("black");
if(typeof(symbol.borderColor) != 'undefined' && symbol.borderColor != "")
{
borderColor = new Color(symbol.borderColor);
}
return borderColor;
},
getBorderSize: function(symbol){
var borderSize = 1;
if(typeof(symbol.borderSize) != 'undefined' && !isNaN(Number(symbol.borderSize)))
{
borderSize = symbol.borderSize;
}
return borderSize;
},
getFillStyle: function(symbol){
var style = SimpleMarkerSymbol.STYLE_CIRCLE;
if(typeof(symbol.fillStyle) != 'undefined' && symbol.fillStyle != "")
{
if(symbol.fillStyle == "circle")
{
style = SimpleMarkerSymbol.STYLE_CIRCLE;
}
else if (symbol.fillStyle == "cross")
{
style = SimpleMarkerSymbol.STYLE_CROSS;
}
else if (symbol.fillStyle == "diamond")
{
style = SimpleMarkerSymbol.STYLE_DIAMOND;
}
else if (symbol.fillStyle == "square")
{
style = SimpleMarkerSymbol.STYLE_SQUARE;
}
else if (symbol.fillStyle == "x")
{
style = SimpleMarkerSymbol.STYLE_X;
}
}
return style;
},
getFillColor: function(symbol){
var color = new Color("red");
if(typeof(symbol.fillColor) != 'undefined' && symbol.fillColor != "")
{
color = new Color(symbol.fillColor);
}
return color;
},
getMarkerSize:function(symbol){
var size = 10;
if(typeof(symbol.size) != 'undefined' && !isNaN(Number(symbol.size)))
{
size = symbol.size;
}
return size;
},
createEsriSymbol: function(symbol){
var borderStyle = this.getBorderStyle(symbol);
var borderColor = this.getBorderColor(symbol);
var borderSize = this.getBorderSize(symbol);
var outline = new SimpleLineSymbol(borderStyle, borderColor, borderSize);
var style = this.getFillStyle(symbol);
var color = this.getFillColor(symbol);
var size = this.getMarkerSize(symbol);
var symb = new SimpleMarkerSymbol(style, size, outline, color);
if(typeof(symbol) != 'undefined' && typeof(symbol.type) != 'undefined'){
if(symbol.type == "marker")
{
/*default (see upper)*/
}
else if(symbol.type == "image")
{
symb = new PictureMarkerSymbol(symbol.url, symbol.width, symbol.height);
}
}
return symb;
},
generateDefaultPopupInfo: function(featureCollection) {
var fields = featureCollection.layerDefinition.fields;
var decimal = {
'esriFieldTypeDouble': 1,
'esriFieldTypeSingle': 1
};
var integer = {
'esriFieldTypeInteger': 1,
'esriFieldTypeSmallInteger': 1
};
var dt = {
'esriFieldTypeDate': 1
};
var displayField = null;
var fieldInfos = array.map(fields, lang.hitch(this, function (item, index) {
if (item.name.toUpperCase() === "NAME") {
displayField = item.name;
}
var visible = (item.type !== "esriFieldTypeOID" && item.type !== "esriFieldTypeGlobalID" && item.type !== "esriFieldTypeGeometry");
var format = null;
if (visible) {
var f = item.name.toLowerCase();
var hideFieldsStr = ",stretched value,fnode_,tnode_,lpoly_,rpoly_,poly_,subclass,subclass_,rings_ok,rings_nok,";
if (hideFieldsStr.indexOf("," + f + ",") > -1 || f.indexOf("area") > -1 || f.indexOf("length") > -1 || f.indexOf("shape") > -1 || f.indexOf("perimeter") > -1 || f.indexOf("objectid") > -1 || f.indexOf("_") == f.length - 1 || f.indexOf("_i") == f.length - 2) {
visible = false;
}
if (item.type in integer) {
format = {
places: 0,
digitSeparator: true
};
} else if (item.type in decimal) {
format = {
places: 2,
digitSeparator: true
};
} else if (item.type in dt) {
format = {
dateFormat: 'shortDateShortTime'
};
}
}
return lang.mixin({}, {
fieldName: item.name,
label: item.alias,
isEditable: false,
tooltip: "",
visible: visible,
format: format,
stringFieldOption: 'textbox'
});
}));
var popupInfo = {
title: displayField ? '{' + displayField + '}' : '',
fieldInfos: fieldInfos,
description: null,
showAttachments: false,
mediaInfos: []
};
return popupInfo;
},
buildInfoTemplate: function(popupInfo) {
var json = {
content: "<table>"
};
array.forEach(popupInfo.fieldInfos, function (field) {
if (field.visible) {
json.content += "<tr><td valign='top'>" + field.label + ": <\/td><td valign='top'>${" + field.fieldName + "}<\/td><\/tr>";
}
});
json.content += "<\/table>";
return json;
},
zoomToData: function(featureLayer) {
// Zoom to the collective extent of the data
var multipoint = new Multipoint(this.spwViewer.get('spwMap').get('esriMap').spatialReference);
array.forEach(featureLayer.graphics, function (graphic) {
var geometry = graphic.geometry;
if (geometry) {
multipoint.addPoint({
x: geometry.x,
y: geometry.y
});
}
});
if (multipoint.points.length > 0) {
this.spwViewer.get('spwMap').get('esriMap').setExtent(multipoint.getExtent().expand(1.25), true);
}
}
});
return spwFileImporter;
});