~dongpo-deng/sahana-eden/test

« back to all changes in this revision

Viewing changes to static/scripts/gis/openlayers/lib/OpenLayers/Handler/Path.js

  • Committer: Deng Dongpo
  • Date: 2010-08-01 09:29:44 UTC
  • Revision ID: dongpo@dhcp-21193.iis.sinica.edu.tw-20100801092944-8t9obt4xtl7otesb
initial

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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. */
 
4
 
 
5
 
 
6
/**
 
7
 * @requires OpenLayers/Handler/Point.js
 
8
 * @requires OpenLayers/Geometry/Point.js
 
9
 * @requires OpenLayers/Geometry/LineString.js
 
10
 */
 
11
 
 
12
/**
 
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.
 
16
 *
 
17
 * Inherits from:
 
18
 *  - <OpenLayers.Handler.Point>
 
19
 */
 
20
OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, {
 
21
    
 
22
    /**
 
23
     * Property: line
 
24
     * {<OpenLayers.Feature.Vector>}
 
25
     */
 
26
    line: null,
 
27
    
 
28
    /**
 
29
     * Property: freehand
 
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.
 
34
     */
 
35
    freehand: false,
 
36
    
 
37
    /**
 
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'.
 
43
     */
 
44
    freehandToggle: 'shiftKey',
 
45
 
 
46
    /**
 
47
     * Constructor: OpenLayers.Handler.Path
 
48
     * Create a new path hander
 
49
     *
 
50
     * Parameters:
 
51
     * control - {<OpenLayers.Control>} The control that owns this handler
 
52
     * callbacks - {Object} An object with a properties whose values are
 
53
     *     functions.  Various callbacks described below.
 
54
     * options - {Object} An optional object with properties to be set on the
 
55
     *           handler
 
56
     *
 
57
     * Named callbacks:
 
58
     * create - Called when a sketch is first created.  Callback called with
 
59
     *     the creation point geometry and sketch feature.
 
60
     * modify - Called with each move of a vertex with the vertex (point)
 
61
     *     geometry and the sketch feature.
 
62
     * point - Called as each point is added.  Receives the new point geometry.
 
63
     * done - Called when the point drawing is finished.  The callback will
 
64
     *     recieve a single argument, the linestring geometry.
 
65
     * cancel - Called when the handler is deactivated while drawing.  The
 
66
     *     cancel callback will receive a geometry.
 
67
     */
 
68
    initialize: function(control, callbacks, options) {
 
69
        OpenLayers.Handler.Point.prototype.initialize.apply(this, arguments);
 
70
    },
 
71
        
 
72
    /**
 
73
     * Method: createFeature
 
74
     * Add temporary geometries
 
75
     *
 
76
     * Parameters:
 
77
     * pixel - {<OpenLayers.Pixel>} The initial pixel location for the new
 
78
     *     feature.
 
79
     */
 
80
    createFeature: function(pixel) {
 
81
        var lonlat = this.control.map.getLonLatFromPixel(pixel);
 
82
        this.point = new OpenLayers.Feature.Vector(
 
83
            new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat)
 
84
        );
 
85
        this.line = new OpenLayers.Feature.Vector(
 
86
            new OpenLayers.Geometry.LineString([this.point.geometry])
 
87
        );
 
88
        this.callback("create", [this.point.geometry, this.getSketch()]);
 
89
        this.point.geometry.clearBounds();
 
90
        this.layer.addFeatures([this.line, this.point], {silent: true});
 
91
    },
 
92
        
 
93
    /**
 
94
     * Method: destroyFeature
 
95
     * Destroy temporary geometries
 
96
     */
 
97
    destroyFeature: function() {
 
98
        OpenLayers.Handler.Point.prototype.destroyFeature.apply(this);
 
99
        this.line = null;
 
100
    },
 
101
 
 
102
    /**
 
103
     * Method: removePoint
 
104
     * Destroy the temporary point.
 
105
     */
 
106
    removePoint: function() {
 
107
        if(this.point) {
 
108
            this.layer.removeFeatures([this.point]);
 
109
        }
 
110
    },
 
111
    
 
112
    /**
 
113
     * Method: addPoint
 
114
     * Add point to geometry.  Send the point index to override
 
115
     * the behavior of LinearRing that disregards adding duplicate points.
 
116
     *
 
117
     * Parameters:
 
118
     * pixel - {<OpenLayers.Pixel>} The pixel location for the new point.
 
119
     */
 
120
    addPoint: function(pixel) {
 
121
        this.layer.removeFeatures([this.point]);
 
122
        var lonlat = this.control.map.getLonLatFromPixel(pixel);
 
123
        this.point = new OpenLayers.Feature.Vector(
 
124
            new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat)
 
125
        );
 
126
        this.line.geometry.addComponent(
 
127
            this.point.geometry, this.line.geometry.components.length
 
128
        );
 
129
        this.callback("point", [this.point.geometry, this.getGeometry()]);
 
130
        this.callback("modify", [this.point.geometry, this.getSketch()]);
 
131
        this.drawFeature();
 
132
    },
 
133
    
 
134
    /**
 
135
     * Method: freehandMode
 
136
     * Determine whether to behave in freehand mode or not.
 
137
     *
 
138
     * Returns:
 
139
     * {Boolean}
 
140
     */
 
141
    freehandMode: function(evt) {
 
142
        return (this.freehandToggle && evt[this.freehandToggle]) ?
 
143
                    !this.freehand : this.freehand;
 
144
    },
 
145
 
 
146
    /**
 
147
     * Method: modifyFeature
 
148
     * Modify the existing geometry given the new point
 
149
     *
 
150
     * Parameters:
 
151
     * pixel - {<OpenLayers.Pixel>} The updated pixel location for the latest
 
152
     *     point.
 
153
     */
 
154
    modifyFeature: function(pixel) {
 
155
        var lonlat = this.control.map.getLonLatFromPixel(pixel);
 
156
        this.point.geometry.x = lonlat.lon;
 
157
        this.point.geometry.y = lonlat.lat;
 
158
        this.callback("modify", [this.point.geometry, this.getSketch()]);
 
159
        this.point.geometry.clearBounds();
 
160
        this.drawFeature();
 
161
    },
 
162
 
 
163
    /**
 
164
     * Method: drawFeature
 
165
     * Render geometries on the temporary layer.
 
166
     */
 
167
    drawFeature: function() {
 
168
        this.layer.drawFeature(this.line, this.style);
 
169
        this.layer.drawFeature(this.point, this.style);
 
170
    },
 
171
 
 
172
    /**
 
173
     * Method: getSketch
 
174
     * Return the sketch feature.
 
175
     *
 
176
     * Returns:
 
177
     * {<OpenLayers.Feature.Vector>}
 
178
     */
 
179
    getSketch: function() {
 
180
        return this.line;
 
181
    },
 
182
 
 
183
    /**
 
184
     * Method: getGeometry
 
185
     * Return the sketch geometry.  If <multi> is true, this will return
 
186
     *     a multi-part geometry.
 
187
     *
 
188
     * Returns:
 
189
     * {<OpenLayers.Geometry.LineString>}
 
190
     */
 
191
    getGeometry: function() {
 
192
        var geometry = this.line && this.line.geometry;
 
193
        if(geometry && this.multi) {
 
194
            geometry = new OpenLayers.Geometry.MultiLineString([geometry]);
 
195
        }
 
196
        return geometry;
 
197
    },
 
198
 
 
199
    /**
 
200
     * Method: mousedown
 
201
     * Handle mouse down.  Add a new point to the geometry and
 
202
     * render it. Return determines whether to propagate the event on the map.
 
203
     * 
 
204
     * Parameters:
 
205
     * evt - {Event} The browser event
 
206
     *
 
207
     * Returns: 
 
208
     * {Boolean} Allow event propagation
 
209
     */
 
210
    mousedown: function(evt) {
 
211
        // ignore double-clicks
 
212
        if (this.lastDown && this.lastDown.equals(evt.xy)) {
 
213
            return false;
 
214
        }
 
215
        if(this.lastDown == null) {
 
216
            if(this.persist) {
 
217
                this.destroyFeature();
 
218
            }
 
219
            this.createFeature(evt.xy);
 
220
        } else if((this.lastUp == null) || !this.lastUp.equals(evt.xy)) {
 
221
            this.addPoint(evt.xy);
 
222
        }
 
223
        this.mouseDown = true;
 
224
        this.lastDown = evt.xy;
 
225
        this.drawing = true;
 
226
        return false;
 
227
    },
 
228
 
 
229
    /**
 
230
     * Method: mousemove
 
231
     * Handle mouse move.  Adjust the geometry and redraw.
 
232
     * Return determines whether to propagate the event on the map.
 
233
     * 
 
234
     * Parameters:
 
235
     * evt - {Event} The browser event
 
236
     *
 
237
     * Returns: 
 
238
     * {Boolean} Allow event propagation
 
239
     */
 
240
    mousemove: function (evt) {
 
241
        if(this.drawing) { 
 
242
            if(this.mouseDown && this.freehandMode(evt)) {
 
243
                this.addPoint(evt.xy);
 
244
            } else {
 
245
                this.modifyFeature(evt.xy);
 
246
            }
 
247
        }
 
248
        return true;
 
249
    },
 
250
    
 
251
    /**
 
252
     * Method: mouseup
 
253
     * Handle mouse up.  Send the latest point in the geometry to
 
254
     * the control. Return determines whether to propagate the event on the map.
 
255
     * 
 
256
     * Parameters:
 
257
     * evt - {Event} The browser event
 
258
     *
 
259
     * Returns: 
 
260
     * {Boolean} Allow event propagation
 
261
     */
 
262
    mouseup: function (evt) {
 
263
        this.mouseDown = false;
 
264
        if(this.drawing) {
 
265
            if(this.freehandMode(evt)) {
 
266
                this.removePoint();
 
267
                this.finalize();
 
268
            } else {
 
269
                if(this.lastUp == null) {
 
270
                   this.addPoint(evt.xy);
 
271
                }
 
272
                this.lastUp = evt.xy;
 
273
            }
 
274
            return false;
 
275
        }
 
276
        return true;
 
277
    },
 
278
  
 
279
    /**
 
280
     * Method: dblclick 
 
281
     * Handle double-clicks.  Finish the geometry and send it back
 
282
     * to the control.
 
283
     * 
 
284
     * Parameters:
 
285
     * evt - {Event} The browser event
 
286
     *
 
287
     * Returns: 
 
288
     * {Boolean} Allow event propagation
 
289
     */
 
290
    dblclick: function(evt) {
 
291
        if(!this.freehandMode(evt)) {
 
292
            var index = this.line.geometry.components.length - 1;
 
293
            this.line.geometry.removeComponent(this.line.geometry.components[index]);
 
294
            this.removePoint();
 
295
            this.finalize();
 
296
        }
 
297
        return false;
 
298
    },
 
299
 
 
300
    CLASS_NAME: "OpenLayers.Handler.Path"
 
301
});