diff --git a/src/ol/parser/ogc/filter_v1.js b/src/ol/parser/ogc/filter_v1.js
index b390e61db6..1deca301fa 100644
--- a/src/ol/parser/ogc/filter_v1.js
+++ b/src/ol/parser/ogc/filter_v1.js
@@ -12,6 +12,8 @@ goog.require('ol.expr.Identifier');
goog.require('ol.expr.Literal');
goog.require('ol.expr.Logical');
goog.require('ol.expr.LogicalOp');
+goog.require('ol.expr.Math');
+goog.require('ol.expr.MathOp');
goog.require('ol.expr.Not');
goog.require('ol.expr.functions');
goog.require('ol.parser.XML');
@@ -28,34 +30,49 @@ ol.parser.ogc.Filter_v1 = function() {
this.readers = {
'http://www.opengis.net/ogc': {
_expression: function(node) {
- var obj, source = '';
+ var expressions = [];
+ var obj, value, numValue, expr;
for (var child = node.firstChild; child; child = child.nextSibling) {
switch (child.nodeType) {
case 1:
obj = this.readNode(child);
if (obj.property) {
- var name = obj.property.getName();
- source += (source !== '') ? '+' + name : name;
+ expressions.push(obj.property);
} else if (goog.isDef(obj.value)) {
return obj.value;
}
break;
case 3: // text node
case 4: // cdata section
- if (source !== '') {
- source += '+';
- }
- if (isNaN(goog.string.toNumber(child.nodeValue))) {
- source += goog.string.quote(goog.string.trim(child.nodeValue));
- } else {
- source += goog.string.trim(child.nodeValue);
+ value = goog.string.trim(child.nodeValue);
+ // no need to concatenate empty strings
+ if (value) {
+ // check for numeric values
+ numValue = goog.string.toNumber(value);
+ if (!isNaN(numValue)) {
+ value = numValue;
+ }
+ expressions.push(new ol.expr.Literal(value));
}
break;
default:
break;
}
}
- return ol.expr.parse(source);
+ // if we have more than one property or literal, we concatenate them
+ var num = expressions.length;
+ if (num === 1) {
+ expr = expressions[0];
+ } else {
+ expr = new ol.expr.Literal('');
+ if (num > 1) {
+ var add = ol.expr.MathOp.ADD;
+ for (var i = 0; i < num; ++i) {
+ expr = new ol.expr.Math(add, expr, expressions[i]);
+ }
+ }
+ }
+ return expr;
},
'Filter': function(node, obj) {
var container = {
@@ -217,7 +234,8 @@ ol.parser.ogc.Filter_v1 = function() {
ol.expr.functions.DWITHIN);
},
'Distance': function(node, obj) {
- obj.distance = new ol.expr.Literal(this.getChildValue(node));
+ var value = goog.string.toNumber(this.getChildValue(node));
+ obj.distance = new ol.expr.Literal(value);
obj.distanceUnits = new ol.expr.Literal(node.getAttribute('units'));
}
}
@@ -328,12 +346,8 @@ ol.parser.ogc.Filter_v1 = function() {
},
'Literal': function(expr) {
goog.asserts.assert(expr instanceof ol.expr.Literal);
- var value = expr.getValue();
- if (value instanceof Date) {
- value = value.toISOString();
- }
var node = this.createElementNS('ogc:Literal');
- node.appendChild(this.createTextNode(value));
+ node.appendChild(this.createTextNode(expr.getValue()));
return node;
},
'LowerBoundary': function(expr) {
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
index 87ec4afffa..be7de99cee 100644
--- a/test/spec/ol/parser/ogc/filter_v1_0_0.test.js
+++ b/test/spec/ol/parser/ogc/filter_v1_0_0.test.js
@@ -4,9 +4,9 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
var parser = new ol.parser.ogc.Filter_v1_0_0();
- describe('#readwrite', function() {
+ describe('reading and writing', function() {
- it('intersects filter read / written correctly', function(done) {
+ it('handles intersects', function(done) {
var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/intersects.xml';
afterLoadXml(url, function(xml) {
var filter = parser.read(xml);
@@ -23,7 +23,7 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
});
});
- it('within filter read / written correctly', function(done) {
+ it('handles within', function(done) {
var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/within.xml';
afterLoadXml(url, function(xml) {
var filter = parser.read(xml);
@@ -39,7 +39,7 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
});
});
- it('contains filter read / written correctly', function(done) {
+ it('handles contains', function(done) {
var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/contains.xml';
afterLoadXml(url, function(xml) {
var filter = parser.read(xml);
@@ -56,18 +56,18 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
});
});
- it('between filter read / written correctly', function(done) {
+ it('handles between', 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).to.be.a(ol.expr.Logical);
expect(filter.getOperator()).to.equal(ol.expr.LogicalOp.AND);
- expect(filter.getLeft() instanceof ol.expr.Comparison).to.be.ok();
+ expect(filter.getLeft()).to.be.a(ol.expr.Comparison);
expect(filter.getLeft().getOperator()).to.equal(
ol.expr.ComparisonOp.GTE);
expect(filter.getLeft().getLeft().getName()).to.equal('number');
expect(filter.getLeft().getRight().getValue()).to.equal(0);
- expect(filter.getRight() instanceof ol.expr.Comparison).to.be.ok();
+ expect(filter.getRight()).to.be.a(ol.expr.Comparison);
expect(filter.getRight().getOperator()).to.equal(
ol.expr.ComparisonOp.LTE);
expect(filter.getRight().getLeft().getName()).to.equal('number');
@@ -78,18 +78,18 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
});
});
- it('between filter read correctly without literals', function(done) {
+ it('handles between 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).to.be.a(ol.expr.Logical);
expect(filter.getOperator()).to.equal(ol.expr.LogicalOp.AND);
- expect(filter.getLeft() instanceof ol.expr.Comparison).to.be.ok();
+ expect(filter.getLeft()).to.be.a(ol.expr.Comparison);
expect(filter.getLeft().getOperator()).to.equal(
ol.expr.ComparisonOp.GTE);
expect(filter.getLeft().getLeft().getName()).to.equal('number');
expect(filter.getLeft().getRight().getValue()).to.equal(0);
- expect(filter.getRight() instanceof ol.expr.Comparison).to.be.ok();
+ expect(filter.getRight()).to.be.a(ol.expr.Comparison);
expect(filter.getRight().getOperator()).to.equal(
ol.expr.ComparisonOp.LTE);
expect(filter.getRight().getLeft().getName()).to.equal('number');
@@ -98,11 +98,11 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
});
});
- it('null filter read / written correctly', function(done) {
+ it('handles null', 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).to.be.a(ol.expr.Comparison);
expect(filter.getLeft().getName()).to.equal('prop');
expect(filter.getRight().getValue()).to.equal(null);
var output = parser.write(filter);
@@ -111,7 +111,7 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
});
});
- it('BBOX written correctly', function(done) {
+ it('writes BBOX', 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(
@@ -126,7 +126,7 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
});
});
- it('BBOX without geometry name written correctly', function(done) {
+ it('writes BBOX without geometry name', 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(
@@ -140,7 +140,28 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
});
});
- it('DWithin written correctly', function(done) {
+ it('reads DWithin', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/dwithin.xml';
+ afterLoadXml(url, function(xml) {
+ var filter = parser.read(xml);
+ expect(filter).to.be.a(ol.expr.Call);
+ var callee = filter.getCallee();
+ expect(callee).to.be.a(ol.expr.Identifier);
+ var name = callee.getName();
+ expect(name).to.equal(ol.expr.functions.DWITHIN);
+ var args = filter.getArgs();
+ expect(args.length).to.equal(5);
+ var distance = args[1];
+ expect(distance).to.be.a(ol.expr.Literal);
+ expect(distance.getValue()).to.equal(1000);
+ var units = args[2];
+ expect(units).to.be.a(ol.expr.Literal);
+ expect(units.getValue()).to.equal('m');
+ done();
+ });
+ });
+
+ it('writes DWithin', 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(
@@ -161,9 +182,9 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
// 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() {
+ describe('logical fid', function() {
- it('logical filter [OR] with fid filter written correctly', function(done) {
+ it('writes logical [OR] with fid', 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,
@@ -179,7 +200,7 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
});
});
- it('logical filter [AND] with fid filter written correctly',
+ it('writes logical [AND] with fid',
function(done) {
var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/' +
'logicalfeatureidand.xml';
@@ -197,7 +218,7 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
});
});
- it('logical filter [NOT] with fid filter written correctly',
+ it('writes logical [NOT] with fid',
function(done) {
var url = 'spec/ol/parser/ogc/xml/filter_v1_0_0/' +
'logicalfeatureidnot.xml';
@@ -213,30 +234,8 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
});
- 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,
- new ol.expr.Identifier('when'), new ol.expr.Literal(start)),
- new ol.expr.Comparison(ol.expr.ComparisonOp.LTE,
- new ol.expr.Identifier('when'), new ol.expr.Literal(end)));
- var output = parser.write(filter);
- expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
- done();
- });
- });
-
- });
-
- describe('_expression reader works as expected', function() {
- it('_expression reader handles combined propertyname and literal',
+ describe('_expression reader', function() {
+ it('handles combined propertyname and literal',
function() {
var xml = '10';
@@ -244,7 +243,7 @@ describe('ol.parser.ogc.Filter_v1_0_0', function() {
'_expression'];
var expr = reader.call(parser, goog.dom.xml.loadXml(
xml).documentElement);
- expect(expr instanceof ol.expr.Literal).to.be.ok();
+ expect(expr).to.be.a(ol.expr.Literal);
expect(expr.getValue()).to.equal(10);
xml = '' +
'fooxbar';
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
index 9d7d06bd3d..b39fc59a0f 100644
--- a/test/spec/ol/parser/ogc/filter_v1_1_0.test.js
+++ b/test/spec/ol/parser/ogc/filter_v1_1_0.test.js
@@ -4,9 +4,9 @@ describe('ol.parser.ogc.Filter_v1_1_0', function() {
var parser = new ol.parser.ogc.Filter_v1_1_0();
- describe('#readwrite', function() {
+ describe('reading and writing', function() {
- it('filter read correctly', function(done) {
+ it('reads filter', function(done) {
var url = 'spec/ol/parser/ogc/xml/filter_v1_1_0/test.xml';
afterLoadXml(url, function(xml) {
var filter = parser.read(xml);
@@ -45,7 +45,7 @@ describe('ol.parser.ogc.Filter_v1_1_0', function() {
});
});
- it('matchCase read correctly', function() {
+ it('reads matchCase', function() {
var cases = [{
str:
'' +
@@ -119,7 +119,7 @@ describe('ol.parser.ogc.Filter_v1_1_0', function() {
}
});
- it('BBOX filter written correctly', function(done) {
+ it('writes BBOX', function(done) {
var url = 'spec/ol/parser/ogc/xml/filter_v1_1_0/bbox.xml';
afterLoadXml(url, function(xml) {
var filter = parser.read(xml);
@@ -129,7 +129,7 @@ describe('ol.parser.ogc.Filter_v1_1_0', function() {
});
});
- it('BBOX filter without property name written correctly', function(done) {
+ it('writes BBOX without property name', 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);
@@ -139,7 +139,7 @@ describe('ol.parser.ogc.Filter_v1_1_0', function() {
});
});
- it('Intersects filter read / written correctly', function(done) {
+ it('handles intersects', function(done) {
var url = 'spec/ol/parser/ogc/xml/filter_v1_1_0/intersects.xml';
afterLoadXml(url, function(xml) {
var filter = parser.read(xml);
@@ -149,7 +149,7 @@ describe('ol.parser.ogc.Filter_v1_1_0', function() {
});
});
- it('Filter functions written correctly', function(done) {
+ it('handles functions', 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(
@@ -165,7 +165,7 @@ describe('ol.parser.ogc.Filter_v1_1_0', function() {
});
});
- it('Custom filter functions written correctly', function(done) {
+ it('writes custom functions', 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,
@@ -179,7 +179,7 @@ describe('ol.parser.ogc.Filter_v1_1_0', function() {
});
});
- it('Nested filter functions written correctly', function(done) {
+ it('writes nested functions', 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(
@@ -197,7 +197,7 @@ describe('ol.parser.ogc.Filter_v1_1_0', function() {
});
});
- it('matchCase written correctly on Like filter', function(done) {
+ it('writes matchCase on like', 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(
@@ -211,7 +211,7 @@ describe('ol.parser.ogc.Filter_v1_1_0', function() {
});
});
- it('sortBy written correctly on Like filter', function(done) {
+ it('writes sortBy on like', 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'];
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
deleted file mode 100644
index 3ad5b0131e..0000000000
--- a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/betweendates.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- 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/custombetweendates.xml b/test/spec/ol/parser/ogc/xml/filter_v1_0_0/custombetweendates.xml
deleted file mode 100644
index f12024a9dd..0000000000
--- a/test/spec/ol/parser/ogc/xml/filter_v1_0_0/custombetweendates.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- when
-
- 2010-11-27
-
-
- 2011-12-27
-
-
-