Ticket #18: patch-18-r371-C0.diff
| File patch-18-r371-C0.diff, 45.8 kB (added by elemoine, 1 year ago) |
|---|
-
build/apidoc_config/Menu.txt
old new 50 50 51 51 File: FeatureReader (GeoExt/data/FeatureReader.js) 52 52 File: FeatureRecord (GeoExt/data/FeatureRecord.js) 53 File: FeatureStoreM ediator (GeoExt/data/FeatureStoreMediator.js)53 File: FeatureStoreMixin (GeoExt/data/FeatureStore.js) 54 54 File: LayerReader (GeoExt/data/LayerReader.js) 55 55 File: LayerRecord (GeoExt/data/LayerRecord.js) 56 File: LayerStoreMediator (GeoExt/data/LayerStoreMediator.js)57 56 File: LayerStoreMixin (GeoExt/data/LayerStore.js) 58 57 File: ProtocolProxy (GeoExt/data/ProtocolProxy.js) 59 58 } # Group: Data -
tests/lib/GeoExt/data/FeatureStoreMediator.html
old new 1 <!DOCTYPE html>2 <html debug="true">3 <head>4 <script type="text/javascript" src="../../../../../ext/adapter/ext/ext-base.js"></script>5 <script type="text/javascript" src="../../../../../ext/ext-all-debug.js"></script>6 7 <script type="text/javascript" src="../../../../../openlayers/lib/OpenLayers.js"></script>8 <script type="text/javascript" src="../../../../lib/GeoExt.js"></script>9 10 <script type="text/javascript">11 function test_constructor(t) {12 t.plan(1);13 // setup14 var mediator, store;15 store = new Ext.data.Store({16 reader: new GeoExt.data.FeatureReader(17 {}, [{name: "name", type: "string"}]18 )19 });20 // 1 test21 mediator = new GeoExt.data.FeatureStoreMediator({22 store: store23 });24 t.ok(mediator.store == store,25 "ctor correctly sets store");26 }27 function test_addFeatures(t) {28 t.plan(4);29 // setup30 var mediator, store, features, flip, filter;31 store = new Ext.data.Store({32 reader: new GeoExt.data.FeatureReader(33 {}, [{name: "name", type: "string"}]34 )35 });36 mediator = new GeoExt.data.FeatureStoreMediator({37 store: store38 });39 function createFeatures() {40 return [41 new OpenLayers.Feature.Vector(null, {42 name: "foo"43 }),44 new OpenLayers.Feature.Vector()45 ];46 }47 // 2 tests48 features = createFeatures();49 mediator.addFeatures(features);50 t.eq(store.getCount(), 2,51 "addFeatures adds correct number of features");52 var record = store.getById(features[0].id);53 t.ok(record.get('feature') == features[0],54 'addFeatures correctly adds features');55 // 1 test56 features = createFeatures();57 mediator.addFeatures(features, {append: false});58 t.eq(store.getCount(), 2,59 "addFeatures adds correct number of features");60 // 1 test61 flip = false;62 filter = function() { flip = !flip; return flip; };63 features = createFeatures();64 mediator.addFeatures(features,65 {append: false, filter: filter});66 t.eq(store.getCount(), 1,67 "addFeatures adds correct number of features " +68 "with filter passed");69 }70 // there's a bug in Ext where Ext dereferences an undefined71 // value, the bug triggers with a grouping store and group72 // field when store.loadData is called with only one arg73 // or with false as the second arg. addFeatures works74 // around that bug, so that test_addFeatures_ExtBug passes75 //76 // prefix the function name with test_ if you want to77 // actually run the test78 /*79 function ExtBug(t) {80 t.plan(1);81 // setup82 var store, a;83 store = new Ext.data.GroupingStore({84 reader: new Ext.data.ArrayReader({id: 0}, [85 {name: "name", mapping: 1},86 {name: "occupation", mapping: 2}87 ]),88 groupField: "name"89 });90 a = [[1, 'Bill', 'Gardener'], [2, 'Ben', 'Horticulturalist']];91 store.loadData(a, false); // same effect with store.loadData(a)92 // 1 test93 t.eq(store.getCount(), 2,94 "correct number of records loaded");95 }96 */97 function test_addFeatures_ExtBug(t) {98 t.plan(2);99 // setup100 var mediator, store, features, flip, filter;101 store = new Ext.data.GroupingStore({102 reader: new GeoExt.data.FeatureReader(103 {}, [{name: "name", type: "string"}]104 ),105 groupField: "name"106 });107 mediator = new GeoExt.data.FeatureStoreMediator({108 store: store109 });110 function createFeatures() {111 return [112 new OpenLayers.Feature.Vector(null, {113 name: "foo"114 }),115 new OpenLayers.Feature.Vector()116 ];117 }118 // 2 tests119 features = createFeatures();120 // {append: false} makes Ext panic without the workaround121 // in FeatureStoreMediator.js, see test_ExtBug for making122 // Ext panic without MapFish involves123 mediator.addFeatures(features, {append: false});124 t.eq(store.getCount(), 2,125 "addFeatures adds correct number of features");126 var record = store.getById(features[0].id);127 t.ok(record.get('feature') == features[0],128 'addFeatures correctly adds features');129 }130 function test_removeFeatures(t) {131 t.plan(1);132 // setup133 var mediator, store, features;134 store = new Ext.data.Store({135 reader: new GeoExt.data.FeatureReader(136 {}, [{name: "name", type: "string"}]137 )138 });139 mediator = new GeoExt.data.FeatureStoreMediator({140 store: store141 });142 function createFeatures() {143 return [144 new OpenLayers.Feature.Vector(null, {145 name: "foo"146 }),147 new OpenLayers.Feature.Vector()148 ];149 }150 // 1 test151 features = createFeatures();152 mediator.addFeatures(features);153 mediator.removeFeatures(features);154 t.eq(store.getCount(), 0,155 'removesFeatures correctly removes features');156 }157 </script>158 <body>159 <div id="map"></div>160 </body>161 </html> -
tests/lib/GeoExt/data/LayerStoreMediator.html
old new 1 <!DOCTYPE html>2 <html debug="true">3 <head>4 <script type="text/javascript" src="../../../../../ext/adapter/ext/ext-base.js"></script>5 <script type="text/javascript" src="../../../../../ext/ext-all-debug.js"></script>6 7 <script type="text/javascript" src="../../../../../openlayers/lib/OpenLayers.js"></script>8 <script type="text/javascript" src="../../../../lib/GeoExt.js"></script>9 10 <script type="text/javascript">11 function test_constructor(t) {12 t.plan(3);13 // setup14 var mediator, store, layer;15 store = new Ext.data.Store({16 reader: new GeoExt.data.FeatureReader(17 {}, [{name: "name", type: "string"}]18 )19 });20 layer = new OpenLayers.Layer.Vector();21 // 3 tests22 mediator = new GeoExt.data.LayerStoreMediator({23 store: store,24 layer: layer,25 activate: function() {26 t.ok(true, "ctor calls activate");27 }28 });29 t.ok(mediator.layer == layer,30 "ctor correctly sets layer");31 t.ok(mediator.featureStoreMediator instanceof32 GeoExt.data.FeatureStoreMediator,33 "ctor correctly creates feature store mediator");34 }35 function test_events(t) {36 t.plan(3);37 // setup38 var mediator, store, layer, eventType;39 store = new Ext.data.Store({40 reader: new GeoExt.data.FeatureReader(41 {}, [{name: "name", type: "string"}]42 )43 });44 layer = new OpenLayers.Layer.Vector();45 mediator = new GeoExt.data.LayerStoreMediator({46 store: store,47 layer: layer,48 update: function() {49 t.ok(true, "update called on " + eventType);50 }51 });52 // 1 test53 eventType = "featuresadded";54 layer.events.triggerEvent(eventType);55 // 1 test56 eventType = "featuresremoved";57 layer.events.triggerEvent(eventType);58 // 1 test59 eventType = "featuremodified";60 layer.events.triggerEvent(eventType);61 }62 function test_update(t) {63 t.plan(2);64 // setup65 var mediator, store, layer;66 store = new Ext.data.Store({67 reader: new GeoExt.data.FeatureReader(68 {}, [{name: "name", type: "string"}]69 )70 });71 layer = new OpenLayers.Layer.Vector();72 mediator = new GeoExt.data.LayerStoreMediator({73 store: store,74 layer: layer75 });76 function createFeatures() {77 return [78 new OpenLayers.Feature.Vector(null, {name: "foo"}),79 new OpenLayers.Feature.Vector(null, {name: "bar"})80 ];81 }82 // 1 test83 layer.features = createFeatures();84 layer.events.triggerEvent("featuresadded");85 t.eq(store.getCount(), 2,86 "featuresadded event caused insertion of 2 records");87 // 1 test88 layer.features = createFeatures();89 layer.events.triggerEvent("featuresadded");90 t.eq(store.getCount(), 2,91 "featuresadded event caused insertion of 2 records");92 }93 </script>94 <body>95 <div id="map"></div>96 </body>97 </html> -
tests/lib/GeoExt/data/FeatureStore.html
old new 1 <!DOCTYPE html> 2 <html debug="true"> 3 <head> 4 <script type="text/javascript" src="../../../../../openlayers/lib/OpenLayers.js"></script> 5 <script type="text/javascript" src="../../../../../ext/adapter/ext/ext-base.js"></script> 6 <script type="text/javascript" src="../../../../../ext/ext-all-debug.js"></script> 7 <script type="text/javascript" src="../../../../lib/GeoExt.js"></script> 8 9 <script type="text/javascript"> 10 function test_constructor(t) { 11 t.plan(3); 12 13 var store, reader, layer; 14 15 store = new GeoExt.data.FeatureStore(); 16 t.ok(store.reader instanceof GeoExt.data.FeatureReader, 17 "ctor creates a feature reader if none is provided"); 18 19 reader = new Ext.data.ArrayReader(); 20 store = new GeoExt.data.FeatureStore({reader: reader}); 21 t.ok(store.reader == reader, 22 "ctor sets the passed reader in the instance"); 23 24 layer = new OpenLayers.Layer.Vector("Foo Layer"); 25 store = new GeoExt.data.FeatureStore({layer: layer}); 26 t.ok(store.layer == layer, 27 "ctor sets the passed layer in the instance"); 28 } 29 30 function test_load_clear(t) { 31 t.plan(4); 32 33 var layer = new OpenLayers.Layer.Vector("Foo layer"); 34 var store = new GeoExt.data.FeatureStore({ 35 layer: layer 36 }); 37 38 store.loadData([ 39 new OpenLayers.Feature.Vector(), 40 new OpenLayers.Feature.Vector() 41 ]); 42 t.eq(layer.features.length, 2, "loading two records in the store with 'loadData' adds two features to the layer"); 43 t.eq(store.getCount(), 2, 'loading two records in the store with "loadData" does not create duplicate records in store'); 44 45 store.removeAll(); 46 t.eq(store.getCount(), 0, '"removeAll" on store removes all records from the store'); 47 t.eq(layer.features.length, 0, '"removeAll" on store removes features from layer'); 48 } 49 50 function test_bind_unbind(t) { 51 t.plan(28); 52 53 var layer = new OpenLayers.Layer.Vector("Foo layer"); 54 var store = new GeoExt.data.FeatureStore(); 55 var features = [new OpenLayers.Feature.Vector("Foo feature"), 56 new OpenLayers.Feature.Vector("Bar feature")]; 57 var records = [ 58 new GeoExt.data.FeatureRecord({ 59 feature: new OpenLayers.Feature.Vector("Foo record")}), 60 new GeoExt.data.FeatureRecord({ 61 feature: new OpenLayers.Feature.Vector("Bar record")}) 62 ]; 63 64 var reinit_test_data = function () { 65 // unbind store 66 store.unbind(); 67 68 // remove all existing records and features 69 store.removeAll(); 70 layer.removeFeatures(layer.features); 71 t.eq(layer.features.length, 0, "there is no more features in the layer"); 72 t.eq(store.getCount(), 0, "there is no more records in the store"); 73 74 // add testing data to store and layer 75 store.add(records); 76 layer.addFeatures(features); 77 t.eq(layer.features.length, 2, "initial features are loaded in the layer"); 78 t.eq(store.getCount(), 2, "initial records are loaded in the store"); 79 }; 80 81 // test store to layer synchronization 82 reinit_test_data(); 83 store.bind(layer, {initDir: GeoExt.data.FeatureStore.STORE_TO_LAYER}); 84 t.eq(layer.features.length, 4, "initial records are synchronized to layer"); 85 t.eq(store.getCount(), 2, "initial features are not synchronized to store"); 86 layer.removeFeatures([features[0]]); 87 t.eq(layer.features.length, 3, "removing feature not present in store has been well removed"); 88 t.eq(store.getCount(), 2, "nothing to remove in store when removing feature not present in store"); 89 90 // test layer to store synchronization 91 reinit_test_data(); 92 store.bind(layer, {initDir: GeoExt.data.FeatureStore.LAYER_TO_STORE}); 93 t.eq(layer.features.length, 2, "initial records are not synchronized to layer"); 94 t.eq(store.getCount(), 4, "initial features are synchronized to store"); 95 store.remove(records[0]); 96 t.eq(store.getCount(), 3, "removing record not present in layer has been well removed"); 97 t.eq(layer.features.length, 2, "nothing to remove in layer when removing record not present in layer"); 98 99 // test both synchronization 100 reinit_test_data(); 101 store.bind(layer, {initDir: GeoExt.data.FeatureStore.LAYER_TO_STORE | 102 GeoExt.data.FeatureStore.STORE_TO_LAYER}); 103 t.eq(layer.features.length, 4, "initial records are synchronized to layer"); 104 t.eq(store.getCount(), 4, "initial features are synchronized to store"); 105 106 // test no synchronization 107 reinit_test_data(); 108 store.bind(layer, {initDir: 0}); 109 t.eq(layer.features.length, 2, "initial records are not synchronized to layer"); 110 t.eq(store.getCount(), 2, "initial features are not synchronized to store"); 111 } 112 113 function test_add_remove(t) { 114 115 t.plan(4); 116 117 var layer = new OpenLayers.Layer.Vector("Foo layer"); 118 var store = new GeoExt.data.FeatureStore({ 119 layer: layer 120 }); 121 var record = new GeoExt.data.FeatureRecord({ 122 feature: new OpenLayers.Feature.Vector() 123 }); 124 125 store.add([record]); 126 t.eq(store.getCount(), 1, 'Adding a record to store with "add" does not create duplicate record in store'); 127 t.eq(layer.features.length, 1, 'Adding a record to store with "add" does create correspondant feature in layer'); 128 129 store.remove(record); 130 t.eq(store.getCount(), 0, 'remove on store with "remove" removes the record from the store'); 131 t.eq(layer.features.length, 0, 'remove on store with "remove" removes the correspondant feature from layer'); 132 } 133 134 function test_addFeatures_removeFeatures(t) { 135 136 t.plan(4); 137 138 var features = [ 139 new OpenLayers.Feature.Vector(), 140 new OpenLayers.Feature.Vector() 141 ]; 142 var layer = new OpenLayers.Layer.Vector("Foo layer"); 143 var store = new GeoExt.data.FeatureStore({ 144 layer: layer 145 }); 146 147 // test layer addFeatures 148 layer.addFeatures(features); 149 t.eq(layer.features.length, 2, 'Adding features to layer with "addFeatures" does not create duplicate features on the layer'); 150 t.eq(store.getCount(), 2, 'Adding features to layer with "addFeatures" does create correspondant records in the store'); 151 152 // test layer removeFeatures 153 layer.removeFeatures(layer.features); 154 t.eq(store.getCount(), 0, '"removeFeatures" on layer removes records from the store'); 155 t.eq(layer.features.length, 0, '"removeFeatures" on layer removes features from layer'); 156 } 157 158 function test_featuremodified_update(t) { 159 t.plan(6); 160 161 /* 162 * Set up 163 */ 164 var feature, id, layer, store, recordType, record; 165 166 feature = new OpenLayers.Feature.Vector(null, { 167 foo: "foo", 168 bar: "bar" 169 }); 170 171 id = feature.id; 172 173 recordType = GeoExt.data.FeatureRecord.create([ 174 {name: "foo"}, {name: "bar"} 175 ]); 176 177 layer = new OpenLayers.Layer.Vector("vector"); 178 179 store = new GeoExt.data.FeatureStore({ 180 layer: layer, 181 recordType: recordType, 182 data: [feature] 183 }); 184 185 t.eq(store.getById(id).get("foo"), "foo", 186 "record gets correct initial value for property \"foo\""); 187 188 t.eq(store.getById(id).get("bar"), "bar", 189 "record gets correct initial value for property \"bar\""); 190 191 /* 192 * Test 193 */ 194 195 // featuremodified 196 feature.attributes.foo = "foo2"; 197 feature.attributes.bar = "bar2"; 198 layer.events.triggerEvent("featuremodified", {feature: feature}); 199 200 t.eq(store.getById(id).get("foo"), "foo2", 201 "featuremodified event causes update of record property \"foo\""); 202 203 t.eq(store.getById(id).get("bar"), "bar2", 204 "featuremodified event causes update of record property \"bar\""); 205 206 // update 207 record = store.getById(id); 208 record.set("foo", "foo3"); 209 record.set("bar", "bar3"); 210 211 t.eq(layer.getFeatureById(id).attributes.foo, "foo3", 212 "update event causes update of feature property \"foo\""); 213 214 t.eq(layer.getFeatureById(id).attributes.bar, "bar3", 215 "update event causes update of feature property \"bar\""); 216 217 } 218 </script> 219 220 <body> 221 <div id="map"></div> 222 </body> 223 </html> 224 -
tests/list-tests.html
old new 1 1 <ul id="testlist"> 2 2 <li>lib/GeoExt/data/FeatureRecord.html</li> 3 3 <li>lib/GeoExt/data/FeatureReader.html</li> 4 <li>lib/GeoExt/data/FeatureStore Mediator.html</li>4 <li>lib/GeoExt/data/FeatureStore.html</li> 5 5 <li>lib/GeoExt/data/LayerRecord.html</li> 6 6 <li>lib/GeoExt/data/LayerReader.html</li> 7 7 <li>lib/GeoExt/data/LayerStore.html</li> 8 <li>lib/GeoExt/data/LayerStoreMediator.html</li>9 8 <li>lib/GeoExt/data/ProtocolProxy.html</li> 10 9 <li>lib/GeoExt/widgets/MapPanel.html</li> 11 10 <li>lib/GeoExt/widgets/Popup.html</li> -
lib/GeoExt.js
old new 60 60 var jsfiles = new Array( 61 61 "GeoExt/data/FeatureRecord.js", 62 62 "GeoExt/data/FeatureReader.js", 63 "GeoExt/data/FeatureStore Mediator.js",63 "GeoExt/data/FeatureStore.js", 64 64 "GeoExt/data/LayerRecord.js", 65 65 "GeoExt/data/LayerReader.js", 66 66 "GeoExt/data/LayerStore.js", 67 "GeoExt/data/LayerStoreMediator.js",68 67 "GeoExt/data/ProtocolProxy.js", 69 68 "GeoExt/widgets/MapPanel.js", 70 69 "GeoExt/widgets/Popup.js" -
lib/GeoExt/data/FeatureStore.js
old new 1 /* Copyright (C) 2008-2009 The Open Source Geospatial Foundation ¹ 2 * Published under the BSD license. 3 * See http://geoext.org/svn/geoext/core/trunk/license.txt for the full text 4 * of the license. 5 * 6 * ¹ pending approval */ 7 8 /** 9 * @include GeoExt/data/FeatureReader.js 10 */ 11 12 Ext.namespace("GeoExt.data"); 13 14 /** 15 * Class: GeoExt.data.FeatureStoreMixin 16 * A store that synchronizes a features array of an {OpenLayers.Layer.Vector} with a 17 * feature store holding {<GeoExt.data.FeatureRecord>} entries. 18 * 19 * This class can not be instantiated directly. Instead, it is meant to extend 20 * {Ext.data.Store} or a subclass of it: 21 * (start code) 22 * var store = new (Ext.extend(Ext.data.Store, GeoExt.data.FeatureStoreMixin))({ 23 * layer: myLayer, 24 * features: myFeatures 25 * }); 26 * (end) 27 * 28 * For convenience, a {<GeoExt.data.FeatureStore>} class is available as a 29 * shortcut to the Ext.extend sequence in the above code snippet. The above 30 * is equivalent to: 31 * (start code) 32 * var store = new GeoExt.data.FeatureStore({ 33 * layer: myLayer, 34 * features: myFeatures 35 * }); 36 * (end) 37 */ 38 GeoExt.data.FeatureStoreMixin = { 39 /** 40 * APIProperty: layer 41 * {OpenLayers.Layer.Vector} Layer that this store will be in sync with. 42 */ 43 layer: null, 44 45 /** 46 * Property: reader 47 * {<GeoExt.data.FeatureReader>} The reader used to get 48 * <GeoExt.data.FeatureRecord> objects from {OpenLayers.Feature.Vector} 49 * objects. 50 */ 51 reader: null, 52 53 /** 54 * Constructor: GeoExt.data.FeatureStoreMixin 55 * 56 * Parameters: 57 * config - {Object} 58 * 59 * Valid config options: 60 * layer - {OpenLayers.Layer.Vector} layer to sync the feature store with. 61 * features - {Array(OpenLayers.Feature.Vector)} Features that will be added to the 62 * feature store (and the layer, because we are already syncing). 63 * recordType - {<GeoExt.data.FeatureRecord>} If provided, a custom feature 64 * record type with additional fields will be used. Default fields for 65 * every feature record are {OpenLayers.Feature.Vector} feature and {String} title. 66 * initDir - {Number} Bitfields specifying the direction to use for the 67 * initial sync between the layer and the store, if set to 0 then no 68 * initial sync is done. Defaults to 69 * <GeoExt.data.FeatureStore.LAYER_TO_STORE>|<GeoExt.data.FeatureStore.STORE_TO_LAYER>. 70 */ 71 constructor: function(config) { 72 config = config || {}; 73 config.reader = config.reader || 74 new GeoExt.data.FeatureReader({}, config.recordType); 75 var layer = config.layer; 76 delete config.layer; 77 // 'features' option - is an alias 'data' option 78 if (config.features) { 79 config.data = config.features; 80 } 81 delete config.features; 82 // "initDir" option 83 var options = {initDir: config.initDir}; 84 delete config.initDir; 85 arguments.callee.superclass.constructor.call(this, config); 86 if(layer) { 87 this.bind(layer, options); 88 } 89 }, 90 91 /** 92 * APIMethod: bind 93 * Bind this store to a layer instance, once bound the store 94 * is synchronized with the layer and vice-versa. 95 * 96 * Parameters: 97 * layer - {OpenLayers.Layer.Vector} The layer instance. 98 * options - {Object} 99 * 100 * Valid config options: 101 * initDir - {Number} Bitfields specifying the direction to use for the 102 * initial sync between the layer and the store, if set to 0 then no 103 * initial sync is done. Defaults to 104 * <GeoExt.data.FeatureStore.LAYER_TO_STORE>|<GeoExt.data.FeatureStore.STORE_TO_LAYER>. 105 */ 106 bind: function(layer, options) { 107 if(this.layer) { 108 // already bound 109 return; 110 } 111 this.layer = layer; 112 options = options || {}; 113 114 var initDir = options.initDir; 115 if(options.initDir == undefined) { 116 initDir = GeoExt.data.FeatureStore.LAYER_TO_STORE | 117 GeoExt.data.FeatureStore.STORE_TO_LAYER; 118 } 119 120 // create a snapshot of the layer's features 121 var features = layer.features.slice(0); 122 123 if(initDir & GeoExt.data.FeatureStore.STORE_TO_LAYER) { 124 var records = this.getRange(); 125 for(var i=records.length - 1; i>=0; i--) { 126 this.layer.addFeatures([records[i].get("feature")]); 127 } 128 } 129 if(initDir & GeoExt.data.FeatureStore.LAYER_TO_STORE) { 130 this.loadData(features, true); 131 } 132 133 layer.events.on({ 134 "featuresadded": this.onFeaturesAdded, 135 "featuresremoved": this.onFeaturesRemoved, 136 "featuremodified": this.onFeatureModified, 137 scope: this 138 }); 139 this.on({ 140 "load": this.onLoad, 141 "clear": this.onClear, 142 "add": this.onAdd, 143 "remove": this.onRemove, 144 "update": this.onUpdate, 145 scope: this 146 }); 147 }, 148 149 /** 150 * APIMethod: unbind 151 * Unbind this store from the layer it is currently bound. 152 */ 153 unbind: function() { 154 if(this.layer) { 155 this.layer.events.un({ 156 "featuresadded": this.onFeaturesAdded, 157 "featuresremoved": this.onFeaturesRemoved, 158 "featuremodified": this.onFeatureModified, 159 scope: this 160 }); 161 this.un("load", this.onLoad, this); 162 this.un("clear", this.onClear, this); 163 this.un("add", this.onAdd, this); 164 this.un("remove", this.onRemove, this); 165 this.un("update", this.onUpdate, this); 166 167 this.layer = null; 168 } 169 }, 170 171 172 /** 173 * Method: onFeaturesAdded 174 * Handler for layer featuresadded event 175 * 176 * Parameters: 177 * evt - {Object} 178 */ 179 onFeaturesAdded: function(evt) { 180 if(!this._adding) { 181 this._adding = true; 182 var features = evt.features; 183 this.loadData(features, true); 184 delete this._adding; 185 } 186 }, 187 188 /** 189 * Method: onFeaturesRemoved 190 * Handler for layer featuresremoved event 191 * 192 * Parameters: 193 * evt - {Object} 194 */ 195 onFeaturesRemoved: function(evt){ 196 if(!this._removing) { 197 this._removing = true; 198 var features = evt.features, feature, record, i; 199 for(i=features.length - 1; i>=0; i--) { 200 feature = features[i]; 201 record = this.getById(feature.id); 202 if(record !== undefined) { 203 this.remove(record); 204 } 205 } 206 delete this._removing; 207 } 208 }, 209 210 /** 211 * Method: onFeatureModified 212 * Handler for layer featuremodified event 213 * 214 * Parameters: 215 * evt - {Object} 216 */ 217 onFeatureModified: function(evt) { 218 if(!this._updating) { 219 this._updating = true; 220 var feature = evt.feature; 221 var record = this.getById(feature.id); 222 if(record !== undefined) { 223 record.beginEdit(); 224 attributes = feature.attributes; 225 if(attributes) { 226 var fields = this.recordType.prototype.fields; 227 for(var i=0, len=fields.length; i<len; i++) { 228 var field = fields.items[i]; 229 var v = attributes[field.mapping || field.name] || 230 field.defaultValue; 231 v = field.convert(v); 232 record.set(field.name, v); 233 } 234 } 235 record.set("state", feature.state); 236 record.set("fid", feature.fid); 237 record.set("feature", feature); 238 record.endEdit(); 239 } 240 delete this._updating; 241 } 242 }, 243 244 /** 245 * Method: onLoad 246 * Handler for store load event 247 * 248 * Parameters: 249 * store - {Ext.data.Store} 250 * records - {Array(Ext.data.Record)} 251 * options - {Object} 252 */ 253 onLoad: function(store, records, options) { 254 if (options && !options.add) { 255 this._removing = true; 256 this.layer.removeFeatures(this.layer.features); 257 delete this._removing; 258 259 // features has already been added to layer on "add" event 260 var len = records.length; 261 if (len > 0) { 262 var features = new Array(len); 263 for (var j = 0; j < len; j++) { 264 features[j] = records[j].get("feature"); 265 } 266 this._adding = true; 267 this.layer.addFeatures(features); 268 delete this._adding; 269 } 270 } 271 }, 272 273 /** 274 * Method: onClear 275 * Handler for store clear event 276 * 277 * Parameters: 278 * store - {Ext.data.Store} 279 */ 280 onClear: function(store) { 281 this._removing = true; 282 this.layer.removeFeatures(this.layer.features); 283 delete this._removing; 284 }, 285 286 /** 287 * Method: onAdd 288 * Handler for store add event 289 * 290 * Parameters: 291 * store - {Ext.data.Store} 292 * records - {Array(Ext.data.Record)} 293 * index - {Number} 294 */ 295 onAdd: function(store, records, index) { 296 if(!this._adding) { 297 var len = records.length; 298 if (len > 0) { 299 var features = new Array(len); 300 for (var j = 0; j < len; j++) { 301 features[j] = records[j].get("feature"); 302 } 303 this._adding = true; 304 this.layer.addFeatures(features); 305 delete this._adding; 306 } 307 } 308 }, 309 310 /** 311 * Method: onRemove 312 * Handler for store remove event 313 * 314 * Parameters: 315 * store - {Ext.data.Store} 316 * records - {Array(Ext.data.Record)} 317 * index - {Number} 318 */ 319 onRemove: function(store, record, index){ 320 if(!this._removing) { 321 var feature = record.get("feature"); 322 if (this.layer.getFeatureById(feature.id) != null) { 323 this._removing = true; 324 this.layer.removeFeatures([record.get("feature")]); 325 delete this._removing; 326 } 327 } 328 }, 329 330 /** 331 * Method: onUpdate 332 * Handler for store update event 333 * 334 * Parameters: 335 * store - {Ext.data.Store} 336 * record - (Ext.data.Record)} 337 * operation - {String} 338 */ 339 onUpdate: function(store, record, operation) { 340 if(!this._updating) { 341 var feature = record.get("feature"); 342 if(record.fields) { 343 var cont = this.layer.events.triggerEvent( 344 "beforefeaturemodified", {feature: feature} 345 ); 346 if(cont !== false) { 347 record.fields.each( 348 function(field) { 349 feature.attributes[field.mapping || field.name] = 350 record.get(field.name); 351 } 352 ); 353 this._updating = true; 354 this.layer.events.triggerEvent( 355 "featuremodified", {feature: feature} 356 ); 357 delete this._updating; 358 if (this.layer.getFeatureById(feature.id) != null) { 359 this.layer.drawFeature(feature); 360 } 361 } 362 } 363 } 364 } 365 }; 366 367 /** 368 * Class: GeoExt.data.FeatureStore 369 * Default implementation of an {Ext.data.Store} extended with 370 * {<GeoExt.data.FeatureStoreMixin>} 371 * 372 * Inherits from: 373 * - {Ext.data.Store} 374 * - {<GeoExt.data.FeatureStoreMixin>} 375 */ 376 /** 377 * Constructor: GeoExt.data.FeatureStore 378 * 379 * Parameters: 380 * config - {Object} See {<GeoExt.data.FeatureStoreMixin>} and 381 * http://extjs.com/deploy/dev/docs/?class=Ext.data.Store for valid config 382 * options. 383 */ 384 GeoExt.data.FeatureStore = Ext.extend( 385 Ext.data.Store, 386 GeoExt.data.FeatureStoreMixin 387 ); 388 389 /** 390 * Constant: GeoExt.data.FeatureStore.LAYER_TO_STORE 391 * {Integer} Constant used to make the store be automatically updated 392 * when changes occur in the layer. 393 */ 394 GeoExt.data.FeatureStore.LAYER_TO_STORE = 1; 395 396 /** 397 * Constant: GeoExt.data.FeatureStore.STORE_TO_LAYER 398 * {Integer} Constant used to make the layer be automatically updated 399 * when changes occur in the store. 400 */ 401 GeoExt.data.FeatureStore.STORE_TO_LAYER = 2; -
lib/GeoExt/data/FeatureStoreMediator.js
old new 1 /*2 * Copyright (C) 2008 Eric Lemoine, Camptocamp France SAS3 *4 * This file is part of GeoExt5 *6 * GeoExt is free software: you can redistribute it and/or modify7 * it under the terms of the GNU General Public License as published by8 * the Free Software Foundation, either version 3 of the License, or9 * (at your option) any later version.10 *11 * GeoExt is distributed in the hope that it will be useful,12 * but WITHOUT ANY WARRANTY; without even the implied warranty of13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14 * GNU General Public License for more details.15 *16 * You should have received a copy of the GNU General Public License17 * along with GeoExt. If not, see <http://www.gnu.org/licenses/>.18 */19 20 /**21 * @requires GeoExt/data/FeatureReader.js22 */23 24 Ext.namespace('GeoExt', 'GeoExt.data');25 26 /**27 * Class: GeoExt.data.FeatureStoreMediator28 * This class is to be used when one wants to insert features in a store.29 *30 * Usage example:31 * (start code)32 * var store = new Ext.data.Store({33 * reader: new GeoExt.data.FeatureReader(34 * {}, [{name: "name", type: "string"}]35 * )36 * });37 * var mediator = new GeoExt.data.FeatureStoreMediator({38 * store: store,39 * append: false,40 * filter: function(feature) {41 * return feature.state != OpenLayers.State.UNKNOWN;42 * }43 * });44 * (end)45 */46 47 /**48 * Constructor: GeoExt.data.FeatureStoreMediator49 * Create an instance of GeoExt.data.FeatureStoreMediator50 *51 * Parameters:52 * config - {Object} A config object used to set the feature53 * store mediator's properties, see below for the list54 * of supported properties.55 *56 * Returns:57 * {<GeoExt.data.FeatureStoreMediator>}58 */59 GeoExt.data.FeatureStoreMediator = function(config){60 Ext.apply(this, config);61 if (!this.store) {62 OpenLayers.Console.error(63 "store is missing in the config");64 }65 if (!(this.store.reader instanceof GeoExt.data.FeatureReader)) {66 OpenLayers.Console.error(67 "store does not use a FeatureReader");68 }69 };70 71 GeoExt.data.FeatureStoreMediator.prototype = {72 /**73 * APIProperty: store74 * {Ext.data.Store} An Ext data store75 */76 store: null,77 78 /**79 * APIProperty: append80 * {Boolean} False if the store must be cleared before adding new81 * features into it, false otherwise; defaults to true.82 */83 append: true,84 85 /**86 * APIProperty: filter87 * {Function} a filter function called for each feature to be88 * inserted, the feature is passed as an argument to the function,89 * if it returns true the feature is inserted into the store,90 * otherwise the feature is not inserted.91 */92 filter: null,93 94 /**95 * APIMethod: addFeatures96 * Add features to the store.97 *98 * Parameters:99 * features - {<OpenLayers.Feature.Vector>} or100 * {Array{<OpenLayers.Feature.Vector>}} A feature or an101 * array of features to add to the store.102 * config - a config object which can include the properties103 * "append" and "filter", if set these properties will104 * override that set in the object.105 */106 addFeatures: function(features, config) {107 if (!Ext.isArray(features)) {108 features = [features];109 }110 config = OpenLayers.Util.applyDefaults(config,111 {append: this.append, filter: this.filter});112 var toAdd = features;113 if (config.filter) {114 toAdd = [];115 var feature;116 for (var i = 0, len = features.length; i < len; i++) {117 feature = features[i];118 if (config.filter(feature)) {119 toAdd.push(feature);120 }121 }122 }123 // because of a bug in Ext if config.append is false we clean124 // the store ourself and always pass true to loadData, there125 // are cases where passing false to loadData results in Ext126 // trying to dereference an undefined value, see the unit127 // tests test_ExtBug and text_addFeatures_ExtBug for128 // concrete examples129 if (!config.append) {130 this.store.removeAll();131 }132 this.store.loadData(toAdd, true);133 },134 135 /**136 * APIMethod: removeFeatures137 * Remove features from the store.138 *139 * Parameters:140 * features - {<OpenLayers.Feature.Vector>} or141 * {Array{<OpenLayers.Feature.Vector>}} A feature or an142 * array of features to remove from the store. If null143 * all the features in the store are removed.144 */145 removeFeatures: function(features) {146 if (!features) {147 this.store.removeAll();148 } else {149 if (!Ext.isArray(features)) {150 features = [features];151 }152 for (var i = 0, len = features.length; i < len; i++) {153 var feature = features[i];154 var r = this.store.getById(feature.id);155 if (r !== undefined) {156 this.store.remove(r);157 }158 }159 }160 }161 }; -
lib/GeoExt/data/LayerStoreMediator.js
old new 1 /*2 * Copyright (C) 2008 Eric Lemoine, Camptocamp France SAS3 *4 * This file is part of GeoExt5 *6 * GeoExt is free software: you can redistribute it and/or modify7 * it under the terms of the GNU General Public License as published by8 * the Free Software Foundation, either version 3 of the License, or9 * (at your option) any later version.10 *11 * GeoExt is distributed in the hope that it will be useful,12 * but WITHOUT ANY WARRANTY; without even the implied warranty of13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14 * GNU General Public License for more details.15 *16 * You should have received a copy of the GNU General Public License17 * along with GeoExt. If not, see <http://www.gnu.org/licenses/>.18 */19 20 /**21 * @requires GeoExt/data/FeatureStoreMediator.js22 */23 24 Ext.namespace('GeoExt', 'GeoExt.data');25 26 /**27 * Class: GeoExt.data.LayerStoreMediator28 *29 * This class is to be used when one wants to insert, remove, and30 * update features in a grid as a result of features being inserted,31 * removed, modified in a vector layer.32 *33 * Usage example:34 * (start code)35 * var layer = new OpenLayers.Layer.Vector("vector");36 * var store = new Ext.data.Store({37 * reader: new GeoExt.data.FeatureReader(38 * {}, [{name: "name", type: "string"}]39 * )40 * });41 * var mediator = new GeoExt.data.LayerStoreMediator({42 * store: store,43 * filter: function(feature) {44 * return feature.state != OpenLayers.State.UNKNOWN;45 * }46 * });47 * (end)48 */49 50 /**51 * Constructor: GeoExt.data.LayerStoreMediator52 * Create an instance of GeoExt.data.LayerStoreMediator.53 *54 * Parameters:55 * config - {Object} A config object used to set the layer56 * store mediator's properties (see below for the list57 * of supported properties), and configure it with the58 * Ext store; see the usage example above.59 *60 * Returns:61 * {<GeoExt.data.LayerStoreMediator>}62 */63 GeoExt.data.LayerStoreMediator = function(config) {64 var store = config.store;65 // no need to place the store in the instance66 delete config.store;67 Ext.apply(this, config);68 if (!this.layer) {69 OpenLayers.Console.error(70 "layer is missing in config");71 }72 this.featureStoreMediator = new GeoExt.data.FeatureStoreMediator({73 store: store74 });75 if (this.autoActivate) {76 this.activate();77 }78 };79 80 GeoExt.data.LayerStoreMediator.prototype = {81 /**82 * APIProperty: layer83 * {<OpenLayers.Layer.Vector>} The vector layer.84 */85 layer: null,86 87 /**88 * APIProperty: filter89 * {Function} a filter function called for each feature to be90 * inserted, the feature is passed as an argument to the function,91 * if it returns true the feature is inserted into the store,92 * otherwise the feature is not inserted.93 */94 filter: null,95 96 /**97 * APIProperty: autoActivate98 * {Boolean} True if the mediator must be activated as part of99 * its creation, false otherwise; if false then the mediator must100 * be explicitely activate using the activate method; defaults101 * to true.102 */103 autoActivate: true,104 105 /**106 * Property: active107 * {Boolean}108 */109 active: false,110 111 /**112 * Property: featureStoreMediator113 * {<GeoExt.data.featureStoreMediator>} An internal114 * feature store mediator for manually adding features to the115 * Ext store.116 */117 featureStoreMediator: null,118 119 /**120 * APIMethod: activate121 * Activate the mediator.122 *123 * Returns:124 * {Boolean} - False if the mediator was already active, true125 * otherwise.126 */127 activate: function() {128 if (!this.active) {129 this.layer.events.on({130 featuresadded: this.update,131 featuresremoved: this.update,132 featuremodified: this.update,133 scope: this134 });135 this.active = true;136 return true;137 }138 return false;139 },140 141 /**142 * APIMethod: deactivate143 * Deactivate the mediator.144 *145 * Returns:146 * {Boolean} - False if the mediator was already deactive, true147 * otherwise.148 */149 deactivate: function() {150 if (this.active) {151 this.layer.events.un({152 featuresadded: this.update,153 featuresremoved: this.update,154 featuremodified: this.update,155 scope: this156 });157 return true;158 }159 return false;160 },161 162 /**163 * Method: update164 * Called when features are added, removed or modified. This165 * function empties the store, loops over the features in166 * the layer, and for each feature calls the user-defined167 * filter function, if the return value of the filter function168 * evaluates to true the feature is added to the store.169 */170 update: function() {171 this.featureStoreMediator.addFeatures(172 this.layer.features,173 {append: false, filter: this.filter});174 }175 };