diff -r 000000000000 -r 54063d8b0412 js/geolocation.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/js/geolocation.js Tue Jul 06 11:31:19 2010 -0700 @@ -0,0 +1,135 @@ +/** + * This class provides access to device GPS data. + * @constructor + */ +function Geolocation() { + /** + * The last known GPS position. + */ + this.lastPosition = null; + this.lastError = null; + this.callbacks = { + onLocationChanged: [], + onError: [] + }; +}; + +/** + * Asynchronously aquires the current position. + * @param {Function} successCallback The function to call when the position + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the position data. + * @param {PositionOptions} options The options for getting the position data + * such as timeout. + */ +Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) { + var referenceTime = 0; + if (this.lastPosition) + referenceTime = this.lastPosition.timestamp; + else + this.start(options); + + var timeout = 20000; + var interval = 500; + if (typeof(options) == 'object' && options.interval) + interval = options.interval; + + if (typeof(successCallback) != 'function') + successCallback = function() {}; + if (typeof(errorCallback) != 'function') + errorCallback = function() {}; + + var dis = this; + var delay = 0; + var timer = setInterval(function() { + delay += interval; + //if we have a new position, call success and cancel the timer + if (dis.lastPosition && dis.lastPosition.timestamp > referenceTime) { + successCallback(dis.lastPosition); + clearInterval(timer); + } else if (delay >= timeout) { //else if timeout has occured then call error and cancel the timer + errorCallback(); + clearInterval(timer); + } + //else the interval gets called again + }, interval); +}; + +/** + * Asynchronously aquires the position repeatedly at a given interval. + * @param {Function} successCallback The function to call each time the position + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the position data. + * @param {PositionOptions} options The options for getting the position data + * such as timeout and the frequency of the watch. + */ +Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) { + // Invoke the appropriate callback with a new Position object every time the implementation + // determines that the position of the hosting device has changed. + this.getCurrentPosition(successCallback, errorCallback, options); + var frequency = 10000; + if (typeof options == 'object' && options.frequency) + frequency = options.frequency; + var that = this; + return setInterval(function() { + that.getCurrentPosition(successCallback, errorCallback, options); + }, frequency); +}; + + +/** + * Clears the specified position watch. + * @param {String} watchId The ID of the watch returned from #watchPosition. + */ +Geolocation.prototype.clearWatch = function(watchId) { + clearInterval(watchId); +}; + +Geolocation.prototype.start = function(options) { + var so = device.getServiceObject("Service.Location", "ILocation"); + + //construct the criteria for our location request + var updateOptions = new Object(); + // Specify that location information need not be guaranteed. This helps in + // that the widget doesn't need to wait for that information possibly indefinitely. + updateOptions.PartialUpdates = true; + + //default 15 seconds + if (typeof(options) == 'object' && options.timeout) + //options.timeout in in ms, updateOptions.UpdateTimeout in microsecs + updateOptions.UpdateTimeOut = options.timeout * 1000; + + //default 1 second + if (typeof(options) == 'object' && options.interval) + //options.timeout in in ms, updateOptions.UpdateTimeout in microsecs + updateOptions.UpdateInterval = options.interval * 1000; + + // Initialize the criteria for the GetLocation call + var trackCriteria = new Object(); + // could use "BasicLocationInformation" or "GenericLocationInfo" + trackCriteria.LocationInformationClass = "GenericLocationInfo"; + trackCriteria.Updateoptions = updateOptions; + + var dis = this; + so.ILocation.Trace(trackCriteria, function(transId, eventCode, result) { + var retVal = result.ReturnValue; + + if (result.ErrorCode != 0 || isNaN(retVal.Latitude)) + return; + + // heading options: retVal.TrueCourse, retVal.MagneticHeading, retVal.Heading, retVal.MagneticCourse + // but retVal.Heading was the only field being returned with data on the test device (Nokia 5800) + // WRT does not provide accuracy + var newCoords = new Coordinates(retVal.Latitude, retVal.Longitude, retVal.Altitude, null, retVal.Heading, retVal.HorizontalSpeed); + var positionObj = { coords: newCoords, timestamp: (new Date()).getTime() }; + + dis.lastPosition = positionObj; + }); + +}; + + +if (typeof navigator.geolocation == "undefined") navigator.geolocation = new Geolocation(); +