From e0c3db12276043713960cd0f048f8abff5631ca0 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 5 Aug 2010 15:38:55 +0000 Subject: [PATCH] Making consistent the evaluate method of filters. The evaluate method accepts vector features, making possible logical filters that combine spatial and comparison filters. r=ahocevar (closes #2773) git-svn-id: http://svn.openlayers.org/trunk/openlayers@10596 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- lib/OpenLayers/Filter.js | 3 +- lib/OpenLayers/Filter/Comparison.js | 26 ++++--- lib/OpenLayers/Filter/Logical.js | 7 +- tests/Filter/Comparison.html | 112 +++++++++++++++++++++++++++- tests/Filter/Logical.html | 69 +++++++++++++++++ tests/Filter/Spatial.html | 21 ++++-- 6 files changed, 215 insertions(+), 23 deletions(-) diff --git a/lib/OpenLayers/Filter.js b/lib/OpenLayers/Filter.js index 31cbcd36ba..55f966ca53 100644 --- a/lib/OpenLayers/Filter.js +++ b/lib/OpenLayers/Filter.js @@ -42,7 +42,8 @@ OpenLayers.Filter = OpenLayers.Class({ * subclasses. * * Parameters: - * context - {Object} Context to use in evaluating the filter. + * context - {Object} Context to use in evaluating the filter. If a vector + * feature is provided, the feature.attributes will be used as context. * * Returns: * {Boolean} The filter applies. diff --git a/lib/OpenLayers/Filter/Comparison.js b/lib/OpenLayers/Filter/Comparison.js index b8d4e92a42..5c6edc65d3 100644 --- a/lib/OpenLayers/Filter/Comparison.js +++ b/lib/OpenLayers/Filter/Comparison.js @@ -93,20 +93,23 @@ OpenLayers.Filter.Comparison = OpenLayers.Class(OpenLayers.Filter, { /** * APIMethod: evaluate - * Evaluates this filter in a specific context. Should be implemented by - * subclasses. + * Evaluates this filter in a specific context. * * Parameters: - * context - {Object} Context to use in evaluating the filter. + * context - {Object} Context to use in evaluating the filter. If a vector + * feature is provided, the feature.attributes will be used as context. * * Returns: * {Boolean} The filter applies. */ evaluate: function(context) { + if (context instanceof OpenLayers.Feature.Vector) { + context = context.attributes; + } var result = false; + var got = context[this.property]; switch(this.type) { case OpenLayers.Filter.Comparison.EQUAL_TO: - var got = context[this.property]; var exp = this.value; if(!this.matchCase && typeof got == "string" && typeof exp == "string") { @@ -116,7 +119,6 @@ OpenLayers.Filter.Comparison = OpenLayers.Class(OpenLayers.Filter, { } break; case OpenLayers.Filter.Comparison.NOT_EQUAL_TO: - var got = context[this.property]; var exp = this.value; if(!this.matchCase && typeof got == "string" && typeof exp == "string") { @@ -126,24 +128,24 @@ OpenLayers.Filter.Comparison = OpenLayers.Class(OpenLayers.Filter, { } break; case OpenLayers.Filter.Comparison.LESS_THAN: - result = context[this.property] < this.value; + result = got < this.value; break; case OpenLayers.Filter.Comparison.GREATER_THAN: - result = context[this.property] > this.value; + result = got > this.value; break; case OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO: - result = context[this.property] <= this.value; + result = got <= this.value; break; case OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO: - result = context[this.property] >= this.value; + result = got >= this.value; break; case OpenLayers.Filter.Comparison.BETWEEN: - result = (context[this.property] >= this.lowerBoundary) && - (context[this.property] <= this.upperBoundary); + result = (got >= this.lowerBoundary) && + (got <= this.upperBoundary); break; case OpenLayers.Filter.Comparison.LIKE: var regexp = new RegExp(this.value, "gi"); - result = regexp.test(context[this.property]); + result = regexp.test(got); break; } return result; diff --git a/lib/OpenLayers/Filter/Logical.js b/lib/OpenLayers/Filter/Logical.js index a438af45a5..fd0f9cbc84 100644 --- a/lib/OpenLayers/Filter/Logical.js +++ b/lib/OpenLayers/Filter/Logical.js @@ -58,11 +58,12 @@ OpenLayers.Filter.Logical = OpenLayers.Class(OpenLayers.Filter, { /** * APIMethod: evaluate - * Evaluates this filter in a specific context. Should be implemented by - * subclasses. + * Evaluates this filter in a specific context. * * Parameters: - * context - {Object} Context to use in evaluating the filter. + * context - {Object} Context to use in evaluating the filter. A vector + * feature may also be provided to evaluate feature attributes in + * comparison filters or geometries in spatial filters. * * Returns: * {Boolean} The filter applies. diff --git a/tests/Filter/Comparison.html b/tests/Filter/Comparison.html index b7c0cb15ef..b9505dbb04 100644 --- a/tests/Filter/Comparison.html +++ b/tests/Filter/Comparison.html @@ -175,7 +175,117 @@ } } - + + function test_evaluate_feature(t) { + + var cases = [{ + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.BETWEEN, + property: "area", + lowerBoundary: 1000, + upperBoundary: 4999 + }), + context: new OpenLayers.Feature.Vector(null, {area: 999}), + expect: false + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.BETWEEN, + property: "area", + lowerBoundary: 1000, + upperBoundary: 4999 + }), + context: new OpenLayers.Feature.Vector(null, {area: 1000}), + expect: true + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.BETWEEN, + property: "area", + lowerBoundary: 1000, + upperBoundary: 4999 + }), + context: new OpenLayers.Feature.Vector(null, {area: 4999}), + expect: true + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.BETWEEN, + property: "area", + lowerBoundary: 1000, + upperBoundary: 4999 + }), + context: new OpenLayers.Feature.Vector(null, {area: 5000}), + expect: false + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.BETWEEN, + property: "area", + lowerBoundary: 1000, + upperBoundary: 4999 + }), + context: new OpenLayers.Feature.Vector(null, {area: 999}), + expect: false + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.EQUAL_TO, + property: "prop", + value: "Foo" + }), + context: new OpenLayers.Feature.Vector(null, {prop: "Foo"}), + expect: true + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.EQUAL_TO, + property: "prop", + value: "Foo" + }), + context: new OpenLayers.Feature.Vector(null, {prop: "foo"}), + expect: false + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.EQUAL_TO, + matchCase: true, + property: "prop", + value: "Foo" + }), + context: new OpenLayers.Feature.Vector(null, {prop: "foo"}), + expect: false + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO, + property: "prop", + value: "foo" + }), + context: {prop: "FOO"}, + expect: true + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO, + matchCase: true, + property: "prop", + value: "foo" + }), + context: new OpenLayers.Feature.Vector(null, {prop: "FOO"}), + expect: true + }, { + filter: new OpenLayers.Filter.Comparison({ + type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO, + matchCase: false, + property: "prop", + value: "foo" + }), + context: new OpenLayers.Feature.Vector(null, {prop: "FOO"}), + expect: false + }]; + + t.plan(cases.length); + + var c; + for(var i=0; i