Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


How to get location information

[Top]


Purpose

This document explains how to get location information using the Location Acquisition API.

[Top]


Required background

Location Acquisition API overview describes the main client/server classes of the API.

Position data and info classes describes the classes that hold location information.

[Top]


Getting location information

Introduction

Client applications use the RPositionServer and RPositioner classes to get position updates. RPositionServer is used by client applications to manage a session with the location server and to get positioning technology module information. RPositioner is used by client applications to manage a subsession with the location server and to get position updates.

Positioning Modes

For each location request from a client, the LBS subsystem can operate in one of several different positioning modes. The Location Acquisition API hides the details of which positioning mode is in use from client applications. A client makes the same sequence of calls to the API to get a position update whichever positioning mode is used. Note that only some of these positioning modes may be available to a client application at runtime.

Each positioning mode is a different way of getting a position fix:

A client application cannot directly choose the positioning mode that is used for its location request. A handset manufacturer may provide an LBS 'control panel' type of application where the GPS mode can be selected by an end user. However for modes that involve the network (Terminal Based Mode, Terminal Assisted Mode and Cell-based Mode) it is possible for a network operator to override the GPS mode as part of the location request. If a client wants to know precisely how a position fix was calculated, this information is available in the returned position info object (as described in more detail later in this document).

Figure 1 shows a simplified sequence for a client requesting a position update from LBS. The sequence shows simplified behaviour for Terminal Based Mode. The A-GPS Module is a positioning module that uses Assisted GPS to calculate a position. The Network Protocol Module is a positioning module that obtains GPS assistance data and reference positions (often approximate positions) from the network. Note that Terminal Based Mode may not be available on all mobile devices. This depends on the positioning modules that have been installed by the handset manufacturer.

Figure 1. Simplified Terminal Based Mode...


Figure 1. Simplified Terminal Based Mode Sequence

Example

The following code shows a simple example of how a client application can get a single position update. The numbers in the code comments refer to sections that follow the code example.

#include <lbs.h>
#include <lbserrors.h>

...

RPositionServer server;
RPositioner positioner;

// 1. Create a session with the location server
User::LeaveIfError(server.Connect());
CleanupClosePushL(server);

// 2. Create a subsession with the Location Server using default positioning module
User::LeaveIfError(positioner.Open(server));
CleanupClosePushL(positioner);

/* 3 (Optional on platforms other than S60)
   This step is only necessary if code is linked to lbs.lib
   Set the requester information - in this example define a requester stack... */

_LIT(KCntPhone, "+358501234567");
_LIT(KSrvName, "MyService");
RRequestorStack stack;
CRequestor* contact = CRequestor::NewLC(CRequestor::ERequestorContact, CRequestor::EFormatTelephone, KCntPhone);
stack.Append(contact);
CRequestor* service = CRequestor::NewLC(CRequestor::ERequestorService,   CRequestor::EFormatApplication, KSrvName);
stack.Append(service);
User::LeaveIfError(positioner.SetRequestor(stack));

TPositionInfo posInfo;
TPosition pos;
TRequestStatus status;

/* 4. To set update options, call RPositioner::SetUpdateOptions(). 
      See the description in section 4 below */

/* 5. Request location information
      Could also call positioner.GetLastKnownPosition(posInfo, status) 
      to get cached location information */
positioner.NotifyPositionUpdate(posInfo, status);
User::WaitForRequest(status);

// 6. Receive location information
if (status != KErrNone)
 {
 // Handle possible client/server errors
 ...
 }

// Get the position data object from the wrapper info object
posInfo.GetPosition(pos);

// Use the position data
...

// Reissue the location request if necessary by calling NotifyPositionUpdate() again

/* 7. To cancel or complete a location request a client
 calls RPositioner::CancelRequest() or RPositioner::CompleteRequest() */

// 8. Cleanup
stack.Reset();
CleanupStack::PopAndDestroy(service);
CleanupStack::PopAndDestroy(contact);
CleanupStack::PopAndDestroy(&positioner);
CleanupStack::PopAndDestroy(&server);

The following describes the steps to get location information as shown in the above example:

1. Create a session with the location server

To create a session with the location server, a client application:

Standard client-server error codes are returned by calls to open the session. A panic occurs if the client application has already created a session with the location server. Error and panic codes specific to LBS are defined in LbsErrors.h.

2. Create a subsession with the location server

Location information requests are issued on a subsession.

To create a subsession, an application calls one of three overloaded RPositioner::Open() member functions:

The LBS subsystem does not compare the vertical accuracy of a calculated position with the vertical accuracy specified by a client application (specified by position quality criteria, by a quality profile or by a positioning module). Only the horizontal accuracy of a calculated position is used to decide if it is accurate enough to be returned to a client application.

3. Set client requester details

If using the Location Acquisition API on the S60 platform it is necessary to set the client requesters by calling RPositioner::SetRequestorL() before calling RPositioner::NotifyPositionUpdate().

On platforms other than S60, the call is optional (it is not implemented by the Location Server).

For application portability between non-S60 and S60 platforms, applications must call one of the RPositioner::SetRequestorL() methods.

4. Set update options

A client application calls RPositioner::SetUpdateOptions() to set the update options. Calling this method only affects future calls to RPositioner::NotifyPositionUpdate() and RPositioner::GetLastKnownPosition() and does not affect any outstanding requests.

A TPositionUpdateOptions parameter specifies the update options and is passed in RPositioner::SetUpdateOptions(). The properties of TPositionUpdateOptions are set either on its construction or via setter methods. The following properties can be defined:

Important note on setting update options

The default constructor of TPositionUpdateOptions sets all update options to zero by default and is the equivalent of calling the following:

When setting update options, a client should beware of causing unexpected side effects. For example, if a client wants to accept partial updates, it might do the following:

However, this process has the side-effect of setting all the other update options to their default values as described above. In particular the client request will now not timeout which is unlikely to be the desired behaviour. To avoid this, a client should usually modify the current update options as follows:

Examples

The following code shows a simple example of how to set update options. Note that all the options are changed by the client.

...

TPositionUpdateOptions options;

// Frequency of updates in microseconds
const TTimeIntervalMicroSeconds KUpdateInterval(2000000);

// How long the application is willing to wait before timing out the request
const TTimeIntervalMicroSeconds KTimeOut(4000000);

// The maximum acceptable age of the information in an update
const TTimeIntervalMicroSeconds KMaxUpdateAge(1000000);

options.SetUpdateInterval(KUpdateInterval);
options.SetUpdateTimeOut(KTimeOut);
options.SetMaxUpdateAge(KMaxUpdateAge);
options.SetAcceptPartialUpdates(EFalse);

User::LeaveIfError(positioner.SetUpdateOptions(options));

/* Now when the application requests location information
it will be provided with these options */ 

positioner.NotifyPositionUpdate(posInfo, status);

...

The following code example shows an example of how to change one update option (to accept partial updates).

...

TPositionUpdateOptions options;

User::LeaveIfError(positioner.GetUpdateOptions(options));
options.SetAcceptPartialUpdates(ETrue);
User::LeaveIfError(positioner.SetUpdateOptions(options));

// The other update options are unchanged

positioner.NotifyPositionUpdate(posInfo, status);

...

Notes

When a call to RPositioner::NotifyPositionUpdate() or RPositioner::GetLastKnownPosition() completes, it is necessary to re-issue the request by calling one of these methods again to obtain further updates even if RPositioner::SetUpdateOptions() has been called. Setting update options allows a client to specify when the next position update is required, but does not cause periodic requests to the location server to be made.

A client application can only have one outstanding request for location information per RPositioner subsession. An attempt to make a second request for location information while one is still outstanding causes a panic to occur. An application must cancel an outstanding request before it makes another request. This process is described in step 7.

5. Request the location information

An application can call one of two methods to obtain position data:

When LBS obtains a position the client's TRequestStatus variable is updated and the TPositionInfoBase parameter contains the position data. Client applications must always check the value of the TRequestStatus parameter as this indicates the success or failure of the location request and may indicate that specified location accuracy criteria could not be satisfied at the time of the request.

The value of TRequestStatus that is set when a position update occurs or times out depends on the configuration of the LBS subsystem. See Location Acquisition API runtime behaviour for more information.

6. Receive and use the location information

When the location server obtains a position, the client's TRequestStatus variable is updated. In the example, the TPositionInfo object that was passed to RPositioner::NotifyPositionUpdate() holds the new position data in a TPosition object.

Important notes

An application should test what kind of position is returned by NotifyPositionUpdate(). TPositionInfoBase::PositionMode() returns a bitmask value of type TPositionModuleInfo::TTechnologyType that is composed of values of type TPositionModuleInfo::_TTechnologyType. Valid combinations of this value are as follows:

TPositionInfoBase::PositionMode() Meaning

ETechnologyNetwork

A reference position obtained from the network

ETechnologyTerminal | ETechnologyAssisted

A position calculated using GPS with assistance data from the network

ETechnologyNetwork | ETechnologyAssisted

A position calculated using GPS measurements by a remote server in the network

ETechnologyTerminal

A position calculated using GPS without assistance data (autonomous mode)

A reference position may be returned to a client application by the location server before a more accurate position fix is available. Whether a reference position is made available to the location server depends on the implementation of the positioning modules by the Symbian OS licensee or handset manufacturer.

If a reference position is returned, the behaviour is as follows:

For the first call to RPositioner::NotifyPositionUpdate()

NotifyPositionUpdate() completes and a reference position is returned to the client. The client application can check for return of a reference position by checking for TPositionInfoBase()::PositionMode() == TPositionModuleInfo::ETechnologyNetwork. If a reference position is returned it may not satisfy the application's position accuracy quality criteria and the application will need to make another NotifyPositionUpdate() request.

For subsequent calls to RPositioner::NotifyPositionUpdate() (made by the same client subsession)

NotifyPositionUpdate() completes and a position is returned to the client. This position may be either:

Note that NotifyPositionUpdate() may complete early if a GPS positioning module signals to LBS that it will be unable to return a location fix with the required quality criteria. In this case the Location Server returns the best location fix it can obtain to the client. The value of the TRequestStatus parameter of the client is set to either KPositionQualityLoss or KErrNone depending on the configuration of Location Acquisition API runtime behaviour.

Tracking

A position update timeline for tracking is shown in figure 2. Note that this diagram shows the timing of updates provided by the Location Server lbslocserver.exe that has been part of the LBS subsystem since Symbian OS v9.2. The exact behaviour of tracking on platforms that use a Location Server for S60 may differ from that shown in Figure 2.

A client application has previously called TPositionUpdateOptions::SetUpdateInterval(T) and RPositioner::SetUpdateOptions() (not shown in figure 2). Partial updates are not set. LBS is also configured to return reference positions and accurate positions only (see Location Acquisition API runtime behaviour for more information about this behaviour). The important points are:

Figure 2. Position updates when tracking


Figure 2. Position updates when tracking

Error codes

The value of a client's TRequestStatus can be set to an LBS error code (defined in lbserrors.h) or an error code defined in a licensee's positioning module. An error causes NotifyPositionUpdate() to complete. An application should always check the value of TRequestStatus when its RunL() method is called.

7. Cancel or complete a location information request

To cancel a location request a client application calls RPositionerSubSessionBase::CancelRequest(), passing a EPositionerNotifyPositionUpdate parameter. The client's TRequestStatus is set to KErrCancel if the request was successfully cancelled and no position update is returned.

To complete a location request early, a client application calls RPositionerSubSessionBase::CompleteRequest() passing a EPositionerNotifyPositionUpdate parameter. Calling this method does not cancel the position update, but asks the location server to return any available position data. The returned position update may be different from that which would have been returned if the request had been allowed to complete normally. If the request is completed early, the client's TRequestStatus is set to KPositionEarlyComplete. Note that this method is not implemented on the S60 platform and returns KErrNotSupported.

8. Close the subsession and session

RPositioner::Close() closes the subsession. RPositionServer::Close() closes the server session. In the code example the cleanup stack function is used. Any privacy requester objects created by a client must also be cleaned up.

[Top]


See also

Location Acquisition API overview

Location Acquisition API runtime behaviour

How to use module information

How to use module selection criteria