From 1faed26393743db1da09bde3791b7c5dd5a5815d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Junod?= Date: Fri, 19 Mar 2010 15:12:50 +0000 Subject: [PATCH] extend Protocol.HTTP for MapFish and FeatureServer. p=elemoine, r=bartvde,me (closes #2393) git-svn-id: http://svn.openlayers.org/trunk/openlayers@10129 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- lib/OpenLayers.js | 10 +- lib/OpenLayers/Protocol/HTTP.js | 180 ++++++++++++++++++-- tests/Protocol/HTTP.html | 289 +++++++++++++++++++++++++++++++- 3 files changed, 455 insertions(+), 24 deletions(-) diff --git a/lib/OpenLayers.js b/lib/OpenLayers.js index 61d30a39f3..6f96612384 100644 --- a/lib/OpenLayers.js +++ b/lib/OpenLayers.js @@ -206,6 +206,11 @@ "OpenLayers/Strategy/BBOX.js", "OpenLayers/Strategy/Save.js", "OpenLayers/Strategy/Refresh.js", + "OpenLayers/Filter.js", + "OpenLayers/Filter/FeatureId.js", + "OpenLayers/Filter/Logical.js", + "OpenLayers/Filter/Comparison.js", + "OpenLayers/Filter/Spatial.js", "OpenLayers/Protocol.js", "OpenLayers/Protocol/HTTP.js", "OpenLayers/Protocol/SQL.js", @@ -221,11 +226,6 @@ "OpenLayers/Style.js", "OpenLayers/StyleMap.js", "OpenLayers/Rule.js", - "OpenLayers/Filter.js", - "OpenLayers/Filter/FeatureId.js", - "OpenLayers/Filter/Logical.js", - "OpenLayers/Filter/Comparison.js", - "OpenLayers/Filter/Spatial.js", "OpenLayers/Format.js", "OpenLayers/Format/XML.js", "OpenLayers/Format/ArcXML.js", diff --git a/lib/OpenLayers/Protocol/HTTP.js b/lib/OpenLayers/Protocol/HTTP.js index 01d52c15cf..6497cc6edf 100644 --- a/lib/OpenLayers/Protocol/HTTP.js +++ b/lib/OpenLayers/Protocol/HTTP.js @@ -5,6 +5,9 @@ /** * @requires OpenLayers/Protocol.js * @requires OpenLayers/Feature/Vector.js + * @requires OpenLayers/Filter/Spatial.js + * @requires OpenLayers/Filter/Comparison.js + * @requires OpenLayers/Filter/Logical.js */ /** @@ -62,6 +65,17 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, { */ readWithPOST: false, + /** + * Property: wildcarded. + * {Boolean} If true percent signs are added around values + * read from LIKE filters, for example if the protocol + * read method is passed a LIKE filter whose property + * is "foo" and whose value is "bar" the string + * "foo__ilike=%bar%" will be sent in the query string; + * defaults to false. + */ + wildcarded: false, + /** * Constructor: OpenLayers.Protocol.HTTP * A class for giving layers generic HTTP protocol. @@ -79,6 +93,7 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, { * scope - {Object} */ initialize: function(options) { + options = options || {}; this.params = {}; this.headers = {}; OpenLayers.Protocol.prototype.initialize.apply(this, arguments); @@ -106,10 +121,8 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, { * url - {String} Url for the request. * params - {Object} Parameters to get serialized as a query string. * headers - {Object} Headers to be set on the request. - * filter - {} If a bbox filter is sent, it will be - * serialized according to the OpenSearch Geo extension - * (bbox=minx,miny,maxx,maxy). Note that a BBOX filter as the child - * of a logical filter will not be serialized. + * filter - {} Filter to get serialized as a + * query string. * readWithPOST - {Boolean} If the request should be done with POST. * * Returns: @@ -121,18 +134,15 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, { read: function(options) { OpenLayers.Protocol.prototype.read.apply(this, arguments); options = OpenLayers.Util.applyDefaults(options, this.options); + options.params = OpenLayers.Util.applyDefaults( + options.params, this.options.params); + if(options.filter) { + options.params = this.filterToParams( + options.filter, options.params); + } var readWithPOST = (options.readWithPOST !== undefined) ? options.readWithPOST : this.readWithPOST; var resp = new OpenLayers.Protocol.Response({requestType: "read"}); - - if(options.filter && options.filter instanceof OpenLayers.Filter.Spatial) { - if(options.filter.type == OpenLayers.Filter.Spatial.BBOX) { - options.params = OpenLayers.Util.extend(options.params, { - bbox: options.filter.value.toArray() - }); - } - } - if(readWithPOST) { resp.priv = OpenLayers.Request.POST({ url: options.url, @@ -150,7 +160,6 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, { headers: options.headers }); } - return resp; }, @@ -167,7 +176,122 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, { handleRead: function(resp, options) { this.handleResponse(resp, options); }, - + + /** + * Method: filterToParams + * Convert an object to parameters. + * + * Parameters: + * filter - {OpenLayers.Filter} filter to convert. + * params - {Object} The parameters object. + * + * Returns: + * {Object} The resulting parameters object. + */ + filterToParams: function(filter, params) { + params = params || {}; + var className = filter.CLASS_NAME; + var filterType = className.substring(className.lastIndexOf(".") + 1); + switch(filterType) { + case "Spatial": + switch(filter.type) { + case OpenLayers.Filter.Spatial.BBOX: + params.bbox = filter.value.toArray(); + break; + case OpenLayers.Filter.Spatial.DWITHIN: + params.tolerance = filter.distance; + // no break here + case OpenLayers.Filter.Spatial.WITHIN: + params.lon = filter.value.x; + params.lat = filter.value.y; + break; + default: + OpenLayers.Console.warn( + "Unknown spatial filter type " + filter.type); + } + break; + case "Comparison": + var op = OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR[filter.type]; + if(op !== undefined) { + var value = filter.value; + if(filter.type == OpenLayers.Filter.Comparison.LIKE) { + value = this.regex2value(value); + if(this.wildcarded) { + value = "%" + value + "%"; + } + } + params[filter.property + "__" + op] = value; + params.queryable = params.queryable || []; + params.queryable.push(filter.property); + } else { + OpenLayers.Console.warn( + "Unknown comparison filter type " + filter.type); + } + break; + case "Logical": + if(filter.type === OpenLayers.Filter.Logical.AND) { + for(var i=0,len=filter.filters.length; i