From 029638080792cc212062b4d7059e95cddf469781 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 28 Jan 2013 14:44:41 +0100 Subject: [PATCH 01/36] Rename MapBrowserEventHandler internal handlers name --- src/ol/mapbrowserevent.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ol/mapbrowserevent.js b/src/ol/mapbrowserevent.js index 079f43b47b..e7e87189ec 100644 --- a/src/ol/mapbrowserevent.js +++ b/src/ol/mapbrowserevent.js @@ -153,7 +153,7 @@ ol.MapBrowserEventHandler = function(map) { ol.BrowserFeature.HAS_TOUCH ? goog.events.EventType.TOUCHSTART : goog.events.EventType.MOUSEDOWN, - this.handleDown_, false, this); + this.handleMouseDown_, false, this); }; goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget); @@ -201,7 +201,7 @@ ol.MapBrowserEventHandler.prototype.click_ = function(browserEvent) { * @param {goog.events.BrowserEvent} browserEvent Browser event. * @private */ -ol.MapBrowserEventHandler.prototype.handleUp_ = function(browserEvent) { +ol.MapBrowserEventHandler.prototype.handleMouseUp_ = function(browserEvent) { if (this.previous_) { if (!this.dragged_) { var now = new Date().getTime(); @@ -231,7 +231,7 @@ ol.MapBrowserEventHandler.prototype.handleUp_ = function(browserEvent) { * @param {goog.events.BrowserEvent} browserEvent Browser event. * @private */ -ol.MapBrowserEventHandler.prototype.handleDown_ = function(browserEvent) { +ol.MapBrowserEventHandler.prototype.handleMouseDown_ = function(browserEvent) { var newEvent = new ol.MapBrowserEvent( ol.MapBrowserEvent.EventType.DOWN, this.map_, browserEvent); this.dispatchEvent(newEvent); @@ -248,12 +248,12 @@ ol.MapBrowserEventHandler.prototype.handleDown_ = function(browserEvent) { ol.BrowserFeature.HAS_TOUCH ? goog.events.EventType.TOUCHMOVE : goog.events.EventType.MOUSEMOVE, - this.drag_, false, this), + this.handleMouseMove_, false, this), goog.events.listen(document, ol.BrowserFeature.HAS_TOUCH ? goog.events.EventType.TOUCHEND : goog.events.EventType.MOUSEUP, - this.handleUp_, false, this) + this.handleMouseUp_, false, this) ]; if (browserEvent.type === goog.events.EventType.MOUSEDOWN) { // prevent browser image dragging on pointer devices @@ -267,7 +267,7 @@ ol.MapBrowserEventHandler.prototype.handleDown_ = function(browserEvent) { * @param {goog.events.BrowserEvent} browserEvent Browser event. * @private */ -ol.MapBrowserEventHandler.prototype.drag_ = function(browserEvent) { +ol.MapBrowserEventHandler.prototype.handleMouseMove_ = function(browserEvent) { var newEvent; if (!this.dragged_) { this.dragged_ = true; From dc40ac6831b47397b51b7a60871f32d34d4c6bde Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 28 Jan 2013 15:02:28 +0100 Subject: [PATCH 02/36] Remove touch events handling in handleMouse* handlers --- src/ol/mapbrowserevent.js | 46 ++++++--------------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/src/ol/mapbrowserevent.js b/src/ol/mapbrowserevent.js index e7e87189ec..84f2723c94 100644 --- a/src/ol/mapbrowserevent.js +++ b/src/ol/mapbrowserevent.js @@ -148,34 +148,14 @@ ol.MapBrowserEventHandler = function(map) { this.clickListenerKey_ = goog.events.listen(element, [goog.events.EventType.CLICK, goog.events.EventType.DBLCLICK], this.click_, false, this); + this.downListenerKey_ = goog.events.listen(element, + goog.events.EventType.MOUSEDOWN, + this.handleMouseDown_, false, this); } - this.downListenerKey_ = goog.events.listen(element, - ol.BrowserFeature.HAS_TOUCH ? - goog.events.EventType.TOUCHSTART : - goog.events.EventType.MOUSEDOWN, - this.handleMouseDown_, false, this); }; goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget); -/** - * @param {goog.events.BrowserEvent} browserEvent Browser event. - * @private - */ -ol.MapBrowserEventHandler.prototype.touchEnableBrowserEvent_ = - function(browserEvent) { - if (ol.BrowserFeature.HAS_TOUCH) { - goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent); - var nativeEvent = browserEvent.getBrowserEvent(); - if (nativeEvent.touches && nativeEvent.touches.length) { - var nativeTouch = nativeEvent.touches[0]; - browserEvent.clientX = nativeTouch.clientX; - browserEvent.clientY = nativeTouch.clientY; - } - } -}; - - /** * @param {goog.events.BrowserEvent} browserEvent Browser event. * @private @@ -236,7 +216,6 @@ ol.MapBrowserEventHandler.prototype.handleMouseDown_ = function(browserEvent) { ol.MapBrowserEvent.EventType.DOWN, this.map_, browserEvent); this.dispatchEvent(newEvent); if (!this.previous_) { - this.touchEnableBrowserEvent_(browserEvent); this.down_ = browserEvent; this.previous_ = { clientX: browserEvent.clientX, @@ -244,21 +223,13 @@ ol.MapBrowserEventHandler.prototype.handleMouseDown_ = function(browserEvent) { }; this.dragged_ = false; this.dragListenerKeys_ = [ - goog.events.listen(document, - ol.BrowserFeature.HAS_TOUCH ? - goog.events.EventType.TOUCHMOVE : - goog.events.EventType.MOUSEMOVE, + goog.events.listen(document, goog.events.EventType.MOUSEMOVE, this.handleMouseMove_, false, this), - goog.events.listen(document, - ol.BrowserFeature.HAS_TOUCH ? - goog.events.EventType.TOUCHEND : - goog.events.EventType.MOUSEUP, + goog.events.listen(document, goog.events.EventType.MOUSEUP, this.handleMouseUp_, false, this) ]; - if (browserEvent.type === goog.events.EventType.MOUSEDOWN) { - // prevent browser image dragging on pointer devices - browserEvent.preventDefault(); - } + // prevent browser image dragging with the dom renderer + browserEvent.preventDefault(); } }; @@ -275,13 +246,10 @@ ol.MapBrowserEventHandler.prototype.handleMouseMove_ = function(browserEvent) { ol.MapBrowserEvent.EventType.DRAGSTART, this.map_, this.down_); this.dispatchEvent(newEvent); } - this.touchEnableBrowserEvent_(browserEvent); this.previous_ = { clientX: browserEvent.clientX, clientY: browserEvent.clientY }; - // prevent viewport dragging on touch devices - browserEvent.preventDefault(); newEvent = new ol.MapBrowserEvent( ol.MapBrowserEvent.EventType.DRAG, this.map_, browserEvent); this.dispatchEvent(newEvent); From 0d42e0878538e2d5fe78d3f1dc9424bc6f19a02d Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 28 Jan 2013 15:37:48 +0100 Subject: [PATCH 03/36] Add listeners for touchstart, touchmove and touchend events --- src/ol/mapbrowserevent.js | 62 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/src/ol/mapbrowserevent.js b/src/ol/mapbrowserevent.js index 84f2723c94..b642b990f8 100644 --- a/src/ol/mapbrowserevent.js +++ b/src/ol/mapbrowserevent.js @@ -137,6 +137,12 @@ ol.MapBrowserEventHandler = function(map) { */ this.dragListenerKeys_ = null; + /** + * @type {Array.} + * @private + */ + this.touchListenerKeys_ = null; + /** * @type {goog.events.BrowserEvent} * @private @@ -151,6 +157,18 @@ ol.MapBrowserEventHandler = function(map) { this.downListenerKey_ = goog.events.listen(element, goog.events.EventType.MOUSEDOWN, this.handleMouseDown_, false, this); + } else { + this.touchListenerKeys_ = [ + goog.events.listen(element, + goog.events.EventType.TOUCHSTART, + this.handleTouchStart_, false, this), + goog.events.listen(element, + goog.events.EventType.TOUCHMOVE, + this.handleTouchMove_, false, this), + goog.events.listen(element, + goog.events.EventType.TOUCHEND, + this.handleTouchEnd_, false, this) + ]; } }; goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget); @@ -256,6 +274,41 @@ ol.MapBrowserEventHandler.prototype.handleMouseMove_ = function(browserEvent) { }; +/** + * @param {goog.events.BrowserEvent} browserEvent Browser event. + * @private + */ +ol.MapBrowserEventHandler.prototype.handleTouchStart_ = function(browserEvent) { + // prevent context menu + browserEvent.preventDefault(); + var newEvent = new ol.MapBrowserEvent( + ol.MapBrowserEvent.EventType.TOUCHSTART, this.map_, browserEvent); + this.dispatchEvent(newEvent); +}; + + +/** + * @param {goog.events.BrowserEvent} browserEvent Browser event. + * @private + */ +ol.MapBrowserEventHandler.prototype.handleTouchMove_ = function(browserEvent) { + var newEvent = new ol.MapBrowserEvent( + ol.MapBrowserEvent.EventType.TOUCHMOVE, this.map_, browserEvent); + this.dispatchEvent(newEvent); +}; + + +/** + * @param {goog.events.BrowserEvent} browserEvent Browser event. + * @private + */ +ol.MapBrowserEventHandler.prototype.handleTouchEnd_ = function(browserEvent) { + var newEvent = new ol.MapBrowserEvent( + ol.MapBrowserEvent.EventType.TOUCHEND, this.map_, browserEvent); + this.dispatchEvent(newEvent); +}; + + /** * FIXME empty description for jsdoc */ @@ -266,6 +319,10 @@ ol.MapBrowserEventHandler.prototype.disposeInternal = function() { goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey); this.dragListenerKeys_ = null; } + if (!goog.isNull(this.touchListenerKeys_)) { + goog.array.forEach(this.touchListenerKeys_, goog.events.unlistenByKey); + this.touchListenerKeys_ = null; + } goog.base(this, 'disposeInternal'); }; @@ -277,8 +334,11 @@ ol.MapBrowserEventHandler.prototype.disposeInternal = function() { ol.MapBrowserEvent.EventType = { CLICK: goog.events.EventType.CLICK, DBLCLICK: goog.events.EventType.DBLCLICK, + DOWN: 'down', DRAGSTART: 'dragstart', DRAG: 'drag', DRAGEND: 'dragend', - DOWN: 'down' + TOUCHSTART: goog.events.EventType.TOUCHSTART, + TOUCHMOVE: goog.events.EventType.TOUCHMOVE, + TOUCHEND: goog.events.EventType.TOUCHEND }; From 942255e177824b62bd56b9251d224a8d3441c1dd Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 28 Jan 2013 15:55:33 +0100 Subject: [PATCH 04/36] Listen to IE pointer events --- src/ol/mapbrowserevent.js | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/ol/mapbrowserevent.js b/src/ol/mapbrowserevent.js index b642b990f8..43905bd757 100644 --- a/src/ol/mapbrowserevent.js +++ b/src/ol/mapbrowserevent.js @@ -49,6 +49,20 @@ ol.MapBrowserEvent = function(type, map, browserEvent, opt_frameState) { goog.inherits(ol.MapBrowserEvent, ol.MapEvent); +/** + * IE specific events. + * See http://msdn.microsoft.com/en-us/library/ie/hh673557(v=vs.85).aspx + * FIXME: replace with goog.events.EventType enum once we use + * goog/events/eventtype.js above r2211 + * @enum {string} + */ +ol.MapBrowserEvent.IEEventType = { + MSPOINTERDOWN: 'MSPointerDown', + MSPOINTERMOVE: 'MSPointerMove', + MSPOINTERUP: 'MSPointerUp' +}; + + /** * @return {ol.Coordinate} Coordinate. */ @@ -159,15 +173,18 @@ ol.MapBrowserEventHandler = function(map) { this.handleMouseDown_, false, this); } else { this.touchListenerKeys_ = [ - goog.events.listen(element, - goog.events.EventType.TOUCHSTART, - this.handleTouchStart_, false, this), - goog.events.listen(element, - goog.events.EventType.TOUCHMOVE, - this.handleTouchMove_, false, this), - goog.events.listen(element, - goog.events.EventType.TOUCHEND, - this.handleTouchEnd_, false, this) + goog.events.listen(element, [ + goog.events.EventType.TOUCHSTART, + ol.MapBrowserEvent.IEEventType.MSPOINTERDOWN + ], this.handleTouchStart_, false, this), + goog.events.listen(element, [ + goog.events.EventType.TOUCHMOVE, + ol.MapBrowserEvent.IEEventType.MSPOINTERMOVE + ], this.handleTouchMove_, false, this), + goog.events.listen(element, [ + goog.events.EventType.TOUCHEND, + ol.MapBrowserEvent.IEEventType.MSPOINTERUP + ], this.handleTouchEnd_, false, this) ]; } }; From a066b323f21cdbbca12ef95c21ef86ea026aaaa2 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Tue, 29 Jan 2013 14:45:15 +0100 Subject: [PATCH 05/36] Move dblclick handling into touch handlers --- src/ol/mapbrowserevent.js | 40 ++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/ol/mapbrowserevent.js b/src/ol/mapbrowserevent.js index 43905bd757..ec19a715dc 100644 --- a/src/ol/mapbrowserevent.js +++ b/src/ol/mapbrowserevent.js @@ -128,10 +128,10 @@ ol.MapBrowserEventHandler = function(map) { /** * Timestamp for the first click of a double click. Will be set back to 0 * as soon as a double click is detected. - * @type {number} + * @type {?number} * @private */ - this.timestamp_ = 0; + this.timestamp_ = null; /** * @type {?number} @@ -198,15 +198,15 @@ goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget); ol.MapBrowserEventHandler.prototype.click_ = function(browserEvent) { if (!this.dragged_) { var newEvent; - if (browserEvent.type !== goog.events.EventType.DBLCLICK) { - newEvent = new ol.MapBrowserEvent( - ol.MapBrowserEvent.EventType.CLICK, this.map_, browserEvent); - this.dispatchEvent(newEvent); - } - if (!this.timestamp_) { + var type = browserEvent.type; + if (this.timestamp_ == 0 || type == goog.events.EventType.DBLCLICK) { newEvent = new ol.MapBrowserEvent( ol.MapBrowserEvent.EventType.DBLCLICK, this.map_, browserEvent); this.dispatchEvent(newEvent); + } else if (type == goog.events.EventType.CLICK) { + newEvent = new ol.MapBrowserEvent( + ol.MapBrowserEvent.EventType.CLICK, this.map_, browserEvent); + this.dispatchEvent(newEvent); } } }; @@ -218,17 +218,6 @@ ol.MapBrowserEventHandler.prototype.click_ = function(browserEvent) { */ ol.MapBrowserEventHandler.prototype.handleMouseUp_ = function(browserEvent) { if (this.previous_) { - if (!this.dragged_) { - var now = new Date().getTime(); - if (!this.timestamp_ || now - this.timestamp_ > 250) { - this.timestamp_ = now; - } else { - this.timestamp_ = 0; - } - if (ol.BrowserFeature.HAS_TOUCH) { - this.click_(this.down_); - } - } this.down_ = null; goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey); this.dragListenerKeys_ = null; @@ -298,6 +287,8 @@ ol.MapBrowserEventHandler.prototype.handleMouseMove_ = function(browserEvent) { ol.MapBrowserEventHandler.prototype.handleTouchStart_ = function(browserEvent) { // prevent context menu browserEvent.preventDefault(); + this.down_ = browserEvent; + this.dragged_ = false; var newEvent = new ol.MapBrowserEvent( ol.MapBrowserEvent.EventType.TOUCHSTART, this.map_, browserEvent); this.dispatchEvent(newEvent); @@ -309,6 +300,7 @@ ol.MapBrowserEventHandler.prototype.handleTouchStart_ = function(browserEvent) { * @private */ ol.MapBrowserEventHandler.prototype.handleTouchMove_ = function(browserEvent) { + this.dragged_ = true; var newEvent = new ol.MapBrowserEvent( ol.MapBrowserEvent.EventType.TOUCHMOVE, this.map_, browserEvent); this.dispatchEvent(newEvent); @@ -323,6 +315,16 @@ ol.MapBrowserEventHandler.prototype.handleTouchEnd_ = function(browserEvent) { var newEvent = new ol.MapBrowserEvent( ol.MapBrowserEvent.EventType.TOUCHEND, this.map_, browserEvent); this.dispatchEvent(newEvent); + if (!this.dragged_) { + var now = goog.now(); + if (!this.timestamp_ || now - this.timestamp_ > 250) { + this.timestamp_ = now; + } else { + this.timestamp_ = 0; + } + this.click_(this.down_); + } + this.down_ = null; }; From ccd568ca3bd305e2870d246806dd12330393ef33 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 4 Feb 2013 15:16:34 +0100 Subject: [PATCH 06/36] Remove unused goog.require --- src/ol/mapbrowserevent.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ol/mapbrowserevent.js b/src/ol/mapbrowserevent.js index ec19a715dc..86380d0b50 100644 --- a/src/ol/mapbrowserevent.js +++ b/src/ol/mapbrowserevent.js @@ -3,7 +3,6 @@ goog.provide('ol.MapBrowserEvent.EventType'); goog.provide('ol.MapBrowserEventHandler'); goog.require('goog.array'); -goog.require('goog.asserts'); goog.require('goog.events.BrowserEvent'); goog.require('goog.events.EventTarget'); goog.require('goog.events.EventType'); From d9a1c18300b5b95265fb2d4e222810e459cd145a Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 18 Feb 2013 11:29:03 +0100 Subject: [PATCH 07/36] Add ol.interaction.TouchPan --- src/objectliterals.exports | 1 + src/ol/interaction/touchinteraction.js | 119 ++++++++++++++++++++++ src/ol/interaction/touchpaninteraction.js | 109 ++++++++++++++++++++ src/ol/map.js | 7 ++ test/spec/ol/map.test.js | 3 +- 5 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 src/ol/interaction/touchinteraction.js create mode 100644 src/ol/interaction/touchpaninteraction.js diff --git a/src/objectliterals.exports b/src/objectliterals.exports index 0e24207a11..3c8adf12f3 100644 --- a/src/objectliterals.exports +++ b/src/objectliterals.exports @@ -12,6 +12,7 @@ @exportObjectLiteralProperty ol.MapOptions.renderers Array.|undefined @exportObjectLiteralProperty ol.MapOptions.shiftDragZoom boolean|undefined @exportObjectLiteralProperty ol.MapOptions.target Element|string +@exportObjectLiteralProperty ol.MapOptions.touchPan boolean|undefined @exportObjectLiteralProperty ol.MapOptions.view ol.IView|undefined @exportObjectLiteralProperty ol.MapOptions.zoomControl boolean|undefined @exportObjectLiteralProperty ol.MapOptions.zoomDelta number|undefined diff --git a/src/ol/interaction/touchinteraction.js b/src/ol/interaction/touchinteraction.js new file mode 100644 index 0000000000..c71d5997de --- /dev/null +++ b/src/ol/interaction/touchinteraction.js @@ -0,0 +1,119 @@ + +goog.provide('ol.interaction.Touch'); + +goog.require('goog.functions'); +goog.require('ol.MapBrowserEvent'); +goog.require('ol.MapBrowserEvent.EventType'); +goog.require('ol.Pixel'); +goog.require('ol.interaction.Interaction'); + + + +/** + * @constructor + * @extends {ol.interaction.Interaction} + */ +ol.interaction.Touch = function() { + + goog.base(this); + + /** + * @type {boolean} + * @private + */ + this.handled_ = false; + + /** + * @type {Object} + * @private + */ + this.trackedTouches_ = {}; + + /** + * @type {Array.} + */ + this.targetTouches = []; + +}; +goog.inherits(ol.interaction.Touch, ol.interaction.Interaction); + + +/** + * @param {Array.} touches TouchEvents. + * @return {ol.Pixel} Centroid pixel. + */ +ol.interaction.Touch.centroid = function(touches) { + var length = touches.length; + var clientX = 0; + var clientY = 0; + for (var i = 0; i < length; i++) { + clientX += touches[i].clientX; + clientY += touches[i].clientY; + } + return new ol.Pixel(clientX / length, clientY / length); +}; + + +/** + * @param {ol.MapBrowserEvent} mapBrowserEvent Event. + * @private + */ +ol.interaction.Touch.prototype.updateTrackedTouches_ = + function(mapBrowserEvent) { + var event = mapBrowserEvent.browserEvent.getBrowserEvent(); + if (goog.isDef(event.targetTouches)) { + // W3C touch events + this.targetTouches = event.targetTouches; + } else { + // IE pointer event + if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.TOUCHEND) { + delete this.trackedTouches_[event.pointerId]; + } else { + this.trackedTouches_[event.pointerId] = event; + } + this.targetTouches = goog.object.getValues(this.trackedTouches_); + } +}; + + +/** + * @param {ol.MapBrowserEvent} mapBrowserEvent Event. + * @protected + */ +ol.interaction.Touch.prototype.handleTouchMove = goog.nullFunction; + + +/** + * @param {ol.MapBrowserEvent} mapBrowserEvent Event. + * @protected + * @return {boolean} Capture dragging. + */ +ol.interaction.Touch.prototype.handleTouchEnd = goog.functions.FALSE; + + +/** + * @param {ol.MapBrowserEvent} mapBrowserEvent Event. + * @protected + * @return {boolean} Capture dragging. + */ +ol.interaction.Touch.prototype.handleTouchStart = goog.functions.FALSE; + + +/** + * @inheritDoc + */ +ol.interaction.Touch.prototype.handleMapBrowserEvent = + function(mapBrowserEvent) { + var browserEvent = mapBrowserEvent.browserEvent.getBrowserEvent(); + this.updateTrackedTouches_(mapBrowserEvent); + if (this.handled_) { + if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.TOUCHMOVE) { + this.handleTouchMove(mapBrowserEvent); + } else if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.TOUCHEND) { + this.handled_ = this.handleTouchEnd(mapBrowserEvent); + } + } + if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.TOUCHSTART) { + this.handled_ = this.handleTouchStart(mapBrowserEvent); + } +}; diff --git a/src/ol/interaction/touchpaninteraction.js b/src/ol/interaction/touchpaninteraction.js new file mode 100644 index 0000000000..1a36caddd5 --- /dev/null +++ b/src/ol/interaction/touchpaninteraction.js @@ -0,0 +1,109 @@ +// FIXME works for View2D only +// FIXME opt_kinetic param +goog.provide('ol.interaction.TouchPan'); + +goog.require('goog.asserts'); +goog.require('ol.Coordinate'); +goog.require('ol.Kinetic'); +goog.require('ol.Pixel'); +goog.require('ol.View'); +goog.require('ol.ViewHint'); +goog.require('ol.interaction.Touch'); + + + +/** + * @constructor + * @extends {ol.interaction.Touch} + */ +ol.interaction.TouchPan = function() { + + goog.base(this); + + /** + * @private + * @type {ol.Kinetic} + */ + this.kinetic_ = new ol.Kinetic(-0.005, 0.05, 100); + + /** + * @type {ol.Pixel} + */ + this.lastCentroid = null; + +}; +goog.inherits(ol.interaction.TouchPan, ol.interaction.Touch); + + +/** + * @inheritDoc + */ +ol.interaction.TouchPan.prototype.handleTouchMove = function(mapBrowserEvent) { + goog.asserts.assert(this.targetTouches.length >= 1); + var centroid = ol.interaction.Touch.centroid(this.targetTouches); + if (!goog.isNull(this.lastCentroid)) { + this.kinetic_.update(centroid.x, centroid.y); + var map = mapBrowserEvent.map; + var view = map.getView(); + var resolution = view.getResolution(); + var rotation = view.getRotation(); + var center = view.getCenter(); + + var deltaX = this.lastCentroid.x - centroid.x; + var deltaY = centroid.y - this.lastCentroid.y; + var newCenter = new ol.Coordinate(deltaX, deltaY) + .scale(view.getResolution()) + .rotate(view.getRotation()); + // FIXME: nice to have center.add(...); + newCenter.x += center.x; + newCenter.y += center.y; + view.setCenter(newCenter); + } + this.lastCentroid = centroid; +}; + + +/** + * @inheritDoc + */ +ol.interaction.TouchPan.prototype.handleTouchEnd = + function(mapBrowserEvent) { + var map = mapBrowserEvent.map; + var view = map.getView(); + if (this.targetTouches.length == 0) { + view.setHint(ol.ViewHint.PANNING, -1); + if (this.kinetic_.end()) { + var distance = this.kinetic_.getDistance(); + var angle = this.kinetic_.getAngle(); + var center = view.getCenter(); + map.addPreRenderFunction(this.kinetic_.pan(center)); + var centerpx = map.getPixelFromCoordinate(center); + var destpx = new ol.Pixel( + centerpx.x - distance * Math.cos(angle), + centerpx.y - distance * Math.sin(angle)); + var dest = map.getCoordinateFromPixel(destpx); + view.setCenter(dest); + } + return false; + } else { + return true; + } +}; + + +/** + * @inheritDoc + */ +ol.interaction.TouchPan.prototype.handleTouchStart = + function(mapBrowserEvent) { + if (this.targetTouches.length >= 1) { + var map = mapBrowserEvent.map; + var view = map.getView(); + this.lastCentroid = null; + this.kinetic_.begin(); + view.setHint(ol.ViewHint.PANNING, 1); + return true; + } else { + return false; + } +}; diff --git a/src/ol/map.js b/src/ol/map.js index 2c4ceea383..3e3fdaef13 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -54,6 +54,7 @@ goog.require('ol.interaction.Interaction'); goog.require('ol.interaction.KeyboardPan'); goog.require('ol.interaction.KeyboardZoom'); goog.require('ol.interaction.MouseWheelZoom'); +goog.require('ol.interaction.TouchPan'); goog.require('ol.interaction.condition'); goog.require('ol.layer.Layer'); goog.require('ol.renderer.Map'); @@ -959,6 +960,12 @@ ol.Map.createInteractions_ = function(mapOptions) { interactions.push(new ol.interaction.DblClickZoom(zoomDelta)); } + var touchPan = goog.isDef(mapOptions.touchPan) ? + mapOptions.touchPan : true; + if (touchPan) { + interactions.push(new ol.interaction.TouchPan()); + } + var dragPan = goog.isDef(mapOptions.dragPan) ? mapOptions.dragPan : true; if (dragPan) { diff --git a/test/spec/ol/map.test.js b/test/spec/ol/map.test.js index e859e7e8e8..2e70b82ba4 100644 --- a/test/spec/ol/map.test.js +++ b/test/spec/ol/map.test.js @@ -77,7 +77,8 @@ describe('ol.Map', function() { dragPan: false, keyboard: false, mouseWheelZoom: false, - shiftDragZoom: false + shiftDragZoom: false, + touchPan: false }; }); From 735e53409583837451a5eb854dfc35c472d9f5dc Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 18 Feb 2013 11:49:36 +0100 Subject: [PATCH 08/36] Add ol.interaction.TouchRotateAndZoom --- src/objectliterals.exports | 1 + .../touchrotateandzoominteraction.js | 146 ++++++++++++++++++ src/ol/map.js | 7 + test/spec/ol/map.test.js | 3 +- 4 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 src/ol/interaction/touchrotateandzoominteraction.js diff --git a/src/objectliterals.exports b/src/objectliterals.exports index 3c8adf12f3..4af5ad024f 100644 --- a/src/objectliterals.exports +++ b/src/objectliterals.exports @@ -13,6 +13,7 @@ @exportObjectLiteralProperty ol.MapOptions.shiftDragZoom boolean|undefined @exportObjectLiteralProperty ol.MapOptions.target Element|string @exportObjectLiteralProperty ol.MapOptions.touchPan boolean|undefined +@exportObjectLiteralProperty ol.MapOptions.touchRotateZoom boolean|undefined @exportObjectLiteralProperty ol.MapOptions.view ol.IView|undefined @exportObjectLiteralProperty ol.MapOptions.zoomControl boolean|undefined @exportObjectLiteralProperty ol.MapOptions.zoomDelta number|undefined diff --git a/src/ol/interaction/touchrotateandzoominteraction.js b/src/ol/interaction/touchrotateandzoominteraction.js new file mode 100644 index 0000000000..002d2ef40b --- /dev/null +++ b/src/ol/interaction/touchrotateandzoominteraction.js @@ -0,0 +1,146 @@ +// FIXME works for View2D only + +goog.provide('ol.interaction.TouchRotateAndZoom'); + +goog.require('goog.asserts'); +goog.require('ol.View'); +goog.require('ol.ViewHint'); +goog.require('ol.interaction.Touch'); + + + +/** + * @constructor + * @extends {ol.interaction.Touch} + */ +ol.interaction.TouchRotateAndZoom = function() { + + goog.base(this); + + /** + * @private + * @type {number|undefined} + */ + this.lastAngle_; + + /** + * @private + * @type {number|undefined} + */ + this.lastDistance_; + + /** + * @private + * @type {boolean} + */ + this.rotating_ = false; + + /** + * @private + * @type {number} + */ + this.rotationDelta_ = 0.0; + + /** + * @private + * @type {number} + */ + this.rotationThreshold_ = 0.3; + +}; +goog.inherits(ol.interaction.TouchRotateAndZoom, ol.interaction.Touch); + + +/** + * @inheritDoc + */ +ol.interaction.TouchRotateAndZoom.prototype.handleTouchMove = + function(mapBrowserEvent) { + goog.asserts.assert(this.targetTouches.length >= 2); + var scaleDelta = 1.0; + var rotationDelta = 0.0; + + var centroid = ol.interaction.Touch.centroid(this.targetTouches); + + var touch0 = this.targetTouches[0]; + var touch1 = this.targetTouches[1]; + var dx = touch0.clientX - touch1.clientX; + var dy = touch0.clientY - touch1.clientY; + + // angle between touches + var angle = Math.atan2( + touch1.clientY - touch0.clientY, + touch1.clientX - touch0.clientX); + + // distance between touches + var distance = Math.sqrt(dx * dx + dy * dy); + + if (goog.isDef(this.lastDistance_)) { + scaleDelta = this.lastDistance_ / distance; + } + this.lastDistance_ = distance; + + if (goog.isDef(this.lastAngle_)) { + var delta = angle - this.lastAngle_; + this.rotationDelta_ += delta; + if (!this.rotating_ && + Math.abs(this.rotationDelta_) > this.rotationThreshold_) { + this.rotating_ = true; + } + rotationDelta = delta; + } + this.lastAngle_ = angle; + + var map = mapBrowserEvent.map; + var view = map.getView(); + + // rotate / scale anchor point. + // FIXME: should be the intersection point between the lines: + // touch0,touch1 and previousTouch0,previousTouch1 + var viewportPosition = goog.style.getClientPosition(map.getViewport()); + centroid.x -= viewportPosition.x; + centroid.y -= viewportPosition.y; + var anchor = map.getCoordinateFromPixel(centroid); + + // scale + view.zoom_(map, view.getResolution() * scaleDelta, anchor); + + // rotate + if (this.rotating_) { + view.rotate(map, view.getRotation() + rotationDelta, anchor); + } +}; + + +/** + * @inheritDoc + */ +ol.interaction.TouchRotateAndZoom.prototype.handleTouchEnd = + function(mapBrowserEvent) { + if (this.targetTouches.length < 2) { + var view = mapBrowserEvent.map.getView(); + view.setHint(ol.ViewHint.PANNING, -1); + return false; + } else { + return true; + } +}; + + +/** + * @inheritDoc + */ +ol.interaction.TouchRotateAndZoom.prototype.handleTouchStart = + function(mapBrowserEvent) { + if (this.targetTouches.length >= 2) { + var view = mapBrowserEvent.map.getView(); + this.lastDistance_ = undefined; + this.lastAngle_ = undefined; + this.rotating_ = false; + this.rotationDelta_ = 0.0; + view.setHint(ol.ViewHint.PANNING, 1); + return true; + } else { + return false; + } +}; diff --git a/src/ol/map.js b/src/ol/map.js index 3e3fdaef13..ad1fa4d8c0 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -55,6 +55,7 @@ goog.require('ol.interaction.KeyboardPan'); goog.require('ol.interaction.KeyboardZoom'); goog.require('ol.interaction.MouseWheelZoom'); goog.require('ol.interaction.TouchPan'); +goog.require('ol.interaction.TouchRotateAndZoom'); goog.require('ol.interaction.condition'); goog.require('ol.layer.Layer'); goog.require('ol.renderer.Map'); @@ -966,6 +967,12 @@ ol.Map.createInteractions_ = function(mapOptions) { interactions.push(new ol.interaction.TouchPan()); } + var touchRotateZoom = goog.isDef(mapOptions.touchRotateZoom) ? + mapOptions.touchRotateZoom : true; + if (touchRotateZoom) { + interactions.push(new ol.interaction.TouchRotateAndZoom()); + } + var dragPan = goog.isDef(mapOptions.dragPan) ? mapOptions.dragPan : true; if (dragPan) { diff --git a/test/spec/ol/map.test.js b/test/spec/ol/map.test.js index 2e70b82ba4..db5ed7f546 100644 --- a/test/spec/ol/map.test.js +++ b/test/spec/ol/map.test.js @@ -78,7 +78,8 @@ describe('ol.Map', function() { keyboard: false, mouseWheelZoom: false, shiftDragZoom: false, - touchPan: false + touchPan: false, + touchRotateZoom: false }; }); From 8c1d42a318f524052a06a7eef86445368f891084 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 18 Feb 2013 14:37:09 +0100 Subject: [PATCH 09/36] Listen to both mouse and touch events --- src/ol/mapbrowserevent.js | 45 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/ol/mapbrowserevent.js b/src/ol/mapbrowserevent.js index 86380d0b50..792585eff0 100644 --- a/src/ol/mapbrowserevent.js +++ b/src/ol/mapbrowserevent.js @@ -163,29 +163,28 @@ ol.MapBrowserEventHandler = function(map) { this.down_ = null; var element = this.map_.getViewport(); - if (!ol.BrowserFeature.HAS_TOUCH) { - this.clickListenerKey_ = goog.events.listen(element, - [goog.events.EventType.CLICK, goog.events.EventType.DBLCLICK], - this.click_, false, this); - this.downListenerKey_ = goog.events.listen(element, - goog.events.EventType.MOUSEDOWN, - this.handleMouseDown_, false, this); - } else { - this.touchListenerKeys_ = [ - goog.events.listen(element, [ - goog.events.EventType.TOUCHSTART, - ol.MapBrowserEvent.IEEventType.MSPOINTERDOWN - ], this.handleTouchStart_, false, this), - goog.events.listen(element, [ - goog.events.EventType.TOUCHMOVE, - ol.MapBrowserEvent.IEEventType.MSPOINTERMOVE - ], this.handleTouchMove_, false, this), - goog.events.listen(element, [ - goog.events.EventType.TOUCHEND, - ol.MapBrowserEvent.IEEventType.MSPOINTERUP - ], this.handleTouchEnd_, false, this) - ]; - } + this.clickListenerKey_ = goog.events.listen(element, + [goog.events.EventType.CLICK, goog.events.EventType.DBLCLICK], + this.click_, false, this); + this.downListenerKey_ = goog.events.listen(element, + goog.events.EventType.MOUSEDOWN, + this.handleMouseDown_, false, this); + // touch events + this.touchListenerKeys_ = [ + goog.events.listen(element, [ + goog.events.EventType.TOUCHSTART, + ol.MapBrowserEvent.IEEventType.MSPOINTERDOWN + ], this.handleTouchStart_, false, this), + goog.events.listen(element, [ + goog.events.EventType.TOUCHMOVE, + ol.MapBrowserEvent.IEEventType.MSPOINTERMOVE + ], this.handleTouchMove_, false, this), + goog.events.listen(element, [ + goog.events.EventType.TOUCHEND, + ol.MapBrowserEvent.IEEventType.MSPOINTERUP + ], this.handleTouchEnd_, false, this) + ]; + }; goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget); From 48ff4a95e0b86a82795bdf535ccda6d01c1da033 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 18 Feb 2013 16:39:34 +0100 Subject: [PATCH 10/36] Remove unused variable, coding style --- src/ol/interaction/touchpaninteraction.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/ol/interaction/touchpaninteraction.js b/src/ol/interaction/touchpaninteraction.js index 1a36caddd5..6bda066cb1 100644 --- a/src/ol/interaction/touchpaninteraction.js +++ b/src/ol/interaction/touchpaninteraction.js @@ -45,19 +45,14 @@ ol.interaction.TouchPan.prototype.handleTouchMove = function(mapBrowserEvent) { this.kinetic_.update(centroid.x, centroid.y); var map = mapBrowserEvent.map; var view = map.getView(); - var resolution = view.getResolution(); - var rotation = view.getRotation(); - var center = view.getCenter(); var deltaX = this.lastCentroid.x - centroid.x; var deltaY = centroid.y - this.lastCentroid.y; - var newCenter = new ol.Coordinate(deltaX, deltaY) + var center = new ol.Coordinate(deltaX, deltaY) .scale(view.getResolution()) - .rotate(view.getRotation()); - // FIXME: nice to have center.add(...); - newCenter.x += center.x; - newCenter.y += center.y; - view.setCenter(newCenter); + .rotate(view.getRotation()) + .add(view.getCenter()); + view.setCenter(center); } this.lastCentroid = centroid; }; From 3e4ae0d79d8bf3e8eaf389d0ae0b716b2d661a9c Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Tue, 19 Feb 2013 15:13:29 +0100 Subject: [PATCH 11/36] Stop ongoing kinetic animation --- src/ol/interaction/touchpaninteraction.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/ol/interaction/touchpaninteraction.js b/src/ol/interaction/touchpaninteraction.js index 6bda066cb1..0c21c78c4b 100644 --- a/src/ol/interaction/touchpaninteraction.js +++ b/src/ol/interaction/touchpaninteraction.js @@ -6,6 +6,7 @@ goog.require('goog.asserts'); goog.require('ol.Coordinate'); goog.require('ol.Kinetic'); goog.require('ol.Pixel'); +goog.require('ol.PreRenderFunction'); goog.require('ol.View'); goog.require('ol.ViewHint'); goog.require('ol.interaction.Touch'); @@ -26,6 +27,12 @@ ol.interaction.TouchPan = function() { */ this.kinetic_ = new ol.Kinetic(-0.005, 0.05, 100); + /** + * @private + * @type {?ol.PreRenderFunction} + */ + this.kineticPreRenderFn_ = null; + /** * @type {ol.Pixel} */ @@ -43,11 +50,9 @@ ol.interaction.TouchPan.prototype.handleTouchMove = function(mapBrowserEvent) { var centroid = ol.interaction.Touch.centroid(this.targetTouches); if (!goog.isNull(this.lastCentroid)) { this.kinetic_.update(centroid.x, centroid.y); - var map = mapBrowserEvent.map; - var view = map.getView(); - var deltaX = this.lastCentroid.x - centroid.x; var deltaY = centroid.y - this.lastCentroid.y; + var view = mapBrowserEvent.map.getView(); var center = new ol.Coordinate(deltaX, deltaY) .scale(view.getResolution()) .rotate(view.getRotation()) @@ -71,7 +76,8 @@ ol.interaction.TouchPan.prototype.handleTouchEnd = var distance = this.kinetic_.getDistance(); var angle = this.kinetic_.getAngle(); var center = view.getCenter(); - map.addPreRenderFunction(this.kinetic_.pan(center)); + this.kineticPreRenderFn_ = this.kinetic_.pan(center); + map.addPreRenderFunction(this.kineticPreRenderFn_); var centerpx = map.getPixelFromCoordinate(center); var destpx = new ol.Pixel( centerpx.x - distance * Math.cos(angle), @@ -95,6 +101,12 @@ ol.interaction.TouchPan.prototype.handleTouchStart = var map = mapBrowserEvent.map; var view = map.getView(); this.lastCentroid = null; + if (!goog.isNull(this.kineticPreRenderFn_) && + map.removePreRenderFunction(this.kineticPreRenderFn_)) { + map.requestRenderFrame(); + view.setCenter(mapBrowserEvent.frameState.view2DState.center); + this.kineticPreRenderFn_ = null; + } this.kinetic_.begin(); view.setHint(ol.ViewHint.PANNING, 1); return true; From 8d24311bc83adee9f0be098c9013135eb141f0b9 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 20 Feb 2013 09:37:11 +0100 Subject: [PATCH 12/36] Take the resolution constraint into account. But only at the end of the pinch zoom action. --- src/ol/interaction/touchrotateandzoominteraction.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ol/interaction/touchrotateandzoominteraction.js b/src/ol/interaction/touchrotateandzoominteraction.js index 002d2ef40b..d06d6ee93d 100644 --- a/src/ol/interaction/touchrotateandzoominteraction.js +++ b/src/ol/interaction/touchrotateandzoominteraction.js @@ -102,7 +102,7 @@ ol.interaction.TouchRotateAndZoom.prototype.handleTouchMove = centroid.y -= viewportPosition.y; var anchor = map.getCoordinateFromPixel(centroid); - // scale + // scale, bypass the resolution constraint view.zoom_(map, view.getResolution() * scaleDelta, anchor); // rotate @@ -118,7 +118,10 @@ ol.interaction.TouchRotateAndZoom.prototype.handleTouchMove = ol.interaction.TouchRotateAndZoom.prototype.handleTouchEnd = function(mapBrowserEvent) { if (this.targetTouches.length < 2) { - var view = mapBrowserEvent.map.getView(); + var map = mapBrowserEvent.map; + var view = map.getView(); + // take the resolution constraint into account + view.zoomToResolution(map, view.getResolution()); view.setHint(ol.ViewHint.PANNING, -1); return false; } else { From 68844007b88dfc2c8ff6a2cf531c2533f2cda4c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Wed, 20 Feb 2013 11:53:54 +0100 Subject: [PATCH 13/36] Add missing goog.require's --- src/{ => ol}/imageurlfunction.js | 1 + src/ol/source/singleimagewmssource.js | 1 + 2 files changed, 2 insertions(+) rename src/{ => ol}/imageurlfunction.js (96%) diff --git a/src/imageurlfunction.js b/src/ol/imageurlfunction.js similarity index 96% rename from src/imageurlfunction.js rename to src/ol/imageurlfunction.js index bb328819eb..ebaec5c427 100644 --- a/src/imageurlfunction.js +++ b/src/ol/imageurlfunction.js @@ -1,6 +1,7 @@ goog.provide('ol.ImageUrlFunction'); goog.provide('ol.ImageUrlFunctionType'); +goog.require('goog.uri.utils'); goog.require('ol.Extent'); goog.require('ol.Size'); diff --git a/src/ol/source/singleimagewmssource.js b/src/ol/source/singleimagewmssource.js index 3529678443..84e66db61f 100644 --- a/src/ol/source/singleimagewmssource.js +++ b/src/ol/source/singleimagewmssource.js @@ -1,5 +1,6 @@ goog.provide('ol.source.SingleImageWMS'); +goog.require('goog.uri.utils'); goog.require('ol.Extent'); goog.require('ol.Image'); goog.require('ol.ImageUrlFunction'); From cf6a27fca39c2c0720f0f6dc999ab8632d55f76f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Wed, 20 Feb 2013 11:54:35 +0100 Subject: [PATCH 14/36] Export ol.Extent.prototype.getHeight and getWidth --- src/ol/extent.exports | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ol/extent.exports b/src/ol/extent.exports index 23e1785d4f..b52ee8007a 100644 --- a/src/ol/extent.exports +++ b/src/ol/extent.exports @@ -1,2 +1,3 @@ @exportSymbol ol.Extent - +@exportProperty ol.Extent.prototype.getHeight +@exportProperty ol.Extent.prototype.getWidth From 2bc8e1a5709c9d179ab89a358e7723cb9143a817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Wed, 20 Feb 2013 11:55:28 +0100 Subject: [PATCH 15/36] Example uses exported properties --- examples/wms-custom-proj.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/wms-custom-proj.js b/examples/wms-custom-proj.js index fea7b563dd..20b2b90072 100644 --- a/examples/wms-custom-proj.js +++ b/examples/wms-custom-proj.js @@ -29,9 +29,8 @@ ol.Projection.addProjection(epsg21781); // We give the single image source a set of resolutions. This prevents the // source from requesting images of arbitrary resolutions. var projectionExtent = epsg21781.getExtent(); -var maxResolution = Math.max( - projectionExtent.maxX - projectionExtent.minX, - projectionExtent.maxY - projectionExtent.minY) / 256; +var maxResolution = Math.max(projectionExtent.getWidth(), + projectionExtent.getHeight()) / 256; var resolutions = new Array(10); for (var i = 0; i < 10; ++i) { resolutions[i] = maxResolution / Math.pow(2.0, i); From fabcb313f14e06034828512b1603151e1400f4e6 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 21 Feb 2013 15:11:09 +0100 Subject: [PATCH 16/36] Satisfy JSLint JSLint complains about functions being declared in blocks. --- src/ol/renderer/canvas/canvastilelayerrenderer.js | 4 ++-- src/ol/renderer/dom/domtilelayerrenderer.js | 4 ++-- src/ol/renderer/webgl/webgltilelayerrenderer.js | 4 ++-- src/ol/source/tiledwmssource.js | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ol/renderer/canvas/canvastilelayerrenderer.js b/src/ol/renderer/canvas/canvastilelayerrenderer.js index e7c48f044c..3e55fec20d 100644 --- a/src/ol/renderer/canvas/canvastilelayerrenderer.js +++ b/src/ol/renderer/canvas/canvastilelayerrenderer.js @@ -129,9 +129,9 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = var tilesToDrawByZ = {}; tilesToDrawByZ[z] = {}; - function isLoaded(tile) { + var isLoaded = function(tile) { return !goog.isNull(tile) && tile.getState() == ol.TileState.LOADED; - } + }; var findLoadedTiles = goog.bind(tileSource.findLoadedTiles, tileSource, tilesToDrawByZ, isLoaded); diff --git a/src/ol/renderer/dom/domtilelayerrenderer.js b/src/ol/renderer/dom/domtilelayerrenderer.js index faeb67d47d..b6157b40d4 100644 --- a/src/ol/renderer/dom/domtilelayerrenderer.js +++ b/src/ol/renderer/dom/domtilelayerrenderer.js @@ -93,9 +93,9 @@ ol.renderer.dom.TileLayer.prototype.renderFrame = var tilesToDrawByZ = {}; tilesToDrawByZ[z] = {}; - function isLoaded(tile) { + var isLoaded = function(tile) { return !goog.isNull(tile) && tile.getState() == ol.TileState.LOADED; - } + }; var findLoadedTiles = goog.bind(tileSource.findLoadedTiles, tileSource, tilesToDrawByZ, isLoaded); diff --git a/src/ol/renderer/webgl/webgltilelayerrenderer.js b/src/ol/renderer/webgl/webgltilelayerrenderer.js index 53405ca10a..83efd39c39 100644 --- a/src/ol/renderer/webgl/webgltilelayerrenderer.js +++ b/src/ol/renderer/webgl/webgltilelayerrenderer.js @@ -365,10 +365,10 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = var tilesToDrawByZ = {}; tilesToDrawByZ[z] = {}; - function isLoaded(tile) { + var isLoaded = function(tile) { return !goog.isNull(tile) && tile.getState() == ol.TileState.LOADED && mapRenderer.isTileTextureLoaded(tile); - } + }; var findLoadedTiles = goog.bind(tileSource.findLoadedTiles, tileSource, tilesToDrawByZ, isLoaded); diff --git a/src/ol/source/tiledwmssource.js b/src/ol/source/tiledwmssource.js index b09147cf2c..a1093f21e4 100644 --- a/src/ol/source/tiledwmssource.js +++ b/src/ol/source/tiledwmssource.js @@ -69,7 +69,7 @@ ol.source.TiledWMS = function(tiledWMSOptions) { tileUrlFunction = ol.TileUrlFunction.nullTileUrlFunction; } - function tileCoordTransform(tileCoord) { + var tileCoordTransform = function(tileCoord) { if (tileGrid.getResolutions().length <= tileCoord.z) { return null; } @@ -90,7 +90,7 @@ ol.source.TiledWMS = function(tiledWMSOptions) { return null; } return new ol.TileCoord(tileCoord.z, x, tileCoord.y); - } + }; goog.base(this, { attributions: tiledWMSOptions.attributions, From 9eeea82338f984b0265924964e6739dfc67128d8 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 21 Feb 2013 15:21:17 +0100 Subject: [PATCH 17/36] Remove CSS color workarounds. --- css/ol.css | 6 ------ 1 file changed, 6 deletions(-) diff --git a/css/ol.css b/css/ol.css index eca80d969c..79fec30bae 100644 --- a/css/ol.css +++ b/css/ol.css @@ -5,9 +5,7 @@ color: #eeeeee; bottom: 0; right: 0; - background: #130085; /* @alternate */ background: rgba(0,60,136,0.3); - filter: alpha(opacity=30); font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif; padding: 2px 4px; } @@ -60,14 +58,10 @@ height: 22px; width: 22px; line-height: 19px; - background: #130085; /* @alternate */ background: rgba(0,60,136,0.5); - filter: alpha(opacity=80); } .ol-zoom a:hover { - background: #130085; /* @alternate */ background: rgba(0,60,136,0.7); - filter: alpha(opacity=100); } @media only screen and (max-width:600px) { .ol-zoom a:hover { From e513b8cc390ba7022fead343db99269c6dbb5bcc Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 21 Feb 2013 16:12:45 +0100 Subject: [PATCH 18/36] Make it explicit that functions operate on tile sources --- src/ol/renderer/layerrenderer.js | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/ol/renderer/layerrenderer.js b/src/ol/renderer/layerrenderer.js index 3379e0da5e..f1477ac8d7 100644 --- a/src/ol/renderer/layerrenderer.js +++ b/src/ol/renderer/layerrenderer.js @@ -14,7 +14,6 @@ goog.require('ol.TileState'); goog.require('ol.layer.Layer'); goog.require('ol.layer.LayerProperty'); goog.require('ol.layer.LayerState'); -goog.require('ol.source.Source'); goog.require('ol.source.TileSource'); @@ -222,24 +221,24 @@ ol.renderer.Layer.prototype.updateAttributions = /** * @protected * @param {Object.>} usedTiles Used tiles. - * @param {ol.source.Source} source Source. + * @param {ol.source.TileSource} tileSource Tile source. * @param {number} z Z. * @param {ol.TileRange} tileRange Tile range. */ ol.renderer.Layer.prototype.updateUsedTiles = - function(usedTiles, source, z, tileRange) { + function(usedTiles, tileSource, z, tileRange) { // FIXME should we use tilesToDrawByZ instead? - var sourceKey = goog.getUid(source).toString(); + var tileSourceKey = goog.getUid(tileSource).toString(); var zKey = z.toString(); - if (sourceKey in usedTiles) { - if (zKey in usedTiles[sourceKey]) { - usedTiles[sourceKey][zKey].extend(tileRange); + if (tileSourceKey in usedTiles) { + if (zKey in usedTiles[tileSourceKey]) { + usedTiles[tileSourceKey][zKey].extend(tileRange); } else { - usedTiles[sourceKey][zKey] = tileRange; + usedTiles[tileSourceKey][zKey] = tileRange; } } else { - usedTiles[sourceKey] = {}; - usedTiles[sourceKey][zKey] = tileRange; + usedTiles[tileSourceKey] = {}; + usedTiles[tileSourceKey][zKey] = tileRange; } }; @@ -247,15 +246,15 @@ ol.renderer.Layer.prototype.updateUsedTiles = /** * @protected * @param {Object.>} wantedTiles Wanted tiles. - * @param {ol.source.Source} source Source. + * @param {ol.source.TileSource} tileSource Tile source. * @param {ol.TileCoord} tileCoord Tile coordinate. */ ol.renderer.Layer.prototype.updateWantedTiles = - function(wantedTiles, source, tileCoord) { - var sourceKey = goog.getUid(source).toString(); + function(wantedTiles, tileSource, tileCoord) { + var tileSourceKey = goog.getUid(tileSource).toString(); var coordKey = tileCoord.toString(); - if (!(sourceKey in wantedTiles)) { - wantedTiles[sourceKey] = {}; + if (!(tileSourceKey in wantedTiles)) { + wantedTiles[tileSourceKey] = {}; } - wantedTiles[sourceKey][coordKey] = true; + wantedTiles[tileSourceKey][coordKey] = true; }; From e68c1adbae62f290f9cef6480daefec6d33ff212 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 21 Feb 2013 16:13:34 +0100 Subject: [PATCH 19/36] Add ol.source.TileSource.useTile --- src/ol/source/tilesource.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ol/source/tilesource.js b/src/ol/source/tilesource.js index e9666dada6..2199511127 100644 --- a/src/ol/source/tilesource.js +++ b/src/ol/source/tilesource.js @@ -119,3 +119,10 @@ ol.source.TileSource.prototype.getTile = goog.abstractMethod; ol.source.TileSource.prototype.getTileGrid = function() { return this.tileGrid; }; + + +/** + * Marks a tile coord as being used, without triggering a load. + * @param {ol.TileCoord} tileCoord Tile coordinate. + */ +ol.source.TileSource.prototype.useTile = goog.nullFunction; From 57b446fa0a8fd479452d9d6f3cd938ad15703456 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 21 Feb 2013 16:14:15 +0100 Subject: [PATCH 20/36] Implement useTile for image tile sources with caches --- src/ol/source/imagetilesource.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/ol/source/imagetilesource.js b/src/ol/source/imagetilesource.js index 4a59b1bcff..d47b9215e5 100644 --- a/src/ol/source/imagetilesource.js +++ b/src/ol/source/imagetilesource.js @@ -109,3 +109,14 @@ ol.source.ImageTileSource.prototype.getTile = function(tileCoord) { ol.source.ImageTileSource.prototype.getTileCoordUrl = function(tileCoord) { return this.tileUrlFunction(tileCoord); }; + + +/** + * @inheritDoc + */ +ol.source.ImageTileSource.prototype.useTile = function(tileCoord) { + var key = tileCoord.toString(); + if (this.tileCache_.containsKey(key)) { + this.tileCache_.get(key); + } +}; From 47e799ced0b580f1e369c13c1e7450dae3097251 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 21 Feb 2013 16:14:51 +0100 Subject: [PATCH 21/36] Mark all low resolution tiles as used to prevent cache expiration --- .../canvas/canvastilelayerrenderer.js | 1 + src/ol/renderer/dom/domtilelayerrenderer.js | 1 + src/ol/renderer/layerrenderer.js | 23 +++++++++++++++++++ .../renderer/webgl/webgltilelayerrenderer.js | 1 + 4 files changed, 26 insertions(+) diff --git a/src/ol/renderer/canvas/canvastilelayerrenderer.js b/src/ol/renderer/canvas/canvastilelayerrenderer.js index e7c48f044c..c60ef7e49a 100644 --- a/src/ol/renderer/canvas/canvastilelayerrenderer.js +++ b/src/ol/renderer/canvas/canvastilelayerrenderer.js @@ -199,6 +199,7 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = } this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange); + this.useLowResolutionTiles(tileSource, z, frameState.extent); this.scheduleExpireCache(frameState, tileSource); var transform = this.transform_; diff --git a/src/ol/renderer/dom/domtilelayerrenderer.js b/src/ol/renderer/dom/domtilelayerrenderer.js index faeb67d47d..3821f2a22b 100644 --- a/src/ol/renderer/dom/domtilelayerrenderer.js +++ b/src/ol/renderer/dom/domtilelayerrenderer.js @@ -217,6 +217,7 @@ ol.renderer.dom.TileLayer.prototype.renderFrame = } this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange); + this.useLowResolutionTiles(tileSource, z, frameState.extent); this.scheduleExpireCache(frameState, tileSource); }; diff --git a/src/ol/renderer/layerrenderer.js b/src/ol/renderer/layerrenderer.js index f1477ac8d7..beb91f376a 100644 --- a/src/ol/renderer/layerrenderer.js +++ b/src/ol/renderer/layerrenderer.js @@ -3,6 +3,7 @@ goog.provide('ol.renderer.Layer'); goog.require('goog.events'); goog.require('goog.events.EventType'); goog.require('ol.Attribution'); +goog.require('ol.Extent'); goog.require('ol.FrameState'); goog.require('ol.Image'); goog.require('ol.ImageState'); @@ -258,3 +259,25 @@ ol.renderer.Layer.prototype.updateWantedTiles = } wantedTiles[tileSourceKey][coordKey] = true; }; + + +/** + * @protected + * @param {ol.source.TileSource} tileSource Tile source. + * @param {number} z Z. + * @param {ol.Extent} extent Extent. + */ +ol.renderer.Layer.prototype.useLowResolutionTiles = + function(tileSource, z, extent) { + var tileGrid = tileSource.getTileGrid(); + var tileRange, x, y, zKey; + // FIXME this should loop up to tileGrid's minZ when implemented + for (; z >= 0; --z) { + tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z); + for (x = tileRange.minX; x <= tileRange.maxX; ++x) { + for (y = tileRange.minY; y <= tileRange.maxY; ++y) { + tileSource.useTile(new ol.TileCoord(z, x, y)); + } + } + } +}; diff --git a/src/ol/renderer/webgl/webgltilelayerrenderer.js b/src/ol/renderer/webgl/webgltilelayerrenderer.js index 53405ca10a..0e939f8665 100644 --- a/src/ol/renderer/webgl/webgltilelayerrenderer.js +++ b/src/ol/renderer/webgl/webgltilelayerrenderer.js @@ -459,6 +459,7 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = } this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange); + this.useLowResolutionTiles(tileSource, z, frameState.extent); this.scheduleExpireCache(frameState, tileSource); goog.vec.Mat4.makeIdentity(this.texCoordMatrix_); From 4c9b70fa5c21c86204f57b6dcd517756f1a293d1 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 21 Feb 2013 16:47:10 +0100 Subject: [PATCH 22/36] Move useLowResolutionTiles from layer renderer to tile source --- .../canvas/canvastilelayerrenderer.js | 2 +- src/ol/renderer/dom/domtilelayerrenderer.js | 2 +- src/ol/renderer/layerrenderer.js | 23 ------------------- .../renderer/webgl/webgltilelayerrenderer.js | 2 +- src/ol/source/tilesource.js | 19 +++++++++++++++ 5 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/ol/renderer/canvas/canvastilelayerrenderer.js b/src/ol/renderer/canvas/canvastilelayerrenderer.js index c60ef7e49a..8cd80ac388 100644 --- a/src/ol/renderer/canvas/canvastilelayerrenderer.js +++ b/src/ol/renderer/canvas/canvastilelayerrenderer.js @@ -199,7 +199,7 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = } this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange); - this.useLowResolutionTiles(tileSource, z, frameState.extent); + tileSource.useLowResolutionTiles(z, frameState.extent); this.scheduleExpireCache(frameState, tileSource); var transform = this.transform_; diff --git a/src/ol/renderer/dom/domtilelayerrenderer.js b/src/ol/renderer/dom/domtilelayerrenderer.js index 3821f2a22b..81c50f779e 100644 --- a/src/ol/renderer/dom/domtilelayerrenderer.js +++ b/src/ol/renderer/dom/domtilelayerrenderer.js @@ -217,7 +217,7 @@ ol.renderer.dom.TileLayer.prototype.renderFrame = } this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange); - this.useLowResolutionTiles(tileSource, z, frameState.extent); + tileSource.useLowResolutionTiles(z, frameState.extent); this.scheduleExpireCache(frameState, tileSource); }; diff --git a/src/ol/renderer/layerrenderer.js b/src/ol/renderer/layerrenderer.js index beb91f376a..f1477ac8d7 100644 --- a/src/ol/renderer/layerrenderer.js +++ b/src/ol/renderer/layerrenderer.js @@ -3,7 +3,6 @@ goog.provide('ol.renderer.Layer'); goog.require('goog.events'); goog.require('goog.events.EventType'); goog.require('ol.Attribution'); -goog.require('ol.Extent'); goog.require('ol.FrameState'); goog.require('ol.Image'); goog.require('ol.ImageState'); @@ -259,25 +258,3 @@ ol.renderer.Layer.prototype.updateWantedTiles = } wantedTiles[tileSourceKey][coordKey] = true; }; - - -/** - * @protected - * @param {ol.source.TileSource} tileSource Tile source. - * @param {number} z Z. - * @param {ol.Extent} extent Extent. - */ -ol.renderer.Layer.prototype.useLowResolutionTiles = - function(tileSource, z, extent) { - var tileGrid = tileSource.getTileGrid(); - var tileRange, x, y, zKey; - // FIXME this should loop up to tileGrid's minZ when implemented - for (; z >= 0; --z) { - tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z); - for (x = tileRange.minX; x <= tileRange.maxX; ++x) { - for (y = tileRange.minY; y <= tileRange.maxY; ++y) { - tileSource.useTile(new ol.TileCoord(z, x, y)); - } - } - } -}; diff --git a/src/ol/renderer/webgl/webgltilelayerrenderer.js b/src/ol/renderer/webgl/webgltilelayerrenderer.js index 0e939f8665..16df44aa6d 100644 --- a/src/ol/renderer/webgl/webgltilelayerrenderer.js +++ b/src/ol/renderer/webgl/webgltilelayerrenderer.js @@ -459,7 +459,7 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = } this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange); - this.useLowResolutionTiles(tileSource, z, frameState.extent); + tileSource.useLowResolutionTiles(z, frameState.extent); this.scheduleExpireCache(frameState, tileSource); goog.vec.Mat4.makeIdentity(this.texCoordMatrix_); diff --git a/src/ol/source/tilesource.js b/src/ol/source/tilesource.js index 2199511127..2afd321a1b 100644 --- a/src/ol/source/tilesource.js +++ b/src/ol/source/tilesource.js @@ -121,6 +121,25 @@ ol.source.TileSource.prototype.getTileGrid = function() { }; +/** + * @param {number} z Z. + * @param {ol.Extent} extent Extent. + */ +ol.source.TileSource.prototype.useLowResolutionTiles = function(z, extent) { + var tileGrid = this.getTileGrid(); + var tileRange, x, y, zKey; + // FIXME this should loop up to tileGrid's minZ when implemented + for (; z >= 0; --z) { + tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z); + for (x = tileRange.minX; x <= tileRange.maxX; ++x) { + for (y = tileRange.minY; y <= tileRange.maxY; ++y) { + this.useTile(new ol.TileCoord(z, x, y)); + } + } + } +}; + + /** * Marks a tile coord as being used, without triggering a load. * @param {ol.TileCoord} tileCoord Tile coordinate. From c36de098bd9ffb941d93fc2d76c372d19059dbf5 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Thu, 21 Feb 2013 16:52:52 +0100 Subject: [PATCH 23/36] Avoid creating a TileCoord object when marking used tiles --- src/ol/source/tilesource.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ol/source/tilesource.js b/src/ol/source/tilesource.js index 2afd321a1b..c250951e7e 100644 --- a/src/ol/source/tilesource.js +++ b/src/ol/source/tilesource.js @@ -133,7 +133,7 @@ ol.source.TileSource.prototype.useLowResolutionTiles = function(z, extent) { tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z); for (x = tileRange.minX; x <= tileRange.maxX; ++x) { for (y = tileRange.minY; y <= tileRange.maxY; ++y) { - this.useTile(new ol.TileCoord(z, x, y)); + this.useTile(z + '/' + x + '/' + y); } } } @@ -142,6 +142,6 @@ ol.source.TileSource.prototype.useLowResolutionTiles = function(z, extent) { /** * Marks a tile coord as being used, without triggering a load. - * @param {ol.TileCoord} tileCoord Tile coordinate. + * @param {string} tileCoordKey Tile coordinate key. */ ol.source.TileSource.prototype.useTile = goog.nullFunction; From 981c1dcbd72fe2f4de844c77b80a14a4016be16a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Fri, 22 Feb 2013 23:16:36 +0100 Subject: [PATCH 24/36] Remove examples/standalone dir --- .../standalone/full-screen-standalone.html | 23 ------ .../overlay-and-popup-standalone.html | 82 ------------------- .../standalone/side-by-side-standalone.html | 71 ---------------- 3 files changed, 176 deletions(-) delete mode 100644 examples/standalone/full-screen-standalone.html delete mode 100644 examples/standalone/overlay-and-popup-standalone.html delete mode 100644 examples/standalone/side-by-side-standalone.html diff --git a/examples/standalone/full-screen-standalone.html b/examples/standalone/full-screen-standalone.html deleted file mode 100644 index afb0f97f38..0000000000 --- a/examples/standalone/full-screen-standalone.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - ol3 full-screen demo - - - -
- - - diff --git a/examples/standalone/overlay-and-popup-standalone.html b/examples/standalone/overlay-and-popup-standalone.html deleted file mode 100644 index e1293b1c54..0000000000 --- a/examples/standalone/overlay-and-popup-standalone.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - ol3 overlay-and-popup demo - - - -
- - Vienna - - -
- - - diff --git a/examples/standalone/side-by-side-standalone.html b/examples/standalone/side-by-side-standalone.html deleted file mode 100644 index e28c0425a7..0000000000 --- a/examples/standalone/side-by-side-standalone.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - ol3 side-by-side demo - - - -

ol3 side-by-side demo

- - - - - - - - - - - - - -
DOMWebGL
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Pan:drag, arrow keys
Zoom:double-click, Shift+double-click, mouse wheel, +/- keys; Shift+drag
Rotate:Alt+drag, r to reset
Brightness/contrast:b/B/c/C keys (WebGL only)
Hue/saturation:h/H/s/S keys (WebGL only)
Opacity:o/O keys
Visibility:v/V keys
Reset0 key
-

Notes: The two maps share the same center, resolution, rotation and layers.

- - - From 31bcd2832ee14bc54599971ff44ae0380a09c86c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Fri, 22 Feb 2013 23:23:04 +0100 Subject: [PATCH 25/36] Update comments in hosted examples loader --- build/loader_hosted_examples.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/loader_hosted_examples.js b/build/loader_hosted_examples.js index 3ec22aa5e2..9afe49715f 100644 --- a/build/loader_hosted_examples.js +++ b/build/loader_hosted_examples.js @@ -6,8 +6,8 @@ * This loader is used for the hosted examples. It is used in place of the * development loader (examples/loader.js). * - * ol.css and ol.js are built with Plovr/Closure, based build/ol.json. - * (`make build` should build them). They are located in the ../build/ + * ol.css and ol.js are built with Plovr/Closure, based on build/ol.json. + * (`build.py build` builds them). They are located in the ../build/ * directory, relatively to this script. * * The script should be named loader.js. So it needs to be renamed to From 343d52cff1d9365201535e7784a60915a0f23124 Mon Sep 17 00:00:00 2001 From: Peter Robins Date: Mon, 25 Feb 2013 15:18:51 +0000 Subject: [PATCH 26/36] Fix bug/typo in projection.getTransform Destination projection is currently using the source projection code --- src/ol/projection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ol/projection.js b/src/ol/projection.js index d6c57812a0..7cbf1892f2 100644 --- a/src/ol/projection.js +++ b/src/ol/projection.js @@ -354,7 +354,7 @@ ol.Projection.getTransform = function(source, destination) { proj4jsDestination = destination; } else { proj4jsDestination = - ol.Projection.getProj4jsProjectionFromCode_(source.getCode()); + ol.Projection.getProj4jsProjectionFromCode_(destination.getCode()); } var destinationProj4jsProj = proj4jsDestination.getProj4jsProj(); transform = From 86262bf17e72e3d8ae4bc5683c4dc3514eaa6352 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Mon, 25 Feb 2013 09:52:33 -0700 Subject: [PATCH 27/36] Space for linter --- test/spec/ol/projection.test.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/test/spec/ol/projection.test.js b/test/spec/ol/projection.test.js index eb1c9b4787..85e5c7b205 100644 --- a/test/spec/ol/projection.test.js +++ b/test/spec/ol/projection.test.js @@ -23,14 +23,13 @@ describe('ol.Projection', function() { }); it('gives that CRS:84, urn:ogc:def:crs:EPSG:6.6:4326, EPSG:4326 are ' + - 'equivalent', function() { - _testAllEquivalent([ - 'CRS:84', - 'urn:ogc:def:crs:EPSG:6.6:4326', - 'EPSG:4326' - ]); - }); - + 'equivalent', function() { + _testAllEquivalent([ + 'CRS:84', + 'urn:ogc:def:crs:EPSG:6.6:4326', + 'EPSG:4326' + ]); + }); }); describe('identify transform', function() { From 48e69f755941b2c559490125d1b2db2ae00e8d24 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Mon, 25 Feb 2013 10:11:21 -0700 Subject: [PATCH 28/36] Unused var --- src/ol/projection.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ol/projection.js b/src/ol/projection.js index 7cbf1892f2..ede51c7712 100644 --- a/src/ol/projection.js +++ b/src/ol/projection.js @@ -254,7 +254,6 @@ ol.Projection.createProjection = function(projection, defaultCode) { * @param {ol.TransformFunction} transformFn Transform. */ ol.Projection.addTransform = function(source, destination, transformFn) { - var projections = ol.Projection.projections_; var sourceCode = source.getCode(); var destinationCode = destination.getCode(); var transforms = ol.Projection.transforms_; From 72ba8c4cbdf1221671ee69c009493057f9af84e9 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Mon, 25 Feb 2013 10:13:04 -0700 Subject: [PATCH 29/36] Smoke test for ol.Projection.getTransformFromCodes --- test/spec/ol/projection.test.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/spec/ol/projection.test.js b/test/spec/ol/projection.test.js index 85e5c7b205..2f56d5e70f 100644 --- a/test/spec/ol/projection.test.js +++ b/test/spec/ol/projection.test.js @@ -125,6 +125,17 @@ describe('ol.Projection', function() { }); + describe('ol.Projection.getTransformFromCodes()', function() { + + it('returns a transform function', function() { + debugger; + var transform = ol.Projection.getTransformFromCodes( + 'GOOGLE', 'EPSG:4326'); + expect(typeof transform).toBe('function'); + }); + + }); + }); goog.require('goog.array'); From 940ba8afa7f1c8d8eb244de950d5fd4e4fd76a3a Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Mon, 25 Feb 2013 11:26:04 -0700 Subject: [PATCH 30/36] Stray debugger --- test/spec/ol/projection.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/spec/ol/projection.test.js b/test/spec/ol/projection.test.js index 2f56d5e70f..6884dafc28 100644 --- a/test/spec/ol/projection.test.js +++ b/test/spec/ol/projection.test.js @@ -128,7 +128,6 @@ describe('ol.Projection', function() { describe('ol.Projection.getTransformFromCodes()', function() { it('returns a transform function', function() { - debugger; var transform = ol.Projection.getTransformFromCodes( 'GOOGLE', 'EPSG:4326'); expect(typeof transform).toBe('function'); From ca85c265378504c86b87bdc8620683b2f1b0a837 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Mon, 25 Feb 2013 11:28:14 -0700 Subject: [PATCH 31/36] Method for removing cached transforms --- src/ol/projection.js | 25 +++++++++++++++++++++++++ test/spec/ol/projection.test.js | 19 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/ol/projection.js b/src/ol/projection.js index ede51c7712..3e1692d01c 100644 --- a/src/ol/projection.js +++ b/src/ol/projection.js @@ -266,6 +266,31 @@ ol.Projection.addTransform = function(source, destination, transformFn) { }; +/** + * Unregisters the conversion function to convert coordinates from the source + * projection to the destination projection. This method is used to clean up + * cached transforms during testing. + * + * @param {ol.Projection} source Source projection. + * @param {ol.Projection} destination Destination projection. + * @return {ol.TransformFunction} transformFn The unregistered transform. + */ +ol.Projection.removeTransform = function(source, destination) { + var sourceCode = source.getCode(); + var destinationCode = destination.getCode(); + var transforms = ol.Projection.transforms_; + goog.asserts.assert(sourceCode in transforms); + goog.asserts.assert(destinationCode in transforms[sourceCode]); + var transform = transforms[sourceCode][destinationCode]; + delete transforms[sourceCode][destinationCode]; + var keys = goog.object.getKeys(transforms[sourceCode]); + if (keys.length == 0) { + delete transforms[sourceCode]; + } + return transform; +}; + + /** * @param {string} code Code which is a combination of authority and identifier * such as “EPSG:4326”. diff --git a/test/spec/ol/projection.test.js b/test/spec/ol/projection.test.js index 6884dafc28..a3a421d119 100644 --- a/test/spec/ol/projection.test.js +++ b/test/spec/ol/projection.test.js @@ -131,6 +131,25 @@ describe('ol.Projection', function() { var transform = ol.Projection.getTransformFromCodes( 'GOOGLE', 'EPSG:4326'); expect(typeof transform).toBe('function'); + }); + + describe('ol.Projection.removeTransform()', function() { + + var extent = new ol.Extent(-180, -90, 180, 90); + var units = ol.ProjectionUnits.DEGREES; + + it('removes functions cached by addTransform', function() { + var foo = new ol.Projection('foo', units, extent); + var bar = new ol.Projection('bar', units, extent); + var transform = function() {}; + ol.Projection.addTransform(foo, bar, transform); + expect(ol.Projection.transforms_).not.toBeUndefined(); + expect(ol.Projection.transforms_.foo).not.toBeUndefined(); + expect(ol.Projection.transforms_.foo.bar).toBe(transform); + + var removed = ol.Projection.removeTransform(foo, bar); + expect(removed).toBe(transform); + expect(ol.Projection.transforms_.foo).toBeUndefined(); }); }); From 52da64564c313e570ea2eec1801ef8b3d58d7b9e Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Mon, 25 Feb 2013 11:40:55 -0700 Subject: [PATCH 32/36] Tests for getting transforms These are regression tests for #231. --- test/spec/ol/projection.test.js | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/test/spec/ol/projection.test.js b/test/spec/ol/projection.test.js index a3a421d119..1ee2c4d91c 100644 --- a/test/spec/ol/projection.test.js +++ b/test/spec/ol/projection.test.js @@ -2,6 +2,27 @@ goog.provide('ol.test.Projection'); describe('ol.Projection', function() { + beforeEach(function() { + spyOn(ol.Projection, 'addTransform').andCallThrough(); + }); + + afterEach(function() { + var argsForCall = ol.Projection.addTransform.argsForCall; + for (var i = 0, ii = argsForCall.length; i < ii; ++i) { + try { + ol.Projection.removeTransform.apply( + ol.Projection, argsForCall[i].splice(0, 2)); + } catch (error) { + if (error instanceof goog.asserts.AssertionError) { + // The removeTransform function may have been called explicitly by the + // tests, so we pass. + } else { + throw error; + } + } + } + }); + describe('projection equivalence', function() { function _testAllEquivalent(codes) { @@ -125,12 +146,45 @@ describe('ol.Projection', function() { }); + describe('ol.Projection.getTransform()', function() { + + var sm = ol.Projection.getFromCode('GOOGLE'); + var gg = ol.Projection.getFromCode('EPSG:4326'); + + it('returns a transform function', function() { + var transform = ol.Projection.getTransform(sm, gg); + expect(typeof transform).toBe('function'); + + var coordinate = transform(new ol.Coordinate(-12000000, 5000000)); + + expect(coordinate.x).toRoughlyEqual(-107.79783409434258, 1e-9); + expect(coordinate.y).toRoughlyEqual(40.91627447067577, 1e-9); + }); + + }); + + describe('ol.Projection.getTransformFromCodes()', function() { + it('returns a function', function() { + var transform = ol.Projection.getTransformFromCodes( + 'GOOGLE', 'EPSG:4326'); + expect(typeof transform).toBe('function'); + }); + it('returns a transform function', function() { var transform = ol.Projection.getTransformFromCodes( 'GOOGLE', 'EPSG:4326'); expect(typeof transform).toBe('function'); + + var coordinate = transform( + new ol.Coordinate(-626172.13571216376, 6887893.4928337997)); + + expect(coordinate.x).toRoughlyEqual(-5.625, 1e-9); + expect(coordinate.y).toRoughlyEqual(52.4827802220782, 1e-9); + + }); + }); describe('ol.Projection.removeTransform()', function() { @@ -158,4 +212,6 @@ describe('ol.Projection', function() { goog.require('goog.array'); goog.require('ol.Coordinate'); +goog.require('ol.Extent'); goog.require('ol.Projection'); +goog.require('ol.ProjectionUnits'); From 7a8b331213325372d0e9fd3ff3b7e8f5209bd8b2 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 27 Feb 2013 10:18:16 +0100 Subject: [PATCH 33/36] Fix 'grids' type declaration. grids property is optional. see: https://github.com/mapbox/tilejson-spec/blob/master/2.0.0/README.md --- externs/tilejson.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externs/tilejson.js b/externs/tilejson.js index 5927c479ee..6e982cc325 100644 --- a/externs/tilejson.js +++ b/externs/tilejson.js @@ -66,7 +66,7 @@ TileJSON.prototype.tiles; /** - * @type {!Array.} + * @type {!Array.|undefined} */ TileJSON.prototype.grids; From dda4060d849712a3b120bd8479161293df43be37 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 27 Feb 2013 13:35:32 +0100 Subject: [PATCH 34/36] Export ol.animation.zoom --- src/ol/animation.exports | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ol/animation.exports b/src/ol/animation.exports index 98207b2e1a..4a8819704d 100644 --- a/src/ol/animation.exports +++ b/src/ol/animation.exports @@ -2,3 +2,4 @@ @exportProperty ol.animation.bounce @exportProperty ol.animation.pan @exportProperty ol.animation.rotate +@exportProperty ol.animation.zoom From 90cb0e8fcb00c89b43c9f76500ba57c57c06a4ac Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 27 Feb 2013 13:52:39 +0100 Subject: [PATCH 35/36] Export ol.easing.* --- src/ol/easing.exports | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/ol/easing.exports diff --git a/src/ol/easing.exports b/src/ol/easing.exports new file mode 100644 index 0000000000..62418771ad --- /dev/null +++ b/src/ol/easing.exports @@ -0,0 +1,5 @@ +@exportSymbol ol.easing +@exportProperty ol.easing.linear +@exportProperty ol.easing.upAndDown +@exportProperty ol.easing.elastic +@exportProperty ol.easing.bounce From 5ccf94a395035872030dfcdea8e27e9141f2e966 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 27 Feb 2013 13:58:30 +0100 Subject: [PATCH 36/36] Do not use goog.now() in the examples (see #229) --- examples/side-by-side.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/side-by-side.js b/examples/side-by-side.js index b5d108b0df..661d1ebb79 100644 --- a/examples/side-by-side.js +++ b/examples/side-by-side.js @@ -131,7 +131,7 @@ keyboardInteraction.addCallback('l', function() { view.setCenter(LONDON); }); keyboardInteraction.addCallback('L', function() { - var start = goog.now(); + var start = +new Date(); var duration = 5000; var bounce = ol.animation.bounce({ resolution: 2 * view.getResolution(), @@ -166,7 +166,7 @@ keyboardInteraction.addCallback('m', function() { view.setCenter(MOSCOW); }); keyboardInteraction.addCallback('M', function() { - var start = goog.now(); + var start = +new Date(); var duration = 5000; var bounce = ol.animation.bounce({ resolution: 2 * view.getResolution(),