From 7f240d3ba93370e0f6b8fd1124a99943f78845a5 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Fri, 11 Sep 2009 22:48:56 +0000 Subject: [PATCH] Adding more complete WMS capabilities parsing. Thanks trondmm for the comprehensive patch. Some minor changes by me - including leaving the srs member value an object. r=me (closes #2164) git-svn-id: http://svn.openlayers.org/trunk/openlayers@9664 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- lib/OpenLayers/Format/WMSCapabilities/v1_1.js | 464 +++++++++++++++++- .../Format/WMSCapabilities/v1_1_0.js | 13 +- .../Format/WMSCapabilities/v1_1_1.js | 16 + tests/Format/WMSCapabilities/v1_1_1.html | 237 ++++++++- 4 files changed, 708 insertions(+), 22 deletions(-) diff --git a/lib/OpenLayers/Format/WMSCapabilities/v1_1.js b/lib/OpenLayers/Format/WMSCapabilities/v1_1.js index 56e218ebac..b548116bdf 100644 --- a/lib/OpenLayers/Format/WMSCapabilities/v1_1.js +++ b/lib/OpenLayers/Format/WMSCapabilities/v1_1.js @@ -63,6 +63,183 @@ OpenLayers.Format.WMSCapabilities.v1_1 = OpenLayers.Class( } }, + /** + * Method: read_cap_Service + */ + read_cap_Service: function(capabilities, node) { + var service = {}; + this.runChildNodes(service, node); + capabilities.service = service; + }, + + /** + * Method: read_cap_Fees + */ + read_cap_Fees: function(service, node) { + var fees = this.getChildValue(node); + if (fees && fees.toLowerCase() != "none") { + service.fees = fees; + } + }, + + /** + * Method: read_cap_AccessConstraints + */ + read_cap_AccessConstraints: function(service, node) { + var constraints = this.getChildValue(node); + if (constraints && constraints.toLowerCase() != "none") { + service.accessConstraints = constraints; + } + }, + + /** + * Method: read_cap_ContactInformation + */ + read_cap_ContactInformation: function(service, node) { + var contact = {}; + this.runChildNodes(contact, node); + service.contactInformation = contact; + }, + + + /** + * Method: read_cap_ContactPersonPrimary + */ + read_cap_ContactPersonPrimary: function(contact, node) { + var personPrimary = {}; + this.runChildNodes(personPrimary, node); + contact.personPrimary = personPrimary; + }, + + /** + * Method: read_cap_ContactPerson + */ + read_cap_ContactPerson: function(primaryPerson, node) { + var person = this.getChildValue(node); + if (person) { + primaryPerson.person = person; + } + }, + + /** + * Method: read_cap_ContactOrganization + */ + read_cap_ContactOrganization: function(primaryPerson, node) { + var organization = this.getChildValue(node); + if (organization) { + primaryPerson.organization = organization; + } + }, + + /** + * Method: read_cap_ContactPosition + */ + read_cap_ContactPosition: function(contact, node) { + var position = this.getChildValue(node); + if (position) { + contact.position = position; + } + }, + + /** + * Method: read_cap_ContactAddress + */ + read_cap_ContactAddress: function(contact, node) { + var contactAddress = {}; + this.runChildNodes(contactAddress, node); + contact.contactAddress = contactAddress; + }, + + /** + * Method: read_cap_AddressType + */ + read_cap_AddressType: function(contactAddress, node) { + var type = this.getChildValue(node); + if (type) { + contactAddress.type = type; + } + }, + + /** + * Method: read_cap_Address + */ + read_cap_Address: function(contactAddress, node) { + var address = this.getChildValue(node); + if (address) { + contactAddress.address = address; + } + }, + + /** + * Method: read_cap_City + */ + read_cap_City: function(contactAddress, node) { + var city = this.getChildValue(node); + if (city) { + contactAddress.city = city; + } + }, + + /** + * Method: read_cap_StateOrProvince + */ + read_cap_StateOrProvince: function(contactAddress, node) { + var stateOrProvince = this.getChildValue(node); + if (stateOrProvince) { + contactAddress.stateOrProvince = stateOrProvince; + } + }, + + /** + * Method: read_cap_PostCode + */ + read_cap_PostCode: function(contactAddress, node) { + var postcode = this.getChildValue(node); + if (postcode) { + contactAddress.postcode = postcode; + } + }, + + /** + * Method: read_cap_Country + */ + read_cap_Country: function(contactAddress, node) { + var country = this.getChildValue(node); + if (country) { + contactAddress.country = country; + } + }, + + /** + * Method: read_cap_ContactVoiceTelephone + */ + read_cap_ContactVoiceTelephone: function(contact, node) { + var phone = this.getChildValue(node); + if (phone) { + contact.phone = phone; + } + }, + + /** + * Method: read_cap_ContactFacsimileTelephone + */ + read_cap_ContactFacsimileTelephone: function(contact, node) { + var fax = this.getChildValue(node); + if (fax) { + contact.fax = fax; + } + }, + + /** + * Method: read_cap_ContactElectronicMailAddress + */ + read_cap_ContactElectronicMailAddress: function(contact, node) { + var email = this.getChildValue(node); + if (email) { + contact.email = email; + } + }, + /** * Method: read_cap_Capability */ @@ -94,6 +271,72 @@ OpenLayers.Format.WMSCapabilities.v1_1 = OpenLayers.Class( request.getmap = getmap; }, + /** + * Method: read_cap_GetCapabilities + */ + read_cap_GetCapabilities: function(request, node) { + var getcapabilities = { + formats: [] + }; + this.runChildNodes(getcapabilities, node); + request.getcapabilities = getcapabilities; + }, + + /** + * Method: read_cap_GetFeatureInfo + */ + read_cap_GetFeatureInfo: function(request, node) { + var getfeatureinfo = { + formats: [] + }; + this.runChildNodes(getfeatureinfo, node); + request.getfeatureinfo = getfeatureinfo; + }, + + /** + * Method: read_cap_DescribeLayer + */ + read_cap_DescribeLayer: function(request, node) { + var describelayer = { + formats: [] + }; + this.runChildNodes(describelayer, node); + request.describelayer = describelayer; + }, + + /** + * Method: read_cap_GetLegendGraphic + */ + read_cap_GetLegendGraphic: function(request, node) { + var getlegendgraphic = { + formats: [] + }; + this.runChildNodes(getlegendgraphic, node); + request.getlegendgraphic = getlegendgraphic; + }, + + /** + * Method: read_cap_GetStyles + */ + read_cap_GetStyles: function(request, node) { + var getstyles = { + formats: [] + }; + this.runChildNodes(getstyles, node); + request.getstyles = getstyles; + }, + + /** + * Method: read_cap_PutStyles + */ + read_cap_PutStyles: function(request, node) { + var putstyles = { + formats: [] + }; + this.runChildNodes(putstyles, node); + request.putstyles = putstyles; + }, + /** * Method: read_cap_Format */ @@ -119,12 +362,27 @@ OpenLayers.Format.WMSCapabilities.v1_1 = OpenLayers.Class( }, /** - * Method: read_cap_Service + * Method: read_cap_Exception */ - read_cap_Service: function(capabilities, node) { - var service = {}; - this.runChildNodes(service, node); - capabilities.service = service; + read_cap_Exception: function(capability, node) { + var exception = { + formats: [] + }; + this.runChildNodes(exception, node); + capability.exception = exception; + }, + + /** + * Method: read_cap_UserDefinedSymbolization + */ + read_cap_UserDefinedSymbolization: function(capability, node) { + var userSymbols = { + supportSLD: parseInt(node.getAttribute("SupportSLD")) == 1, + userLayer: parseInt(node.getAttribute("UserLayer")) == 1, + userStyle: parseInt(node.getAttribute("UserStyle")) == 1, + remoteWFS: parseInt(node.getAttribute("RemoteWFS")) == 1 + }; + capability.userSymbols = userSymbols; }, /** @@ -134,20 +392,82 @@ OpenLayers.Format.WMSCapabilities.v1_1 = OpenLayers.Class( var layer = { formats: capability.request.getmap.formats || [], styles: [], + srs: {}, + bbox: {}, + dimensions: {}, metadataURLs: [], - keywords: [], - queryable: (node.getAttribute("queryable") === "1" - || node.getAttribute("queryable") === "true") + authorityURLs: {}, + identifiers: {}, + keywords: [] }; + // deal with property inheritance if(parentLayer) { // add style layer.styles = layer.styles.concat(parentLayer.styles); - // use llbbox - layer.llbbox = parentLayer.llbbox; - // use min/maxScale - layer.minScale = parentLayer.minScale; - layer.maxScale = parentLayer.maxScale; + + var attributes = ["queryable", + "cascaded", + "fixedWidth", + "fixedHeight", + "opaque", + "noSubsets", + "llbbox", + "minScale", + "maxScale", + "attribution"]; + + var complexAttr = ["srs", + "bbox", + "dimensions", + "authorityURLs"]; + + var key; + for (var i=0; i 0) { @@ -251,6 +572,55 @@ OpenLayers.Format.WMSCapabilities.v1_1 = OpenLayers.Class( layer.metadataURLs.push(metadataURL); }, + /** + * Method: read_cap_DataURL + */ + read_cap_DataURL: function(layer, node) { + layer.dataURL = {}; + this.runChildNodes(layer.dataURL, node); + }, + + /** + * Method: read_cap_FeatureListURL + */ + read_cap_FeatureListURL: function(layer, node) { + layer.featureListURL = {}; + this.runChildNodes(layer.featureListURL, node); + }, + + /** + * Method: read_cap_AuthorityURL + */ + read_cap_AuthorityURL: function(layer, node) { + var name = node.getAttribute("name"); + if (! (name in layer.authorityURLs)) { + var authority = {}; + this.runChildNodes(authority, node); + layer.authorityURLs[name] = authority.href; + } else { + // A child Layer SHALL NOT define an AuthorityURL with the + // same name attribute as one inherited from a parent + return; + } + }, + + /** + * Method: read_cap_Identifier + */ + read_cap_Identifier: function(layer, node) { + var authority = node.getAttribute("authority"); + + if (authority in layer.authorityURLs) { + layer.identifiers[authority] = this.getChildValue(node); + } else { + // A layer SHALL NOT declare an Identifier unless a + // corresponding authorityURL has been declared or + // inherited earlier in the Capabilities XML + return; + } + + }, + /** * Method: read_cap_KeywordList */ @@ -280,6 +650,29 @@ OpenLayers.Format.WMSCapabilities.v1_1 = OpenLayers.Class( ]; }, + /** + * Method: read_cap_BoundingBox + */ + read_cap_BoundingBox: function(layer, node) { + var bbox = {}; + bbox.srs = node.getAttribute("SRS"); + bbox.bbox = [ + parseFloat(node.getAttribute("minx")), + parseFloat(node.getAttribute("miny")), + parseFloat(node.getAttribute("maxx")), + parseFloat(node.getAttribute("maxy")) + ]; + var res = { + x: parseFloat(node.getAttribute("resx")), + y: parseFloat(node.getAttribute("resy")) + }; + + if (! (isNaN(res.x) && isNaN(res.y))) { + bbox.res = res; + } + layer.bbox[bbox.srs] = bbox; + }, + /** * Method: read_cap_Style */ @@ -289,6 +682,51 @@ OpenLayers.Format.WMSCapabilities.v1_1 = OpenLayers.Class( layer.styles.push(style); }, + /** + * Method: read_cap_Dimension + */ + read_cap_Dimension: function(layer, node) { + var name = node.getAttribute("name").toLowerCase(); + + if (name in layer["dimensions"]) { + // "A child SHALL NOT redefine a Dimension with the same + // name attribute as one that was inherited" + return; + } + + var dim = { + name: name, + units: node.getAttribute("units"), + unitsymbol: node.getAttribute("unitSymbol") + }; + + layer.dimensions[dim.name] = dim; + }, + + /** + * Method: read_cap_Extent + */ + read_cap_Extent: function(layer, node) { + var name = node.getAttribute("name").toLowerCase(); + + if (name in layer["dimensions"]) { + var extent = layer.dimensions[name]; + + extent.nearestVal = node.getAttribute("nearestValue") === "1"; + extent.multipleVal = node.getAttribute("multipleValues") === "1"; + extent.current = node.getAttribute("current") === "1"; + extent["default"] = node.getAttribute("default") || ""; + var values = this.getChildValue(node); + extent.values = values.split(","); + } else { + // A layer SHALL NOT declare an Extent unless a Dimension + // with the same name has been declared or inherited + // earlier in the Capabilities XML + return; + } + + }, + /** * Method: read_cap_LegendURL */ diff --git a/lib/OpenLayers/Format/WMSCapabilities/v1_1_0.js b/lib/OpenLayers/Format/WMSCapabilities/v1_1_0.js index 87461964bc..2b4a5dd437 100644 --- a/lib/OpenLayers/Format/WMSCapabilities/v1_1_0.js +++ b/lib/OpenLayers/Format/WMSCapabilities/v1_1_0.js @@ -32,6 +32,17 @@ OpenLayers.Format.WMSCapabilities.v1_1_0 = OpenLayers.Class( ); }, + /** + * Method: read_cap_SRS + */ + read_cap_SRS: function(layer, node) { + var srs = this.getChildValue(node); + var values = srs.split(/ +/); + for (var i=0, len=values.length; i - + Acme Corp. Map Server EPSG:4326 + + ROADS_RIVERS Roads and Rivers @@ -282,7 +498,7 @@ Changes: 123456 - application/vnd.ogc.se_xml" + application/vnd.ogc.se_xml @@ -307,6 +523,8 @@ Changes: + + ROADS_1M Roads at 1:1M scale @@ -320,7 +538,6 @@ Changes: 123456 text/plain - @@ -365,41 +582,45 @@ Changes: 1999-01-01/2000-08-22/P1D - + Clouds Forecast cloud cover + Temperature Forecast temperature - + Pressure Forecast barometric pressure 1999-01-01/2000-08-22/P1D 0,1000,3000,5000,10000 - + + ozone_image Global ozone distribution (1992) 1992 - + population World population, annual 1990/2000/P1Y - + + + -->