Merge pull request #11648 from virtualcitySYSTEMS/dwithin

Dwithin filter
This commit is contained in:
Andreas Hocevar
2020-10-19 11:18:44 +02:00
committed by GitHub
4 changed files with 319 additions and 89 deletions

View File

@@ -925,9 +925,10 @@ const GETFEATURE_SERIALIZERS = {
'Or': makeChildAppender(writeLogicalFilter),
'Not': makeChildAppender(writeNotFilter),
'BBOX': makeChildAppender(writeBboxFilter),
'Contains': makeChildAppender(writeContainsFilter),
'Intersects': makeChildAppender(writeIntersectsFilter),
'Within': makeChildAppender(writeWithinFilter),
'Contains': makeChildAppender(writeSpatialFilter),
'Intersects': makeChildAppender(writeSpatialFilter),
'Within': makeChildAppender(writeSpatialFilter),
'DWithin': makeChildAppender(writeDWithinFilter),
'PropertyIsEqualTo': makeChildAppender(writeComparisonFilter),
'PropertyIsNotEqualTo': makeChildAppender(writeComparisonFilter),
'PropertyIsLessThan': makeChildAppender(writeComparisonFilter),
@@ -944,11 +945,12 @@ const GETFEATURE_SERIALIZERS = {
'Or': makeChildAppender(writeLogicalFilter),
'Not': makeChildAppender(writeNotFilter),
'BBOX': makeChildAppender(writeBboxFilter),
'Contains': makeChildAppender(writeContainsFilter),
'Disjoint': makeChildAppender(writeDisjointFilter),
'Intersects': makeChildAppender(writeIntersectsFilter),
'Contains': makeChildAppender(writeSpatialFilter),
'Disjoint': makeChildAppender(writeSpatialFilter),
'Intersects': makeChildAppender(writeSpatialFilter),
'ResourceId': makeChildAppender(writeResourceIdFilter),
'Within': makeChildAppender(writeWithinFilter),
'Within': makeChildAppender(writeSpatialFilter),
'DWithin': makeChildAppender(writeDWithinFilter),
'PropertyIsEqualTo': makeChildAppender(writeComparisonFilter),
'PropertyIsNotEqualTo': makeChildAppender(writeComparisonFilter),
'PropertyIsLessThan': makeChildAppender(writeComparisonFilter),
@@ -1048,54 +1050,6 @@ function writeBboxFilter(node, filter, objectStack) {
format.prototype.writeGeometryElement(node, filter.extent, objectStack);
}
/**
* @param {Node} node Node.
* @param {import("./filter/Contains.js").default} filter Filter.
* @param {Array<*>} objectStack Node stack.
*/
function writeContainsFilter(node, filter, objectStack) {
const parent = /** @type {Object} */ (objectStack[objectStack.length - 1]);
const context = parent['context'];
const version = context['version'];
parent['srsName'] = filter.srsName;
const format = GML_FORMATS[version];
writePropertyName(version, node, filter.geometryName);
format.prototype.writeGeometryElement(node, filter.geometry, objectStack);
}
/**
* @param {Node} node Node.
* @param {import("./filter/Intersects.js").default} filter Filter.
* @param {Array<*>} objectStack Node stack.
*/
function writeIntersectsFilter(node, filter, objectStack) {
const parent = /** @type {Object} */ (objectStack[objectStack.length - 1]);
const context = parent['context'];
const version = context['version'];
parent['srsName'] = filter.srsName;
const format = GML_FORMATS[version];
writePropertyName(version, node, filter.geometryName);
format.prototype.writeGeometryElement(node, filter.geometry, objectStack);
}
/**
* @param {Node} node Node.
* @param {import("./filter/Disjoint.js").default} filter Filter.
* @param {Array<*>} objectStack Node stack.
*/
function writeDisjointFilter(node, filter, objectStack) {
const parent = /** @type {Object} */ (objectStack[objectStack.length - 1]);
const context = parent['context'];
const version = context['version'];
parent['srsName'] = filter.srsName;
const format = GML_FORMATS[version];
writePropertyName(version, node, filter.geometryName);
format.prototype.writeGeometryElement(node, filter.geometry, objectStack);
}
/**
* @param {Element} node Element.
* @param {import("./filter/ResourceId.js").default} filter Filter.
@@ -1107,10 +1061,10 @@ function writeResourceIdFilter(node, filter, objectStack) {
/**
* @param {Node} node Node.
* @param {import("./filter/Within.js").default} filter Filter.
* @param {import("./filter/Spatial.js").default} filter Filter.
* @param {Array<*>} objectStack Node stack.
*/
function writeWithinFilter(node, filter, objectStack) {
function writeSpatialFilter(node, filter, objectStack) {
const parent = /** @type {Object} */ (objectStack[objectStack.length - 1]);
const context = parent['context'];
const version = context['version'];
@@ -1121,6 +1075,26 @@ function writeWithinFilter(node, filter, objectStack) {
format.prototype.writeGeometryElement(node, filter.geometry, objectStack);
}
/**
* @param {Node} node Node.
* @param {import("./filter/DWithin.js").default} filter Filter.
* @param {Array<*>} objectStack Node stack.
*/
function writeDWithinFilter(node, filter, objectStack) {
const parent = /** @type {Object} */ (objectStack[objectStack.length - 1]);
const context = parent['context'];
const version = context['version'];
writeSpatialFilter(node, filter, objectStack);
const distance = createElementNS(getFilterNS(version), 'Distance');
writeStringTextNode(distance, filter.distance.toString());
if (version === '2.0.0') {
distance.setAttribute('uom', filter.unit);
} else {
distance.setAttribute('units', filter.unit);
}
node.appendChild(distance);
}
/**
* @param {Node} node Node.
* @param {import("./filter/During.js").default} filter Filter.
@@ -1130,11 +1104,8 @@ function writeDuringFilter(node, filter, objectStack) {
const parent = /** @type {Object} */ (objectStack[objectStack.length - 1]);
const context = parent['context'];
const version = context['version'];
const ns = FESNS[version];
const valueReference = createElementNS(ns, 'ValueReference');
writeStringTextNode(valueReference, filter.propertyName);
node.appendChild(valueReference);
writeExpression(FESNS[version], 'ValueReference', node, filter.propertyName);
const timePeriod = createElementNS(GMLNS, 'TimePeriod');
node.appendChild(timePeriod);
@@ -1202,12 +1173,11 @@ function writeComparisonFilter(node, filter, objectStack) {
const parent = /** @type {Object} */ (objectStack[objectStack.length - 1]);
const context = parent['context'];
const version = context['version'];
const ns = OGCNS[context['version']];
if (filter.matchCase !== undefined) {
node.setAttribute('matchCase', filter.matchCase.toString());
}
writePropertyName(version, node, filter.propertyName);
writeOgcLiteral(ns, node, '' + filter.expression);
writeLiteral(version, node, '' + filter.expression);
}
/**
@@ -1231,17 +1201,17 @@ function writeIsBetweenFilter(node, filter, objectStack) {
const parent = /** @type {Object} */ (objectStack[objectStack.length - 1]);
const context = parent['context'];
const version = context['version'];
const ns = OGCNS[context['version']];
const ns = getFilterNS(version);
writePropertyName(version, node, filter.propertyName);
const lowerBoundary = createElementNS(ns, 'LowerBoundary');
node.appendChild(lowerBoundary);
writeOgcLiteral(ns, lowerBoundary, '' + filter.lowerBoundary);
writeLiteral(version, lowerBoundary, '' + filter.lowerBoundary);
const upperBoundary = createElementNS(ns, 'UpperBoundary');
node.appendChild(upperBoundary);
writeOgcLiteral(ns, upperBoundary, '' + filter.upperBoundary);
writeLiteral(version, upperBoundary, '' + filter.upperBoundary);
}
/**
@@ -1253,7 +1223,6 @@ function writeIsLikeFilter(node, filter, objectStack) {
const parent = /** @type {Object} */ (objectStack[objectStack.length - 1]);
const context = parent['context'];
const version = context['version'];
const ns = OGCNS[version];
node.setAttribute('wildCard', filter.wildCard);
node.setAttribute('singleChar', filter.singleChar);
node.setAttribute('escapeChar', filter.escapeChar);
@@ -1261,7 +1230,7 @@ function writeIsLikeFilter(node, filter, objectStack) {
node.setAttribute('matchCase', filter.matchCase.toString());
}
writePropertyName(version, node, filter.propertyName);
writeOgcLiteral(ns, node, '' + filter.pattern);
writeLiteral(version, node, '' + filter.pattern);
}
/**
@@ -1270,12 +1239,21 @@ function writeIsLikeFilter(node, filter, objectStack) {
* @param {Node} node Node.
* @param {string} value Value.
*/
function writeOgcExpression(ns, tagName, node, value) {
function writeExpression(ns, tagName, node, value) {
const property = createElementNS(ns, tagName);
writeStringTextNode(property, value);
node.appendChild(property);
}
/**
* @param {string} version Version.
* @param {Node} node Node.
* @param {string} value PropertyName value.
*/
function writeLiteral(version, node, value) {
writeExpression(getFilterNS(version), 'Literal', node, value);
}
/**
* @param {string} version Version.
* @param {Node} node Node.
@@ -1283,30 +1261,12 @@ function writeOgcExpression(ns, tagName, node, value) {
*/
function writePropertyName(version, node, value) {
if (version === '2.0.0') {
writeFesValueReference(FESNS[version], node, value);
writeExpression(FESNS[version], 'ValueReference', node, value);
} else {
writeOgcExpression(OGCNS[version], 'PropertyName', node, value);
writeExpression(OGCNS[version], 'PropertyName', node, value);
}
}
/**
* @param {string} ns Namespace.
* @param {Node} node Node.
* @param {string} value PropertyName value.
*/
function writeFesValueReference(ns, node, value) {
writeOgcExpression(ns, 'ValueReference', node, value);
}
/**
* @param {string} ns Namespace.
* @param {Node} node Node.
* @param {string} value PropertyName value.
*/
function writeOgcLiteral(ns, node, value) {
writeOgcExpression(ns, 'Literal', node, value);
}
/**
* @param {Node} node Node.
* @param {string} time PropertyName value.

View File

@@ -4,6 +4,7 @@
import And from './filter/And.js';
import Bbox from './filter/Bbox.js';
import Contains from './filter/Contains.js';
import DWithin from './filter/DWithin.js';
import Disjoint from './filter/Disjoint.js';
import During from './filter/During.js';
import EqualTo from './filter/EqualTo.js';
@@ -131,6 +132,23 @@ export function within(geometryName, geometry, opt_srsName) {
return new Within(geometryName, geometry, opt_srsName);
}
/**
* Create a `<DWithin>` operator to test whether a geometry-valued property
* is within a distance to a given geometry.
*
* @param {!string} geometryName Geometry name to use.
* @param {!import("../geom/Geometry.js").default} geometry Geometry.
* @param {!number} distance Distance.
* @param {!string} unit Unit.
* @param {string=} opt_srsName SRS name. No srsName attribute will be
* set on geometries when this is not provided.
* @returns {!DWithin} `<DWithin>` operator.
* @api
*/
export function dwithin(geometryName, geometry, distance, unit, opt_srsName) {
return new DWithin(geometryName, geometry, distance, unit, opt_srsName);
}
/**
* Creates a `<PropertyIsEqualTo>` comparison operator.
*

View File

@@ -0,0 +1,38 @@
/**
* @module ol/format/filter/DWithin
*/
import Spatial from './Spatial.js';
/**
* @classdesc
* Represents a `<DWithin>` operator to test whether a geometry-valued property
* is within a distance to a given geometry.
* @api
*/
class DWithin extends Spatial {
/**
* @param {!string} geometryName Geometry name to use.
* @param {!import("../../geom/Geometry.js").default} geometry Geometry.
* @param {!number} distance Distance.
* @param {!string} unit Unit.
* @param {string=} opt_srsName SRS name. No srsName attribute will be
* set on geometries when this is not provided.
*/
constructor(geometryName, geometry, distance, unit, opt_srsName) {
super('DWithin', geometryName, geometry, opt_srsName);
/**
* @public
* @type {!number}
*/
this.distance = distance;
/**
* @public
* @type {!string}
*/
this.unit = unit;
}
}
export default DWithin;