--- a/labs/openlayers/lib/OpenLayers/Filter/Comparison.js +++ b/labs/openlayers/lib/OpenLayers/Filter/Comparison.js @@ -1,1 +1,259 @@ - +/* 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/Filter.js + * @requires OpenLayers/Console.js + */ + +/** + * Class: OpenLayers.Filter.Comparison + * This class represents a comparison filter. + * + * Inherits from + * - + */ +OpenLayers.Filter.Comparison = OpenLayers.Class(OpenLayers.Filter, { + + /** + * APIProperty: type + * {String} type: type of the comparison. This is one of + * - OpenLayers.Filter.Comparison.EQUAL_TO = "=="; + * - OpenLayers.Filter.Comparison.NOT_EQUAL_TO = "!="; + * - OpenLayers.Filter.Comparison.LESS_THAN = "<"; + * - OpenLayers.Filter.Comparison.GREATER_THAN = ">"; + * - OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO = "<="; + * - OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO = ">="; + * - OpenLayers.Filter.Comparison.BETWEEN = ".."; + * - OpenLayers.Filter.Comparison.LIKE = "~"; + */ + type: null, + + /** + * APIProperty: property + * {String} + * name of the context property to compare + */ + property: null, + + /** + * APIProperty: value + * {Number} or {String} + * comparison value for binary comparisons. In the case of a String, this + * can be a combination of text and propertyNames in the form + * "literal ${propertyName}" + */ + value: null, + + /** + * Property: matchCase + * {Boolean} Force case sensitive searches for EQUAL_TO and NOT_EQUAL_TO + * comparisons. The Filter Encoding 1.1 specification added a matchCase + * attribute to ogc:PropertyIsEqualTo and ogc:PropertyIsNotEqualTo + * elements. This property will be serialized with those elements only + * if using the v1.1.0 filter format. However, when evaluating filters + * here, the matchCase property will always be respected (for EQUAL_TO + * and NOT_EQUAL_TO). Default is true. + */ + matchCase: true, + + /** + * APIProperty: lowerBoundary + * {Number} or {String} + * lower boundary for between comparisons. In the case of a String, this + * can be a combination of text and propertyNames in the form + * "literal ${propertyName}" + */ + lowerBoundary: null, + + /** + * APIProperty: upperBoundary + * {Number} or {String} + * upper boundary for between comparisons. In the case of a String, this + * can be a combination of text and propertyNames in the form + * "literal ${propertyName}" + */ + upperBoundary: null, + + /** + * Constructor: OpenLayers.Filter.Comparison + * Creates a comparison rule. + * + * Parameters: + * options - {Object} An optional object with properties to set on the + * rule + * + * Returns: + * {} + */ + initialize: function(options) { + OpenLayers.Filter.prototype.initialize.apply(this, [options]); + }, + + /** + * APIMethod: evaluate + * Evaluates this filter in a specific context. + * + * Parameters: + * 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 exp = this.value; + if(!this.matchCase && + typeof got == "string" && typeof exp == "string") { + result = (got.toUpperCase() == exp.toUpperCase()); + } else { + result = (got == exp); + } + break; + case OpenLayers.Filter.Comparison.NOT_EQUAL_TO: + var exp = this.value; + if(!this.matchCase && + typeof got == "string" && typeof exp == "string") { + result = (got.toUpperCase() != exp.toUpperCase()); + } else { + result = (got != exp); + } + break; + case OpenLayers.Filter.Comparison.LESS_THAN: + result = got < this.value; + break; + case OpenLayers.Filter.Comparison.GREATER_THAN: + result = got > this.value; + break; + case OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO: + result = got <= this.value; + break; + case OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO: + result = got >= this.value; + break; + case OpenLayers.Filter.Comparison.BETWEEN: + result = (got >= this.lowerBoundary) && + (got <= this.upperBoundary); + break; + case OpenLayers.Filter.Comparison.LIKE: + var regexp = new RegExp(this.value, "gi"); + result = regexp.test(got); + break; + } + return result; + }, + + /** + * APIMethod: value2regex + * Converts the value of this rule into a regular expression string, + * according to the wildcard characters specified. This method has to + * be called after instantiation of this class, if the value is not a + * regular expression already. + * + * Parameters: + * wildCard - {} wildcard character in the above value, default + * is "*" + * singleChar - {) single-character wildcard in the above value + * default is "." + * escape - {) escape character in the above value, default is + * "!" + * + * Returns: + * {String} regular expression string + */ + value2regex: function(wildCard, singleChar, escapeChar) { + if (wildCard == ".") { + var msg = "'.' is an unsupported wildCard character for "+ + "OpenLayers.Filter.Comparison"; + OpenLayers.Console.error(msg); + return null; + } + + + // set UMN MapServer defaults for unspecified parameters + wildCard = wildCard ? wildCard : "*"; + singleChar = singleChar ? singleChar : "."; + escapeChar = escapeChar ? escapeChar : "!"; + + this.value = this.value.replace( + new RegExp("\\"+escapeChar+"(.|$)", "g"), "\\$1"); + this.value = this.value.replace( + new RegExp("\\"+singleChar, "g"), "."); + this.value = this.value.replace( + new RegExp("\\"+wildCard, "g"), ".*"); + this.value = this.value.replace( + new RegExp("\\\\.\\*", "g"), "\\"+wildCard); + this.value = this.value.replace( + new RegExp("\\\\\\.", "g"), "\\"+singleChar); + + return this.value; + }, + + /** + * Method: regex2value + * Convert the value of this rule from a regular expression string into an + * ogc literal string using a wildCard of *, a singleChar of ., and an + * escape of !. Leaves the property unmodified. + * + * Returns: + * {String} A string value. + */ + regex2value: function() { + + var value = this.value; + + // replace ! with !! + value = value.replace(/!/g, "!!"); + + // replace \. with !. (watching out for \\.) + value = value.replace(/(\\)?\\\./g, function($0, $1) { + return $1 ? $0 : "!."; + }); + + // replace \* with #* (watching out for \\*) + value = value.replace(/(\\)?\\\*/g, function($0, $1) { + return $1 ? $0 : "!*"; + }); + + // replace \\ with \ + value = value.replace(/\\\\/g, "\\"); + + // convert .* to * (the sequence #.* is not allowed) + value = value.replace(/\.\*/g, "*"); + + return value; + }, + + /** + * APIMethod: clone + * Clones this filter. + * + * Returns: + * {} Clone of this filter. + */ + clone: function() { + return OpenLayers.Util.extend(new OpenLayers.Filter.Comparison(), this); + }, + + CLASS_NAME: "OpenLayers.Filter.Comparison" +}); + + +OpenLayers.Filter.Comparison.EQUAL_TO = "=="; +OpenLayers.Filter.Comparison.NOT_EQUAL_TO = "!="; +OpenLayers.Filter.Comparison.LESS_THAN = "<"; +OpenLayers.Filter.Comparison.GREATER_THAN = ">"; +OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO = "<="; +OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO = ">="; +OpenLayers.Filter.Comparison.BETWEEN = ".."; +OpenLayers.Filter.Comparison.LIKE = "~"; +