add new DistanceWithin Filter

This commit is contained in:
Jannes Bolling
2020-10-14 17:34:17 +02:00
parent d4acf2ce10
commit ab43047e7a
4 changed files with 122 additions and 0 deletions

View File

@@ -928,6 +928,7 @@ const GETFEATURE_SERIALIZERS = {
'Contains': makeChildAppender(writeContainsFilter), 'Contains': makeChildAppender(writeContainsFilter),
'Intersects': makeChildAppender(writeIntersectsFilter), 'Intersects': makeChildAppender(writeIntersectsFilter),
'Within': makeChildAppender(writeWithinFilter), 'Within': makeChildAppender(writeWithinFilter),
'DWithin': makeChildAppender(writeDWithinFilter),
'PropertyIsEqualTo': makeChildAppender(writeComparisonFilter), 'PropertyIsEqualTo': makeChildAppender(writeComparisonFilter),
'PropertyIsNotEqualTo': makeChildAppender(writeComparisonFilter), 'PropertyIsNotEqualTo': makeChildAppender(writeComparisonFilter),
'PropertyIsLessThan': makeChildAppender(writeComparisonFilter), 'PropertyIsLessThan': makeChildAppender(writeComparisonFilter),
@@ -949,6 +950,7 @@ const GETFEATURE_SERIALIZERS = {
'Intersects': makeChildAppender(writeIntersectsFilter), 'Intersects': makeChildAppender(writeIntersectsFilter),
'ResourceId': makeChildAppender(writeResourceIdFilter), 'ResourceId': makeChildAppender(writeResourceIdFilter),
'Within': makeChildAppender(writeWithinFilter), 'Within': makeChildAppender(writeWithinFilter),
'DWithin': makeChildAppender(writeDWithinFilter),
'PropertyIsEqualTo': makeChildAppender(writeComparisonFilter), 'PropertyIsEqualTo': makeChildAppender(writeComparisonFilter),
'PropertyIsNotEqualTo': makeChildAppender(writeComparisonFilter), 'PropertyIsNotEqualTo': makeChildAppender(writeComparisonFilter),
'PropertyIsLessThan': makeChildAppender(writeComparisonFilter), 'PropertyIsLessThan': makeChildAppender(writeComparisonFilter),
@@ -1121,6 +1123,27 @@ function writeWithinFilter(node, filter, objectStack) {
format.prototype.writeGeometryElement(node, filter.geometry, 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'];
context['srsName'] = filter.srsName;
const format = GML_FORMATS[version];
writePropertyName(version, node, filter.geometryName);
format.prototype.writeGeometryElement(node, filter.geometry, objectStack);
const distance = createElementNS(getFilterNS(version), 'Distance');
writeStringTextNode(distance, filter.distance.toString());
distance.setAttribute('uom', filter.unit);
node.appendChild(distance);
}
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {import("./filter/During.js").default} filter Filter. * @param {import("./filter/During.js").default} filter Filter.

View File

@@ -4,6 +4,7 @@
import And from './filter/And.js'; import And from './filter/And.js';
import Bbox from './filter/Bbox.js'; import Bbox from './filter/Bbox.js';
import Contains from './filter/Contains.js'; import Contains from './filter/Contains.js';
import DWithin from './filter/DWithin.js';
import Disjoint from './filter/Disjoint.js'; import Disjoint from './filter/Disjoint.js';
import During from './filter/During.js'; import During from './filter/During.js';
import EqualTo from './filter/EqualTo.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); 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. * 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;

View File

@@ -19,6 +19,7 @@ import {
contains as containsFilter, contains as containsFilter,
disjoint as disjointFilter, disjoint as disjointFilter,
during as duringFilter, during as duringFilter,
dwithin as dwithinFilter,
equalTo as equalToFilter, equalTo as equalToFilter,
greaterThan as greaterThanFilter, greaterThan as greaterThanFilter,
greaterThanOrEqualTo as greaterThanOrEqualToFilter, greaterThanOrEqualTo as greaterThanOrEqualToFilter,
@@ -686,6 +687,48 @@ describe('ol.format.WFS', function () {
expect(serialized.firstElementChild).to.xmleql(parse(text)); expect(serialized.firstElementChild).to.xmleql(parse(text));
}); });
it('creates a dwithin filter', function () {
const text =
'<wfs:Query xmlns:wfs="http://www.opengis.net/wfs" ' +
' typeName="area" srsName="EPSG:4326" ' +
' xmlns:topp="http://www.openplans.org/topp">' +
' <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
' <ogc:DWithin>' +
' <ogc:PropertyName>the_geom</ogc:PropertyName>' +
' <gml:Polygon xmlns:gml="http://www.opengis.net/gml">' +
' <gml:exterior>' +
' <gml:LinearRing>' +
' <gml:posList srsDimension="2">' +
' 10 20 10 25 15 25 15 20 10 20' +
' </gml:posList>' +
' </gml:LinearRing>' +
' </gml:exterior>' +
' </gml:Polygon>' +
' <ogc:Distance uom="m">10</ogc:Distance>' +
' </ogc:DWithin>' +
' </ogc:Filter>' +
'</wfs:Query>';
const serialized = new WFS().writeGetFeature({
srsName: 'EPSG:4326',
featureTypes: ['area'],
filter: dwithinFilter(
'the_geom',
new Polygon([
[
[10, 20],
[10, 25],
[15, 25],
[15, 20],
[10, 20],
],
]),
10,
'm'
),
});
expect(serialized.firstElementChild).to.xmleql(parse(text));
});
it('creates During property filter', function () { it('creates During property filter', function () {
const text = const text =
'<wfs:Query xmlns:wfs="http://www.opengis.net/wfs" ' + '<wfs:Query xmlns:wfs="http://www.opengis.net/wfs" ' +