diff --git a/src/ol/expr/expression.js b/src/ol/expr/expression.js
index 81a511bc26..277364d750 100644
--- a/src/ol/expr/expression.js
+++ b/src/ol/expr/expression.js
@@ -97,7 +97,14 @@ ol.expr.lib = {};
ol.expr.functions = {
EXTENT: 'extent',
FID: 'fid',
- GEOMETRY_TYPE: 'geometryType'
+ GEOMETRY_TYPE: 'geometryType',
+ INTERSECTS: 'intersects',
+ CONTAINS: 'contains',
+ DWITHIN: 'dwithin',
+ WITHIN: 'within',
+ LIKE: 'like',
+ IEQ: 'ieq',
+ INEQ: 'ineq'
};
@@ -107,12 +114,16 @@ ol.expr.functions = {
* @param {number} maxX Maximum x-coordinate value.
* @param {number} minY Minimum y-coordinate value.
* @param {number} maxY Maximum y-coordinate value.
+ * @param {string=} opt_projection Projection of the extent.
+ * @param {string=} opt_attribute Name of the geometry attribute to use.
* @return {boolean} The provided extent intersects the feature's extent.
* @this {ol.Feature}
*/
-ol.expr.lib[ol.expr.functions.EXTENT] = function(minX, maxX, minY, maxY) {
+ol.expr.lib[ol.expr.functions.EXTENT] = function(minX, maxX, minY, maxY,
+ opt_projection, opt_attribute) {
var intersects = false;
- var geometry = this.getGeometry();
+ var geometry = goog.isDef(opt_attribute) ?
+ this.getAttributes()[opt_attribute] : this.getGeometry();
if (geometry) {
intersects = ol.extent.intersects(geometry.getBounds(),
[minX, maxX, minY, maxY]);
@@ -142,6 +153,75 @@ ol.expr.lib[ol.expr.functions.FID] = function(var_args) {
};
+/**
+ * Determine if a feature attribute is like the provided value.
+ * @param {string} attribute The name of the attribute to test for.
+ * @param {string} value The value to test for.
+ * @param {string} wildCard The wildcard character to use.
+ * @param {string} singleChar The single character to use.
+ * @param {string} escapeChar The escape character to use.
+ * @param {boolean} matchCase Should we match case or not?
+ * @this {ol.Feature}
+ */
+ol.expr.lib[ol.expr.functions.LIKE] = function(attribute, value, wildCard,
+ singleChar, escapeChar, matchCase) {
+ if (wildCard == '.') {
+ throw new Error('"." is an unsupported wildCard character for ' +
+ 'ol.filter.Comparison');
+ }
+ // set UMN MapServer defaults for unspecified parameters
+ wildCard = goog.isDef(wildCard) ? wildCard : '*';
+ singleChar = goog.isDef(singleChar) ? singleChar : '.';
+ escapeChar = goog.isDef(escapeChar) ? escapeChar : '!';
+ var val;
+ val = value.replace(
+ new RegExp('\\' + escapeChar + '(.|$)', 'g'), '\\$1');
+ val = value.replace(
+ new RegExp('\\' + singleChar, 'g'), '.');
+ val = value.replace(
+ new RegExp('\\' + wildCard, 'g'), '.*');
+ val = value.replace(
+ new RegExp('\\\\.\\*', 'g'), '\\' + wildCard);
+ val = value.replace(
+ new RegExp('\\\\\\.', 'g'), '\\' + singleChar);
+ var attributes = this.getAttributes();
+ var modifiers = (matchCase === false) ? 'gi' : 'g';
+ return new RegExp(val, modifiers).test(attributes[attribute]);
+};
+
+
+/**
+ * Case insensitive comparison for equality.
+ * @param {string} attribute Name of the attribute.
+ * @param {string} value Value to test for equality.
+ * @this {ol.Feature}
+ */
+ol.expr.lib[ol.expr.functions.IEQ] = function(attribute, value) {
+ var attributes = this.getAttributes();
+ if (goog.isString(value) && goog.isString(attributes[attribute])) {
+ return value.toUpperCase() == attributes[attribute].toUpperCase();
+ } else {
+ return value == attributes[attribute];
+ }
+};
+
+
+/**
+ * Case insensitive comparison for non-equality.
+ * @param {string} attribute Name of the attribute.
+ * @param {string} value Value to test for non-equality.
+ * @this {ol.Feature}
+ */
+ol.expr.lib[ol.expr.functions.INEQ] = function(attribute, value) {
+ var attributes = this.getAttributes();
+ if (goog.isString(value) && goog.isString(attributes[attribute])) {
+ return value.toUpperCase() == attributes[attribute].toUpperCase();
+ } else {
+ return value != attributes[attribute];
+ }
+};
+
+
/**
* Determine if a feature's default geometry is of the given type.
* @param {ol.geom.GeometryType} type Geometry type.
@@ -156,3 +236,31 @@ ol.expr.lib[ol.expr.functions.GEOMETRY_TYPE] = function(type) {
}
return same;
};
+
+
+ol.expr.lib[ol.expr.functions.INTERSECTS] = function(geom, opt_projection,
+ opt_attribute) {
+ throw new Error('Spatial function not implemented: ' +
+ ol.expr.functions.INTERSECTS);
+};
+
+
+ol.expr.lib[ol.expr.functions.WITHIN] = function(geom, opt_projection,
+ opt_attribute) {
+ throw new Error('Spatial function not implemented: ' +
+ ol.expr.functions.WITHIN);
+};
+
+
+ol.expr.lib[ol.expr.functions.CONTAINS] = function(geom, opt_projeciton,
+ opt_attribute) {
+ throw new Error('Spatial function not implemented: ' +
+ ol.expr.functions.CONTAINS);
+};
+
+
+ol.expr.lib[ol.expr.functions.DWITHIN] = function(geom, distance, units,
+ opt_projection, opt_attribute) {
+ throw new Error('Spatial function not implemented: ' +
+ ol.expr.functions.DWITHIN);
+};
diff --git a/src/ol/parser/ogc/filter.js b/src/ol/parser/ogc/filter.js
new file mode 100644
index 0000000000..6f1aece8fa
--- /dev/null
+++ b/src/ol/parser/ogc/filter.js
@@ -0,0 +1,37 @@
+goog.provide('ol.parser.ogc.Filter');
+goog.require('ol.parser.ogc.Filter_v1_0_0');
+goog.require('ol.parser.ogc.Filter_v1_1_0');
+goog.require('ol.parser.ogc.Versioned');
+
+
+/**
+ * @define {boolean} Whether to enable OGC Filter version 1.0.0.
+ */
+ol.ENABLE_OGCFILTER_1_0_0 = true;
+
+
+/**
+ * @define {boolean} Whether to enable OGC Filter version 1.1.0.
+ */
+ol.ENABLE_OGCFILTER_1_1_0 = true;
+
+
+
+/**
+ * @constructor
+ * @param {Object=} opt_options Options which will be set on this object.
+ * @extends {ol.parser.ogc.Versioned}
+ */
+ol.parser.ogc.Filter = function(opt_options) {
+ opt_options = opt_options || {};
+ opt_options['defaultVersion'] = '1.0.0';
+ this.parsers = {};
+ if (ol.ENABLE_OGCFILTER_1_0_0) {
+ this.parsers['v1_0_0'] = ol.parser.ogc.Filter_v1_0_0;
+ }
+ if (ol.ENABLE_OGCFILTER_1_1_0) {
+ this.parsers['v1_1_0'] = ol.parser.ogc.Filter_v1_1_0;
+ }
+ goog.base(this, opt_options);
+};
+goog.inherits(ol.parser.ogc.Filter, ol.parser.ogc.Versioned);
diff --git a/src/ol/parser/ogc/filter_v1.js b/src/ol/parser/ogc/filter_v1.js
new file mode 100644
index 0000000000..4b7f1063ec
--- /dev/null
+++ b/src/ol/parser/ogc/filter_v1.js
@@ -0,0 +1,582 @@
+goog.provide('ol.parser.ogc.Filter_v1');
+goog.require('goog.array');
+goog.require('goog.dom.xml');
+goog.require('goog.string');
+goog.require('ol.expr');
+goog.require('ol.expr.Call');
+goog.require('ol.expr.Comparison');
+goog.require('ol.expr.ComparisonOp');
+goog.require('ol.expr.Identifier');
+goog.require('ol.expr.Logical');
+goog.require('ol.expr.LogicalOp');
+goog.require('ol.expr.Not');
+goog.require('ol.expr.functions');
+goog.require('ol.parser.XML');
+
+
+
+/**
+ * @constructor
+ * @extends {ol.parser.XML}
+ */
+ol.parser.ogc.Filter_v1 = function() {
+ this.defaultNamespaceURI = 'http://www.opengis.net/ogc';
+ this.errorProperty = 'filter';
+ this.readers = {
+ 'http://www.opengis.net/ogc': {
+ '_expression': function(node) {
+ // only the simplest of ogc:expression handled
+ // "some text and an attribute"
+ var obj, value = '';
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ switch (child.nodeType) {
+ case 1:
+ obj = this.readNode(child);
+ if (obj['property']) {
+ value += obj['property'];
+ } else if (goog.isDef(obj['value'])) {
+ value += obj['value'];
+ }
+ break;
+ case 3: // text node
+ case 4: // cdata section
+ value += child.nodeValue;
+ break;
+ default:
+ break;
+ }
+ }
+ return value;
+ },
+ 'Filter': function(node, obj) {
+ var container = {
+ 'filters': []
+ };
+ this.readChildNodes(node, container);
+ if (goog.isDef(container['fids'])) {
+ obj['filter'] = new ol.expr.Call(
+ new ol.expr.Identifier(ol.expr.functions.FID),
+ container['fids']);
+ } else if (container['filters'].length > 0) {
+ obj['filter'] = container['filters'][0];
+ }
+ },
+ 'FeatureId': function(node, obj) {
+ var fid = node.getAttribute('fid');
+ if (fid) {
+ if (!goog.isDef(obj['fids'])) {
+ obj['fids'] = {};
+ }
+ obj['fids'][fid] = true;
+ }
+ },
+ 'And': function(node, obj) {
+ var container = {'filters': []};
+ this.readChildNodes(node, container);
+ var filter = this.aggregateLogical_(container['filters'],
+ ol.expr.LogicalOp.AND);
+ obj['filters'].push(filter);
+ },
+ 'Or': function(node, obj) {
+ var container = {'filters': []};
+ this.readChildNodes(node, container);
+ var filter = this.aggregateLogical_(container['filters'],
+ ol.expr.LogicalOp.OR);
+ obj['filters'].push(filter);
+ },
+ 'Not': function(node, obj) {
+ var container = {'filters': []};
+ this.readChildNodes(node, container);
+ // Not is unary so can only contain 1 child filter
+ obj['filters'].push(new ol.expr.Not(
+ container.filters[0]));
+ },
+ 'PropertyIsNull': function(node, obj) {
+ var container = {};
+ this.readChildNodes(node, container);
+ obj['filters'].push(new ol.expr.Comparison(
+ ol.expr.ComparisonOp.EQ,
+ container['property'],
+ null));
+ },
+ 'PropertyIsLessThan': function(node, obj) {
+ var container = {};
+ this.readChildNodes(node, container);
+ obj['filters'].push(new ol.expr.Comparison(
+ ol.expr.ComparisonOp.LT,
+ container['property'],
+ container['value']));
+ },
+ 'PropertyIsGreaterThan': function(node, obj) {
+ var container = {};
+ this.readChildNodes(node, container);
+ obj['filters'].push(new ol.expr.Comparison(
+ ol.expr.ComparisonOp.GT,
+ container['property'],
+ container['value']));
+ },
+ 'PropertyIsLessThanOrEqualTo': function(node, obj) {
+ var container = {};
+ this.readChildNodes(node, container);
+ obj['filters'].push(new ol.expr.Comparison(
+ ol.expr.ComparisonOp.LTE,
+ container['property'],
+ container['value']));
+ },
+ 'PropertyIsGreaterThanOrEqualTo': function(node, obj) {
+ var container = {};
+ this.readChildNodes(node, container);
+ obj['filters'].push(new ol.expr.Comparison(
+ ol.expr.ComparisonOp.GTE,
+ container['property'],
+ container['value']));
+ },
+ 'PropertyIsBetween': function(node, obj) {
+ var container = {};
+ this.readChildNodes(node, container);
+ obj['filters'].push(new ol.expr.Logical(ol.expr.LogicalOp.AND,
+ new ol.expr.Comparison(ol.expr.ComparisonOp.GTE,
+ container['property'], container['lowerBoundary']),
+ new ol.expr.Comparison(ol.expr.ComparisonOp.LTE,
+ container['property'], container['upperBoundary'])));
+ },
+ 'Literal': function(node, obj) {
+ var nodeValue = this.getChildValue(node);
+ var value = goog.string.toNumber(nodeValue);
+ obj['value'] = isNaN(value) ? nodeValue : value;
+ },
+ 'PropertyName': function(node, obj) {
+ obj['property'] = this.getChildValue(node);
+ },
+ 'LowerBoundary': function(node, obj) {
+ var readers = this.readers[this.defaultNamespaceURI];
+ obj['lowerBoundary'] = goog.string.toNumber(
+ readers['_expression'].call(this, node));
+ },
+ 'UpperBoundary': function(node, obj) {
+ var readers = this.readers[this.defaultNamespaceURI];
+ obj['upperBoundary'] = goog.string.toNumber(
+ readers['_expression'].call(this, node));
+ },
+ '_spatial': function(node, obj, identifier) {
+ var args = [], container = {};
+ this.readChildNodes(node, container);
+ if (goog.isDef(container.geometry)) {
+ args.push(this.gml_.createGeometry(container));
+ } else {
+ args = container['bounds'];
+ }
+ if (goog.isDef(container['distance'])) {
+ args.push(container['distance']);
+ }
+ if (goog.isDef(container['distanceUnits'])) {
+ args.push(container['distanceUnits']);
+ }
+ args.push(container['projection']);
+ if (goog.isDef(container['property'])) {
+ args.push(container['property']);
+ }
+ obj['filters'].push(new ol.expr.Call(new ol.expr.Identifier(
+ identifier), args));
+ },
+ 'BBOX': function(node, obj) {
+ var readers = this.readers[this.defaultNamespaceURI];
+ readers['_spatial'].call(this, node, obj,
+ ol.expr.functions.EXTENT);
+ },
+ 'Intersects': function(node, obj) {
+ var readers = this.readers[this.defaultNamespaceURI];
+ readers['_spatial'].call(this, node, obj,
+ ol.expr.functions.INTERSECTS);
+ },
+ 'Within': function(node, obj) {
+ var readers = this.readers[this.defaultNamespaceURI];
+ readers['_spatial'].call(this, node, obj,
+ ol.expr.functions.WITHIN);
+ },
+ 'Contains': function(node, obj) {
+ var readers = this.readers[this.defaultNamespaceURI];
+ readers['_spatial'].call(this, node, obj,
+ ol.expr.functions.CONTAINS);
+ },
+ 'DWithin': function(node, obj) {
+ var readers = this.readers[this.defaultNamespaceURI];
+ readers['_spatial'].call(this, node, obj,
+ ol.expr.functions.DWITHIN);
+ },
+ 'Distance': function(node, obj) {
+ obj['distance'] = parseInt(this.getChildValue(node), 10);
+ obj['distanceUnits'] = node.getAttribute('units');
+ }
+ }
+ };
+ this.writers = {
+ 'http://www.opengis.net/ogc': {
+ 'Filter': function(filter) {
+ var node = this.createElementNS('ogc:Filter');
+ this.writeNode(this.getFilterType_(filter), filter, null, node);
+ return node;
+ },
+ '_featureIds': function(filter) {
+ var node = this.createDocumentFragment();
+ var fids = filter.getArgs();
+ for (var i = 0, ii = fids.length; i < ii; i++) {
+ this.writeNode('FeatureId', fids[i], null, node);
+ }
+ return node;
+ },
+ 'FeatureId': function(fid) {
+ var node = this.createElementNS('ogc:FeatureId');
+ node.setAttribute('fid', fid);
+ return node;
+ },
+ 'And': function(filter) {
+ var node = this.createElementNS('ogc:And');
+ var subFilters = [];
+ this.getSubfiltersForLogical_(filter, subFilters);
+ for (var i = 0, ii = subFilters.length; i < ii; ++i) {
+ var subFilter = subFilters[i];
+ if (goog.isDefAndNotNull(subFilter)) {
+ this.writeNode(this.getFilterType_(subFilter), subFilter,
+ null, node);
+ }
+ }
+ return node;
+ },
+ 'Or': function(filter) {
+ var node = this.createElementNS('ogc:Or');
+ var subFilters = [];
+ this.getSubfiltersForLogical_(filter, subFilters);
+ for (var i = 0, ii = subFilters.length; i < ii; ++i) {
+ var subFilter = subFilters[i];
+ if (goog.isDefAndNotNull(subFilter)) {
+ this.writeNode(this.getFilterType_(subFilter), subFilter,
+ null, node);
+ }
+ }
+ return node;
+ },
+ 'Not': function(filter) {
+ var node = this.createElementNS('ogc:Not');
+ var childFilter = filter.getArgument();
+ this.writeNode(this.getFilterType_(childFilter), childFilter, null,
+ node);
+ return node;
+ },
+ 'PropertyIsLessThan': function(filter) {
+ var node = this.createElementNS('ogc:PropertyIsLessThan');
+ this.writeNode('PropertyName', filter.getLeft(), null, node);
+ this.writeOgcExpression(filter.getRight(), node);
+ return node;
+ },
+ 'PropertyIsGreaterThan': function(filter) {
+ var node = this.createElementNS('ogc:PropertyIsGreaterThan');
+ this.writeNode('PropertyName', filter.getLeft(), null, node);
+ this.writeOgcExpression(filter.getRight(), node);
+ return node;
+ },
+ 'PropertyIsLessThanOrEqualTo': function(filter) {
+ var node = this.createElementNS('ogc:PropertyIsLessThanOrEqualTo');
+ this.writeNode('PropertyName', filter.getLeft(), null, node);
+ this.writeOgcExpression(filter.getRight(), node);
+ return node;
+ },
+ 'PropertyIsGreaterThanOrEqualTo': function(filter) {
+ var node = this.createElementNS('ogc:PropertyIsGreaterThanOrEqualTo');
+ this.writeNode('PropertyName', filter.getLeft(), null, node);
+ this.writeOgcExpression(filter.getRight(), node);
+ return node;
+ },
+ 'PropertyIsBetween': function(filter) {
+ var node = this.createElementNS('ogc:PropertyIsBetween');
+ var property = filter.getLeft().getLeft();
+ this.writeNode('PropertyName', property, null, node);
+ var lower, upper;
+ var filters = new Array(2);
+ filters[0] = filter.getLeft();
+ filters[1] = filter.getRight();
+ for (var i = 0; i < 2; ++i) {
+ var value = filters[i].getRight();
+ if (filters[i].getOperator() === ol.expr.ComparisonOp.GTE) {
+ lower = value;
+ } else if (filters[i].getOperator() === ol.expr.ComparisonOp.LTE) {
+ upper = value;
+ }
+ }
+ this.writeNode('LowerBoundary', lower, null, node);
+ this.writeNode('UpperBoundary', upper, null, node);
+ return node;
+ },
+ 'PropertyName': function(name) {
+ var node = this.createElementNS('ogc:PropertyName');
+ node.appendChild(this.createTextNode(name));
+ return node;
+ },
+ 'Literal': function(value) {
+ if (value instanceof Date) {
+ value = value.toISOString();
+ }
+ var node = this.createElementNS('ogc:Literal');
+ node.appendChild(this.createTextNode(value));
+ return node;
+ },
+ 'LowerBoundary': function(value) {
+ var node = this.createElementNS('ogc:LowerBoundary');
+ this.writeOgcExpression(value, node);
+ return node;
+ },
+ 'UpperBoundary': function(value) {
+ var node = this.createElementNS('ogc:UpperBoundary');
+ this.writeOgcExpression(value, node);
+ return node;
+ },
+ 'INTERSECTS': function(filter) {
+ return this.writeSpatial_(filter, 'Intersects');
+ },
+ 'WITHIN': function(filter) {
+ return this.writeSpatial_(filter, 'Within');
+ },
+ 'CONTAINS': function(filter) {
+ return this.writeSpatial_(filter, 'Contains');
+ },
+ 'DWITHIN': function(filter) {
+ var node = this.writeSpatial_(filter, 'DWithin');
+ this.writeNode('Distance', filter, null, node);
+ return node;
+ },
+ 'Distance': function(filter) {
+ var node = this.createElementNS('ogc:Distance');
+ var args = filter.getArgs();
+ node.setAttribute('units', args[2]);
+ node.appendChild(this.createTextNode(args[1]));
+ return node;
+ },
+ 'Function': function(filter) {
+ var node = this.createElementNS('ogc:Function');
+ node.setAttribute('name', filter.getCallee().getName());
+ var params = filter.getArgs();
+ for (var i = 0, len = params.length; i < len; i++) {
+ this.writeOgcExpression(params[i], node);
+ }
+ return node;
+ },
+ 'PropertyIsNull': function(filter) {
+ var node = this.createElementNS('ogc:PropertyIsNull');
+ this.writeNode('PropertyName', filter.getLeft(), null, node);
+ return node;
+ }
+ }
+ };
+ this.filterMap_ = {
+ '&&': 'And',
+ '||': 'Or',
+ '!': 'Not',
+ '==': 'PropertyIsEqualTo',
+ '!=': 'PropertyIsNotEqualTo',
+ '<': 'PropertyIsLessThan',
+ '>': 'PropertyIsGreaterThan',
+ '<=': 'PropertyIsLessThanOrEqualTo',
+ '>=': 'PropertyIsGreaterThanOrEqualTo',
+ '..': 'PropertyIsBetween',
+ '~': 'PropertyIsLike',
+ 'NULL': 'PropertyIsNull',
+ 'BBOX': 'BBOX',
+ 'DWITHIN': 'DWITHIN',
+ 'WITHIN': 'WITHIN',
+ 'CONTAINS': 'CONTAINS',
+ 'INTERSECTS': 'INTERSECTS',
+ 'FID': '_featureIds'
+ };
+ goog.base(this);
+};
+goog.inherits(ol.parser.ogc.Filter_v1, ol.parser.XML);
+
+
+/**
+ * @param {ol.expr.Expression} filter The filter to determine the type of.
+ * @return {string} The type of filter.
+ * @private
+ */
+ol.parser.ogc.Filter_v1.prototype.getFilterType_ = function(filter) {
+ var type;
+ if (filter instanceof ol.expr.Logical ||
+ filter instanceof ol.expr.Comparison) {
+ type = filter.getOperator();
+ var isNull = (type === ol.expr.ComparisonOp.EQ &&
+ filter.getRight() === null);
+ if (isNull) {
+ type = 'NULL';
+ }
+ var isBetween = (type === ol.expr.LogicalOp.AND &&
+ filter.getLeft() instanceof ol.expr.Comparison &&
+ filter.getRight() instanceof ol.expr.Comparison &&
+ filter.getLeft().getLeft() === filter.getRight().getLeft() &&
+ (filter.getLeft().getOperator() === ol.expr.ComparisonOp.LTE ||
+ filter.getLeft().getOperator() === ol.expr.ComparisonOp.GTE) &&
+ (filter.getRight().getOperator() === ol.expr.ComparisonOp.LTE ||
+ filter.getRight().getOperator() === ol.expr.ComparisonOp.GTE));
+ if (isBetween) {
+ type = '..';
+ }
+ } else if (filter instanceof ol.expr.Call) {
+ var callee = filter.getCallee().getName();
+ if (callee === ol.expr.functions.FID) {
+ type = 'FID';
+ }
+ else if (callee === ol.expr.functions.IEQ) {
+ type = '==';
+ } else if (callee === ol.expr.functions.INEQ) {
+ type = '!=';
+ }
+ else if (callee === ol.expr.functions.LIKE) {
+ type = '~';
+ }
+ else if (callee === ol.expr.functions.CONTAINS) {
+ type = 'CONTAINS';
+ } else if (callee === ol.expr.functions.WITHIN) {
+ type = 'WITHIN';
+ } else if (callee === ol.expr.functions.DWITHIN) {
+ type = 'DWITHIN';
+ } else if (callee === ol.expr.functions.EXTENT) {
+ type = 'BBOX';
+ } else if (callee === ol.expr.functions.INTERSECTS) {
+ type = 'INTERSECTS';
+ }
+ } else if (filter instanceof ol.expr.Not) {
+ type = '!';
+ }
+ var filterType = this.filterMap_[type];
+ if (!filterType) {
+ throw new Error('Filter writing not supported for rule type: ' + type);
+ }
+ return filterType;
+};
+
+
+/**
+ * @param {string|Document|Element} data Data to read.
+ * @return {Object} An object representing the document.
+ */
+ol.parser.ogc.Filter_v1.prototype.read = function(data) {
+ if (goog.isString(data)) {
+ data = goog.dom.xml.loadXml(data);
+ }
+ if (data && data.nodeType == 9) {
+ data = data.documentElement;
+ }
+ var obj = {};
+ this.readNode(data, obj);
+ return obj['filter'];
+};
+
+
+/**
+ * @param {ol.expr.Expression} filter The filter to write out.
+ * @return {string} The serialized filter.
+ */
+ol.parser.ogc.Filter_v1.prototype.write = function(filter) {
+ var root = this.writeNode('Filter', filter);
+ this.setAttributeNS(
+ root, 'http://www.w3.org/2001/XMLSchema-instance',
+ 'xsi:schemaLocation', this.schemaLocation);
+ return this.serialize(root);
+};
+
+
+/**
+ * @param {ol.expr.Call|string|number} value The value write out.
+ * @param {Element} node The node to append to.
+ * @return {Element} The node to which was appended.
+ * @protected
+ */
+ol.parser.ogc.Filter_v1.prototype.writeOgcExpression = function(value, node) {
+ if (value instanceof ol.expr.Call) {
+ this.writeNode('Function', value, null, node);
+ } else {
+ this.writeNode('Literal', value, null, node);
+ }
+ return node;
+};
+
+
+/**
+ * @param {ol.expr.Logical} filter The filter to retrieve the sub filters from.
+ * @param {Array.
} subFilters The sub filters retrieved.
+ * @private
+ */
+ol.parser.ogc.Filter_v1.prototype.getSubfiltersForLogical_ = function(filter,
+ subFilters) {
+ var operator = filter.getOperator();
+ var filters = new Array(2);
+ filters[0] = filter.getLeft();
+ filters[1] = filter.getRight();
+ for (var i = 0; i < 2; ++i) {
+ if (filters[i] instanceof ol.expr.Logical && filters[i].getOperator() ===
+ operator) {
+ this.getSubfiltersForLogical_(filters[i], subFilters);
+ } else {
+ subFilters.push(filters[i]);
+ }
+ }
+};
+
+
+/**
+ * Since ol.expr.Logical can only have a left and a right, we need to nest
+ * sub filters coming from OGC Filter.
+ * @param {Array.} filters The filters to aggregate.
+ * @param {ol.expr.LogicalOp} operator The logical operator to use.
+ * @return {ol.expr.Logical} The logical filter created.
+ * @private
+ */
+ol.parser.ogc.Filter_v1.prototype.aggregateLogical_ = function(filters,
+ operator) {
+ var subFilters = [];
+ var newFilters = [];
+ // we only need to do this if we have more than 2 items
+ if (filters.length > 2) {
+ while (filters.length) {
+ subFilters.push(filters.pop());
+ if (subFilters.length === 2) {
+ newFilters.push(new ol.expr.Logical(operator,
+ subFilters[0], subFilters[1]));
+ goog.array.clear(subFilters);
+ }
+ }
+ // there could be a single item left now
+ if (subFilters.length === 1) {
+ newFilters.push(subFilters[0]);
+ }
+ return this.aggregateLogical_(newFilters, operator);
+ } else {
+ return new ol.expr.Logical(operator, filters[0], filters[1]);
+ }
+};
+
+
+/**
+ * @param {ol.parser.ogc.GML_v2|ol.parser.ogc.GML_v3} gml The GML parser to
+ * use.
+ * @protected
+ */
+ol.parser.ogc.Filter_v1.prototype.setGmlParser = function(gml) {
+ this.gml_ = gml;
+ for (var uri in this.gml_.readers) {
+ for (var key in this.gml_.readers[uri]) {
+ if (!goog.isDef(this.readers[uri])) {
+ this.readers[uri] = {};
+ }
+ this.readers[uri][key] = goog.bind(this.gml_.readers[uri][key],
+ this.gml_);
+ }
+ }
+ for (uri in this.gml_.writers) {
+ for (key in this.gml_.writers[uri]) {
+ if (!goog.isDef(this.writers[uri])) {
+ this.writers[uri] = {};
+ }
+ this.writers[uri][key] = goog.bind(this.gml_.writers[uri][key],
+ this.gml_);
+ }
+ }
+};
diff --git a/src/ol/parser/ogc/filter_v1_0_0.js b/src/ol/parser/ogc/filter_v1_0_0.js
new file mode 100644
index 0000000000..7bbc07f568
--- /dev/null
+++ b/src/ol/parser/ogc/filter_v1_0_0.js
@@ -0,0 +1,167 @@
+goog.provide('ol.parser.ogc.Filter_v1_0_0');
+
+goog.require('goog.object');
+goog.require('ol.expr');
+goog.require('ol.expr.Call');
+goog.require('ol.expr.Comparison');
+goog.require('ol.expr.ComparisonOp');
+goog.require('ol.expr.Identifier');
+goog.require('ol.expr.functions');
+goog.require('ol.geom.Geometry');
+goog.require('ol.parser.ogc.Filter_v1');
+goog.require('ol.parser.ogc.GML_v2');
+
+
+
+/**
+ * @constructor
+ * @extends {ol.parser.ogc.Filter_v1}
+ */
+ol.parser.ogc.Filter_v1_0_0 = function() {
+ goog.base(this);
+ this.version = '1.0.0';
+ this.schemaLocation = 'http://www.opengis.net/ogc ' +
+ 'http://schemas.opengis.net/filter/1.0.0/filter.xsd';
+ goog.object.extend(this.readers['http://www.opengis.net/ogc'], {
+ 'PropertyIsEqualTo': function(node, obj) {
+ var container = {};
+ this.readChildNodes(node, container);
+ obj['filters'].push(new ol.expr.Comparison(
+ ol.expr.ComparisonOp.EQ,
+ container['property'],
+ container['value']));
+ },
+ 'PropertyIsNotEqualTo': function(node, obj) {
+ var container = {};
+ this.readChildNodes(node, container);
+ obj['filters'].push(new ol.expr.Comparison(
+ ol.expr.ComparisonOp.NEQ,
+ container['property'],
+ container['value']));
+ },
+ 'PropertyIsLike': function(node, obj) {
+ var container = {};
+ this.readChildNodes(node, container);
+ var args = [];
+ args.push(container['property'], container['value'],
+ node.getAttribute('wildCard'),
+ node.getAttribute('singleChar'),
+ node.getAttribute('escape')
+ );
+ obj['filters'].push(new ol.expr.Call(
+ new ol.expr.Identifier(ol.expr.functions.LIKE), args));
+ }
+ });
+ goog.object.extend(this.writers['http://www.opengis.net/ogc'], {
+ 'PropertyIsEqualTo': function(filter) {
+ var node = this.createElementNS('ogc:PropertyIsEqualTo');
+ var property = filter.getLeft();
+ if (goog.isDef(property)) {
+ this.writeNode('PropertyName', property, null, node);
+ }
+ this.writeOgcExpression(filter.getRight(), node);
+ return node;
+ },
+ 'PropertyIsNotEqualTo': function(filter) {
+ var node = this.createElementNS('ogc:PropertyIsNotEqualTo');
+ var property = filter.getLeft();
+ if (goog.isDef(property)) {
+ this.writeNode('PropertyName', property, null, node);
+ }
+ this.writeOgcExpression(filter.getRight(), node);
+ return node;
+ },
+ 'PropertyIsLike': function(filter) {
+ var node = this.createElementNS('ogc:PropertyIsLike');
+ var args = filter.getArgs();
+ node.setAttribute('wildCard', args[2]);
+ node.setAttribute('singleChar', args[3]);
+ node.setAttribute('escape', args[4]);
+ var property = args[0];
+ if (goog.isDef(property)) {
+ this.writeNode('PropertyName', property, null, node);
+ }
+ this.writeNode('Literal', args[1], null, node);
+ return node;
+ },
+ 'BBOX': function(filter) {
+ var node = this.createElementNS('ogc:BBOX');
+ var args = filter.getArgs();
+ var property = args[5], bbox = [args[0], args[1], args[2], args[3]],
+ projection = args[4];
+ // PropertyName is mandatory in 1.0.0, but e.g. GeoServer also
+ // accepts filters without it.
+ if (goog.isDefAndNotNull(property)) {
+ this.writeNode('PropertyName', property, null, node);
+ }
+ var box = this.writeNode('Box', bbox,
+ 'http://www.opengis.net/gml');
+ if (goog.isDefAndNotNull(projection)) {
+ box.setAttribute('srsName', projection);
+ }
+ node.appendChild(box);
+ return node;
+ }
+ });
+ this.setGmlParser(new ol.parser.ogc.GML_v2({featureNS: 'http://foo'}));
+};
+goog.inherits(ol.parser.ogc.Filter_v1_0_0,
+ ol.parser.ogc.Filter_v1);
+
+
+/**
+ * @param {ol.expr.Call} filter The filter to write out.
+ * @param {string} name The name of the spatial operator.
+ * @return {Element} The node created.
+ * @private
+ */
+ol.parser.ogc.Filter_v1_0_0.prototype.writeSpatial_ = function(filter, name) {
+ var node = this.createElementNS('ogc:' + name);
+ var args = filter.getArgs();
+ var property, geom = null, bbox, call, projection;
+ if (goog.isNumber(args[0])) {
+ bbox = [args[0], args[1], args[2], args[3]];
+ projection = args[4];
+ property = args[5];
+ } else if (args[0] instanceof ol.geom.Geometry) {
+ geom = args[0];
+ if (name === 'DWithin') {
+ projection = args[3];
+ property = args[4];
+ } else {
+ projection = args[1];
+ property = args[2];
+ }
+ } else if (args[0] instanceof ol.expr.Call) {
+ call = args[0];
+ if (name === 'DWithin') {
+ projection = args[3];
+ property = args[4];
+ } else {
+ projection = args[1];
+ property = args[2];
+ }
+ }
+ if (goog.isDefAndNotNull(property)) {
+ this.writeNode('PropertyName', property, null, node);
+ }
+ if (goog.isDef(call)) {
+ this.writeNode('Function', call, null, node);
+ } else {
+ var child;
+ if (geom !== null) {
+ child = this.writeNode('_geometry', geom,
+ this.gml_.featureNS).firstChild;
+ } else if (bbox.length === 4) {
+ child = this.writeNode('Box', bbox,
+ 'http://www.opengis.net/gml');
+ }
+ if (goog.isDef(child)) {
+ if (goog.isDef(projection)) {
+ child.setAttribute('srsName', projection);
+ }
+ node.appendChild(child);
+ }
+ }
+ return node;
+};
diff --git a/src/ol/parser/ogc/filter_v1_1_0.js b/src/ol/parser/ogc/filter_v1_1_0.js
new file mode 100644
index 0000000000..6cfa18ed44
--- /dev/null
+++ b/src/ol/parser/ogc/filter_v1_1_0.js
@@ -0,0 +1,217 @@
+goog.provide('ol.parser.ogc.Filter_v1_1_0');
+
+goog.require('goog.object');
+goog.require('ol.expr');
+goog.require('ol.expr.Call');
+goog.require('ol.expr.Comparison');
+goog.require('ol.expr.ComparisonOp');
+goog.require('ol.expr.Identifier');
+goog.require('ol.expr.functions');
+goog.require('ol.geom.Geometry');
+goog.require('ol.parser.ogc.Filter_v1');
+goog.require('ol.parser.ogc.GML_v3');
+
+
+
+/**
+ * @constructor
+ * @extends {ol.parser.ogc.Filter_v1}
+ */
+ol.parser.ogc.Filter_v1_1_0 = function() {
+ goog.base(this);
+ this.version = '1.1.0';
+ this.schemaLocation = 'http://www.opengis.net/ogc ' +
+ 'http://schemas.opengis.net/filter/1.1.0/filter.xsd';
+ goog.object.extend(this.readers['http://www.opengis.net/ogc'], {
+ 'PropertyIsEqualTo': function(node, obj) {
+ var matchCase = node.getAttribute('matchCase');
+ var container = {}, filter;
+ this.readChildNodes(node, container);
+ if (matchCase === 'false' || matchCase === '0') {
+ filter = new ol.expr.Call(new ol.expr.Identifier(ol.expr.functions.IEQ),
+ [container['property'], container['value']]);
+ } else {
+ filter = new ol.expr.Comparison(
+ ol.expr.ComparisonOp.EQ,
+ container['property'],
+ container['value']);
+ }
+ obj['filters'].push(filter);
+ },
+ 'PropertyIsNotEqualTo': function(node, obj) {
+ var matchCase = node.getAttribute('matchCase');
+ var container = {}, filter;
+ this.readChildNodes(node, container);
+ if (matchCase === 'false' || matchCase === '0') {
+ filter = new ol.expr.Call(new ol.expr.Identifier(
+ ol.expr.functions.INEQ),
+ [container['property'], container['value']]);
+ } else {
+ filter = new ol.expr.Comparison(
+ ol.expr.ComparisonOp.NEQ,
+ container['property'],
+ container['value']);
+ }
+ obj['filters'].push(filter);
+ },
+ 'PropertyIsLike': function(node, obj) {
+ var container = {};
+ this.readChildNodes(node, container);
+ var args = [];
+ args.push(container['property'], container['value'],
+ node.getAttribute('wildCard'),
+ node.getAttribute('singleChar'),
+ node.getAttribute('escapeChar'),
+ node.getAttribute('matchCase'));
+ obj['filters'].push(new ol.expr.Call(
+ new ol.expr.Identifier(ol.expr.functions.LIKE), args));
+ }
+ });
+ goog.object.extend(this.writers['http://www.opengis.net/ogc'], {
+ 'PropertyIsEqualTo': function(filter) {
+ var node = this.createElementNS('ogc:PropertyIsEqualTo');
+ var property, value;
+ if (filter instanceof ol.expr.Call) {
+ var args = filter.getArgs();
+ property = args[0];
+ value = args[1];
+ node.setAttribute('matchCase', false);
+ } else {
+ property = filter.getLeft();
+ value = filter.getRight();
+ }
+ this.writeNode('PropertyName', property, null, node);
+ this.writeOgcExpression(value, node);
+ return node;
+ },
+ 'PropertyIsNotEqualTo': function(filter) {
+ var node = this.createElementNS('ogc:PropertyIsNotEqualTo');
+ var property, value;
+ if (filter instanceof ol.expr.Call) {
+ var args = filter.getArgs();
+ property = args[0];
+ value = args[1];
+ node.setAttribute('matchCase', false);
+ } else {
+ property = filter.getLeft();
+ value = filter.getRight();
+ }
+ this.writeNode('PropertyName', property, null, node);
+ this.writeOgcExpression(value, node);
+ return node;
+ },
+ 'PropertyIsLike': function(filter) {
+ var node = this.createElementNS('ogc:PropertyIsLike');
+ var args = filter.getArgs();
+ node.setAttribute('wildCard', args[2]);
+ node.setAttribute('singleChar', args[3]);
+ node.setAttribute('escapeChar', args[4]);
+ if (goog.isDefAndNotNull(args[5])) {
+ node.setAttribute('matchCase', args[5]);
+ }
+ var property = args[0];
+ if (goog.isDef(property)) {
+ this.writeNode('PropertyName', property, null, node);
+ }
+ this.writeNode('Literal', args[1], null, node);
+ return node;
+ },
+ 'BBOX': function(filter) {
+ var node = this.createElementNS('ogc:BBOX');
+ var args = filter.getArgs();
+ var property = args[5], bbox = [args[0], args[1], args[2], args[3]],
+ projection = args[4];
+ // PropertyName is optional in 1.1.0
+ if (goog.isDefAndNotNull(property)) {
+ this.writeNode('PropertyName', property, null, node);
+ }
+ var box = this.writeNode('Envelope', bbox,
+ 'http://www.opengis.net/gml');
+ if (goog.isDefAndNotNull(projection)) {
+ box.setAttribute('srsName', projection);
+ }
+ node.appendChild(box);
+ return node;
+ },
+ 'SortBy': function(sortProperties) {
+ var node = this.createElementNS('ogc:SortBy');
+ for (var i = 0, l = sortProperties.length; i < l; i++) {
+ this.writeNode('SortProperty', sortProperties[i], null, node);
+ }
+ return node;
+ },
+ 'SortProperty': function(sortProperty) {
+ var node = this.createElementNS('ogc:SortProperty');
+ this.writeNode('PropertyName', sortProperty['property'], null, node);
+ this.writeNode('SortOrder',
+ (sortProperty['order'] == 'DESC') ? 'DESC' : 'ASC', null, node);
+ return node;
+ },
+ 'SortOrder': function(value) {
+ var node = this.createElementNS('ogc:SortOrder');
+ node.appendChild(this.createTextNode(value));
+ return node;
+ }
+ });
+ this.setGmlParser(new ol.parser.ogc.GML_v3());
+};
+goog.inherits(ol.parser.ogc.Filter_v1_1_0,
+ ol.parser.ogc.Filter_v1);
+
+
+/**
+ * @param {ol.expr.Call} filter The filter to write out.
+ * @param {string} name The name of the spatial operator.
+ * @return {Element} The node created.
+ * @private
+ */
+ol.parser.ogc.Filter_v1_1_0.prototype.writeSpatial_ = function(filter, name) {
+ var node = this.createElementNS('ogc:' + name);
+ var args = filter.getArgs();
+ var property, geom = null, bbox, call, projection;
+ if (goog.isNumber(args[0])) {
+ bbox = [args[0], args[1], args[2], args[3]];
+ projection = args[4];
+ property = args[5];
+ } else if (args[0] instanceof ol.geom.Geometry) {
+ geom = args[0];
+ if (name === 'DWithin') {
+ projection = args[3];
+ property = args[4];
+ } else {
+ projection = args[1];
+ property = args[2];
+ }
+ } else if (args[0] instanceof ol.expr.Call) {
+ call = args[0];
+ if (name === 'DWithin') {
+ projection = args[3];
+ property = args[4];
+ } else {
+ projection = args[1];
+ property = args[2];
+ }
+ }
+ if (goog.isDefAndNotNull(property)) {
+ this.writeNode('PropertyName', property, null, node);
+ }
+ if (goog.isDef(call)) {
+ this.writeNode('Function', call, null, node);
+ } else {
+ var child;
+ if (geom !== null) {
+ child = this.writeNode('_geometry', geom,
+ this.gml_.featureNS).firstChild;
+ } else if (bbox.length === 4) {
+ child = this.writeNode('Envelope', bbox,
+ 'http://www.opengis.net/gml');
+ }
+ if (goog.isDef(child)) {
+ if (goog.isDef(projection)) {
+ child.setAttribute('srsName', projection);
+ }
+ node.appendChild(child);
+ }
+ }
+ return node;
+};
diff --git a/src/ol/parser/ogc/gml.js b/src/ol/parser/ogc/gml.js
index f5c221655f..339ef64971 100644
--- a/src/ol/parser/ogc/gml.js
+++ b/src/ol/parser/ogc/gml.js
@@ -284,7 +284,7 @@ ol.parser.ogc.GML = function(opt_options) {
sharedVertices = callback(feature, geom.type);
}
}
- var geometry = this.createGeometry_({geometry: geom},
+ var geometry = this.createGeometry({geometry: geom},
sharedVertices);
if (goog.isDef(geometry)) {
feature.setGeometry(geometry);
@@ -434,7 +434,7 @@ ol.parser.ogc.GML = function(opt_options) {
} else if (type === ol.geom.GeometryType.GEOMETRYCOLLECTION) {
child = this.writeNode('GeometryCollection', geometry, null, node);
}
- if (goog.isDef(this.srsName)) {
+ if (goog.isDefAndNotNull(this.srsName)) {
this.setAttributeNS(child, null, 'srsName', this.srsName);
}
return node;
@@ -503,13 +503,12 @@ ol.parser.ogc.GML.prototype.readNode = function(node, obj, opt_first) {
/**
- * @private
* @param {Object} container Geometry container.
* @param {ol.geom.SharedVertices=} opt_vertices Shared vertices.
* @return {ol.geom.Geometry} The geometry created.
*/
// TODO use a mixin since this is also used in the KML parser
-ol.parser.ogc.GML.prototype.createGeometry_ = function(container,
+ol.parser.ogc.GML.prototype.createGeometry = function(container,
opt_vertices) {
var geometry = null, coordinates, i, ii;
switch (container.geometry.type) {
@@ -553,7 +552,7 @@ ol.parser.ogc.GML.prototype.createGeometry_ = function(container,
case ol.geom.GeometryType.GEOMETRYCOLLECTION:
var geometries = [];
for (i = 0, ii = container.geometry.parts.length; i < ii; i++) {
- geometries.push(this.createGeometry_({
+ geometries.push(this.createGeometry({
geometry: container.geometry.parts[i]
}, opt_vertices));
}
diff --git a/src/ol/parser/ogc/gml_v2.js b/src/ol/parser/ogc/gml_v2.js
index feea6d3b22..9b4c364c2a 100644
--- a/src/ol/parser/ogc/gml_v2.js
+++ b/src/ol/parser/ogc/gml_v2.js
@@ -29,6 +29,7 @@ ol.parser.ogc.GML_v2 = function(opt_options) {
'Box': function(node, container) {
var coordinates = [];
this.readChildNodes(node, coordinates);
+ container.projection = node.getAttribute('srsName');
container.bounds = [coordinates[0][0][0], coordinates[0][1][0],
coordinates[0][0][1], coordinates[0][1][1]];
}
@@ -90,10 +91,10 @@ ol.parser.ogc.GML_v2 = function(opt_options) {
},
'Box': function(extent) {
var node = this.createElementNS('gml:Box');
- this.writeNode('coordinates', [[extent.minX, extent.minY],
- [extent.maxX, extent.maxY]], null, node);
+ this.writeNode('coordinates', [[extent[0], extent[1]],
+ [extent[2], extent[3]]], null, node);
// srsName attribute is optional for gml:Box
- if (goog.isDef(this.srsName)) {
+ if (goog.isDefAndNotNull(this.srsName)) {
node.setAttribute('srsName', this.srsName);
}
return node;
diff --git a/src/ol/parser/ogc/gml_v3.js b/src/ol/parser/ogc/gml_v3.js
index 744d75afc8..7ed61aa31c 100644
--- a/src/ol/parser/ogc/gml_v3.js
+++ b/src/ol/parser/ogc/gml_v3.js
@@ -55,7 +55,7 @@ ol.parser.ogc.GML_v3 = function(opt_options) {
} else if (type === ol.geom.GeometryType.GEOMETRYCOLLECTION) {
child = this.writeNode('MultiGeometry', geometry, null, node);
}
- if (goog.isDef(this.srsName)) {
+ if (goog.isDefAndNotNull(this.srsName)) {
this.setAttributeNS(child, null, 'srsName', this.srsName);
}
return node;
@@ -206,6 +206,7 @@ ol.parser.ogc.GML_v3 = function(opt_options) {
'Envelope': function(node, container) {
var coordinates = [];
this.readChildNodes(node, coordinates);
+ container.projection = node.getAttribute('srsName');
container.bounds = [coordinates[0][0][0][0], coordinates[1][0][0][0],
coordinates[0][0][0][1], coordinates[1][0][0][1]];
},
@@ -374,9 +375,9 @@ ol.parser.ogc.GML_v3 = function(opt_options) {
// only 2d for simple features profile
var pos;
if (this.axisOrientation.substr(0, 2) === 'en') {
- pos = (bounds.left + ' ' + bounds.bottom);
+ pos = (bounds[0] + ' ' + bounds[2]);
} else {
- pos = (bounds.bottom + ' ' + bounds.left);
+ pos = (bounds[2] + ' ' + bounds[0]);
}
var node = this.createElementNS('gml:lowerCorner');
node.appendChild(this.createTextNode(pos));
@@ -386,9 +387,9 @@ ol.parser.ogc.GML_v3 = function(opt_options) {
// only 2d for simple features profile
var pos;
if (this.axisOrientation.substr(0, 2) === 'en') {
- pos = (bounds.right + ' ' + bounds.top);
+ pos = (bounds[1] + ' ' + bounds[3]);
} else {
- pos = (bounds.top + ' ' + bounds.right);
+ pos = (bounds[3] + ' ' + bounds[1]);
}
var node = this.createElementNS('gml:upperCorner');
node.appendChild(this.createTextNode(pos));
diff --git a/src/ol/parser/xml.js b/src/ol/parser/xml.js
index e5c35f3d5c..09a4389792 100644
--- a/src/ol/parser/xml.js
+++ b/src/ol/parser/xml.js
@@ -182,8 +182,9 @@ ol.parser.XML.prototype.createElementNS = function(name, opt_uri) {
* results to a node.
*
* @param {string} name The name of a node to generate. Only use a local name.
- * @param {Object} obj Structure containing data for the writer.
- * @param {string=} opt_uri The name space uri to which the node belongs.
+ * @param {Object|string|number} obj Structure containing data for the writer.
+ * @param {?string=} opt_uri The name space uri to which the node
+ * belongs.
* @param {Element=} opt_parent Result will be appended to this node. If no
* parent is supplied, the node will not be appended to anything.
* @return {?Element} The child node.
@@ -273,3 +274,22 @@ ol.parser.XML.prototype.serialize = function(node) {
return goog.dom.xml.serialize(node);
}
};
+
+
+/**
+ * Create a document fragment node that can be appended to another node
+ * created by createElementNS. This will call
+ * document.createDocumentFragment outside of IE. In IE, the ActiveX
+ * object's createDocumentFragment method is used.
+ *
+ * @return {Element} A document fragment.
+ */
+ol.parser.XML.prototype.createDocumentFragment = function() {
+ var element;
+ if (this.xmldom) {
+ element = this.xmldom.createDocumentFragment();
+ } else {
+ element = document.createDocumentFragment();
+ }
+ return element;
+};
diff --git a/test/spec/ol/parser/ogc/filter_v1_0_0.test.js b/test/spec/ol/parser/ogc/filter_v1_0_0.test.js
new file mode 100644
index 0000000000..3c413c75ca
--- /dev/null
+++ b/test/spec/ol/parser/ogc/filter_v1_0_0.test.js
@@ -0,0 +1,238 @@
+goog.provide('ol.test.parser.ogc.Filter_v1_0_0');
+
+describe('ol.parser.ogc.Filter_v1_0_0', function() {
+
+ var parser = new ol.parser.ogc.Filter_v1_0_0();
+
+ describe('#readwrite', function() {
+
+ it('intersects filter read / written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/intersects.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = parser.read(xml);
+ expect(filter instanceof ol.expr.Call).to.be(true);
+ expect(filter.getCallee().getName()).to.eql(
+ ol.expr.functions.INTERSECTS);
+ var args = filter.getArgs();
+ var geom = args[0];
+ expect(geom instanceof ol.geom.Polygon).to.be(true);
+ expect(args[2]).to.eql('Geometry');
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('within filter read / written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/within.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = parser.read(xml);
+ expect(filter instanceof ol.expr.Call).to.be(true);
+ expect(filter.getCallee().getName()).to.eql(ol.expr.functions.WITHIN);
+ var args = filter.getArgs();
+ var geom = args[0];
+ expect(geom instanceof ol.geom.Polygon).to.be(true);
+ expect(args[2]).to.eql('Geometry');
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('contains filter read / written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/contains.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = parser.read(xml);
+ expect(filter instanceof ol.expr.Call).to.be(true);
+ expect(filter.getCallee().getName()).to.eql(
+ ol.expr.functions.CONTAINS);
+ var args = filter.getArgs();
+ var geom = args[0];
+ expect(geom instanceof ol.geom.Polygon).to.be(true);
+ expect(args[2]).to.eql('Geometry');
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('between filter read / written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/between.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = parser.read(xml);
+ expect(filter instanceof ol.expr.Logical).to.be.ok();
+ expect(filter.getOperator()).to.eql(ol.expr.LogicalOp.AND);
+ expect(filter.getLeft() instanceof ol.expr.Comparison).to.be.ok();
+ expect(filter.getLeft().getOperator()).to.eql(ol.expr.ComparisonOp.GTE);
+ expect(filter.getLeft().getLeft()).to.eql('number');
+ expect(filter.getLeft().getRight()).to.eql(0);
+ expect(filter.getRight() instanceof ol.expr.Comparison).to.be.ok();
+ expect(filter.getRight().getOperator()).to.eql(
+ ol.expr.ComparisonOp.LTE);
+ expect(filter.getRight().getLeft()).to.eql('number');
+ expect(filter.getRight().getRight()).to.eql(100);
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('between filter read correctly without literals', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/between2.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = parser.read(xml);
+ expect(filter instanceof ol.expr.Logical).to.be.ok();
+ expect(filter.getOperator()).to.eql(ol.expr.LogicalOp.AND);
+ expect(filter.getLeft() instanceof ol.expr.Comparison).to.be.ok();
+ expect(filter.getLeft().getOperator()).to.eql(ol.expr.ComparisonOp.GTE);
+ expect(filter.getLeft().getLeft()).to.eql('number');
+ expect(filter.getLeft().getRight()).to.eql(0);
+ expect(filter.getRight() instanceof ol.expr.Comparison).to.be.ok();
+ expect(filter.getRight().getOperator()).to.eql(
+ ol.expr.ComparisonOp.LTE);
+ expect(filter.getRight().getLeft()).to.eql('number');
+ expect(filter.getRight().getRight()).to.eql(100);
+ done();
+ });
+ });
+
+ it('null filter read / written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/null.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = parser.read(xml);
+ expect(filter instanceof ol.expr.Comparison).to.be.ok();
+ expect(filter.getLeft()).to.eql('prop');
+ expect(filter.getRight()).to.eql(null);
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('BBOX written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/bbox.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = new ol.expr.Call(
+ new ol.expr.Identifier(ol.expr.functions.EXTENT),
+ [-180, -90, 180, 90, 'EPSG:4326', 'the_geom']);
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('BBOX without geometry name written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/bbox_nogeom.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = new ol.expr.Call(
+ new ol.expr.Identifier(ol.expr.functions.EXTENT),
+ [-180, -90, 180, 90, 'EPSG:4326']);
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('DWithin written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/dwithin.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = new ol.expr.Call(new ol.expr.Identifier(
+ ol.expr.functions.DWITHIN),
+ [new ol.geom.Point([2488789, 289552]), 1000, 'm', undefined,
+ 'Geometry']);
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ filter = parser.read(xml);
+ output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ });
+
+ // the Filter Encoding spec doesn't allow for FID filters inside logical
+ // filters however, to be liberal, we will write them without complaining
+ describe('#logicalfid', function() {
+
+ it('logical filter [OR] with fid filter written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/logicalfeatureid.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = new ol.expr.Logical(ol.expr.LogicalOp.OR,
+ new ol.expr.Call(new ol.expr.Identifier(ol.expr.functions.LIKE),
+ ['person', 'me', '*', '.', '!']),
+ new ol.expr.Call(new ol.expr.Identifier(ol.expr.functions.FID),
+ ['foo.1', 'foo.2']));
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('logical filter [AND] with fid filter written correctly',
+ function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/' +
+ 'logicalfeatureidand.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = new ol.expr.Logical(ol.expr.LogicalOp.AND,
+ new ol.expr.Call(new ol.expr.Identifier(ol.expr.functions.LIKE),
+ ['person', 'me', '*', '.', '!']),
+ new ol.expr.Call(new ol.expr.Identifier(ol.expr.functions.FID),
+ ['foo.1', 'foo.2']));
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('logical filter [NOT] with fid filter written correctly',
+ function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/' +
+ 'logicalfeatureidnot.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = new ol.expr.Not(
+ new ol.expr.Call(new ol.expr.Identifier(ol.expr.functions.FID),
+ ['foo.2']));
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ });
+
+ describe('#date', function() {
+
+ it('date writing works as expected', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/betweendates.xml';
+ afterLoadXml(url, function(xml) {
+ // ISO 8601: 2010-11-27T18:19:15.123Z
+ var start = new Date(Date.UTC(2010, 10, 27, 18, 19, 15, 123));
+ // ISO 8601: 2011-12-27T18:19:15.123Z
+ var end = new Date(Date.UTC(2011, 11, 27, 18, 19, 15, 123));
+ var filter = new ol.expr.Logical(ol.expr.LogicalOp.AND,
+ new ol.expr.Comparison(ol.expr.ComparisonOp.GTE, 'when', start),
+ new ol.expr.Comparison(ol.expr.ComparisonOp.LTE, 'when', end));
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ });
+
+});
+
+goog.require('goog.dom.xml');
+goog.require('ol.expr');
+goog.require('ol.expr.Call');
+goog.require('ol.expr.Comparison');
+goog.require('ol.expr.ComparisonOp');
+goog.require('ol.expr.Identifier');
+goog.require('ol.expr.Logical');
+goog.require('ol.expr.LogicalOp');
+goog.require('ol.expr.Not');
+goog.require('ol.expr.functions');
+goog.require('ol.geom.Point');
+goog.require('ol.geom.Polygon');
+goog.require('ol.parser.ogc.Filter_v1_0_0');
diff --git a/test/spec/ol/parser/ogc/filter_v1_1_0.test.js b/test/spec/ol/parser/ogc/filter_v1_1_0.test.js
new file mode 100644
index 0000000000..695a848d65
--- /dev/null
+++ b/test/spec/ol/parser/ogc/filter_v1_1_0.test.js
@@ -0,0 +1,230 @@
+goog.provide('ol.test.parser.ogc.Filter_v1_1_0');
+
+describe('ol.parser.ogc.Filter_v1_1_0', function() {
+
+ var parser = new ol.parser.ogc.Filter_v1_1_0();
+
+ describe('#readwrite', function() {
+
+ it('filter read correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_1_0/test.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = parser.read(xml);
+ expect(filter instanceof ol.expr.Logical).to.be(true);
+ expect(filter.getOperator()).to.eql(ol.expr.LogicalOp.OR);
+ var filters = [];
+ parser.getSubfiltersForLogical_(filter, filters);
+ expect(filters.length).to.eql(5);
+ expect(filters[0]).to.eql(new ol.expr.Logical(ol.expr.LogicalOp.AND,
+ new ol.expr.Comparison(
+ ol.expr.ComparisonOp.GTE, 'number', 1064866676),
+ new ol.expr.Comparison(
+ ol.expr.ComparisonOp.LTE, 'number', 1065512599)));
+ expect(filters[1]).to.eql(new ol.expr.Not(new ol.expr.Comparison(
+ ol.expr.ComparisonOp.LTE, 'FOO', 5000)));
+ expect(filters[2] instanceof ol.expr.Call).to.be(true);
+ expect(filters[2].getCallee().getName()).to.eql(
+ ol.expr.functions.LIKE);
+ expect(filters[2].getArgs()).to.eql(['cat', '*dog.food!*good', '*',
+ '.', '!', null]);
+ expect(filters[3] instanceof ol.expr.Call).to.be(true);
+ expect(filters[3].getCallee().getName()).to.eql(
+ ol.expr.functions.IEQ);
+ expect(filters[3].getArgs()).to.eql(['cat', 'dog']);
+ expect(filters[4] instanceof ol.expr.Comparison).to.be(true);
+ expect(filters[4].getOperator()).to.eql(ol.expr.ComparisonOp.EQ);
+ expect(filters[4].getLeft()).to.eql('cat');
+ expect(filters[4].getRight()).to.eql('dog');
+ done();
+ });
+ });
+
+ it('matchCase read correctly', function() {
+ var cases = [{
+ str:
+ '' +
+ '' +
+ 'cat' +
+ 'dog' +
+ '' +
+ '',
+ exp: true
+ }, {
+ str:
+ '' +
+ '' +
+ 'cat' +
+ 'dog' +
+ '' +
+ '',
+ exp: true
+ }, {
+ str:
+ '' +
+ '' +
+ 'cat' +
+ 'dog' +
+ '' +
+ '',
+ exp: true
+ }, {
+ str:
+ '' +
+ '' +
+ 'cat' +
+ 'dog' +
+ '' +
+ '',
+ exp: false
+ }, {
+ str:
+ '' +
+ '' +
+ 'cat' +
+ 'dog' +
+ '' +
+ '',
+ exp: false
+ }, {
+ str:
+ '' +
+ '' +
+ 'cat' +
+ 'dog' +
+ '' +
+ '',
+ exp: true
+ }, {
+ str:
+ '' +
+ '' +
+ 'cat' +
+ 'dog' +
+ '' +
+ '',
+ exp: false
+ }];
+ var filter, c;
+ for (var i = 0; i < cases.length; ++i) {
+ c = cases[i];
+ filter = parser.read(c.str);
+ var matchCase = (filter instanceof ol.expr.Call) ? false : true;
+ expect(matchCase).to.eql(c.exp);
+ }
+ });
+
+ it('BBOX filter written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_1_0/bbox.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = parser.read(xml);
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('BBOX filter without property name written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_1_0/bbox_nogeomname.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = parser.read(xml);
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('Intersects filter read / written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_1_0/intersects.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = parser.read(xml);
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('Filter functions written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_1_0/function.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = new ol.expr.Call(new ol.expr.Identifier(
+ ol.expr.functions.INTERSECTS),
+ [new ol.expr.Call(new ol.expr.Identifier('querySingle'),
+ ['sf:restricted', 'the_geom',
+ 'cat=3']), undefined, 'the_geom']);
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('Custom filter functions written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_1_0/customfunction.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = new ol.expr.Logical(ol.expr.LogicalOp.AND,
+ new ol.expr.Call(new ol.expr.Identifier(ol.expr.functions.INEQ),
+ ['FOO', new ol.expr.Call(new ol.expr.Identifier('customFunction'),
+ ['param1', 'param2'])]));
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('Nested filter functions written correctly', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_1_0/nestedfunction.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = new ol.expr.Call(new ol.expr.Identifier(
+ ol.expr.functions.DWITHIN),
+ [new ol.expr.Call(new ol.expr.Identifier('collectGeometries'),
+ [new ol.expr.Call(new ol.expr.Identifier('queryCollection'),
+ ['sf:roads', 'the_geom', 'INCLUDE'])]), 200, 'meters',
+ undefined, 'the_geom']);
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('matchCase written correctly on Like filter', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_1_0/likematchcase.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = new ol.expr.Call(
+ new ol.expr.Identifier(ol.expr.functions.LIKE),
+ ['person', '*me*', '*', '.', '!', false]);
+ var output = parser.write(filter);
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('sortBy written correctly on Like filter', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_1_0/sortby.xml';
+ afterLoadXml(url, function(xml) {
+ var writer = parser.writers['http://www.opengis.net/ogc']['SortBy'];
+ var output = writer.call(parser, [{
+ 'property': 'Title',
+ 'order': 'ASC'
+ },{
+ 'property': 'Relevance',
+ 'order': 'DESC'
+ }]);
+ expect(output).to.xmleql(xml);
+ done();
+ });
+ });
+
+ });
+
+});
+
+goog.require('goog.dom.xml');
+goog.require('ol.expr');
+goog.require('ol.expr.Call');
+goog.require('ol.expr.Comparison');
+goog.require('ol.expr.ComparisonOp');
+goog.require('ol.expr.Identifier');
+goog.require('ol.expr.Logical');
+goog.require('ol.expr.LogicalOp');
+goog.require('ol.expr.Not');
+goog.require('ol.expr.functions');
+goog.require('ol.parser.ogc.Filter_v1_1_0');
diff --git a/test/spec/ol/parser/ogc/gml_v2.test.js b/test/spec/ol/parser/ogc/gml_v2.test.js
index cfa4d82859..f57f1cbbd9 100644
--- a/test/spec/ol/parser/ogc/gml_v2.test.js
+++ b/test/spec/ol/parser/ogc/gml_v2.test.js
@@ -19,7 +19,7 @@ describe('ol.parser.gml_v2', function() {
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
parser.srsName = 'foo';
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(parser.serialize(node))).to.xmleql(xml);
@@ -47,7 +47,7 @@ describe('ol.parser.gml_v2', function() {
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
parser.srsName = 'foo';
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(parser.serialize(node))).to.xmleql(xml);
@@ -76,7 +76,7 @@ describe('ol.parser.gml_v2', function() {
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
parser.srsName = 'foo';
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(parser.serialize(node))).to.xmleql(xml);
@@ -104,7 +104,7 @@ describe('ol.parser.gml_v2', function() {
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
parser.srsName = 'foo';
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(parser.serialize(node))).to.xmleql(xml);
@@ -138,7 +138,7 @@ describe('ol.parser.gml_v2', function() {
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
parser.srsName = 'foo';
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(parser.serialize(node))).to.xmleql(xml);
@@ -170,7 +170,7 @@ describe('ol.parser.gml_v2', function() {
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
parser.srsName = 'foo';
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(parser.serialize(node))).to.xmleql(xml);
@@ -188,7 +188,7 @@ describe('ol.parser.gml_v2', function() {
var p = new ol.parser.ogc.GML_v2({srsName: 'foo',
featureNS: 'http://foo'});
var obj = p.read(xml);
- var geom = p.createGeometry_({geometry: obj.geometry});
+ var geom = p.createGeometry({geometry: obj.geometry});
var node = p.featureNSWiters_['_geometry'].apply(p,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(p.serialize(node))).to.xmleql(xml);
@@ -231,7 +231,7 @@ describe('ol.parser.gml_v2', function() {
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
parser.srsName = 'foo';
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(parser.serialize(node))).to.xmleql(xml);
diff --git a/test/spec/ol/parser/ogc/gml_v3.test.js b/test/spec/ol/parser/ogc/gml_v3.test.js
index b58878b0c4..5586181d0d 100644
--- a/test/spec/ol/parser/ogc/gml_v3.test.js
+++ b/test/spec/ol/parser/ogc/gml_v3.test.js
@@ -17,7 +17,7 @@ describe('ol.parser.gml_v3', function() {
var url = 'spec/ol/parser/ogc/xml/gml_v3/linearring.xml';
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
parser.srsName = 'foo';
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
@@ -33,7 +33,7 @@ describe('ol.parser.gml_v3', function() {
var url = 'spec/ol/parser/ogc/xml/gml_v3/linestring.xml';
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
parser.srsName = 'foo';
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
@@ -59,7 +59,7 @@ describe('ol.parser.gml_v3', function() {
afterLoadXml(url, function(xml) {
var p = new ol.parser.ogc.GML_v3({curve: true, srsName: 'foo'});
var obj = p.read(xml);
- var geom = p.createGeometry_({geometry: obj.geometry});
+ var geom = p.createGeometry({geometry: obj.geometry});
var node = p.featureNSWiters_['_geometry'].apply(p,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(p.serialize(node))).to.xmleql(xml);
@@ -84,7 +84,7 @@ describe('ol.parser.gml_v3', function() {
afterLoadXml(url, function(xml) {
var p = new ol.parser.ogc.GML_v3({multiCurve: false, srsName: 'foo'});
var obj = p.read(xml);
- var geom = p.createGeometry_({geometry: obj.geometry});
+ var geom = p.createGeometry({geometry: obj.geometry});
var node = p.featureNSWiters_['_geometry'].apply(p,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(p.serialize(node))).to.xmleql(xml);
@@ -99,7 +99,7 @@ describe('ol.parser.gml_v3', function() {
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
parser.srsName = 'foo';
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(parser.serialize(node))).to.xmleql(xml);
@@ -116,7 +116,7 @@ describe('ol.parser.gml_v3', function() {
afterLoadXml(url, function(xml) {
var p = new ol.parser.ogc.GML_v3({curve: true, srsName: 'foo'});
var obj = p.read(xml);
- var geom = p.createGeometry_({geometry: obj.geometry});
+ var geom = p.createGeometry({geometry: obj.geometry});
var node = p.featureNSWiters_['_geometry'].apply(p,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(p.serialize(node))).to.xmleql(xml);
@@ -143,7 +143,7 @@ describe('ol.parser.gml_v3', function() {
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
parser.srsName = 'foo';
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(parser.serialize(node))).to.xmleql(xml);
@@ -170,7 +170,7 @@ describe('ol.parser.gml_v3', function() {
afterLoadXml(url, function(xml) {
var p = new ol.parser.ogc.GML_v3({multiSurface: false, srsName: 'foo'});
var obj = p.read(xml);
- var geom = p.createGeometry_({geometry: obj.geometry});
+ var geom = p.createGeometry({geometry: obj.geometry});
var node = p.featureNSWiters_['_geometry'].apply(p,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(p.serialize(node))).to.xmleql(xml);
@@ -195,7 +195,7 @@ describe('ol.parser.gml_v3', function() {
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
parser.srsName = 'foo';
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(parser.serialize(node))).to.xmleql(xml);
@@ -211,7 +211,7 @@ describe('ol.parser.gml_v3', function() {
afterLoadXml(url, function(xml) {
var p = new ol.parser.ogc.GML_v3({surface: true, srsName: 'foo'});
var obj = p.read(xml);
- var geom = p.createGeometry_({geometry: obj.geometry});
+ var geom = p.createGeometry({geometry: obj.geometry});
var node = p.featureNSWiters_['_geometry'].apply(p,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(p.serialize(node))).to.xmleql(xml);
@@ -225,7 +225,7 @@ describe('ol.parser.gml_v3', function() {
var url = 'spec/ol/parser/ogc/xml/gml_v3/point.xml';
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
parser.srsName = 'foo';
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
@@ -240,7 +240,7 @@ describe('ol.parser.gml_v3', function() {
var url = 'spec/ol/parser/ogc/xml/gml_v3/polygon.xml';
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
- var geom = parser.createGeometry_({geometry: obj.geometry});
+ var geom = parser.createGeometry({geometry: obj.geometry});
parser.srsName = 'foo';
var node = parser.featureNSWiters_['_geometry'].apply(parser,
[geom]).firstChild;
@@ -263,7 +263,7 @@ describe('ol.parser.gml_v3', function() {
afterLoadXml(url, function(xml) {
var p = new ol.parser.ogc.GML_v3({surface: true, srsName: 'foo'});
var obj = p.read(xml);
- var geom = p.createGeometry_({geometry: obj.geometry});
+ var geom = p.createGeometry({geometry: obj.geometry});
var node = p.featureNSWiters_['_geometry'].apply(p,
[geom]).firstChild;
expect(goog.dom.xml.loadXml(p.serialize(node))).to.xmleql(xml);
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0.xml
new file mode 100644
index 0000000000..5aea430597
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0.xml
@@ -0,0 +1,23 @@
+
+
+
+ number
+
+ 1064866676
+
+
+ 1065512599
+
+
+
+ cat
+ *dog.food!*good
+
+
+
+ FOO
+ 5000
+
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/bbox.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/bbox.xml
new file mode 100644
index 0000000000..48d6f7f118
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/bbox.xml
@@ -0,0 +1,8 @@
+
+
+ the_geom
+
+ -180,-90 180,90
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/bbox_nogeom.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/bbox_nogeom.xml
new file mode 100644
index 0000000000..d763209eda
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/bbox_nogeom.xml
@@ -0,0 +1,7 @@
+
+
+
+ -180,-90 180,90
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/between.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/between.xml
new file mode 100644
index 0000000000..1108065c53
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/between.xml
@@ -0,0 +1,11 @@
+
+
+ number
+
+ 0
+
+
+ 100
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/between2.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/between2.xml
new file mode 100644
index 0000000000..3655c7a877
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/between2.xml
@@ -0,0 +1,7 @@
+
+
+ number
+ 0
+ 100
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/betweendates.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/betweendates.xml
new file mode 100644
index 0000000000..3ad5b0131e
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/betweendates.xml
@@ -0,0 +1,11 @@
+
+
+ when
+
+ 2010-11-27T18:19:15.123Z
+
+
+ 2011-12-27T18:19:15.123Z
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/contains.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/contains.xml
new file mode 100644
index 0000000000..98b99ce04d
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/contains.xml
@@ -0,0 +1,12 @@
+
+
+ Geometry
+
+
+
+ 2488789,289552 2588789,289552 2588789,389552 2488789,389552 2488789,289552
+
+
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/custombetweendates.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/custombetweendates.xml
new file mode 100644
index 0000000000..f12024a9dd
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/custombetweendates.xml
@@ -0,0 +1,11 @@
+
+
+ when
+
+ 2010-11-27
+
+
+ 2011-12-27
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/dwithin.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/dwithin.xml
new file mode 100644
index 0000000000..9b71143a30
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/dwithin.xml
@@ -0,0 +1,9 @@
+
+
+ Geometry
+
+ 2488789,289552
+
+ 1000
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/intersects.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/intersects.xml
new file mode 100644
index 0000000000..6f34074a11
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/intersects.xml
@@ -0,0 +1,12 @@
+
+
+ Geometry
+
+
+
+ 2488789,289552 2588789,289552 2588789,389552 2488789,389552 2488789,289552
+
+
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/logicalfeatureid.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/logicalfeatureid.xml
new file mode 100644
index 0000000000..85e7b8f3c0
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/logicalfeatureid.xml
@@ -0,0 +1,10 @@
+
+
+
+ person
+ me
+
+
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/logicalfeatureidand.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/logicalfeatureidand.xml
new file mode 100644
index 0000000000..446197772a
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/logicalfeatureidand.xml
@@ -0,0 +1,10 @@
+
+
+
+ person
+ me
+
+
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/logicalfeatureidnot.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/logicalfeatureidnot.xml
new file mode 100644
index 0000000000..94ad30468f
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/logicalfeatureidnot.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/null.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/null.xml
new file mode 100644
index 0000000000..bc0d304e64
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/null.xml
@@ -0,0 +1,5 @@
+
+
+ prop
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/within.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/within.xml
new file mode 100644
index 0000000000..820ea450fc
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/within.xml
@@ -0,0 +1,12 @@
+
+
+ Geometry
+
+
+
+ 2488789,289552 2588789,289552 2588789,389552 2488789,389552 2488789,289552
+
+
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_1_0/bbox.xml b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/bbox.xml
new file mode 100644
index 0000000000..9974500d3d
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/bbox.xml
@@ -0,0 +1,9 @@
+
+
+ the_geom
+
+ -180 -90
+ 180 90
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_1_0/bbox_nogeomname.xml b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/bbox_nogeomname.xml
new file mode 100644
index 0000000000..29a08f44c9
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/bbox_nogeomname.xml
@@ -0,0 +1,8 @@
+
+
+
+ -180 -90
+ 180 90
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_1_0/customfunction.xml b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/customfunction.xml
new file mode 100644
index 0000000000..cebdc718cc
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/customfunction.xml
@@ -0,0 +1,11 @@
+
+
+
+ FOO
+
+ param1
+ param2
+
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_1_0/function.xml b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/function.xml
new file mode 100644
index 0000000000..749508778f
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/function.xml
@@ -0,0 +1,10 @@
+
+
+ the_geom
+
+ sf:restricted
+ the_geom
+ cat=3
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_1_0/intersects.xml b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/intersects.xml
new file mode 100644
index 0000000000..b2b537638b
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/intersects.xml
@@ -0,0 +1,9 @@
+
+
+ Geometry
+
+ -180 -90
+ 180 90
+
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_1_0/likematchcase.xml b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/likematchcase.xml
new file mode 100644
index 0000000000..97225dfcdc
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/likematchcase.xml
@@ -0,0 +1,6 @@
+
+
+ person
+ *me*
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_1_0/nestedfunction.xml b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/nestedfunction.xml
new file mode 100644
index 0000000000..9771d40de7
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/nestedfunction.xml
@@ -0,0 +1,13 @@
+
+
+ the_geom
+
+
+ sf:roads
+ the_geom
+ INCLUDE
+
+
+ 200
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_1_0/sortby.xml b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/sortby.xml
new file mode 100644
index 0000000000..c229843628
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/sortby.xml
@@ -0,0 +1,10 @@
+
+
+ Title
+ ASC
+
+
+ Relevance
+ DESC
+
+
diff --git a/test/spec/ol/parser/ogc/xml/filter_v1_1_0/test.xml b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/test.xml
new file mode 100644
index 0000000000..f025e4d3be
--- /dev/null
+++ b/test/spec/ol/parser/ogc/xml/filter_v1_1_0/test.xml
@@ -0,0 +1,31 @@
+
+
+
+ number
+
+ 1064866676
+
+
+ 1065512599
+
+
+
+ cat
+ *dog.food!*good
+
+
+
+ FOO
+ 5000
+
+
+
+ cat
+ dog
+
+
+ cat
+ dog
+
+
+