Project

General

Profile

1
/*
2
License: LGPL as per: http://www.gnu.org/copyleft/lesser.html
3
$Id: OwsContext.js 3887 2008-02-27 18:18:53Z ahocevar $
4
*/
5

    
6
// Ensure this object's dependancies are loaded.
7
mapbuilder.loadScript(baseDir+"/model/ModelBase.js");
8

    
9
/**
10
 * Stores an OWS Context document as defined by the OGC interoperability
11
 * experiment. This model should be eventually merged with the standard OGC
12
 * context doc.
13
 * Listeners supported by this model:
14
 * "refresh" called when window parameters (width/height, bbox) are changed
15
 * "hidden" called when visibilty of a layer is changed
16
 * "wfs_getFeature" called when feature resources are loaded
17
 *
18
 * @constructor
19
 * @base ModelBase
20
 * @author Mike Adair
21
 * @requires Sarissa
22
 *
23
 */
24
function OwsContext(modelNode, parent) {
25
  // Inherit the ModelBase functions and parameters
26
  ModelBase.apply(this, new Array(modelNode, parent));
27

    
28
  // MAP-186
29
  this.namespace = this.namespace ? this.namespace.replace(/\"/g, "'")+" " : '';
30
  this.namespace = this.namespace + "xmlns:wmc='http://www.opengis.net/context' xmlns:ows='http://www.opengis.net/ows' xmlns:ogc='http://www.opengis.net/ogc' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:gml='http://www.opengis.net/gml' xmlns:wfs='http://www.opengis.net/wfs' xmlns:sld='http://www.opengis.net/sld'";
31

    
32
  /**
33
   * Change a Layer's visibility.
34
   * @param layerId  The name of the layer that is to be changed
35
   * @param hidden     String with the value to be set; 1=hidden, 0=visible.
36
   */
37
  this.setHidden=function(layerId, hidden){
38
    // Set the hidden attribute in the Context
39
    var hiddenValue = "0";
40
    if (hidden) hiddenValue = "1";
41

    
42
    var layer=this.getLayer(layerId);
43
    if (layer) layer.setAttribute("hidden", hiddenValue);
44
    // Call the listeners
45
    this.callListeners("hidden", layerId);
46
  }
47

    
48
  /**
49
   * Get the layer's visiblity attribute value.
50
   * @param layerId  The name of the layer that is to be changed
51
   * @return hidden  String with the value; 1=hidden, 0=visible.
52
   */
53
  this.getHidden=function(layerId){
54
    var hidden=1;
55
    var layer=this.getFeatureNode(layerId)
56
    if (layer) hidden = layer.getAttribute("hidden");
57
    return hidden;
58
  }
59

    
60
  /**
61
   * Get the BoundingBox value from the Context document.
62
   * @return BoundingBox array with the sequence (xmin,ymin,xmax,ymax).
63
   */
64
  this.getBoundingBox=function() {
65
    var bbox = new Array();
66
    // Extract BoundingBox from the context
67
    var lowerLeft=this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/ows:BoundingBox/ows:LowerCorner");
68
    var upperRight=this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/ows:BoundingBox/ows:UpperCorner");
69
    var strBbox = new String(getNodeValue(lowerLeft) + " " + getNodeValue(upperRight)).split(" ");
70
    for (i=0; i<strBbox.length; ++i) {
71
      bbox[i] = parseFloat(strBbox[i]);
72
    }
73
    return bbox;
74
  }
75

    
76
  /**
77
   * Set the BoundingBox element and call the refresh listeners
78
   * @param boundingBox array in the sequence (xmin, ymin, xmax, ymax).
79
   */
80
  this.setBoundingBox=function(boundingBox) {
81
    // Set BoundingBox in context
82
    var lowerLeft=this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/ows:BoundingBox/ows:LowerCorner");
83
    lowerLeft.firstChild.nodeValue = boundingBox[0] + " " + boundingBox[1];
84
    var upperRight=this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/ows:BoundingBox/ows:UpperCorner");
85
    upperRight.firstChild.nodeValue = boundingBox[2] + " " + boundingBox[3];
86
    // Call the listeners
87
    this.callListeners("bbox", boundingBox);
88
  }
89

    
90
  /**
91
   * Set the BoundingBox element and call the refresh listeners
92
   * @param boundingBox array in the sequence (xmin, ymin, xmax, ymax).
93
   */
94
  this.initBbox=function(objRef) {
95
    // Set BoundingBox in context from URL CGI params
96
    if (window.cgiArgs["bbox"]) {   //set as minx,miny,maxx,maxy
97
      var bbox = window.cgiArgs["bbox"].split(',');
98
      objRef.setBoundingBox(bbox);
99
    }
100
  }
101
  this.addListener( "loadModel", this.initBbox, this );
102
  //this.addListener( "contextLoaded", this.initBbox, this );
103

    
104
  /**
105
   * Set the aoi param and call the refresh listeners
106
   * @param boundingBox array in the sequence (xmin, ymin, xmax, ymax).
107
   */
108
  this.initAoi=function(objRef) {
109
    // Set AOI of context from URL CGI params
110
    if (window.cgiArgs["aoi"]) {      //set as ul,lr point arrays
111
      var aoi = window.cgiArgs["aoi"].split(',');
112
      objRef.setParam("aoi",new Array(new Array(aoi[0],aoi[3]),new Array(aoi[2],aoi[1])));
113
    }
114
  }
115
  this.addListener( "loadModel", this.initAoi, this );
116
  //MA this.addListener( "contextLoaded", this.initAoi, this );
117

    
118
  /**
119
   * Set the Spatial Reference System for the context document.
120
   * @param srs The Spatial Reference System.
121
   */
122
  this.setSRS=function(srs) {
123
    var bbox=this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/ows:BoundingBox");
124
    bbox.setAttribute("crs",srs);
125
    this.callListeners("srs");
126
  }
127

    
128
  /**
129
   * Get the Spatial Reference System from the context document.
130
   * @return srs The Spatial Reference System.
131
   */
132
  this.getSRS=function() {
133
    var bbox=this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/ows:BoundingBox");
134
    srs=bbox.getAttribute("crs");
135
    srs = srs ? srs : 'EPSG:4326';
136
    return srs;
137
  }
138

    
139
  /**
140
   * Get the Projection object from the context document.
141
   * @return Proj Object of  The Spatial Reference System.
142
   */
143
  this.initProj=function(objRef) {
144
    objRef.proj=new OpenLayers.Projection(objRef.getSRS());
145
  }
146
  this.addFirstListener( "loadModel", this.initProj, this );
147

    
148
  /**
149
   * Get the Window width.
150
   * @return width The width of map window from the context document
151
   */
152
  this.getWindowWidth=function() {
153
    var win=this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/wmc:Window");
154
    return win.getAttribute("width");
155
  }
156

    
157
  /**
158
   * Set the Window width.
159
   * @param width The width of map window to set in the context document
160
   */
161
  this.setWindowWidth=function(width) {
162
    var win=this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/wmc:Window");
163
    win.setAttribute("width", width);
164
    this.callListeners("resize");
165
  }
166

    
167
  /**
168
   * Get the Window height.
169
   * @return height The height of map window from the context document.
170
   */
171
  this.getWindowHeight=function() {
172
    var win=this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/wmc:Window");
173
    return win.getAttribute("height");
174
  }
175

    
176
  /**
177
   * Set the Window height.
178
   * @param height The height of map window to set in the context document
179
   */
180
  this.setWindowHeight=function(height) {
181
    var win=this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/wmc:Window");
182
    win.setAttribute("height", height);
183
    this.callListeners("resize");
184
  }
185

    
186
  /**
187
   * Returns the width/height of the map window as an array
188
   * Added by Andreas Hocevar for compatibility with Context.js
189
   */
190
  this.getWindowSize=function() {
191
    var win=this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/wmc:Window");
192
    return new Array(win.getAttribute("width"), win.getAttribute("height"));
193
  }
194

    
195
  /**
196
   * Set the Window width and height in one function call to avoid a resize event in between
197
   * setting width and height, because that causes checkBbox to be triggered, which adjusts the
198
   * bbox then when it should not yet be adjusted.
199
   * Based on setWindowSize by VTS in Context.js
200
   * Added by Andreas Hocevar for compatibility with Context.js
201
   * @param size Size of the map window as (width, height) array
202
   */
203
  this.setWindowSize=function(size) {
204
    var win=this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/wmc:Window");
205
    var width = size[0];
206
    var height = size[1];
207
    win.setAttribute("width", width);
208
    win.setAttribute("height", height);
209
    this.callListeners("resize");
210
  }
211

    
212
  /**
213
   * returns a node that has the specified feature name in the context doc
214
   * @param featureName Name element value to return
215
   * @return the node from the context doc with the specified feature name
216
   */
217
  this.getFeatureNode = function(layerId) {
218
    if( this.doc ) {
219

    
220
      // Find feature by id
221
      var feature = this.doc.selectSingleNode("//wmc:ResourceList/*[@id='"+layerId+"']");
222

    
223
      // Fallback: find feature by name
224
      if (feature == null) {
225
        feature = this.doc.selectSingleNode("//wmc:ResourceList/*[wmc:Name='"+layerId+"']");
226
      }
227

    
228
      if(feature == null ) {
229
        alert(mbGetMessage("featureNotFoundOwsContext"));
230
      }
231

    
232
      return feature;
233
    }
234
  }
235

    
236
  /**
237
   * Returns the serverUrl for the layer passed in as the feature argument.
238
   * @param requestName ignored for context docs (only GetMap supported)
239
   * @param method ignored for context docs (only GET supported)
240
   * @param feature the node for the feature from the context doc
241
   * @return height String URL for the GetMap request
242
   */
243
  this.getServerUrl = function(requestName, method, feature) {
244
    var service = requestName.split(":");
245
    if (service.length > 0) {
246
      service = service[0].toUpperCase();
247
    }
248
    var url = feature.selectSingleNode("wmc:Server[@service='OGC:"+service+"']/wmc:OnlineResource").getAttribute("xlink:href");
249
    if (!url) {
250
      // fallback to default service
251
      url = feature.selectSingleNode("wmc:Server/wmc:OnlineResource").getAttribute("xlink:href");
252
    }
253
    return url;
254
  }
255

    
256
  /**
257
   * Returns the WMS version for the layer passed in as the feature argument
258
   * @param feature the node for the feature from the context doc
259
   * @return the WMS GetMap version for the Layer.
260
   */
261
  this.getVersion = function(feature) {
262
    return feature.selectSingleNode("wmc:Server").getAttribute("version");
263
  }
264

    
265
  /**
266
   * Get HTTP method for the specified feature
267
   * @param feature the Layer node from the context doc
268
   * @return the HTTP method to get the feature with
269
   */
270
  this.getMethod = function(feature) {
271
    return feature.selectSingleNode("wmc:Server/wmc:OnlineResource").getAttribute("wmc:method");
272
  }
273

    
274
  /**
275
   * Return the service type of the bottom layer in the layer list.
276
   * This is used to match navigation tools with the basemap.
277
   */
278
  this.getBaseLayerService=function(){
279
    //x=this.doc.selectSingleNode("/wmc:OWSContext/wmc:ResourceList/wmc:Layer[last()]/wmc:Server/@service");
280
    x=this.doc.selectSingleNode("/wmc:OWSContext/wmc:ResourceList/wmc:Layer[last()]/wmc:Server");
281
    s=x.getAttribute("service");
282
    //alert("OwsContext.getBaseLayerService: s="+s);
283
    return s;
284
  }
285

    
286
  /**
287
   * listener method which loads WFS features from the context doc, after WMS
288
   * layers are loaded.
289
   * @param objRef Pointer to this object.
290
   */
291
  this.loadFeatures = function(objRef) {
292
    var nodeSelectXpath = objRef.nodeSelectXpath + "/wmc:FeatureType[wmc:Server/@service='OGC:WFS']/wmc:Name";
293
    var featureList = objRef.doc.selectNodes(nodeSelectXpath);
294
    for (var i=0; i<featureList.length; i++) {
295
      var featureName = getNodeValue(featureList[i]);
296
      objRef.setParam('wfs_GetFeature',featureName);
297
    }
298

    
299
    //this.callListeners("contextLoaded");  //PGC
300
  }
301
  this.addListener("loadModel", this.loadFeatures, this);
302

    
303
  /**
304
   * Listener function which sets stylesheet params for WebServiceRequests
305
   * @param objRef pointer to this object
306
   * @param featureNodeId the id of the node in the doc to be processed by the stylesheet
307
   */
308
  this.setRequestParameters = function(featureName, requestStylesheet) {
309
    var feature = this.getFeatureNode(featureName);
310
    if (feature.selectSingleNode("ogc:Filter")) {
311
      requestStylesheet.setParameter("filter", escape((new XMLSerializer()).serializeToString(feature.selectSingleNode("ogc:Filter"))) );
312
    }
313
  }
314
  //this.addFirstListener("wfs_GetFeature", this.setRequestParameters, this);
315

    
316
  /**
317
   * Method to get a list of queryable layers
318
   * @return the list with queryable layers
319
   */
320
  this.getQueryableLayers = function() {
321
    var listNodeArray = this.doc.selectNodes("/wmc:OWSContext/wmc:ResourceList/wmc:Layer[@queryable='1']|/wmc:OWSContext/wmc:ResourceList/wmc:FeatureType[@queryable='1']");
322
    if (listNodeArray == null) {
323
      listNodeArray = this.doc.selectNodes("/wmc:OWSContext/wmc:ResourceList/wmc:Layer|/wmc:OWSContext/wmc:ResourceList/wmc:Layer");
324
    }
325
    return listNodeArray;
326
  }
327

    
328
  /**
329
   * Method to get a list of all layers in the context doc
330
   * TBD: merge this with above, passing queryable as an optional boolean param?
331
   * @TODO Add the other layers
332
   * @return the list with all layers
333
   */
334
  this.getAllLayers = function() {
335
    var listNodeArray = this.doc.selectNodes("//wmc:Layer|//wmc:FeatureType");
336
    return listNodeArray;
337
  }
338

    
339
  /**
340
   * Method to get a layer with the specified id/name in the context doc
341
   * @param layerId/layerName the layer to be returned
342
   * @return the list with all layers
343
   * @TODO check other layers
344
   */
345
  this.getLayer = function(layerId) {
346
    var layer = this.doc.selectSingleNode("/wmc:OWSContext/wmc:ResourceList/wmc:FeatureType[@id='"+layerId+"']");
347
    if (layer == null) {
348
      layer = this.doc.selectSingleNode("/wmc:OWSContext/wmc:ResourceList/wmc:Layer[@id='"+layerId+"']");
349
    }
350
    if (layer == null) {
351
      layer = this.doc.selectSingleNode("/wmc:OWSContext/wmc:ResourceList/wmc:Layer[wmc:Name='"+layerId+"']");
352
    }
353
    if (layer == null) {
354
      layer = this.doc.selectSingleNode("/wmc:OWSContext/wmc:ResourceList/wmc:FeatureType[wmc:Name='"+layerId+"']");
355
    }
356
    if( layer == null ) {
357
      layer = this.doc.selectSingleNode("/wmc:OWSContext/wmc:ResourceList/wmc:RssLayer[@id='"+layerId+"']");
358
    }
359
    //TBD: add in time stamp
360
    return layer;
361
  }
362

    
363
  /**
364
   * Method to get a layer id with the specified id/name in the context doc
365
   * @param layerName the name of the layer of which the id is to be returned
366
   * @return the id of the layer || false
367
   */
368
  this.getLayerIdByName = function(layerName) {
369
    var layer = this.getLayer(layerName);
370
    var id;
371
    if (layer) {
372
      id = layer.getAttribute("id");
373
    }
374

    
375
    return id || false;
376
  }
377

    
378

    
379
  /**
380
   * Method to add a Layer to the LayerList
381
   * @param layerNode the Layer node from another context doc or capabiltiies doc
382
   */
383
  this.addLayer = function(objRef, layerNode) {
384
    if( objRef.doc != null ) {
385
      var parentNode = objRef.doc.selectSingleNode("/wmc:OWSContext/wmc:ResourceList");
386

    
387
      // Generate layer id if layer doesn't have an id
388
      var randomNumber = Math.round(10000 * Math.random());
389
      id = Mapbuilder.getProperty(layerNode, "wmc:Name") + "_" + randomNumber; 
390
      layerNode.setAttribute("id", id);
391
      
392
      // check if that node does not alreayd exist, replace it (query may have changed)
393
      var id = layerNode.getAttribute("id");
394
      var str = "/wmc:OWSContext/wmc:ResourceList/"+layerNode.nodeName+"[@id='"+id+"']";
395
      var node = objRef.doc.selectSingleNode(str);
396
      if( node != null ) {
397
        parentNode.removeChild(node);
398
      }
399

    
400
      parentNode.appendChild(layerNode);
401
      objRef.modified = true;
402
      if (this.debug) {
403
         mbDebugMessage( "Adding layer:"+(new XMLSerializer()).serializeToString( layerNode ) );
404
      }
405
    } else {
406
      alert(mbGetMessage("nullOwsContext"));
407
    }
408
    //objRef.callListeners("refresh");
409
  }
410
  this.addFirstListener( "addLayer", this.addLayer, this );
411

    
412
  /**
413
   * Method to get the baselayer 
414
   * @return the baseLayer
415
   * @TODO check for other baselayers
416
   */
417
   this.getBaseLayer = function() {
418
      var baseLayer = this.doc.selectSingleNode("/wmc:OWSContext/wmc:ResourceList/ows:BaseLayer");
419
      return baseLayer;
420
   }
421
   
422
 /**
423
   * Method to add a Sld to the StyleList
424
   * @param layerName the Layer name from another context doc or capabiltiies doc
425
   * TBD: make sure this will work again using layerId instead of layerName
426
   */
427
  this.addSLD = function(objRef,sldNode) {
428
    // alert("context addSLD : "+objRef.id);
429
    var layerName=Mapbuilder.getProperty(sldNode, "//Name");
430
    var parentNode = objRef.doc.selectSingleNode("//wmc:Layer[wmc:Name='"+layerName+"']");
431
    parentNode.appendChild(sldNode.cloneNode(true));
432

    
433
    objRef.modified = true;
434
      var attribs=[];
435
    attribs["sld_body"]=(new XMLSerializer()).serializeToString(objRef.doc.selectSingleNode("//wmc:Layer[wmc:Name='"+layerName+"']/wmc:StyleList/wmc:Style/wmc:SLD/wmc:StyledLayerDescriptor"));
436
    objRef.map.mbMapPane.refreshLayer(objRef.map.mbMapPane,layerName,attribs);
437
  }
438
  this.addFirstListener( "addSLD", this.addSLD, this );
439

    
440
  /**
441
   * Method to remove a Layer from the LayerList
442
   * @param layerId the Layer to be deleted
443
   */
444
  this.deleteLayer = function(objRef, layerId) {
445
    var deletedNode = objRef.getLayer(layerId);
446
    if (!deletedNode) {
447
      alert(mbGetMessage("nodeNotFound", layerId));
448
      return;
449
    }
450
    deletedNode.parentNode.removeChild(deletedNode);
451
    objRef.modified = true;
452
  }
453
  this.addFirstListener( "deleteLayer", this.deleteLayer, this );
454

    
455
  /**
456
   * Method to move a Layer in the LayerList up
457
   * @param layerId the layer to be moved
458
   */
459
  this.moveLayerUp = function(objRef, layerId) {
460
    var movedNode = objRef.getLayer(layerId);
461
    var sibNode = movedNode.selectSingleNode("following-sibling::*");
462
    if (!sibNode) {
463
      alert(mbGetMessage("cantMoveUp", layerId));
464
      return;
465
    }
466
    movedNode.parentNode.insertBefore(sibNode,movedNode);
467
    objRef.modified = true;
468
  }
469
  this.addFirstListener( "moveLayerUp", this.moveLayerUp, this );
470

    
471
  /**
472
   * Method to move a Layer in the LayerList down
473
   * @param layerId the layer to be moved
474
   */
475
  this.moveLayerDown = function(objRef, layerId) {
476
    var movedNode = objRef.getLayer(layerId);
477
    var listNodeArray = movedNode.selectNodes("preceding-sibling::*");  //preceding-sibling axis contains all previous siblings
478
    var sibNode = listNodeArray[listNodeArray.length-1];
479
    if (!sibNode) {
480
      alert(mbGetMessage("cantMoveDown", layerId));
481
      return;
482
    }
483
    movedNode.parentNode.insertBefore(movedNode,sibNode);
484
    objRef.modified = true;
485
  }
486
  this.addFirstListener( "moveLayerDown", this.moveLayerDown, this );
487

    
488
  /**
489
   * Adds a node to the Context document extension element.  The extension element
490
   * will be created if it doesn't already exist.
491
   * @param extensionNode the node to be appended in the extension element.
492
   * @return the ndoe added to the extension element
493
   */
494
  this.setExtension = function(extensionNode) {
495
    var extension = this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/wmc:Extension");
496
    if (!extension) {
497
      var general = this.doc.selectSingleNode("/wmc:OWSContext/wmc:General");
498
      var newChild = createElementWithNS(this.doc,"Extension",'http://www.opengis.net/context');
499
      extension = general.appendChild(newChild);
500
    }
501
    return extension.appendChild(extensionNode);
502
  }
503

    
504
  /**
505
   * Returns the contents of the extension element
506
   * @return the contents of the extension element
507
   */
508
  this.getExtension = function() {
509
    return this.doc.selectSingleNode("/wmc:OWSContext/wmc:General/wmc:Extension");
510
  }
511

    
512
  // PL -BRGM
513
  /**
514
   * Change a Layer's opacity
515
   * @param layerId  The name of the layer that is to be changed
516
   * @param Opacity     Value of the opacity
517
   */
518
  this.setOpacity=function(layerId, Opacity){
519
    // Set the hidden attribute in the Context
520
    var layer = this.getLayer(layerId);
521
    if (layer) layer.setAttribute("opacity", Opacity);
522
    // Call the listeners
523
    this.callListeners("opacity", layerId);
524
  }
525

    
526
  /**
527
   * Get the layer's opacity attribute value.
528
   * @param layerId  The name of the layer that is to be changed
529
   * @return hidden  String with the value; 1=hidden, 0=visible.
530
   */
531
  this.getOpacity=function(layerId){
532
    var opacity=1;
533
    var layer = this.getLayer(layerId);
534
    if (layer) opacity = layer.getAttribute("opacity");
535
    return opacity;
536
  }
537
  // PL -END
538
  
539
  /**
540
   * Parses a Dimension element from the Context document as a loadModel listener.
541
   * This results in an XML structure with one element for each GetMap time value
542
   * parameter and added to the Context extrension element.
543
   * @param objRef a pointer to this object
544
   */
545
  this.initTimeExtent = function( objRef ) {
546
    //only the first one selected is used as the timestamp source
547
    //var extentNode = objRef.doc.selectSingleNode("//wmc:Layer/wmc:Dimension[@name='time']");
548
    //TBD: how to deal with multiple time dimensions in one context doc, or caps doc?
549
    var timeNodes = objRef.doc.selectNodes("//wmc:Dimension[@name='time']");
550
    for (var i=0; i<timeNodes.length; ++i) {
551
      var extentNode = timeNodes[i];
552
      objRef.timestampList = createElementWithNS(objRef.doc,"TimestampList",mbNsUrl);
553
      var layerId;
554
      var layerNode = extentNode.parentNode.parentNode;
555
      if (layerNode.selectSingleNode("@id")) {
556
        layerId = Mapbuilder.getProperty(layerNode, "@id");
557
      } else {
558
        layerId =Mapbuilder.getProperty(layerNode, "wmc:Name");
559
      }
560
      objRef.timestampList.setAttribute("layerId", layerId);
561
      //alert("found time dimension, extent:"+getNodeValue(extentNode));
562
      var times = getNodeValue(extentNode).split(",");   //comma separated list of arguments
563
      for (var j=0; j<times.length; ++j) {
564
        var params = times[j].split("/");     // parses start/end/period
565
        if (params.length==3) {
566
          var start = setISODate(params[0]);
567
          var stop = setISODate(params[1]);
568
          var period = params[2];
569
          var parts = period.match(/^P((\d*)Y)?((\d*)M)?((\d*)D)?T?((\d*)H)?((\d*)M)?((.*)S)?/);
570
          for (var i=1; i<parts.length; ++i) {
571
            if (!parts[i]) parts[i]=0;
572
          }
573
          //alert("start time:"+start.toString());
574
          do {
575
            var timestamp = createElementWithNS(objRef.doc,"Timestamp",mbNsUrl);
576
            timestamp.appendChild(objRef.doc.createTextNode(getISODate(start)));
577
            objRef.timestampList.appendChild(timestamp);
578

    
579
            start.setFullYear(start.getFullYear()+parseInt(parts[2],10));
580
            start.setMonth(start.getMonth()+parseInt(parts[4],10));
581
            start.setDate(start.getDate()+parseInt(parts[6],10));
582
            start.setHours(start.getHours()+parseInt(parts[8],10));
583
            start.setMinutes(start.getMinutes()+parseInt(parts[10],10));
584
            start.setSeconds(start.getSeconds()+parseFloat(parts[12]));
585
            //alert("time:"+start.toString());
586
          } while(start.getTime() <= stop.getTime());
587

    
588
        } else {
589
          //output single date value
590
          var timestamp = createElementWithNS(objRef.doc,"Timestamp",mbNsUrl);
591
          timestamp.appendChild(objRef.doc.createTextNode(times[j]));
592
          objRef.timestampList.appendChild(timestamp);
593
        }
594
      }
595
     objRef.setExtension(objRef.timestampList);
596
    }
597
  }
598
  this.addFirstListener( "loadModel", this.initTimeExtent, this );
599

    
600
  /**
601
   * clear the time extent created by initTimeExtent
602
   * @param objRef reference to this model
603
   */
604
  this.clearTimeExtent = function( objRef ) {
605
    var tsList = objRef.timestampList;
606
    if (tsList) {
607
      tsList.parentNode.removeChild(tsList);
608
    }
609
  }
610
  this.addListener("newModel", this.clearTimeExtent, this);
611

    
612
  /**
613
   * Returns the current timestamp value.
614
   * @param layerName the name of the Layer from which the timestamp list was generated
615
   * @return the current timestamp value.
616
   */
617
  this.getCurrentTimestamp = function( layerName ) {
618
    var index = this.getParam("timestamp");
619
    return getNodeValue(this.timestampList.childNodes[index]);
620
  }
621

    
622
}
(12-12/19)