From 035f487dc586ffdf1d05828848b95f3a54199deb Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Fri, 1 Feb 2013 08:56:55 +0100 Subject: [PATCH 1/9] Add ol.Geolocation --- src/ol/geolocation.js | 100 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/ol/geolocation.js diff --git a/src/ol/geolocation.js b/src/ol/geolocation.js new file mode 100644 index 0000000000..d432e45fbb --- /dev/null +++ b/src/ol/geolocation.js @@ -0,0 +1,100 @@ +// FIXME: handle errors ? + +goog.provide('ol.Geolocation'); +goog.provide('ol.GeolocationProperty'); + +goog.require('ol.Coordinate'); +goog.require('ol.Object'); +goog.require('ol.Projection'); + + +/** + * @enum {string} + */ +ol.GeolocationProperty = { + ACCURACY: 'accuracy', + POSITION: 'position' +}; + + + +/** + * @constructor + * @extends {ol.Object} + * @param {ol.Projection} projection Projection. + * @param {GeolocationPositionOptions=} opt_positionOptions PositionOptions. + */ +ol.Geolocation = function(projection, opt_positionOptions) { + + goog.base(this); + + this.transformCoords_ = ol.Projection.getTransform( + ol.Projection.getFromCode('EPSG:4326'), projection); + + /** + * @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 + * @param {GeolocationPosition} position position event. + */ +ol.Geolocation.prototype.positionChange_ = function(position) { + var coords = position.coords; + var coord = new ol.Coordinate(coords.longitude, coords.latitude); + this.set(ol.GeolocationProperty.POSITION, this.transformCoords_(coord)); + 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} 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} accuracy. + */ +ol.Geolocation.prototype.getAccuracy = function() { + return /** @type {number} */ ( + this.get(ol.GeolocationProperty.ACCURACY)); +}; +goog.exportProperty( + ol.Geolocation.prototype, + 'getAccuracy', + ol.Geolocation.prototype.getAccuracy); From 37e172f0435bac63faa2e147153cce986351c9da Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Fri, 1 Feb 2013 12:01:48 +0100 Subject: [PATCH 2/9] Add missing export file for ol.Geolocation --- src/ol/geolocation.exports | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/ol/geolocation.exports 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 From 38f245c5c8ee25190c080a73370b880a439d4ceb Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Fri, 1 Feb 2013 13:53:55 +0100 Subject: [PATCH 3/9] Add projection property to ol.Geolocation --- src/ol/geolocation.js | 44 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/ol/geolocation.js b/src/ol/geolocation.js index d432e45fbb..e3cca58e5b 100644 --- a/src/ol/geolocation.js +++ b/src/ol/geolocation.js @@ -13,7 +13,8 @@ goog.require('ol.Projection'); */ ol.GeolocationProperty = { ACCURACY: 'accuracy', - POSITION: 'position' + POSITION: 'position', + PROJECTION: 'projection' }; @@ -21,15 +22,14 @@ ol.GeolocationProperty = { /** * @constructor * @extends {ol.Object} - * @param {ol.Projection} projection Projection. * @param {GeolocationPositionOptions=} opt_positionOptions PositionOptions. */ -ol.Geolocation = function(projection, opt_positionOptions) { +ol.Geolocation = function(opt_positionOptions) { goog.base(this); - this.transformCoords_ = ol.Projection.getTransform( - ol.Projection.getFromCode('EPSG:4326'), projection); + // set the default projection + this.setProjection(ol.Projection.getFromCode('EPSG:4326')); /** * @private @@ -98,3 +98,37 @@ goog.exportProperty( ol.Geolocation.prototype, 'getAccuracy', ol.Geolocation.prototype.getAccuracy); + + +/** + * @return {ol.Projection} 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); + + this.transformCoords_ = ol.Projection.getTransform( + ol.Projection.getFromCode('EPSG:4326'), projection); +}; +goog.exportProperty( + ol.Geolocation.prototype, + 'setProjection', + ol.Geolocation.prototype.setProjection); + + +/** + * @private + */ +ol.Geolocation.prototype.transformCoords_ = goog.functions.identity; From 6675de437fb89b29ccbf4a6f990b0c44333402aa Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 4 Feb 2013 09:46:31 +0100 Subject: [PATCH 4/9] Handle projection change in ol.Geolocation --- src/ol/geolocation.js | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/ol/geolocation.js b/src/ol/geolocation.js index e3cca58e5b..1816b89849 100644 --- a/src/ol/geolocation.js +++ b/src/ol/geolocation.js @@ -3,6 +3,7 @@ goog.provide('ol.Geolocation'); goog.provide('ol.GeolocationProperty'); +goog.require('goog.functions'); goog.require('ol.Coordinate'); goog.require('ol.Object'); goog.require('ol.Projection'); @@ -28,8 +29,16 @@ ol.Geolocation = function(opt_positionOptions) { goog.base(this); - // set the default projection - this.setProjection(ol.Projection.getFromCode('EPSG:4326')); + /** + * The unprojected (EPSG:4326) device position. + * @private + * @type {ol.Coordinate} + */ + this.position_ = null; + + goog.events.listen( + this, ol.Object.getChangedEventType(ol.GeolocationProperty.PROJECTION), + this.handleProjectionChanged, false, this); /** * @private @@ -52,14 +61,28 @@ ol.Geolocation.prototype.disposeInternal = function() { }; +/** + * @protected + */ +ol.Geolocation.prototype.handleProjectionChanged = function() { + this.transformCoords_ = ol.Projection.getTransform( + ol.Projection.getFromCode('EPSG:4326'), this.getProjection()); + if (!goog.isNull(this.position_)) { + this.set(ol.GeolocationProperty.POSITION, + this.transformCoords_(this.position_)); + } +}; + + /** * @private * @param {GeolocationPosition} position position event. */ ol.Geolocation.prototype.positionChange_ = function(position) { var coords = position.coords; - var coord = new ol.Coordinate(coords.longitude, coords.latitude); - this.set(ol.GeolocationProperty.POSITION, this.transformCoords_(coord)); + 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); }; @@ -118,9 +141,6 @@ goog.exportProperty( */ ol.Geolocation.prototype.setProjection = function(projection) { this.set(ol.GeolocationProperty.PROJECTION, projection); - - this.transformCoords_ = ol.Projection.getTransform( - ol.Projection.getFromCode('EPSG:4326'), projection); }; goog.exportProperty( ol.Geolocation.prototype, @@ -130,5 +150,7 @@ goog.exportProperty( /** * @private + * @param {ol.Coordinate} coordinate Coordinate. + * @return {ol.Coordinate} Coordinate. */ ol.Geolocation.prototype.transformCoords_ = goog.functions.identity; From 114280e60e1bc2c042bf596bd293b2f9b8932fe3 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 4 Feb 2013 10:52:29 +0100 Subject: [PATCH 5/9] Add a marker at the device position --- examples/full-screen.html | 7 +++++++ examples/full-screen.js | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/examples/full-screen.html b/examples/full-screen.html index 53db08f8af..11a3d5d560 100644 --- a/examples/full-screen.html +++ b/examples/full-screen.html @@ -21,6 +21,12 @@ padding: 0 0.5em 0.5em 0.5em; border-radius: 4px; } + #geolocation { + background-color: white; + border: 1px solid #222; + border-radius: 10px 10px 10px 0; + padding: 3px; + } @media only screen and (max-width: 600px) { #text { display: none; @@ -31,6 +37,7 @@
+

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); From a679bb7bef570ceae3e139353edb74b508c8955e Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 6 Feb 2013 10:59:18 +0100 Subject: [PATCH 6/9] Set handleProjectionChanged from protected to private --- src/ol/geolocation.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ol/geolocation.js b/src/ol/geolocation.js index 1816b89849..7e4a9ed667 100644 --- a/src/ol/geolocation.js +++ b/src/ol/geolocation.js @@ -38,7 +38,7 @@ ol.Geolocation = function(opt_positionOptions) { goog.events.listen( this, ol.Object.getChangedEventType(ol.GeolocationProperty.PROJECTION), - this.handleProjectionChanged, false, this); + this.handleProjectionChanged_, false, this); /** * @private @@ -62,9 +62,9 @@ ol.Geolocation.prototype.disposeInternal = function() { /** - * @protected + * @private */ -ol.Geolocation.prototype.handleProjectionChanged = function() { +ol.Geolocation.prototype.handleProjectionChanged_ = function() { this.transformCoords_ = ol.Projection.getTransform( ol.Projection.getFromCode('EPSG:4326'), this.getProjection()); if (!goog.isNull(this.position_)) { From 753b37ad479f93b2f42b00d792aeda9b2388b8bc Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 6 Feb 2013 11:00:55 +0100 Subject: [PATCH 7/9] Add 'undefined' return type for all get* functions --- src/ol/geolocation.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/ol/geolocation.js b/src/ol/geolocation.js index 7e4a9ed667..de6b291290 100644 --- a/src/ol/geolocation.js +++ b/src/ol/geolocation.js @@ -65,11 +65,14 @@ ol.Geolocation.prototype.disposeInternal = function() { * @private */ ol.Geolocation.prototype.handleProjectionChanged_ = function() { - this.transformCoords_ = ol.Projection.getTransform( - ol.Projection.getFromCode('EPSG:4326'), this.getProjection()); - if (!goog.isNull(this.position_)) { - this.set(ol.GeolocationProperty.POSITION, - this.transformCoords_(this.position_)); + 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_)); + } } }; @@ -97,7 +100,7 @@ ol.Geolocation.prototype.positionError_ = function(error) { /** * The position of the device. - * @return {ol.Coordinate} position. + * @return {ol.Coordinate|undefined} position. */ ol.Geolocation.prototype.getPosition = function() { return /** @type {ol.Coordinate} */ ( @@ -111,7 +114,7 @@ goog.exportProperty( /** * The accuracy of the position in meters. - * @return {number} accuracy. + * @return {number|undefined} accuracy. */ ol.Geolocation.prototype.getAccuracy = function() { return /** @type {number} */ ( @@ -124,7 +127,7 @@ goog.exportProperty( /** - * @return {ol.Projection} projection. + * @return {ol.Projection|undefined} projection. */ ol.Geolocation.prototype.getProjection = function() { return /** @type {ol.Projection} */ ( From 44a5eca4375435943f488e82e9a121668f9095d3 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 7 Feb 2013 15:59:12 +0100 Subject: [PATCH 8/9] Add ol.Geolocation.isSupported property --- src/ol/geolocation.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ol/geolocation.js b/src/ol/geolocation.js index de6b291290..eab663b2fa 100644 --- a/src/ol/geolocation.js +++ b/src/ol/geolocation.js @@ -77,6 +77,12 @@ ol.Geolocation.prototype.handleProjectionChanged_ = function() { }; +/** + * @type {boolean} Is supported. + */ +ol.Geolocation.isSupported = 'geolocation' in navigator; + + /** * @private * @param {GeolocationPosition} position position event. From a36145fc1ff4544aa867d2928c27fea7d9d2fd7a Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 7 Feb 2013 16:20:15 +0100 Subject: [PATCH 9/9] Check if the Geolocation API is supported --- src/ol/geolocation.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/ol/geolocation.js b/src/ol/geolocation.js index eab663b2fa..b75aaaf38c 100644 --- a/src/ol/geolocation.js +++ b/src/ol/geolocation.js @@ -1,4 +1,5 @@ -// FIXME: handle errors ? +// FIXME handle geolocation not supported +// FIXME handle geolocation errors goog.provide('ol.Geolocation'); goog.provide('ol.GeolocationProperty'); @@ -36,18 +37,20 @@ ol.Geolocation = function(opt_positionOptions) { */ this.position_ = null; - goog.events.listen( - this, ol.Object.getChangedEventType(ol.GeolocationProperty.PROJECTION), - this.handleProjectionChanged_, false, this); + 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); + /** + * @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);