More trip planner testing with colors
[busui.git] / labs / openlayers / lib / OpenLayers / Format / WMSCapabilities / v1.js
blob:a/labs/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1.js -> blob:b/labs/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1.js
  /* 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/WMSCapabilities.js
  * @requires OpenLayers/Format/XML.js
  */
   
  /**
  * Class: OpenLayers.Format.WMSCapabilities.v1
  * Abstract class not to be instantiated directly. Creates
  * the common parts for both WMS 1.1.X and WMS 1.3.X.
  *
  * Inherits from:
  * - <OpenLayers.Format.XML>
  */
  OpenLayers.Format.WMSCapabilities.v1 = OpenLayers.Class(
  OpenLayers.Format.XML, {
   
  /**
  * Property: namespaces
  * {Object} Mapping of namespace aliases to namespace URIs.
  */
  namespaces: {
  wms: "http://www.opengis.net/wms",
  xlink: "http://www.w3.org/1999/xlink",
  xsi: "http://www.w3.org/2001/XMLSchema-instance"
  },
   
  /**
  * Property: defaultPrefix
  */
  defaultPrefix: "wms",
   
  /**
  * Constructor: OpenLayers.Format.WMSCapabilities.v1
  * Create an instance of one of the subclasses.
  *
  * 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]);
  },
   
  /**
  * APIMethod: 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]);
  }
  if(data && data.nodeType == 9) {
  data = data.documentElement;
  }
  var capabilities = {};
  this.readNode(data, capabilities);
   
  // postprocess the layer list
  this.postProcessLayers(capabilities);
   
  return capabilities;
  },
   
  /**
  * Method: postProcessLayers
  * Post process the layers, so that the nested layer structure is converted
  * to a flat layer list with only named layers.
  *
  * Parameters:
  * capabilities - {Object} The object (structure) returned by the parser with
  * all the info from the GetCapabilities response.
  */
  postProcessLayers: function(capabilities) {
  if (capabilities.capability) {
  capabilities.capability.layers = [];
  var layers = capabilities.capability.nestedLayers;
  for (var i=0, len = layers.length; i<len; ++i) {
  var layer = layers[i];
  this.processLayer(capabilities.capability, layer);
  }
  }
  },
   
  /**
  * Method: processLayer
  * Recursive submethod of postProcessLayers. This function will among
  * others deal with property inheritance.
  *
  * Parameters:
  * capability - {Object} The capability part of the capabilities object
  * layer - {Object} The layer that needs processing
  * parentLayer - {Object} The parent layer of the respective layer
  */
  processLayer: function(capability, layer, parentLayer) {
  if (layer.formats === undefined) {
  layer.formats = capability.request.getmap.formats;
  }
   
  // deal with property inheritance
  if(parentLayer) {
  // add style
  layer.styles = layer.styles.concat(parentLayer.styles);
  var attributes = ["queryable",
  "cascaded",
  "fixedWidth",
  "fixedHeight",
  "opaque",
  "noSubsets",
  "llbbox",
  "minScale",
  "maxScale",
  "attribution"];
   
  var complexAttr = ["srs",
  "bbox",
  "dimensions",
  "authorityURLs"];
   
  var key;
  for (var j=0; j<attributes.length; j++) {
  key = attributes[j];
  if (key in parentLayer) {
  // only take parent value if not present (null or undefined)
  if (layer[key] == null) {
  layer[key] = parentLayer[key];
  }
  // if attribute isn't present, and we haven't
  // inherited anything from a parent layer
  // set to default value
  if (layer[key] == null) {
  var intAttr = ["cascaded", "fixedWidth", "fixedHeight"];
  var boolAttr = ["queryable", "opaque", "noSubsets"];
  if (OpenLayers.Util.indexOf(intAttr, key) != -1) {
  layer[key] = 0;
  }
  if (OpenLayers.Util.indexOf(boolAttr, key) != -1) {
  layer[key] = false;
  }
  }
  }
  }
   
  for (var j=0; j<complexAttr.length; j++) {
  key = complexAttr[j];
  layer[key] = OpenLayers.Util.extend(
  layer[key], parentLayer[key]);
  }
  }
   
  // process sublayers
  for (var i=0, len=layer.nestedLayers.length; i<len; i++) {
  var childLayer = layer.nestedLayers[i];
  this.processLayer(capability, childLayer, layer);
  }
   
  if (layer.name) {
  capability.layers.push(layer);
  }
   
  },
   
  /**
  * Property: readers
  * Contains public functions, grouped by namespace prefix, that will
  * be applied when a namespaced node is found matching the function
  * name. The function will be applied in the scope of this parser
  * with two arguments: the node being read and a context object passed
  * from the parent.
  */
  readers: {
  "wms": {
  "Service": function(node, obj) {
  obj.service = {};
  this.readChildNodes(node, obj.service);
  },
  "Name": function(node, obj) {
  obj.name = this.getChildValue(node);
  },
  "Title": function(node, obj) {
  obj.title = this.getChildValue(node);
  },
  "Abstract": function(node, obj) {
  obj["abstract"] = this.getChildValue(node);
  },
  "BoundingBox": function(node, obj) {
  var bbox = {};
  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;
  }
  // return the bbox so that descendant classes can set the
  // CRS and SRS and add it to the obj
  return bbox;
  },
  "OnlineResource": function(node, obj) {
  obj.href = this.getAttributeNS(node, this.namespaces.xlink,
  "href");
  },
  "ContactInformation": function(node, obj) {
  obj.contactInformation = {};
  this.readChildNodes(node, obj.contactInformation);
  },
  "ContactPersonPrimary": function(node, obj) {
  obj.personPrimary = {};
  this.readChildNodes(node, obj.personPrimary);
  },
  "ContactPerson": function(node, obj) {
  obj.person = this.getChildValue(node);
  },
  "ContactOrganization": function(node, obj) {
  obj.organization = this.getChildValue(node);
  },
  "ContactPosition": function(node, obj) {
  obj.position = this.getChildValue(node);
  },
  "ContactAddress": function(node, obj) {
  obj.contactAddress = {};
  this.readChildNodes(node, obj.contactAddress);
  },
  "AddressType": function(node, obj) {
  obj.type = this.getChildValue(node);
  },
  "Address": function(node, obj) {
  obj.address = this.getChildValue(node);
  },
  "City": function(node, obj) {
  obj.city = this.getChildValue(node);
  },
  "StateOrProvince": function(node, obj) {
  obj.stateOrProvince = this.getChildValue(node);
  },
  "PostCode": function(node, obj) {
  obj.postcode = this.getChildValue(node);
  },
  "Country": function(node, obj) {
  obj.country = this.getChildValue(node);
  },
  "ContactVoiceTelephone": function(node, obj) {
  obj.phone = this.getChildValue(node);
  },
  "ContactFacsimileTelephone": function(node, obj) {
  obj.fax = this.getChildValue(node);
  },
  "ContactElectronicMailAddress": function(node, obj) {
  obj.email = this.getChildValue(node);
  },
  "Fees": function(node, obj) {
  var fees = this.getChildValue(node);
  if (fees && fees.toLowerCase() != "none") {
  obj.fees = fees;
  }
  },
  "AccessConstraints": function(node, obj) {
  var constraints = this.getChildValue(node);
  if (constraints && constraints.toLowerCase() != "none") {
  obj.accessConstraints = constraints;
  }
  },
  "Capability": function(node, obj) {
  obj.capability = {nestedLayers: []};
  this.readChildNodes(node, obj.capability);
  },
  "Request": function(node, obj) {
  obj.request = {};
  this.readChildNodes(node, obj.request);
  },
  "GetCapabilities": function(node, obj) {
  obj.getcapabilities = {formats: []};
  this.readChildNodes(node, obj.getcapabilities);
  },
  "Format": function(node, obj) {
  if (obj.formats instanceof Array) {
  obj.formats.push(this.getChildValue(node));
  } else {
  obj.format = this.getChildValue(node);
  }
  },
  "DCPType": function(node, obj) {
  this.readChildNodes(node, obj);
  },
  "HTTP": function(node, obj) {
  this.readChildNodes(node, obj);
  },
  "Get": function(node, obj) {
  this.readChildNodes(node, obj);
  },
  "Post": function(node, obj) {
  this.readChildNodes(node, obj);
  },
  "GetMap": function(node, obj) {
  obj.getmap = {formats: []};
  this.readChildNodes(node, obj.getmap);
  },
  "GetFeatureInfo": function(node, obj) {
  obj.getfeatureinfo = {formats: []};
  this.readChildNodes(node, obj.getfeatureinfo);
  },
  "Exception": function(node, obj) {
  obj.exception = {formats: []};
  this.readChildNodes(node, obj.exception);
  },
  "Layer": function(node, obj) {
  var attrNode = node.getAttributeNode("queryable");
  var queryable = (attrNode && attrNode.specified) ?
  node.getAttribute("queryable") : null;
  attrNode = node.getAttributeNode("cascaded");
  var cascaded = (attrNode && attrNode.specified) ?
  node.getAttribute("cascaded") : null;
  attrNode = node.getAttributeNode("opaque");
  var opaque = (attrNode && attrNode.specified) ?
  node.getAttribute('opaque') : null;
  var noSubsets = node.getAttribute('noSubsets');
  var fixedWidth = node.getAttribute('fixedWidth');
  var fixedHeight = node.getAttribute('fixedHeight');
  var layer = {nestedLayers: [], styles: [], srs: {},
  metadataURLs: [], bbox: {}, dimensions: {},
  authorityURLs: {}, identifiers: {}, keywords: [],
  queryable: (queryable && queryable !== "") ?
  ( queryable === "1" || queryable === "true" ) : null,
  cascaded: (cascaded !== null) ? parseInt(cascaded) : null,
  opaque: opaque ?
  (opaque === "1" || opaque === "true" ) : null,
  noSubsets: (noSubsets !== null) ?
  ( noSubsets === "1" || noSubsets === "true" ) : null,
  fixedWidth: (fixedWidth != null) ?
  parseInt(fixedWidth) : null,
  fixedHeight: (fixedHeight != null) ?
  parseInt(fixedHeight) : null
  };
  obj.nestedLayers.push(layer);
  this.readChildNodes(node, layer);
  if(layer.name) {
  var parts = layer.name.split(":");
  if(parts.length > 0) {