[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