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

A conforming implementation MUST provide a method to retrieve one-shot orientation information.

A conforming implementation MUST allow an application to register to receive
updates when the hosting device orientation changes.

A conforming implementation MUST allow an application to stop receiving such updates.

A conforming implementation SHOULD be agnostic to the underlying sources of information.

A conforming implementation MAY provide the ability for an application to increase
accuracy by considering geolocation data in the orienation calculation.

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.

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.

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:

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.

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.

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 CompassPositionlongitude attribute were set to a value of -180, the CompassErrorCallback must be invoked with the CompassErrorcode 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.