From 962ed067173d6c95d50884b876eba7e95587b8a5 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Tue, 14 Jan 2014 17:01:10 +0100 Subject: [PATCH 1/4] Add new 'accuracyGeometry' property to ol.Geolocation --- src/ol/geolocation.js | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/ol/geolocation.js b/src/ol/geolocation.js index cc489b1b9e..e38fd00f4f 100644 --- a/src/ol/geolocation.js +++ b/src/ol/geolocation.js @@ -3,12 +3,14 @@ goog.provide('ol.Geolocation'); goog.provide('ol.GeolocationProperty'); +goog.require('goog.asserts'); goog.require('goog.events'); goog.require('goog.events.EventType'); goog.require('goog.math'); goog.require('ol.BrowserFeature'); goog.require('ol.Coordinate'); goog.require('ol.Object'); +goog.require('ol.geom.Circle'); goog.require('ol.proj'); @@ -17,6 +19,7 @@ goog.require('ol.proj'); */ ol.GeolocationProperty = { ACCURACY: 'accuracy', + ACCURACY_GEOMETRY: 'accuracyGeometry', ALTITUDE: 'altitude', ALTITUDE_ACCURACY: 'altitudeAccuracy', HEADING: 'heading', @@ -50,6 +53,8 @@ ol.GeolocationProperty = { * @todo stability experimental * @todo observable accuracy {number} readonly the accuracy of the position * measurement in meters + * @todo observable accuracyGeometry {ol.geom.Circle} readonly a + * `ol.geom.Circle` geometry of the position accuracy. * @todo observable altitude {number} readonly the altitude of the position in * meters above mean sea level * @todo observable altitudeAccuracy {number} readonly the accuracy of the @@ -176,9 +181,19 @@ ol.Geolocation.prototype.positionChange_ = function(position) { this.position_[0] = coords.longitude; this.position_[1] = coords.latitude; } - this.set(ol.GeolocationProperty.POSITION, this.transform_(this.position_)); + var projectedPosition = this.transform_(this.position_); + this.set(ol.GeolocationProperty.POSITION, projectedPosition); this.set(ol.GeolocationProperty.SPEED, goog.isNull(coords.speed) ? undefined : coords.speed); + + var accuracyGeometry = this.getAccuracyGeometry(); + if (goog.isNull(accuracyGeometry)) { + accuracyGeometry = new ol.geom.Circle(projectedPosition, coords.accuracy); + } else { + goog.asserts.assertInstanceof(accuracyGeometry, ol.geom.Circle); + accuracyGeometry.setCenterAndRadius(projectedPosition, coords.accuracy); + } + this.set(ol.GeolocationProperty.ACCURACY_GEOMETRY, accuracyGeometry); }; @@ -207,6 +222,21 @@ goog.exportProperty( ol.Geolocation.prototype.getAccuracy); +/** + * Get a `ol.geom.Circle` geometry of the position accuracy. + * @return {?ol.geom.Circle} Accuracy geometry. + * @todo stability experimental + */ +ol.Geolocation.prototype.getAccuracyGeometry = function() { + return /** @type {?ol.geom.Circle} */ ( + this.get(ol.GeolocationProperty.ACCURACY_GEOMETRY) || null); +}; +goog.exportProperty( + ol.Geolocation.prototype, + 'getAccuracyGeometry', + ol.Geolocation.prototype.getAccuracyGeometry); + + /** * Get the altitude associated with the position. * @return {number|undefined} The altitude in meters above the mean sea level. From e62842464c9faa609e5972239e5b985dd92e62ef Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Wed, 15 Jan 2014 09:09:47 +0100 Subject: [PATCH 2/4] Use accuracyGeometry in geolocation example --- examples/geolocation.html | 10 ---------- examples/geolocation.js | 35 +++++++++++++++++++---------------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/examples/geolocation.html b/examples/geolocation.html index 8b5ec77a5d..7fecca68de 100644 --- a/examples/geolocation.html +++ b/examples/geolocation.html @@ -8,15 +8,6 @@ - Geolocation example @@ -63,7 +54,6 @@ - diff --git a/examples/geolocation.js b/examples/geolocation.js index 8989dee7f7..675ffcccd6 100644 --- a/examples/geolocation.js +++ b/examples/geolocation.js @@ -2,11 +2,13 @@ // FIXME this circle will need to compensate for the pointResolution of the // FIXME EPSG:3857 projection +goog.require('ol.Feature'); +goog.require('ol.FeatureOverlay'); goog.require('ol.Geolocation'); goog.require('ol.Map'); -goog.require('ol.Overlay'); goog.require('ol.View2D'); goog.require('ol.dom.Input'); +goog.require('ol.geom.Point'); goog.require('ol.layer.Tile'); goog.require('ol.source.OSM'); @@ -22,7 +24,7 @@ var map = new ol.Map({ source: new ol.source.OSM() }) ], - renderer: exampleNS.getRendererFromQueryString(), + renderer: 'canvas', target: 'map', view: view }); @@ -41,22 +43,23 @@ geolocation.on('propertychange', function() { $('#speed').text(geolocation.getSpeed() + ' [m/s]'); }); -var marker = new ol.Overlay({ - element: /** @type {Element} */ ($('').addClass('icon-flag').get(0)), - positioning: 'bottom-left', - stopEvent: false -}); -map.addOverlay(marker); -// bind the marker position to the device location. -marker.bindTo('position', geolocation); - -geolocation.on('change:accuracy', function() { - $(marker.getElement()).tooltip({ - title: this.getAccuracy() + 'm from this point' - }); -}); geolocation.on('error', function(error) { var info = document.getElementById('info'); info.innerHTML = error.message; info.style.display = ''; }); + + +var accuracyFeature = new ol.Feature(); +accuracyFeature.bindTo('geometry', geolocation, 'accuracyGeometry'); + +var positionFeature = new ol.Feature(); +positionFeature.bindTo('geometry', geolocation, 'position') + .transform(function() {}, function(coordinates) { + return coordinates ? new ol.geom.Point(coordinates) : null; + }); + +var featuresOverlay = new ol.FeatureOverlay({ + map: map, + features: [accuracyFeature, positionFeature] +}); From 0c8552edbb864f1c1a8a1cc91ef1fdd7541422bf Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 11 Mar 2014 15:27:10 +0100 Subject: [PATCH 3/4] Add ol.Sphere#circle --- src/ol/sphere/sphere.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/ol/sphere/sphere.js b/src/ol/sphere/sphere.js index 825d843263..d63f8573c2 100644 --- a/src/ol/sphere/sphere.js +++ b/src/ol/sphere/sphere.js @@ -10,7 +10,9 @@ goog.provide('ol.Sphere'); +goog.require('goog.array'); goog.require('goog.math'); +goog.require('ol.geom.Polygon'); @@ -28,6 +30,32 @@ ol.Sphere = function(radius) { }; +/** + * Returns an approximation to a circle centered on `center` with radius + * `radius` with `n` distinct points. + * + * @param {ol.Coordinate} center Center. + * @param {number} radius Radius. + * @param {number=} opt_n N. + * @return {ol.geom.Geometry} Circle geometry. + */ +ol.Sphere.prototype.circle = function(center, radius, opt_n) { + var n = goog.isDef(opt_n) ? opt_n : 32; + /** @type {Array.} */ + var flatCoordinates = []; + var i; + for (i = 0; i < n; ++i) { + goog.array.extend( + flatCoordinates, this.offset(center, radius, 2 * Math.PI * i / n)); + } + flatCoordinates.push(flatCoordinates[0], flatCoordinates[1]); + var polygon = new ol.geom.Polygon(null); + polygon.setFlatCoordinates( + ol.geom.GeometryLayout.XY, flatCoordinates, [flatCoordinates.length]); + return polygon; +}; + + /** * Returns the distance from c1 to c2 using the spherical law of cosines. * From a267ed4e5299fc5cdb24b84de24c142d174f9e2a Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Tue, 11 Mar 2014 15:42:08 +0100 Subject: [PATCH 4/4] Use ol.Sphere#circle to create the accuracy 'circle' --- examples/geolocation.js | 4 ---- src/ol/geolocation.js | 24 ++++++++++-------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/examples/geolocation.js b/examples/geolocation.js index 675ffcccd6..b693c7efc5 100644 --- a/examples/geolocation.js +++ b/examples/geolocation.js @@ -1,7 +1,3 @@ -// FIXME use an ol.geom.Circle to display a circle with accuracy -// FIXME this circle will need to compensate for the pointResolution of the -// FIXME EPSG:3857 projection - goog.require('ol.Feature'); goog.require('ol.FeatureOverlay'); goog.require('ol.Geolocation'); diff --git a/src/ol/geolocation.js b/src/ol/geolocation.js index e38fd00f4f..0a1e621024 100644 --- a/src/ol/geolocation.js +++ b/src/ol/geolocation.js @@ -10,8 +10,9 @@ goog.require('goog.math'); goog.require('ol.BrowserFeature'); goog.require('ol.Coordinate'); goog.require('ol.Object'); -goog.require('ol.geom.Circle'); +goog.require('ol.geom.Geometry'); goog.require('ol.proj'); +goog.require('ol.sphere.WGS84'); /** @@ -53,8 +54,8 @@ ol.GeolocationProperty = { * @todo stability experimental * @todo observable accuracy {number} readonly the accuracy of the position * measurement in meters - * @todo observable accuracyGeometry {ol.geom.Circle} readonly a - * `ol.geom.Circle` geometry of the position accuracy. + * @todo observable accuracyGeometry {ol.geom.Geometry} readonly a + * geometry of the position accuracy. * @todo observable altitude {number} readonly the altitude of the position in * meters above mean sea level * @todo observable altitudeAccuracy {number} readonly the accuracy of the @@ -186,14 +187,9 @@ ol.Geolocation.prototype.positionChange_ = function(position) { this.set(ol.GeolocationProperty.SPEED, goog.isNull(coords.speed) ? undefined : coords.speed); - var accuracyGeometry = this.getAccuracyGeometry(); - if (goog.isNull(accuracyGeometry)) { - accuracyGeometry = new ol.geom.Circle(projectedPosition, coords.accuracy); - } else { - goog.asserts.assertInstanceof(accuracyGeometry, ol.geom.Circle); - accuracyGeometry.setCenterAndRadius(projectedPosition, coords.accuracy); - } - this.set(ol.GeolocationProperty.ACCURACY_GEOMETRY, accuracyGeometry); + var geometry = ol.sphere.WGS84.circle(this.position_, coords.accuracy); + geometry.transform(this.transform_); + this.set(ol.GeolocationProperty.ACCURACY_GEOMETRY, geometry); }; @@ -223,12 +219,12 @@ goog.exportProperty( /** - * Get a `ol.geom.Circle` geometry of the position accuracy. - * @return {?ol.geom.Circle} Accuracy geometry. + * Get a geometry of the position accuracy. + * @return {?ol.geom.Geometry} Accuracy geometry. * @todo stability experimental */ ol.Geolocation.prototype.getAccuracyGeometry = function() { - return /** @type {?ol.geom.Circle} */ ( + return /** @type {?ol.geom.Geometry} */ ( this.get(ol.GeolocationProperty.ACCURACY_GEOMETRY) || null); }; goog.exportProperty(