More trip planner testing with colors
[busui.git] / labs / openlayers / lib / OpenLayers / Strategy / Filter.js
blob:a/labs/openlayers/lib/OpenLayers/Strategy/Filter.js -> blob:b/labs/openlayers/lib/OpenLayers/Strategy/Filter.js
--- a/labs/openlayers/lib/OpenLayers/Strategy/Filter.js
+++ b/labs/openlayers/lib/OpenLayers/Strategy/Filter.js
@@ -1,1 +1,165 @@
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for 
+ * full list of contributors). Published under the Clear BSD license.  
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
 
+/**
+ * @requires OpenLayers/Strategy.js
+ * @requires OpenLayers/Filter.js
+ */
+
+/**
+ * Class: OpenLayers.Strategy.Filter
+ * Strategy for limiting features that get added to a layer by 
+ *     evaluating a filter.  The strategy maintains a cache of
+ *     all features until removeFeatures is called on the layer.
+ *
+ * Inherits from:
+ *  - <OpenLayers.Strategy>
+ */
+OpenLayers.Strategy.Filter = OpenLayers.Class(OpenLayers.Strategy, {
+    
+    /**
+     * APIProperty: filter
+     * {<OpenLayers.Filter>}  Filter for limiting features sent to the layer.
+     *     Use the <setFilter> method to update this filter after construction.
+     */
+    filter: null,
+    
+    /**
+     * Property: cache
+     * {Array(<OpenLayers.Feature.Vector>)} List of currently cached
+     *     features.
+     */
+    cache: null,
+    
+    /**
+     * Property: caching
+     * {Boolean} The filter is currently caching features.
+     */
+    caching: false,
+    
+    /**
+     * Constructor: OpenLayers.Strategy.Filter
+     * Create a new filter strategy.
+     *
+     * Parameters:
+     * options - {Object} Optional object whose properties will be set on the
+     *     instance.  Strategy must be constructed with at least a <filter> 
+     *     property.
+     */
+    initialize: function(options) {
+        OpenLayers.Strategy.prototype.initialize.apply(this, [options]);
+        if (!this.filter || !(this.filter instanceof OpenLayers.Filter)) {
+            throw new Error("Filter strategy must be constructed with a filter");
+        }
+    },
+
+    /**
+     * APIMethod: activate
+     * Activate the strategy.  Register any listeners, do appropriate setup.
+     *     By default, this strategy automatically activates itself when a layer
+     *     is added to a map.
+     *
+     * Returns:
+     * {Boolean} True if the strategy was successfully activated or false if
+     *      the strategy was already active.
+     */
+    activate: function() {
+        var activated = OpenLayers.Strategy.prototype.activate.apply(this, arguments);
+        if (activated) {
+            this.cache = [];
+            this.layer.events.on({
+                "beforefeaturesadded": this.handleAdd,
+                "beforefeaturesremoved": this.handleRemove,
+                scope: this
+            });
+        }
+        return activated;
+    },
+    
+    /**
+     * APIMethod: deactivate
+     * Deactivate the strategy.  Clear the feature cache.
+     *
+     * Returns:
+     * {Boolean} True if the strategy was successfully deactivated or false if
+     *      the strategy was already inactive.
+     */
+    deactivate: function() {
+        this.cache = null;
+        if (this.layer && this.layer.events) {
+            this.layer.events.un({
+                "beforefeaturesadded": this.handleAdd,
+                "beforefeaturesremoved": this.handleRemove,
+                scope: this
+            });            
+        }
+        return OpenLayers.Strategy.prototype.deactivate.apply(this, arguments);
+    },
+    
+    /**
+     * Method: handleAdd
+     */
+    handleAdd: function(event) {
+        if (!this.caching) {
+            var features = event.features;
+            event.features = [];
+            var feature;
+            for (var i=0, ii=features.length; i<ii; ++i) {
+                feature = features[i];
+                if (this.filter.evaluate(feature)) {
+                    event.features.push(feature);
+                } else {
+                    this.cache.push(feature);
+                }
+            }
+        }
+    },
+    
+    /**
+     * Method: handleRemove
+     */
+    handleRemove: function(event) {
+        if (!this.caching) {
+            this.cache = [];
+        }
+    },
+
+    /** 
+     * APIMethod: setFilter
+     * Update the filter for this strategy.  This will re-evaluate
+     *     any features on the layer and in the cache.  Only features
+     *     for which filter.evalute(feature) returns true will be
+     *     added to the layer.  Others will be cached by the strategy.
+     *
+     * Parameters:
+     * filter - <OpenLayers.Filter> A filter for evaluating features.
+     */
+    setFilter: function(filter) {
+        this.filter = filter;
+        var previousCache = this.cache;
+        this.cache = [];
+        // look through layer for features to remove from layer
+        this.handleAdd({features: this.layer.features});
+        // cache now contains features to remove from layer
+        if (this.cache.length > 0) {
+            this.caching = true;
+            this.layer.removeFeatures(this.cache.slice(), {silent: true});
+            this.caching = false;
+        }
+        // now look through previous cache for features to add to layer
+        if (previousCache.length > 0) {
+            var event = {features: previousCache};
+            this.handleAdd(event);
+            // event has features to add to layer
+            this.caching = true;
+            this.layer.addFeatures(event.features, {silent: true});
+            this.caching = false;
+        }
+    },
+
+    CLASS_NAME: "OpenLayers.Strategy.Filter"
+
+});
+