@geogirafe/lib-geoportal
Version:
GeoGirafe is a flexible application to build online geoportals.
92 lines (91 loc) • 3.34 kB
JavaScript
import { WFS as OlWFS } from 'ol/format.js';
import GML32 from 'ol/format/GML32.js';
import { CompositeCurveGML3, CompositeCurveGML32 } from './compositecurvegml.js';
/**
* WFS parser
*
* Extends ol.format.WFS to be able to read nested `FeatureCollections` in GML32,
* which are present in WFS 2.0.0 responses from MapServer, GeoServer and QGIS Server.
* This does not change behaviour for WFS 1.1.0 and 1.0.0.
*
* Can be removed later when the problem linked below is resolved in ol.
*
* Code copied and adapted from
* https://github.com/openlayers/openlayers/issues/12389
*/
export default class WfsParser extends OlWFS {
constructor(opt_options) {
const options = {
gmlFormat: opt_options?.gmlFormat,
version: opt_options?.version,
featureNS: opt_options?.featureNS,
featureType: opt_options?.featureType,
schemaLocation: opt_options?.schemaLocation
};
if (!options.gmlFormat) {
if (options.version === '2.0.0') {
options.gmlFormat = new CompositeCurveGML32(options);
}
else if (!options.version || options.version === '1.1.0') {
options.gmlFormat = new CompositeCurveGML3(options);
}
}
super(options);
}
readFeatures(source, opt_options) {
// @ts-expect-error gmlFormat_ is private in super class
if (this.gmlFormat_ instanceof GML32) {
return this.readFeaturesGML32(source, opt_options);
}
return super.readFeatures(source, opt_options);
}
readFeaturesGML32(source, opt_options) {
let doc;
if (source instanceof Document) {
doc = source;
}
else if (typeof source === 'string') {
const domParser = new DOMParser();
doc = domParser.parseFromString(source, 'application/xml');
}
else {
console.warn('Source for GML3.2 not supported!');
return [];
}
let features;
if (this.hasNestedFeatureCollectionsGML32(doc)) {
features = this.readNestedFeatureCollectionsGML32(doc, opt_options);
}
else {
features = super.readFeatures(doc.documentElement, opt_options);
}
return features ?? [];
}
readNestedFeatureCollectionsGML32(doc, opt_options) {
let features = [];
const children = doc.documentElement.children;
for (const child of children) {
if (this.isNestedFeatureCollection(child)) {
const collection = child.children.item(0);
if (collection?.children?.length) {
features = features.concat(super.readFeatures(collection, opt_options));
}
}
}
return features;
}
hasNestedFeatureCollectionsGML32(doc) {
const children = doc.documentElement.children;
for (const child of children) {
if (this.isNestedFeatureCollection(child)) {
return true;
}
}
return false;
}
isNestedFeatureCollection(element) {
return (element?.localName === 'member' &&
element.children?.length > 0 &&
element.children.item(0)?.localName === 'FeatureCollection');
}
}