Retour à la documentation
define([
'dojo/_base/declare',
'dojo/_base/array',
'dojo/_base/lang',
'dojo/_base/connect',
'dojo/on',
'dojo/keys',
'spw/api/GeometryUtils',
'spw/api/SpwViewer',
'esri/toolbars/draw'
], function(declare, array, lang, connect, on, keys, GeometryUtils, SpwViewer, Draw) {
/**
* @class spw.api.SpwDrawToolbar
* @classdesc classe permettant d'encapsuler le widget de dessin ESRI
* @extends {esri/toolbars/draw}
*/
var spwdrawtoolbar = declare([Draw], {
_angleActivated: false,
_activated: false,
angleStepValue: 45,
_previousAngle: null,
constructor: function(map) {
on(window.document, 'keydown', lang.hitch(this, this.onKeyDown));
on(window.document, 'keyup', lang.hitch(this, this.onKeyUp));
},
_onClickHandler: function(c) {
if (this._angleActivated && this._points && this._points.length > 1) {
var firstpt = (this._tGraphic && this._tGraphic.geometry ? this._tGraphic.geometry.getPoint(0, 1) : this._points[this._points.length - 1]);
this._points[this._points.length - 1] = firstpt;
this._graphic.geometry.setPoint(0, this._points.length - 1, firstpt);
c.mapPoint = (this._tGraphic && this._tGraphic.geometry ? this._tGraphic.geometry.getPoint(0, 0) : c.mapPoint);
}
this.inherited(arguments);
},
_onMouseMoveHandler: function(c) {
var a;
this.map.snappingManager && (a = this.map.snappingManager._snappingPoint);
var nbPoints = this._points.length;
var b = this._points[nbPoints - 1];
c = a || c.mapPoint;
a = this._tGraphic;
var d = a.geometry;
if (d == null) {
return;
}
switch (this._geometryType) {
case spwdrawtoolbar.POLYLINE:
case spwdrawtoolbar.POLYGON:
var previous = null;
var projected = null;
d.setPoint(0, 0, {
x: b.x,
y: b.y
});
d.setPoint(0, 1, {
x: c.x,
y: c.y
});
if (!this._angleActivated) {
a.setGeometry(d);
break;
}
if (nbPoints === 1) {
// chercher le graphics le plus proche
var minDis = Infinity;
var allGraphics = [].concat(SpwViewer.getInstance().get('spwMap').getMapServices({
visible: true,
type: 'DRAW_LAYER'
}));
allGraphics = [].concat.apply([], allGraphics.map(function(g) {
return g && g.layer ? g.layer.graphics : null;
}));//.concat(this.map.graphics.graphics);
array.forEach(allGraphics, lang.hitch(this, function(g) {
if (g == null || g.geometry == null || ['polyline', 'polygon'].indexOf(g.geometry.type) < 0) {
return false;
}
var geom = g.geometry;
// en fonction du type de la géometrie, trouver la ligne la plus proche...
var pathsOrRings = geom.paths == null ? geom.rings == null ? null : geom.rings : geom.paths;
array.forEach(pathsOrRings, lang.hitch(this, function(pr) {
if (pr == null || pr.length < 2) {
return;
}
for (var i = 1; i < pr.length; ++i) {
var tmpLine = new esri.geometry.Polyline(geom.spatialReference);
tmpLine.addPath([pr[i-1], pr[i]]);
var dis = GeometryUtils.distance(tmpLine, b);
if (minDis > dis) {
previous = tmpLine;
minDis = dis;
}
}
}));
}));
if (previous) {
projected = GeometryUtils.projectOnLine(previous, this._points[nbPoints-1]);
d.setPoint(0, 0, projected);
}
}
else {
previous = new esri.geometry.Polyline(this._points[nbPoints-2].spatialReference);
previous.addPath([this._points[nbPoints-2], this._points[nbPoints-1]]);
projected = this._points[nbPoints-1];
}
if (previous == null) {
a.setGeometry(d);
break;
}
// trouver l'angle et calculer le deuxième point en fonction de la ligne précédente
// et gérer le changement de distance
var angle = GeometryUtils.angleBetweenLines(previous, d);
var tmp = angle / this.angleStepValue;
var nearestAngle = Math.round(tmp) * this.angleStepValue;
var dis2 = GeometryUtils.length(d);
var realAngle = 180 - nearestAngle;
if (GeometryUtils.distance(projected, previous.getPoint(0, 0)) < 0.001) {
realAngle = -nearestAngle;
var tmpPt = previous.getPoint(0, 0);
previous.setPoint(0, 0, previous.getPoint(0, 1));
previous.setPoint(0, 1, tmpPt);
}
else {
previous.setPoint(0, 1, projected);
}
var rotated = GeometryUtils.rotate(previous, realAngle, previous.getPoint(0, 1));
var dis1 = GeometryUtils.length(rotated);
var dt = dis2 / dis1;
var pt1 = rotated.getPoint(0, 0);
var pt2 = rotated.getPoint(0, 1);
rotated.setPoint(0, 0, {
x: ((1 - dt) * pt2.x) + (dt * pt1.x),
y: ((1 - dt) * pt2.y) + (dt * pt1.y)
});
a.setGeometry(rotated);
this._previousAngle = nearestAngle;
break;
// case spwdrawtoolbar.POLYGON:
// d.setPoint(0, 0, {
// x: b.x,
// y: b.y
// });
// d.setPoint(0, 1, {
// x: c.x,
// y: c.y
// });
// a.setGeometry(d);
}
var toSend = null;
if (this._geometryType === spwdrawtoolbar.POLYLINE) {
toSend = (this._graphic && this._graphic.geometry ? new esri.geometry.Polyline(this._graphic.geometry.toJson()) : null);
}
else if (this._geometryType === spwdrawtoolbar.POLYGON) {
toSend = (this._graphic && this._graphic.geometry ? new esri.geometry.Polygon(this._graphic.geometry.toJson()) : null);
}
if (toSend && this._angleActivated && previous) {
toSend._insertPoints([a.geometry.getPoint(0, 0)], 0);
}
else if (toSend) {
toSend._insertPoints([a.geometry.getPoint(0, 1)], 0);
}
this.emit('mouse-move', {
geometry: toSend
});
},
/**
* Active l'outil de dessin
*/
activate: function() {
this.inherited(arguments);
this._activated = true;
},
/**
* Désactive l'outil de dessin
*/
deactivate: function() {
this.inherited(arguments);
this._activated = false;
},
/**
* Méthode appelée lors d'un keydown sur le clavier
* @param evt l'événement KeyDown
*/
onKeyDown: function(evt) {
if (['polyline', 'polygon'].indexOf(this._graphic && this._graphic.geometry ? this._graphic.geometry.type : '') > -1) {
this._angleActivated = evt.ctrlKey;
}
else {
this._angleActivated = false;
}
},
/**
* Méthode appelée lors d'un keyup sur le clavier
* @param evt l'événement KeyUp
*/
onKeyUp: function(evt) {
this._angleActivated = ['polyline', 'polygon'].indexOf(this._graphic && this._graphic.geometry ? this._graphic.geometry.type : '') > -1 && evt.ctrlKey;
if (!this._activated) {
return;
}
var charOrCode = evt.charCode || evt.keyCode;
if (charOrCode === keys.F2) {
this.finishDrawing();
}
else if (evt.ctrlKey && charOrCode === 'Z'.charCodeAt(0)) {
if ([spwdrawtoolbar.POLYLINE, spwdrawtoolbar.POLYGON].indexOf(this._geometryType) < 0) {
return;
}
this._points.pop();
if (this._points.length === 0) {
connect.disconnect(this._onMouseMoveHandler_connect);
this._clear();
this._setTooltipMessage(0);
return;
}
// on vire le dernier point
var curPath = this._graphic.geometry.type === 'polyline' ? this._graphic.geometry.paths[0] : this._graphic.geometry.rings[0];
this._graphic.geometry.removePoint(0, curPath.length - 1);
this._graphic.setGeometry(this._graphic.geometry).setSymbol(this.lineSymbol);
// modification de la dernière ligne affichée
var graph = this._tGraphic;
var geom = graph.geometry;
geom.setPoint(0, 0, this._points[this._points.length - 1]);
graph.draw();
}
}
});
["ARROW", "CIRCLE", "DOWN_ARROW", "ELLIPSE", "EXTENT", "FREEHAND_POLYGON", "FREEHAND_POLYLINE", "LEFT_ARROW", "LINE", "MULTI_POINT", "POINT", "POLYGON", "POLYLINE", "RECTANGLE", "RIGHT_ARROW", "TRIANGLE", "UP_ARROW"].forEach(function(key) {
spwdrawtoolbar[key] = Draw[key];
});
return spwdrawtoolbar;
});