source: ether_iasi/trunk/web/resources/js/OpenLayers-2.12/lib/OpenLayers/Strategy/BBOX.js @ 738

Last change on this file since 738 was 738, checked in by vmipsl, 11 years ago

OpenLayers?

File size: 9.2 KB
Line 
1/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
2 * full list of contributors). Published under the 2-clause BSD license.
3 * See license.txt in the OpenLayers distribution or repository for the
4 * full text of the license. */
5
6/**
7 * @requires OpenLayers/Strategy.js
8 * @requires OpenLayers/Filter/Spatial.js
9 */
10
11/**
12 * Class: OpenLayers.Strategy.BBOX
13 * A simple strategy that reads new features when the viewport invalidates
14 *     some bounds.
15 *
16 * Inherits from:
17 *  - <OpenLayers.Strategy>
18 */
19OpenLayers.Strategy.BBOX = OpenLayers.Class(OpenLayers.Strategy, {
20   
21    /**
22     * Property: bounds
23     * {<OpenLayers.Bounds>} The current data bounds (in the same projection
24     *     as the layer - not always the same projection as the map).
25     */
26    bounds: null,
27   
28    /**
29     * Property: resolution
30     * {Float} The current data resolution.
31     */ 
32    resolution: null, 
33           
34    /**
35     * APIProperty: ratio
36     * {Float} The ratio of the data bounds to the viewport bounds (in each
37     *     dimension).  Default is 2.
38     */
39    ratio: 2,
40
41    /**
42     * Property: resFactor
43     * {Float} Optional factor used to determine when previously requested
44     *     features are invalid.  If set, the resFactor will be compared to the
45     *     resolution of the previous request to the current map resolution.
46     *     If resFactor > (old / new) and 1/resFactor < (old / new).  If you
47     *     set a resFactor of 1, data will be requested every time the
48     *     resolution changes.  If you set a resFactor of 3, data will be
49     *     requested if the old resolution is 3 times the new, or if the new is
50     *     3 times the old.  If the old bounds do not contain the new bounds
51     *     new data will always be requested (with or without considering
52     *     resFactor).
53     */ 
54    resFactor: null, 
55   
56    /**
57     * Property: response
58     * {<OpenLayers.Protocol.Response>} The protocol response object returned
59     *      by the layer protocol.
60     */
61    response: null,
62
63    /**
64     * Constructor: OpenLayers.Strategy.BBOX
65     * Create a new BBOX strategy.
66     *
67     * Parameters:
68     * options - {Object} Optional object whose properties will be set on the
69     *     instance.
70     */
71   
72    /**
73     * Method: activate
74     * Set up strategy with regard to reading new batches of remote data.
75     *
76     * Returns:
77     * {Boolean} The strategy was successfully activated.
78     */
79    activate: function() {
80        var activated = OpenLayers.Strategy.prototype.activate.call(this);
81        if(activated) {
82            this.layer.events.on({
83                "moveend": this.update,
84                "refresh": this.update,
85                "visibilitychanged": this.update,
86                scope: this
87            });
88            this.update();
89        }
90        return activated;
91    },
92   
93    /**
94     * Method: deactivate
95     * Tear down strategy with regard to reading new batches of remote data.
96     *
97     * Returns:
98     * {Boolean} The strategy was successfully deactivated.
99     */
100    deactivate: function() {
101        var deactivated = OpenLayers.Strategy.prototype.deactivate.call(this);
102        if(deactivated) {
103            this.layer.events.un({
104                "moveend": this.update,
105                "refresh": this.update,
106                "visibilitychanged": this.update,
107                scope: this
108            });
109        }
110        return deactivated;
111    },
112
113    /**
114     * Method: update
115     * Callback function called on "moveend" or "refresh" layer events.
116     *
117     * Parameters:
118     * options - {Object} Optional object whose properties will determine
119     *     the behaviour of this Strategy
120     *
121     * Valid options include:
122     * force - {Boolean} if true, new data must be unconditionally read.
123     * noAbort - {Boolean} if true, do not abort previous requests.
124     */
125    update: function(options) {
126        var mapBounds = this.getMapBounds();
127        if (mapBounds !== null && ((options && options.force) ||
128          (this.layer.visibility && this.layer.calculateInRange() && this.invalidBounds(mapBounds)))) {
129            this.calculateBounds(mapBounds);
130            this.resolution = this.layer.map.getResolution(); 
131            this.triggerRead(options);
132        }
133    },
134   
135    /**
136     * Method: getMapBounds
137     * Get the map bounds expressed in the same projection as this layer.
138     *
139     * Returns:
140     * {<OpenLayers.Bounds>} Map bounds in the projection of the layer.
141     */
142    getMapBounds: function() {
143        if (this.layer.map === null) {
144            return null;
145        }
146        var bounds = this.layer.map.getExtent();
147        if(bounds && !this.layer.projection.equals(
148                this.layer.map.getProjectionObject())) {
149            bounds = bounds.clone().transform(
150                this.layer.map.getProjectionObject(), this.layer.projection
151            );
152        }
153        return bounds;
154    },
155
156    /**
157     * Method: invalidBounds
158     * Determine whether the previously requested set of features is invalid.
159     *     This occurs when the new map bounds do not contain the previously
160     *     requested bounds.  In addition, if <resFactor> is set, it will be
161     *     considered.
162     *
163     * Parameters:
164     * mapBounds - {<OpenLayers.Bounds>} the current map extent, will be
165     *      retrieved from the map object if not provided
166     *
167     * Returns:
168     * {Boolean}
169     */
170    invalidBounds: function(mapBounds) {
171        if(!mapBounds) {
172            mapBounds = this.getMapBounds();
173        }
174        var invalid = !this.bounds || !this.bounds.containsBounds(mapBounds);
175        if(!invalid && this.resFactor) {
176            var ratio = this.resolution / this.layer.map.getResolution();
177            invalid = (ratio >= this.resFactor || ratio <= (1 / this.resFactor));
178        }
179        return invalid;
180    },
181 
182    /**
183     * Method: calculateBounds
184     *
185     * Parameters:
186     * mapBounds - {<OpenLayers.Bounds>} the current map extent, will be
187     *      retrieved from the map object if not provided
188     */
189    calculateBounds: function(mapBounds) {
190        if(!mapBounds) {
191            mapBounds = this.getMapBounds();
192        }
193        var center = mapBounds.getCenterLonLat();
194        var dataWidth = mapBounds.getWidth() * this.ratio;
195        var dataHeight = mapBounds.getHeight() * this.ratio;
196        this.bounds = new OpenLayers.Bounds(
197            center.lon - (dataWidth / 2),
198            center.lat - (dataHeight / 2),
199            center.lon + (dataWidth / 2),
200            center.lat + (dataHeight / 2)
201        );
202    },
203   
204    /**
205     * Method: triggerRead
206     *
207     * Parameters:
208     * options - {Object} Additional options for the protocol's read method
209     *     (optional)
210     *
211     * Returns:
212     * {<OpenLayers.Protocol.Response>} The protocol response object
213     *      returned by the layer protocol.
214     */
215    triggerRead: function(options) {
216        if (this.response && !(options && options.noAbort === true)) {
217            this.layer.protocol.abort(this.response);
218            this.layer.events.triggerEvent("loadend");
219        }
220        this.layer.events.triggerEvent("loadstart");
221        this.response = this.layer.protocol.read(
222            OpenLayers.Util.applyDefaults({
223                filter: this.createFilter(),
224                callback: this.merge,
225                scope: this
226        }, options));
227    },
228 
229    /**
230     * Method: createFilter
231     * Creates a spatial BBOX filter. If the layer that this strategy belongs
232     * to has a filter property, this filter will be combined with the BBOX
233     * filter.
234     *
235     * Returns
236     * {<OpenLayers.Filter>} The filter object.
237     */
238    createFilter: function() {
239        var filter = new OpenLayers.Filter.Spatial({
240            type: OpenLayers.Filter.Spatial.BBOX,
241            value: this.bounds,
242            projection: this.layer.projection
243        });
244        if (this.layer.filter) {
245            filter = new OpenLayers.Filter.Logical({
246                type: OpenLayers.Filter.Logical.AND,
247                filters: [this.layer.filter, filter]
248            });
249        }
250        return filter;
251    },
252   
253    /**
254     * Method: merge
255     * Given a list of features, determine which ones to add to the layer.
256     *     If the layer projection differs from the map projection, features
257     *     will be transformed from the layer projection to the map projection.
258     *
259     * Parameters:
260     * resp - {<OpenLayers.Protocol.Response>} The response object passed
261     *      by the protocol.
262     */
263    merge: function(resp) {
264        this.layer.destroyFeatures();
265        var features = resp.features;
266        if(features && features.length > 0) {
267            var remote = this.layer.projection;
268            var local = this.layer.map.getProjectionObject();
269            if(!local.equals(remote)) {
270                var geom;
271                for(var i=0, len=features.length; i<len; ++i) {
272                    geom = features[i].geometry;
273                    if(geom) {
274                        geom.transform(remote, local);
275                    }
276                }
277            }
278            this.layer.addFeatures(features);
279        }
280        this.response = null;
281        this.layer.events.triggerEvent("loadend");
282    },
283   
284    CLASS_NAME: "OpenLayers.Strategy.BBOX" 
285});
Note: See TracBrowser for help on using the repository browser.