root/sandbox/tschaub/wfsv/lib/OpenLayers/Control/FeatureEditor.js

Revision 5571, 10.1 KB (checked in by tschaub, 4 years ago)

More merge corrections, a few new features, and some bug fixes.

Line 
1/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
2 * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
3 * for the full text of the license. */
4
5/**
6 * @requires OpenLayers/Control/Panel.js
7 *
8 * Class: OpenLayers.Control.FeatureEditor
9 *
10 * Inherits from:
11 *  - <OpenLayers.Control.Panel>
12 */
13OpenLayers.Control.FeatureEditor = OpenLayers.Class(OpenLayers.Control.Panel, {
14   
15    /**
16     * Property: vectorLayer
17     * {<OpenLayers.Layer.Vector>} Layer for rendering features.
18     */
19    vectorLayer: null,
20
21    /**
22     * Property: xml
23     * {<OpenLayers.Format.XML>} XML parser
24     */
25    xml: null,
26   
27    /**
28     * Property: gml
29     * {<OpenLayers.Format.GML>} GML parser
30     */
31    gml: null,
32   
33    /**
34     * Property: layerOptions
35     * {Object} Any options to be set on the vector layer.
36     */
37    layerOptions: null,
38   
39    /**
40     * Property: transId
41     * {Integer}
42     */
43    transId: 0,
44   
45    /**
46     * Property: modified
47     * {Boolean} Modifications have been made.
48     */
49    modified: false,
50   
51    /**
52     * Property: staticLayer
53     * {<OpenLayers.Layer>}
54     */
55    staticLayer: null,
56   
57    /**
58     * Constructor: OpenLayers.Control.FeatureEditor
59     * Create a new FeatureEditor panel.
60     *
61     * Parameters:
62     * url - {String} URL for service.
63     * featureType - {String} Name of the FeatureType.
64     * geometryType - {String} Geometry type for the features.  One of
65     *     "Point", "MultiPoint", "LineString", "MultiLineString",
66     *     "Polygon", and "MultiPolygon".
67     * options - {Object} An optional object whose properties will be used
68     *     to extend the control.
69     */
70    initialize: function(url, featureType, geometryType, options) {
71        OpenLayers.Control.Panel.prototype.initialize.apply(this, [options]);
72        OpenLayers.Util.applyDefaults(this.layerOptions, {
73            displayInLayerSwitcher: false,
74            geometry_column: "the_geom",
75            typename: featureType.substring(featureType.lastIndexOf(":") + 1)
76        });
77        this.url = url;
78        this.featureType = featureType;
79        this.geometryType = geometryType;
80        this.vectorLayer = new OpenLayers.Layer.Vector(this.id + "Layer",
81                                                       this.layerOptions);
82        this.xml = new OpenLayers.Format.XML();
83        this.gml = new OpenLayers.Format.GML();
84       
85        this.navigationControl = new OpenLayers.Control.Navigation();
86        this.defaultControl = this.navigationControl;
87       
88        // TODO: better handling of changes flag
89        var panel = this;  // alternatively bind this to callbacks
90
91        // draw control
92        var handlerName = this.geometryType.replace("Multi", "");
93        handlerName = (handlerName == "LineString") ? "Path" : handlerName;
94
95        var handlerOptions = (this.geometryType.indexOf("Multi") == 0) ?
96                                                {forceMulti: true} : {};
97       
98        this.drawControl = new OpenLayers.Control.DrawFeature(
99                            this.vectorLayer,
100                            OpenLayers.Handler[handlerName],
101                            {displayClass: "olControlDrawFeature",
102                            handlerOptions: handlerOptions});
103        this.drawControl.featureAdded = function(feature) {
104            feature.state = OpenLayers.State.INSERT;
105            panel.modified = true;
106        };
107       
108        // getFeature request control
109        this.featuresControl = new OpenLayers.Control.BoundsBox(
110                                                this.prepareRequest, this);
111
112        // modify control
113        this.modifyControl = new OpenLayers.Control.ModifyFeature(
114                this.vectorLayer,
115                {displayClass: "olControlModifyFeature",
116                 onModificationStart: this.onModificationStart,
117                 onModificationEnd: this.onModificationEnd}
118        );
119        this.modifyControl.onModification = function(feature) {
120            if(feature.state != OpenLayers.State.INSERT) {
121                feature.state = OpenLayers.State.UPDATE;
122            }
123            panel.modified = true;
124        };
125
126        // save control
127        var saveOptions = {
128            onSuccess: OpenLayers.Function.bind(this.saveSuccess, this),
129            onFailure: OpenLayers.Function.bind(this.saveFailure, this),
130            formatOptions: {
131                layerName: this.featureType
132            }
133        };
134        if(this.confirmSave) {
135            saveOptions.condition = this.confirmSave;
136        }
137        this.saveControl = new OpenLayers.Control.SaveFeatures(
138                                        this.vectorLayer,
139                                        this.url,
140                                        OpenLayers.Format.WFSV,
141                                        saveOptions);
142       
143        this.addControls([this.saveControl,
144                          this.modifyControl,
145                          this.featuresControl,
146                          this.drawControl,
147                          this.navigationControl]);
148    },
149   
150    /**
151     * Method: changeLayer
152     */
153    changeLayer: function(featureType, geometryType, layerOptions) {
154        var activeTool = this.activeTool;
155        if(activeTool) {
156            activeTool.deactivate();
157        }
158        this.clearFeatures();
159        this.modified = false;
160        this.featureType = featureType;
161        if(layerOptions) {
162            OpenLayers.Util.extend(this.vectorLayer, layerOptions);
163        }
164        if(geometryType && geometryType != this.geometryType) {
165            // switch out the draw control's handler
166            this.geometryType = geometryType;
167            this.drawControl.handler.destroy();
168            var handlerName = this.geometryType.replace("Multi", "");
169            handlerName = (handlerName == "LineString") ? "Path" : handlerName;
170            var options = (this.geometryType.indexOf("Multi") == 0) ?
171                          {forceMulti: true} : {forceMulti: false};
172            OpenLayers.Util.extend(this.drawControl.handlerOptions, options);
173
174            var constructor = OpenLayers.Handler[handlerName];
175            this.drawControl.handler = new constructor(this.drawControl,
176                                                       this.drawControl.callbacks,
177                                                       this.drawControl.handlerOptions);
178        }
179        // set relevant WFS parser properties
180        this.saveControl.format.featureName = this.featureType.substring(this.featureType.lastIndexOf(":") + 1);
181        this.saveControl.format.layerName = this.featureType;
182        if(activeTool) {
183            activeTool.activate();
184        }
185    },
186   
187    /**
188     * Method: clearFeatures
189     */
190    clearFeatures: function() {
191        this.vectorLayer.removeFeatures(this.vectorLayer.features);
192    },
193   
194    /**
195     * Method: saveSuccess
196     */
197    saveSuccess: function(response) {
198        this.transId += 1;
199        this.modified = false;
200        this.activateControl(this.defaultControl);
201        this.clearFeatures();
202        if(this.staticLayer) {
203            this.staticLayer.mergeNewParams({transaction_id: this.transId});
204        }
205    },
206   
207    /**
208     * Method: saveFailure
209     */
210    saveFailure: function(response) {
211        this.modified = false;
212        this.activateControl(this.defaultControl);
213        this.clearFeatures();
214        OpenLayers.Console.log('failed', response);
215    },
216
217    /**
218     * Method: draw
219     *
220     * Returns: {DOMElement}
221     */   
222    draw: function() {
223        this.map.addLayer(this.vectorLayer);
224        return OpenLayers.Control.Panel.prototype.draw.apply(this, arguments);
225    },
226   
227    /**
228     * APIMethod: prepareRequest
229     * Prepare the request to get features.  Prepares a WFS getFeature request
230     *     but can be overridden for other service types.  Calls requestFeatures
231     *     prior to returning.
232     *
233     * Parameters:
234     * bounds - {<OpenLayers.Bounds>}
235     */
236    prepareRequest: function(bounds) {
237        var params = {
238            service: "WFS",
239            request: "getFeature",
240            version: "1.0.0",
241            srsName: this.map.projection,
242            typeName: this.featureType,
243            bbox: [bounds.left, bounds.bottom, bounds.right, bounds.top, this.map.projection]
244        };
245       
246        // TODO: put HTTPRequest.getFullRequestString in Util
247        var url = this.url + "?" + OpenLayers.Util.getParameterString(params);
248       
249        this.requestFeatures(url);
250    },
251   
252    /**
253     * Method: requestFeatures
254     * Issue a request and register listeners for response.
255     *
256     * Parameters:
257     * url - {String}
258     */
259    requestFeatures: function(url) {
260        var callback;
261        var evt = this.featuresControl.handler.evt;
262        if(evt.shiftKey) {
263            callback = this.addFeatures;
264        } else if(evt.ctrlKey) {
265            callback = this.removeFeatures;
266        } else {
267            callback = this.resetFeatures;
268        }
269       
270        OpenLayers.loadURL(url, null, this, callback);
271    },
272   
273    /**
274     * Method: addFeatures
275     */
276    addFeatures: function(request) {
277        var features = this.gml.read(request.responseXML);
278        this.vectorLayer.addFeatures(features, {unique: true});
279    },
280   
281    /**
282     * Method: removeFeatures
283     */
284    removeFeatures: function(request) {
285        var features = this.gml.read(request.responseXML);
286        var forRemoval = [];
287        var fid, potentialFeature;
288        for(var i=0; i<features.length; ++i) {
289            potentialFeature = this.vectorLayer.fids[features[i].fid];
290            if(potentialFeature) {
291                forRemoval.push(potentialFeature);
292            }
293        }
294        this.vectorLayer.removeFeatures(forRemoval);
295    },
296   
297    /**
298     * Method: resetFeatures
299     */
300    resetFeatures: function(request) {
301        var features = this.gml.read(request.responseXML);
302        // remove current features and add new ones
303        // TODO: modify layer.destroyFeatures for use here
304        this.vectorLayer.removeFeatures(this.vectorLayer.features);
305        this.vectorLayer.addFeatures(features);
306    },   
307   
308    CLASS_NAME: "OpenLayers.Control.FeatureEditor"
309   
310});
Note: See TracBrowser for help on using the browser.