Filter enhancements. Adding support for serializing filters with Filter Encoding 1.1. Adding matchCase attribute to filters with binary operators. Refactoring filter formats to use methods from base XML format. r=ahocevar,adube (closes #1790)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@8812 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
+105
-29
@@ -67,40 +67,116 @@
|
||||
}
|
||||
|
||||
function test_evaluate(t) {
|
||||
t.plan(5);
|
||||
|
||||
var filter = new OpenLayers.Filter.Comparison({
|
||||
var cases = [{
|
||||
filter: new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.BETWEEN,
|
||||
property: "area",
|
||||
lowerBoundary: 1000,
|
||||
upperBoundary: 4999,
|
||||
type: OpenLayers.Filter.Comparison.BETWEEN});
|
||||
|
||||
var features = [
|
||||
new OpenLayers.Feature.Vector(null, {
|
||||
area: 999}),
|
||||
new OpenLayers.Feature.Vector(null, {
|
||||
area: 1000}),
|
||||
new OpenLayers.Feature.Vector(null, {
|
||||
area: 4999}),
|
||||
new OpenLayers.Feature.Vector(null, {
|
||||
area: 5000})];
|
||||
// PropertyIsBetween filter: lower and upper boundary are inclusive
|
||||
var filterResults = {
|
||||
0: false,
|
||||
1: true,
|
||||
2: true,
|
||||
3: false};
|
||||
for (var i in filterResults) {
|
||||
var result = filter.evaluate(features[i].attributes);
|
||||
t.eq(result, filterResults[i], "feature "+i+
|
||||
" evaluates to "+result.toString()+" correctly.");
|
||||
upperBoundary: 4999
|
||||
}),
|
||||
context: {area: 999},
|
||||
expect: false
|
||||
}, {
|
||||
filter: new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.BETWEEN,
|
||||
property: "area",
|
||||
lowerBoundary: 1000,
|
||||
upperBoundary: 4999
|
||||
}),
|
||||
context: {area: 1000},
|
||||
expect: true
|
||||
}, {
|
||||
filter: new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.BETWEEN,
|
||||
property: "area",
|
||||
lowerBoundary: 1000,
|
||||
upperBoundary: 4999
|
||||
}),
|
||||
context: {area: 4999},
|
||||
expect: true
|
||||
}, {
|
||||
filter: new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.BETWEEN,
|
||||
property: "area",
|
||||
lowerBoundary: 1000,
|
||||
upperBoundary: 4999
|
||||
}),
|
||||
context: {area: 5000},
|
||||
expect: false
|
||||
}, {
|
||||
filter: new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.BETWEEN,
|
||||
property: "area",
|
||||
lowerBoundary: 1000,
|
||||
upperBoundary: 4999
|
||||
}),
|
||||
context: {area: 999},
|
||||
expect: false
|
||||
}, {
|
||||
filter: new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.EQUAL_TO,
|
||||
property: "prop",
|
||||
value: "Foo"
|
||||
}),
|
||||
context: {prop: "Foo"},
|
||||
expect: true
|
||||
}, {
|
||||
filter: new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.EQUAL_TO,
|
||||
property: "prop",
|
||||
value: "Foo"
|
||||
}),
|
||||
context: {prop: "foo"},
|
||||
expect: false
|
||||
}, {
|
||||
filter: new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.EQUAL_TO,
|
||||
matchCase: true,
|
||||
property: "prop",
|
||||
value: "Foo"
|
||||
}),
|
||||
context: {prop: "foo"},
|
||||
expect: false
|
||||
}, {
|
||||
filter: new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
|
||||
property: "prop",
|
||||
value: "foo"
|
||||
}),
|
||||
context: {prop: "FOO"},
|
||||
expect: true
|
||||
}, {
|
||||
filter: new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
|
||||
matchCase: true,
|
||||
property: "prop",
|
||||
value: "foo"
|
||||
}),
|
||||
context: {prop: "FOO"},
|
||||
expect: true
|
||||
}, {
|
||||
filter: new OpenLayers.Filter.Comparison({
|
||||
type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
|
||||
matchCase: false,
|
||||
property: "prop",
|
||||
value: "foo"
|
||||
}),
|
||||
context: {prop: "FOO"},
|
||||
expect: false
|
||||
}];
|
||||
|
||||
t.plan(cases.length);
|
||||
|
||||
var c;
|
||||
for(var i=0; i<cases.length; ++i) {
|
||||
c = cases[i];
|
||||
t.eq(c.filter.evaluate(c.context), c.expect, "case " + i + ": " + c.filter.type);
|
||||
}
|
||||
var context = {
|
||||
area: 4998
|
||||
};
|
||||
var result = filter.evaluate(context);
|
||||
t.eq(result, true, "evaluation against custom filter context works.");
|
||||
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -53,6 +53,31 @@
|
||||
|
||||
}
|
||||
|
||||
function test_BBOX(t) {
|
||||
t.plan(1);
|
||||
var filter = new OpenLayers.Filter.Spatial({
|
||||
type: OpenLayers.Filter.Spatial.BBOX,
|
||||
property: "the_geom",
|
||||
value: new OpenLayers.Bounds(-180, -90, 180, 90),
|
||||
projection: "EPSG:4326"
|
||||
});
|
||||
|
||||
var out =
|
||||
'<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
|
||||
'<ogc:BBOX>' +
|
||||
'<ogc:PropertyName>the_geom</ogc:PropertyName>' +
|
||||
'<gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326">' +
|
||||
'<gml:coordinates decimal="." cs="," ts=" ">-90,-180 90,180</gml:coordinates>' +
|
||||
'</gml:Box>' +
|
||||
'</ogc:BBOX>' +
|
||||
'</ogc:Filter>';
|
||||
|
||||
var parser = new OpenLayers.Format.Filter.v1_0_0();
|
||||
var node = parser.write(filter);
|
||||
|
||||
t.xml_eq(node, out, "bbox correctly written");
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="../../../lib/OpenLayers.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var test_xml =
|
||||
'<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
|
||||
'<ogc:Or>' +
|
||||
'<ogc:PropertyIsBetween>' +
|
||||
'<ogc:PropertyName>number</ogc:PropertyName>' +
|
||||
'<ogc:LowerBoundary>' +
|
||||
'<ogc:Literal>1064866676</ogc:Literal>' +
|
||||
'</ogc:LowerBoundary>' +
|
||||
'<ogc:UpperBoundary>' +
|
||||
'<ogc:Literal>1065512599</ogc:Literal>' +
|
||||
'</ogc:UpperBoundary>' +
|
||||
'</ogc:PropertyIsBetween>' +
|
||||
'<ogc:PropertyIsLike wildCard="*" singleChar="." escape="!">' +
|
||||
'<ogc:PropertyName>cat</ogc:PropertyName>' +
|
||||
'<ogc:Literal>*dog.food!*good</ogc:Literal>' +
|
||||
'</ogc:PropertyIsLike>' +
|
||||
'<ogc:Not>' +
|
||||
'<ogc:PropertyIsLessThanOrEqualTo>' +
|
||||
'<ogc:PropertyName>FOO</ogc:PropertyName>' +
|
||||
'<ogc:Literal>5000</ogc:Literal>' +
|
||||
'</ogc:PropertyIsLessThanOrEqualTo>' +
|
||||
'</ogc:Not>' +
|
||||
'<ogc:PropertyIsEqualTo matchCase="true">' +
|
||||
'<ogc:PropertyName>cat</ogc:PropertyName>' +
|
||||
'<ogc:Literal>dog</ogc:Literal>' +
|
||||
'</ogc:PropertyIsEqualTo>' +
|
||||
'<ogc:PropertyIsEqualTo matchCase="false">' +
|
||||
'<ogc:PropertyName>cat</ogc:PropertyName>' +
|
||||
'<ogc:Literal>dog</ogc:Literal>' +
|
||||
'</ogc:PropertyIsEqualTo>' +
|
||||
'</ogc:Or>' +
|
||||
'</ogc:Filter>';
|
||||
|
||||
function test_read(t) {
|
||||
t.plan(3);
|
||||
|
||||
var parser = new OpenLayers.Format.Filter.v1_1_0();
|
||||
var xml = new OpenLayers.Format.XML();
|
||||
var filter = parser.read(xml.read(test_xml).documentElement);
|
||||
|
||||
t.ok(filter instanceof OpenLayers.Filter.Logical, "instance of correct class");
|
||||
t.eq(filter.type, OpenLayers.Filter.Logical.OR, "correct type");
|
||||
t.eq(filter.filters.length, 5, "correct number of child filters");
|
||||
}
|
||||
|
||||
function test_write(t) {
|
||||
t.plan(1);
|
||||
|
||||
// read first - testing that write produces the ogc:Filter element above
|
||||
var parser = new OpenLayers.Format.Filter.v1_1_0();
|
||||
var xml = new OpenLayers.Format.XML();
|
||||
var filter = parser.read(xml.read(test_xml).documentElement);
|
||||
|
||||
var node = parser.write(filter);
|
||||
t.xml_eq(node, test_xml, "filter correctly written");
|
||||
|
||||
}
|
||||
|
||||
function test_matchCase(t) {
|
||||
var parser = new OpenLayers.Format.Filter.v1_1_0();
|
||||
var xml = new OpenLayers.Format.XML();
|
||||
|
||||
var cases = [{
|
||||
str:
|
||||
'<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
|
||||
'<ogc:PropertyIsEqualTo>' +
|
||||
'<ogc:PropertyName>cat</ogc:PropertyName>' +
|
||||
'<ogc:Literal>dog</ogc:Literal>' +
|
||||
'</ogc:PropertyIsEqualTo>' +
|
||||
'</ogc:Filter>',
|
||||
exp: true
|
||||
}, {
|
||||
str:
|
||||
'<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
|
||||
'<ogc:PropertyIsEqualTo matchCase="1">' +
|
||||
'<ogc:PropertyName>cat</ogc:PropertyName>' +
|
||||
'<ogc:Literal>dog</ogc:Literal>' +
|
||||
'</ogc:PropertyIsEqualTo>' +
|
||||
'</ogc:Filter>',
|
||||
exp: true
|
||||
}, {
|
||||
str:
|
||||
'<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
|
||||
'<ogc:PropertyIsEqualTo matchCase="true">' +
|
||||
'<ogc:PropertyName>cat</ogc:PropertyName>' +
|
||||
'<ogc:Literal>dog</ogc:Literal>' +
|
||||
'</ogc:PropertyIsEqualTo>' +
|
||||
'</ogc:Filter>',
|
||||
exp: true
|
||||
}, {
|
||||
str:
|
||||
'<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
|
||||
'<ogc:PropertyIsEqualTo matchCase="0">' +
|
||||
'<ogc:PropertyName>cat</ogc:PropertyName>' +
|
||||
'<ogc:Literal>dog</ogc:Literal>' +
|
||||
'</ogc:PropertyIsEqualTo>' +
|
||||
'</ogc:Filter>',
|
||||
exp: false
|
||||
}, {
|
||||
str:
|
||||
'<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
|
||||
'<ogc:PropertyIsEqualTo matchCase="0">' +
|
||||
'<ogc:PropertyName>cat</ogc:PropertyName>' +
|
||||
'<ogc:Literal>dog</ogc:Literal>' +
|
||||
'</ogc:PropertyIsEqualTo>' +
|
||||
'</ogc:Filter>',
|
||||
exp: false
|
||||
}, {
|
||||
str:
|
||||
'<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
|
||||
'<ogc:PropertyIsNotEqualTo matchCase="true">' +
|
||||
'<ogc:PropertyName>cat</ogc:PropertyName>' +
|
||||
'<ogc:Literal>dog</ogc:Literal>' +
|
||||
'</ogc:PropertyIsNotEqualTo>' +
|
||||
'</ogc:Filter>',
|
||||
exp: true
|
||||
}, {
|
||||
str:
|
||||
'<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
|
||||
'<ogc:PropertyIsNotEqualTo matchCase="false">' +
|
||||
'<ogc:PropertyName>cat</ogc:PropertyName>' +
|
||||
'<ogc:Literal>dog</ogc:Literal>' +
|
||||
'</ogc:PropertyIsNotEqualTo>' +
|
||||
'</ogc:Filter>',
|
||||
exp: false
|
||||
}];
|
||||
|
||||
t.plan(cases.length);
|
||||
|
||||
var filter, c;
|
||||
for(var i=0; i<cases.length; ++i) {
|
||||
c = cases[i];
|
||||
filter = parser.read(xml.read(c.str).documentElement);
|
||||
t.eq(filter.matchCase, c.exp, "case " + i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function test_BBOX(t) {
|
||||
t.plan(1);
|
||||
var filter = new OpenLayers.Filter.Spatial({
|
||||
type: OpenLayers.Filter.Spatial.BBOX,
|
||||
property: "the_geom",
|
||||
value: new OpenLayers.Bounds(-180, -90, 180, 90),
|
||||
projection: "EPSG:4326"
|
||||
});
|
||||
|
||||
var out =
|
||||
'<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
|
||||
'<ogc:BBOX>' +
|
||||
'<ogc:PropertyName>the_geom</ogc:PropertyName>' +
|
||||
'<gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326">' +
|
||||
'<gml:lowerCorner>-90 -180</gml:lowerCorner>' +
|
||||
'<gml:upperCorner>90 180</gml:upperCorner>' +
|
||||
'</gml:Envelope>' +
|
||||
'</ogc:BBOX>' +
|
||||
'</ogc:Filter>';
|
||||
|
||||
var parser = new OpenLayers.Format.Filter.v1_1_0();
|
||||
var node = parser.write(filter);
|
||||
|
||||
t.xml_eq(node, out, "bbox correctly written");
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -53,6 +53,7 @@
|
||||
<li>Format/SLD/v1_0_0.html</li>
|
||||
<li>Format/Filter.html</li>
|
||||
<li>Format/Filter/v1_0_0.html</li>
|
||||
<li>Format/Filter/v1_1_0.html</li>
|
||||
<li>Format/WKT.html</li>
|
||||
<li>Format/WMC.html</li>
|
||||
<li>Format/WMC/v1_1_0.html</li>
|
||||
|
||||
Reference in New Issue
Block a user