1
/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
2
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
3
* full text of the license. */
7
* @requires OpenLayers/Handler/Point.js
8
* @requires OpenLayers/Geometry/Point.js
9
* @requires OpenLayers/Geometry/LineString.js
13
* Class: OpenLayers.Handler.Path
14
* Handler to draw a path on the map. Path is displayed on mouse down,
15
* moves on mouse move, and is finished on mouse up.
18
* - <OpenLayers.Handler.Point>
20
OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, {
24
* {<OpenLayers.Feature.Vector>}
30
* {Boolean} In freehand mode, the handler starts the path on mouse down,
31
* adds a point for every mouse move, and finishes the path on mouse up.
32
* Outside of freehand mode, a point is added to the path on every mouse
33
* click and double-click finishes the path.
38
* Property: freehandToggle
39
* {String} If set, freehandToggle is checked on mouse events and will set
40
* the freehand mode to the opposite of this.freehand. To disallow
41
* toggling between freehand and non-freehand mode, set freehandToggle to
42
* null. Acceptable toggle values are 'shiftKey', 'ctrlKey', and 'altKey'.
44
freehandToggle: 'shiftKey',
47
* Constructor: OpenLayers.Handler.Path
48
* Create a new path hander
51
* control - {<OpenLayers.Control>}
52
* callbacks - {Object} An object with a 'done' property whos value is a
53
* function to be called when the path drawing is finished. The
54
* callback should expect to recieve a single argument, the line
55
* string geometry. If the callbacks object contains a 'point'
56
* property, this function will be sent each point as they are added.
57
* If the callbacks object contains a 'cancel' property, this function
58
* will be called when the handler is deactivated while drawing. The
59
* cancel should expect to receive a geometry.
60
* options - {Object} An optional object with properties to be set on the
63
initialize: function(control, callbacks, options) {
64
OpenLayers.Handler.Point.prototype.initialize.apply(this, arguments);
68
* Method: createFeature
69
* Add temporary geometries
71
createFeature: function() {
72
this.line = new OpenLayers.Feature.Vector(
73
new OpenLayers.Geometry.LineString());
74
this.point = new OpenLayers.Feature.Vector(
75
new OpenLayers.Geometry.Point());
76
this.layer.addFeatures([this.line, this.point], {silent: true});
80
* Method: destroyFeature
81
* Destroy temporary geometries
83
destroyFeature: function() {
84
OpenLayers.Handler.Point.prototype.destroyFeature.apply(this);
89
* Method: destroyPoint
90
* Destroy the temporary point.
92
destroyPoint: function() {
94
this.layer.destroyFeatures([this.point]);
100
* Add point to geometry. Send the point index to override
101
* the behavior of LinearRing that disregards adding duplicate points.
103
addPoint: function() {
104
this.line.geometry.addComponent(this.point.geometry.clone(),
105
this.line.geometry.components.length);
106
this.callback("point", [this.point.geometry, this.getGeometry()]);
110
* Method: freehandMode
111
* Determine whether to behave in freehand mode or not.
116
freehandMode: function(evt) {
117
return (this.freehandToggle && evt[this.freehandToggle]) ?
118
!this.freehand : this.freehand;
122
* Method: modifyFeature
123
* Modify the existing geometry given the new point
125
modifyFeature: function() {
126
var index = this.line.geometry.components.length - 1;
127
this.line.geometry.components[index].x = this.point.geometry.x;
128
this.line.geometry.components[index].y = this.point.geometry.y;
129
this.line.geometry.components[index].clearBounds();
133
* Method: drawFeature
134
* Render geometries on the temporary layer.
136
drawFeature: function() {
137
this.layer.drawFeature(this.line, this.style);
138
this.layer.drawFeature(this.point, this.style);
142
* Method: getGeometry
143
* Return the sketch geometry. If <multi> is true, this will return
144
* a multi-part geometry.
147
* {<OpenLayers.Geometry.LineString>}
149
getGeometry: function() {
150
var geometry = this.line.geometry;
152
geometry = new OpenLayers.Geometry.MultiLineString([geometry]);
159
* Handle mouse down. Add a new point to the geometry and
160
* render it. Return determines whether to propagate the event on the map.
163
* evt - {Event} The browser event
166
* {Boolean} Allow event propagation
168
mousedown: function(evt) {
169
// ignore double-clicks
170
if (this.lastDown && this.lastDown.equals(evt.xy)) {
173
if(this.lastDown == null) {
175
this.destroyFeature();
177
this.createFeature();
179
this.mouseDown = true;
180
this.lastDown = evt.xy;
181
var lonlat = this.control.map.getLonLatFromPixel(evt.xy);
182
this.point.geometry.x = lonlat.lon;
183
this.point.geometry.y = lonlat.lat;
184
this.point.geometry.clearBounds();
185
if((this.lastUp == null) || !this.lastUp.equals(evt.xy)) {
195
* Handle mouse move. Adjust the geometry and redraw.
196
* Return determines whether to propagate the event on the map.
199
* evt - {Event} The browser event
202
* {Boolean} Allow event propagation
204
mousemove: function (evt) {
206
var lonlat = this.map.getLonLatFromPixel(evt.xy);
207
this.point.geometry.x = lonlat.lon;
208
this.point.geometry.y = lonlat.lat;
209
this.point.geometry.clearBounds();
210
if(this.mouseDown && this.freehandMode(evt)) {
213
this.modifyFeature();
222
* Handle mouse up. Send the latest point in the geometry to
223
* the control. Return determines whether to propagate the event on the map.
226
* evt - {Event} The browser event
229
* {Boolean} Allow event propagation
231
mouseup: function (evt) {
232
this.mouseDown = false;
234
if(this.freehandMode(evt)) {
240
if(this.lastUp == null) {
243
this.lastUp = evt.xy;
252
* Handle double-clicks. Finish the geometry and send it back
256
* evt - {Event} The browser event
259
* {Boolean} Allow event propagation
261
dblclick: function(evt) {
262
if(!this.freehandMode(evt)) {
263
var index = this.line.geometry.components.length - 1;
264
this.line.geometry.removeComponent(this.line.geometry.components[index]);
273
CLASS_NAME: "OpenLayers.Handler.Path"