Merge pull request #852 from bartvde/ogcfilter2
Add parser for OGC Filter 1.0 and 1.1 (read/write) (r=@tschaub,@ahocevar)
This commit is contained in:
@@ -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.get(opt_attribute) : this.getGeometry();
|
||||
if (geometry) {
|
||||
intersects = ol.extent.intersects(geometry.getBounds(),
|
||||
[minX, maxX, minY, maxY]);
|
||||
@@ -142,6 +153,72 @@ ol.expr.lib[ol.expr.functions.FID] = function(var_args) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determine if two strings are like one another, based on simple pattern
|
||||
* matching.
|
||||
* @param {string} value The string to test.
|
||||
* @param {string} pattern The comparison pattern.
|
||||
* @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(value, pattern, wildCard,
|
||||
singleChar, escapeChar, matchCase) {
|
||||
if (wildCard == '.') {
|
||||
throw new Error('"." is an unsupported wildCard character for ' +
|
||||
'the "like" function');
|
||||
}
|
||||
// set UMN MapServer defaults for unspecified parameters
|
||||
wildCard = goog.isDef(wildCard) ? wildCard : '*';
|
||||
singleChar = goog.isDef(singleChar) ? singleChar : '.';
|
||||
escapeChar = goog.isDef(escapeChar) ? escapeChar : '!';
|
||||
pattern = pattern.replace(
|
||||
new RegExp('\\' + escapeChar + '(.|$)', 'g'), '\\$1');
|
||||
pattern = pattern.replace(
|
||||
new RegExp('\\' + singleChar, 'g'), '.');
|
||||
pattern = pattern.replace(
|
||||
new RegExp('\\' + wildCard, 'g'), '.*');
|
||||
pattern = pattern.replace(
|
||||
new RegExp('\\\\.\\*', 'g'), '\\' + wildCard);
|
||||
pattern = pattern.replace(
|
||||
new RegExp('\\\\\\.', 'g'), '\\' + singleChar);
|
||||
var modifiers = (matchCase === false) ? 'gi' : 'g';
|
||||
return new RegExp(pattern, modifiers).test(value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Case insensitive comparison for equality.
|
||||
* @param {*} first First value.
|
||||
* @param {*} second Second value.
|
||||
* @this {ol.Feature}
|
||||
*/
|
||||
ol.expr.lib[ol.expr.functions.IEQ] = function(first, second) {
|
||||
if (goog.isString(first) && goog.isString(second)) {
|
||||
return first.toUpperCase() == second.toUpperCase();
|
||||
} else {
|
||||
return first == second;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Case insensitive comparison for non-equality.
|
||||
* @param {*} first First value.
|
||||
* @param {*} second Second value.
|
||||
* @this {ol.Feature}
|
||||
*/
|
||||
ol.expr.lib[ol.expr.functions.INEQ] = function(first, second) {
|
||||
if (goog.isString(first) && goog.isString(second)) {
|
||||
return first.toUpperCase() != second.toUpperCase();
|
||||
} else {
|
||||
return first != second;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determine if a feature's default geometry is of the given type.
|
||||
* @param {ol.geom.GeometryType} type Geometry type.
|
||||
@@ -156,3 +233,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);
|
||||
};
|
||||
|
||||
@@ -277,12 +277,12 @@ ol.expr.Identifier.prototype.getName = function() {
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.expr.Expression}
|
||||
* @param {string|number|boolean|null} value A literal value.
|
||||
* @param {string|number|boolean|Date|null} value A literal value.
|
||||
*/
|
||||
ol.expr.Literal = function(value) {
|
||||
|
||||
/**
|
||||
* @type {string|number|boolean|null}
|
||||
* @type {string|number|boolean|Date|null}
|
||||
* @private
|
||||
*/
|
||||
this.value_ = value;
|
||||
@@ -301,7 +301,7 @@ ol.expr.Literal.prototype.evaluate = function() {
|
||||
|
||||
/**
|
||||
* Get the literal value.
|
||||
* @return {string|number|boolean|null} The literal value.
|
||||
* @return {string|number|boolean|Date|null} The literal value.
|
||||
*/
|
||||
ol.expr.Literal.prototype.getValue = function() {
|
||||
return this.value_;
|
||||
|
||||
37
src/ol/parser/ogc/filter.js
Normal file
37
src/ol/parser/ogc/filter.js
Normal file
@@ -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);
|
||||
607
src/ol/parser/ogc/filter_v1.js
Normal file
607
src/ol/parser/ogc/filter_v1.js
Normal file
@@ -0,0 +1,607 @@
|
||||
goog.provide('ol.parser.ogc.Filter_v1');
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.dom.xml');
|
||||
goog.require('goog.object');
|
||||
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.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');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
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) {
|
||||
expressions.push(obj.property);
|
||||
} else if (goog.isDef(obj.value)) {
|
||||
return obj.value;
|
||||
}
|
||||
break;
|
||||
case 3: // text node
|
||||
case 4: // cdata section
|
||||
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;
|
||||
}
|
||||
}
|
||||
// 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 = {
|
||||
filters: []
|
||||
};
|
||||
this.readChildNodes(node, container);
|
||||
if (goog.isDef(container.fids)) {
|
||||
obj.filter = new ol.expr.Call(
|
||||
new ol.expr.Identifier(ol.expr.functions.FID),
|
||||
goog.object.getValues(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 = {};
|
||||
}
|
||||
if (!obj.fids.hasOwnProperty(fid)) {
|
||||
obj.fids[fid] = new ol.expr.Literal(fid);
|
||||
}
|
||||
}
|
||||
},
|
||||
'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,
|
||||
new ol.expr.Literal(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 = new ol.expr.Literal(isNaN(value) ? nodeValue : value);
|
||||
},
|
||||
'PropertyName': function(node, obj) {
|
||||
obj.property = new ol.expr.Identifier(this.getChildValue(node));
|
||||
},
|
||||
'LowerBoundary': function(node, obj) {
|
||||
var readers = this.readers[this.defaultNamespaceURI];
|
||||
obj.lowerBoundary = readers._expression.call(this, node);
|
||||
},
|
||||
'UpperBoundary': function(node, obj) {
|
||||
var readers = this.readers[this.defaultNamespaceURI];
|
||||
obj.upperBoundary = readers._expression.call(this, node);
|
||||
},
|
||||
_spatial: function(node, obj, identifier) {
|
||||
var args = [], container = {};
|
||||
this.readChildNodes(node, container);
|
||||
if (goog.isDef(container.geometry)) {
|
||||
args.push(new ol.expr.Literal(this.gml_.createGeometry(container)));
|
||||
} else {
|
||||
args = [new ol.expr.Literal(container.bounds[0]),
|
||||
new ol.expr.Literal(container.bounds[1]),
|
||||
new ol.expr.Literal(container.bounds[2]),
|
||||
new ol.expr.Literal(container.bounds[3])];
|
||||
}
|
||||
if (goog.isDef(container.distance)) {
|
||||
args.push(container.distance);
|
||||
}
|
||||
if (goog.isDef(container.distanceUnits)) {
|
||||
args.push(container.distanceUnits);
|
||||
}
|
||||
args.push(new ol.expr.Literal(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) {
|
||||
var value = goog.string.toNumber(this.getChildValue(node));
|
||||
obj.distance = new ol.expr.Literal(value);
|
||||
obj.distanceUnits = new ol.expr.Literal(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 args = filter.getArgs();
|
||||
for (var i = 0, ii = args.length; i < ii; i++) {
|
||||
goog.asserts.assert(args[i] instanceof ol.expr.Literal);
|
||||
this.writeNode('FeatureId', args[i].getValue(), 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 expr = filters[i].getRight();
|
||||
if (filters[i].getOperator() === ol.expr.ComparisonOp.GTE) {
|
||||
lower = expr;
|
||||
} else if (filters[i].getOperator() === ol.expr.ComparisonOp.LTE) {
|
||||
upper = expr;
|
||||
}
|
||||
}
|
||||
this.writeNode('LowerBoundary', lower, null, node);
|
||||
this.writeNode('UpperBoundary', upper, null, node);
|
||||
return node;
|
||||
},
|
||||
'PropertyName': function(expr) {
|
||||
goog.asserts.assert(expr instanceof ol.expr.Identifier);
|
||||
var node = this.createElementNS('ogc:PropertyName');
|
||||
node.appendChild(this.createTextNode(expr.getName()));
|
||||
return node;
|
||||
},
|
||||
'Literal': function(expr) {
|
||||
goog.asserts.assert(expr instanceof ol.expr.Literal);
|
||||
var node = this.createElementNS('ogc:Literal');
|
||||
node.appendChild(this.createTextNode(expr.getValue()));
|
||||
return node;
|
||||
},
|
||||
'LowerBoundary': function(expr) {
|
||||
var node = this.createElementNS('ogc:LowerBoundary');
|
||||
this.writeOgcExpression(expr, node);
|
||||
return node;
|
||||
},
|
||||
'UpperBoundary': function(expr) {
|
||||
var node = this.createElementNS('ogc:UpperBoundary');
|
||||
this.writeOgcExpression(expr, 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();
|
||||
goog.asserts.assert(args[2] instanceof ol.expr.Literal);
|
||||
node.setAttribute('units', args[2].getValue());
|
||||
goog.asserts.assert(args[1] instanceof ol.expr.Literal);
|
||||
node.appendChild(this.createTextNode(args[1].getValue()));
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
goog.base(this);
|
||||
};
|
||||
goog.inherits(ol.parser.ogc.Filter_v1, ol.parser.XML);
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ol.parser.ogc.Filter_v1.filterMap_ = {
|
||||
'&&': 'And',
|
||||
'||': 'Or',
|
||||
'!': 'Not',
|
||||
'==': 'PropertyIsEqualTo',
|
||||
'!=': 'PropertyIsNotEqualTo',
|
||||
'<': 'PropertyIsLessThan',
|
||||
'>': 'PropertyIsGreaterThan',
|
||||
'<=': 'PropertyIsLessThanOrEqualTo',
|
||||
'>=': 'PropertyIsGreaterThanOrEqualTo',
|
||||
'..': 'PropertyIsBetween',
|
||||
'like': 'PropertyIsLike',
|
||||
'null': 'PropertyIsNull',
|
||||
'extent': 'BBOX',
|
||||
'dwithin': 'DWITHIN',
|
||||
'within': 'WITHIN',
|
||||
'contains': 'CONTAINS',
|
||||
'intersects': 'INTERSECTS',
|
||||
'fid': '_featureIds',
|
||||
'ieq': 'PropertyIsEqualTo',
|
||||
'ineq': 'PropertyIsNotEqualTo'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @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 left = filter.getLeft();
|
||||
var right = filter.getRight();
|
||||
var isNull = (type === ol.expr.ComparisonOp.EQ &&
|
||||
right instanceof ol.expr.Literal && right.getValue() === null);
|
||||
if (isNull) {
|
||||
type = 'null';
|
||||
}
|
||||
var isBetween = (type === ol.expr.LogicalOp.AND &&
|
||||
left instanceof ol.expr.Comparison &&
|
||||
right instanceof ol.expr.Comparison &&
|
||||
left.getLeft() instanceof ol.expr.Identifier &&
|
||||
right.getLeft() instanceof ol.expr.Identifier &&
|
||||
left.getLeft().getName() === right.getLeft().getName() &&
|
||||
(left.getOperator() === ol.expr.ComparisonOp.LTE ||
|
||||
left.getOperator() === ol.expr.ComparisonOp.GTE) &&
|
||||
(right.getOperator() === ol.expr.ComparisonOp.LTE ||
|
||||
right.getOperator() === ol.expr.ComparisonOp.GTE));
|
||||
if (isBetween) {
|
||||
type = '..';
|
||||
}
|
||||
} else if (filter instanceof ol.expr.Call) {
|
||||
var callee = filter.getCallee();
|
||||
goog.asserts.assert(callee instanceof ol.expr.Identifier);
|
||||
type = callee.getName();
|
||||
} else if (filter instanceof ol.expr.Not) {
|
||||
type = '!';
|
||||
}
|
||||
var filterType = ol.parser.ogc.Filter_v1.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.Expression} expr 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(expr, node) {
|
||||
if (expr instanceof ol.expr.Call) {
|
||||
this.writeNode('Function', expr, null, node);
|
||||
} else if (expr instanceof ol.expr.Literal) {
|
||||
this.writeNode('Literal', expr, null, node);
|
||||
} else if (expr instanceof ol.expr.Identifier) {
|
||||
this.writeNode('PropertyName', expr, null, node);
|
||||
}
|
||||
return node;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.expr.Logical} filter The filter to retrieve the sub filters from.
|
||||
* @param {Array.<ol.expr.Expression>} 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.<ol.expr.Expression>} 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]));
|
||||
subFilters.length = 0;
|
||||
}
|
||||
}
|
||||
// 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_);
|
||||
}
|
||||
}
|
||||
};
|
||||
179
src/ol/parser/ogc/filter_v1_0_0.js
Normal file
179
src/ol/parser/ogc/filter_v1_0_0.js
Normal file
@@ -0,0 +1,179 @@
|
||||
goog.provide('ol.parser.ogc.Filter_v1_0_0');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
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.Literal');
|
||||
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,
|
||||
new ol.expr.Literal(node.getAttribute('wildCard')),
|
||||
new ol.expr.Literal(node.getAttribute('singleChar')),
|
||||
new ol.expr.Literal(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();
|
||||
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();
|
||||
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();
|
||||
goog.asserts.assert(args[2] instanceof ol.expr.Literal);
|
||||
node.setAttribute('wildCard', args[2].getValue());
|
||||
goog.asserts.assert(args[3] instanceof ol.expr.Literal);
|
||||
node.setAttribute('singleChar', args[3].getValue());
|
||||
goog.asserts.assert(args[4] instanceof ol.expr.Literal);
|
||||
node.setAttribute('escape', args[4].getValue());
|
||||
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();
|
||||
goog.asserts.assert(args[0] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[1] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[2] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[3] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[4] instanceof ol.expr.Literal);
|
||||
var property = args[5], bbox = [args[0].getValue(), args[1].getValue(),
|
||||
args[2].getValue(), args[3].getValue()],
|
||||
projection = args[4].getValue();
|
||||
// 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 (args[0] instanceof ol.expr.Literal && goog.isNumber(args[0].getValue())) {
|
||||
goog.asserts.assert(args[1] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[2] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[3] instanceof ol.expr.Literal);
|
||||
bbox = [args[0].getValue(), args[1].getValue(), args[2].getValue(),
|
||||
args[3].getValue()];
|
||||
projection = args[4];
|
||||
property = args[5];
|
||||
} else if (args[0] instanceof ol.expr.Literal &&
|
||||
args[0].getValue() instanceof ol.geom.Geometry) {
|
||||
geom = args[0].getValue();
|
||||
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)) {
|
||||
goog.asserts.assert(projection instanceof ol.expr.Literal);
|
||||
if (goog.isDefAndNotNull(projection.getValue())) {
|
||||
child.setAttribute('srsName', projection.getValue());
|
||||
}
|
||||
node.appendChild(child);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
};
|
||||
237
src/ol/parser/ogc/filter_v1_1_0.js
Normal file
237
src/ol/parser/ogc/filter_v1_1_0.js
Normal file
@@ -0,0 +1,237 @@
|
||||
goog.provide('ol.parser.ogc.Filter_v1_1_0');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
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.Literal');
|
||||
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,
|
||||
new ol.expr.Literal(node.getAttribute('wildCard')),
|
||||
new ol.expr.Literal(node.getAttribute('singleChar')),
|
||||
new ol.expr.Literal(node.getAttribute('escapeChar')),
|
||||
new ol.expr.Literal(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();
|
||||
goog.asserts.assert(args[2] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[3] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[4] instanceof ol.expr.Literal);
|
||||
node.setAttribute('wildCard', args[2].getValue());
|
||||
node.setAttribute('singleChar', args[3].getValue());
|
||||
node.setAttribute('escapeChar', args[4].getValue());
|
||||
if (goog.isDefAndNotNull(args[5])) {
|
||||
goog.asserts.assert(args[5] instanceof ol.expr.Literal);
|
||||
node.setAttribute('matchCase', args[5].getValue());
|
||||
}
|
||||
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();
|
||||
goog.asserts.assert(args[0] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[1] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[2] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[3] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[4] instanceof ol.expr.Literal);
|
||||
var property = args[5], bbox = [args[0].getValue(), args[1].getValue(),
|
||||
args[2].getValue(), args[3].getValue()],
|
||||
projection = args[4].getValue();
|
||||
// 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);
|
||||
goog.asserts.assert(sortProperty['order'] instanceof ol.expr.Literal);
|
||||
this.writeNode('SortOrder',
|
||||
(sortProperty['order'].getValue() == '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 (args[0] instanceof ol.expr.Literal && goog.isNumber(args[0].getValue())) {
|
||||
goog.asserts.assert(args[1] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[2] instanceof ol.expr.Literal);
|
||||
goog.asserts.assert(args[3] instanceof ol.expr.Literal);
|
||||
bbox = [args[0].getValue(), args[1].getValue(), args[2].getValue(),
|
||||
args[3].getValue()];
|
||||
projection = args[4];
|
||||
property = args[5];
|
||||
} else if (args[0] instanceof ol.expr.Literal &&
|
||||
args[0].getValue() instanceof ol.geom.Geometry) {
|
||||
geom = args[0].getValue();
|
||||
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)) {
|
||||
goog.asserts.assert(projection instanceof ol.expr.Literal);
|
||||
if (goog.isDefAndNotNull(projection.getValue())) {
|
||||
child.setAttribute('srsName', projection.getValue());
|
||||
}
|
||||
node.appendChild(child);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
};
|
||||
@@ -310,7 +310,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);
|
||||
@@ -460,7 +460,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;
|
||||
@@ -550,13 +550,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) {
|
||||
@@ -600,7 +599,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));
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ ol.parser.ogc.GML_v2 = function(opt_options) {
|
||||
this.readers[this.defaultNamespaceURI]['_inherit'].apply(this,
|
||||
[node, coordinates, container]);
|
||||
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]];
|
||||
}
|
||||
@@ -100,10 +101,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;
|
||||
|
||||
@@ -56,7 +56,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;
|
||||
@@ -211,6 +211,7 @@ ol.parser.ogc.GML_v3 = function(opt_options) {
|
||||
this.readers[this.defaultNamespaceURI]['_inherit'].apply(this,
|
||||
[node, coordinates, container]);
|
||||
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]];
|
||||
},
|
||||
@@ -387,9 +388,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));
|
||||
@@ -399,9 +400,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));
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user