Project

General

Profile

Download (37.6 KB) Statistics
| Branch: | Tag: | Revision:
1
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
2
 * full list of contributors). Published under the 2-clause BSD license.
3
 * See license.txt in the OpenLayers distribution or repository for the
4
 * full text of the license. */
5

    
6
/**
7
 * @requires OpenLayers/Format/WMC.js
8
 * @requires OpenLayers/Format/XML.js
9
 */
10

    
11
/**
12
 * Class: OpenLayers.Format.WMC.v1
13
 * Superclass for WMC version 1 parsers.
14
 *
15
 * Inherits from:
16
 *  - <OpenLayers.Format.XML>
17
 */
18
OpenLayers.Format.WMC.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
19
    
20
    /**
21
     * Property: namespaces
22
     * {Object} Mapping of namespace aliases to namespace URIs.
23
     */
24
    namespaces: {
25
        ol: "http://openlayers.org/context",
26
        wmc: "http://www.opengis.net/context",
27
        sld: "http://www.opengis.net/sld",
28
        xlink: "http://www.w3.org/1999/xlink",
29
        xsi: "http://www.w3.org/2001/XMLSchema-instance"
30
    },
31
    
32
    /**
33
     * Property: schemaLocation
34
     * {String} Schema location for a particular minor version.
35
     */
36
    schemaLocation: "",
37

    
38
    /**
39
     * Method: getNamespacePrefix
40
     * Get the namespace prefix for a given uri from the <namespaces> object.
41
     *
42
     * Returns:
43
     * {String} A namespace prefix or null if none found.
44
     */
45
    getNamespacePrefix: function(uri) {
46
        var prefix = null;
47
        if(uri == null) {
48
            prefix = this.namespaces[this.defaultPrefix];
49
        } else {
50
            for(prefix in this.namespaces) {
51
                if(this.namespaces[prefix] == uri) {
52
                    break;
53
                }
54
            }
55
        }
56
        return prefix;
57
    },
58
    
59
    /**
60
     * Property: defaultPrefix
61
     */
62
    defaultPrefix: "wmc",
63

    
64
    /**
65
     * Property: rootPrefix
66
     * {String} Prefix on the root node that maps to the context namespace URI.
67
     */
68
    rootPrefix: null,
69
    
70
    /**
71
     * Property: defaultStyleName
72
     * {String} Style name used if layer has no style param.  Default is "".
73
     */
74
    defaultStyleName: "",
75
    
76
    /**
77
     * Property: defaultStyleTitle
78
     * {String} Default style title.  Default is "Default".
79
     */
80
    defaultStyleTitle: "Default",
81
    
82
    /**
83
     * Constructor: OpenLayers.Format.WMC.v1
84
     * Instances of this class are not created directly.  Use the
85
     *     <OpenLayers.Format.WMC> constructor instead.
86
     *
87
     * Parameters:
88
     * options - {Object} An optional object whose properties will be set on
89
     *     this instance.
90
     */
91
    initialize: function(options) {
92
        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);
93
    },
94

    
95
    /**
96
     * Method: read
97
     * Read capabilities data from a string, and return a list of layers. 
98
     * 
99
     * Parameters: 
100
     * data - {String} or {DOMElement} data to read/parse.
101
     *
102
     * Returns:
103
     * {Array} List of named layers.
104
     */
105
    read: function(data) {
106
        if(typeof data == "string") {
107
            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
108
        }
109
        var root = data.documentElement;
110
        this.rootPrefix = root.prefix;
111
        var context = {
112
            version: root.getAttribute("version")
113
        };
114
        this.runChildNodes(context, root);
115
        return context;
116
    },
117
    
118
    /**
119
     * Method: runChildNodes
120
     */
121
    runChildNodes: function(obj, node) {
122
        var children = node.childNodes;
123
        var childNode, processor, prefix, local;
124
        for(var i=0, len=children.length; i<len; ++i) {
125
            childNode = children[i];
126
            if(childNode.nodeType == 1) {
127
                prefix = this.getNamespacePrefix(childNode.namespaceURI);
128
                local = childNode.nodeName.split(":").pop();
129
                processor = this["read_" + prefix + "_" + local];
130
                if(processor) {
131
                    processor.apply(this, [obj, childNode]);
132
                }
133
            }
134
        }
135
    },
136
    
137
    /**
138
     * Method: read_wmc_General
139
     */
140
    read_wmc_General: function(context, node) {
141
        this.runChildNodes(context, node);
142
    },
143
    
144
    /**
145
     * Method: read_wmc_BoundingBox
146
     */
147
    read_wmc_BoundingBox: function(context, node) {
148
        context.projection = node.getAttribute("SRS");
149
        context.bounds = new OpenLayers.Bounds(
150
            node.getAttribute("minx"), node.getAttribute("miny"),
151
            node.getAttribute("maxx"), node.getAttribute("maxy")
152
        );
153
    },
154
    
155
    /**
156
     * Method: read_wmc_LayerList
157
     */
158
    read_wmc_LayerList: function(context, node) {
159
        // layersContext is an array containing info for each layer
160
        context.layersContext = [];
161
        this.runChildNodes(context, node);
162
    },
163
    
164
    /**
165
     * Method: read_wmc_Layer
166
     */
167
    read_wmc_Layer: function(context, node) {
168
        var layerContext = {
169
            visibility: (node.getAttribute("hidden") != "1"),
170
            queryable: (node.getAttribute("queryable") == "1"),
171
            formats: [],
172
             styles: [],
173
             metadata: {}
174
        };
175

    
176
        this.runChildNodes(layerContext, node);
177
        // set properties common to multiple objects on layer options/params
178
        context.layersContext.push(layerContext);
179
    },
180
    
181
    /**
182
     * Method: read_wmc_Extension
183
     */
184
    read_wmc_Extension: function(obj, node) {
185
        this.runChildNodes(obj, node);
186
    },
187

    
188
    /**
189
     * Method: read_ol_units
190
     */
191
    read_ol_units: function(layerContext, node) {
192
        layerContext.units = this.getChildValue(node);
193
    },
194
    
195
    /**
196
     * Method: read_ol_maxExtent
197
     */
198
    read_ol_maxExtent: function(obj, node) {
199
        var bounds = new OpenLayers.Bounds(
200
            node.getAttribute("minx"), node.getAttribute("miny"),
201
            node.getAttribute("maxx"), node.getAttribute("maxy")
202
        );
203
        obj.maxExtent = bounds;
204
    },
205
    
206
    /**
207
     * Method: read_ol_transparent
208
     */
209
    read_ol_transparent: function(layerContext, node) {
210
        layerContext.transparent = this.getChildValue(node);
211
    },
212

    
213
    /**
214
     * Method: read_ol_numZoomLevels
215
     */
216
    read_ol_numZoomLevels: function(layerContext, node) {
217
        layerContext.numZoomLevels = parseInt(this.getChildValue(node));
218
    },
219

    
220
    /**
221
     * Method: read_ol_opacity
222
     */
223
    read_ol_opacity: function(layerContext, node) {
224
        layerContext.opacity = parseFloat(this.getChildValue(node));
225
    },
226

    
227
    /**
228
     * Method: read_ol_singleTile
229
     */
230
    read_ol_singleTile: function(layerContext, node) {
231
        layerContext.singleTile = (this.getChildValue(node) == "true");
232
    },
233

    
234
    /**
235
     * Method: read_ol_tileSize
236
     */
237
    read_ol_tileSize: function(layerContext, node) {
238
        var obj = {"width": node.getAttribute("width"), "height": node.getAttribute("height")};
239
        layerContext.tileSize = obj;
240
    },
241
    
242
    /**
243
     * Method: read_ol_isBaseLayer
244
     */
245
    read_ol_isBaseLayer: function(layerContext, node) {
246
        layerContext.isBaseLayer = (this.getChildValue(node) == "true");
247
    },
248

    
249
    /**
250
     * Method: read_ol_displayInLayerSwitcher
251
     */
252
    read_ol_displayInLayerSwitcher: function(layerContext, node) {
253
        layerContext.displayInLayerSwitcher = (this.getChildValue(node) == "true");
254
    },
255

    
256
    /**
257
     * Method: read_wmc_Server
258
     */
259
    read_wmc_Server: function(layerContext, node) {
260
        layerContext.version = node.getAttribute("version");
261
         layerContext.url = this.getOnlineResource_href(node);
262
         layerContext.metadata.servertitle = node.getAttribute("title");
263
    },
264

    
265
    /**
266
     * Method: read_wmc_FormatList
267
     */
268
    read_wmc_FormatList: function(layerContext, node) {
269
        this.runChildNodes(layerContext, node);
270
    },
271

    
272
    /**
273
     * Method: read_wmc_Format
274
     */
275
    read_wmc_Format: function(layerContext, node) {
276
        var format = {
277
            value: this.getChildValue(node)
278
        };
279
        if(node.getAttribute("current") == "1") {
280
            format.current = true;
281
        }
282
        layerContext.formats.push(format);
283
    },
284
    
285
    /**
286
     * Method: read_wmc_StyleList
287
     */
288
    read_wmc_StyleList: function(layerContext, node) {
289
        this.runChildNodes(layerContext, node);
290
    },
291

    
292
    /**
293
     * Method: read_wmc_Style
294
     */
295
    read_wmc_Style: function(layerContext, node) {
296
        var style = {};
297
        this.runChildNodes(style, node);
298
        if(node.getAttribute("current") == "1") {
299
            style.current = true;
300
        }
301
        layerContext.styles.push(style);
302
    },
303
    
304
    /**
305
     * Method: read_wmc_SLD
306
     */
307
    read_wmc_SLD: function(style, node) {
308
        this.runChildNodes(style, node);
309
        // style either comes back with an href or a body property
310
    },
311
    
312
    /**
313
     * Method: read_sld_StyledLayerDescriptor
314
     */
315
    read_sld_StyledLayerDescriptor: function(sld, node) {
316
        var xml = OpenLayers.Format.XML.prototype.write.apply(this, [node]);
317
        sld.body = xml;
318
    },
319

    
320
    /**
321
      * Method: read_sld_FeatureTypeStyle
322
      */
323
     read_sld_FeatureTypeStyle: function(sld, node) {
324
         var xml = OpenLayers.Format.XML.prototype.write.apply(this, [node]);
325
         sld.body = xml;
326
     },
327

    
328
     /**
329
     * Method: read_wmc_OnlineResource
330
     */
331
    read_wmc_OnlineResource: function(obj, node) {
332
        obj.href = this.getAttributeNS(
333
            node, this.namespaces.xlink, "href"
334
        );
335
    },
336
    
337
    /**
338
     * Method: read_wmc_Name
339
     */
340
    read_wmc_Name: function(obj, node) {
341
        var name = this.getChildValue(node);
342
        if(name) {
343
            obj.name = name;
344
        }
345
    },
346

    
347
    /**
348
     * Method: read_wmc_Title
349
     */
350
    read_wmc_Title: function(obj, node) {
351
        var title = this.getChildValue(node);
352
        if(title) {
353
            obj.title = title;
354
        }
355
    },
356

    
357
    /**
358
     * Method: read_wmc_MetadataURL
359
     */
360
    read_wmc_MetadataURL: function(layerContext, node) {
361
         layerContext.metadataURL = this.getOnlineResource_href(node);
362
     },
363

    
364
     /**
365
      * Method: read_wmc_KeywordList
366
      */
367
     read_wmc_KeywordList: function(context, node) {
368
         context.keywords = [];
369
         this.runChildNodes(context.keywords, node);
370
    },
371

    
372
    /**
373
      * Method: read_wmc_Keyword
374
      */
375
     read_wmc_Keyword: function(keywords, node) {
376
         keywords.push(this.getChildValue(node));
377
     },
378

    
379
     /**
380
     * Method: read_wmc_Abstract
381
     */
382
    read_wmc_Abstract: function(obj, node) {
383
        var abst = this.getChildValue(node);
384
        if(abst) {
385
            obj["abstract"] = abst;
386
        }
387
    },
388
    
389
    /**
390
      * Method: read_wmc_LogoURL
391
      */
392
     read_wmc_LogoURL: function(context, node) {
393
         context.logo = {
394
             width:  node.getAttribute("width"),
395
             height: node.getAttribute("height"),
396
             format: node.getAttribute("format"),
397
             href:   this.getOnlineResource_href(node)
398
         };
399
     },
400

    
401
     /**
402
      * Method: read_wmc_DescriptionURL
403
      */
404
     read_wmc_DescriptionURL: function(context, node) {
405
         context.descriptionURL = this.getOnlineResource_href(node);
406
     },
407

    
408
     /**
409
      * Method: read_wmc_ContactInformation
410
     */
411
     read_wmc_ContactInformation: function(obj, node) {
412
         var contact = {};
413
         this.runChildNodes(contact, node);
414
         obj.contactInformation = contact;
415
     },
416

    
417
     /**
418
      * Method: read_wmc_ContactPersonPrimary
419
      */
420
     read_wmc_ContactPersonPrimary: function(contact, node) {
421
         var personPrimary = {};
422
         this.runChildNodes(personPrimary, node);
423
         contact.personPrimary = personPrimary;
424
     },
425

    
426
     /**
427
      * Method: read_wmc_ContactPerson
428
      */
429
     read_wmc_ContactPerson: function(primaryPerson, node) {
430
         var person = this.getChildValue(node);
431
         if (person) {
432
             primaryPerson.person = person;
433
         }
434
     },
435

    
436
     /**
437
      * Method: read_wmc_ContactOrganization
438
      */
439
     read_wmc_ContactOrganization: function(primaryPerson, node) {
440
         var organization = this.getChildValue(node);
441
         if (organization) {
442
             primaryPerson.organization = organization;
443
         }
444
     },
445

    
446
     /**
447
      * Method: read_wmc_ContactPosition
448
      */
449
     read_wmc_ContactPosition: function(contact, node) {
450
         var position = this.getChildValue(node);
451
         if (position) {
452
             contact.position = position;
453
         }
454
     },
455

    
456
     /**
457
      * Method: read_wmc_ContactAddress
458
      */
459
     read_wmc_ContactAddress: function(contact, node) {
460
         var contactAddress = {};
461
         this.runChildNodes(contactAddress, node);
462
         contact.contactAddress = contactAddress;
463
     },
464

    
465
     /**
466
      * Method: read_wmc_AddressType
467
      */
468
     read_wmc_AddressType: function(contactAddress, node) {
469
         var type = this.getChildValue(node);
470
         if (type) {
471
             contactAddress.type = type;
472
         }
473
     },
474

    
475
     /**
476
      * Method: read_wmc_Address
477
      */
478
     read_wmc_Address: function(contactAddress, node) {
479
         var address = this.getChildValue(node);
480
         if (address) {
481
             contactAddress.address = address;
482
         }
483
     },
484

    
485
     /**
486
      * Method: read_wmc_City
487
      */
488
     read_wmc_City: function(contactAddress, node) {
489
         var city = this.getChildValue(node);
490
         if (city) {
491
             contactAddress.city = city;
492
         }
493
     },
494

    
495
     /**
496
      * Method: read_wmc_StateOrProvince
497
      */
498
     read_wmc_StateOrProvince: function(contactAddress, node) {
499
         var stateOrProvince = this.getChildValue(node);
500
         if (stateOrProvince) {
501
             contactAddress.stateOrProvince = stateOrProvince;
502
         }
503
     },
504

    
505
     /**
506
      * Method: read_wmc_PostCode
507
      */
508
     read_wmc_PostCode: function(contactAddress, node) {
509
         var postcode = this.getChildValue(node);
510
         if (postcode) {
511
             contactAddress.postcode = postcode;
512
         }
513
     },
514

    
515
     /**
516
      * Method: read_wmc_Country
517
      */
518
     read_wmc_Country: function(contactAddress, node) {
519
         var country = this.getChildValue(node);
520
         if (country) {
521
             contactAddress.country = country;
522
         }
523
     },
524

    
525
     /**
526
      * Method: read_wmc_ContactVoiceTelephone
527
      */
528
     read_wmc_ContactVoiceTelephone: function(contact, node) {
529
         var phone = this.getChildValue(node);
530
         if (phone) {
531
             contact.phone = phone;
532
         }
533
     },
534

    
535
     /**
536
      * Method: read_wmc_ContactFacsimileTelephone
537
      */
538
     read_wmc_ContactFacsimileTelephone: function(contact, node) {
539
         var fax = this.getChildValue(node);
540
         if (fax) {
541
             contact.fax = fax;
542
         }
543
     },
544

    
545
     /**
546
      * Method: read_wmc_ContactElectronicMailAddress
547
      */
548
     read_wmc_ContactElectronicMailAddress: function(contact, node) {
549
         var email = this.getChildValue(node);
550
         if (email) {
551
             contact.email = email;
552
         }
553
     },
554

    
555
     /**
556
      * Method: read_wmc_DataURL
557
      */
558
     read_wmc_DataURL: function(layerContext, node) {
559
         layerContext.dataURL = this.getOnlineResource_href(node);
560
     },
561

    
562
     /**
563
     * Method: read_wmc_LegendURL
564
     */
565
    read_wmc_LegendURL: function(style, node) {
566
        var legend = {
567
            width: node.getAttribute('width'),
568
             height: node.getAttribute('height'),
569
             format: node.getAttribute('format'),
570
             href:   this.getOnlineResource_href(node)
571
        };
572
        style.legend = legend;
573
    },
574
    
575
    /**
576
      * Method: read_wmc_DimensionList
577
      */
578
     read_wmc_DimensionList: function(layerContext, node) {
579
         layerContext.dimensions = {};
580
         this.runChildNodes(layerContext.dimensions, node);
581
     },
582
     /**
583
      * Method: read_wmc_Dimension
584
      */
585
     read_wmc_Dimension: function(dimensions, node) {
586
         var name = node.getAttribute("name").toLowerCase();
587

    
588
         var dim = {
589
             name:           name,
590
             units:          node.getAttribute("units")          ||  "",
591
             unitSymbol:     node.getAttribute("unitSymbol")     ||  "",
592
             userValue:      node.getAttribute("userValue")      ||  "",
593
             nearestValue:   node.getAttribute("nearestValue")   === "1",
594
             multipleValues: node.getAttribute("multipleValues") === "1",
595
             current:        node.getAttribute("current")        === "1",
596
             "default":      node.getAttribute("default")        ||  ""
597
         };
598
         var values = this.getChildValue(node);
599
         dim.values = values.split(",");
600

    
601
         dimensions[dim.name] = dim;
602
     },
603

    
604
     /**
605
     * Method: write
606
     *
607
     * Parameters:
608
     * context - {Object} An object representing the map context.
609
     * options - {Object} Optional object.
610
     *
611
     * Returns:
612
     * {String} A WMC document string.
613
     */
614
    write: function(context, options) {
615
        var root = this.createElementDefaultNS("ViewContext");
616
        this.setAttributes(root, {
617
            version: this.VERSION,
618
            id: (options && typeof options.id == "string") ?
619
                    options.id :
620
                    OpenLayers.Util.createUniqueID("OpenLayers_Context_")
621
        });
622
        
623
        // add schemaLocation attribute
624
        this.setAttributeNS(
625
            root, this.namespaces.xsi,
626
            "xsi:schemaLocation", this.schemaLocation
627
        );
628
        
629
        // required General element
630
        root.appendChild(this.write_wmc_General(context));
631

    
632
        // required LayerList element
633
        root.appendChild(this.write_wmc_LayerList(context));
634

    
635
        return OpenLayers.Format.XML.prototype.write.apply(this, [root]);
636
    },
637
    
638
    /**
639
     * Method: createElementDefaultNS
640
     * Shorthand for createElementNS with namespace from <defaultPrefix>.
641
     *     Can optionally be used to set attributes and a text child value.
642
     *
643
     * Parameters:
644
     * name - {String} The qualified node name.
645
     * childValue - {String} Optional value for text child node.
646
     * attributes - {Object} Optional object representing attributes.
647
     *
648
     * Returns:
649
     * {Element} An element node.
650
     */
651
    createElementDefaultNS: function(name, childValue, attributes) {
652
        var node = this.createElementNS(
653
            this.namespaces[this.defaultPrefix],
654
            name
655
        );
656
        if(childValue) {
657
            node.appendChild(this.createTextNode(childValue));
658
        }
659
        if(attributes) {
660
            this.setAttributes(node, attributes);
661
        }
662
        return node;
663
    },
664
    
665
    /**
666
     * Method: setAttributes
667
     * Set multiple attributes given key value pairs from an object.
668
     *
669
     * Parameters:
670
     * node - {Element} An element node.
671
     * obj - {Object} An object whose properties represent attribute names and
672
     *     values represent attribute values.
673
     */
674
    setAttributes: function(node, obj) {
675
        var value;
676
        for(var name in obj) {
677
            value = obj[name].toString();
678
            if(value.match(/[A-Z]/)) {
679
                // safari lowercases attributes with setAttribute
680
                this.setAttributeNS(node, null, name, value);
681
            } else {
682
                node.setAttribute(name, value);
683
            }
684
        }
685
    },
686

    
687
    /**
688
     * Method: write_wmc_General
689
     * Create a General node given an context object.
690
     *
691
     * Parameters:
692
     * context - {Object} Context object.
693
     *
694
     * Returns:
695
     * {Element} A WMC General element node.
696
     */
697
    write_wmc_General: function(context) {
698
        var node = this.createElementDefaultNS("General");
699

    
700
        // optional Window element
701
        if(context.size) {
702
            node.appendChild(this.createElementDefaultNS(
703
                "Window", null,
704
                {
705
                    width: context.size.w,
706
                    height: context.size.h
707
                }
708
            ));
709
        }
710
        
711
        // required BoundingBox element
712
        var bounds = context.bounds;
713
        node.appendChild(this.createElementDefaultNS(
714
            "BoundingBox", null,
715
            {
716
                minx: bounds.left.toPrecision(18),
717
                miny: bounds.bottom.toPrecision(18),
718
                maxx: bounds.right.toPrecision(18),
719
                maxy: bounds.top.toPrecision(18),
720
                SRS: context.projection
721
            }
722
        ));
723

    
724
        // required Title element
725
        node.appendChild(this.createElementDefaultNS(
726
            "Title", context.title
727
        ));
728
        
729
         // optional KeywordList element
730
         if (context.keywords) {
731
             node.appendChild(this.write_wmc_KeywordList(context.keywords));
732
         }
733

    
734
         // optional Abstract element
735
         if (context["abstract"]) {
736
             node.appendChild(this.createElementDefaultNS(
737
                 "Abstract", context["abstract"]
738
             ));
739
         }
740

    
741
         // Optional LogoURL element
742
         if (context.logo) {
743
             node.appendChild(this.write_wmc_URLType("LogoURL", context.logo.href, context.logo));
744
         }
745

    
746
         // Optional DescriptionURL element
747
         if (context.descriptionURL) {
748
             node.appendChild(this.write_wmc_URLType("DescriptionURL", context.descriptionURL));
749
         }
750

    
751
         // Optional ContactInformation element
752
         if (context.contactInformation) {
753
             node.appendChild(this.write_wmc_ContactInformation(context.contactInformation));
754
         }
755

    
756
        // OpenLayers specific map properties
757
        node.appendChild(this.write_ol_MapExtension(context));
758
        
759
        return node;
760
    },
761
    
762
    /**
763
      * Method: write_wmc_KeywordList
764
      */
765
     write_wmc_KeywordList: function(keywords) {
766
         var node = this.createElementDefaultNS("KeywordList");
767

    
768
         for (var i=0, len=keywords.length; i<len; i++) {
769
             node.appendChild(this.createElementDefaultNS(
770
                 "Keyword", keywords[i]
771
             ));
772
         }
773
         return node;
774
     },
775
     /**
776
      * Method: write_wmc_ContactInformation
777
      */
778
     write_wmc_ContactInformation: function(contact) {
779
         var node = this.createElementDefaultNS("ContactInformation");
780

    
781
         if (contact.personPrimary) {
782
             node.appendChild(this.write_wmc_ContactPersonPrimary(contact.personPrimary));
783
         }
784
         if (contact.position) {
785
             node.appendChild(this.createElementDefaultNS(
786
                 "ContactPosition", contact.position
787
             ));
788
         }
789
         if (contact.contactAddress) {
790
             node.appendChild(this.write_wmc_ContactAddress(contact.contactAddress));
791
         }
792
         if (contact.phone) {
793
             node.appendChild(this.createElementDefaultNS(
794
                 "ContactVoiceTelephone", contact.phone
795
             ));
796
         }
797
         if (contact.fax) {
798
             node.appendChild(this.createElementDefaultNS(
799
                 "ContactFacsimileTelephone", contact.fax
800
             ));
801
         }
802
         if (contact.email) {
803
             node.appendChild(this.createElementDefaultNS(
804
                 "ContactElectronicMailAddress", contact.email
805
             ));
806
         }
807
         return node;
808
     },
809

    
810
     /**
811
      * Method: write_wmc_ContactPersonPrimary
812
      */
813
     write_wmc_ContactPersonPrimary: function(personPrimary) {
814
         var node = this.createElementDefaultNS("ContactPersonPrimary");
815
         if (personPrimary.person) {
816
             node.appendChild(this.createElementDefaultNS(
817
                 "ContactPerson", personPrimary.person
818
             ));
819
         }
820
         if (personPrimary.organization) {
821
             node.appendChild(this.createElementDefaultNS(
822
                 "ContactOrganization", personPrimary.organization
823
             ));
824
         }
825
         return node;
826
     },
827

    
828
     /**
829
      * Method: write_wmc_ContactAddress
830
      */
831
     write_wmc_ContactAddress: function(contactAddress) {
832
         var node = this.createElementDefaultNS("ContactAddress");
833
         if (contactAddress.type) {
834
             node.appendChild(this.createElementDefaultNS(
835
                 "AddressType", contactAddress.type
836
             ));
837
         }
838
         if (contactAddress.address) {
839
             node.appendChild(this.createElementDefaultNS(
840
                 "Address", contactAddress.address
841
             ));
842
         }
843
         if (contactAddress.city) {
844
             node.appendChild(this.createElementDefaultNS(
845
                 "City", contactAddress.city
846
             ));
847
         }
848
         if (contactAddress.stateOrProvince) {
849
             node.appendChild(this.createElementDefaultNS(
850
                 "StateOrProvince", contactAddress.stateOrProvince
851
             ));
852
         }
853
         if (contactAddress.postcode) {
854
             node.appendChild(this.createElementDefaultNS(
855
                 "PostCode", contactAddress.postcode
856
             ));
857
         }
858
         if (contactAddress.country) {
859
             node.appendChild(this.createElementDefaultNS(
860
                 "Country", contactAddress.country
861
             ));
862
         }
863
         return node;
864
     },
865

    
866
     /**
867
     * Method: write_ol_MapExtension
868
     */
869
    write_ol_MapExtension: function(context) {
870
        var node = this.createElementDefaultNS("Extension");
871
        
872
        var bounds = context.maxExtent;
873
        if(bounds) {
874
            var maxExtent = this.createElementNS(
875
                this.namespaces.ol, "ol:maxExtent"
876
            );
877
            this.setAttributes(maxExtent, {
878
                minx: bounds.left.toPrecision(18),
879
                miny: bounds.bottom.toPrecision(18),
880
                maxx: bounds.right.toPrecision(18),
881
                maxy: bounds.top.toPrecision(18)
882
            });
883
            node.appendChild(maxExtent);
884
        }
885
        
886
        return node;
887
    },
888
    
889
    /**
890
     * Method: write_wmc_LayerList
891
     * Create a LayerList node given an context object.
892
     *
893
     * Parameters:
894
     * context - {Object} Context object.
895
     *
896
     * Returns:
897
     * {Element} A WMC LayerList element node.
898
     */
899
    write_wmc_LayerList: function(context) {
900
        var list = this.createElementDefaultNS("LayerList");
901
        
902
        for(var i=0, len=context.layersContext.length; i<len; ++i) {
903
            list.appendChild(this.write_wmc_Layer(context.layersContext[i]));
904
        }
905
        
906
        return list;
907
    },
908

    
909
    /**
910
     * Method: write_wmc_Layer
911
     * Create a Layer node given a layer context object.
912
     *
913
     * Parameters:
914
     * context - {Object} A layer context object.}
915
     *
916
     * Returns:
917
     * {Element} A WMC Layer element node.
918
     */
919
    write_wmc_Layer: function(context) {
920
        var node = this.createElementDefaultNS(
921
            "Layer", null, {
922
                queryable: context.queryable ? "1" : "0",
923
                hidden: context.visibility ? "0" : "1"
924
            }
925
        );
926
        
927
        // required Server element
928
        node.appendChild(this.write_wmc_Server(context));
929

    
930
        // required Name element
931
        node.appendChild(this.createElementDefaultNS(
932
            "Name", context.name
933
        ));
934
        
935
        // required Title element
936
        node.appendChild(this.createElementDefaultNS(
937
            "Title", context.title
938
        ));
939

    
940
         // optional Abstract element
941
         if (context["abstract"]) {
942
             node.appendChild(this.createElementDefaultNS(
943
                 "Abstract", context["abstract"]
944
             ));
945
         }
946

    
947
         // optional DataURL element
948
         if (context.dataURL) {
949
             node.appendChild(this.write_wmc_URLType("DataURL", context.dataURL));
950
         }
951

    
952
        // optional MetadataURL element
953
        if (context.metadataURL) {
954
             node.appendChild(this.write_wmc_URLType("MetadataURL", context.metadataURL));
955
        }
956
        
957
        return node;
958
    },
959
    
960
    /**
961
     * Method: write_wmc_LayerExtension
962
     * Add OpenLayers specific layer parameters to an Extension element.
963
     *
964
     * Parameters:
965
     * context - {Object} A layer context object.
966
     *
967
     * Returns:
968
     * {Element} A WMC Extension element (for a layer).
969
     */
970
    write_wmc_LayerExtension: function(context) {
971
        var node = this.createElementDefaultNS("Extension");
972
        
973
        var bounds = context.maxExtent;
974
        var maxExtent = this.createElementNS(
975
            this.namespaces.ol, "ol:maxExtent"
976
        );
977
        this.setAttributes(maxExtent, {
978
            minx: bounds.left.toPrecision(18),
979
            miny: bounds.bottom.toPrecision(18),
980
            maxx: bounds.right.toPrecision(18),
981
            maxy: bounds.top.toPrecision(18)
982
        });
983
        node.appendChild(maxExtent);
984
        
985
        if (context.tileSize && !context.singleTile) {
986
            var size = this.createElementNS(
987
                this.namespaces.ol, "ol:tileSize"
988
            );
989
            this.setAttributes(size, context.tileSize);
990
            node.appendChild(size);
991
        }
992
        
993
        var properties = [
994
            "transparent", "numZoomLevels", "units", "isBaseLayer",
995
            "opacity", "displayInLayerSwitcher", "singleTile"
996
        ];
997
        var child;
998
        for(var i=0, len=properties.length; i<len; ++i) {
999
            child = this.createOLPropertyNode(context, properties[i]);
1000
            if(child) {
1001
                node.appendChild(child);
1002
            }
1003
        }
1004

    
1005
        return node;
1006
    },
1007
    
1008
    /**
1009
     * Method: createOLPropertyNode
1010
     * Create a node representing an OpenLayers property.  If the property is
1011
     *     null or undefined, null will be returned.
1012
     *
1013
     * Parameters:
1014
     * obj - {Object} An object.
1015
     * prop - {String} A property.
1016
     *
1017
     * Returns:
1018
     * {Element} A property node.
1019
     */
1020
    createOLPropertyNode: function(obj, prop) {
1021
        var node = null;
1022
        if(obj[prop] != null) {
1023
            node = this.createElementNS(this.namespaces.ol, "ol:" + prop);
1024
            node.appendChild(this.createTextNode(obj[prop].toString()));
1025
        }
1026
        return node;
1027
    },
1028

    
1029
    /**
1030
     * Method: write_wmc_Server
1031
     * Create a Server node given a layer context object.
1032
     *
1033
     * Parameters:
1034
     * context - {Object} Layer context object.
1035
     *
1036
     * Returns:
1037
     * {Element} A WMC Server element node.
1038
     */
1039
    write_wmc_Server: function(context) {
1040
         var server = context.server;
1041
        var node = this.createElementDefaultNS("Server");
1042
         var attributes = {
1043
            service: "OGC:WMS",
1044
             version: server.version
1045
         };
1046
         if (server.title) {
1047
             attributes.title = server.title;
1048
         }
1049
         this.setAttributes(node, attributes);
1050
        
1051
        // required OnlineResource element
1052
         node.appendChild(this.write_wmc_OnlineResource(server.url));
1053
        
1054
        return node;
1055
    },
1056

    
1057
    /**
1058
     * Method: write_wmc_URLType
1059
     * Create a LogoURL/DescriptionURL/MetadataURL/DataURL/LegendURL node given a object and elementName.
1060
     *
1061
     * Parameters:
1062
     * elName - {String} Name of element (LogoURL/DescriptionURL/MetadataURL/LegendURL)
1063
     * url - {String} URL string value
1064
     * attr - {Object} Optional attributes (width, height, format)
1065
     *
1066
     * Returns:
1067
     * {Element} A WMC element node.
1068
     */
1069
     write_wmc_URLType: function(elName, url, attr) {
1070
         var node = this.createElementDefaultNS(elName);
1071
         node.appendChild(this.write_wmc_OnlineResource(url));
1072
         if (attr) {
1073
             var optionalAttributes = ["width", "height", "format"];
1074
             for (var i=0; i<optionalAttributes.length; i++) {
1075
                 if (optionalAttributes[i] in attr) {
1076
                     node.setAttribute(optionalAttributes[i], attr[optionalAttributes[i]]);
1077
                 }
1078
             }
1079
         }
1080
         return node;
1081
     },
1082

    
1083
     /**
1084
      * Method: write_wmc_DimensionList
1085
      */
1086
     write_wmc_DimensionList: function(context) {
1087
         var node = this.createElementDefaultNS("DimensionList");
1088
         var required_attributes = {
1089
             name: true,
1090
             units: true,
1091
             unitSymbol: true,
1092
             userValue: true
1093
         };
1094
         for (var dim in context.dimensions) {
1095
             var attributes = {};
1096
             var dimension = context.dimensions[dim];
1097
             for (var name in dimension) {
1098
                 if (typeof dimension[name] == "boolean") {
1099
                     attributes[name] = Number(dimension[name]);
1100
                 } else {
1101
                     attributes[name] = dimension[name];
1102
                 }
1103
             }
1104
             var values = "";
1105
             if (attributes.values) {
1106
                 values = attributes.values.join(",");
1107
                 delete attributes.values;
1108
             }
1109

    
1110
             node.appendChild(this.createElementDefaultNS(
1111
                 "Dimension", values, attributes
1112
             ));
1113
         }
1114
        return node;
1115
    },
1116

    
1117
    /**
1118
     * Method: write_wmc_FormatList
1119
     * Create a FormatList node given a layer context.
1120
     *
1121
     * Parameters:
1122
     * context - {Object} Layer context object.
1123
     *
1124
     * Returns:
1125
     * {Element} A WMC FormatList element node.
1126
     */
1127
    write_wmc_FormatList: function(context) {
1128
        var node = this.createElementDefaultNS("FormatList");
1129
        for (var i=0, len=context.formats.length; i<len; i++) {
1130
            var format = context.formats[i];
1131
            node.appendChild(this.createElementDefaultNS(
1132
                "Format",
1133
                format.value,
1134
                (format.current && format.current == true) ?
1135
                    {current: "1"} : null
1136
            ));
1137
        }
1138

    
1139
        return node;
1140
    },
1141

    
1142
    /**
1143
     * Method: write_wmc_StyleList
1144
     * Create a StyleList node given a layer context.
1145
     *
1146
     * Parameters:
1147
     * layer - {Object} Layer context object.
1148
     *
1149
     * Returns:
1150
     * {Element} A WMC StyleList element node.
1151
     */
1152
    write_wmc_StyleList: function(layer) {
1153
        var node = this.createElementDefaultNS("StyleList");
1154

    
1155
        var styles = layer.styles;
1156
        if (styles && OpenLayers.Util.isArray(styles)) {
1157
            var sld;
1158
            for (var i=0, len=styles.length; i<len; i++) {
1159
                var s = styles[i];
1160
                // three style types to consider
1161
                // [1] linked SLD
1162
                // [2] inline SLD
1163
                // [3] named style
1164
                // running child nodes always gets name, optionally gets href or body
1165
                var style = this.createElementDefaultNS(
1166
                    "Style",
1167
                    null,
1168
                    (s.current && s.current == true) ?
1169
                    {current: "1"} : null
1170
                );
1171
                if(s.href) { // [1]
1172
                    sld = this.createElementDefaultNS("SLD");
1173
                     // Name is optional.
1174
                     if (s.name) {
1175
                    sld.appendChild(this.createElementDefaultNS("Name", s.name));
1176
                     }
1177
                    // Title is optional.
1178
                    if (s.title) {
1179
                        sld.appendChild(this.createElementDefaultNS("Title", s.title));
1180
                    }
1181
                     // LegendURL is optional
1182
                     if (s.legend) {
1183
                         sld.appendChild(this.write_wmc_URLType("LegendURL", s.legend.href, s.legend));
1184
                     }
1185

    
1186
                     var link = this.write_wmc_OnlineResource(s.href);
1187
                     sld.appendChild(link);
1188
                    style.appendChild(sld);
1189
                } else if(s.body) { // [2]
1190
                    sld = this.createElementDefaultNS("SLD");
1191
                     // Name is optional.
1192
                     if (s.name) {
1193
                         sld.appendChild(this.createElementDefaultNS("Name", s.name));
1194
                     }
1195
                     // Title is optional.
1196
                     if (s.title) {
1197
                         sld.appendChild(this.createElementDefaultNS("Title", s.title));
1198
                     }
1199
                     // LegendURL is optional
1200
                     if (s.legend) {
1201
                         sld.appendChild(this.write_wmc_URLType("LegendURL", s.legend.href, s.legend));
1202
                     }
1203

    
1204
                    // read in body as xml doc - assume proper namespace declarations
1205
                    var doc = OpenLayers.Format.XML.prototype.read.apply(this, [s.body]);
1206
                    // append to StyledLayerDescriptor node
1207
                    var imported = doc.documentElement;
1208
                    if(sld.ownerDocument && sld.ownerDocument.importNode) {
1209
                        imported = sld.ownerDocument.importNode(imported, true);
1210
                    }
1211
                    sld.appendChild(imported);
1212
                    style.appendChild(sld);            
1213
                } else { // [3]
1214
                    // both Name and Title are required.
1215
                    style.appendChild(this.createElementDefaultNS("Name", s.name));
1216
                    style.appendChild(this.createElementDefaultNS("Title", s.title));
1217
                    // Abstract is optional
1218
                    if (s['abstract']) { // abstract is a js keyword
1219
                        style.appendChild(this.createElementDefaultNS(
1220
                            "Abstract", s['abstract']
1221
                        ));
1222
                    }
1223
                     // LegendURL is optional
1224
                     if (s.legend) {
1225
                         style.appendChild(this.write_wmc_URLType("LegendURL", s.legend.href, s.legend));
1226
                }
1227
                 }
1228
                node.appendChild(style);
1229
            }
1230
        }
1231

    
1232
        return node;
1233
    },
1234

    
1235
    /**
1236
     * Method: write_wmc_OnlineResource
1237
     * Create an OnlineResource node given a URL.
1238
     *
1239
     * Parameters:
1240
     * href - {String} URL for the resource.
1241
     *
1242
     * Returns:
1243
     * {Element} A WMC OnlineResource element node.
1244
     */
1245
    write_wmc_OnlineResource: function(href) {
1246
        var node = this.createElementDefaultNS("OnlineResource");
1247
        this.setAttributeNS(node, this.namespaces.xlink, "xlink:type", "simple");
1248
        this.setAttributeNS(node, this.namespaces.xlink, "xlink:href", href);
1249
        return node;
1250
    },
1251

    
1252
     /**
1253
      * Method: getOnlineResource_href
1254
      */
1255
     getOnlineResource_href: function(node) {
1256
         var object = {};
1257
         var links = node.getElementsByTagName("OnlineResource");
1258
         if(links.length > 0) {
1259
             this.read_wmc_OnlineResource(object, links[0]);
1260
         }
1261
         return object.href;
1262
     },
1263

    
1264

    
1265
    CLASS_NAME: "OpenLayers.Format.WMC.v1" 
1266

    
1267
});
(1-1/3)