Hi
I've written a patch that allows passing a filter to the
Handler.Feature constructor. This filter object is basically a
user-defined function. Each time a feature is to be selected, that
function is executed. If the function returns true the feature is
selected, otherwise it's not. This filter thing can be useful when one
wants to restrict feature modification to certain features, based on
some user-defined conditions.
See attached patch. Please comment...
Thanks,
--
Eric
Index: tests/Handler/test_Feature.html
===================================================================
--- tests/Handler/test_Feature.html (revision 5383)
+++ tests/Handler/test_Feature.html (working copy)
@@ -120,6 +120,42 @@
feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(0,0));
handler.select("foo", {});
}
+
+ function test_Handler_feature_filter(t) {
+ t.plan(5);
+ var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));
+ var map = new OpenLayers.Map('map');
+ var control = new OpenLayers.Control();
+ map.addControl(control);
+ var layer = new OpenLayers.Layer();
+ layer.getFeatureFromEvent = function(evt) { return feature };
+ map.addLayer(layer);
+ var filterArgs = ['foo', 'bar'];
+ var filterScope = {'foo':'foo', 'bar':'bar'};
+ var filter = function(f, arg0, arg1) {
+ t.eq(f.id, feature.id,
+ "Correct feature passed to filter func");
+ t.ok(arg0 == filterArgs[0] && arg1 == filterArgs[1],
+ "Correct args passed to filter");
+ t.ok(this['foo'] == filterScope['foo'] && this['bar'] == filterScope['bar'],
+ "Correct scope passed to filter func");
+ return true;
+ }
+ var handler = new OpenLayers.Handler.Feature(control, layer, {},
+ {'filter': {'fn': filter, 'args': filterArgs, 'scope': filterScope}});
+ handler.activate();
+ handler.callback = function(type,featurelist) {
+ t.eq(featurelist[0].id, feature.id, "Correct feature called back on");
+ }
+ handler.select("foo", {});
+ handler.feature = null;
+ handler.filter = {'fn': function(f) {return false;}, 'args': null, 'scope': null};
+ handler.callback = function(type,featurelist) {
+ t.fail("Shouldn't have called back on " + featurelist[0].geometry);
+ }
+ handler.select("foo", {});
+ }
+
function test_Handler_Feature_callbacks(t) {
t.plan(75);
Index: lib/OpenLayers/Control/DragFeature.js
===================================================================
--- lib/OpenLayers/Control/DragFeature.js (revision 5383)
+++ lib/OpenLayers/Control/DragFeature.js (working copy)
@@ -23,8 +23,21 @@
* send a list of strings corresponding to the geometry class names.
*/
geometryTypes: null,
-
+
/**
+ * APIProperty: filter
+ * {Object} To filter features that can be dragged. The object must
+ * have the properties fn, scope and args. fn is a {Function}, it
+ * is passed a {<OpenLayers.Feature.Vector>} object as its first
+ * argument, and it's expected to return true if the feature can
+ * be modified, and false otherwise. fn is also passed the args
+ * specified in the args property. The args property must be
+ * an {Array}. fn is executed using the scope specified in the
+ * scope property.
+ */
+ filter: null,
+
+ /**
* APIProperty: onStart
* {Function} Define this function if you want to know when a drag starts.
* The function should expect to receive two arguments: the feature
@@ -127,7 +140,10 @@
this.featureCallbacks = OpenLayers.Util.extend({over: this.overFeature,
out: this.outFeature
}, this.featureCallbacks);
- var handlerOptions = {geometryTypes: this.geometryTypes};
+ var handlerOptions = {
+ filter: this.filter,
+ geometryTypes: this.geometryTypes
+ }
this.featureHandler = new OpenLayers.Handler.Feature(this, this.layer,
this.featureCallbacks,
handlerOptions);
Index: lib/OpenLayers/Control/SelectFeature.js
===================================================================
--- lib/OpenLayers/Control/SelectFeature.js (revision 5383)
+++ lib/OpenLayers/Control/SelectFeature.js (working copy)
@@ -50,6 +50,19 @@
geometryTypes: null,
/**
+ * APIProperty: filter
+ * {Object} To filter features that can be selected. The object must
+ * have the properties fn, scope and args. fn is a {Function}, it
+ * is passed a {<OpenLayers.Feature.Vector>} object as its first
+ * argument, and it's expected to return true if the feature can
+ * be modified, and false otherwise. fn is also passed the args
+ * specified in the args property. The args property must be
+ * an {Array}. fn is executed using the scope specified in the
+ * scope property.
+ */
+ filter: null,
+
+ /**
* Property: layer
* {<OpenLayers.Layer.Vector>}
*/
@@ -88,7 +101,10 @@
over: this.overFeature,
out: this.outFeature
}, this.callbacks);
- var handlerOptions = {geometryTypes: this.geometryTypes};
+ var handlerOptions = {
+ geometryTypes: this.geometryTypes,
+ filter: this.filter
+ };
this.handler = new OpenLayers.Handler.Feature(this, layer,
this.callbacks,
handlerOptions);
Index: lib/OpenLayers/Control/ModifyFeature.js
===================================================================
--- lib/OpenLayers/Control/ModifyFeature.js (revision 5383)
+++ lib/OpenLayers/Control/ModifyFeature.js (working copy)
@@ -29,6 +29,19 @@
geometryTypes: null,
/**
+ * APIProperty: filter
+ * {Object} To filter features that can be modified. The object must
+ * have the properties fn, scope and args. fn is a {Function}, it
+ * is passed a {<OpenLayers.Feature.Vector>} object as its first
+ * argument, and it's expected to return true if the feature can
+ * be modified, and false otherwise. fn is also passed the args
+ * specified in the args property. The args property must be
+ * an {Array}. fn is executed using the scope specified in the
+ * scope property.
+ */
+ filter: null,
+
+ /**
* Property: layer
* {<OpenLayers.Layer.Vector>}
*/
@@ -168,6 +181,7 @@
// configure the select control
var selectOptions = {
geometryTypes: this.geometryTypes,
+ filter: this.filter,
onSelect: function(feature) {
control.selectFeature.apply(control, [feature]);
},
Index: lib/OpenLayers/Handler/Feature.js
===================================================================
--- lib/OpenLayers/Handler/Feature.js (revision 5383)
+++ lib/OpenLayers/Handler/Feature.js (working copy)
@@ -20,8 +20,21 @@
* @type Array(String)
*/
geometryTypes: null,
-
+
/**
+ * APIProperty: filter
+ * {Object} To filter features that can be selected. The object must
+ * have the properties fn, scope and args. fn is a {Function}, it
+ * is passed a {<OpenLayers.Feature.Vector>} object as its first
+ * argument, and it's expected to return true if the feature can
+ * be modified, and false otherwise. fn is also passed the args
+ * specified in the args property. The args property must be
+ * an {Array}. fn is executed using the scope specified in the
+ * scope property.
+ */
+ filter: null,
+
+ /**
* Property: layerIndex
* {Int}
*/
@@ -127,9 +140,11 @@
var feature = this.layer.getFeatureFromEvent(evt);
var selected = false;
if(feature) {
- if(this.geometryTypes == null ||
- (OpenLayers.Util.indexOf(this.geometryTypes,
- feature.geometry.CLASS_NAME) > -1)) {
+ if((this.geometryTypes == null ||
+ (OpenLayers.Util.indexOf(this.geometryTypes,
+ feature.geometry.CLASS_NAME) > -1)) &&
+ (this.filter == null ||
+ this.filter.fn.apply(this.filter.scope, [feature].concat(this.filter.args)))) {
// three cases:
// over a new, out of the last and over a new, or still on the last
if(!this.feature) {
_______________________________________________
Dev mailing list
[email protected]
http://openlayers.org/mailman/listinfo/dev