Bienvenue sur PostGIS.fr

Bienvenue sur PostGIS.fr , le site de la communauté des utilisateurs francophones de PostGIS.

PostGIS ajoute le support d'objets géographique à la base de données PostgreSQL. En effet, PostGIS "spatialise" le serverur PostgreSQL, ce qui permet de l'utiliser comme une base de données SIG.

Maintenu à jour, en fonction de nos disponibilités et des diverses sorties des outils que nous testons, nous vous proposons l'ensemble de nos travaux publiés en langue française.

source: trunk/workshop-routing-foss4g/web/GeoExt/lib/GeoExt/data/FeatureStore.js @ 76

Revision 76, 15.2 KB checked in by djay, 12 years ago (diff)

Ajout du répertoire web

  • Property svn:executable set to *
Line 
1/**
2 * Copyright (c) 2008-2010 The Open Source Geospatial Foundation
3 *
4 * Published under the BSD license.
5 * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
6 * of the license.
7 */
8
9/**
10 * @include GeoExt/data/FeatureReader.js
11 */
12
13/** api: (define)
14 *  module = GeoExt.data
15 *  class = FeatureStore
16 *  base_link = `Ext.data.Store <http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Store>`_
17 */
18Ext.namespace("GeoExt.data");
19
20/** api: constructor
21 *  .. class:: FeatureStore
22 *
23 *      A store containing :class:`GeoExt.data.FeatureRecord` entries that
24 *      optionally synchronizes with an ``OpenLayers.Layer.Vector``.
25 */
26
27/** api: example
28 *  Sample code to create a store with features from a vector layer:
29 * 
30 *  .. code-block:: javascript
31 *
32 *      var store = new GeoExt.data.FeatureStore({
33 *          layer: myLayer,
34 *          features: myFeatures
35 *      });
36 */
37
38/**
39 * Class: GeoExt.data.FeatureStoreMixin
40 * A store that synchronizes a features array of an {OpenLayers.Layer.Vector} with a
41 * feature store holding {<GeoExt.data.FeatureRecord>} entries.
42 *
43 * This class can not be instantiated directly. Instead, it is meant to extend
44 * {Ext.data.Store} or a subclass of it:
45 * (start code)
46 * var store = new (Ext.extend(Ext.data.Store, new GeoExt.data.FeatureStoreMixin))({
47 *     layer: myLayer,
48 *     features: myFeatures
49 * });
50 * (end)
51 *
52 * For convenience, a {<GeoExt.data.FeatureStore>} class is available as a
53 * shortcut to the Ext.extend sequence in the above code snippet. The above
54 * is equivalent to:
55 * (start code)
56 * var store = new GeoExt.data.FeatureStore({
57 *     layer: myLayer,
58 *     features: myFeatures
59 * });
60 * (end)
61 */
62GeoExt.data.FeatureStoreMixin = function() {
63    return {
64        /** api: config[layer]
65         *  ``OpenLayers.Layer.Vector``  Layer to synchronize the store with.
66         */
67        layer: null,
68       
69        /** api: config[features]
70         *  ``Array(OpenLayers.Feature.Vector)``  Features that will be added to the
71         *  store (and the layer if provided).
72         */
73
74        /** api: config[reader]
75         *  ``Ext.data.DataReader`` The reader used to produce records from objects
76         *  features.  Default is :class:`GeoExt.data.FeatureReader`.
77         */
78        reader: null,
79
80        /** api: config[featureFilter]
81         *  ``OpenLayers.Filter`` This filter is evaluated before a feature
82         *  record is added to the store.
83         */
84        featureFilter: null,
85       
86        /** api: config[initDir]
87         *  ``Number``  Bitfields specifying the direction to use for the
88         *  initial sync between the layer and the store, if set to 0 then no
89         *  initial sync is done. Default is
90         *  ``GeoExt.data.FeatureStore.LAYER_TO_STORE|GeoExt.data.FeatureStore.STORE_TO_LAYER``.
91         */
92
93        /** private */
94        constructor: function(config) {
95            config = config || {};
96            config.reader = config.reader ||
97                            new GeoExt.data.FeatureReader({}, config.fields);
98            var layer = config.layer;
99            delete config.layer;
100            // 'features' option - is an alias 'data' option
101            if (config.features) {
102                config.data = config.features;
103            }
104            delete config.features;
105            // "initDir" option
106            var options = {initDir: config.initDir};
107            delete config.initDir;
108            arguments.callee.superclass.constructor.call(this, config);
109            if(layer) {
110                this.bind(layer, options);
111            }
112        },
113
114        /** api: method[bind]
115         *  :param layer: ``OpenLayers.Layer`` Layer that the store should be
116         *      synchronized with.
117         * 
118         *  Bind this store to a layer instance, once bound the store
119         *  is synchronized with the layer and vice-versa.
120         */ 
121        bind: function(layer, options) {
122            if(this.layer) {
123                // already bound
124                return;
125            }
126            this.layer = layer;
127            options = options || {};
128
129            var initDir = options.initDir;
130            if(options.initDir == undefined) {
131                initDir = GeoExt.data.FeatureStore.LAYER_TO_STORE |
132                          GeoExt.data.FeatureStore.STORE_TO_LAYER;
133            }
134
135            // create a snapshot of the layer's features
136            var features = layer.features.slice(0);
137
138            if(initDir & GeoExt.data.FeatureStore.STORE_TO_LAYER) {
139                var records = this.getRange();
140                for(var i=records.length - 1; i>=0; i--) {
141                    this.layer.addFeatures([records[i].getFeature()]);
142                }
143            }
144
145            if(initDir & GeoExt.data.FeatureStore.LAYER_TO_STORE) {
146                this.loadData(features, true /* append */);
147            }
148
149            layer.events.on({
150                "featuresadded": this.onFeaturesAdded,
151                "featuresremoved": this.onFeaturesRemoved,
152                "featuremodified": this.onFeatureModified,
153                scope: this
154            });
155            this.on({
156                "load": this.onLoad,
157                "clear": this.onClear,
158                "add": this.onAdd,
159                "remove": this.onRemove,
160                "update": this.onUpdate,
161                scope: this
162            });
163        },
164
165        /** api: method[unbind]
166         *  Unbind this store from the layer it is currently bound.
167         */
168        unbind: function() {
169            if(this.layer) {
170                this.layer.events.un({
171                    "featuresadded": this.onFeaturesAdded,
172                    "featuresremoved": this.onFeaturesRemoved,
173                    "featuremodified": this.onFeatureModified,
174                    scope: this
175                });
176                this.un("load", this.onLoad, this);
177                this.un("clear", this.onClear, this);
178                this.un("add", this.onAdd, this);
179                this.un("remove", this.onRemove, this);
180                this.un("update", this.onUpdate, this);
181
182                this.layer = null;
183            }
184        },
185       
186        /** api: method[getRecordFromFeature]
187         *  :arg feature: ``OpenLayers.Vector.Feature``
188         *  :returns: :class:`GeoExt.data.FeatureRecord` The record corresponding
189         *      to the given feature.  Returns null if no record matches.
190         *
191         *  Get the record corresponding to a feature.
192         */
193        getRecordFromFeature: function(feature) {
194            var record = null;
195            if(feature.state !== OpenLayers.State.INSERT) {
196                record = this.getById(feature.id);
197            } else {
198                var index = this.findBy(function(r) {
199                    return r.getFeature() === feature;
200                });
201                if(index > -1) {
202                    record = this.getAt(index);
203                }
204            }
205            return record;
206        },
207       
208        /** private: method[onFeaturesAdded]
209         *  Handler for layer featuresadded event
210         */
211        onFeaturesAdded: function(evt) {
212            if(!this._adding) {
213                var features = evt.features, toAdd = features;
214                if(this.featureFilter) {
215                    toAdd = [];
216                    var i, len, feature;
217                    for(var i=0, len=features.length; i<len; i++) {
218                        feature = features[i];
219                        if (this.featureFilter.evaluate(feature) !== false) {
220                            toAdd.push(feature);
221                        }
222                    }
223                }
224                // add feature records to the store, when called with
225                // append true loadData triggers an "add" event and
226                // then a "load" event
227                this._adding = true;
228                this.loadData(toAdd, true /* append */);
229                delete this._adding;
230            }
231        },
232       
233        /** private: method[onFeaturesRemoved]
234         *  Handler for layer featuresremoved event
235         */
236        onFeaturesRemoved: function(evt){
237            if(!this._removing) {
238                var features = evt.features, feature, record, i;
239                for(i=features.length - 1; i>=0; i--) {
240                    feature = features[i];
241                    record = this.getRecordFromFeature(feature);
242                    if(record !== undefined) {
243                        this._removing = true;
244                        this.remove(record);
245                        delete this._removing;
246                    }
247                }
248            }
249        },
250       
251        /** private: method[onFeatureModified]
252         *  Handler for layer featuremodified event
253         */
254        onFeatureModified: function(evt) {
255            if(!this._updating) {
256                var feature = evt.feature;
257                var record = this.getRecordFromFeature(feature);
258                if(record !== undefined) {
259                    record.beginEdit();
260                    var attributes = feature.attributes;
261                    if(attributes) {
262                        var fields = this.recordType.prototype.fields;
263                        for(var i=0, len=fields.length; i<len; i++) {
264                            var field = fields.items[i];
265                            var key = field.mapping || field.name;
266                            if(key in attributes) {
267                                record.set(field.name, field.convert(attributes[key]));
268                            }
269                        }
270                    }
271                    // the calls to set below won't trigger "update"
272                    // events because we called beginEdit to start a
273                    // "transaction", "update" will be triggered by
274                    // endEdit
275                    record.set("state", feature.state);
276                    record.set("fid", feature.fid);
277                    record.setFeature(feature);
278                    this._updating = true;
279                    record.endEdit();
280                    delete this._updating;
281                }
282            }
283        },
284
285        /** private: method[addFeaturesToLayer]
286         *  Given an array of records add features to the layer. This
287         *  function is used by the onLoad and onAdd handlers.
288         */
289        addFeaturesToLayer: function(records) {
290            var i, len, features;
291            features = new Array((len=records.length));
292            for(i=0; i<len; i++) {
293                features[i] = records[i].getFeature();
294            }
295            if(features.length > 0) {
296                this._adding = true;
297                this.layer.addFeatures(features);
298                delete this._adding;
299            }
300        },
301       
302        /** private: method[onLoad]
303         *  :param store: ``Ext.data.Store``
304         *  :param records: ``Array(Ext.data.Record)``
305         *  :param options: ``Object``
306         *
307         *  Handler for store load event
308         */
309        onLoad: function(store, records, options) {
310            // if options.add is true an "add" event was already
311            // triggered, and onAdd already did the work of
312            // adding the features to the layer.
313            if(!options || options.add !== true) {
314                this._removing = true;
315                this.layer.removeFeatures(this.layer.features);
316                delete this._removing;
317
318                this.addFeaturesToLayer(records);
319            }
320        },
321       
322        /** private: method[onClear]
323         *  :param store: ``Ext.data.Store``
324         *     
325         *  Handler for store clear event
326         */
327        onClear: function(store) {
328            this._removing = true;
329            this.layer.removeFeatures(this.layer.features);
330            delete this._removing;
331        },
332       
333        /** private: method[onAdd]
334         *  :param store: ``Ext.data.Store``
335         *  :param records: ``Array(Ext.data.Record)``
336         *  :param index: ``Number``
337         *
338         *  Handler for store add event
339         */
340        onAdd: function(store, records, index) {
341            if(!this._adding) {
342                // addFeaturesToLayer takes care of setting
343                // this._adding to true and deleting it
344                this.addFeaturesToLayer(records);
345            }
346        },
347       
348        /** private: method[onRemove]
349         *  :param store: ``Ext.data.Store``
350         *  :param records: ``Array(Ext.data.Record)``
351         *  :param index: ``Number``
352         *     
353         *  Handler for store remove event
354         */
355        onRemove: function(store, record, index){
356            if(!this._removing) {
357                var feature = record.getFeature();
358                if (this.layer.getFeatureById(feature.id) != null) {
359                    this._removing = true;
360                    this.layer.removeFeatures([record.getFeature()]);
361                    delete this._removing;
362                }
363            }
364        },
365
366        /** private: method[onUpdate]
367         *  :param store: ``Ext.data.Store``
368         *  :param record: ``Ext.data.Record``
369         *  :param operation: ``String``
370         *
371         *  Handler for update.
372         */
373        onUpdate: function(store, record, operation) {
374            if(!this._updating) {
375                /**
376                  * TODO: remove this if the FeatureReader adds attributes
377                  * for all fields that map to feature.attributes.
378                  * In that case, it would be sufficient to check (key in feature.attributes).
379                  */
380                var defaultFields = new GeoExt.data.FeatureRecord().fields;
381                var feature = record.getFeature();
382                if(record.fields) {
383                    var cont = this.layer.events.triggerEvent(
384                        "beforefeaturemodified", {feature: feature}
385                    );
386                    if(cont !== false) {
387                        var attributes = feature.attributes;
388                        record.fields.each(
389                            function(field) {
390                                var key = field.mapping || field.name;
391                                if (!defaultFields.containsKey(key)) {
392                                    attributes[key] = record.get(field.name);
393                                }
394                            }
395                        );
396                        this._updating = true;
397                        this.layer.events.triggerEvent(
398                            "featuremodified", {feature: feature}
399                        );
400                        delete this._updating;
401                        if (this.layer.getFeatureById(feature.id) != null) {
402                            this.layer.drawFeature(feature);
403                        }
404                    }
405                }
406            }
407        }
408    };
409};
410
411GeoExt.data.FeatureStore = Ext.extend(
412    Ext.data.Store,
413    new GeoExt.data.FeatureStoreMixin
414);
415
416/**
417 * Constant: GeoExt.data.FeatureStore.LAYER_TO_STORE
418 * {Integer} Constant used to make the store be automatically updated
419 * when changes occur in the layer.
420 */
421GeoExt.data.FeatureStore.LAYER_TO_STORE = 1;
422
423/**
424 * Constant: GeoExt.data.FeatureStore.STORE_TO_LAYER
425 * {Integer} Constant used to make the layer be automatically updated
426 * when changes occur in the store.
427 */
428GeoExt.data.FeatureStore.STORE_TO_LAYER = 2;
Note: See TracBrowser for help on using the repository browser.