add a Geolocate control, p=cmoullet,aabt, r=me (closes #1885)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@11258 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
Éric Lemoine
2011-02-22 16:48:05 +00:00
parent 8965a61c75
commit 50c292f176
5 changed files with 374 additions and 0 deletions

109
examples/geolocation.html Normal file
View File

@@ -0,0 +1,109 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<title>OpenLayers Geolocation</title>
<link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
<link rel="stylesheet" href="style.css" type="text/css" />
<script src="../lib/OpenLayers.js"></script>
<script type="text/javascript">
var map, layer, vector, watchId;
function init(){
var style = {
fillOpacity: 0.1,
fillColor: '#000',
strokeColor: '#f00',
strokeOpacity: 0.6
}
map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.OSM( "Simple OSM Map");
vector = new OpenLayers.Layer.Vector('vector');
map.addLayers([layer, vector]);
map.setCenter(
new OpenLayers.LonLat(-71.147, 42.472).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), 12
);
var geolocate = new OpenLayers.Control.Geolocate({
geolocationOptions: {
enableHighAccuracy: false,
maximumAge: 0,
timeout: 7000
}
});
map.addControl(geolocate);
geolocate.events.register("locationupdated",this,function(e) {
vector.removeAllFeatures();
vector.addFeatures([
new OpenLayers.Feature.Vector(
e.point,
{},
{
graphicName: 'cross',
strokeColor: '#f00',
strokeWidth: 2,
fillOpacity: 0,
pointRadius: 10
}
),
new OpenLayers.Feature.Vector(
OpenLayers.Geometry.Polygon.createRegularPolygon(
new OpenLayers.Geometry.Point(e.point.x, e.point.y),
e.position.coords.accuracy/2,
50,
0
),
{},
style
)
]);
map.zoomToExtent(vector.getDataExtent());
});
geolocate.events.register("locationfailed",this,function() {
console.log('Location detection failed');
});
window.geolocate = geolocate;
$('locate').onclick = function() {
geolocate.deactivate();
$('track').checked = false;
geolocate.watch = false;
geolocate.activate();
};
$('track').onclick = function() {
geolocate.deactivate();
if (this.checked) {
geolocate.watch = true;
geolocate.activate();
}
};
}
</script>
</head>
<body onload="init()">
<h1 id="title">Geolocation Example</h1>
<div id="tags">
geolocation, geolocate, mobile
</div>
<p id="shortdesc">
Track current position and display it with its accuracy.
</p>
<div id="map" class="smallmap"></div>
<div id="docs">
<button id="locate">Locate me!</button>
<label>
<input type="checkbox" name="track" id="track" />
Track my position
</label>&nbsp;
</div>
</body>
</html>

View File

@@ -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",

View File

@@ -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>
*/
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
* <http://dev.w3.org/geo/api/spec-source.html>. 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"
});

View File

@@ -0,0 +1,105 @@
<html>
<head>
<script src="../../lib/OpenLayers.js"></script>
<script type="text/javascript">
var map, control, centerLL
watch = null,
geolocation= {
getCurrentPosition: function(f) {
f({
coords: { latitude: 10, longitude: 10 }
});
},
watchPosition: function(f) {
watch = true;
},
clearWatch: function() {
watch = null;
}
};
function test_initialize(t) {
t.plan(3);
control = new OpenLayers.Control.Geolocate({geolocationOptions: {foo: 'bar'}});
t.ok(control instanceof OpenLayers.Control.Geolocate,
"new OpenLayers.Control returns object" );
t.eq(control.displayClass, "olControlGeolocate", "displayClass is correct" );
t.eq(control.geolocationOptions.foo, 'bar',
'provided geolocation options are set in the geolocationOptions prop');
}
function test_bind(t) {
t.plan(3);
var control = new OpenLayers.Control.Geolocate({
geolocation: geolocation
});
control.events.register('locationupdated', null, function() {
t.ok(true, 'locationupdated event is fired when bound');
});
map.addControl(control);
control.activate();
var center = map.getCenter();
t.eq(center.lon, 10, 'bound control sets the map lon');
t.eq(center.lat, 10, 'bound control sets the map lat');
control.deactivate();
map.removeControl(control);
map.setCenter(centerLL);
}
function test_unbind(t) {
t.plan(3);
var control = new OpenLayers.Control.Geolocate({
geolocation: geolocation,
bind: false
});
control.events.register('locationupdated', null, function() {
t.ok(true, 'locationupdated event is fired when unbound');
});
map.addControl(control);
control.activate();
var center = map.getCenter();
t.eq(center.lon, 0, 'unbound control doesnt sets the map lon');
t.eq(center.lat, 0, 'unbound control doesnt sets the map lat');
control.deactivate();
map.removeControl(control);
map.setCenter(centerLL);
}
function test_watch(t) {
t.plan(2);
var control = new OpenLayers.Control.Geolocate({
geolocation: geolocation,
watch: true
});
map.addControl(control);
control.activate();
t.eq(watch, true, 'watch option makes calls to watchPosition');
control.deactivate();
t.eq(watch, null, 'deactivate control calls the clearwatch');
map.removeControl(control);
map.setCenter(centerLL);
}
function test_uncapable(t) {
t.plan(1);
var control = new OpenLayers.Control.Geolocate({
geolocation: null,
bind: false
});
control.events.register('locationuncapable', null, function() {
t.ok(true,'uncapable browser fired locationuncapable event');
});
map.addControl(control);
control.activate();
}
function loader() {
map = new OpenLayers.Map('map');
var layer = new OpenLayers.Layer.WMS("Test Layer",
"http://labs.metacarta.com/wms-c/Basic.py?",
{layers: "basic"});
map.addLayer(layer);
centerLL = new OpenLayers.LonLat(0,0);
map.setCenter(centerLL, 5);
}
</script>
</head>
<body onload="loader()">
<div id="map" style="width: 256px; height: 256px;"/>
</body>
</html>

View File

@@ -15,6 +15,7 @@
<li>Control/DragFeature.html</li>
<li>Control/DragPan.html</li>
<li>Control/DrawFeature.html</li>
<li>Control/Geolocate.html</li>
<li>Control/GetFeature.html</li>
<li>Control/Graticule.html</li>
<li>Control/KeyboardDefaults.html</li>