Full-screen example
Example of a full-screen map.
diff --git a/examples/full-screen.js b/examples/full-screen.js
index 3e9cce6f89..eb13bda2f2 100644
--- a/examples/full-screen.js
+++ b/examples/full-screen.js
@@ -1,8 +1,11 @@
goog.require('goog.debug.Console');
goog.require('goog.debug.Logger');
goog.require('goog.debug.Logger.Level');
+goog.require('goog.style');
+goog.require('ol.AnchoredElement');
goog.require('ol.Collection');
goog.require('ol.Coordinate');
+goog.require('ol.Geolocation');
goog.require('ol.Map');
goog.require('ol.RendererHints');
goog.require('ol.View2D');
@@ -28,3 +31,14 @@ var map = new ol.Map({
zoom: 0
})
});
+
+var geolocation = new ol.Geolocation();
+geolocation.bindTo('projection', map.getView());
+
+var element = document.getElementById('geolocation');
+var marker = new ol.AnchoredElement({
+ map: map,
+ element: element
+});
+marker.bindTo('position', geolocation);
+goog.style.showElement(element, true);
diff --git a/examples/side-by-side.js b/examples/side-by-side.js
index 4c5bb354b7..b5d108b0df 100644
--- a/examples/side-by-side.js
+++ b/examples/side-by-side.js
@@ -42,12 +42,13 @@ var domMap = new ol.Map({
view: view
});
-domMap.getControls().push(new ol.control.MousePosition({
+var domMousePosition = new ol.control.MousePosition({
coordinateFormat: ol.Coordinate.toStringHDMS,
projection: ol.Projection.getFromCode('EPSG:4326'),
target: document.getElementById('domMousePosition'),
undefinedHTML: ' '
-}));
+});
+domMousePosition.setMap(domMap);
var webglMap = new ol.Map({
renderer: ol.RendererHint.WEBGL,
@@ -58,12 +59,13 @@ if (webglMap !== null) {
webglMap.bindTo('view', domMap);
}
-webglMap.getControls().push(new ol.control.MousePosition({
+var webglMousePosition = new ol.control.MousePosition({
coordinateFormat: ol.Coordinate.toStringHDMS,
projection: ol.Projection.getFromCode('EPSG:4326'),
target: document.getElementById('webglMousePosition'),
undefinedHTML: ' '
-}));
+});
+webglMousePosition.setMap(webglMap);
var canvasMap = new ol.Map({
renderer: ol.RendererHint.CANVAS,
@@ -74,12 +76,13 @@ if (canvasMap !== null) {
canvasMap.bindTo('view', domMap);
}
-canvasMap.getControls().push(new ol.control.MousePosition({
+var canvasMousePosition = new ol.control.MousePosition({
coordinateFormat: ol.Coordinate.toStringHDMS,
projection: ol.Projection.getFromCode('EPSG:4326'),
target: document.getElementById('canvasMousePosition'),
undefinedHtml: ' '
-}));
+});
+canvasMousePosition.setMap(canvasMap);
var keyboardInteraction = new ol.interaction.Keyboard();
keyboardInteraction.addCallback('0', function() {
@@ -110,7 +113,7 @@ keyboardInteraction.addCallback('H', function() {
layer.setHue(layer.getHue() + (Math.PI / 5));
});
keyboardInteraction.addCallback('j', function() {
- var bounce = ol.animation.createBounce({
+ var bounce = ol.animation.bounce({
resolution: 2 * view.getResolution()
});
domMap.addPreRenderFunction(bounce);
@@ -118,69 +121,69 @@ keyboardInteraction.addCallback('j', function() {
canvasMap.addPreRenderFunction(bounce);
});
keyboardInteraction.addCallback('l', function() {
- var panFrom = ol.animation.createPanFrom({
+ var pan = ol.animation.pan({
source: view.getCenter(),
easing: ol.easing.elastic
});
- domMap.addPreRenderFunction(panFrom);
- webglMap.addPreRenderFunction(panFrom);
- canvasMap.addPreRenderFunction(panFrom);
+ domMap.addPreRenderFunction(pan);
+ webglMap.addPreRenderFunction(pan);
+ canvasMap.addPreRenderFunction(pan);
view.setCenter(LONDON);
});
keyboardInteraction.addCallback('L', function() {
var start = goog.now();
var duration = 5000;
- var bounce = ol.animation.createBounce({
+ var bounce = ol.animation.bounce({
resolution: 2 * view.getResolution(),
start: start,
duration: duration
});
- var panFrom = ol.animation.createPanFrom({
+ var pan = ol.animation.pan({
source: view.getCenter(),
start: start,
duration: duration
});
- var spin = ol.animation.createSpin({
- turns: 2,
+ var rotate = ol.animation.rotate({
+ rotation: 4 * Math.PI,
start: start,
duration: duration
});
- var preRenderFunctions = [bounce, panFrom, spin];
+ var preRenderFunctions = [bounce, pan, rotate];
domMap.addPreRenderFunctions(preRenderFunctions);
webglMap.addPreRenderFunctions(preRenderFunctions);
canvasMap.addPreRenderFunctions(preRenderFunctions);
view.setCenter(LONDON);
});
keyboardInteraction.addCallback('m', function() {
- var panFrom = ol.animation.createPanFrom({
+ var pan = ol.animation.pan({
source: view.getCenter(),
duration: 1000,
easing: ol.easing.bounce
});
- domMap.addPreRenderFunction(panFrom);
- webglMap.addPreRenderFunction(panFrom);
- canvasMap.addPreRenderFunction(panFrom);
+ domMap.addPreRenderFunction(pan);
+ webglMap.addPreRenderFunction(pan);
+ canvasMap.addPreRenderFunction(pan);
view.setCenter(MOSCOW);
});
keyboardInteraction.addCallback('M', function() {
var start = goog.now();
var duration = 5000;
- var bounce = ol.animation.createBounce({
+ var bounce = ol.animation.bounce({
resolution: 2 * view.getResolution(),
start: start,
duration: duration
});
- var panFrom = ol.animation.createPanFrom({
+ var pan = ol.animation.pan({
source: view.getCenter(),
start: start,
duration: duration
});
- var spin = ol.animation.createSpin({
- turns: -2,
+ var rotate = ol.animation.rotate({
+ rotation: -4 * Math.PI,
start: start,
duration: duration
});
- var preRenderFunctions = [bounce, panFrom, spin];
+ var preRenderFunctions = [bounce, pan, rotate];
domMap.addPreRenderFunctions(preRenderFunctions);
webglMap.addPreRenderFunctions(preRenderFunctions);
canvasMap.addPreRenderFunctions(preRenderFunctions);
@@ -206,21 +209,21 @@ keyboardInteraction.addCallback('vV', function() {
layer.setVisible(!layer.getVisible());
});
keyboardInteraction.addCallback('x', function() {
- var spin = ol.animation.createSpin({
- turns: 2,
+ var rotate = ol.animation.rotate({
+ rotation: 4 * Math.PI,
duration: 2000
});
- domMap.addPreRenderFunction(spin);
- webglMap.addPreRenderFunction(spin);
- canvasMap.addPreRenderFunction(spin);
+ domMap.addPreRenderFunction(rotate);
+ webglMap.addPreRenderFunction(rotate);
+ canvasMap.addPreRenderFunction(rotate);
});
keyboardInteraction.addCallback('X', function() {
- var spin = ol.animation.createSpin({
- turns: -2,
+ var rotate = ol.animation.rotate({
+ rotation: -4 * Math.PI,
duration: 2000
});
- domMap.addPreRenderFunction(spin);
- webglMap.addPreRenderFunction(spin);
- canvasMap.addPreRenderFunction(spin);
+ domMap.addPreRenderFunction(rotate);
+ webglMap.addPreRenderFunction(rotate);
+ canvasMap.addPreRenderFunction(rotate);
});
domMap.getInteractions().push(keyboardInteraction);
diff --git a/pake.py b/pake.py
index dec8b71a7a..27b3648580 100644
--- a/pake.py
+++ b/pake.py
@@ -288,7 +288,10 @@ def ifind(*paths):
for path in paths:
for dirpath, dirnames, names in os.walk(path):
for name in names:
- yield os.path.join(dirpath, name)
+ if sys.platform == 'win32':
+ yield '/'.join(dirpath.split('\\') + [name])
+ else:
+ yield os.path.join(dirpath, name)
def main(argv=sys.argv):
diff --git a/readme.md b/readme.md
index 62b9f9ed5e..723a41881d 100644
--- a/readme.md
+++ b/readme.md
@@ -13,12 +13,16 @@ Run build.py:
$ ./build.py
+Windows users should run `build` instead.
+
## Run examples locally
Run the [Plovr](http://plovr.com/) web server with:
$ ./build.py serve
+Windows users should run `build serve` instead.
+
Then, either open one of the example html files from the `examples` directory directly in your browser, or start a simple webserver, for example:
$ python -mSimpleHTTPServer
diff --git a/src/objectliterals.exports b/src/objectliterals.exports
index bbd66ec223..cf5e830f3f 100644
--- a/src/objectliterals.exports
+++ b/src/objectliterals.exports
@@ -1,5 +1,5 @@
@exportObjectLiteral ol.MapOptions
-@exportObjectLiteralProperty ol.MapOptions.controls ol.Collection|undefined
+@exportObjectLiteralProperty ol.MapOptions.attributionControl boolean|undefined
@exportObjectLiteralProperty ol.MapOptions.doubleClickZoom boolean|undefined
@exportObjectLiteralProperty ol.MapOptions.dragPan boolean|undefined
@exportObjectLiteralProperty ol.MapOptions.interactions ol.Collection|undefined
@@ -13,6 +13,7 @@
@exportObjectLiteralProperty ol.MapOptions.shiftDragZoom boolean|undefined
@exportObjectLiteralProperty ol.MapOptions.target Element|string
@exportObjectLiteralProperty ol.MapOptions.view ol.IView|undefined
+@exportObjectLiteralProperty ol.MapOptions.zoomControl boolean|undefined
@exportObjectLiteralProperty ol.MapOptions.zoomDelta number|undefined
@exportObjectLiteral ol.View2DOptions
@@ -32,23 +33,23 @@
@exportObjectLiteralProperty ol.animation.BounceOptions.duration number|undefined
@exportObjectLiteralProperty ol.animation.BounceOptions.easing function(number):number|undefined
-@exportObjectLiteral ol.animation.PanFromOptions
-@exportObjectLiteralProperty ol.animation.PanFromOptions.source ol.Coordinate
-@exportObjectLiteralProperty ol.animation.PanFromOptions.start number|undefined
-@exportObjectLiteralProperty ol.animation.PanFromOptions.duration number|undefined
-@exportObjectLiteralProperty ol.animation.PanFromOptions.easing function(number):number|undefined
+@exportObjectLiteral ol.animation.PanOptions
+@exportObjectLiteralProperty ol.animation.PanOptions.source ol.Coordinate
+@exportObjectLiteralProperty ol.animation.PanOptions.start number|undefined
+@exportObjectLiteralProperty ol.animation.PanOptions.duration number|undefined
+@exportObjectLiteralProperty ol.animation.PanOptions.easing function(number):number|undefined
-@exportObjectLiteral ol.animation.SpinOptions
-@exportObjectLiteralProperty ol.animation.SpinOptions.turns number
-@exportObjectLiteralProperty ol.animation.SpinOptions.start number|undefined
-@exportObjectLiteralProperty ol.animation.SpinOptions.duration number|undefined
-@exportObjectLiteralProperty ol.animation.SpinOptions.easing function(number):number|undefined
+@exportObjectLiteral ol.animation.RotateOptions
+@exportObjectLiteralProperty ol.animation.RotateOptions.rotation number
+@exportObjectLiteralProperty ol.animation.RotateOptions.start number|undefined
+@exportObjectLiteralProperty ol.animation.RotateOptions.duration number|undefined
+@exportObjectLiteralProperty ol.animation.RotateOptions.easing function(number):number|undefined
-@exportObjectLiteral ol.animation.ZoomFromOptions
-@exportObjectLiteralProperty ol.animation.ZoomFromOptions.resolution number
-@exportObjectLiteralProperty ol.animation.ZoomFromOptions.start number|undefined
-@exportObjectLiteralProperty ol.animation.ZoomFromOptions.duration number|undefined
-@exportObjectLiteralProperty ol.animation.ZoomFromOptions.easing function(number):number|undefined
+@exportObjectLiteral ol.animation.ZoomOptions
+@exportObjectLiteralProperty ol.animation.ZoomOptions.resolution number
+@exportObjectLiteralProperty ol.animation.ZoomOptions.start number|undefined
+@exportObjectLiteralProperty ol.animation.ZoomOptions.duration number|undefined
+@exportObjectLiteralProperty ol.animation.ZoomOptions.easing function(number):number|undefined
@exportObjectLiteral ol.control.AttributionOptions
@exportObjectLiteralProperty ol.control.AttributionOptions.map ol.Map|undefined
diff --git a/src/ol/animation.exports b/src/ol/animation.exports
index 7286bf8cc3..98207b2e1a 100644
--- a/src/ol/animation.exports
+++ b/src/ol/animation.exports
@@ -1,4 +1,4 @@
@exportSymbol ol.animation
-@exportProperty ol.animation.createBounce
-@exportProperty ol.animation.createPanFrom
-@exportProperty ol.animation.createSpin
+@exportProperty ol.animation.bounce
+@exportProperty ol.animation.pan
+@exportProperty ol.animation.rotate
diff --git a/src/ol/animation.js b/src/ol/animation.js
index feccd87f06..74a7120de2 100644
--- a/src/ol/animation.js
+++ b/src/ol/animation.js
@@ -12,7 +12,7 @@ goog.require('ol.easing');
* @param {ol.animation.BounceOptions} options Options.
* @return {ol.PreRenderFunction} Pre-render function.
*/
-ol.animation.createBounce = function(options) {
+ol.animation.bounce = function(options) {
var resolution = options.resolution;
var start = goog.isDef(options.start) ? options.start : goog.now();
var duration = goog.isDef(options.duration) ? options.duration : 1000;
@@ -38,10 +38,10 @@ ol.animation.createBounce = function(options) {
/**
- * @param {ol.animation.PanFromOptions} options Options.
+ * @param {ol.animation.PanOptions} options Options.
* @return {ol.PreRenderFunction} Pre-render function.
*/
-ol.animation.createPanFrom = function(options) {
+ol.animation.pan = function(options) {
var source = options.source;
var start = goog.isDef(options.start) ? options.start : goog.now();
var sourceX = source.x;
@@ -71,15 +71,15 @@ ol.animation.createPanFrom = function(options) {
/**
- * @param {ol.animation.SpinOptions} options Options.
+ * @param {ol.animation.RotateOptions} options Options.
* @return {ol.PreRenderFunction} Pre-render function.
*/
-ol.animation.createSpin = function(options) {
+ol.animation.rotate = function(options) {
+ var sourceRotation = options.rotation;
var start = goog.isDef(options.start) ? options.start : goog.now();
var duration = goog.isDef(options.duration) ? options.duration : 1000;
var easing = goog.isDef(options.easing) ?
options.easing : goog.fx.easing.inAndOut;
- var deltaTheta = 2 * options.turns * Math.PI;
return function(map, frameState) {
if (frameState.time < start) {
@@ -87,9 +87,11 @@ ol.animation.createSpin = function(options) {
frameState.viewHints[ol.ViewHint.ANIMATING] += 1;
return true;
} else if (frameState.time < start + duration) {
- var delta = easing((frameState.time - start) / duration);
+ var delta = 1 - easing((frameState.time - start) / duration);
+ var deltaRotation =
+ sourceRotation - frameState.view2DState.rotation;
frameState.animate = true;
- frameState.view2DState.rotation += delta * deltaTheta;
+ frameState.view2DState.rotation += delta * deltaRotation;
frameState.viewHints[ol.ViewHint.ANIMATING] += 1;
return true;
} else {
@@ -100,10 +102,10 @@ ol.animation.createSpin = function(options) {
/**
- * @param {ol.animation.ZoomFromOptions} options Options.
+ * @param {ol.animation.ZoomOptions} options Options.
* @return {ol.PreRenderFunction} Pre-render function.
*/
-ol.animation.createZoomFrom = function(options) {
+ol.animation.zoom = function(options) {
var sourceResolution = options.resolution;
var start = goog.isDef(options.start) ? options.start : goog.now();
var duration = goog.isDef(options.duration) ? options.duration : 1000;
diff --git a/src/ol/control/attribution.exports b/src/ol/control/attribution.exports
index 961219fc9d..57e5bdb9d8 100644
--- a/src/ol/control/attribution.exports
+++ b/src/ol/control/attribution.exports
@@ -1,2 +1,3 @@
@exportClass ol.control.Attribution ol.control.AttributionOptions
+@exportProperty ol.control.Attribution.prototype.setMap
diff --git a/src/ol/control/mouseposition.exports b/src/ol/control/mouseposition.exports
index 7a4856fcb5..e29f9caa13 100644
--- a/src/ol/control/mouseposition.exports
+++ b/src/ol/control/mouseposition.exports
@@ -1,2 +1,3 @@
@exportClass ol.control.MousePosition ol.control.MousePositionOptions
+@exportProperty ol.control.MousePosition.prototype.setMap
diff --git a/src/ol/control/zoom.exports b/src/ol/control/zoom.exports
index 1a1835cffb..91cb9a7fbe 100644
--- a/src/ol/control/zoom.exports
+++ b/src/ol/control/zoom.exports
@@ -1,2 +1,2 @@
@exportClass ol.control.Zoom ol.control.ZoomOptions
-
+@exportProperty ol.control.Zoom.prototype.setMap
diff --git a/src/ol/framestate.js b/src/ol/framestate.js
index bbe89d10a0..9e45ce99b6 100644
--- a/src/ol/framestate.js
+++ b/src/ol/framestate.js
@@ -31,7 +31,7 @@ goog.require('ol.layer.LayerState');
* usedTiles: Object.
>,
* view2DState: ol.View2DState,
* viewHints: Array.,
- * wantedTiles: Object.>}}
+ * wantedTiles: Object.>}}
*/
ol.FrameState;
diff --git a/src/ol/geolocation.exports b/src/ol/geolocation.exports
new file mode 100644
index 0000000000..adc26edc01
--- /dev/null
+++ b/src/ol/geolocation.exports
@@ -0,0 +1 @@
+@exportSymbol ol.Geolocation
diff --git a/src/ol/geolocation.js b/src/ol/geolocation.js
new file mode 100644
index 0000000000..b75aaaf38c
--- /dev/null
+++ b/src/ol/geolocation.js
@@ -0,0 +1,168 @@
+// FIXME handle geolocation not supported
+// FIXME handle geolocation errors
+
+goog.provide('ol.Geolocation');
+goog.provide('ol.GeolocationProperty');
+
+goog.require('goog.functions');
+goog.require('ol.Coordinate');
+goog.require('ol.Object');
+goog.require('ol.Projection');
+
+
+/**
+ * @enum {string}
+ */
+ol.GeolocationProperty = {
+ ACCURACY: 'accuracy',
+ POSITION: 'position',
+ PROJECTION: 'projection'
+};
+
+
+
+/**
+ * @constructor
+ * @extends {ol.Object}
+ * @param {GeolocationPositionOptions=} opt_positionOptions PositionOptions.
+ */
+ol.Geolocation = function(opt_positionOptions) {
+
+ goog.base(this);
+
+ /**
+ * The unprojected (EPSG:4326) device position.
+ * @private
+ * @type {ol.Coordinate}
+ */
+ this.position_ = null;
+
+ if (ol.Geolocation.isSupported) {
+ goog.events.listen(
+ this, ol.Object.getChangedEventType(ol.GeolocationProperty.PROJECTION),
+ this.handleProjectionChanged_, false, this);
+
+ /**
+ * @private
+ * @type {number}
+ */
+ this.watchId_ = navigator.geolocation.watchPosition(
+ goog.bind(this.positionChange_, this),
+ goog.bind(this.positionError_, this),
+ opt_positionOptions);
+ }
+};
+goog.inherits(ol.Geolocation, ol.Object);
+
+
+/**
+ * @inheritDoc
+ */
+ol.Geolocation.prototype.disposeInternal = function() {
+ navigator.geolocation.clearWatch(this.watchId_);
+ goog.base(this, 'disposeInternal');
+};
+
+
+/**
+ * @private
+ */
+ol.Geolocation.prototype.handleProjectionChanged_ = function() {
+ var projection = this.getProjection();
+ if (goog.isDefAndNotNull(projection)) {
+ this.transformCoords_ = ol.Projection.getTransform(
+ ol.Projection.getFromCode('EPSG:4326'), projection);
+ if (!goog.isNull(this.position_)) {
+ this.set(ol.GeolocationProperty.POSITION,
+ this.transformCoords_(this.position_));
+ }
+ }
+};
+
+
+/**
+ * @type {boolean} Is supported.
+ */
+ol.Geolocation.isSupported = 'geolocation' in navigator;
+
+
+/**
+ * @private
+ * @param {GeolocationPosition} position position event.
+ */
+ol.Geolocation.prototype.positionChange_ = function(position) {
+ var coords = position.coords;
+ this.position_ = new ol.Coordinate(coords.longitude, coords.latitude);
+ this.set(ol.GeolocationProperty.POSITION,
+ this.transformCoords_(this.position_));
+ this.set(ol.GeolocationProperty.ACCURACY, coords.accuracy);
+};
+
+
+/**
+ * @private
+ * @param {GeolocationPositionError} error error object.
+ */
+ol.Geolocation.prototype.positionError_ = function(error) {
+};
+
+
+/**
+ * The position of the device.
+ * @return {ol.Coordinate|undefined} position.
+ */
+ol.Geolocation.prototype.getPosition = function() {
+ return /** @type {ol.Coordinate} */ (
+ this.get(ol.GeolocationProperty.POSITION));
+};
+goog.exportProperty(
+ ol.Geolocation.prototype,
+ 'getPosition',
+ ol.Geolocation.prototype.getPosition);
+
+
+/**
+ * The accuracy of the position in meters.
+ * @return {number|undefined} accuracy.
+ */
+ol.Geolocation.prototype.getAccuracy = function() {
+ return /** @type {number} */ (
+ this.get(ol.GeolocationProperty.ACCURACY));
+};
+goog.exportProperty(
+ ol.Geolocation.prototype,
+ 'getAccuracy',
+ ol.Geolocation.prototype.getAccuracy);
+
+
+/**
+ * @return {ol.Projection|undefined} projection.
+ */
+ol.Geolocation.prototype.getProjection = function() {
+ return /** @type {ol.Projection} */ (
+ this.get(ol.GeolocationProperty.PROJECTION));
+};
+goog.exportProperty(
+ ol.Geolocation.prototype,
+ 'getProjection',
+ ol.Geolocation.prototype.getProjection);
+
+
+/**
+ * @param {ol.Projection} projection Projection.
+ */
+ol.Geolocation.prototype.setProjection = function(projection) {
+ this.set(ol.GeolocationProperty.PROJECTION, projection);
+};
+goog.exportProperty(
+ ol.Geolocation.prototype,
+ 'setProjection',
+ ol.Geolocation.prototype.setProjection);
+
+
+/**
+ * @private
+ * @param {ol.Coordinate} coordinate Coordinate.
+ * @return {ol.Coordinate} Coordinate.
+ */
+ol.Geolocation.prototype.transformCoords_ = goog.functions.identity;
diff --git a/src/ol/interaction/dragpaninteraction.js b/src/ol/interaction/dragpaninteraction.js
index 6cca9a096d..e7228f8cf6 100644
--- a/src/ol/interaction/dragpaninteraction.js
+++ b/src/ol/interaction/dragpaninteraction.js
@@ -51,7 +51,9 @@ goog.inherits(ol.interaction.DragPan, ol.interaction.Drag);
*/
ol.interaction.DragPan.prototype.handleDrag = function(mapBrowserEvent) {
if (this.kinetic_) {
- this.kinetic_.update(mapBrowserEvent.browserEvent);
+ this.kinetic_.update(
+ mapBrowserEvent.browserEvent.clientX,
+ mapBrowserEvent.browserEvent.clientY);
}
var map = mapBrowserEvent.map;
// FIXME works for View2D only
@@ -84,7 +86,7 @@ ol.interaction.DragPan.prototype.handleDragEnd = function(mapBrowserEvent) {
var distance = this.kinetic_.getDistance();
var angle = this.kinetic_.getAngle();
var center = view.getCenter();
- this.kineticPreRenderFn_ = this.kinetic_.createPanFrom(center);
+ this.kineticPreRenderFn_ = this.kinetic_.pan(center);
map.addPreRenderFunction(this.kineticPreRenderFn_);
var centerpx = map.getPixelFromCoordinate(center);
@@ -104,7 +106,7 @@ ol.interaction.DragPan.prototype.handleDragStart = function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
if (this.condition_(browserEvent)) {
if (this.kinetic_) {
- this.kinetic_.begin(browserEvent);
+ this.kinetic_.begin(browserEvent.clientX, browserEvent.clientY);
}
var map = mapBrowserEvent.map;
map.requestRenderFrame();
diff --git a/src/ol/interaction/dragrotateandzoominteraction.js b/src/ol/interaction/dragrotateandzoominteraction.js
index 95df6f5320..9cc3ab89ca 100644
--- a/src/ol/interaction/dragrotateandzoominteraction.js
+++ b/src/ol/interaction/dragrotateandzoominteraction.js
@@ -79,7 +79,7 @@ ol.interaction.DragRotateAndZoom.prototype.handleDragStart =
browserEvent.offsetX - size.width / 2,
size.height / 2 - browserEvent.offsetY);
var theta = Math.atan2(delta.y, delta.x);
- this.startRotation_ = (view.getRotation() || 0) + theta;
+ this.startRotation_ = view.getRotation() + theta;
this.startRatio_ = resolution / delta.magnitude();
map.requestRenderFrame();
return true;
diff --git a/src/ol/interaction/dragrotateinteraction.js b/src/ol/interaction/dragrotateinteraction.js
index f951f6fd2c..048a847957 100644
--- a/src/ol/interaction/dragrotateinteraction.js
+++ b/src/ol/interaction/dragrotateinteraction.js
@@ -67,7 +67,7 @@ ol.interaction.DragRotate.prototype.handleDragStart =
var theta = Math.atan2(
size.height / 2 - offset.y,
offset.x - size.width / 2);
- this.startRotation_ = (view.getRotation() || 0) + theta;
+ this.startRotation_ = view.getRotation() + theta;
return true;
} else {
return false;
diff --git a/src/ol/kinetic.js b/src/ol/kinetic.js
index 5be0754ead..31fcb8b9aa 100644
--- a/src/ol/kinetic.js
+++ b/src/ol/kinetic.js
@@ -63,23 +63,25 @@ ol.Kinetic = function(decay, minVelocity, delay) {
/**
- * @param {goog.events.BrowserEvent} browserEvent Browser event.
+ * @param {number} x X.
+ * @param {number} y Y.
*/
-ol.Kinetic.prototype.begin = function(browserEvent) {
+ol.Kinetic.prototype.begin = function(x, y) {
this.points_.length = 0;
this.angle_ = 0;
this.initialVelocity_ = 0;
- this.update(browserEvent);
+ this.update(x, y);
};
/**
- * @param {goog.events.BrowserEvent} browserEvent Browser event.
+ * @param {number} x X.
+ * @param {number} y Y.
*/
-ol.Kinetic.prototype.update = function(browserEvent) {
+ol.Kinetic.prototype.update = function(x, y) {
this.points_.push({
- x: browserEvent.clientX,
- y: browserEvent.clientY,
+ x: x,
+ y: y,
t: goog.now()
});
};
@@ -112,7 +114,7 @@ ol.Kinetic.prototype.end = function() {
* @param {ol.Coordinate} source Source coordinate for the animation.
* @return {ol.PreRenderFunction} Pre-render function for kinetic animation.
*/
-ol.Kinetic.prototype.createPanFrom = function(source) {
+ol.Kinetic.prototype.pan = function(source) {
var decay = this.decay_;
var initialVelocity = this.initialVelocity_;
var minVelocity = this.minVelocity_;
@@ -121,7 +123,7 @@ ol.Kinetic.prototype.createPanFrom = function(source) {
return initialVelocity * (Math.exp((decay * t) * duration) - 1) /
(minVelocity - initialVelocity);
};
- return ol.animation.createPanFrom({
+ return ol.animation.pan({
source: source,
duration: duration,
easing: easingFunction
diff --git a/src/ol/map.exports b/src/ol/map.exports
index 8c4285f1c3..96ee6e3e29 100644
--- a/src/ol/map.exports
+++ b/src/ol/map.exports
@@ -1,7 +1,6 @@
@exportClass ol.Map ol.MapOptions
@exportProperty ol.Map.prototype.addPreRenderFunction
@exportProperty ol.Map.prototype.addPreRenderFunctions
-@exportProperty ol.Map.prototype.getControls
@exportProperty ol.Map.prototype.getInteractions
@exportSymbol ol.RendererHint
diff --git a/src/ol/map.js b/src/ol/map.js
index 58925d8443..9d391c90d5 100644
--- a/src/ol/map.js
+++ b/src/ol/map.js
@@ -22,8 +22,6 @@ goog.require('goog.events.MouseWheelHandler');
goog.require('goog.events.MouseWheelHandler.EventType');
goog.require('ol.BrowserFeature');
goog.require('ol.Collection');
-goog.require('ol.CollectionEvent');
-goog.require('ol.CollectionEventType');
goog.require('ol.Color');
goog.require('ol.Coordinate');
goog.require('ol.Extent');
@@ -230,17 +228,6 @@ ol.Map = function(mapOptions) {
this.handleBrowserEvent, false, this);
this.registerDisposable(mouseWheelHandler);
- /**
- * @type {ol.Collection}
- * @private
- */
- this.controls_ = mapOptionsInternal.controls;
-
- goog.events.listen(this.controls_, ol.CollectionEventType.ADD,
- this.handleControlsAdd_, false, this);
- goog.events.listen(this.controls_, ol.CollectionEventType.REMOVE,
- this.handleControlsRemove_, false, this);
-
/**
* @type {ol.Collection}
* @private
@@ -299,7 +286,9 @@ ol.Map = function(mapOptions) {
// this gives the map an initial size
this.handleBrowserWindowResize();
- this.controls_.forEach(
+ /** @type {Array.} */
+ var controls = mapOptionsInternal.controls;
+ goog.array.forEach(controls,
/**
* @param {ol.control.Control} control Control.
*/
@@ -387,14 +376,6 @@ ol.Map.prototype.getTarget = function() {
};
-/**
- * @return {ol.Collection} Controls.
- */
-ol.Map.prototype.getControls = function() {
- return this.controls_;
-};
-
-
/**
* @param {ol.Pixel} pixel Pixel.
* @return {ol.Coordinate} Coordinate.
@@ -500,9 +481,8 @@ ol.Map.prototype.getTilePriority = function(tile, tileSourceKey, tileCenter) {
if (goog.isNull(frameState) || !(tileSourceKey in frameState.wantedTiles)) {
return ol.TileQueue.DROP;
}
- var zKey = tile.tileCoord.z.toString();
- if (!(zKey in frameState.wantedTiles[tileSourceKey]) ||
- !frameState.wantedTiles[tileSourceKey][zKey].contains(tile.tileCoord)) {
+ var coordKey = tile.tileCoord.toString();
+ if (!frameState.wantedTiles[tileSourceKey][coordKey]) {
return ol.TileQueue.DROP;
}
var center = frameState.view2DState.center;
@@ -523,26 +503,6 @@ ol.Map.prototype.handleBrowserEvent = function(browserEvent, opt_type) {
};
-/**
- * @param {ol.CollectionEvent} collectionEvent Collection event.
- * @private
- */
-ol.Map.prototype.handleControlsAdd_ = function(collectionEvent) {
- var control = /** @type {ol.control.Control} */ (collectionEvent.elem);
- control.setMap(this);
-};
-
-
-/**
- * @param {ol.CollectionEvent} collectionEvent Collection event.
- * @private
- */
-ol.Map.prototype.handleControlsRemove_ = function(collectionEvent) {
- var control = /** @type {ol.control.Control} */ (collectionEvent.elem);
- control.setMap(null);
-};
-
-
/**
* @param {ol.MapBrowserEvent} mapBrowserEvent The event to handle.
*/
@@ -754,8 +714,8 @@ ol.Map.prototype.renderFrame_ = function(time) {
frameState.extent = ol.Extent.boundingExtent.apply(null, corners);
}
- this.renderer_.renderFrame(frameState);
this.frameState_ = frameState;
+ this.renderer_.renderFrame(frameState);
this.dirty_ = false;
if (!goog.isNull(frameState)) {
@@ -849,7 +809,7 @@ ol.Map.prototype.withFrozenRendering = function(f, opt_obj) {
/**
- * @typedef {{controls: ol.Collection,
+ * @typedef {{controls: Array.,
* interactions: ol.Collection,
* rendererConstructor:
* function(new: ol.renderer.Map, Element, ol.Map),
@@ -915,14 +875,9 @@ ol.Map.createOptionsInternal = function(mapOptions) {
}
/**
- * @type {ol.Collection}
+ * @type {Array.}
*/
- var controls;
- if (goog.isDef(mapOptions.controls)) {
- controls = mapOptions.controls;
- } else {
- controls = ol.Map.createControls_(mapOptions);
- }
+ var controls = ol.Map.createControls_(mapOptions);
/**
* @type {ol.Collection}
@@ -953,22 +908,29 @@ ol.Map.createOptionsInternal = function(mapOptions) {
/**
* @private
* @param {ol.MapOptions} mapOptions Map options.
- * @return {ol.Collection} Controls.
+ * @return {Array.} Controls.
*/
ol.Map.createControls_ = function(mapOptions) {
+ /** @type {Array.} */
+ var controls = [];
- var controls = new ol.Collection();
+ var attributionControl = goog.isDef(mapOptions.attributionControl) ?
+ mapOptions.attributionControl : true;
+ if (attributionControl) {
+ controls.push(new ol.control.Attribution({}));
+ }
- controls.push(new ol.control.Attribution({}));
-
- var zoomDelta = goog.isDef(mapOptions.zoomDelta) ?
- mapOptions.zoomDelta : 4;
- controls.push(new ol.control.Zoom({
- delta: zoomDelta
- }));
+ var zoomControl = goog.isDef(mapOptions.zoomControl) ?
+ mapOptions.zoomControl : true;
+ if (zoomControl) {
+ var zoomDelta = goog.isDef(mapOptions.zoomDelta) ?
+ mapOptions.zoomDelta : 4;
+ controls.push(new ol.control.Zoom({
+ delta: zoomDelta
+ }));
+ }
return controls;
-
};
diff --git a/src/ol/renderer/canvas/canvastilelayerrenderer.js b/src/ol/renderer/canvas/canvastilelayerrenderer.js
index 59b0c6051c..02e5e904ff 100644
--- a/src/ol/renderer/canvas/canvastilelayerrenderer.js
+++ b/src/ol/renderer/canvas/canvastilelayerrenderer.js
@@ -167,6 +167,9 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame =
tileState = tile.getState();
if (tileState == ol.TileState.IDLE) {
+ goog.events.listenOnce(tile, goog.events.EventType.CHANGE,
+ this.handleTileChange, false, this);
+ this.updateWantedTiles(frameState.wantedTiles, tileSource, tileCoord);
tileCenter = tileGrid.getTileCoordCenter(tileCoord);
frameState.tileQueue.enqueue(tile, tileSourceKey, tileCenter);
} else if (tileState == ol.TileState.LOADED) {
@@ -214,11 +217,6 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame =
}
}
- if (!allTilesLoaded) {
- frameState.animate = true;
- this.updateWantedTiles(frameState.wantedTiles, tileSource, z, tileRange);
- }
-
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
this.scheduleExpireCache(frameState, tileSource);
diff --git a/src/ol/renderer/dom/domtilelayerrenderer.js b/src/ol/renderer/dom/domtilelayerrenderer.js
index a92d34a0d2..094d6a3009 100644
--- a/src/ol/renderer/dom/domtilelayerrenderer.js
+++ b/src/ol/renderer/dom/domtilelayerrenderer.js
@@ -131,6 +131,9 @@ ol.renderer.dom.TileLayer.prototype.renderFrame =
tileState = tile.getState();
if (tileState == ol.TileState.IDLE) {
+ goog.events.listenOnce(tile, goog.events.EventType.CHANGE,
+ this.handleTileChange, false, this);
+ this.updateWantedTiles(frameState.wantedTiles, tileSource, tileCoord);
tileCenter = tileGrid.getTileCoordCenter(tileCoord);
frameState.tileQueue.enqueue(tile, tileSourceKey, tileCenter);
} else if (tileState == ol.TileState.LOADED) {
@@ -232,11 +235,6 @@ ol.renderer.dom.TileLayer.prototype.renderFrame =
this.renderedVisible_ = true;
}
- if (!allTilesLoaded) {
- frameState.animate = true;
- this.updateWantedTiles(frameState.wantedTiles, tileSource, z, tileRange);
- }
-
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
this.scheduleExpireCache(frameState, tileSource);
diff --git a/src/ol/renderer/layerrenderer.js b/src/ol/renderer/layerrenderer.js
index 4ff6f66cab..fab64889fc 100644
--- a/src/ol/renderer/layerrenderer.js
+++ b/src/ol/renderer/layerrenderer.js
@@ -4,7 +4,10 @@ goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('ol.FrameState');
goog.require('ol.Object');
+goog.require('ol.Tile');
+goog.require('ol.TileCoord');
goog.require('ol.TileRange');
+goog.require('ol.TileState');
goog.require('ol.layer.Layer');
goog.require('ol.layer.LayerProperty');
goog.require('ol.layer.LayerState');
@@ -146,6 +149,19 @@ ol.renderer.Layer.prototype.handleLayerVisibleChange = function() {
};
+/**
+ * Handle changes in tile state.
+ * @param {goog.events.Event} event Tile change event.
+ * @protected
+ */
+ol.renderer.Layer.prototype.handleTileChange = function(event) {
+ var tile = /** @type {ol.Tile} */ (event.target);
+ if (tile.getState() === ol.TileState.LOADED) {
+ this.getMap().requestRenderFrame();
+ }
+};
+
+
/**
* @param {ol.FrameState} frameState Frame state.
* @param {ol.layer.LayerState} layerState Layer state.
@@ -197,24 +213,16 @@ ol.renderer.Layer.prototype.updateUsedTiles =
/**
* @protected
- * @param {Object.>} wantedTiles Wanted
- * tile ranges.
+ * @param {Object.>} wantedTiles Wanted tiles.
* @param {ol.source.Source} source Source.
- * @param {number} z Z.
- * @param {ol.TileRange} tileRange Tile range.
+ * @param {ol.TileCoord} tileCoord Tile coordinate.
*/
ol.renderer.Layer.prototype.updateWantedTiles =
- function(wantedTiles, source, z, tileRange) {
+ function(wantedTiles, source, tileCoord) {
var sourceKey = goog.getUid(source).toString();
- var zKey = z.toString();
- if (sourceKey in wantedTiles) {
- if (zKey in wantedTiles[sourceKey]) {
- wantedTiles[sourceKey][zKey].extend(tileRange);
- } else {
- wantedTiles[sourceKey][zKey] = tileRange;
- }
- } else {
+ var coordKey = tileCoord.toString();
+ if (!(sourceKey in wantedTiles)) {
wantedTiles[sourceKey] = {};
- wantedTiles[sourceKey][zKey] = tileRange;
}
+ wantedTiles[sourceKey][coordKey] = true;
};
diff --git a/src/ol/renderer/webgl/webgltilelayerrenderer.js b/src/ol/renderer/webgl/webgltilelayerrenderer.js
index 3663948de8..27c0cbadab 100644
--- a/src/ol/renderer/webgl/webgltilelayerrenderer.js
+++ b/src/ol/renderer/webgl/webgltilelayerrenderer.js
@@ -393,6 +393,9 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
tileState = tile.getState();
if (tileState == ol.TileState.IDLE) {
+ goog.events.listenOnce(tile, goog.events.EventType.CHANGE,
+ this.handleTileChange, false, this);
+ this.updateWantedTiles(frameState.wantedTiles, tileSource, tileCoord);
tileCenter = tileGrid.getTileCoordCenter(tileCoord);
frameState.tileQueue.enqueue(tile, tileSourceKey, tileCenter);
} else if (tileState == ol.TileState.LOADED) {
@@ -457,7 +460,6 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
this.renderedTileRange_ = null;
this.renderedFramebufferExtent_ = null;
frameState.animate = true;
- this.updateWantedTiles(frameState.wantedTiles, tileSource, z, tileRange);
}
}
diff --git a/src/ol/structs/lrucache.js b/src/ol/structs/lrucache.js
index ecf53521a6..7792dc2f61 100644
--- a/src/ol/structs/lrucache.js
+++ b/src/ol/structs/lrucache.js
@@ -91,7 +91,7 @@ ol.structs.LRUCache.prototype.clear = function() {
* @return {boolean} Contains key.
*/
ol.structs.LRUCache.prototype.containsKey = function(key) {
- return key in this.entries_;
+ return this.entries_.hasOwnProperty(key);
};
@@ -155,15 +155,6 @@ ol.structs.LRUCache.prototype.getKeys = function() {
};
-/**
- * @return {string} Last key.
- */
-ol.structs.LRUCache.prototype.getLastKey = function() {
- goog.asserts.assert(!goog.isNull(this.newest_));
- return this.newest_.key_;
-};
-
-
/**
* @return {Array} Values.
*/
diff --git a/src/ol/view2d.js b/src/ol/view2d.js
index c1da3c23bc..ca726b99f4 100644
--- a/src/ol/view2d.js
+++ b/src/ol/view2d.js
@@ -298,7 +298,7 @@ ol.View2D.prototype.zoom = function(map, delta, opt_anchor, opt_duration) {
var currentResolution = this.getResolution();
if (goog.isDef(currentResolution) && goog.isDef(opt_duration)) {
map.requestRenderFrame();
- map.addPreRenderFunction(ol.animation.createZoomFrom({
+ map.addPreRenderFunction(ol.animation.zoom({
resolution: currentResolution,
duration: opt_duration
}));
diff --git a/test/spec/ol/lrucache.test.js b/test/spec/ol/lrucache.test.js
index 7ceb8a0115..587724e36a 100644
--- a/test/spec/ol/lrucache.test.js
+++ b/test/spec/ol/lrucache.test.js
@@ -99,11 +99,38 @@ describe('ol.structs.LRUCache', function() {
});
});
- describe('setting a disallowed key', function() {
- it('raises an exception', function() {
+ describe('disallowed keys', function() {
+ it('setting raises an exception', function() {
+ expect(function() {
+ lruCache.set('constructor', 0);
+ }).toThrow();
expect(function() {
lruCache.set('hasOwnProperty', 0);
}).toThrow();
+ expect(function() {
+ lruCache.set('isPrototypeOf', 0);
+ }).toThrow();
+ expect(function() {
+ lruCache.set('propertyIsEnumerable', 0);
+ }).toThrow();
+ expect(function() {
+ lruCache.set('toLocaleString', 0);
+ }).toThrow();
+ expect(function() {
+ lruCache.set('toString', 0);
+ }).toThrow();
+ expect(function() {
+ lruCache.set('valueOf', 0);
+ }).toThrow();
+ });
+ it('getting returns false', function() {
+ expect(lruCache.containsKey('constructor')).toBeFalsy();
+ expect(lruCache.containsKey('hasOwnProperty')).toBeFalsy();
+ expect(lruCache.containsKey('isPrototypeOf')).toBeFalsy();
+ expect(lruCache.containsKey('propertyIsEnumerable')).toBeFalsy();
+ expect(lruCache.containsKey('toLocaleString')).toBeFalsy();
+ expect(lruCache.containsKey('toString')).toBeFalsy();
+ expect(lruCache.containsKey('valueOf')).toBeFalsy();
});
});