[OpenLayers-Commits] r12237 - in
sandbox/mpriour/temporal_map/openlayers/lib: .
OpenLayers/Control OpenLayers/Control/TimeManager OpenLayers/Layer
commits-20090109 at openlayers.org
commits-20090109 at openlayers.org
Fri Aug 12 00:00:59 EDT 2011
Author: mpriour
Date: 2011-08-11 21:00:58 -0700 (Thu, 11 Aug 2011)
New Revision: 12237
Added:
sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager.js
sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager/
sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager/WMS.js
Modified:
sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers.js
sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Layer/WMS.js
Log:
Initial commit of TimeManager controls.
OpenLayers.Control.TimeManager contains all the API functions needed to interact with a slider control.
OpenLayers/Control/TimeManager/WMS.js is just skeleton code.
Added: sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager/WMS.js
===================================================================
--- sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager/WMS.js (rev 0)
+++ sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager/WMS.js 2011-08-12 04:00:58 UTC (rev 12237)
@@ -0,0 +1,55 @@
+/* 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.Control.TimeManager.WMS
+ * Control to display and animate WMS layers across time.
+ * This control is created by {OpenLayers.Control.TimeManager} instances
+ *
+ * Inherits From:
+ * - <OpenLayers.Control.TimeManager>
+ */
+OpenLayers.Control.TimeManager.WMS = OpenLayers.Class(OpenLayers.Control.TimeManager, {
+ /**
+ * Property: useLastValidInterval
+ * {Boolean} If true and a wms layer has distinct valid time intervals,
+ * then continue to display it using the last valid time within the
+ * overall control time range
+ */
+ useLastValidInterval:true,
+
+ /**
+ * Property: parentControl
+ * {<OpenLayers.Control.TimeManager>}
+ */
+ parentControl:null,
+
+ /**
+ * Constructor: OpenLayers.Control.TimeManager.WMS
+ * Create a new time manager control for temporal WMS layers.
+ *
+ * Parameters:
+ * options - {Object} Optional object whose properties will be set on the
+ * control.
+ */
+ initialize:function(options){
+ options = options||{};
+ OpenLayers.Util.extend(this,options);
+ this.range = this.buildRange(this.layers);
+ },
+
+ onTick:function(evt){
+ this.currentTime = evt.currentTime;
+ if(this.currentTime<=this.range[1] && this.currentTime>=this.range[0]){
+ //TODO: Implement time tick for WMS layers
+ }
+ },
+ CLASS_NAME:'OpenLayers.Control.TimeManager.WMS'
+});
\ No newline at end of file
Added: sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager.js
===================================================================
--- sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager.js (rev 0)
+++ sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Control/TimeManager.js 2011-08-12 04:00:58 UTC (rev 12237)
@@ -0,0 +1,352 @@
+/* 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.js
+ */
+
+/**
+ * Class: OpenLayers.Control.TimeManager
+ * Control to display and animate map layers across time.
+ *
+ * Inherits From:
+ * - <OpenLayers.Control>
+ */
+OpenLayers.Control.TimeManager = OpenLayers.Class(OpenLayers.Control, {
+
+ /**
+ * Constant: EVENT_TYPES
+ *
+ * Supported event types:
+ * - *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
+ * map or layer display is modified.
+ * - *play* Triggered when the control begins a time-series animation.
+ * - *stop* Triggered when the control stops a time-series animation.
+ * Listeners receive an event object with a {Boolean} *rangeExceeded*
+ * property indicating the control stopped due to reaching the end of
+ * its configured time range (true) or due to the stop function call
+ * (false). This event will only fire on the stop function call during
+ * a loop-mode animation.
+ * - *reset* Triggered when the control resets a time-series animation.
+ * Listeners receive an event object with a {Boolean} *looped*
+ * property indicating the control reset due to running in looped mode
+ * (true) or the reset function call (false)
+ */
+ EVENT_TYPES: ["tick","play","stop","reset"],
+
+
+ /**
+ * Property: layers
+ * {Array(<OpenLayers.Layer.Vector>)}
+ */
+ layers: null,
+
+ /**
+ * Property: units
+ * {OpenLayers.TimeUnit}
+ */
+ units:null,
+
+ /**
+ * Property: step
+ * {Number} The number of time units each tick will advance the current
+ * animation time. Negative units with tick time in reverse.
+ * Default : 1.
+ */
+ step:1,
+
+ /**
+ * Property: range
+ * {Array(Date)} 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.
+ */
+ range:null,
+
+ /**
+ * Property: intervals
+ * {Array(Date)} Array of valid distinct UTC dates/times that the time-
+ * series animation can use. (Optional)
+ */
+ intervals:null,
+
+ /**
+ * Property: frameRate
+ * {Number} A positive floating point number of frames (or ticks) per
+ * second to use in time-series animations. Values less than 1 will
+ * make each tick last for more than 1 second. Example: 0.5 = 1 tick
+ * every 2 seconds. 3 = 3 ticks per second.
+ * Default : 1.
+ */
+ frameRate:1,
+
+ /**
+ * Property: loop
+ * {Boolean} true to continue running the animation until stop is called
+ * Default:false
+ */
+ loop:false,
+
+ /**
+ * Property: snapToIntervals
+ * {Boolean} If intervals are configured and this property is true then
+ * tick will advance to the next time/date in the intervals array
+ * regardless of the step value.
+ */
+ snapToIntervals:false,
+
+ /**
+ * Property: currentTime
+ * {Date} The current time of the time-series animation
+ */
+ currentTime:null,
+
+ /**
+ * Private Property: childControls
+ * {Array(<OpenLayers.Control.TimeManager>)} An array of the controls that
+ * this control "manages". Read-Only
+ */
+ childControls:null,
+
+ /**
+ * Private Property: utcOffset
+ * {Number} millisecond difference between local & UTC time. Read-Only
+ */
+ utcOffset:0,
+
+ /**
+ * Constructor: OpenLayers.Control.TimeManager
+ * Create a new time manager control.
+ *
+ * Parameters:
+ * options - {Object} Optional object whose properties will be set on the
+ * control.
+ */
+ initialize: function(options){
+ options = options||{};
+ OpenLayers.Control.prototype.initialize.call(this,options);
+ this.utcOffset = new Date().getTimezoneOffset() * -6e4;
+ 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);
+ }
+ this.range=[this.intervals[0],this.intervals[this.intervals.length-1]];
+ }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);
+ }
+ 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));
+ },
+ /**
+ * Method: tick
+ * Advance/reverse time one step forward/backward. Fires the 'tick' event
+ * if time can be incremented without exceeding the time range.
+ *
+ */
+ tick:function(){
+ if(this.intervals && this.snapToIntervals){
+ var newIndex = OpenLayers.Util.indexOf(this.intervals,this.currentTime)+(this.step>0)?1:-1;
+ if (newIndex < this.intervals.length && newIndex>-1) {
+ this.currentTime = this.intervals[newIndex];
+ }else{
+ //force the currentTime beyond the range
+ this.currentTime = (this.step>0)?new Date(this.range[1].getTime()+100):new Date(this.range[0].getTime()-100);
+ }
+ }
+ else{
+ this.incrementTime();
+ }
+ //test that we have reached the end of our range
+ if (this.currentTime > this.range[1] || this.currentTime<this.range[0]) {
+ //loop in looping mode
+ if (this.loop) {
+ this.timer && clearInterval(this.timer) && (this.timer=null);
+ this.currentTime = (this.step>0)?new Date(this.range[0].getTime()):new Date(this.range[1].getTime());
+ this.events.triggerEvent('reset',{'looped':true});
+ this.play();
+ }
+ //stop in normal mode
+ else {
+ this.timer && clearInterval(this.timer) && (this.timer=null);
+ this.triggerEvent('stop', {'rangeExceeded': true});
+ }
+ }
+ else {
+ this.events.triggerEvent('tick', {currentTime: this.currentTime});
+ }
+ },
+ /**
+ * Method: play
+ * Begins/resumes the time-series animation. Fires the 'play' event,
+ * then calls 'tick' at the interval set by the frameRate property
+ */
+ play:function(){
+ //ensure that we don't have multiple timers running
+ this.timer && clearInterval(this.timer) && (this.timer=null);
+ //start playing
+ this.events.triggerEvent('play');
+ this.tick();
+ this.timer = setInterval(this.tick,1000/this.frameRate);
+ },
+ /**
+ * Method: stop
+ * Stops the time-series animation. Fires the 'stop' event.
+ */
+ stop:function(){
+ this.timer && clearInterval(this.timer) && (this.timer=null);
+ this.triggerEvent('stop',{'rangeExceeded':false});
+ },
+ /**
+ * Method: setRange
+ * Sets the time range used by this control. Will modify the start time or
+ * current time only if the animation is not currently running
+ *
+ * Parameters:
+ * range - {Arrray} UTC time range
+ */
+ 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);
+ 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]}
+ },
+ /**
+ * Method:setStart
+ * Sets the start time for an animation. If the step is negative then this
+ * sets the maximum time in the control's range parameter. Will only effect
+ * the currentTime if an animation has not begun.
+ *
+ * Parameters:
+ * time - {Object} UTC start time/date
+ */
+ setStart:function(time){
+ if(!(time instanceof Date))time=new Date(Date.parse(time)+utcOffset);
+ 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);
+ },
+ /**
+ * Method:setEnd
+ * Sets the end time for an animation. If the step is negative then this
+ * sets the minimum time in the control's range parameter. Will not effect
+ * the current time.
+ *
+ * Parameters:
+ * time - {Object} UTC stop time/date
+ */
+ setEnd:function(time){
+ if(!(time instanceof Date))time=new Date(Date.parse(time)+utcOffset);
+ this.range[(this.step>0)?1:0]=time;
+ },
+ /**
+ * Method:setTime
+ * Manually sets the currentTime used in the control's animation.
+ *
+ * Parameters: {Object} time
+ * time - {Object} UTC current animation time/date
+ */
+ setTime:function(time){
+ if(!(time instanceof Date))time=new Date(Date.parse(time)+utcOffset);
+ this.currentTime = time;
+ },
+ /**
+ * Method:reset
+ * Resets the time to the animation start time. Fires the 'reset' event.
+ *
+ * Returns:
+ * {Date} the control's currentTime, which is also the control's start time
+ */
+ 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});
+ return this.currentTime;
+ },
+ /**
+ * Method: incrementTime
+ * Moves the current animation time forward by the specified step & stepUnit
+ *
+ * Parameters:
+ * step - {Number}
+ * stepUnit - {<OpenLayers.TimeUnit>}
+ */
+ incrementTime:function(step,stepUnit){
+ step = step || this.step;
+ stepUnit = stepUnit || this.unit;
+ this.currentTime['setUTC'+stepUnit](this.currentTime['getUTC'+stepUnit]()+step);
+ },
+ /**
+ * Private Method: buildChildControls
+ * 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){
+ layers = layers || this.layers;
+ var layerTypes = {}, childControls = [];
+ //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);
+ }
+ }
+ //create subclassed child controls
+ 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);
+ ctl.events.on({
+ 'tick': ctl.onTick,
+ scope: ctl
+ })
+ childControls.push(new OpenLayers)
+ }
+ return childControls;
+ },
+ /**
+ * APIMethod: destroy
+ * Destroys the control
+ */
+ 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);
+ },
+
+ CLASS_NAME:'OpenLayers.Control.TimeManager'
+});
+
+OpenLayers.TimeUnit = {
+ SECONDS:'Seconds',
+ MINUTES:'Minutes',
+ HOURS:'Hours',
+ DAYS:'Date',
+ MONTHS:'Month',
+ YEARS:'FullYear'
+}
\ No newline at end of file
Modified: sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Layer/WMS.js
===================================================================
--- sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Layer/WMS.js 2011-08-11 13:21:04 UTC (rev 12236)
+++ sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers/Layer/WMS.js 2011-08-12 04:00:58 UTC (rev 12237)
@@ -71,8 +71,37 @@
* true as value. This is only relevant for WMS versions >= 1.3.0.
*/
yx: {'EPSG:4326': true},
-
/**
+ * Property: timeInterval
+ * {Array(Date)} An array containing at least 2 date values or parseable
+ * strings.
+ * An array with 2 values will be assumed to be the time range
+ * An array with 3 or more values is the distinct times for which the
+ * layer has data.
+ * (code)
+ * ex: GetCapabilities response snippet
+ * <Dimension name="time" units="ISO8601"/>
+ * <Extent name="time" default="2006-06-23T03:10:00Z" nearestValue="0">1995-01-01/2011-12-31/PT5M</Extent>
+ *
+ * translates to:
+ * timeInterval:['1995-01-01','2011-12-31'],
+ * timeStep:5,
+ * timeUnit:OpenLayers.TimeUnit.MINUTES
+ * (end)
+ */
+ timeInterval:null,
+ /**
+ * Property: timeStep
+ * {Number} A floating point number for the grainularity of the time data
+ */
+ timeStep:null,
+ /**
+ * Property: timeUnit
+ * {<OpenLayers.TimeUnit>} One of the time unit constants describing the
+ * grainularity of the time data
+ */
+ timeUnit:null,
+ /**
* Constructor: OpenLayers.Layer.WMS
* Create a new WMS layer object
*
Modified: sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers.js
===================================================================
--- sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers.js 2011-08-11 13:21:04 UTC (rev 12236)
+++ sandbox/mpriour/temporal_map/openlayers/lib/OpenLayers.js 2011-08-12 04:00:58 UTC (rev 12237)
@@ -213,6 +213,8 @@
"OpenLayers/Control/Graticule.js",
"OpenLayers/Control/TransformFeature.js",
"OpenLayers/Control/SLDSelect.js",
+ "OpenLayers/Control/TimeManager.js",
+ "OpenLayers/Control/TimeManager/WMS.js",
"OpenLayers/Geometry.js",
"OpenLayers/Geometry/Rectangle.js",
"OpenLayers/Geometry/Collection.js",
More information about the Commits
mailing list