A proposal for the Compass API. This should be part of the Geolocation API.

Introduction

Compass

This compass specification is based loosely on the Google Android Compass API, and the W3C [[GEOLOCATION-API]]. This specification estimated estimate magnetic field at a given point on Earth, and in particular, to compute the magnetic declination from true north.

This uses the World Magnetic Model produced by the United States National Geospatial-Intelligence Agency. More details about the model can be found at http://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml. This class currently uses WMM-2005 which is valid until 2010, but should produce acceptable results for several years after that.

Requirements

Use-Cases

Walking Turn-by-turn Route Navigation

A mapping application can help the user navigate along a route by providing detailed turn-by-turn directions. The application does this by registering with the Geolocation API to receive repeated location updates of the user's position. The application calculates the speed and determines that the user is walking and also registers with the Compass API to receive updates about the user's orientation. These updates are delivered as soon as the implementing user agent determines that the orientation of the user has changed, which allows the application to adjust accordingly.

Show the user's Position and Orientation on a Map

A user finds herself in an unfamiliar city area and cannot determine where she is or which direction she is facing. She wants to check her orientation so she uses her hand-held device to navigate to a Web-based mapping application that can pinpoint her exact location on the city map using the Geolocation API and her precise orientation using the Compass API. She then asks the Web application to provide driving directions from her current position to her desired destination.

Annotating Content with Orientation and Location information

A group of friends is hiking through the Scottish highlands. Some of them write short notes and take pictures at various points throughout the journey and store them using a Web application that can work offline on their hand-held devices. Whenever they add new content, the application automatically tags it with location data from the Geolocation API and orientation data from the Compass API. Every time they reach a town or a village, and they are again within network coverage, the application automatically uploads their notes and pictures to a popular blogging Web site, which uses the geolocation data to construct links that point to a mapping service. Users who follow the group's trip can click on these links to see a satellite view of the area where the notes were written and the pictures were taken. They can also use orientation data to determine which direction the photographer was facing when the pictures were taken. Another example is a life blog where a user creates content (e.g. images, video, audio) that records her every day experiences. This content can be automatically annotated with information such as time, geographic position, orientation, or even the user's emotional state at the time of the recording.
void getCurrentOrientation ( in CompassCallback successCallback, [Optional] in CompassPosition position, [Optional] in CompassErrorCallback errorCallback, [Optional] in CompassOptions options)
The getCurrentOrientation() function takes one, two, three or four arguments. When called, it must immediately return and then asynchronously acquire a new Orientation object based on the values in the CompassPosition object. If successful, this method must invoke its associated successCallback argument with a Orientation object as an argument. If the attempt fails, and the method was invoked with a non-null errorCallback argument, this method must invoke the errorCallback with a OrientationError object as an argument.

If the CompassPosition parameter contains valid information, the implementation SHOULD use the position of the device to increase the accuracy of the orientation calculation.

int watchOrientation ( in CompassCallback successCallback, [Optional] in CompassPosition position, [Optional] in CompassErrorCallback errorCallback, [Optional] in CompassOptions options)
The watchOrientation() function takes one, two, three or four arguments. When called, it must immediately return and then asynchronously start a watch process defined as the following set of steps:
  1. Acquire a new Orientation object based on the values in the CompassPosition object. If successful, invoke the associated successCallback with an Orientation object as the argument. If the attempt fails, and the method was invoked with a non-null errorCallback argument, this method must invoke the errorCallback with a OrientationError object as an argument.
  2. Invoke the appropriate callback with a new Orientation object every time the implementation determines that the orientation of the hosting device has changed.
If the CompassPosition parameter contains valid information, the implementation SHOULD use the position of the device to increase the accuracy of the orientation calculation.

This method returns an integer value that uniquely identifies the watch process. When the clearWatch() method is called with this identifier, the watch process MUST stop acquiring any new position fixes and must cease invoking any callbacks. When this value is used in a call to updatePosition(), the watch process SHOULD update the position information that it is using in its orientation caluculations.

void updatePosition ( in int watchId, in CompassPosition compassPosition )
The updatePosition() function provides new position information to the watch specified by the watchId parameter. The watch SHOULD use this updated position in its orientation calculations. If this method is not called, the implementation MUST continue to use the information provided (if any) in the original call to watchOrientation().

NOTE: I'm not sure that the watchId parameter is necessary. Is there a use case where the caller would want to update the compass position for one watch and not any others?

void clearWatch ( in int watchId )
When this method is called, the implementation MUST stop calling the successCallback and errorCallback associated with the watchId.

CompassCallback

void handleEvent(in Orientation orientation)
This function MUST be called whenever the implementation successfully retrieves orientation information as a result to a prior call to either getCurrentOrientation() or watchOrientation(). If an implementation is able to retrieve orientation information, but the information does not meet the criteria specified in the OrientationOptions argument, this method SHOULD NOT be called.

CompassErrorCallback

void handleEvent(in OrientationError error)
This function MUST be called whenever the implementation is unable to retrieve orientation information as a result to a prior call to either getCurrentOrientation() or watchOrientation(). If an implementation is able to retrieve orientation information, but the information does not meet the criteria specified in the OrientationOptions argument, this method SHOULD be called.

CompassPosition

The CompassPosition object allows an implementation to provide more accurate orientation information. How this information is obtained is beyond the scope of this specification.
readonly attribute float latitude
Degrees latitude in WGS84 geodetic coordinates -- positive is east. Values MUST be greater than -180, and less than or equal to 180.
readonly attribute float longitude
Degrees longitude in WGS84 geodetic coordinates -- positive is north. Values MUST be greater than -180, and less than or equal to 180.
readonly attribute float altitudeMeteres
Altitude in WGS84 geodetic coordinates, in meters.
readonly attribute DOMTimeStamp timestamp
Time at which to evaluate the declination, in milliseconds since January 1, 1970. (approximate is fine -- the declination changes very slowly).

CompassOptions

attribute unsigned int sampleInterval
The sampleInterval attribute specifies in milliseconds how often the implementation SHOULD check to see if the orientation has changed. While the specification allows the caller to sample at very small intervals, on many implementations, this may be wasteful because the battery device may update its level information at a frequency significantly below the sampleInterval. On implementations that are event driven, this value MAY be ignored. The caller should be aware that setting a value too small can adversely affect the battery life. The default value SHOULD be 1,000, or once every one second.
readonly attribute boolean enableHighAccuracy
The enableHighAccuracy attribute provides a hint that the application would like to receive the best possible results. This may result in slower response times or increased power consumption. The user might also deny this capability, or the device might not be able to provide more accurate results than if the flag wasn't specified.
readonly attribute long timeout
The timeout attribute denotes the maximum length of time (expressed in milliseconds) that is allowed to pass from the call to getCurrentOrientation() or watchOrientation() until the corresponding successCallback is invoked. If the implementation is unable to successfully acquire a new Orientation before the given timeout elapses, and no other errors have occurred in this interval, then the corresponding errorCallback MUST be invoked with a OrientationError object whose code attribute is set to TIMEOUT.

Orientation

readonly attribute DOMTimeStamp timestamp
Time at which the orientation was calculated, in milliseconds since January 1, 1970.
readonly attribute float declination
The declination of the horizontal component of the magnetic field from true north, in degrees (i.e. positive means the magnetic field is rotated east that much from true north). The maximum value MUST be 180; the minumum value MUST be greater than -180.
readonly attribute float fieldStrength
Total field strength in nanoteslas.
readonly attribute float horizontalStrength
Horizontal component of the field strength in nonoteslas.
readonly attribute float inclination
The inclination of the magnetic field in degrees -- positive means the magnetic field is rotated downwards. The maximum value MUST be 180; the minumum value MUST be greater than -180.
readonly attribute float x
The X (northward?) component of the magnetic field in nanoteslas.
readonly attribute float y
The Y (eastward) component of the magnetic field in nanoteslas.
readonly attribute float z
The Z (downward) component of the magnetic field in nanoteslas.

OrientationError

readonly attribute unsigned short UNKNOWN_ERROR
The orientation acquisition process failed due to an error not covered by the definition of any other error code in this interface.
readonly attribute unsigned short PERMISSION_DENIED
The orientation acquisition process failed because the application origin does not have permission to use this API.
readonly attribute unsigned short ORIENTATION_UNAVAILALBE
The orientation of the device could not be determined. The implementation reported an internal error that caused the process to fail entirely.
readonly attribute unsigned short TIMEOUT
The specified maximum length of time has elapsed before the implementation could successfully acquire a new Orientation object.
readonly attribute unsigned short INVALID_VALUE
The implementation failed to retrieve orientation information because one or more of the values in the CompassOptions or CompassPosition parameters of the getCurrentOrientation() or watchOrientation() calls was invalid. For example, if the CompassPosition longitude attribute were set to a value of -180, the CompassErrorCallback must be invoked with the CompassError code attribute equal to INVALID_VALUE (4).
readonly attribute unsigned short code
The code attribute SHOULD contain one of the errors defined in this specification. An implementation MAY define additional error codes, but MUST NOT use the numeric values defined here.
readonly attribute DOMString message
The message attribute must return an error message describing the details of the error encountered. This attribute is primarily intended for debugging and developers should not use it directly in their application user interface.

Acknowledgements

Many thanks to Clayne Robison and Andy Idsinga at Intel Corporation for their contributions to this specification.