[OpenLayers-Commits] r11712 - in trunk/openlayers: lib
lib/OpenLayers/Filter lib/OpenLayers/Format/Filter
tests/Format/Filter
commits-20090109 at openlayers.org
commits-20090109 at openlayers.org
Thu Mar 17 11:47:32 EDT 2011
Author: bartvde
Date: 2011-03-17 08:47:28 -0700 (Thu, 17 Mar 2011)
New Revision: 11712
Added:
trunk/openlayers/lib/OpenLayers/Filter/Function.js
Modified:
trunk/openlayers/lib/OpenLayers.js
trunk/openlayers/lib/OpenLayers/Format/Filter/v1.js
trunk/openlayers/lib/OpenLayers/Format/Filter/v1_0_0.js
trunk/openlayers/lib/OpenLayers/Format/Filter/v1_1_0.js
trunk/openlayers/tests/Format/Filter/v1_0_0.html
trunk/openlayers/tests/Format/Filter/v1_1_0.html
Log:
Geoserver filter Functions support in OL filter encoding, p=igrcic,r=me (closes #3053)
Added: trunk/openlayers/lib/OpenLayers/Filter/Function.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Filter/Function.js (rev 0)
+++ trunk/openlayers/lib/OpenLayers/Filter/Function.js 2011-03-17 15:47:28 UTC (rev 11712)
@@ -0,0 +1,52 @@
+/* Copyright (c) 2006-2011 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
+ */
+
+/**
+ * Class: OpenLayers.Filter.Function
+ * This class represents a filter function.
+ * We are using this class for creation of complex
+ * filters that can contain filter functions as values.
+ * Nesting function as other functions parameter is supported.
+ *
+ * Inherits from
+ * - <OpenLayers.Filter>
+ */
+OpenLayers.Filter.Function = OpenLayers.Class(OpenLayers.Filter, {
+
+ /**
+ * APIProperty: name
+ * {String} Name of the function.
+ */
+ name: null,
+
+ /**
+ * APIProperty: params
+ * {Array(<OpenLayers.Filter.Function> || String || Number)} Function parameters
+ * For now support only other Functions, String or Number
+ */
+ params: null,
+
+ /**
+ * Constructor: OpenLayers.Filter.Function
+ * Creates a filter function.
+ *
+ * Parameters:
+ * options - {Object} An optional object with properties to set on the
+ * function.
+ *
+ * Returns:
+ * {<OpenLayers.Filter.Function>}
+ */
+ initialize: function(options) {
+ OpenLayers.Filter.prototype.initialize.apply(this, [options]);
+ },
+
+ CLASS_NAME: "OpenLayers.Filter.Function"
+});
+
Modified: trunk/openlayers/lib/OpenLayers/Format/Filter/v1.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Format/Filter/v1.js 2011-03-17 13:01:37 UTC (rev 11711)
+++ trunk/openlayers/lib/OpenLayers/Format/Filter/v1.js 2011-03-17 15:47:28 UTC (rev 11712)
@@ -186,6 +186,10 @@
"Distance": function(node, obj) {
obj.distance = parseInt(this.getChildValue(node));
obj.distanceUnits = node.getAttribute("units");
+ },
+ "Function": function(node, obj) {
+ //TODO write decoder for it
+ return;
}
}
},
@@ -234,6 +238,28 @@
},
/**
+ * Method: writeOgcExpression
+ * Limited support for writing OGC expressions. Currently it supports
+ * (<OpenLayers.Filter.Function> || String || Number)
+ *
+ * Parameters:
+ * value - (<OpenLayers.Filter.Function> || String || Number)
+ * node - {DOMElement} A parent DOM element
+ *
+ * Returns:
+ * {DOMElement} Updated node element.
+ */
+ writeOgcExpression: function(value, node) {
+ if(value instanceof OpenLayers.Filter.Function){
+ var child = this.writeNode("Function", value, node);
+ node.appendChild(child);
+ } else {
+ this.writeNode("Literal", value, node);
+ }
+ return node;
+ },
+
+ /**
* Method: write
*
* Parameters:
@@ -303,35 +329,39 @@
},
"PropertyIsLessThan": function(filter) {
var node = this.createElementNSPlus("ogc:PropertyIsLessThan");
- // no ogc:expression handling for now
+ // no ogc:expression handling for PropertyName for now
this.writeNode("PropertyName", filter, node);
- this.writeNode("Literal", filter.value, node);
+ // handle Literals or Functions for now
+ this.writeOgcExpression(filter.value, node);
return node;
},
"PropertyIsGreaterThan": function(filter) {
var node = this.createElementNSPlus("ogc:PropertyIsGreaterThan");
- // no ogc:expression handling for now
+ // no ogc:expression handling for PropertyName for now
this.writeNode("PropertyName", filter, node);
- this.writeNode("Literal", filter.value, node);
+ // handle Literals or Functions for now
+ this.writeOgcExpression(filter.value, node);
return node;
},
"PropertyIsLessThanOrEqualTo": function(filter) {
var node = this.createElementNSPlus("ogc:PropertyIsLessThanOrEqualTo");
- // no ogc:expression handling for now
+ // no ogc:expression handling for PropertyName for now
this.writeNode("PropertyName", filter, node);
- this.writeNode("Literal", filter.value, node);
+ // handle Literals or Functions for now
+ this.writeOgcExpression(filter.value, node);
return node;
},
"PropertyIsGreaterThanOrEqualTo": function(filter) {
var node = this.createElementNSPlus("ogc:PropertyIsGreaterThanOrEqualTo");
- // no ogc:expression handling for now
+ // no ogc:expression handling for PropertyName for now
this.writeNode("PropertyName", filter, node);
- this.writeNode("Literal", filter.value, node);
+ // handle Literals or Functions for now
+ this.writeOgcExpression(filter.value, node);
return node;
},
"PropertyIsBetween": function(filter) {
var node = this.createElementNSPlus("ogc:PropertyIsBetween");
- // no ogc:expression handling for now
+ // no ogc:expression handling for PropertyName for now
this.writeNode("PropertyName", filter, node);
this.writeNode("LowerBoundary", filter, node);
this.writeNode("UpperBoundary", filter, node);
@@ -350,13 +380,13 @@
});
},
"LowerBoundary": function(filter) {
- // no ogc:expression handling for now
+ // handle Literals or Functions for now
var node = this.createElementNSPlus("ogc:LowerBoundary");
- this.writeNode("Literal", filter.lowerBoundary, node);
+ this.writeOgcExpression(filter.lowerBoundary, node);
return node;
},
"UpperBoundary": function(filter) {
- // no ogc:expression handling for now
+ // handle Literals or Functions for now
var node = this.createElementNSPlus("ogc:UpperBoundary");
this.writeNode("Literal", filter.upperBoundary, node);
return node;
@@ -382,8 +412,20 @@
},
value: filter.distance
});
+ },
+ "Function": function(filter) {
+ var node = this.createElementNSPlus("ogc:Function", {
+ attributes: {
+ name: filter.name
}
+ });
+ var params = filter.params;
+ for(var i=0, len=params.length; i<len; i++){
+ this.writeOgcExpression(params[i], node);
}
+ return node;
+ }
+ }
},
/**
Modified: trunk/openlayers/lib/OpenLayers/Format/Filter/v1_0_0.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Format/Filter/v1_0_0.js 2011-03-17 13:01:37 UTC (rev 11711)
+++ trunk/openlayers/lib/OpenLayers/Format/Filter/v1_0_0.js 2011-03-17 15:47:28 UTC (rev 11712)
@@ -96,16 +96,18 @@
"ogc": OpenLayers.Util.applyDefaults({
"PropertyIsEqualTo": function(filter) {
var node = this.createElementNSPlus("ogc:PropertyIsEqualTo");
- // no ogc:expression handling for now
+ // no ogc:expression handling for PropertyName for now
this.writeNode("PropertyName", filter, node);
- this.writeNode("Literal", filter.value, node);
+ // handle Literals or Functions for now
+ this.writeOgcExpression(filter.value, node);
return node;
},
"PropertyIsNotEqualTo": function(filter) {
var node = this.createElementNSPlus("ogc:PropertyIsNotEqualTo");
- // no ogc:expression handling for now
+ // no ogc:expression handling for PropertyName for now
this.writeNode("PropertyName", filter, node);
- this.writeNode("Literal", filter.value, node);
+ // handle Literals or Functions for now
+ this.writeOgcExpression(filter.value, node);
return node;
},
"PropertyIsLike": function(filter) {
@@ -150,6 +152,9 @@
writeSpatial: function(filter, name) {
var node = this.createElementNSPlus("ogc:"+name);
this.writeNode("PropertyName", filter, node);
+ if(filter.value instanceof OpenLayers.Filter.Function) {
+ this.writeNode("Function", filter.value, node);
+ } else {
var child;
if(filter.value instanceof OpenLayers.Geometry) {
child = this.writeNode("feature:_geometry", filter.value).firstChild;
@@ -160,6 +165,7 @@
child.setAttribute("srsName", filter.projection);
}
node.appendChild(child);
+ }
return node;
},
Modified: trunk/openlayers/lib/OpenLayers/Format/Filter/v1_1_0.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Format/Filter/v1_1_0.js 2011-03-17 13:01:37 UTC (rev 11711)
+++ trunk/openlayers/lib/OpenLayers/Format/Filter/v1_1_0.js 2011-03-17 15:47:28 UTC (rev 11712)
@@ -108,18 +108,20 @@
var node = this.createElementNSPlus("ogc:PropertyIsEqualTo", {
attributes: {matchCase: filter.matchCase}
});
- // no ogc:expression handling for now
+ // no ogc:expression handling for PropertyName for now
this.writeNode("PropertyName", filter, node);
- this.writeNode("Literal", filter.value, node);
+ // handle Literals or Functions for now
+ this.writeOgcExpression(filter.value, node);
return node;
},
"PropertyIsNotEqualTo": function(filter) {
var node = this.createElementNSPlus("ogc:PropertyIsNotEqualTo", {
attributes: {matchCase: filter.matchCase}
});
- // no ogc:expression handling for now
+ // no ogc:expression handling for PropertyName for now
this.writeNode("PropertyName", filter, node);
- this.writeNode("Literal", filter.value, node);
+ // handle Literals or Functions for now
+ this.writeOgcExpression(filter.value, node);
return node;
},
"PropertyIsLike": function(filter) {
@@ -164,6 +166,9 @@
writeSpatial: function(filter, name) {
var node = this.createElementNSPlus("ogc:"+name);
this.writeNode("PropertyName", filter, node);
+ if(filter.value instanceof OpenLayers.Filter.Function) {
+ this.writeNode("Function", filter.value, node);
+ } else {
var child;
if(filter.value instanceof OpenLayers.Geometry) {
child = this.writeNode("feature:_geometry", filter.value).firstChild;
@@ -174,6 +179,7 @@
child.setAttribute("srsName", filter.projection);
}
node.appendChild(child);
+ }
return node;
},
Modified: trunk/openlayers/lib/OpenLayers.js
===================================================================
--- trunk/openlayers/lib/OpenLayers.js 2011-03-17 13:01:37 UTC (rev 11711)
+++ trunk/openlayers/lib/OpenLayers.js 2011-03-17 15:47:28 UTC (rev 11712)
@@ -244,6 +244,7 @@
"OpenLayers/Filter/Logical.js",
"OpenLayers/Filter/Comparison.js",
"OpenLayers/Filter/Spatial.js",
+ "OpenLayers/Filter/Function.js",
"OpenLayers/Protocol.js",
"OpenLayers/Protocol/HTTP.js",
"OpenLayers/Protocol/SimpleFilterSerializer.js",
Modified: trunk/openlayers/tests/Format/Filter/v1_0_0.html
===================================================================
--- trunk/openlayers/tests/Format/Filter/v1_0_0.html 2011-03-17 13:01:37 UTC (rev 11711)
+++ trunk/openlayers/tests/Format/Filter/v1_0_0.html 2011-03-17 15:47:28 UTC (rev 11712)
@@ -152,7 +152,117 @@
}
+ function test_FilterFunctions(t) {
+ t.plan(2);
+ var parser = new OpenLayers.Format.Filter.v1_0_0();
+
+ //test spatial intersects with filter function
+ var filter = new OpenLayers.Filter.Spatial({
+ property: 'the_geom',
+ type: OpenLayers.Filter.Spatial.INTERSECTS,
+ value: new OpenLayers.Filter.Function({
+ name : 'querySingle',
+ params: ['sf:restricted', 'the_geom', 'cat=3']
+ })
+ });
+
+ var out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:Intersects>' +
+ '<ogc:PropertyName>the_geom</ogc:PropertyName>' +
+ '<ogc:Function name="querySingle">' +
+ '<ogc:Literal>sf:restricted</ogc:Literal>' +
+ '<ogc:Literal>the_geom</ogc:Literal>' +
+ '<ogc:Literal>cat=3</ogc:Literal>' +
+ '</ogc:Function>' +
+ '</ogc:Intersects>' +
+ '</ogc:Filter>';
+
+
+ var node = parser.write(filter);
+
+ //test writer
+ t.xml_eq(node, out, "spatial intersect filter with functions correctly written");
+
+ //test logical filter with custom function
+ filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.AND,
+ filters: [
+ new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
+ property: "FOO",
+ value: new OpenLayers.Filter.Function({
+ name : 'customFunction',
+ params : ['param1', 'param2']
+ })
+ })
+ ]
+ });
+
+ out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:And>' +
+ '<ogc:PropertyIsNotEqualTo>' +
+ '<ogc:PropertyName>FOO</ogc:PropertyName>' +
+ '<ogc:Function name="customFunction">' +
+ '<ogc:Literal>param1</ogc:Literal>' +
+ '<ogc:Literal>param2</ogc:Literal>' +
+ '</ogc:Function>' +
+ '</ogc:PropertyIsNotEqualTo>' +
+ '</ogc:And>' +
+ '</ogc:Filter>';
+
+ node = parser.write(filter);
+
+ //test writer
+ t.xml_eq(node, out, "comparison filter with filter functions correctly written");
+
+ }
+
+ function test_NestedFilterFunctions(t) {
+ t.plan(1);
+
+ //test spatial dwithin with nested filter function
+ var filter = new OpenLayers.Filter.Spatial({
+ property: 'the_geom',
+ type: OpenLayers.Filter.Spatial.DWITHIN,
+ value: new OpenLayers.Filter.Function({
+ name : 'collectGeometries',
+ params: [
+ new OpenLayers.Filter.Function({
+ name : 'queryCollection',
+ params: ['sf:roads', 'the_geom', 'INCLUDE']
+ })
+ ]
+ }),
+ distanceUnits: "meters",
+ distance: 200
+ });
+
+ var out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:DWithin>' +
+ '<ogc:PropertyName>the_geom</ogc:PropertyName>' +
+ '<ogc:Function name="collectGeometries">' +
+ '<ogc:Function name="queryCollection">' +
+ '<ogc:Literal>sf:roads</ogc:Literal>' +
+ '<ogc:Literal>the_geom</ogc:Literal>' +
+ '<ogc:Literal>INCLUDE</ogc:Literal>' +
+ '</ogc:Function>' +
+ '</ogc:Function>' +
+ '<ogc:Distance units="meters">200</ogc:Distance>' +
+ '</ogc:DWithin>' +
+ '</ogc:Filter>';
+
+ var parser = new OpenLayers.Format.Filter.v1_0_0();
+ var node = parser.write(filter);
+
+ //test writer
+ t.xml_eq(node, out, "spatial dwithin filter with nested functions correctly written");
+ }
+
+
</script>
</head>
<body>
Modified: trunk/openlayers/tests/Format/Filter/v1_1_0.html
===================================================================
--- trunk/openlayers/tests/Format/Filter/v1_1_0.html 2011-03-17 13:01:37 UTC (rev 11711)
+++ trunk/openlayers/tests/Format/Filter/v1_1_0.html 2011-03-17 15:47:28 UTC (rev 11712)
@@ -203,6 +203,118 @@
}
+ function test_FilterFunctions(t) {
+ t.plan(2);
+
+ var parser = new OpenLayers.Format.Filter.v1_1_0();
+
+ //test spatial intersects with filter function
+ var filter = new OpenLayers.Filter.Spatial({
+ property: 'the_geom',
+ type: OpenLayers.Filter.Spatial.INTERSECTS,
+ value: new OpenLayers.Filter.Function({
+ name : 'querySingle',
+ params: ['sf:restricted', 'the_geom', 'cat=3']
+ })
+ });
+
+ var out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:Intersects>' +
+ '<ogc:PropertyName>the_geom</ogc:PropertyName>' +
+ '<ogc:Function name="querySingle">' +
+ '<ogc:Literal>sf:restricted</ogc:Literal>' +
+ '<ogc:Literal>the_geom</ogc:Literal>' +
+ '<ogc:Literal>cat=3</ogc:Literal>' +
+ '</ogc:Function>' +
+ '</ogc:Intersects>' +
+ '</ogc:Filter>';
+
+
+ var node = parser.write(filter);
+
+ //test writer
+ t.xml_eq(node, out, "spatial intersect filter with functions correctly written");
+
+ //test logical filter with custom function
+ filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.AND,
+ filters: [
+ new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
+ matchCase: false,
+ property: "FOO",
+ value: new OpenLayers.Filter.Function({
+ name : 'customFunction',
+ params : ['param1', 'param2']
+ })
+ })
+ ]
+ });
+
+ out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:And>' +
+ '<ogc:PropertyIsNotEqualTo matchCase="false">' +
+ '<ogc:PropertyName>FOO</ogc:PropertyName>' +
+ '<ogc:Function name="customFunction">' +
+ '<ogc:Literal>param1</ogc:Literal>' +
+ '<ogc:Literal>param2</ogc:Literal>' +
+ '</ogc:Function>' +
+ '</ogc:PropertyIsNotEqualTo>' +
+ '</ogc:And>' +
+ '</ogc:Filter>';
+
+ node = parser.write(filter);
+
+ //test writer
+ t.xml_eq(node, out, "comparison filter with filter functions correctly written");
+
+ }
+
+ function test_NestedFilterFunctions(t) {
+ t.plan(1);
+
+ //test spatial dwithin with nested filter function
+ var filter = new OpenLayers.Filter.Spatial({
+ property: 'the_geom',
+ type: OpenLayers.Filter.Spatial.DWITHIN,
+ value: new OpenLayers.Filter.Function({
+ name : 'collectGeometries',
+ params: [
+ new OpenLayers.Filter.Function({
+ name : 'queryCollection',
+ params: ['sf:roads', 'the_geom', 'INCLUDE']
+ })
+ ]
+ }),
+ distanceUnits: "meters",
+ distance: 200
+ });
+
+ var out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:DWithin>' +
+ '<ogc:PropertyName>the_geom</ogc:PropertyName>' +
+ '<ogc:Function name="collectGeometries">' +
+ '<ogc:Function name="queryCollection">' +
+ '<ogc:Literal>sf:roads</ogc:Literal>' +
+ '<ogc:Literal>the_geom</ogc:Literal>' +
+ '<ogc:Literal>INCLUDE</ogc:Literal>' +
+ '</ogc:Function>' +
+ '</ogc:Function>' +
+ '<ogc:Distance units="meters">200</ogc:Distance>' +
+ '</ogc:DWithin>' +
+ '</ogc:Filter>';
+
+ var parser = new OpenLayers.Format.Filter.v1_1_0();
+ var node = parser.write(filter);
+
+ //test writer
+ t.xml_eq(node, out, "spatial dwithin filter with nested functions correctly written");
+ }
+
+
</script>
</head>
<body>
More information about the Commits
mailing list