diff --git a/src/ol/format/WFS.js b/src/ol/format/WFS.js index bf7f73f2ad..0c94a31819 100644 --- a/src/ol/format/WFS.js +++ b/src/ol/format/WFS.js @@ -205,16 +205,20 @@ const WFSNS = { }; /** - * @type {string} + * @type {Object} */ -const FESNS = 'http://www.opengis.net/fes'; +const FESNS = { + '2.0.0': 'http://www.opengis.net/fes/2.0', + '1.1.0': 'http://www.opengis.net/fes', + '1.0.0': 'http://www.opengis.net/fes', +}; /** * @type {Object} */ const SCHEMA_LOCATIONS = { '2.0.0': - 'http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0.0/wfs.xsd', + 'http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd', '1.1.0': 'http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd', '1.0.0': @@ -904,7 +908,7 @@ const GETFEATURE_SERIALIZERS = { 'PropertyIsBetween': makeChildAppender(writeIsBetweenFilter), 'PropertyIsLike': makeChildAppender(writeIsLikeFilter), }, - 'http://www.opengis.net/ogc/1.1': { + 'http://www.opengis.net/fes/2.0': { 'During': makeChildAppender(writeDuringFilter), 'And': makeChildAppender(writeLogicalFilter), 'Or': makeChildAppender(writeLogicalFilter), @@ -912,6 +916,7 @@ const GETFEATURE_SERIALIZERS = { 'BBOX': makeChildAppender(writeBboxFilter), 'Contains': makeChildAppender(writeContainsFilter), 'Intersects': makeChildAppender(writeIntersectsFilter), + 'ResourceId': makeChildAppender(writeResourceIdFilter), 'Within': makeChildAppender(writeWithinFilter), 'PropertyIsEqualTo': makeChildAppender(writeComparisonFilter), 'PropertyIsNotEqualTo': makeChildAppender(writeComparisonFilter), @@ -944,7 +949,13 @@ function writeQuery(node, featureType, objectStack) { } else { typeName = featureType; } - node.setAttribute('typeName', typeName); + let typeNameAttr; + if (version === '2.0.0') { + typeNameAttr = 'typeNames'; + } else { + typeNameAttr = 'typeName'; + } + node.setAttribute(typeNameAttr, typeName); if (srsName) { node.setAttribute('srsName', srsName); } @@ -965,7 +976,7 @@ function writeQuery(node, featureType, objectStack) { ); const filter = context['filter']; if (filter) { - const child = createElementNS(OGCNS[version], 'Filter'); + const child = createElementNS(getFilterNS(version), 'Filter'); node.appendChild(child); writeFilterCondition(child, filter, objectStack); } @@ -1035,6 +1046,15 @@ function writeIntersectsFilter(node, filter, objectStack) { GML3.prototype.writeGeometryElement(node, filter.geometry, objectStack); } +/** + * @param {Element} node Element. + * @param {import("./filter/ResourceId.js").default} filter Filter. + * @param {Array<*>} objectStack Node stack. + */ +function writeResourceIdFilter(node, filter, objectStack) { + node.setAttribute('rid', /** @type {string} */ (filter.rid)); +} + /** * @param {Node} node Node. * @param {import("./filter/Within.js").default} filter Filter. @@ -1056,7 +1076,11 @@ function writeWithinFilter(node, filter, objectStack) { * @param {Array<*>} objectStack Node stack. */ function writeDuringFilter(node, filter, objectStack) { - const valueReference = createElementNS(FESNS, 'ValueReference'); + 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); @@ -1271,4 +1295,14 @@ function writeGetFeature(node, featureTypes, objectStack) { ); } +function getFilterNS(version) { + let ns; + if (version === '2.0.0') { + ns = FESNS[version]; + } else { + ns = OGCNS[version]; + } + return ns; +} + export default WFS; diff --git a/src/ol/format/filter.js b/src/ol/format/filter.js index c4d2c9615d..99490840f0 100644 --- a/src/ol/format/filter.js +++ b/src/ol/format/filter.js @@ -17,6 +17,7 @@ import LessThanOrEqualTo from './filter/LessThanOrEqualTo.js'; import Not from './filter/Not.js'; import NotEqualTo from './filter/NotEqualTo.js'; import Or from './filter/Or.js'; +import ResourceId from './filter/ResourceId.js'; import Within from './filter/Within.js'; /** @@ -260,3 +261,7 @@ export function like( export function during(propertyName, begin, end) { return new During(propertyName, begin, end); } + +export function resourceId(rid) { + return new ResourceId(rid); +} diff --git a/src/ol/format/filter/ResourceId.js b/src/ol/format/filter/ResourceId.js new file mode 100644 index 0000000000..d68a6bcf75 --- /dev/null +++ b/src/ol/format/filter/ResourceId.js @@ -0,0 +1,25 @@ +/** + * @module ol/format/filter/ResourceId + */ +import Filter from './Filter.js'; + +/** + * @classdesc + * + * @abstract + */ +class ResourceId extends Filter { + /** + * @param {!string} rid Resource ID. + */ + constructor(rid) { + super('ResourceId'); + + /** + * @type {!string} + */ + this.rid = rid; + } +} + +export default ResourceId; diff --git a/test/spec/ol/format/wfs.test.js b/test/spec/ol/format/wfs.test.js index 058aab97af..89f39d13cc 100644 --- a/test/spec/ol/format/wfs.test.js +++ b/test/spec/ol/format/wfs.test.js @@ -27,6 +27,7 @@ import { like as likeFilter, not as notFilter, or as orFilter, + resourceId as resourceIdFilter, within as withinFilter, } from '../../../../src/ol/format/filter.js'; import {parse} from '../../../../src/ol/xml.js'; @@ -1382,4 +1383,28 @@ describe('ol.format.WFS', function () { expect(serialized).to.xmleql(parse(text)); }); }); + + describe('WFS 2.0.0', function () { + let getFeatureXml; + before(function (done) { + afterLoadText('spec/ol/format/wfs/2.0.0/GetFeature.xml', function (xml) { + getFeatureXml = xml; + done(); + }); + }); + + it('GetFeature', function () { + const wfs = new WFS({ + version: '2.0.0', + }); + const filter = resourceIdFilter('bugsites.3'); + const serialized = wfs.writeGetFeature({ + featureNS: 'http://www.openplans.org/spearfish', + featureTypes: ['bugsites'], + featurePrefix: 'sf', + filter, + }); + expect(serialized).to.xmleql(parse(getFeatureXml)); + }); + }); }); diff --git a/test/spec/ol/format/wfs/2.0.0/GetFeature.xml b/test/spec/ol/format/wfs/2.0.0/GetFeature.xml new file mode 100644 index 0000000000..20e1b43f8c --- /dev/null +++ b/test/spec/ol/format/wfs/2.0.0/GetFeature.xml @@ -0,0 +1,20 @@ + + + + + + + + +