--- a/labs/openlayers/lib/OpenLayers/Format/WMC/v1.js +++ b/labs/openlayers/lib/OpenLayers/Format/WMC/v1.js @@ -1,1 +1,836 @@ - +/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for + * full list of contributors). Published under the Clear BSD license. + * See http://svn.openlayers.org/trunk/openlayers/license.txt for the + * full text of the license. */ + +/** + * @requires OpenLayers/Format/WMC.js + * @requires OpenLayers/Format/XML.js + */ + +/** + * Class: OpenLayers.Format.WMC.v1 + * Superclass for WMC version 1 parsers. + * + * Inherits from: + * - + */ +OpenLayers.Format.WMC.v1 = OpenLayers.Class(OpenLayers.Format.XML, { + + /** + * Property: namespaces + * {Object} Mapping of namespace aliases to namespace URIs. + */ + namespaces: { + ol: "http://openlayers.org/context", + wmc: "http://www.opengis.net/context", + sld: "http://www.opengis.net/sld", + xlink: "http://www.w3.org/1999/xlink", + xsi: "http://www.w3.org/2001/XMLSchema-instance" + }, + + /** + * Property: schemaLocation + * {String} Schema location for a particular minor version. + */ + schemaLocation: "", + + /** + * Method: getNamespacePrefix + * Get the namespace prefix for a given uri from the object. + * + * Returns: + * {String} A namespace prefix or null if none found. + */ + getNamespacePrefix: function(uri) { + var prefix = null; + if(uri == null) { + prefix = this.namespaces[this.defaultPrefix]; + } else { + for(prefix in this.namespaces) { + if(this.namespaces[prefix] == uri) { + break; + } + } + } + return prefix; + }, + + /** + * Property: defaultPrefix + */ + defaultPrefix: "wmc", + + /** + * Property: rootPrefix + * {String} Prefix on the root node that maps to the context namespace URI. + */ + rootPrefix: null, + + /** + * Property: defaultStyleName + * {String} Style name used if layer has no style param. Default is "". + */ + defaultStyleName: "", + + /** + * Property: defaultStyleTitle + * {String} Default style title. Default is "Default". + */ + defaultStyleTitle: "Default", + + /** + * Constructor: OpenLayers.Format.WMC.v1 + * Instances of this class are not created directly. Use the + * constructor instead. + * + * Parameters: + * options - {Object} An optional object whose properties will be set on + * this instance. + */ + initialize: function(options) { + OpenLayers.Format.XML.prototype.initialize.apply(this, [options]); + }, + + /** + * Method: read + * Read capabilities data from a string, and return a list of layers. + * + * Parameters: + * data - {String} or {DOMElement} data to read/parse. + * + * Returns: + * {Array} List of named layers. + */ + read: function(data) { + if(typeof data == "string") { + data = OpenLayers.Format.XML.prototype.read.apply(this, [data]); + } + var root = data.documentElement; + this.rootPrefix = root.prefix; + var context = { + version: root.getAttribute("version") + }; + this.runChildNodes(context, root); + return context; + }, + + /** + * Method: runChildNodes + */ + runChildNodes: function(obj, node) { + var children = node.childNodes; + var childNode, processor, prefix, local; + for(var i=0, len=children.length; i 0) { + this.read_wmc_OnlineResource(server, links[0]); + } + layerContext.url = server.href; + }, + + /** + * Method: read_wmc_FormatList + */ + read_wmc_FormatList: function(layerContext, node) { + this.runChildNodes(layerContext, node); + }, + + /** + * Method: read_wmc_Format + */ + read_wmc_Format: function(layerContext, node) { + var format = { + value: this.getChildValue(node) + }; + if(node.getAttribute("current") == "1") { + format.current = true; + } + layerContext.formats.push(format); + }, + + /** + * Method: read_wmc_StyleList + */ + read_wmc_StyleList: function(layerContext, node) { + this.runChildNodes(layerContext, node); + }, + + /** + * Method: read_wmc_Style + */ + read_wmc_Style: function(layerContext, node) { + var style = {}; + this.runChildNodes(style, node); + if(node.getAttribute("current") == "1") { + style.current = true; + } + layerContext.styles.push(style); + }, + + /** + * Method: read_wmc_SLD + */ + read_wmc_SLD: function(style, node) { + this.runChildNodes(style, node); + // style either comes back with an href or a body property + }, + + /** + * Method: read_sld_StyledLayerDescriptor + */ + read_sld_StyledLayerDescriptor: function(sld, node) { + var xml = OpenLayers.Format.XML.prototype.write.apply(this, [node]); + sld.body = xml; + }, + + /** + * Method: read_wmc_OnlineResource + */ + read_wmc_OnlineResource: function(obj, node) { + obj.href = this.getAttributeNS( + node, this.namespaces.xlink, "href" + ); + }, + + /** + * Method: read_wmc_Name + */ + read_wmc_Name: function(obj, node) { + var name = this.getChildValue(node); + if(name) { + obj.name = name; + } + }, + + /** + * Method: read_wmc_Title + */ + read_wmc_Title: function(obj, node) { + var title = this.getChildValue(node); + if(title) { + obj.title = title; + } + }, + + /** + * Method: read_wmc_MetadataURL + */ + read_wmc_MetadataURL: function(layerContext, node) { + var metadataURL = {}; + var links = node.getElementsByTagName("OnlineResource"); + if(links.length > 0) { + this.read_wmc_OnlineResource(metadataURL, links[0]); + } + layerContext.metadataURL = metadataURL.href; + + }, + + /** + * Method: read_wmc_Abstract + */ + read_wmc_Abstract: function(obj, node) { + var abst = this.getChildValue(node); + if(abst) { + obj["abstract"] = abst; + } + }, + + /** + * Method: read_wmc_LegendURL + */ + read_wmc_LegendURL: function(style, node) { + var legend = { + width: node.getAttribute('width'), + height: node.getAttribute('height') + }; + var links = node.getElementsByTagName("OnlineResource"); + if(links.length > 0) { + this.read_wmc_OnlineResource(legend, links[0]); + } + style.legend = legend; + }, + + /** + * Method: write + * + * Parameters: + * context - {Object} An object representing the map context. + * options - {Object} Optional object. + * + * Returns: + * {String} A WMC document string. + */ + write: function(context, options) { + var root = this.createElementDefaultNS("ViewContext"); + this.setAttributes(root, { + version: this.VERSION, + id: (options && typeof options.id == "string") ? + options.id : + OpenLayers.Util.createUniqueID("OpenLayers_Context_") + }); + + // add schemaLocation attribute + this.setAttributeNS( + root, this.namespaces.xsi, + "xsi:schemaLocation", this.schemaLocation + ); + + // required General element + root.appendChild(this.write_wmc_General(context)); + + // required LayerList element + root.appendChild(this.write_wmc_LayerList(context)); + + return OpenLayers.Format.XML.prototype.write.apply(this, [root]); + }, + + /** + * Method: createElementDefaultNS + * Shorthand for createElementNS with namespace from . + * Can optionally be used to set attributes and a text child value. + * + * Parameters: + * name - {String} The qualified node name. + * childValue - {String} Optional value for text child node. + * attributes - {Object} Optional object representing attributes. + * + * Returns: + * {Element} An element node. + */ + createElementDefaultNS: function(name, childValue, attributes) { + var node = this.createElementNS( + this.namespaces[this.defaultPrefix], + name + ); + if(childValue) { + node.appendChild(this.createTextNode(childValue)); + } + if(attributes) { + this.setAttributes(node, attributes); + } + return node; + }, + + /** + * Method: setAttributes + * Set multiple attributes given key value pairs from an object. + * + * Parameters: + * node - {Element} An element node. + * obj - {Object} An object whose properties represent attribute names and + * values represent attribute values. + */ + setAttributes: function(node, obj) { + var value; + for(var name in obj) { + value = obj[name].toString(); + if(value.match(/[A-Z]/)) { + // safari lowercases attributes with setAttribute + this.setAttributeNS(node, null, name, value); + } else { + node.setAttribute(name, value); + } + } + }, + + /** + * Method: write_wmc_General + * Create a General node given an context object. + * + * Parameters: + * context - {Object} Context object. + * + * Returns: + * {Element} A WMC General element node. + */ + write_wmc_General: function(context) { + var node = this.createElementDefaultNS("General"); + + // optional Window element + if(context.size) { + node.appendChild(this.createElementDefaultNS( + "Window", null, + { + width: context.size.w, + height: context.size.h + } + )); + } + + // required BoundingBox element + var bounds = context.bounds; + node.appendChild(this.createElementDefaultNS( + "BoundingBox", null, + { + minx: bounds.left.toPrecision(18), + miny: bounds.bottom.toPrecision(18), + maxx: bounds.right.toPrecision(18), + maxy: bounds.top.toPrecision(18), + SRS: context.projection + } + )); + + // required Title element + node.appendChild(this.createElementDefaultNS( + "Title", context.title + )); + + // OpenLayers specific map properties + node.appendChild(this.write_ol_MapExtension(context)); + + return node; + }, + + /** + * Method: write_ol_MapExtension + */ + write_ol_MapExtension: function(context) { + var node = this.createElementDefaultNS("Extension"); + + var bounds = context.maxExtent; + if(bounds) { + var maxExtent = this.createElementNS( + this.namespaces.ol, "ol:maxExtent" + ); + this.setAttributes(maxExtent, { + minx: bounds.left.toPrecision(18), + miny: bounds.bottom.toPrecision(18), + maxx: bounds.right.toPrecision(18), + maxy: bounds.top.toPrecision(18) + }); + node.appendChild(maxExtent); + } + + return node; + }, + + /** + * Method: write_wmc_LayerList + * Create a LayerList node given an context object. + * + * Parameters: + * context - {Object} Context object. + * + * Returns: + * {Element} A WMC LayerList element node. + */ + write_wmc_LayerList: function(context) { + var list = this.createElementDefaultNS("LayerList"); + + for(var i=0, len=context.layersContext.length; i