diff --git a/src/ol/format/getfeatureinfoformat.js b/src/ol/format/getfeatureinfoformat.js index 709fe891c9..d8a726cf94 100644 --- a/src/ol/format/getfeatureinfoformat.js +++ b/src/ol/format/getfeatureinfoformat.js @@ -1,5 +1,6 @@ goog.provide('ol.format.GetFeatureInfo'); +goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom'); goog.require('goog.dom.NodeType'); @@ -15,7 +16,7 @@ goog.require('ol.xml'); /** * @classdesc - * Format for reading MapServer GetFeatureInfo format.It uses + * Format for reading GetFeatureInfo format.It uses * ol.format.GML2 to read features. * * @constructor @@ -77,27 +78,43 @@ ol.format.GetFeatureInfo.prototype.readFeatures_ = function(node, objectStack) { node.namespaceURI = this.featureNS_; goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); var localName = ol.xml.getLocalName(node); - var features; + var features = []; + if (node.childNodes.length === 0) { + return features; + } if (localName == 'msGMLOutput') { - var context = objectStack[0]; - goog.asserts.assert(goog.isObject(context)); + goog.array.forEach(node.childNodes, function(layer) { + if (layer.nodeType !== goog.dom.NodeType.ELEMENT) { + return; + } + var context = objectStack[0]; + goog.asserts.assert(goog.isObject(context)); - var layer = node.firstElementChild; - goog.asserts.assert(layer.localName.indexOf(this.layerIdentifier_) >= 0); + goog.asserts.assert(layer.localName.indexOf(this.layerIdentifier_) >= 0); - var featureType = goog.string.remove(layer.localName, - this.layerIdentifier_) + this.featureIdentifier_; + var featureType = goog.string.remove(layer.localName, + this.layerIdentifier_) + this.featureIdentifier_; - goog.object.set(context, 'featureType', featureType); - goog.object.set(context, 'featureNS', this.featureNS_); + goog.object.set(context, 'featureType', featureType); + goog.object.set(context, 'featureNS', this.featureNS_); - var parsers = {}; - var parsersNS = {}; - parsers[featureType] = ol.xml.makeArrayPusher( - this.gmlFormat_.readFeatureElement, this.gmlFormat_); - parsersNS[goog.object.get(context, 'featureNS')] = parsers; - features = ol.xml.pushParseAndPop([], parsersNS, layer, objectStack, - this.gmlFormat_); + var parsers = {}; + parsers[featureType] = ol.xml.makeArrayPusher( + this.gmlFormat_.readFeatureElement, this.gmlFormat_); + var parsersNS = ol.xml.makeParsersNS( + [goog.object.get(context, 'featureNS'), null], parsers); + layer.namespaceURI = this.featureNS_; + var layerFeatures = ol.xml.pushParseAndPop( + [], parsersNS, layer, objectStack, this.gmlFormat_); + if (goog.isDef(layerFeatures)) { + goog.array.extend(/** @type {Array} */ (features), layerFeatures); + } + }, this); + } + if (localName == 'FeatureCollection') { + features = ol.xml.pushParseAndPop([], + this.gmlFormat_.FEATURE_COLLECTION_PARSERS, node, + [{}], this.gmlFormat_); } if (!goog.isDef(features)) { features = []; diff --git a/test/spec/ol/format/getfeatureinfoformat.test.js b/test/spec/ol/format/getfeatureinfoformat.test.js index 647df35c2d..1b9acd2333 100644 --- a/test/spec/ol/format/getfeatureinfoformat.test.js +++ b/test/spec/ol/format/getfeatureinfoformat.test.js @@ -37,6 +37,163 @@ describe('ol.format.GetFeatureInfo', function() { expect(feature.get('boundedBy')).to.eql( [-531138.686422, 5386348.414671, -117252.819653, 6144475.186022]); }); + + it('read empty response', function() { + // read empty response + var text = '' + + '' + + ' ' + + ' ' + + ''; + var features = new ol.format.GetFeatureInfo().readFeatures(text); + expect(features.length).to.be(0); + }); + + it('read empty attributes', function() { + text = + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 107397.266000,460681.063000 116568.188000,480609.250000' + + ' ' + + ' ' + + ' ' + + ' bar' + + ' ' + + ' ' + + ' ' + + ''; + var features = new ol.format.GetFeatureInfo().readFeatures(text); + expect(features.length).to.be(1); + expect(features[0].get('FOO')).to.be('bar'); + // FIXME is that really wanted ? + expect(features[0].get('EMPTY')).to.be(undefined); + }); + + it('read features from multiple layers', function() { + text = + '' + + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 129799.109000,467950.250000 133199.906000,468904.063000' + + ' ' + + ' ' + + ' ' + + ' 287' + + ' N403' + + ' #N403' + + ' 1' + + ' P' + + ' 4091.25' + + ' <shape>' + + ' <null>' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 129936.000000,468362.000000 131686.000000,473119.000000' + + ' ' + + ' ' + + ' ' + + ' 1251' + + ' 1515' + + ' 00:00:00 01/01/1998' + + ' 1472' + + ' 1309' + + ' D' + + ' 227' + + ' Vecht' + + ' 2' + + ' Vecht' + + ' 18.25' + + ' 23.995' + + ' 5745.09' + + ' <shape>' + + ' <null>' + + ' ' + + ' ' + + ''; + var features = new ol.format.GetFeatureInfo().readFeatures(text); + expect(features.length).to.be(2); + expect(features[0].get('OBJECTID')).to.be('287'); + expect(features[1].get('OBJECTID')).to.be('1251'); + }); + + it('read geoserver’s response', function() { + text = + '' + + '' + + ' ' + + ' ' + + ' ' + + '591943.9375,4925605 593045.625,4925845' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 3' + + ' secondary highway, hard surface' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + '593045.60746465,4925605.0059156 593024.32382915,4925606.79305411' + + ' 592907.54863574,4925624.85647524 592687.35111096,' + + '4925670.76834012 592430.76279218,4925678.79393165' + + ' 592285.97636109,4925715.70811767 592173.39165655,' + + '4925761.83511156 592071.1753393,4925793.95523514' + + ' 591985.96972625,4925831.59842486' + + ' 591943.98769455,4925844.93220071' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''; + var features = new ol.format.GetFeatureInfo().readFeatures(text); + expect(features.length).to.be(1); + expect(features[0].get('cat')).to.be('3'); + expect(features[0].getGeometry().getType()).to.be('MultiLineString'); + }); + }); }); }); diff --git a/test/spec/ol/format/wms/getfeatureinfo.xml b/test/spec/ol/format/wms/getfeatureinfo.xml index f431b15ad3..f00c6c4f93 100644 --- a/test/spec/ol/format/wms/getfeatureinfo.xml +++ b/test/spec/ol/format/wms/getfeatureinfo.xml @@ -1,5 +1,5 @@ - + ADCP de coque 2001 @@ -42,4 +42,4 @@ http://www.ifremer.fr/sismerData/jsp/visualisationMetadata3.jsp?strPortail=ifremer&langue=FR&pageOrigine=CS&cle1=108842_3&cle2=ADCP01 - \ No newline at end of file +