- From: Richard Maher via GitHub <sysbot+gh@w3.org>
- Date: Tue, 09 Feb 2016 00:36:11 +0000
- To: public-geolocation@w3.org
I found this a useful layman's reference for hardware support of
geofencing: -
http://gpsworld.com/putting-the-ultra-low-power-in-geofence/
Explains a lot to me especially about power consumption,
I maintain that the SW architecture, in combination with any Android
support for position batching, that subsequently offloads geo-fence
processing to a central server in order to determine alarm/other
processing for ALL users, is a viable if not preferable alternative.
Whether or not a wake-lock or cpu-lock is a retrograde step in power
consumption, its implementation and availability pays homage to the
user's right to self-determination. Likewise the user should be
empowered to authorize GPS tracking while the phone is off.
Surely a myopic cluster of GNSS ICs is a less than optimal solution
for fleet management or social networking, and an instance of
functionality-devolution gone too far? IMHO, other than for monitoring
prisoners on probation, the current geofence solution is a textbook
case of the tail wagging the dog.
A Service Worker should be able to subscribe to a PositionManager
optionally specifying min distance and/or seconds between updates to
the position. A positionChanged event will be sufficient to
re-instantiate a terminated SW.
Below is how I throttle GeoLocation.watchPosition now: -
Tier3Toolbox.prototype.LocationThrottle =
function(initHndlr, moveHndlr, standHndlr, errorHndlr,
userOptions)
{
if(!navigator.geolocation) {
throw new Error("Unsupported browser -
No Geolocation support");
}
if (arguments.length < 4) {
throw new Error("Insufficient call
arguments");
}
if (typeof initHndlr != "function" ||
typeof moveHndlr != "function" ||
typeof standHndlr != "function" ||
typeof errorHndlr != "function") {
throw new Error("The Init, Move,
Stand, and Error handler parameters must be functions");
}
var lastPos, trackerId, loiterTimer,
deltaMetres,
recalibrateTimer, lastOptions,
lastDrop, replayTimer
;
var MAXSILENCE = 30;
var watchCount = 1;
var acceptCount = 1;
var lastUpdate = 0;
var initHndlr = initHndlr;
var moveHndlr = moveHndlr;
var standHndlr = standHndlr;
var errorHndlr = errorHndlr;
var options, defMaxSilence, timeDetent,
spaceDetent,
loiterDetent, maxLocAge, accurate,
maxSilence, lastOptions
;
function moveReplay()
{
replayTimer = null;
if ((lastDrop.timestamp >
lastPos.timestamp)) {
lastDrop.timestamp =
Date.now();
filterLocation(lastDrop);
}
}
function loiterLimit()
{
loiterTimer = null;
standHndlr.call(null);
}
var recalibrate =
function()
{
if (window.console)
console.log("recalibrating");
recalibrateTimer = null;
if (trackerId)
navigator.geolocation.clearWatch(trackerId);
getCurrent(initAcc);
}
var getCurrent =
function(success)
{
navigator.geolocation.getCurrentPosition(success,locError,{
enableHighAccuracy: false,
maximumAge: Number.POSITIVE_INFINITY,
timeout: 10000
});
}
var initLoc =
function(position)
{
lastPos = position;
initHndlr.call(null,
position);
}
var initAcc =
function(position)
{
watchCount++;
trackerId =
navigator.geolocation.watchPosition(filterLocation, locError, {
enableHighAccuracy: accurate,
maximumAge: maxLocAge
});
recalibrateTimer =
setTimeout(recalibrate, maxSilence);
}
var start =
function(userOptions)
{
parseOptions(userOptions);
trackerId =
navigator.geolocation.watchPosition(filterLocation, locError, {
enableHighAccuracy: accurate,
maximumAge: maxLocAge,
timeout: Number.POSITIVE_INFINITY
});
loiterTimer =
setTimeout(loiterLimit, loiterDetent);
recalibrateTimer =
setTimeout(recalibrate, maxSilence);
}
var parseOptions =
function(userOptions)
{
options = userOptions ||
lastOptions;
defMaxSilence = (("maxSilence"
in options) ? options.maxSilence : MAXSILENCE );
timeDetent = (("minSilence"
in options) ? options.minSilence :
0 ) * 1000;
spaceDetent =
(("minProgress" in options) ? options.minProgress :
0 );
loiterDetent = (("maxSnail"
in options) ? options.maxSnail : defMaxSilence ) * 1000;
maxLocAge = (("maxAge"
in options) ? options.maxAge :
0 );
if (maxLocAge !=
Number.POSITIVE_INFINITY) maxLocAge *= 1000;
accurate = (("accurate"
in options) ? options.accurate : true );
maxSilence = defMaxSilence
* 1000;
lastOptions = options;
}
var locError =
function(error)
{
errorHndlr.call(null, error);
}
var filterLocation =
function(position)
{
if (!lastPos) return;
watchCount++;
if (position.timestamp <=
lastPos.timestamp)
return;
var currTime = Date.now();
var dropping = false;
if (((position.timestamp -
lastPos.timestamp) < timeDetent) ||
((currTime -
lastUpdate ) < timeDetent)) {
dropping = true;
} else {
clearTimeout(recalibrateTimer);
recalibrateTimer =
setTimeout(recalibrate, maxSilence);
}
deltaMetres =
Tier3Toolbox.calculateDistance(
position.coords.latitude,
position.coords.longitude,
lastPos.coords.latitude,
lastPos.coords.longitude)
if (deltaMetres.toFixed() <
spaceDetent) {
return;
}
if (dropping) {
lastDrop = position;
clearTimeout(replayTimer);
replayTimer =
setTimeout(moveReplay, timeDetent);
return;
}
acceptCount++;
lastPos = position;
lastUpdate = currTime;
clearTimeout(loiterTimer);
loiterTimer =
setTimeout(loiterLimit, loiterDetent);
moveHndlr.call(null, position,
deltaMetres);
}
var stop =
function()
{
if (trackerId)
navigator.geolocation.clearWatch(trackerId);
clearTimeout(recalibrateTimer);
clearTimeout(loiterTimer);
clearTimeout(replayTimer);
}
parseOptions(userOptions);
getCurrent(initLoc);
return {start : start, stop : stop};
};
--
GitHub Notification of comment by RichardMaher
Please view or discuss this issue at
https://github.com/w3c/geofencing-api/issues/25#issuecomment-181642272
using your GitHub account
Received on Tuesday, 9 February 2016 00:36:23 UTC