Ticket #18: patch-18-r371-D1.diff
| File patch-18-r371-D1.diff, 48.7 kB (added by elemoine, 1 year ago) |
|---|
-
geoext/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 -
geoext/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> -
geoext/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> -
geoext/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(5); 32 33 var layer = new OpenLayers.Layer.Vector("Foo layer"); 34 var store = new GeoExt.data.FeatureStore({ 35 layer: layer 36 }); 37 38 // loadData 39 store.loadData([ 40 new OpenLayers.Feature.Vector(), 41 new OpenLayers.Feature.Vector() 42 ]); 43 t.eq(layer.features.length, 2, "loading two records in the store with 'loadData' adds two features to the layer"); 44 t.eq(store.getCount(), 2, 'loading two records in the store with "loadData" does not create duplicate records in store'); 45 46 // loadData with recordFilter 47 store.recordFilter = function(record) { return false; }; 48 store.loadData([ 49 new OpenLayers.Feature.Vector(), 50 new OpenLayers.Feature.Vector() 51 ]); 52 t.eq(layer.features.length, 0, 53 "loading two records in the store with 'loadData' adds no feature to the layer if recordFilter returns false"); 54 55 // removeAll 56 store.removeAll(); 57 t.eq(store.getCount(), 0, '"removeAll" on store removes all records from the store'); 58 t.eq(layer.features.length, 0, '"removeAll" on store removes features from layer'); 59 } 60 61 function test_bind_unbind(t) { 62 t.plan(28); 63 64 var layer = new OpenLayers.Layer.Vector("Foo layer"); 65 var store = new GeoExt.data.FeatureStore(); 66 var features = [new OpenLayers.Feature.Vector("Foo feature"), 67 new OpenLayers.Feature.Vector("Bar feature")]; 68 var records = [ 69 new GeoExt.data.FeatureRecord({ 70 feature: new OpenLayers.Feature.Vector("Foo record")}), 71 new GeoExt.data.FeatureRecord({ 72 feature: new OpenLayers.Feature.Vector("Bar record")}) 73 ]; 74 75 var reinit_test_data = function () { 76 // unbind store 77 store.unbind(); 78 79 // remove all existing records and features 80 store.removeAll(); 81 layer.removeFeatures(layer.features); 82 t.eq(layer.features.length, 0, "there is no more features in the layer"); 83 t.eq(store.getCount(), 0, "there is no more records in the store"); 84 85 // add testing data to store and layer 86 store.add(records); 87 layer.addFeatures(features); 88 t.eq(layer.features.length, 2, "initial features are loaded in the layer"); 89 t.eq(store.getCount(), 2, "initial records are loaded in the store"); 90 }; 91 92 // test store to layer synchronization 93 reinit_test_data(); 94 store.bind(layer, {initDir: GeoExt.data.FeatureStore.STORE_TO_LAYER}); 95 t.eq(layer.features.length, 4, "initial records are synchronized to layer"); 96 t.eq(store.getCount(), 2, "initial features are not synchronized to store"); 97 layer.removeFeatures([features[0]]); 98 t.eq(layer.features.length, 3, "removing feature not present in store has been well removed"); 99 t.eq(store.getCount(), 2, "nothing to remove in store when removing feature not present in store"); 100 101 // test layer to store synchronization 102 reinit_test_data(); 103 store.bind(layer, {initDir: GeoExt.data.FeatureStore.LAYER_TO_STORE}); 104 t.eq(layer.features.length, 2, "initial records are not synchronized to layer"); 105 t.eq(store.getCount(), 4, "initial features are synchronized to store"); 106 store.remove(records[0]); 107 t.eq(store.getCount(), 3, "removing record not present in layer has been well removed"); 108 t.eq(layer.features.length, 2, "nothing to remove in layer when removing record not present in layer"); 109 110 // test both synchronization 111 reinit_test_data(); 112 store.bind(layer, {initDir: GeoExt.data.FeatureStore.LAYER_TO_STORE | 113 GeoExt.data.FeatureStore.STORE_TO_LAYER}); 114 t.eq(layer.features.length, 4, "initial records are synchronized to layer"); 115 t.eq(store.getCount(), 4, "initial features are synchronized to store"); 116 117 // test no synchronization 118 reinit_test_data(); 119 store.bind(layer, {initDir: 0}); 120 t.eq(layer.features.length, 2, "initial records are not synchronized to layer"); 121 t.eq(store.getCount(), 2, "initial features are not synchronized to store"); 122 } 123 124 function test_add_remove(t) { 125 126 t.plan(5); 127 128 var layer = new OpenLayers.Layer.Vector("Foo layer"); 129 var store = new GeoExt.data.FeatureStore({ 130 layer: layer 131 }); 132 var record = new GeoExt.data.FeatureRecord({ 133 feature: new OpenLayers.Feature.Vector() 134 }); 135 136 // add 137 store.add([record]); 138 t.eq(store.getCount(), 1, 'Adding a record to store with "add" does not create duplicate record in store'); 139 t.eq(layer.features.length, 1, 'Adding a record to store with "add" does create corresponding feature in layer'); 140 141 // remove 142 store.remove(record); 143 t.eq(store.getCount(), 0, 'remove on store with "remove" removes the record from the store'); 144 t.eq(layer.features.length, 0, 'remove on store with "remove" removes the corresponding feature from layer'); 145 146 // add with recordFilter 147 store.recordFilter = function(record) { return false; }; 148 store.add([record]); 149 t.eq(layer.features.length, 0, 150 'Adding a record with "add" does not add feature to layer if recordFilter returns false'); 151 } 152 153 function test_addFeatures_removeFeatures(t) { 154 155 t.plan(5); 156 157 var features = [ 158 new OpenLayers.Feature.Vector(), 159 new OpenLayers.Feature.Vector() 160 ]; 161 var layer = new OpenLayers.Layer.Vector("Foo layer"); 162 var store = new GeoExt.data.FeatureStore({ 163 layer: layer 164 }); 165 166 // test layer addFeatures 167 layer.addFeatures(features); 168 t.eq(layer.features.length, 2, 'Adding features to layer with "addFeatures" does not create duplicate features on the layer'); 169 t.eq(store.getCount(), 2, 'Adding features to layer with "addFeatures" does create corresponding records in the store'); 170 171 // test layer removeFeatures 172 layer.removeFeatures(layer.features); 173 t.eq(store.getCount(), 0, '"removeFeatures" on layer removes records from the store'); 174 t.eq(layer.features.length, 0, '"removeFeatures" on layer removes features from layer'); 175 176 // test layer addFeatures with featureFilter 177 store.featureFilter = function(feature) { return false; }; 178 layer.addFeatures(features); 179 t.eq(store.getCount(), 0, 180 'Adding features to layer with "addFeatures" does not insert records in the store if featureFilter returns false'); 181 } 182 183 function test_featuremodified_update(t) { 184 t.plan(6); 185 186 /* 187 * Set up 188 */ 189 var feature, id, layer, store, recordType, record; 190 191 feature = new OpenLayers.Feature.Vector(null, { 192 foo: "foo", 193 bar: "bar" 194 }); 195 196 id = feature.id; 197 198 recordType = GeoExt.data.FeatureRecord.create([ 199 {name: "foo"}, {name: "bar"} 200 ]); 201 202 layer = new OpenLayers.Layer.Vector("vector"); 203 204 store = new GeoExt.data.FeatureStore({ 205 layer: layer, 206 recordType: recordType, 207 data: [feature] 208 }); 209 210 t.eq(store.getById(id).get("foo"), "foo", 211 "record gets correct initial value for property \"foo\""); 212 213 t.eq(store.getById(id).get("bar"), "bar", 214 "record gets correct initial value for property \"bar\""); 215 216 /* 217 * Test 218 */ 219 220 // featuremodified 221 feature.attributes.foo = "foo2"; 222 feature.attributes.bar = "bar2"; 223 layer.events.triggerEvent("featuremodified", {feature: feature}); 224 225 t.eq(store.getById(id).get("foo"), "foo2", 226 "featuremodified event causes update of record property \"foo\""); 227 228 t.eq(store.getById(id).get("bar"), "bar2", 229 "featuremodified event causes update of record property \"bar\""); 230 231 // update 232 record = store.getById(id); 233 record.set("foo", "foo3"); 234 record.set("bar", "bar3"); 235 236 t.eq(layer.getFeatureById(id).attributes.foo, "foo3", 237 "update event causes update of feature property \"foo\""); 238 239 t.eq(layer.getFeatureById(id).attributes.bar, "bar3", 240 "update event causes update of feature property \"bar\""); 241 242 } 243 </script> 244 245 <body> 246 <div id="map"></div> 247 </body> 248 </html> 249 -
geoext/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> -
geoext/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" -
geoext/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 * APIProperty: featureFilter 55 * {Function} This function is called before a feature record is added to 56 * the store, it receives the feature from which a feature record is 57 * to be created, if it returns false then no record is added. 58 */ 59 featureFilter: function(feature) {}, 60 61 /** 62 * APIProperty: recordFilter 63 * {Function} This function is called before a feature is added to the 64 * layer, it receives the feature record associated with the feature 65 * to be added, if it returns false then no feature is added. 66 */ 67 recordFilter: function(record) {}, 68 69 /** 70 * Constructor: GeoExt.data.FeatureStoreMixin 71 * 72 * Parameters: 73 * config - {Object} 74 * 75 * Valid config options: 76 * layer - {OpenLayers.Layer.Vector} layer to sync the feature store with. 77 * features - {Array(OpenLayers.Feature.Vector)} Features that will be added to the 78 * feature store (and the layer, because we are already syncing). 79 * recordType - {<GeoExt.data.FeatureRecord>} If provided, a custom feature 80 * record type with additional fields will be used. Default fields for 81 * every feature record are {OpenLayers.Feature.Vector} feature and {String} title. 82 * initDir - {Number} Bitfields specifying the direction to use for the 83 * initial sync between the layer and the store, if set to 0 then no 84 * initial sync is done. Defaults to 85 * <GeoExt.data.FeatureStore.LAYER_TO_STORE>|<GeoExt.data.FeatureStore.STORE_TO_LAYER>. 86 */ 87 constructor: function(config) { 88 config = config || {}; 89 config.reader = config.reader || 90 new GeoExt.data.FeatureReader({}, config.recordType); 91 var layer = config.layer; 92 delete config.layer; 93 // 'features' option - is an alias 'data' option 94 if (config.features) { 95 config.data = config.features; 96 } 97 delete config.features; 98 // "initDir" option 99 var options = {initDir: config.initDir}; 100 delete config.initDir; 101 arguments.callee.superclass.constructor.call(this, config); 102 if(layer) { 103 this.bind(layer, options); 104 } 105 }, 106 107 /** 108 * APIMethod: bind 109 * Bind this store to a layer instance, once bound the store 110 * is synchronized with the layer and vice-versa. 111 * 112 * Parameters: 113 * layer - {OpenLayers.Layer.Vector} The layer instance. 114 * options - {Object} 115 * 116 * Valid config options: 117 * initDir - {Number} Bitfields specifying the direction to use for the 118 * initial sync between the layer and the store, if set to 0 then no 119 * initial sync is done. Defaults to 120 * <GeoExt.data.FeatureStore.LAYER_TO_STORE>|<GeoExt.data.FeatureStore.STORE_TO_LAYER>. 121 */ 122 bind: function(layer, options) { 123 if(this.layer) { 124 // already bound 125 return; 126 } 127 this.layer = layer; 128 options = options || {}; 129 130 var initDir = options.initDir; 131 if(options.initDir == undefined) { 132 initDir = GeoExt.data.FeatureStore.LAYER_TO_STORE | 133 GeoExt.data.FeatureStore.STORE_TO_LAYER; 134 } 135 136 // create a snapshot of the layer's features 137 var features = layer.features.slice(0); 138 139 if(initDir & GeoExt.data.FeatureStore.STORE_TO_LAYER) { 140 var records = this.getRange(); 141 for(var i=records.length - 1; i>=0; i--) { 142 this.layer.addFeatures([records[i].get("feature")]); 143 } 144 } 145 146 if(initDir & GeoExt.data.FeatureStore.LAYER_TO_STORE) { 147 this.loadData(features, true /* append */); 148 } 149 150 layer.events.on({ 151 "featuresadded": this.onFeaturesAdded, 152 "featuresremoved": this.onFeaturesRemoved, 153 "featuremodified": this.onFeatureModified, 154 scope: this 155 }); 156 this.on({ 157 "load": this.onLoad, 158 "clear": this.onClear, 159 "add": this.onAdd, 160 "remove": this.onRemove, 161 "update": this.onUpdate, 162 scope: this 163 }); 164 }, 165 166 /** 167 * APIMethod: unbind 168 * Unbind this store from the layer it is currently bound. 169 */ 170 unbind: function() { 171 if(this.layer) { 172 this.layer.events.un({ 173 "featuresadded": this.onFeaturesAdded, 174 "featuresremoved": this.onFeaturesRemoved, 175 "featuremodified": this.onFeatureModified, 176 scope: this 177 }); 178 this.un("load", this.onLoad, this); 179 this.un("clear", this.onClear, this); 180 this.un("add", this.onAdd, this); 181 this.un("remove", this.onRemove, this); 182 this.un("update", this.onUpdate, this); 183 184 this.layer = null; 185 } 186 }, 187 188 189 /** 190 * Method: onFeaturesAdded 191 * Handler for layer featuresadded event 192 * 193 * Parameters: 194 * evt - {Object} 195 */ 196 onFeaturesAdded: function(evt) { 197 if(!this._adding) { 198 var i, len, feature, features = evt.features, toAdd = []; 199 for(var i=0, len=features.length; i<len; i++) { 200 feature = features[i]; 201 if(this.featureFilter(feature) !== false) { 202 toAdd.push(feature); 203 } 204 } 205 // add feature records to the store, when called with 206 // append true loadData triggers an "add" event and 207 // then a "load" event 208 this._adding = true; 209 this.loadData(toAdd, true /* append */); 210 delete this._adding; 211 } 212 }, 213 214 /** 215 * Method: onFeaturesRemoved 216 * Handler for layer featuresremoved event 217 * 218 * Parameters: 219 * evt - {Object} 220 */ 221 onFeaturesRemoved: function(evt){ 222 if(!this._removing) { 223 var features = evt.features, feature, record, i; 224 for(i=features.length - 1; i>=0; i--) { 225 feature = features[i]; 226 record = this.getById(feature.id); 227 if(record !== undefined) { 228 this._removing = true; 229 this.remove(record); 230 delete this._removing; 231 } 232 } 233 } 234 }, 235 236 /** 237 * Method: onFeatureModified 238 * Handler for layer featuremodified event 239 * 240 * Parameters: 241 * evt - {Object} 242 */ 243 onFeatureModified: function(evt) { 244 if(!this._updating) { 245 var feature = evt.feature; 246 var record = this.getById(feature.id); 247 if(record !== undefined) { 248 record.beginEdit(); 249 attributes = feature.attributes; 250 if(attributes) { 251 var fields = this.recordType.prototype.fields; 252 for(var i=0, len=fields.length; i<len; i++) { 253 var field = fields.items[i]; 254 var v = attributes[field.mapping || field.name] || 255 field.defaultValue; 256 v = field.convert(v); 257 record.set(field.name, v); 258 } 259 } 260 // the calls to set below won't trigger "update" 261 // events because we called beginEdit to start a 262 // "transaction", "update" will be triggered by 263 // endEdit 264 record.set("state", feature.state); 265 record.set("fid", feature.fid); 266 record.set("feature", feature); 267 this._updating = true; 268 record.endEdit(); 269 delete this._updating; 270 } 271 } 272 }, 273 274 /** 275 * Method: onLoad 276 * Handler for store load event 277 * 278 * Parameters: 279 * store - {Ext.data.Store} 280 * records - {Array(Ext.data.Record)} 281 * options - {Object} 282 */ 283 onLoad: function(store, records, options) { 284 // if options.add is true an "add" event was already 285 // triggered, and onAdd already did the work of 286 // adding the features to the layer. 287 if(!options || options.add !== true) { 288 this._removing = true; 289 this.layer.removeFeatures(this.layer.features); 290 delete this._removing; 291 var i, len, record, features = []; 292 for(i=0, len=records.length; i<len; i++) { 293 record = records[i]; 294 if(this.recordFilter(record) !== false) { 295 features.push(record.get("feature")); 296 } 297 } 298 if(features.length > 0) { 299 this._adding = true; 300 this.layer.addFeatures(features); 301 delete this._adding; 302 } 303 } 304 }, 305 306 /** 307 * Method: onClear 308 * Handler for store clear event 309 * 310 * Parameters: 311 * store - {Ext.data.Store} 312 */ 313 onClear: function(store) { 314 this._removing = true; 315 this.layer.removeFeatures(this.layer.features); 316 delete this._removing; 317 }, 318 319 /** 320 * Method: onAdd 321 * Handler for store add event 322 * 323 * Parameters: 324 * store - {Ext.data.Store} 325 * records - {Array(Ext.data.Record)} 326 * index - {Number} 327 */ 328 onAdd: function(store, records, index) { 329 if(!this._adding) { 330 var i, len, record, features = []; 331 for(i=0, len=records.length; i<len; i++) { 332 record = records[i]; 333 if(this.recordFilter(record) !== false) { 334 features.push(record.get("feature")); 335 } 336 } 337 if(features.length > 0) { 338 this._adding = true; 339 this.layer.addFeatures(features); 340 delete this._adding; 341 } 342 } 343 }, 344 345 /** 346 * Method: onRemove 347 * Handler for store remove event 348 * 349 * Parameters: 350 * store - {Ext.data.Store} 351 * records - {Array(Ext.data.Record)} 352 * index - {Number} 353 */ 354 onRemove: function(store, record, index){ 355 if(!this._removing) { 356 var feature = record.get("feature"); 357 if (this.layer.getFeatureById(feature.id) != null) { 358 this._removing = true; 359 this.layer.removeFeatures([record.get("feature")]); 360 delete this._removing; 361 } 362 } 363 }, 364 365 /** 366 * Method: onUpdate 367 * Handler for store update event 368 * 369 * Parameters: 370 * store - {Ext.data.Store} 371 * record - (Ext.data.Record)} 372 * operation - {String} 373 */ 374 onUpdate: function(store, record, operation) { 375 if(!this._updating) { 376 var feature = record.get("feature"); 377 if(record.fields) { 378 var cont = this.layer.events.triggerEvent( 379 "beforefeaturemodified", {feature: feature} 380 ); 381 if(cont !== false) { 382 record.fields.each( 383 function(field) { 384 feature.attributes[field.mapping || field.name] = 385 record.get(field.name); 386 } 387 ); 388 this._updating = true; 389 this.layer.events.triggerEvent( 390 "featuremodified", {feature: feature} 391 ); 392 delete this._updating; 393 if (this.layer.getFeatureById(feature.id) != null) { 394 this.layer.drawFeature(feature); 395 } 396 } 397 } 398 } 399 } 400 }; 401 402 /** 403 * Class: GeoExt.data.FeatureStore 404 * Default implementation of an {Ext.data.Store} extended with 405 * {<GeoExt.data.FeatureStoreMixin>} 406 * 407 * Inherits from: 408 * - {Ext.data.Store} 409 * - {<GeoExt.data.FeatureStoreMixin>} 410 */ 411 /** 412 * Constructor: GeoExt.data.FeatureStore 413 * 414 * Parameters: 415 * config - {Object} See {<GeoExt.data.FeatureStoreMixin>} and 416 * http://extjs.com/deploy/dev/docs/?class=Ext.data.Store for valid config 417 * options. 418 */ 419 GeoExt.data.FeatureStore = Ext.extend( 420 Ext.data.Store, 421 GeoExt.data.FeatureStoreMixin 422 ); 423 424 /** 425 * Constant: GeoExt.data.FeatureStore.LAYER_TO_STORE 426 * {Integer} Constant used to make the store be automatically updated 427 * when changes occur in the layer. 428 */ 429 GeoExt.data.FeatureStore.LAYER_TO_STORE = 1; 430 431 /** 432 * Constant: GeoExt.data.FeatureStore.STORE_TO_LAYER 433 * {Integer} Constant used to make the layer be automatically updated 434 * when changes occur in the store. 435 */ 436 GeoExt.data.FeatureStore.STORE_TO_LAYER = 2; -
geoext/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 }; -
geoext/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 };