From 7080c508a4ac25943d63838085a2bc81b5d8ae02 Mon Sep 17 00:00:00 2001 From: tsauerwein Date: Wed, 18 May 2016 11:24:30 +0200 Subject: [PATCH] Handle multiple featureMember elements for different types --- src/ol/format/gml/gmlbaseformat.js | 22 ++++-- .../gml/multiple-typenames-mapserver.xml | 40 ++++++++++ test/spec/ol/format/wfsformat.test.js | 79 +++++++++++++++++++ 3 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 test/spec/ol/format/gml/multiple-typenames-mapserver.xml diff --git a/src/ol/format/gml/gmlbaseformat.js b/src/ol/format/gml/gmlbaseformat.js index c09891056c..fa28970f8d 100644 --- a/src/ol/format/gml/gmlbaseformat.js +++ b/src/ol/format/gml/gmlbaseformat.js @@ -106,13 +106,13 @@ ol.format.GMLBase.ONLY_WHITESPACE_RE_ = /^[\s\xa0]*$/; /** * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. - * @return {Array.} Features. + * @return {Array. | undefined} Features. */ ol.format.GMLBase.prototype.readFeaturesInternal = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); var localName = node.localName; - var features; + var features = null; if (localName == 'FeatureCollection') { if (node.namespaceURI === 'http://www.opengis.net/wfs') { features = ol.xml.pushParseAndPop([], @@ -154,8 +154,11 @@ ol.format.GMLBase.prototype.readFeaturesInternal = function(node, objectStack) { } } } - context['featureType'] = featureType; - context['featureNS'] = featureNS; + if (localName != 'featureMember') { + // recheck featureType for each featureMember + context['featureType'] = featureType; + context['featureNS'] = featureNS; + } } if (typeof featureNS === 'string') { var ns = featureNS; @@ -178,9 +181,13 @@ ol.format.GMLBase.prototype.readFeaturesInternal = function(node, objectStack) { } parsersNS[featureNS[p]] = parsers; } - features = ol.xml.pushParseAndPop([], parsersNS, node, objectStack); + if (localName == 'featureMember') { + features = ol.xml.pushParseAndPop(undefined, parsersNS, node, objectStack); + } else { + features = ol.xml.pushParseAndPop([], parsersNS, node, objectStack); + } } - if (!features) { + if (features === null) { features = []; } return features; @@ -628,7 +635,8 @@ ol.format.GMLBase.prototype.readFeaturesFromNode = function(node, opt_options) { if (opt_options) { ol.object.assign(options, this.getReadOptions(node, opt_options)); } - return this.readFeaturesInternal(node, [options]); + var features = this.readFeaturesInternal(node, [options]); + return features || []; }; diff --git a/test/spec/ol/format/gml/multiple-typenames-mapserver.xml b/test/spec/ol/format/gml/multiple-typenames-mapserver.xml new file mode 100644 index 0000000000..182ceadfb1 --- /dev/null +++ b/test/spec/ol/format/gml/multiple-typenames-mapserver.xml @@ -0,0 +1,40 @@ + + + + + 539647.507960,151807.355864 540717.151197,152910.783525 + + + + + 347267989 + + + + + 983813610 + + + + + 347549357 + + + + + 34751234 + + + + + 34751235 + + + diff --git a/test/spec/ol/format/wfsformat.test.js b/test/spec/ol/format/wfsformat.test.js index cd49f089af..3460f7a046 100644 --- a/test/spec/ol/format/wfsformat.test.js +++ b/test/spec/ol/format/wfsformat.test.js @@ -791,6 +791,34 @@ describe('ol.format.WFS', function() { }); + describe('when parsing multiple feature types separately', function() { + + var lineFeatures, polygonFeatures; + before(function(done) { + afterLoadText('spec/ol/format/gml/multiple-typenames.xml', function(xml) { + try { + lineFeatures = new ol.format.WFS({ + featureNS: 'http://localhost:8080/official', + featureType: ['planet_osm_line'] + }).readFeatures(xml); + polygonFeatures = new ol.format.WFS({ + featureNS: 'http://localhost:8080/official', + featureType: ['planet_osm_polygon'] + }).readFeatures(xml); + } catch (e) { + done(e); + } + done(); + }); + }); + + it('reads all features', function() { + expect(lineFeatures.length).to.be(3); + expect(polygonFeatures.length).to.be(9); + }); + + }); + describe('when parsing multiple feature types', function() { var features; @@ -811,6 +839,57 @@ describe('ol.format.WFS', function() { }); + describe('when parsing multiple feature types (MapServer)', function() { + + var features; + before(function(done) { + afterLoadText('spec/ol/format/gml/multiple-typenames-mapserver.xml', function(xml) { + try { + features = new ol.format.WFS().readFeatures(xml); + } catch (e) { + done(e); + } + done(); + }); + }); + + it('reads all features', function() { + expect(features.length).to.be(5); + features.forEach(function(feature) { + expect(feature instanceof ol.Feature).to.be(true); + }); + }); + + }); + + describe('when parsing multiple feature types separately (MapServer)', function() { + + var busFeatures, infoFeatures; + before(function(done) { + afterLoadText('spec/ol/format/gml/multiple-typenames-mapserver.xml', function(xml) { + try { + busFeatures = new ol.format.WFS({ + featureNS: 'http://mapserver.gis.umn.edu/mapserver', + featureType: ['bus_stop'] + }).readFeatures(xml); + infoFeatures = new ol.format.WFS({ + featureNS: 'http://mapserver.gis.umn.edu/mapserver', + featureType: ['information'] + }).readFeatures(xml); + } catch (e) { + done(e); + } + done(); + }); + }); + + it('reads all features', function() { + expect(busFeatures.length).to.be(3); + expect(infoFeatures.length).to.be(2); + }); + + }); + });