1 /* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
2 * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
3 * full text of the license. */
6 * @requires OpenLayers/Format/Filter.js
7 * @requires OpenLayers/Format/XML.js
11 * Class: OpenLayers.Format.Filter.v1
12 * Superclass for Filter version 1 parsers.
15 * - <OpenLayers.Format.XML>
17 OpenLayers.Format.Filter.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
20 * Property: namespaces
21 * {Object} Mapping of namespace aliases to namespace URIs.
24 ogc: "http://www.opengis.net/ogc",
25 gml: "http://www.opengis.net/gml",
26 xlink: "http://www.w3.org/1999/xlink",
27 xsi: "http://www.w3.org/2001/XMLSchema-instance"
31 * Property: defaultPrefix
36 * Property: schemaLocation
37 * {String} Schema location for a particular minor version.
42 * Constructor: OpenLayers.Format.Filter.v1
43 * Instances of this class are not created directly. Use the
44 * <OpenLayers.Format.Filter> constructor instead.
47 * options - {Object} An optional object whose properties will be set on
50 initialize: function(options) {
51 OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);
58 * data - {DOMElement} A Filter document element.
61 * {<OpenLayers.Filter>} A filter object.
63 read: function(data) {
65 this.readers.ogc["Filter"].apply(this, [data, obj]);
71 * Contains public functions, grouped by namespace prefix, that will
72 * be applied when a namespaced node is found matching the function
73 * name. The function will be applied in the scope of this parser
74 * with two arguments: the node being read and a context object passed
79 "Filter": function(node, parent) {
80 // Filters correspond to subclasses of OpenLayers.Filter.
81 // Since they contain information we don't persist, we
82 // create a temporary object and then pass on the filter
83 // (ogc:Filter) to the parent obj.
88 this.readChildNodes(node, obj);
89 if(obj.fids.length > 0) {
90 parent.filter = new OpenLayers.Filter.FeatureId({
93 } else if(obj.filters.length > 0) {
94 parent.filter = obj.filters[0];
97 "FeatureId": function(node, obj) {
98 var fid = node.getAttribute("fid");
103 "And": function(node, obj) {
104 var filter = new OpenLayers.Filter.Logical({
105 type: OpenLayers.Filter.Logical.AND
107 this.readChildNodes(node, filter);
108 obj.filters.push(filter);
110 "Or": function(node, obj) {
111 var filter = new OpenLayers.Filter.Logical({
112 type: OpenLayers.Filter.Logical.OR
114 this.readChildNodes(node, filter);
115 obj.filters.push(filter);
117 "Not": function(node, obj) {
118 var filter = new OpenLayers.Filter.Logical({
119 type: OpenLayers.Filter.Logical.NOT
121 this.readChildNodes(node, filter);
122 obj.filters.push(filter);
124 "PropertyIsLessThan": function(node, obj) {
125 var filter = new OpenLayers.Filter.Comparison({
126 type: OpenLayers.Filter.Comparison.LESS_THAN
128 this.readChildNodes(node, filter);
129 obj.filters.push(filter);
131 "PropertyIsGreaterThan": function(node, obj) {
132 var filter = new OpenLayers.Filter.Comparison({
133 type: OpenLayers.Filter.Comparison.GREATER_THAN
135 this.readChildNodes(node, filter);
136 obj.filters.push(filter);
138 "PropertyIsLessThanOrEqualTo": function(node, obj) {
139 var filter = new OpenLayers.Filter.Comparison({
140 type: OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO
142 this.readChildNodes(node, filter);
143 obj.filters.push(filter);
145 "PropertyIsGreaterThanOrEqualTo": function(node, obj) {
146 var filter = new OpenLayers.Filter.Comparison({
147 type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO
149 this.readChildNodes(node, filter);
150 obj.filters.push(filter);
152 "PropertyIsBetween": function(node, obj) {
153 var filter = new OpenLayers.Filter.Comparison({
154 type: OpenLayers.Filter.Comparison.BETWEEN
156 this.readChildNodes(node, filter);
157 obj.filters.push(filter);
159 "PropertyIsLike": function(node, obj) {
160 var filter = new OpenLayers.Filter.Comparison({
161 type: OpenLayers.Filter.Comparison.LIKE
163 this.readChildNodes(node, filter);
164 var wildCard = node.getAttribute("wildCard");
165 var singleChar = node.getAttribute("singleChar");
166 var esc = node.getAttribute("escape");
167 filter.value2regex(wildCard, singleChar, esc);
168 obj.filters.push(filter);
170 "Literal": function(node, obj) {
171 obj.value = OpenLayers.String.numericIf(
172 this.getChildValue(node));
174 "PropertyName": function(node, filter) {
175 filter.property = this.getChildValue(node);
177 "LowerBoundary": function(node, filter) {
178 filter.lowerBoundary = OpenLayers.String.numericIf(
179 this.readOgcExpression(node));
181 "UpperBoundary": function(node, filter) {
182 filter.upperBoundary = OpenLayers.String.numericIf(
183 this.readOgcExpression(node));
185 "Intersects": function(node, obj) {
186 this.readSpatial(node, obj, OpenLayers.Filter.Spatial.INTERSECTS);
188 "Within": function(node, obj) {
189 this.readSpatial(node, obj, OpenLayers.Filter.Spatial.WITHIN);
191 "Contains": function(node, obj) {
192 this.readSpatial(node, obj, OpenLayers.Filter.Spatial.CONTAINS);
194 "DWithin": function(node, obj) {
195 this.readSpatial(node, obj, OpenLayers.Filter.Spatial.DWITHIN);
197 "Distance": function(node, obj) {
198 obj.distance = parseInt(this.getChildValue(node));
199 obj.distanceUnits = node.getAttribute("units");
205 * Method: readSpatial
207 * Read a {<OpenLayers.Filter.Spatial>} filter.
210 * node - {DOMElement} A DOM element that contains an ogc:expression.
211 * obj - {Object} The target object.
212 * type - {String} One of the OpenLayers.Filter.Spatial.* constants.
215 * {<OpenLayers.Filter.Spatial>} The created filter.
217 readSpatial: function(node, obj, type) {
218 var filter = new OpenLayers.Filter.Spatial({
221 this.readChildNodes(node, filter);
222 filter.value = filter.components[0];
223 delete filter.components;
224 obj.filters.push(filter);
228 * Method: readOgcExpression
229 * Limited support for OGC expressions.
232 * node - {DOMElement} A DOM element that contains an ogc:expression.
235 * {String} A value to be used in a symbolizer.
237 readOgcExpression: function(node) {
239 this.readChildNodes(node, obj);
240 var value = obj.value;
242 value = this.getChildValue(node);
251 * filter - {<OpenLayers.Filter>} A filter object.
254 * {DOMElement} An ogc:Filter element.
256 write: function(filter) {
257 return this.writers.ogc["Filter"].apply(this, [filter]);
262 * As a compliment to the readers property, this structure contains public
263 * writing functions grouped by namespace alias and named like the
264 * node names they produce.
268 "Filter": function(filter) {
269 var node = this.createElementNSPlus("ogc:Filter");
270 var sub = filter.CLASS_NAME.split(".").pop();
271 if(sub == "FeatureId") {
272 for(var i=0; i<filter.fids.length; ++i) {
273 this.writeNode("FeatureId", filter.fids[i], node);
276 this.writeNode(this.getFilterType(filter), filter, node);
280 "FeatureId": function(fid) {
281 return this.createElementNSPlus("ogc:FeatureId", {
282 attributes: {fid: fid}
285 "And": function(filter) {
286 var node = this.createElementNSPlus("ogc:And");
288 for(var i=0; i<filter.filters.length; ++i) {
289 childFilter = filter.filters[i];
291 this.getFilterType(childFilter), childFilter, node
296 "Or": function(filter) {
297 var node = this.createElementNSPlus("ogc:Or");
299 for(var i=0; i<filter.filters.length; ++i) {
300 childFilter = filter.filters[i];
302 this.getFilterType(childFilter), childFilter, node
307 "Not": function(filter) {
308 var node = this.createElementNSPlus("ogc:Not");
309 var childFilter = filter.filters[0];
311 this.getFilterType(childFilter), childFilter, node
315 "PropertyIsLessThan": function(filter) {
316 var node = this.createElementNSPlus("ogc:PropertyIsLessThan");
317 // no ogc:expression handling for now
318 this.writeNode("PropertyName", filter, node);
319 this.writeNode("Literal", filter.value, node);
322 "PropertyIsGreaterThan": function(filter) {
323 var node = this.createElementNSPlus("ogc:PropertyIsGreaterThan");
324 // no ogc:expression handling for now
325 this.writeNode("PropertyName", filter, node);
326 this.writeNode("Literal", filter.value, node);
329 "PropertyIsLessThanOrEqualTo": function(filter) {
330 var node = this.createElementNSPlus("ogc:PropertyIsLessThanOrEqualTo");
331 // no ogc:expression handling for now
332 this.writeNode("PropertyName", filter, node);
333 this.writeNode("Literal", filter.value, node);
336 "PropertyIsGreaterThanOrEqualTo": function(filter) {
337 var node = this.createElementNSPlus("ogc:PropertyIsGreaterThanOrEqualTo");
338 // no ogc:expression handling for now
339 this.writeNode("PropertyName", filter, node);
340 this.writeNode("Literal", filter.value, node);
343 "PropertyIsBetween": function(filter) {
344 var node = this.createElementNSPlus("ogc:PropertyIsBetween");
345 // no ogc:expression handling for now
346 this.writeNode("PropertyName", filter, node);
347 this.writeNode("LowerBoundary", filter, node);
348 this.writeNode("UpperBoundary", filter, node);
351 "PropertyIsLike": function(filter) {
352 var node = this.createElementNSPlus("ogc:PropertyIsLike", {
354 wildCard: "*", singleChar: ".", escape: "!"
357 // no ogc:expression handling for now
358 this.writeNode("PropertyName", filter, node);
359 // convert regex string to ogc string
360 this.writeNode("Literal", filter.regex2value(), node);
363 "PropertyName": function(filter) {
364 // no ogc:expression handling for now
365 return this.createElementNSPlus("ogc:PropertyName", {
366 value: filter.property
369 "Literal": function(value) {
370 // no ogc:expression handling for now
371 return this.createElementNSPlus("ogc:Literal", {
375 "LowerBoundary": function(filter) {
376 // no ogc:expression handling for now
377 var node = this.createElementNSPlus("ogc:LowerBoundary");
378 this.writeNode("Literal", filter.lowerBoundary, node);
381 "UpperBoundary": function(filter) {
382 // no ogc:expression handling for now
383 var node = this.createElementNSPlus("ogc:UpperBoundary");
384 this.writeNode("Literal", filter.upperBoundary, node);
387 "INTERSECTS": function(filter) {
388 return this.writeSpatial(filter, "Intersects");
390 "WITHIN": function(filter) {
391 return this.writeSpatial(filter, "Within");
393 "CONTAINS": function(filter) {
394 return this.writeSpatial(filter, "Contains");
396 "DWITHIN": function(filter) {
397 var node = this.writeSpatial(filter, "DWithin");
398 this.writeNode("Distance", filter, node);
401 "Distance": function(filter) {
402 return this.createElementNSPlus("ogc:Distance", {
404 units: filter.distanceUnits
406 value: filter.distance
413 * Method: getFilterType
415 getFilterType: function(filter) {
416 var filterType = this.filterMap[filter.type];
418 throw "Filter writing not supported for rule type: " + filter.type;
424 * Property: filterMap
425 * {Object} Contains a member for each filter type. Values are node names
426 * for corresponding OGC Filter child elements.
432 "==": "PropertyIsEqualTo",
433 "!=": "PropertyIsNotEqualTo",
434 "<": "PropertyIsLessThan",
435 ">": "PropertyIsGreaterThan",
436 "<=": "PropertyIsLessThanOrEqualTo",
437 ">=": "PropertyIsGreaterThanOrEqualTo",
438 "..": "PropertyIsBetween",
439 "~": "PropertyIsLike",
441 "DWITHIN": "DWITHIN",
443 "CONTAINS": "CONTAINS",
444 "INTERSECTS": "INTERSECTS"
447 CLASS_NAME: "OpenLayers.Format.Filter.v1"