From 5fba2dd7d5accd6fe22ee06bf9b8a55131502423 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Tue, 4 Feb 2014 15:25:23 +0100 Subject: [PATCH 1/9] Move src/ol/parser/* and tests into old directory --- {src/ol => old}/parser/ogc/exceptionreportparser.js | 0 {src/ol => old}/parser/ogc/versionedparser.js | 0 {src/ol => old}/parser/ogc/wmscapabilitiesparser.exports | 0 {src/ol => old}/parser/ogc/wmscapabilitiesparser.js | 0 {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1.js | 0 {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1_0_0.js | 0 {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1_1.js | 0 {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1_1_0.js | 0 {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1_1_1.js | 0 {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1_1_1_WMSC.js | 0 {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1_3_0.js | 0 {src/ol => old}/parser/parser.js | 0 {src/ol => old}/parser/xmlparser.js | 0 {test => old/test}/spec/ol/parser/ogc/exceptionreport.test.js | 0 {test => old/test}/spec/ol/parser/ogc/versioned.test.js | 0 {test => old/test}/spec/ol/parser/ogc/wmscapabilities.test.js | 0 .../test}/spec/ol/parser/ogc/wmscapabilities_v1_0_0.test.js | 0 .../test}/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js | 0 .../test}/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js | 0 .../test}/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js | 0 .../test}/spec/ol/parser/ogc/xml/wmscapabilities_v1_0_0.xml | 0 .../ol/parser/ogc/xml/wmscapabilities_v1_1_1/exceptionsample.xml | 0 .../spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml | 0 .../spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml | 0 .../ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/fallback.xml | 0 .../spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/wmsc.xml | 0 .../ol/parser/ogc/xml/wmscapabilities_v1_3_0/exceptionsample.xml | 0 .../spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml | 0 28 files changed, 0 insertions(+), 0 deletions(-) rename {src/ol => old}/parser/ogc/exceptionreportparser.js (100%) rename {src/ol => old}/parser/ogc/versionedparser.js (100%) rename {src/ol => old}/parser/ogc/wmscapabilitiesparser.exports (100%) rename {src/ol => old}/parser/ogc/wmscapabilitiesparser.js (100%) rename {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1.js (100%) rename {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1_0_0.js (100%) rename {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1_1.js (100%) rename {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1_1_0.js (100%) rename {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1_1_1.js (100%) rename {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1_1_1_WMSC.js (100%) rename {src/ol => old}/parser/ogc/wmscapabilitiesparser_v1_3_0.js (100%) rename {src/ol => old}/parser/parser.js (100%) rename {src/ol => old}/parser/xmlparser.js (100%) rename {test => old/test}/spec/ol/parser/ogc/exceptionreport.test.js (100%) rename {test => old/test}/spec/ol/parser/ogc/versioned.test.js (100%) rename {test => old/test}/spec/ol/parser/ogc/wmscapabilities.test.js (100%) rename {test => old/test}/spec/ol/parser/ogc/wmscapabilities_v1_0_0.test.js (100%) rename {test => old/test}/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js (100%) rename {test => old/test}/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js (100%) rename {test => old/test}/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js (100%) rename {test => old/test}/spec/ol/parser/ogc/xml/wmscapabilities_v1_0_0.xml (100%) rename {test => old/test}/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/exceptionsample.xml (100%) rename {test => old/test}/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml (100%) rename {test => old/test}/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml (100%) rename {test => old/test}/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/fallback.xml (100%) rename {test => old/test}/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/wmsc.xml (100%) rename {test => old/test}/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/exceptionsample.xml (100%) rename {test => old/test}/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml (100%) diff --git a/src/ol/parser/ogc/exceptionreportparser.js b/old/parser/ogc/exceptionreportparser.js similarity index 100% rename from src/ol/parser/ogc/exceptionreportparser.js rename to old/parser/ogc/exceptionreportparser.js diff --git a/src/ol/parser/ogc/versionedparser.js b/old/parser/ogc/versionedparser.js similarity index 100% rename from src/ol/parser/ogc/versionedparser.js rename to old/parser/ogc/versionedparser.js diff --git a/src/ol/parser/ogc/wmscapabilitiesparser.exports b/old/parser/ogc/wmscapabilitiesparser.exports similarity index 100% rename from src/ol/parser/ogc/wmscapabilitiesparser.exports rename to old/parser/ogc/wmscapabilitiesparser.exports diff --git a/src/ol/parser/ogc/wmscapabilitiesparser.js b/old/parser/ogc/wmscapabilitiesparser.js similarity index 100% rename from src/ol/parser/ogc/wmscapabilitiesparser.js rename to old/parser/ogc/wmscapabilitiesparser.js diff --git a/src/ol/parser/ogc/wmscapabilitiesparser_v1.js b/old/parser/ogc/wmscapabilitiesparser_v1.js similarity index 100% rename from src/ol/parser/ogc/wmscapabilitiesparser_v1.js rename to old/parser/ogc/wmscapabilitiesparser_v1.js diff --git a/src/ol/parser/ogc/wmscapabilitiesparser_v1_0_0.js b/old/parser/ogc/wmscapabilitiesparser_v1_0_0.js similarity index 100% rename from src/ol/parser/ogc/wmscapabilitiesparser_v1_0_0.js rename to old/parser/ogc/wmscapabilitiesparser_v1_0_0.js diff --git a/src/ol/parser/ogc/wmscapabilitiesparser_v1_1.js b/old/parser/ogc/wmscapabilitiesparser_v1_1.js similarity index 100% rename from src/ol/parser/ogc/wmscapabilitiesparser_v1_1.js rename to old/parser/ogc/wmscapabilitiesparser_v1_1.js diff --git a/src/ol/parser/ogc/wmscapabilitiesparser_v1_1_0.js b/old/parser/ogc/wmscapabilitiesparser_v1_1_0.js similarity index 100% rename from src/ol/parser/ogc/wmscapabilitiesparser_v1_1_0.js rename to old/parser/ogc/wmscapabilitiesparser_v1_1_0.js diff --git a/src/ol/parser/ogc/wmscapabilitiesparser_v1_1_1.js b/old/parser/ogc/wmscapabilitiesparser_v1_1_1.js similarity index 100% rename from src/ol/parser/ogc/wmscapabilitiesparser_v1_1_1.js rename to old/parser/ogc/wmscapabilitiesparser_v1_1_1.js diff --git a/src/ol/parser/ogc/wmscapabilitiesparser_v1_1_1_WMSC.js b/old/parser/ogc/wmscapabilitiesparser_v1_1_1_WMSC.js similarity index 100% rename from src/ol/parser/ogc/wmscapabilitiesparser_v1_1_1_WMSC.js rename to old/parser/ogc/wmscapabilitiesparser_v1_1_1_WMSC.js diff --git a/src/ol/parser/ogc/wmscapabilitiesparser_v1_3_0.js b/old/parser/ogc/wmscapabilitiesparser_v1_3_0.js similarity index 100% rename from src/ol/parser/ogc/wmscapabilitiesparser_v1_3_0.js rename to old/parser/ogc/wmscapabilitiesparser_v1_3_0.js diff --git a/src/ol/parser/parser.js b/old/parser/parser.js similarity index 100% rename from src/ol/parser/parser.js rename to old/parser/parser.js diff --git a/src/ol/parser/xmlparser.js b/old/parser/xmlparser.js similarity index 100% rename from src/ol/parser/xmlparser.js rename to old/parser/xmlparser.js diff --git a/test/spec/ol/parser/ogc/exceptionreport.test.js b/old/test/spec/ol/parser/ogc/exceptionreport.test.js similarity index 100% rename from test/spec/ol/parser/ogc/exceptionreport.test.js rename to old/test/spec/ol/parser/ogc/exceptionreport.test.js diff --git a/test/spec/ol/parser/ogc/versioned.test.js b/old/test/spec/ol/parser/ogc/versioned.test.js similarity index 100% rename from test/spec/ol/parser/ogc/versioned.test.js rename to old/test/spec/ol/parser/ogc/versioned.test.js diff --git a/test/spec/ol/parser/ogc/wmscapabilities.test.js b/old/test/spec/ol/parser/ogc/wmscapabilities.test.js similarity index 100% rename from test/spec/ol/parser/ogc/wmscapabilities.test.js rename to old/test/spec/ol/parser/ogc/wmscapabilities.test.js diff --git a/test/spec/ol/parser/ogc/wmscapabilities_v1_0_0.test.js b/old/test/spec/ol/parser/ogc/wmscapabilities_v1_0_0.test.js similarity index 100% rename from test/spec/ol/parser/ogc/wmscapabilities_v1_0_0.test.js rename to old/test/spec/ol/parser/ogc/wmscapabilities_v1_0_0.test.js diff --git a/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js b/old/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js similarity index 100% rename from test/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js rename to old/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js diff --git a/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js b/old/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js similarity index 100% rename from test/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js rename to old/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js diff --git a/test/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js b/old/test/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js similarity index 100% rename from test/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js rename to old/test/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_0_0.xml b/old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_0_0.xml similarity index 100% rename from test/spec/ol/parser/ogc/xml/wmscapabilities_v1_0_0.xml rename to old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_0_0.xml diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/exceptionsample.xml b/old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/exceptionsample.xml similarity index 100% rename from test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/exceptionsample.xml rename to old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/exceptionsample.xml diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml b/old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml similarity index 100% rename from test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml rename to old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/gssample.xml diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml b/old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml similarity index 100% rename from test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml rename to old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/ogcsample.xml diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/fallback.xml b/old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/fallback.xml similarity index 100% rename from test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/fallback.xml rename to old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/fallback.xml diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/wmsc.xml b/old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/wmsc.xml similarity index 100% rename from test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/wmsc.xml rename to old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1_WMSC/wmsc.xml diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/exceptionsample.xml b/old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/exceptionsample.xml similarity index 100% rename from test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/exceptionsample.xml rename to old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/exceptionsample.xml diff --git a/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml b/old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml similarity index 100% rename from test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml rename to old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml From 55a8f9a5ece100ab02d343968ba9b07f3ab7f101 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 26 Feb 2014 09:34:11 +0100 Subject: [PATCH 2/9] Remove duplicate files --- .../parser/ogc/xml/exceptionreport/ows1_0_0.xml | 9 --------- .../parser/ogc/xml/exceptionreport/ows1_1_0.xml | 9 --------- .../parser/ogc/xml/exceptionreport/wms1_3_0.xml | 16 ---------------- 3 files changed, 34 deletions(-) delete mode 100644 test/spec/ol/parser/ogc/xml/exceptionreport/ows1_0_0.xml delete mode 100644 test/spec/ol/parser/ogc/xml/exceptionreport/ows1_1_0.xml delete mode 100644 test/spec/ol/parser/ogc/xml/exceptionreport/wms1_3_0.xml diff --git a/test/spec/ol/parser/ogc/xml/exceptionreport/ows1_0_0.xml b/test/spec/ol/parser/ogc/xml/exceptionreport/ows1_0_0.xml deleted file mode 100644 index 141558d04d..0000000000 --- a/test/spec/ol/parser/ogc/xml/exceptionreport/ows1_0_0.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - Update error: Error occured updating features - Second exception line - - diff --git a/test/spec/ol/parser/ogc/xml/exceptionreport/ows1_1_0.xml b/test/spec/ol/parser/ogc/xml/exceptionreport/ows1_1_0.xml deleted file mode 100644 index 9fed1376dd..0000000000 --- a/test/spec/ol/parser/ogc/xml/exceptionreport/ows1_1_0.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - Update error: Error occured updating features - Second exception line - - diff --git a/test/spec/ol/parser/ogc/xml/exceptionreport/wms1_3_0.xml b/test/spec/ol/parser/ogc/xml/exceptionreport/wms1_3_0.xml deleted file mode 100644 index 631d67064a..0000000000 --- a/test/spec/ol/parser/ogc/xml/exceptionreport/wms1_3_0.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - Plain text message about an error. - Another error message, this one with a service exception code supplied. - - , line 42 -A message that includes angle brackets in text must be enclosed in a Character Data Section as in this example. All XML-like markup is ignored except for this sequence of three closing characters:' + -]]> - - - foo.c An error occurred Similarly, actual XML can be enclosed in a CDATA section. A generic parser will ignore that XML, but application-specific software may choose to process it. ]]> - - From 13698d0d0633d16a7071b33e3b713f778eca7075 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 12 Feb 2014 10:05:58 +0100 Subject: [PATCH 3/9] Add ol.format.XML --- src/ol/format/xmlformat.js | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/ol/format/xmlformat.js diff --git a/src/ol/format/xmlformat.js b/src/ol/format/xmlformat.js new file mode 100644 index 0000000000..28f1051273 --- /dev/null +++ b/src/ol/format/xmlformat.js @@ -0,0 +1,45 @@ +goog.provide('ol.format.XML'); + +goog.require('goog.asserts'); +goog.require('ol.xml'); + + + +/** + * @constructor + */ +ol.format.XML = function() { +}; + + +/** + * @param {Document|Node|string} source Source. + * @return {Object} + */ +ol.format.XML.prototype.read = function(source) { + if (ol.xml.isDocument(source)) { + return this.readFromDocument(/** @type {Document} */ (source)); + } else if (ol.xml.isNode(source)) { + return this.readFromNode(/** @type {Node} */ (source)); + } else if (goog.isString(source)) { + var doc = ol.xml.load(source); + return this.readFromDocument(doc); + } else { + goog.asserts.fail(); + return null; + } +}; + + +/** + * @param {Document} doc Document. + * @return {Object} + */ +ol.format.XML.prototype.readFromDocument = goog.abstractMethod; + + +/** + * @param {Node} node Node. + * @return {Object} + */ +ol.format.XML.prototype.readFromNode = goog.abstractMethod; From 2f53c4a3ad3b7a903ffd2a9308cb141573124880 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 12 Feb 2014 11:31:04 +0100 Subject: [PATCH 4/9] Add ol.format.XLink --- src/ol/format/xlinkformat.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/ol/format/xlinkformat.js diff --git a/src/ol/format/xlinkformat.js b/src/ol/format/xlinkformat.js new file mode 100644 index 0000000000..a01b61ec7e --- /dev/null +++ b/src/ol/format/xlinkformat.js @@ -0,0 +1,17 @@ +goog.provide('ol.format.XLink'); + + +/** + * @const + * @type {string} + */ +ol.format.XLink.NAMESPACE_URI = 'http://www.w3.org/1999/xlink'; + + +/** + * @param {Node} node Node. + * @return {boolean|undefined} Boolean. + */ +ol.format.XLink.readHref = function(node) { + return node.getAttributeNS(ol.format.XLink.NAMESPACE_URI, 'href'); +}; From d7d2b3353dc5a4f7039d3d9776f6f388ab0ba74f Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 12 Feb 2014 13:01:23 +0100 Subject: [PATCH 5/9] Add ol.xml.makeObjectPropertyPusher --- src/ol/xml.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/ol/xml.js b/src/ol/xml.js index 89d0042ed3..be03cdda9a 100644 --- a/src/ol/xml.js +++ b/src/ol/xml.js @@ -410,6 +410,36 @@ ol.xml.makeReplacer = function(valueReader, opt_this) { }; +/** + * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader. + * @param {string=} opt_property Property. + * @param {T=} opt_this The object to use as `this` in `valueReader`. + * @return {ol.xml.Parser} Parser. + * @template T + */ +ol.xml.makeObjectPropertyPusher = + function(valueReader, opt_property, opt_this) { + goog.asserts.assert(goog.isDef(valueReader)); + return ( + /** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + */ + function(node, objectStack) { + var value = valueReader.call(opt_this, node, objectStack); + if (goog.isDef(value)) { + var object = /** @type {Object} */ + (objectStack[objectStack.length - 1]); + var property = goog.isDef(opt_property) ? + opt_property : node.localName; + goog.asserts.assert(goog.isObject(object)); + var array = goog.object.setIfUndefined(object, property, []); + array.push(value); + } + }); +}; + + /** * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader. * @param {string=} opt_property Property. From 1c13d6ed694e1e2071d16d4136768afe7661ca55 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 5 Feb 2014 14:22:35 +0100 Subject: [PATCH 6/9] Add ol.format.WMSCapabilities --- examples/wms-capabilities.js | 24 +- .../ol/parser/ogc/wmscapabilities.test.js | 45 - src/ol/format/wmscapabilitiesformat.exports | 2 + src/ol/format/wmscapabilitiesformat.js | 813 ++++++++++++++++++ .../spec/ol/format/wms}/ogcsample.xml | 0 test/spec/ol/format/wmscapabilities.test.js | 148 ++++ 6 files changed, 969 insertions(+), 63 deletions(-) delete mode 100644 old/test/spec/ol/parser/ogc/wmscapabilities.test.js create mode 100644 src/ol/format/wmscapabilitiesformat.exports create mode 100644 src/ol/format/wmscapabilitiesformat.js rename {old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0 => test/spec/ol/format/wms}/ogcsample.xml (100%) create mode 100644 test/spec/ol/format/wmscapabilities.test.js diff --git a/examples/wms-capabilities.js b/examples/wms-capabilities.js index 8566372599..2e3d201026 100644 --- a/examples/wms-capabilities.js +++ b/examples/wms-capabilities.js @@ -1,20 +1,8 @@ -goog.require('ol.parser.ogc.WMSCapabilities'); +goog.require('ol.format.WMSCapabilities'); -var parser = new ol.parser.ogc.WMSCapabilities(), result; -var url = 'data/ogcsample.xml'; +var parser = new ol.format.WMSCapabilities(); -var xhr = new XMLHttpRequest(); -xhr.open('GET', url, true); - - -/** - * onload handler for the XHR request. - */ -xhr.onload = function() { - if (xhr.status == 200) { - result = parser.read(xhr.responseXML); - document.getElementById('log').innerHTML = - window.JSON.stringify(result, undefined, 2); - } -}; -xhr.send(); +$.ajax('data/ogcsample.xml').then(function(response) { + var result = parser.read(response); + $('#log').html(window.JSON.stringify(result, null, 2)); +}); diff --git a/old/test/spec/ol/parser/ogc/wmscapabilities.test.js b/old/test/spec/ol/parser/ogc/wmscapabilities.test.js deleted file mode 100644 index 315368c425..0000000000 --- a/old/test/spec/ol/parser/ogc/wmscapabilities.test.js +++ /dev/null @@ -1,45 +0,0 @@ -goog.provide('ol.test.parser.ogc.WMSCapabilities'); - -describe('test WMSCapabilities', function() { - describe('test getVersion', function() { - var snippet = '' + - ''; - var snippet2 = '' + - ''; - it('Version taken from document', function() { - var parser = new ol.parser.ogc.WMSCapabilities(); - var data = parser.read(snippet); - expect(data.version).to.eql('1.3.0'); - }); - it('Version taken from parser takes preference', function() { - var parser = new ol.parser.ogc.WMSCapabilities({version: '1.1.0'}); - var data = parser.read(snippet); - expect(data.version).to.eql('1.1.0'); - }); - it('If nothing else is set, defaultVersion should be returned', function() { - var parser = new ol.parser.ogc.WMSCapabilities({defaultVersion: '1.1.1'}); - var data = parser.read(snippet2); - expect(data.version).to.eql('1.1.1'); - }); - var parser = new ol.parser.ogc.WMSCapabilities({defaultVersion: '1.1.1'}); - it('Version from options returned', function() { - var version = parser.getVersion(null, {version: '1.3.0'}); - expect(version).to.eql('1.3.0'); - }); - var msg = 'defaultVersion returned if no version specified in options ' + - 'and no version on the format'; - it(msg, function() { - var version = parser.getVersion(null); - expect(version).to.eql('1.1.1'); - }); - msg = 'version returned of the Format if no version specified in options'; - it(msg, function() { - parser.version = '1.1.0'; - var version = parser.getVersion(null); - expect(version).to.eql('1.1.0'); - }); - }); -}); - -goog.require('ol.parser.ogc.WMSCapabilities'); diff --git a/src/ol/format/wmscapabilitiesformat.exports b/src/ol/format/wmscapabilitiesformat.exports new file mode 100644 index 0000000000..0b1c5a8deb --- /dev/null +++ b/src/ol/format/wmscapabilitiesformat.exports @@ -0,0 +1,2 @@ +@exportSymbol ol.format.WMSCapabilities +@exportProperty ol.format.WMSCapabilities.prototype.read diff --git a/src/ol/format/wmscapabilitiesformat.js b/src/ol/format/wmscapabilitiesformat.js new file mode 100644 index 0000000000..19d3d8355a --- /dev/null +++ b/src/ol/format/wmscapabilitiesformat.js @@ -0,0 +1,813 @@ +goog.provide('ol.format.WMSCapabilities'); + +goog.require('goog.array'); +goog.require('goog.asserts'); +goog.require('goog.dom.NodeType'); +goog.require('goog.object'); +goog.require('goog.string'); +goog.require('ol.format.XLink'); +goog.require('ol.format.XML'); +goog.require('ol.format.XSD'); +goog.require('ol.xml'); + + +/** + * @typedef {{westBoundLongitude: number, + * southBoundLatitude: number, + * eastBoundLongitude: number, + * northBoundLatitude: number}} + */ +ol.format.EXGeographicBoundingBoxType; + + + +/** + * @constructor + * @extends {ol.format.XML} + */ +ol.format.WMSCapabilities = function() { + + goog.base(this); + + /** + * @type {string|undefined} + */ + this.version = undefined; +}; +goog.inherits(ol.format.WMSCapabilities, ol.format.XML); + + +/** + * @param {Document} doc Document. + * @return {Object} WMS Capability object. + */ +ol.format.WMSCapabilities.prototype.readFromDocument = function(doc) { + goog.asserts.assert(doc.nodeType == goog.dom.NodeType.DOCUMENT); + for (var n = doc.firstChild; !goog.isNull(n); n = n.nextSibling) { + if (n.nodeType == goog.dom.NodeType.ELEMENT) { + return this.readFromNode(n); + } + } + return null; +}; + + +/** + * @param {Node} node Node. + * @return {Object} WMS Capability object. + */ +ol.format.WMSCapabilities.prototype.readFromNode = function(node) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'WMS_Capabilities' || + node.localName == 'WMT_MS_Capabilities'); + this.version = goog.string.trim(node.getAttribute('version')); + goog.asserts.assertString(this.version); + var wmsCapabilityObject = ol.xml.pushParseAndPop({ + 'version': this.version + }, ol.format.WMSCapabilities.PARSERS_, node, []); + return goog.isDef(wmsCapabilityObject) ? wmsCapabilityObject : null; +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object|undefined} Attribution object. + */ +ol.format.WMSCapabilities.readAttribution_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Attribution'); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.ATTRIBUTION_PARSERS_, node, objectStack); +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object} Bounding box object. + */ +ol.format.WMSCapabilities.readBoundingBox_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'BoundingBox'); + + var extent = /** @type {ol.Extent} */ ([ + ol.format.XSD.readDecimalString(node.getAttribute('minx')), + ol.format.XSD.readDecimalString(node.getAttribute('miny')), + ol.format.XSD.readDecimalString(node.getAttribute('maxx')), + ol.format.XSD.readDecimalString(node.getAttribute('maxy')) + ]); + + var resolutions = /** @type {Array.} */ ([ + ol.format.XSD.readDecimalString(node.getAttribute('resx')), + ol.format.XSD.readDecimalString(node.getAttribute('resy')) + ]); + + return { + 'crs': node.getAttribute('CRS'), + 'extent': extent, + 'res': resolutions + }; +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {ol.Extent|undefined} Bounding box object. + */ +ol.format.WMSCapabilities.readEXGeographicBoundingBox_ = + function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'EX_GeographicBoundingBox'); + var geographicBoundingBox = ol.xml.pushParseAndPop( + /** @type {ol.format.EXGeographicBoundingBoxType} */ ({}), + ol.format.WMSCapabilities.EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS_, + node, objectStack); + return /** @type {ol.Extent} */ ([ + geographicBoundingBox.westBoundLongitude, + geographicBoundingBox.southBoundLatitude, + geographicBoundingBox.eastBoundLongitude, + geographicBoundingBox.northBoundLatitude + ]); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} Capability object. + */ +ol.format.WMSCapabilities.readCapability_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Capability'); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.CAPABILITY_PARSERS_, node, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} Service object. + */ +ol.format.WMSCapabilities.readService_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Service'); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.SERVICE_PARSERS_, node, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} Contact information object. + */ +ol.format.WMSCapabilities.readContactInformation_ = + function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'ContactInformation'); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.CONTACT_INFORMATION_PARSERS_, + node, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} Contact person object. + */ +ol.format.WMSCapabilities.readContactPersonPrimary_ = + function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'ContactPersonPrimary'); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.CONTACT_PERSON_PARSERS_, + node, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} Contact address object. + */ +ol.format.WMSCapabilities.readContactAddress_ = + function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'ContactAddress'); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.CONTACT_ADDRESS_PARSERS_, + node, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Array.|undefined} Format array. + */ +ol.format.WMSCapabilities.readException_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Exception'); + return ol.xml.pushParseAndPop( + [], ol.format.WMSCapabilities.EXCEPTION_PARSERS_, node, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Object|undefined} Layer object. + */ +ol.format.WMSCapabilities.readCapabilityLayer_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Layer'); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.LAYER_PARSERS_, node, objectStack); +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object|undefined} Layer object. + */ +ol.format.WMSCapabilities.readLayer_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Layer'); + var parentLayerObject = /** @type {Object.} */ + (objectStack[objectStack.length - 1]); + + var layerObject = /** @type {Object.} */ (ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.LAYER_PARSERS_, node, objectStack)); + + if (goog.isDef(layerObject)) { + var queryable = + ol.format.XSD.readBooleanString(node.getAttribute('queryable')); + if (!goog.isDef(queryable)) { + queryable = goog.object.get(parentLayerObject, 'queryable'); + } + goog.object.set( + layerObject, 'queryable', goog.isDef(queryable) ? queryable : false); + + var cascaded = ol.format.XSD.readNonNegativeIntegerString( + node.getAttribute('cascaded')); + if (!goog.isDef(cascaded)) { + cascaded = goog.object.get(parentLayerObject, 'cascaded'); + } + goog.object.set(layerObject, 'cascaded', cascaded); + + var opaque = ol.format.XSD.readBooleanString(node.getAttribute('opaque')); + if (!goog.isDef(opaque)) { + opaque = goog.object.get(parentLayerObject, 'opaque'); + } + goog.object.set(layerObject, 'opaque', goog.isDef(opaque) ? opaque : false); + + var noSubsets = + ol.format.XSD.readBooleanString(node.getAttribute('noSubsets')); + if (!goog.isDef(noSubsets)) { + noSubsets = goog.object.get(parentLayerObject, 'noSubsets'); + } + goog.object.set( + layerObject, 'noSubsets', goog.isDef(noSubsets) ? noSubsets : false); + + var fixedWidth = + ol.format.XSD.readDecimalString(node.getAttribute('fixedWidth')); + if (!goog.isDef(fixedWidth)) { + fixedWidth = goog.object.get(parentLayerObject, 'fixedWidth'); + } + goog.object.set(layerObject, 'fixedWidth', fixedWidth); + + var fixedHeight = + ol.format.XSD.readDecimalString(node.getAttribute('fixedHeight')); + if (!goog.isDef(fixedHeight)) { + fixedHeight = goog.object.get(parentLayerObject, 'fixedHeight'); + } + goog.object.set(layerObject, 'fixedHeight', fixedHeight); + + // See 7.2.4.8 + var addKeys = ['Style', 'CRS', 'AuthorityURL']; + goog.array.forEach(addKeys, function(key) { + var parentValue = goog.object.get(parentLayerObject, key); + if (goog.isDef(parentValue)) { + var childValue = goog.object.setIfUndefined(layerObject, key, []); + childValue = childValue.concat(parentValue); + } + }); + + var replaceKeys = ['EX_GeographicBoundingBox', 'BoundingBox', 'Dimension', + 'Attribution', 'MinScaleDenominator', 'MaxScaleDenominator']; + goog.array.forEach(replaceKeys, function(key) { + var childValue = goog.object.get(layerObject, key); + if (!goog.isDef(childValue)) { + var parentValue = goog.object.get(parentLayerObject, key); + goog.object.set(layerObject, key, parentValue); + } + }); + + return layerObject; + } +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object} Dimension object. + */ +ol.format.WMSCapabilities.readDimension_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Dimension'); + var dimensionObject = { + 'name': node.getAttribute('name'), + 'units': node.getAttribute('units'), + 'unitSymbol': node.getAttribute('unitSymbol'), + 'default': node.getAttribute('default'), + 'multipleValues': ol.format.XSD.readBooleanString( + node.getAttribute('multipleValues')), + 'nearestValue': ol.format.XSD.readBooleanString( + node.getAttribute('nearestValue')), + 'current': ol.format.XSD.readBooleanString(node.getAttribute('current')), + 'values': ol.format.XSD.readString(node) + }; + return dimensionObject; +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object|undefined} Online resource object. + */ +ol.format.WMSCapabilities.readFormatOnlineresource_ = + function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.FORMAT_ONLINERESOURCE_PARSERS_, + node, objectStack); +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object|undefined} Request object. + */ +ol.format.WMSCapabilities.readRequest_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Request'); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.REQUEST_PARSERS_, node, objectStack); +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object|undefined} DCP type object. + */ +ol.format.WMSCapabilities.readDCPType_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'DCPType'); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.DCPTYPE_PARSERS_, node, objectStack); +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object|undefined} HTTP object. + */ +ol.format.WMSCapabilities.readHTTP_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'HTTP'); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.HTTP_PARSERS_, node, objectStack); +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object|undefined} Operation type object. + */ +ol.format.WMSCapabilities.readOperationType_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.OPERATIONTYPE_PARSERS_, node, objectStack); +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object|undefined} Online resource object. + */ +ol.format.WMSCapabilities.readSizedFormatOnlineresource_ = + function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + var formatOnlineresource = + ol.format.WMSCapabilities.readFormatOnlineresource_(node, objectStack); + if (goog.isDef(formatOnlineresource)) { + var size = /** @type {ol.Size} */ ([ + ol.format.XSD.readNonNegativeIntegerString(node.getAttribute('width')), + ol.format.XSD.readNonNegativeIntegerString(node.getAttribute('height')) + ]); + goog.object.set(formatOnlineresource, 'size', size); + return formatOnlineresource; + } + return undefined; +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object|undefined} Authority URL object. + */ +ol.format.WMSCapabilities.readAuthorityURL_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'AuthorityURL'); + var authorityObject = + ol.format.WMSCapabilities.readFormatOnlineresource_(node, objectStack); + if (goog.isDef(authorityObject)) { + goog.object.set(authorityObject, 'name', node.getAttribute('name')); + return authorityObject; + } + return undefined; +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object|undefined} Metadata URL object. + */ +ol.format.WMSCapabilities.readMetadataURL_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'MetadataURL'); + var metadataObject = + ol.format.WMSCapabilities.readFormatOnlineresource_(node, objectStack); + if (goog.isDef(metadataObject)) { + goog.object.set(metadataObject, 'type', node.getAttribute('type')); + return metadataObject; + } + return undefined; +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Object|undefined} Style object. + */ +ol.format.WMSCapabilities.readStyle_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Style'); + return ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.STYLE_PARSERS_, node, objectStack); +}; + + +/** + * @private + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Array.|undefined} Keyword list. + */ +ol.format.WMSCapabilities.readKeywordList_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'KeywordList'); + return ol.xml.pushParseAndPop( + [], ol.format.WMSCapabilities.KEYWORDLIST_PARSERS_, node, objectStack); +}; + + +/** + * @const + * @private + * @type {Array.} + */ +ol.format.WMSCapabilities.NAMESPACE_URIS_ = [ + null, + 'http://www.opengis.net/wms' +]; + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'Service': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readService_), + 'Capability': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readCapability_) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.CAPABILITY_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'Request': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readRequest_), + 'Exception': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readException_), + 'Layer': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readCapabilityLayer_) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.SERVICE_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'Name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'Title': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'Abstract': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'KeywordList': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readKeywordList_), + 'OnlineResource': ol.xml.makeObjectPropertySetter( + ol.format.XLink.readHref), + 'ContactInformation': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readContactInformation_), + 'Fees': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'AccessConstraints': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString), + 'LayerLimit': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readNonNegativeInteger), + 'MaxWidth': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readNonNegativeInteger), + 'MaxHeight': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readNonNegativeInteger) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.CONTACT_INFORMATION_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'ContactPersonPrimary': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readContactPersonPrimary_), + 'ContactPosition': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString), + 'ContactAddress': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readContactAddress_), + 'ContactVoiceTelephone': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString), + 'ContactFacsimileTelephone': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString), + 'ContactElectronicMailAddress': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.CONTACT_PERSON_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'ContactPerson': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString), + 'ContactOrganization': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.CONTACT_ADDRESS_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'AddressType': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'Address': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'City': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'StateOrProvince': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readString), + 'PostCode': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'Country': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.EXCEPTION_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'Format': ol.xml.makeArrayPusher(ol.format.XSD.readString) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.LAYER_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'Name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'Title': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'Abstract': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'KeywordList': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readKeywordList_), + 'CRS': ol.xml.makeObjectPropertyPusher(ol.format.XSD.readString), + 'EX_GeographicBoundingBox': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readEXGeographicBoundingBox_), + 'BoundingBox': ol.xml.makeObjectPropertyPusher( + ol.format.WMSCapabilities.readBoundingBox_), + 'Dimension': ol.xml.makeObjectPropertyPusher( + ol.format.WMSCapabilities.readDimension_), + 'Attribution': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readAttribution_), + 'AuthorityURL': ol.xml.makeObjectPropertyPusher( + ol.format.WMSCapabilities.readAuthorityURL_), + 'Identifier': ol.xml.makeObjectPropertyPusher(ol.format.XSD.readString), + 'MetadataURL': ol.xml.makeObjectPropertyPusher( + ol.format.WMSCapabilities.readMetadataURL_), + 'DataURL': ol.xml.makeObjectPropertyPusher( + ol.format.WMSCapabilities.readFormatOnlineresource_), + 'FeatureListURL': ol.xml.makeObjectPropertyPusher( + ol.format.WMSCapabilities.readFormatOnlineresource_), + 'Style': ol.xml.makeObjectPropertyPusher( + ol.format.WMSCapabilities.readStyle_), + 'MinScaleDenominator': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readDecimal), + 'MaxScaleDenominator': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readDecimal), + 'Layer': ol.xml.makeObjectPropertyPusher( + ol.format.WMSCapabilities.readLayer_) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.ATTRIBUTION_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'Title': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'OnlineResource': ol.xml.makeObjectPropertySetter( + ol.format.XLink.readHref), + 'LogoURL': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readSizedFormatOnlineresource_) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS_ = + ol.xml.makeParsersNS(ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'westBoundLongitude': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readDecimal), + 'eastBoundLongitude': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readDecimal), + 'southBoundLatitude': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readDecimal), + 'northBoundLatitude': ol.xml.makeObjectPropertySetter( + ol.format.XSD.readDecimal) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.REQUEST_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'GetCapabilities': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readOperationType_), + 'GetMap': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readOperationType_), + 'GetFeatureInfo': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readOperationType_) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.OPERATIONTYPE_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'Format': ol.xml.makeObjectPropertyPusher(ol.format.XSD.readString), + 'DCPType': ol.xml.makeObjectPropertyPusher( + ol.format.WMSCapabilities.readDCPType_) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.DCPTYPE_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'HTTP': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readHTTP_) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.HTTP_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'Get': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readFormatOnlineresource_), + 'Post': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readFormatOnlineresource_) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.STYLE_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'Name': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'Title': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'Abstract': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'LegendURL': ol.xml.makeObjectPropertyPusher( + ol.format.WMSCapabilities.readSizedFormatOnlineresource_), + 'StyleSheetURL': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readFormatOnlineresource_), + 'StyleURL': ol.xml.makeObjectPropertySetter( + ol.format.WMSCapabilities.readFormatOnlineresource_) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.FORMAT_ONLINERESOURCE_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'Format': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString), + 'OnlineResource': ol.xml.makeObjectPropertySetter( + ol.format.XLink.readHref) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.WMSCapabilities.KEYWORDLIST_PARSERS_ = ol.xml.makeParsersNS( + ol.format.WMSCapabilities.NAMESPACE_URIS_, { + 'Keyword': ol.xml.makeArrayPusher(ol.format.XSD.readString) + }); diff --git a/old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml b/test/spec/ol/format/wms/ogcsample.xml similarity index 100% rename from old/test/spec/ol/parser/ogc/xml/wmscapabilities_v1_3_0/ogcsample.xml rename to test/spec/ol/format/wms/ogcsample.xml diff --git a/test/spec/ol/format/wmscapabilities.test.js b/test/spec/ol/format/wmscapabilities.test.js new file mode 100644 index 0000000000..4cebad7bce --- /dev/null +++ b/test/spec/ol/format/wmscapabilities.test.js @@ -0,0 +1,148 @@ +goog.provide('ol.test.format.WMSCapabilities'); + +describe('ol.format.WMSCapabilities', function() { + + describe('when parsing ogcsample.xml', function() { + + var parser = new ol.format.WMSCapabilities(); + var capabilities; + before(function(done) { + afterLoadText('spec/ol/format/wms/ogcsample.xml', function(xml) { + try { + capabilities = parser.read(xml); + } catch (e) { + done(e); + } + done(); + }); + }); + + it('can read version', function() { + expect(capabilities.version).to.eql('1.3.0'); + }); + + it('can read Service section', function() { + // FIXME not all fields are tested + var service = capabilities.Service; + var contact = service.ContactInformation; + + expect(service.Name).to.eql('WMS'); + expect(service.Title).to.eql('Acme Corp. Map Server'); + expect(service.KeywordList).to.eql(['bird', 'roadrunner', 'ambush']); + expect(service.OnlineResource).to.eql('http://hostname/'); + expect(service.Fees).to.eql('none'); + expect(service.AccessConstraints).to.eql('none'); + expect(service.LayerLimit).to.eql(16); + expect(service.MaxWidth).to.eql(2048); + expect(service.MaxHeight).to.eql(2048); + + expect(contact.ContactPosition).to.eql('Computer Scientist'); + expect(contact.ContactPersonPrimary).to.eql({ + ContactPerson: 'Jeff Smith', + ContactOrganization: 'NASA' + }); + }); + + it('can read Capability.Exception', function() { + var exception = capabilities.Capability.Exception; + + expect(exception).to.eql(['XML', 'INIMAGE', 'BLANK']); + }); + + it('can read Capability.Request.GetCapabilities', function() { + var getCapabilities = capabilities.Capability.Request.GetCapabilities; + + expect(getCapabilities.Format).to.eql(['text/xml']); + expect(getCapabilities.DCPType.length).to.eql(1); + var http = getCapabilities.DCPType[0].HTTP; + expect(http.Get.OnlineResource).to.eql('http://hostname/path?'); + expect(http.Post.OnlineResource).to.eql('http://hostname/path?'); + }); + + it('can read Capability.Request.GetFeatureInfo', function() { + var getFeatureInfo = capabilities.Capability.Request.GetFeatureInfo; + + expect(getFeatureInfo.Format).to.eql( + ['text/xml', 'text/plain', 'text/html']); + expect(getFeatureInfo.DCPType.length).to.eql(1); + var http = getFeatureInfo.DCPType[0].HTTP; + expect(http.Get.OnlineResource).to.eql('http://hostname/path?'); + }); + + it('can read Capability.Request.GetMap', function() { + var getMap = capabilities.Capability.Request.GetMap; + + expect(getMap.Format).to.eql(['image/gif', 'image/png', 'image/jpeg']); + expect(getMap.DCPType.length).to.eql(1); + var http = getMap.DCPType[0].HTTP; + expect(http.Get.OnlineResource).to.eql('http://hostname/path?'); + }); + + it('can read Capability.Layer', function() { + var layer = capabilities.Capability.Layer; + + expect(layer.Title).to.eql('Acme Corp. Map Server'); + expect(layer.Name).to.be(undefined); + expect(layer.CRS).to.eql(['CRS:84']); + expect(layer.AuthorityURL).to.eql([{ + name: 'DIF_ID', + OnlineResource: 'http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html' + }]); + expect(layer.BoundingBox).to.eql([{ + crs: 'CRS:84', + extent: [-1, -1, 1, 1], + res: [0, 0] + }]); + + expect(layer.Layer.length).to.eql(4); + expect(layer.Layer[0].Name).to.eql('ROADS_RIVERS'); + expect(layer.Layer[0].Title).to.eql('Roads and Rivers'); + expect(layer.Layer[0].CRS).to.eql(['EPSG:26986']); + expect(layer.Layer[0].Identifier).to.eql(['123456']); + expect(layer.Layer[0].BoundingBox).to.eql([{ + crs: 'CRS:84', + extent: [-71.63, 41.75, -70.78, 42.9], + res: [0.01, 0.01] + }, { + crs: 'EPSG:26986', + extent: [189000, 834000, 285000, 962000], + res: [1, 1] + }]); + expect(layer.Layer[0].EX_GeographicBoundingBox).to.eql( + [-71.63, 41.75, -70.78, 42.9]); + expect(layer.Layer[0].Style).to.eql([{ + Name: 'USGS', + Title: 'USGS Topo Map Style', + Abstract: 'Features are shown in a style like that used in USGS ' + + 'topographic maps.', + StyleSheetURL: { + Format: 'text/xsl', + OnlineResource: 'http://www.university.edu/stylesheets/usgs.xsl' + }, + LegendURL: [{ + Format: 'image/gif', + OnlineResource: 'http://www.university.edu/legends/usgs.gif', + size: [72, 72] + }] + }]); + expect(layer.Layer[0].FeatureListURL).to.eql([{ + Format: 'XML', + OnlineResource: 'http://www.university.edu/data/roads_rivers.gml' + }]); + expect(layer.Layer[0].Attribution).to.eql({ + Title: 'State College University', + OnlineResource: 'http://www.university.edu/', + LogoURL: { + Format: 'image/gif', + OnlineResource: 'http://www.university.edu/icons/logo.gif', + size: [100, 100] + } + }); + + }); + + + }); +}); + +goog.require('ol.format.WMSCapabilities'); From ea8c004c76b7cbe81316f92ab3786efafe674d88 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 10 Mar 2014 17:13:16 +0100 Subject: [PATCH 7/9] Remove unneeded type cast --- src/ol/format/wmscapabilitiesformat.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ol/format/wmscapabilitiesformat.js b/src/ol/format/wmscapabilitiesformat.js index 19d3d8355a..1498715448 100644 --- a/src/ol/format/wmscapabilitiesformat.js +++ b/src/ol/format/wmscapabilitiesformat.js @@ -93,17 +93,17 @@ ol.format.WMSCapabilities.readBoundingBox_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); goog.asserts.assert(node.localName == 'BoundingBox'); - var extent = /** @type {ol.Extent} */ ([ + var extent = [ ol.format.XSD.readDecimalString(node.getAttribute('minx')), ol.format.XSD.readDecimalString(node.getAttribute('miny')), ol.format.XSD.readDecimalString(node.getAttribute('maxx')), ol.format.XSD.readDecimalString(node.getAttribute('maxy')) - ]); + ]; - var resolutions = /** @type {Array.} */ ([ + var resolutions = [ ol.format.XSD.readDecimalString(node.getAttribute('resx')), ol.format.XSD.readDecimalString(node.getAttribute('resy')) - ]); + ]; return { 'crs': node.getAttribute('CRS'), @@ -127,12 +127,12 @@ ol.format.WMSCapabilities.readEXGeographicBoundingBox_ = /** @type {ol.format.EXGeographicBoundingBoxType} */ ({}), ol.format.WMSCapabilities.EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS_, node, objectStack); - return /** @type {ol.Extent} */ ([ + return [ geographicBoundingBox.westBoundLongitude, geographicBoundingBox.southBoundLatitude, geographicBoundingBox.eastBoundLongitude, geographicBoundingBox.northBoundLatitude - ]); + ]; }; @@ -431,10 +431,10 @@ ol.format.WMSCapabilities.readSizedFormatOnlineresource_ = var formatOnlineresource = ol.format.WMSCapabilities.readFormatOnlineresource_(node, objectStack); if (goog.isDef(formatOnlineresource)) { - var size = /** @type {ol.Size} */ ([ + var size = [ ol.format.XSD.readNonNegativeIntegerString(node.getAttribute('width')), ol.format.XSD.readNonNegativeIntegerString(node.getAttribute('height')) - ]); + ]; goog.object.set(formatOnlineresource, 'size', size); return formatOnlineresource; } From 2fdae368c280e44d7c93b931a8f287d5e5387e82 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 10 Mar 2014 17:18:04 +0100 Subject: [PATCH 8/9] Check if the EX_GeographicBoundingBox is correctly parsed --- src/ol/format/wmscapabilitiesformat.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/ol/format/wmscapabilitiesformat.js b/src/ol/format/wmscapabilitiesformat.js index 1498715448..c6c42043a5 100644 --- a/src/ol/format/wmscapabilitiesformat.js +++ b/src/ol/format/wmscapabilitiesformat.js @@ -127,12 +127,16 @@ ol.format.WMSCapabilities.readEXGeographicBoundingBox_ = /** @type {ol.format.EXGeographicBoundingBoxType} */ ({}), ol.format.WMSCapabilities.EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS_, node, objectStack); - return [ - geographicBoundingBox.westBoundLongitude, - geographicBoundingBox.southBoundLatitude, - geographicBoundingBox.eastBoundLongitude, - geographicBoundingBox.northBoundLatitude - ]; + if (goog.isDef(geographicBoundingBox)) { + return [ + geographicBoundingBox.westBoundLongitude, + geographicBoundingBox.southBoundLatitude, + geographicBoundingBox.eastBoundLongitude, + geographicBoundingBox.northBoundLatitude + ]; + } else { + return undefined; + } }; From 924ecba95c858b41c98fa08d75ad59a8a67d7f44 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 10 Mar 2014 17:22:35 +0100 Subject: [PATCH 9/9] Fix coding style --- src/ol/format/wmscapabilitiesformat.js | 131 +++++++++++++------------ 1 file changed, 66 insertions(+), 65 deletions(-) diff --git a/src/ol/format/wmscapabilitiesformat.js b/src/ol/format/wmscapabilitiesformat.js index c6c42043a5..ff1979fff8 100644 --- a/src/ol/format/wmscapabilitiesformat.js +++ b/src/ol/format/wmscapabilitiesformat.js @@ -259,72 +259,73 @@ ol.format.WMSCapabilities.readLayer_ = function(node, objectStack) { var layerObject = /** @type {Object.} */ (ol.xml.pushParseAndPop( {}, ol.format.WMSCapabilities.LAYER_PARSERS_, node, objectStack)); - if (goog.isDef(layerObject)) { - var queryable = - ol.format.XSD.readBooleanString(node.getAttribute('queryable')); - if (!goog.isDef(queryable)) { - queryable = goog.object.get(parentLayerObject, 'queryable'); - } - goog.object.set( - layerObject, 'queryable', goog.isDef(queryable) ? queryable : false); - - var cascaded = ol.format.XSD.readNonNegativeIntegerString( - node.getAttribute('cascaded')); - if (!goog.isDef(cascaded)) { - cascaded = goog.object.get(parentLayerObject, 'cascaded'); - } - goog.object.set(layerObject, 'cascaded', cascaded); - - var opaque = ol.format.XSD.readBooleanString(node.getAttribute('opaque')); - if (!goog.isDef(opaque)) { - opaque = goog.object.get(parentLayerObject, 'opaque'); - } - goog.object.set(layerObject, 'opaque', goog.isDef(opaque) ? opaque : false); - - var noSubsets = - ol.format.XSD.readBooleanString(node.getAttribute('noSubsets')); - if (!goog.isDef(noSubsets)) { - noSubsets = goog.object.get(parentLayerObject, 'noSubsets'); - } - goog.object.set( - layerObject, 'noSubsets', goog.isDef(noSubsets) ? noSubsets : false); - - var fixedWidth = - ol.format.XSD.readDecimalString(node.getAttribute('fixedWidth')); - if (!goog.isDef(fixedWidth)) { - fixedWidth = goog.object.get(parentLayerObject, 'fixedWidth'); - } - goog.object.set(layerObject, 'fixedWidth', fixedWidth); - - var fixedHeight = - ol.format.XSD.readDecimalString(node.getAttribute('fixedHeight')); - if (!goog.isDef(fixedHeight)) { - fixedHeight = goog.object.get(parentLayerObject, 'fixedHeight'); - } - goog.object.set(layerObject, 'fixedHeight', fixedHeight); - - // See 7.2.4.8 - var addKeys = ['Style', 'CRS', 'AuthorityURL']; - goog.array.forEach(addKeys, function(key) { - var parentValue = goog.object.get(parentLayerObject, key); - if (goog.isDef(parentValue)) { - var childValue = goog.object.setIfUndefined(layerObject, key, []); - childValue = childValue.concat(parentValue); - } - }); - - var replaceKeys = ['EX_GeographicBoundingBox', 'BoundingBox', 'Dimension', - 'Attribution', 'MinScaleDenominator', 'MaxScaleDenominator']; - goog.array.forEach(replaceKeys, function(key) { - var childValue = goog.object.get(layerObject, key); - if (!goog.isDef(childValue)) { - var parentValue = goog.object.get(parentLayerObject, key); - goog.object.set(layerObject, key, parentValue); - } - }); - - return layerObject; + if (!goog.isDef(layerObject)) { + return undefined; } + var queryable = + ol.format.XSD.readBooleanString(node.getAttribute('queryable')); + if (!goog.isDef(queryable)) { + queryable = goog.object.get(parentLayerObject, 'queryable'); + } + goog.object.set( + layerObject, 'queryable', goog.isDef(queryable) ? queryable : false); + + var cascaded = ol.format.XSD.readNonNegativeIntegerString( + node.getAttribute('cascaded')); + if (!goog.isDef(cascaded)) { + cascaded = goog.object.get(parentLayerObject, 'cascaded'); + } + goog.object.set(layerObject, 'cascaded', cascaded); + + var opaque = ol.format.XSD.readBooleanString(node.getAttribute('opaque')); + if (!goog.isDef(opaque)) { + opaque = goog.object.get(parentLayerObject, 'opaque'); + } + goog.object.set(layerObject, 'opaque', goog.isDef(opaque) ? opaque : false); + + var noSubsets = + ol.format.XSD.readBooleanString(node.getAttribute('noSubsets')); + if (!goog.isDef(noSubsets)) { + noSubsets = goog.object.get(parentLayerObject, 'noSubsets'); + } + goog.object.set( + layerObject, 'noSubsets', goog.isDef(noSubsets) ? noSubsets : false); + + var fixedWidth = + ol.format.XSD.readDecimalString(node.getAttribute('fixedWidth')); + if (!goog.isDef(fixedWidth)) { + fixedWidth = goog.object.get(parentLayerObject, 'fixedWidth'); + } + goog.object.set(layerObject, 'fixedWidth', fixedWidth); + + var fixedHeight = + ol.format.XSD.readDecimalString(node.getAttribute('fixedHeight')); + if (!goog.isDef(fixedHeight)) { + fixedHeight = goog.object.get(parentLayerObject, 'fixedHeight'); + } + goog.object.set(layerObject, 'fixedHeight', fixedHeight); + + // See 7.2.4.8 + var addKeys = ['Style', 'CRS', 'AuthorityURL']; + goog.array.forEach(addKeys, function(key) { + var parentValue = goog.object.get(parentLayerObject, key); + if (goog.isDef(parentValue)) { + var childValue = goog.object.setIfUndefined(layerObject, key, []); + childValue = childValue.concat(parentValue); + } + }); + + var replaceKeys = ['EX_GeographicBoundingBox', 'BoundingBox', 'Dimension', + 'Attribution', 'MinScaleDenominator', 'MaxScaleDenominator']; + goog.array.forEach(replaceKeys, function(key) { + var childValue = goog.object.get(layerObject, key); + if (!goog.isDef(childValue)) { + var parentValue = goog.object.get(parentLayerObject, key); + goog.object.set(layerObject, key, parentValue); + } + }); + + return layerObject; };