1
/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
2
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
3
* full text of the license. */
6
* @requires OpenLayers/Format/XML.js
10
* Class: OpenLayers.Format.WMC.v1
11
* Superclass for WMC version 1 parsers.
14
* - <OpenLayers.Format.XML>
16
OpenLayers.Format.WMC.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
19
* Property: namespaces
20
* {Object} Mapping of namespace aliases to namespace URIs.
23
ol: "http://openlayers.org/context",
24
wmc: "http://www.opengis.net/context",
25
sld: "http://www.opengis.net/sld",
26
xlink: "http://www.w3.org/1999/xlink",
27
xsi: "http://www.w3.org/2001/XMLSchema-instance"
31
* Property: schemaLocation
32
* {String} Schema location for a particular minor version.
37
* Method: getNamespacePrefix
38
* Get the namespace prefix for a given uri from the <namespaces> object.
41
* {String} A namespace prefix or null if none found.
43
getNamespacePrefix: function(uri) {
46
prefix = this.namespaces[this.defaultPrefix];
48
for(prefix in this.namespaces) {
49
if(this.namespaces[prefix] == uri) {
58
* Property: defaultPrefix
63
* Property: rootPrefix
64
* {String} Prefix on the root node that maps to the context namespace URI.
69
* Property: defaultStyleName
70
* {String} Style name used if layer has no style param. Default is "".
75
* Property: defaultStyleTitle
76
* {String} Default style title. Default is "Default".
78
defaultStyleTitle: "Default",
81
* Constructor: OpenLayers.Format.WMC.v1
82
* Instances of this class are not created directly. Use the
83
* <OpenLayers.Format.WMC> constructor instead.
86
* options - {Object} An optional object whose properties will be set on
89
initialize: function(options) {
90
OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);
95
* Read capabilities data from a string, and return a list of layers.
98
* data - {String} or {DOMElement} data to read/parse.
101
* {Array} List of named layers.
103
read: function(data) {
104
if(typeof data == "string") {
105
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
107
var root = data.documentElement;
108
this.rootPrefix = root.prefix;
110
version: root.getAttribute("version")
112
this.runChildNodes(context, root);
117
* Method: runChildNodes
119
runChildNodes: function(obj, node) {
120
var children = node.childNodes;
121
var childNode, processor, prefix, local;
122
for(var i=0, len=children.length; i<len; ++i) {
123
childNode = children[i];
124
if(childNode.nodeType == 1) {
125
prefix = this.getNamespacePrefix(childNode.namespaceURI);
126
local = childNode.nodeName.split(":").pop();
127
processor = this["read_" + prefix + "_" + local];
129
processor.apply(this, [obj, childNode]);
136
* Method: read_wmc_General
138
read_wmc_General: function(context, node) {
139
this.runChildNodes(context, node);
143
* Method: read_wmc_BoundingBox
145
read_wmc_BoundingBox: function(context, node) {
146
context.projection = node.getAttribute("SRS");
147
context.bounds = new OpenLayers.Bounds(
148
parseFloat(node.getAttribute("minx")),
149
parseFloat(node.getAttribute("miny")),
150
parseFloat(node.getAttribute("maxx")),
151
parseFloat(node.getAttribute("maxy"))
156
* Method: read_wmc_LayerList
158
read_wmc_LayerList: function(context, node) {
160
this.runChildNodes(context, node);
164
* Method: read_wmc_Layer
166
read_wmc_Layer: function(context, node) {
170
visibility: (node.getAttribute("hidden") != "1"),
171
queryable: (node.getAttribute("queryable") == "1")
177
this.runChildNodes(layerInfo, node);
178
// set properties common to multiple objects on layer options/params
179
layerInfo.params.layers = layerInfo.name;
180
layerInfo.options.maxExtent = layerInfo.maxExtent;
182
var layer = this.getLayerFromInfo(layerInfo);
183
context.layers.push(layer);
187
* Method: getLayerFromInfo
188
* Create a WMS layer from a layerInfo object.
191
* layerInfo - {Object} An object representing a WMS layer.
194
* {<OpenLayers.Layer.WMS>} A WMS layer.
196
getLayerFromInfo: function(layerInfo) {
197
var options = layerInfo.options;
198
if (this.layerOptions) {
199
OpenLayers.Util.applyDefaults(options, this.layerOptions);
201
var layer = new OpenLayers.Layer.WMS(
211
* Method: read_wmc_Extension
213
read_wmc_Extension: function(obj, node) {
214
this.runChildNodes(obj, node);
218
* Method: read_ol_units
220
read_ol_units: function(layerInfo, node) {
221
layerInfo.options.units = this.getChildValue(node);
225
* Method: read_ol_maxExtent
227
read_ol_maxExtent: function(obj, node) {
228
var bounds = new OpenLayers.Bounds(
229
node.getAttribute("minx"), node.getAttribute("miny"),
230
node.getAttribute("maxx"), node.getAttribute("maxy")
232
obj.maxExtent = bounds;
236
* Method: read_ol_transparent
238
read_ol_transparent: function(layerInfo, node) {
239
layerInfo.params.transparent = this.getChildValue(node);
243
* Method: read_ol_numZoomLevels
245
read_ol_numZoomLevels: function(layerInfo, node) {
246
layerInfo.options.numZoomLevels = parseInt(this.getChildValue(node));
250
* Method: read_ol_opacity
252
read_ol_opacity: function(layerInfo, node) {
253
layerInfo.options.opacity = parseFloat(this.getChildValue(node));
257
* Method: read_ol_singleTile
259
read_ol_singleTile: function(layerInfo, node) {
260
layerInfo.options.singleTile = (this.getChildValue(node) == "true");
264
* Method: read_ol_isBaseLayer
266
read_ol_isBaseLayer: function(layerInfo, node) {
267
layerInfo.options.isBaseLayer = (this.getChildValue(node) == "true");
271
* Method: read_ol_displayInLayerSwitcher
273
read_ol_displayInLayerSwitcher: function(layerInfo, node) {
274
layerInfo.options.displayInLayerSwitcher =
275
(this.getChildValue(node) == "true");
279
* Method: read_wmc_Server
281
read_wmc_Server: function(layerInfo, node) {
282
layerInfo.params.version = node.getAttribute("version");
283
this.runChildNodes(layerInfo, node);
287
* Method: read_wmc_FormatList
289
read_wmc_FormatList: function(layerInfo, node) {
290
this.runChildNodes(layerInfo, node);
294
* Method: read_wmc_Format
296
read_wmc_Format: function(layerInfo, node) {
297
var format = this.getChildValue(node);
298
layerInfo.formats.push(format);
299
if(node.getAttribute("current") == "1") {
300
layerInfo.params.format = format;
305
* Method: read_wmc_StyleList
307
read_wmc_StyleList: function(layerInfo, node) {
308
this.runChildNodes(layerInfo, node);
312
* Method: read_wmc_Style
314
read_wmc_Style: function(layerInfo, node) {
316
this.runChildNodes(style, node);
317
if(node.getAttribute("current") == "1") {
318
// three style types to consider
322
// running child nodes always gets name, optionally gets href or body
324
layerInfo.params.sld = style.href;
325
} else if(style.body) {
326
layerInfo.params.sld_body = style.body;
328
layerInfo.params.styles = style.name;
331
layerInfo.styles.push(style);
335
* Method: read_wmc_SLD
337
read_wmc_SLD: function(style, node) {
338
this.runChildNodes(style, node);
339
// style either comes back with an href or a body property
343
* Method: read_sld_StyledLayerDescriptor
345
read_sld_StyledLayerDescriptor: function(sld, node) {
346
var xml = OpenLayers.Format.XML.prototype.write.apply(this, [node]);
351
* Method: read_wmc_OnlineResource
353
read_wmc_OnlineResource: function(obj, node) {
354
obj.href = this.getAttributeNS(
355
node, this.namespaces.xlink, "href"
360
* Method: read_wmc_Name
362
read_wmc_Name: function(obj, node) {
363
var name = this.getChildValue(node);
370
* Method: read_wmc_Title
372
read_wmc_Title: function(obj, node) {
373
var title = this.getChildValue(node);
380
* Method: read_wmc_MetadataURL
382
read_wmc_MetadataURL: function(layerInfo, node) {
383
var metadataURL = {};
384
var links = node.getElementsByTagName("OnlineResource");
385
if(links.length > 0) {
386
this.read_wmc_OnlineResource(metadataURL, links[0]);
388
layerInfo.options.metadataURL = metadataURL.href;
393
* Method: read_wmc_Abstract
395
read_wmc_Abstract: function(obj, node) {
396
var abst = this.getChildValue(node);
398
obj["abstract"] = abst;
403
* Method: read_wmc_LatLonBoundingBox
405
read_wmc_LatLonBoundingBox: function(layer, node) {
407
parseFloat(node.getAttribute("minx")),
408
parseFloat(node.getAttribute("miny")),
409
parseFloat(node.getAttribute("maxx")),
410
parseFloat(node.getAttribute("maxy"))
415
* Method: read_wmc_LegendURL
417
read_wmc_LegendURL: function(style, node) {
419
width: node.getAttribute('width'),
420
height: node.getAttribute('height')
422
var links = node.getElementsByTagName("OnlineResource");
423
if(links.length > 0) {
424
this.read_wmc_OnlineResource(legend, links[0]);
426
style.legend = legend;
433
* context - {Object} An object representing the map context.
434
* options - {Object} Optional object.
437
* {String} A WMC document string.
439
write: function(context, options) {
440
var root = this.createElementDefaultNS("ViewContext");
441
this.setAttributes(root, {
442
version: this.VERSION,
443
id: (options && typeof options.id == "string") ?
445
OpenLayers.Util.createUniqueID("OpenLayers_Context_")
448
// add schemaLocation attribute
450
root, this.namespaces.xsi,
451
"xsi:schemaLocation", this.schemaLocation
454
// required General element
455
root.appendChild(this.write_wmc_General(context));
457
// required LayerList element
458
root.appendChild(this.write_wmc_LayerList(context));
460
return OpenLayers.Format.XML.prototype.write.apply(this, [root]);
464
* Method: createElementDefaultNS
465
* Shorthand for createElementNS with namespace from <defaultPrefix>.
466
* Can optionally be used to set attributes and a text child value.
469
* name - {String} The qualified node name.
470
* childValue - {String} Optional value for text child node.
471
* attributes - {Object} Optional object representing attributes.
474
* {Element} An element node.
476
createElementDefaultNS: function(name, childValue, attributes) {
477
var node = this.createElementNS(
478
this.namespaces[this.defaultPrefix],
482
node.appendChild(this.createTextNode(childValue));
485
this.setAttributes(node, attributes);
491
* Method: setAttributes
492
* Set multiple attributes given key value pairs from an object.
495
* node - {Element} An element node.
496
* obj - {Object} An object whose properties represent attribute names and
497
* values represent attribute values.
499
setAttributes: function(node, obj) {
501
for(var name in obj) {
502
value = obj[name].toString();
503
if(value.match(/[A-Z]/)) {
504
// safari lowercases attributes with setAttribute
505
this.setAttributeNS(node, null, name, value);
507
node.setAttribute(name, value);
513
* Method: write_wmc_General
514
* Create a General node given an context object.
517
* context - {Object} Context object.
520
* {Element} A WMC General element node.
522
write_wmc_General: function(context) {
523
var node = this.createElementDefaultNS("General");
525
// optional Window element
527
node.appendChild(this.createElementDefaultNS(
530
width: context.size.w,
531
height: context.size.h
536
// required BoundingBox element
537
var bounds = context.bounds;
538
node.appendChild(this.createElementDefaultNS(
541
minx: bounds.left.toPrecision(10),
542
miny: bounds.bottom.toPrecision(10),
543
maxx: bounds.right.toPrecision(10),
544
maxy: bounds.top.toPrecision(10),
545
SRS: context.projection
549
// required Title element
550
node.appendChild(this.createElementDefaultNS(
551
"Title", context.title
554
// OpenLayers specific map properties
555
node.appendChild(this.write_ol_MapExtension(context));
561
* Method: write_ol_MapExtension
563
write_ol_MapExtension: function(context) {
564
var node = this.createElementDefaultNS("Extension");
566
var bounds = context.maxExtent;
568
var maxExtent = this.createElementNS(
569
this.namespaces.ol, "ol:maxExtent"
571
this.setAttributes(maxExtent, {
572
minx: bounds.left.toPrecision(10),
573
miny: bounds.bottom.toPrecision(10),
574
maxx: bounds.right.toPrecision(10),
575
maxy: bounds.top.toPrecision(10)
577
node.appendChild(maxExtent);
584
* Method: write_wmc_LayerList
585
* Create a LayerList node given an context object.
588
* context - {Object} Context object.
591
* {Element} A WMC LayerList element node.
593
write_wmc_LayerList: function(context) {
594
var list = this.createElementDefaultNS("LayerList");
597
for(var i=0, len=context.layers.length; i<len; ++i) {
598
layer = context.layers[i];
599
if(layer instanceof OpenLayers.Layer.WMS) {
600
list.appendChild(this.write_wmc_Layer(layer));
608
* Method: write_wmc_Layer
609
* Create a Layer node given a layer object.
612
* layer - {<OpenLayers.Layer.WMS>} Layer object.
615
* {Element} A WMC Layer element node.
617
write_wmc_Layer: function(layer) {
618
var node = this.createElementDefaultNS(
620
queryable: layer.queryable ? "1" : "0",
621
hidden: layer.visibility ? "0" : "1"
625
// required Server element
626
node.appendChild(this.write_wmc_Server(layer));
628
// required Name element
629
node.appendChild(this.createElementDefaultNS(
630
"Name", layer.params["LAYERS"]
633
// required Title element
634
node.appendChild(this.createElementDefaultNS(
638
// optional MetadataURL element
639
if (layer.metadataURL) {
640
node.appendChild(this.write_wmc_MetadataURL(layer));
643
// optional FormatList element
644
node.appendChild(this.write_wmc_FormatList(layer));
646
// optional StyleList element
647
node.appendChild(this.write_wmc_StyleList(layer));
649
// OpenLayers specific properties go in an Extension element
650
node.appendChild(this.write_wmc_LayerExtension(layer));
656
* Method: write_wmc_LayerExtension
657
* Add OpenLayers specific layer parameters to an Extension element.
660
* layer - {<OpenLayers.Layer.WMS>} A WMS layer.
663
* {Element} A WMC Extension element (for a layer).
665
write_wmc_LayerExtension: function(layer) {
666
var node = this.createElementDefaultNS("Extension");
668
var bounds = layer.maxExtent;
669
var maxExtent = this.createElementNS(
670
this.namespaces.ol, "ol:maxExtent"
672
this.setAttributes(maxExtent, {
673
minx: bounds.left.toPrecision(10),
674
miny: bounds.bottom.toPrecision(10),
675
maxx: bounds.right.toPrecision(10),
676
maxy: bounds.top.toPrecision(10)
678
node.appendChild(maxExtent);
680
var param = layer.params["TRANSPARENT"];
682
var trans = this.createElementNS(
683
this.namespaces.ol, "ol:transparent"
685
trans.appendChild(this.createTextNode(param));
686
node.appendChild(trans);
690
"numZoomLevels", "units", "isBaseLayer",
691
"opacity", "displayInLayerSwitcher", "singleTile"
694
for(var i=0, len=properties.length; i<len; ++i) {
695
child = this.createOLPropertyNode(layer, properties[i]);
697
node.appendChild(child);
705
* Method: createOLPropertyNode
706
* Create a node representing an OpenLayers property. If the property is
707
* null or undefined, null will be returned.
710
* object - {Object} An object.
711
* prop - {String} A property.
714
* {Element} A property node.
716
createOLPropertyNode: function(obj, prop) {
718
if(obj[prop] != null) {
719
node = this.createElementNS(this.namespaces.ol, "ol:" + prop);
720
node.appendChild(this.createTextNode(obj[prop].toString()));
726
* Method: write_wmc_Server
727
* Create a Server node given a layer object.
730
* layer - {<OpenLayers.Layer.WMS>} Layer object.
733
* {Element} A WMC Server element node.
735
write_wmc_Server: function(layer) {
736
var node = this.createElementDefaultNS("Server");
737
this.setAttributes(node, {
739
version: layer.params["VERSION"]
742
// required OnlineResource element
743
node.appendChild(this.write_wmc_OnlineResource(layer.url));
749
* Method: write_wmc_MetadataURL
750
* Create a MetadataURL node given a layer object.
753
* layer - {<OpenLayers.Layer.WMS>} Layer object.
756
* {Element} A WMC metadataURL element node.
758
write_wmc_MetadataURL: function(layer) {
759
var node = this.createElementDefaultNS("MetadataURL");
761
// required OnlineResource element
762
node.appendChild(this.write_wmc_OnlineResource(layer.metadataURL));
768
* Method: write_wmc_FormatList
769
* Create a FormatList node given a layer.
772
* layer - {<OpenLayers.Layer.WMS>} Layer object.
775
* {Element} A WMC FormatList element node.
777
write_wmc_FormatList: function(layer) {
778
var node = this.createElementDefaultNS("FormatList");
779
node.appendChild(this.createElementDefaultNS(
780
"Format", layer.params["FORMAT"], {current: "1"}
787
* Method: write_wmc_StyleList
788
* Create a StyleList node given a layer.
791
* layer - {<OpenLayers.Layer.WMS>} Layer object.
794
* {Element} A WMC StyleList element node.
796
write_wmc_StyleList: function(layer) {
797
var node = this.createElementDefaultNS("StyleList");
798
var style = this.createElementDefaultNS(
799
"Style", null, {current: "1"}
802
// Style can come from one of three places (prioritized as below):
803
// 1) an SLD parameter
804
// 2) and SLD_BODY parameter
805
// 3) the STYLES parameter
807
if(layer.params["SLD"]) {
808
// create link from SLD parameter
809
var sld = this.createElementDefaultNS("SLD");
810
var link = this.write_wmc_OnlineResource(layer.params["SLD"]);
811
sld.appendChild(link);
812
style.appendChild(sld);
813
} else if(layer.params["SLD_BODY"]) {
814
// include sld fragment from SLD_BODY parameter
815
var sld = this.createElementDefaultNS("SLD");
816
var body = layer.params["SLD_BODY"];
817
// read in body as xml doc - assume proper namespace declarations
818
var doc = OpenLayers.Format.XML.prototype.read.apply(this, [body]);
819
// append to StyledLayerDescriptor node
820
var imported = doc.documentElement;
821
if(sld.ownerDocument && sld.ownerDocument.importNode) {
822
imported = sld.ownerDocument.importNode(imported, true);
824
sld.appendChild(imported);
825
style.appendChild(sld);
827
// use name(s) from STYLES parameter
828
var name = layer.params["STYLES"] ?
829
layer.params["STYLES"] : this.defaultStyleName;
831
style.appendChild(this.createElementDefaultNS("Name", name));
832
style.appendChild(this.createElementDefaultNS(
833
"Title", this.defaultStyleTitle
836
node.appendChild(style);
841
* Method: write_wmc_OnlineResource
842
* Create an OnlineResource node given a URL.
845
* href - {String} URL for the resource.
848
* {Element} A WMC OnlineResource element node.
850
write_wmc_OnlineResource: function(href) {
851
var node = this.createElementDefaultNS("OnlineResource");
852
this.setAttributeNS(node, this.namespaces.xlink, "xlink:type", "simple");
853
this.setAttributeNS(node, this.namespaces.xlink, "xlink:href", href);
857
CLASS_NAME: "OpenLayers.Format.WMC.v1"