diff --git a/examples/geolocation.html b/examples/geolocation.html new file mode 100644 index 0000000000..2a881ed316 --- /dev/null +++ b/examples/geolocation.html @@ -0,0 +1,109 @@ + + + + + OpenLayers Geolocation + + + + + + + +

Geolocation Example

+ +
+ geolocation, geolocate, mobile +
+ +

+ Track current position and display it with its accuracy. +

+ +
+ +
+ +   +
+ + diff --git a/lib/OpenLayers.js b/lib/OpenLayers.js index b73d7a6f6e..1741aa6fd7 100644 --- a/lib/OpenLayers.js +++ b/lib/OpenLayers.js @@ -331,6 +331,7 @@ "OpenLayers/Control/ZoomOut.js", "OpenLayers/Control/ZoomPanel.js", "OpenLayers/Control/EditingToolbar.js", + "OpenLayers/Control/Geolocate.js", "OpenLayers/Symbolizer.js", "OpenLayers/Symbolizer/Point.js", "OpenLayers/Symbolizer/Line.js", diff --git a/lib/OpenLayers/Control/Geolocate.js b/lib/OpenLayers/Control/Geolocate.js new file mode 100644 index 0000000000..d9c0a9ebea --- /dev/null +++ b/lib/OpenLayers/Control/Geolocate.js @@ -0,0 +1,158 @@ +/* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for + * full list of contributors). Published under the Clear BSD license. + * See http://svn.openlayers.org/trunk/openlayers/license.txt for the + * full text of the license. */ + +/** + * @requires OpenLayers/Control.js + * @requires OpenLayers/Geometry/Point.js + * @requires OpenLayers/Projection.js + */ + +/** + * Class: OpenLayers.Control.Geolocate + * The Geolocate control wraps w3c geolocation API into control that can be + * bound to a map, and generate events on location update + * + * To use this control requires to load the proj4js library if the projection + * of the map is not EPSG:4326 or EPSG:900913. + * + * Inherits from: + * - + */ +OpenLayers.Control.Geolocate = OpenLayers.Class(OpenLayers.Control, { + + /** + * Constant: EVENT_TYPES + * Supported event types: + * - *locationupdated* Triggered when browser return a new position + * - *locationfailed* Triggered when geolocation has failed + * - *locationuncapable* Triggered when control is activated on a browser + * which doesn't support geolocation + */ + EVENT_TYPES: ["locationupdated", "locationfailed", "locationuncapable"], + + /** + * Property: geolocation + * {Object} The geolocation engine, as a property to be possibly mocked. + */ + geolocation: navigator.geolocation, + + /** + * APIProperty: bind + * {Boolean} If true, map center will be set on location update. + */ + bind: true, + + /** + * APIProperty: watch + * {Boolean} If true, position will be update regularly. + */ + watch: false, + + /** + * APIProperty: geolocationOptions + * {Object} Options to pass to the navigator's geolocation API. See + * . No specific + * option is passed to the geolocation API by default. + */ + geolocationOptions: null, + + /** + * Constructor: OpenLayers.Control.Geolocate + * Create a new control to deal with browser geolocation API + * + */ + initialize: function(options) { + // concatenate events specific to this control with those from the base + this.EVENT_TYPES = + OpenLayers.Control.Geolocate.prototype.EVENT_TYPES.concat( + OpenLayers.Control.prototype.EVENT_TYPES + ); + this.geolocationOptions = {}; + OpenLayers.Control.prototype.initialize.apply(this, [options]); + }, + + /** + * Method: activate + * Activates the control. + * + * Returns: + * {Boolean} The control was effectively activated. + */ + activate: function () { + if (!this.geolocation) { + this.events.triggerEvent("locationuncapable"); + return false; + } + if (!this.active) { + if (this.watch) { + this.watchId = this.geolocation.watchPosition( + OpenLayers.Function.bind(this.geolocate, this), + OpenLayers.Function.bind(this.failure, this), + this.geolocationOptions + ); + } else { + this.geolocation.getCurrentPosition( + OpenLayers.Function.bind(this.geolocate, this), + OpenLayers.Function.bind(this.failure, this), + this.geolocationOptions + ); + } + } + return OpenLayers.Control.prototype.activate.apply( + this, arguments + ); + }, + + /** + * Method: deactivate + * Deactivates the control. + * + * Returns: + * {Boolean} The control was effectively deactivated. + */ + deactivate: function () { + if (this.active && this.watchId !== null) { + this.geolocation.clearWatch(this.watchId); + } + return OpenLayers.Control.prototype.deactivate.apply( + this, arguments + ); + }, + + /** + * Method: geolocate + * Activates the control. + * + */ + geolocate: function (position) { + var center = new OpenLayers.LonLat( + position.coords.longitude, + position.coords.latitude + ).transform( + new OpenLayers.Projection("EPSG:4326"), + this.map.getProjectionObject() + ); + if (this.bind) { + this.map.setCenter(center); + } + this.events.triggerEvent("locationupdated", { + position: position, + point: new OpenLayers.Geometry.Point( + center.lon, center.lat + ) + }); + }, + + /** + * Method: failure + * method called on browser's geolocation failure + * + */ + failure: function (error) { + this.events.triggerEvent("locationfailed", {error: error}); + }, + + CLASS_NAME: "OpenLayers.Control.Geolocate" +}); diff --git a/tests/Control/Geolocate.html b/tests/Control/Geolocate.html new file mode 100644 index 0000000000..0c2f433507 --- /dev/null +++ b/tests/Control/Geolocate.html @@ -0,0 +1,105 @@ + + + + + + +
+ + diff --git a/tests/list-tests.html b/tests/list-tests.html index b894091841..be92040d0f 100644 --- a/tests/list-tests.html +++ b/tests/list-tests.html @@ -15,6 +15,7 @@
  • Control/DragFeature.html
  • Control/DragPan.html
  • Control/DrawFeature.html
  • +
  • Control/Geolocate.html
  • Control/GetFeature.html
  • Control/Graticule.html
  • Control/KeyboardDefaults.html