[OpenLayers-Commits] r12339 - in sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers: . Control

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Wed Sep 7 13:45:47 EDT 2011


Author: mpriour
Date: 2011-09-07 10:45:46 -0700 (Wed, 07 Sep 2011)
New Revision: 12339

Added:
   sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/TimeHandler.js
Removed:
   sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager/
Modified:
   sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager.js
Log:
- Modify TimeManager control to use simple class based TimeHandlers rather than OpenLayers.Control based TimeManager subclasses to control the time-enabled layer display.

- Modify TimeManager to automatically configure itself from the map and properly handle the addition or removal of layers to the map.

- Provide a method by which the control will use only the properties it was configured with instead of listening to layer related map events.

Modified: sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager.js
===================================================================
--- sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager.js	2011-09-07 17:34:09 UTC (rev 12338)
+++ sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager.js	2011-09-07 17:45:46 UTC (rev 12339)
@@ -21,6 +21,8 @@
      * Constant: EVENT_TYPES
      *
      * Supported event types:
+     *  - *beforetick* Triggered before the control advances one step in time.
+     *      Return false to prevent the tick from occuring.
      *  - *tick* Triggered when the control advances one step in time.
      *      Listeners receive an event object with a *currentTime* parameter.
      *      Event is fired after the time has been incremented but before the
@@ -37,12 +39,12 @@
      *      property indicating the control reset due to running in looped mode
      *      (true) or the reset function call (false)
      */
-    EVENT_TYPES: ["tick","play","stop","reset"],
+    EVENT_TYPES: ["beforetick","tick","play","stop","reset"],
 
 
     /**
      * Property: layers
-     * {Array(<OpenLayers.Layer.Vector>)}
+     * {Array(<OpenLayers.Layer>)}
      */
     layers: null,
 	
@@ -62,17 +64,21 @@
 	
     /**
      * Property: range
-     * {Array(Date)} 2 member array containing the minimum and maximum times
+     * {Array(Date|String)} 2 member array containing the minimum and maximum times
      *     in UTC that the time-series animation will use. (Optional if using
      *     the intervals property). The 1st value should ALWAYS be less than
      *     the second value. Use negative step values to do reverse time.
+     *     Note: You can use an ISO 8601 formated string (see 
+     *     http://tools.ietf.org/html/rfc3339) or Date objects.
      */
 	range:null,
 	
 	/**
 	 * Property: intervals
-	 * {Array(Date)} Array of valid distinct UTC dates/times that the time-
+	 * {Array(Date|String)} Array of valid distinct UTC dates/times that the time-
 	 * 	   series animation can use. (Optional)
+	 *     Note: You can use an ISO 8601 formated string (see 
+     *     http://tools.ietf.org/html/rfc3339) or Date objects.
 	 */
 	intervals:null,
 		
@@ -108,19 +114,13 @@
 	currentTime:null,
 	
 	/**
-	 * Private Property: childControls
-	 * {Array(<OpenLayers.Control.TimeManager>)} An array of the controls that
+	 * Private Property: timeHandlers
+	 * {Array(<OpenLayers.TimeHandler>)} An array of the handlers that
 	 *     this control "manages". Read-Only
 	 */
-	childControls:null,
+	timeHandlers:null,
 	
 	/**
-	 * Private Property: utcOffset
-	 * {Number} millisecond difference between local & UTC time. Read-Only
-	 */
-	utcOffset:new Date().getTimezoneOffset() * -6e4,
-	
-	/**
      * Constructor: OpenLayers.Control.TimeManager
      * Create a new time manager control.
      *
@@ -134,21 +134,139 @@
 		if(this.intervals){
 			for(var i=0,len=this.intervals.length;i<len;i++){
 				var interval = this.intervals[i];
-				if(!(interval[i] instanceof Date))this.intervals[i]=new Date(Date.parse(interval)+utcOffset);
+				if(!(interval[i] instanceof Date))this.intervals[i]=OpenLayers.Date.parse(interval);
 			}
+            this.intervals.sort(function(a,b){return b-a});
 			this.range=[this.intervals[0],this.intervals[this.intervals.length-1]];
+            this.fixedIntervals=true;
 		}else if(this.range){
-			if(!(this.range[0] instanceof Date))this.range[0]=new Date(Date.parse(this.range[0])+utcOffset);
-			if(!(this.range[1] instanceof Date))this.range[1]=new Date(Date.parse(this.range[1])+utcOffset);
+			if(!(this.range[0] instanceof Date))this.range[0]=OpenLayers.Date.parse(this.range[0]);
+			if(!(this.range[1] instanceof Date))this.range[1]=OpenLayers.Date.parse(this.range[1]);
+            this.fixedRange = true;
 		}
-		this.currentTime = new Date(this.range[0].getTime());
-		this.childControls = this.buildChildControls(options.layers,OpenLayers.Util.applyDefaults({
-			utcOffset: this.utcOffset,
-			intervals:this.intervals,
-			range:this.range
-		},options));
+		if (this.range[0]) {
+            this.currentTime = new Date(this.range[0].getTime());
+        }
+		if (options.layers) {
+            this.timeHandlers = this.buildTimeHandlers(options.layers);
+            if(this.timeHandlers.length){this.fixedLayers=true;}
+        }
 	},
 	/**
+	 * APIMethod: destroy
+	 * Destroys the control
+	 */
+	destroy:function(){
+		for(var i=this.timeHandlers.length-1;i>-1;i--){
+			this.timeHandlers[i].destroy();
+		}
+		this.layers=null;
+		OpenLayers.Control.prototype.destroy.call(this);
+	},
+    /**
+     * APIMethod: setMap
+     * Sets the map parameter of the control. Also called automattically when
+     * the control is added to the map.
+     * Parameter:
+     *    map {<OpenLayers.Map>}
+     */
+    setMap:function(map){
+        OpenLayers.Control.prototype.setMap.call(this,map);
+        //if the control was not directly intialized with specific layers, then
+        //get layers from map and build appropiate time handlers
+        if(!this.timeHandlers){
+            for(var i=0,len=map.layers.length;i<len;i++){
+                var lyr=map.layers[i];
+                if(lyr.metadata.timeInterval && lyr.metadata.timeInterval.length){
+                    if(!this.layers)layers=[];
+                    this.layers.push(lyr);
+                }
+            }
+            this.timeHandlers = this.buildTimeHandlers(this.layers)
+        }
+        //if no interval was specified & interval !== false, get from timeHandlers
+        if(!this.intevals && this.intervals !== false){
+            this.intervals = this.buildIntervals(this.timeHandlers);
+        }
+        //if no range was specified then get from timeHandlers
+        if(!this.range){
+            this.range = this.buildRange(this.timeHandlers);
+        }
+        
+        //set map handlers for layer additions and removal
+        this.map.events.on({
+            'addlayer':this.onAddLayer,
+            'removelayer':this.onRemoveLayer,
+            scope:this
+        })
+    },
+    onAddLayer: function(evt){
+        var lyr = evt.layer;
+        var added=false;
+        if (lyr.metadata.timeInterval && !this.fixedLayers) {
+            this.timeHandlers || (this.timeHandlers = [])
+            var handlerClass = lyr.CLASS_NAME.match(/\.Layer\.(\w+)/)[1]
+            for (var i = 0, len = this.timeHandlers.length; i < len; i++) {
+                if (!lyr.timeHandler && this.timeHandlers[i] instanceof OpenLayers.TimeHandler[handlerClass]) {
+                    this.timeHandlers[i].addLayer(lyr);
+                    added = true;
+                    break;
+                }
+            }
+            if (!added) {
+                var handlers = this.buildTimeHandlers([lyr]);
+                this.timeHandlers.push(handlers[0]);
+                added = true;
+            }
+            //check if layer could be used in a time handler & if so modify the
+            //control range & interval as needed. time handler will convert timeInterval
+            //values to real dates
+            if(added){
+                var lyrIntervals = lyr.metadata.timeInterval;
+                if (lyrIntervals.length > 2 && !this.fixedIntervals) {
+                    this.intervals || (this.intervals = []);
+                    this.intervals = this.getUniqueDates(this.intervals.concat(lyrIntervals));
+                    //adjust range as needed
+                    if(this.intervals[0]<this.range[0]){this.range[0]=new Date(this.intervals[0].getTime())}
+                    if(this.intervals[1]>this.range[1]){this.range[1]=new Date(this.intervals[1].getTime())}
+                }
+                else if(!this.fixedRange){
+                    if(lyrIntervals[0]<this.range[0]){this.range[0]=new Date(lyrIntervals[0].getTime())}
+                    if(lyrIntervals[1]>this.range[1]){this.range[1]=new Date(lyrIntervals[1].getTime())}
+                }
+            }
+        }
+    },
+    onRemoveLayer:function(evt){
+        var lyr = evt.layer;
+        if(lyr.metadata.timeInterval){
+            var lyrIntervals = lyr.metadata.timeInterval;
+            //find the handler with the layer
+            for(var i=0, len = this.timeHandlers.length;i<len;i++){
+                var handler = this.timeHandlers[i];
+                if(OpenLayers.Util.indexOf(handler.layers,lyr)>-1){
+                    handler.removeLayer(lyr);
+                    //if the handler doesn't handle any layers, get rid of it
+                    if(!handler.layers.length){
+                        this.timeHandlers.splice(i,1);
+                        handler.destroy();
+                    }
+                    break;
+                }
+            }
+            if(lyrIntervals.length>2 && !this.fixedIntervals){
+                this.intervals = this.buildIntervals(this.timeHandlers);
+                if(this.intervals[0]>this.range[0]){this.range[0]=new Date(this.intervals[0].getTime())}
+                if(this.intervals[1]<this.range[1]){this.range[1]=new Date(this.intervals[1].getTime())}
+            }
+            else if(!this.fixedRange){
+                if (lyrIntervals[0].getTime() == this.range[0].getTime() || lyrIntervals[1].getTime() == this.range[1].getTime()) {
+                    this.range = this.buildRange(this.timeHandlers);
+                }
+            }
+        }
+    },
+	/**
 	 * Method: tick
 	 * Advance/reverse time one step forward/backward. Fires the 'tick' event
 	 * if time can be incremented without exceeding the time range.
@@ -183,7 +301,19 @@
 			}
 		}
 		else {
-			this.events.triggerEvent('tick', {currentTime: this.currentTime});
+            function canTickCheck(){
+                var canTick = false;
+                for (var i = 0, len = this.timeHandlers.length; i < len; i++) {
+                    canTick = this.timeHandlers[i].canTick;
+                    if (!canTick) break;
+                }
+                return canTick;
+            }
+            if (canTickCheck()) {
+                this.events.triggerEvent('tick', {currentTime: this.currentTime});
+            }else{
+                //TODO: Handle not yet ready timeHandlers & don't tick until we're ready
+            }
 		}
 	},
 	/**
@@ -213,11 +343,12 @@
 	 * current time only if the animation is not currently running
 	 * 
 	 * Parameters:
-	 * range - {Arrray} UTC time range
+	 * range - {Arrray(Date|String)} UTC time range using either Date objects
+	 *     or ISO 8601 formatted strings
 	 */
 	setRange:function(range){
-		if(!(range[0] instanceof Date))range[0]=new Date(Date.parse(range[0])+utcOffset);
-		if(!(range[1] instanceof Date))range[1]=new Date(Date.parse(range[1])+utcOffset);
+		if(!(range[0] instanceof Date))range[0]=OpenLayers.Date.parse(range[0]);
+		if(!(range[1] instanceof Date))range[1]=OpenLayers.Date.parse(range[1]);
 		this.range=range;
 		//set current time to correct location if the timer isn't running yet.
 		if(!this.timer){this.currentTime = this.range[(this.step>0)?0:1]}
@@ -229,10 +360,11 @@
 	 * the currentTime if an animation has not begun.
 	 * 
 	 * Parameters:
-	 * time - {Object} UTC start time/date
+	 * time - {Date|String} UTC start time/date using either a Date object or
+	 *     ISO 8601 formatted string.
 	 */
 	setStart:function(time){
-		if(!(time instanceof Date))time=new Date(Date.parse(time)+utcOffset);
+		if(!(time instanceof Date))time=OpenLayers.Date.parse(time);
 		this.range[(this.step>0)?0:1]=time;
 		//set current time to this start time if we haven't already started
 		!this.timer && (this.currentTime=time);
@@ -244,10 +376,11 @@
 	 * the current time.
 	 * 
 	 * Parameters:
-	 * time - {Object} UTC stop time/date
+	 * time - {Date|String} UTC stop time/date using either a Date object or
+	 *     ISO 8601 formatted string.
 	 */	
 	setEnd:function(time){
-		if(!(time instanceof Date))time=new Date(Date.parse(time)+utcOffset);
+		if(!(time instanceof Date))time=OpenLayers.Date.parse(time);
 		this.range[(this.step>0)?1:0]=time;
 	},
 	/**
@@ -255,10 +388,11 @@
 	 * Manually sets the currentTime used in the control's animation.
 	 * 
 	 * Parameters: {Object} time
-	 * time - {Object} UTC current animation time/date
+	 * time - {Date|String} UTC current animantion time/date using either a 
+	 *     Date object or ISO 8601 formatted string.
 	 */
 	setTime:function(time){
-		if(!(time instanceof Date))time=new Date(Date.parse(time)+utcOffset);
+		if(!(time instanceof Date))time=OpenLayers.Date.parse(time);
 		this.currentTime = time;
 	},
 	/**
@@ -271,7 +405,7 @@
 	reset:function(){
 		this.timer && clearInterval(this.timer);
 		this.currentTime = (this.step>0)?new Date(this.range[0].getTime()):new Date(this.range[1].getTime());
-		this.events.triggerEvent('reset',{'looped':false});
+		this.events.triggerEvent('reset',{'looped':false,'currentTime':this.currentTime});
 		return this.currentTime;
 	},
 	/**
@@ -288,56 +422,121 @@
 		this.currentTime['setUTC'+stepUnit](this.currentTime['getUTC'+stepUnit]()+step);
 	},
 	/**
-	 * Private Method: buildChildControls
+	 * Private Method: buildTimeHandlers
 	 * Creates the controls "managed" by this control.
 	 * 
 	 * Parameters:
 	 * layers - {Array(<OpenLayers.Layer>)}
-	 * options - {Object} Options to pass to the control constructors
 	 * 
 	 * Returns:
 	 * {Array(<OpenLayers.Control.TimeControl>)}
 	 */
-	buildChildControls:function(layers,options){
+	buildTimeHandlers:function(layers){
 		layers = layers || this.layers;
-		var layerTypes = {}, childControls = [];
+		var layerTypes = {}, handlers = [];
 		//categorize layers and separate into arrays for use in subclasses
 		for(var i=0,len=layers.length;i<len;i++){
 			var lyr = layers[i];
-			var lyrClass = lyr.CLASS_NAME.match(/\.Layer\.(\w+)/)[1];
-			if(OpenLayers.Control.TimeManager[lyrClass]){
-				!layerTypes[lyrClass] && (layerTypes[lyrClass]=[])
-				layerTypes[lyrClass].push(lyr);
-			}
+			//allow user specified overrides and custom behavior
+            if (lyr.timeHandler) {
+                var handler;
+                if(lyr.timeHandler instanceof OpenLayers.TimeHandler){
+                    handler = lyr.timeHandler;
+                    handler.layers = (handler.layers && handler.layers instanceof Array)?(handler.layers.push(lyr)):handler.layers=[lyr];
+                    handler.timeManager=this;
+                }else if(lyr.timeHandler instanceof Function){
+                    handler = new OpenLayers.TimeHandler({
+                        onTick:lyr.timeHandler,
+                        layers:[lyr],
+                        timeManager:this
+                    })
+                }
+                this.events.on({
+                    tick: handler.onTick,
+                    scope: this
+                })
+                handlers.push(handler);
+            }
+            else {
+                var lyrClass = lyr.CLASS_NAME.match(/\.Layer\.(\w+)/)[1];
+                if (OpenLayers.TimeHandler[lyrClass]) {
+                    !layerTypes[lyrClass] && (layerTypes[lyrClass] = [])
+                    layerTypes[lyrClass].push(lyr);
+                }
+            }
 		}
-		//create subclassed child controls
+		//create subclassed time handlers
 		for(var k in layerTypes){
-			var ctlClass = OpenLayers.Control.TimeManager[k];
-			var ctlOptions = OpenLayers.Util.applyDefaults({
-				layers:layerTypes[k],
-				parentControl:this
-			},options);
-			var ctl = new ctlClass(ctlOptions);
+			var handler = new OpenLayers.TimeHandler[k]({
+                layers: layerTypes[k],
+                timeManager: this
+            });
 			this.events.on({
-				'tick': ctl.onTick,
-				scope: ctl
+				'tick': handler.onTick,
+				scope: handler
 			})
-			childControls.push(ctl)
+			handlers.push(handler)
 		}
-		return childControls;
+		return handlers;
 	},
 	/**
-	 * APIMethod: destroy
-	 * Destroys the control
+	 * Method: buildIntervals
+	 * Builds an array of distinct date/times that the time handlers are
+	 * configured with
+	 * Parameters:
+	 *    handlers - {Array(<OpenLayers.TimeHandler>)}
+	 *       (Optional) An array of time handlers to calculate the intervals from.
+	 *       Defaults to the control's timeHandlers property. 
+	 * Returns: {Array(Date)}
 	 */
-	destroy:function(){
-		for(var i=this.childControls.length-1;i>-1;i--){
-			this.childControls[i].destroy();
-		}
-		this.layers=null;
-		OpenLayers.Control.prototype.destroy.call(this);
-	},
-	
+    buildIntervals:function(handlers){
+        handlers = handlers || this.timeHandlers;
+        var intervals = [];
+        for(var i=0,len=handlers.length;i<len;i++){
+            var handler = handlers[i];
+            if(handler.intervals){
+                intervals = intervals.concat(handler.intervals);
+            }
+        }
+        intervals =(intervals.length)?this.getUniqueDates(intervals):null;
+        return intervals;
+    },
+	/**
+	 * Method: buildRange
+	 * Builds an 2 member array with the overall start & stop date/times that
+	 * the time handlers are configured with.
+	 * Parameters:
+	 *    handlers - {Array(<OpenLayers.TimeHandler>)}
+	 *       (Optional) An array of time handlers to calculate the intervals from.
+	 *       Defaults to the control's timeHandlers property. 
+	 * Returns: {Array(Date)}
+	 */
+    buildRange:function(handlers){
+        handlers = handlers || this.timeHandlers;
+        var range = [];
+        for(var i=0,len=handlers.length;i<len;i++){
+            var subrange = handlers[i].range;
+            if(!subrange[0] || subrange[0]<range[0]){range[0]=new Date(subrange[0].getTime())}
+            if(!subrange[1] || subrange[1]>range[1]){range[1]=new Date(subrange[1].getTime())}
+        }
+        return range;
+    },
+    getUniqueDates:function(dates){
+        //sort the times
+        dates.sort(function(a, b){
+            return b - a;
+        });
+        //filter for unique
+        dates = OpenLayers.Array.filter(dates, function(item, index, array){
+            for (var i = index + 1; i < array.length; i++) {
+                if (item.getTime() == array[i].getTime()) {
+                    return false
+                }
+            }
+            return true;
+        });
+        return dates
+    },    
 	CLASS_NAME:'OpenLayers.Control.TimeManager'
 });
 

Added: sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/TimeHandler.js
===================================================================
--- sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/TimeHandler.js	                        (rev 0)
+++ sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/TimeHandler.js	2011-09-07 17:45:46 UTC (rev 12339)
@@ -0,0 +1,133 @@
+/* Copyright (c) 2006-2011 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/Control/TimeManager.js
+ */
+
+/**
+ * Class: OpenLayers.TimeHandler.WMS
+ * Class to display and animate WMS layers across time.
+ * This class is created by {OpenLayers.Control.TimeManager} instances
+ *
+ * Inherits From:
+ *  - <OpenLayers.Class>
+ */
+OpenLayers.TimeHandler = OpenLayers.Class({
+	/**
+	 * Property: timeManager
+	 * {<OpenLayers.Control.TimeManager>}
+	 */
+	timeManager:null,
+    /**
+     * Property: canTick
+     * {Boolean}
+     */
+    canTick:true,
+	/**
+	 * Property: intervals
+	 * {Array(Date)}
+	 */
+    intervals:null,
+    /**
+     * Property: range
+     * {Array(Date)}
+     */
+    range:null,
+    /**
+     * Property: layers
+     * {Array(<OpenLayers.Layer>)}
+     */
+    layers:null,
+	/**
+     * Constructor: OpenLayers.Control.TimeManager
+     * Create a new time manager control for temporal layers.
+     *
+     * Parameters:
+     * options - {Object} Optional object whose properties will be set on the
+     *     control.
+     */
+	initialize:function(options){
+		this.events = new OpenLayers.Events(this, null);
+		OpenLayers.Util.extend(this,options||{});
+        if(this.eventListeners instanceof Object) {
+            this.events.on(this.eventListeners);
+        }
+        if (this.layers) {
+            var timeConfig = this.buildRangeAndIntervals(this.layers);
+            this.range = timeConfig.range;
+            this.intervals = timeConfig.intervals;
+        }
+	},
+	
+	onTick:function(){
+        //Implemented By Subclasses
+    },
+	addLayer: function(layer){
+        this.layers = (!this.layers)?[layer]:this.layers.concat(layer);
+        var timeInterval = layer.metadata.timeInterval;
+        if (timeInterval.length == 2) {
+            if (timeInterval[0] < this.range[0]) {this.range[0] = new Date(timeInterval[0].getDate())}
+            if (timeInterval[1] > this.range[1]) {this.range[1] = new Date(timeInterval[1].getDate())}
+        }
+        else {
+            var timeConfig = this.buildRangeAndIntervals(this.layers);
+            this.range = timeConfig.range;
+            this.intervals = timeConfig.intervals;
+        }
+    },
+    removeLayer:function(layer){
+        for(var i=0,len=this.layers.length;i<length;i++){
+            if(layer==this.layers[i]){
+                this.layers.splice(i,1);
+                break;
+            }
+        }
+        var timeInterval = layer.metadata.timeInterval;
+        /*if we only had a range and this layer wasn't one of the end points
+        then we don't need to do anything, otherwise we might as well rebuild
+        the range & intervals*/
+       if(this.intervals || timeInterval[0].getTime() == this.range[0].getTime() || timeInterval[1].getTime() == this.range[1].getTime()){
+           var timeConfig = this.buildRangeAndIntervals(this.layers);
+           this.range = timeConfig.range;
+           this.intervals = timeConfig.intervals;
+       }
+    },
+	buildRangeAndIntervals:function(layers){
+		var range = [], intervals=[];
+		for(var i=0,len=layers.length;i<len;i++){
+			var timeInterval = (layers[i].metadata)?layers[i].metadata.timeInterval:null;
+			if (timeInterval) {
+                for (var j = 0; j < timeInterval.length; j++) {
+                    if (!(timeInterval[j] instanceof Date)) {
+                        timeInterval[j] = OpenLayers.Date.parse(timeInterval[j])
+                    }
+                }
+                if (timeInterval.length == 2) {
+                    if (!range[0] || timeInterval[0] < range[0]) {range[0] = timeInterval[0];}
+                    if (!range[1] || timeInterval[1] > range[1]) {range[1] = timeInterval[1];}
+                }
+                else if (timeInterval.length > 2) {
+                    for (var j = 0; j < timeInterval.length; j++) {
+                        if (OpenLayers.Util.indexOf(intervals, timeInterval[j]) == -1) {
+                            intervals.push(timeInterval[j])
+                        }
+                    }
+                }
+            }
+		}
+		if(intervals.length){
+            intervals = this.timeManager.getUniqueDates(intervals);
+            if (!range[0] || intervals[0] < range[0]) {range[0] = intervals[0];}
+			if (!range[1] || intervals[1] > range[1]) {range[1] = intervals[1];}
+		}else{
+            intervals=null;
+        }
+		return {'range':range,'intervals':intervals}
+	},
+	
+	CLASS_NAME:'OpenLayers.TimeHandler'
+});
\ No newline at end of file



More information about the Commits mailing list