diff --git a/lib/OpenLayers/Strategy/BBOX.js b/lib/OpenLayers/Strategy/BBOX.js index a513a34ddf..53b171a83f 100644 --- a/lib/OpenLayers/Strategy/BBOX.js +++ b/lib/OpenLayers/Strategy/BBOX.js @@ -24,6 +24,12 @@ OpenLayers.Strategy.BBOX = OpenLayers.Class(OpenLayers.Strategy, { */ bounds: null, + /** + * Property: resolution + * {Float} The current data resolution. + */ + resolution: null, + /** * APIProperty: ratio * {Float} The ratio of the data bounds to the viewport bounds (in each @@ -31,6 +37,21 @@ OpenLayers.Strategy.BBOX = OpenLayers.Class(OpenLayers.Strategy, { */ ratio: 2, + /** + * Property: resFactor + * {Float} Optional factor used to determine when previously requested + * features are invalid. If set, the resFactor will be compared to the + * resolution of the previous request to the current map resolution. + * If resFactor > (old / new) and 1/resFactor < (old / new). If you + * set a resFactor of 1, data will be requested every time the + * resolution changes. If you set a resFactor of 3, data will be + * requested if the old resolution is 3 times the new, or if the new is + * 3 times the old. If the old bounds do not contain the new bounds + * new data will always be requested (with or without considering + * resFactor). + */ + resFactor: null, + /** * Property: response * {} The protocol response object returned @@ -107,6 +128,7 @@ OpenLayers.Strategy.BBOX = OpenLayers.Class(OpenLayers.Strategy, { var mapBounds = this.getMapBounds(); if ((options && options.force) || this.invalidBounds(mapBounds)) { this.calculateBounds(mapBounds); + this.resolution = this.layer.map.getResolution(); this.triggerRead(); } }, @@ -130,6 +152,10 @@ OpenLayers.Strategy.BBOX = OpenLayers.Class(OpenLayers.Strategy, { /** * Method: invalidBounds + * Determine whether the previously requested set of features is invalid. + * This occurs when the new map bounds do not contain the previously + * requested bounds. In addition, if is set, it will be + * considered. * * Parameters: * mapBounds - {} the current map extent, will be @@ -142,7 +168,12 @@ OpenLayers.Strategy.BBOX = OpenLayers.Class(OpenLayers.Strategy, { if(!mapBounds) { mapBounds = this.getMapBounds(); } - return !this.bounds || !this.bounds.containsBounds(mapBounds); + var invalid = !this.bounds || !this.bounds.containsBounds(mapBounds); + if(!invalid && this.resFactor) { + var ratio = this.resolution / this.layer.map.getResolution(); + invalid = (ratio >= this.resFactor || ratio <= (1 / this.resFactor)); + } + return invalid; }, /** diff --git a/tests/Strategy/BBOX.html b/tests/Strategy/BBOX.html index 6352d8bee6..f03dd6523f 100644 --- a/tests/Strategy/BBOX.html +++ b/tests/Strategy/BBOX.html @@ -165,6 +165,33 @@ map.destroy(); } + + function test_resFactor(t) { + t.plan(2); + + var map = new OpenLayers.Map("map"); + var bbox = new OpenLayers.Strategy.BBOX(); + var fakeProtocol = new OpenLayers.Protocol({ + 'read': function() { + t.ok(true, "read called once without resfactor"); + } + }); + var layer = new OpenLayers.Layer.Vector("test", { + strategies: [bbox], + protocol: fakeProtocol, + isBaseLayer: true + }); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0, 0), 0); + map.zoomIn(); + + fakeProtocol.read = function() { + t.ok("read called again on zooming with resFactor: 1"); + } + bbox.resFactor = 1; + map.zoomIn(); + + } function test_createFilter(t) { t.plan(3);