S60 Map and Navigation API |
DN0667838 |
CONFIDENTIAL |
Version |
Date |
Status |
Description |
---|---|---|---|
1.0 |
16.10.2006 |
Approved |
|
![]() |
This API enables client to access map and navigation features of the provider application. Following are the most important use cases: showing map (optionally with landmarks), selecting a location from map, engaging navigation.
![]() |
This API is intended for end-user applications, which possess any location-related information and wish to use it with map and/or navigation features. This is Client-Server type of Library API.
This API does not implement these features itself but instead serves as a gateway between client applications and provider applications, which actually implement map views and navigation. Provider applications are application servers and perform in their own processes and utilize their own views. Client applications only request certain services via this API and these are executed in a separate application.
![]() |
The main use cases provided by the API are following:
![]() |
Each of these classes represent a connection to the provider application. In order to instantiate them, it is needed to supply an instance of CMnProvider, defined in Map and Navigation Provider Discovery API, to either NewL or NewChainedL methods.
![]() |
This API relies on functionality provided by external applications, Provider applications, which are executed in a separate process from client. Access to map views is provided by the CMnMapView class and navigation service is available through the CMnNavigator class. The client creates these classes using either NewL or NewChainedL methods, which differ in the way how the provider application is executed.
There are two execution modes available: standalone (the user can switch between the client application and the provider application), initiated by the NewL method, and "chained" (when provider application's main window group is made child of client's window group thus hiding the client application from the user and making it impossible to switch back until the provider application is closed), initiated by the NewChainedL method. The chained mode is similar to the embedded mode with the exception that the child application is running in its own process.
CMnMapView has one asynchronous method, SelectFromMapL, which must be completed or cancelled before next asynchronous request is made. If this methods, then no asynchronous request is outstanding.
Client can use MAknServerAppExitObserver-derived class as observer. Handler function of this class provides default implementation, which closes client application if provider application has been closed by user by "Exit" menu option. This behavior is only valid for the case when provider application is executed in chained mode. In standalone mode, provider application is treated as "independent" on client application and hence client does not need to be closed if provider application is closed.
General use of this API is described by following sequence:
Following diagram depicts typical sequence when provider is executed in standalone mode.
![]() |
The client uses the CMnMapView class in order to use map features and the CMnMapView::ShowMapL method in order to request the map view display. Whatever options are required they must be set before ShowMapL is called as they only affect the next call to this function and do not affect the currently displayed map.
![]() |
The simplest case is showing the map of some area. The area is defined by central point and radius. Central point is the coordinate of the location on the globe and the radius (in meters) defines what minimal area around this location must be visible in the map view.
![]() |
This subcase is very similar to showing map of an area. Here the client additionally specifies what landmarks should be shown on the map.
Use CMnMapView::AddLandmarksToShowL overloads to specify landmarks to show on map. These methods can be called any number of times and all landmarks are added to the common list of landmarks, which is shown when ShowMap is called next time. Use CMnMapView::ResetLandmarksToShow to clear the list of landmarks.
![]() |
Another extension to the showing map use case is to specify that the map should be shown with the current location in the center. This is done by calling CMnMapView::ShowCurrentLocationL instead of ShowMapL. The map is centered at the current location point and the central point setting of map area is ignored (but the radius part of area settings is used). All other options are applicable in the same way as they are for the ShowMapL call.
The map is only required to be drawn the first time centered to the current location. If the current location moves, the map does not move automatically. However, if the CMnMapView::ECurrentLocationShowAlways option is set, then map is updated if the current location goes beyond the visible area.
![]() |
The following is the example of a function, which invokes map views. Its input parameter is reference to the CMnProvider class, which the caller must obtain from Map and Navigation Provider Discovery API. See documentation on this API for code examples on how to find available provider applications.
void ShowMapL( CMnProvider& aProvider ) { // 1. Connect to map provider CMnMapView* mapview = CMnMapView::NewL( aProvider ); CleanupStack::PushL( mapview ); // 2a. Add some landmark instances to show CPosLandmark* landmark = CPosLandmark::NewLC(); _LIT( KDummyLandmarkName, "DummyLandmark" ); landmark->SetLandmarkNameL( KDummyLandmarkName ); TLocality loc(TCoordinate( 0, 0, 3 ), 4, 5); landmark->SetPositionL(loc); RPointerArray<CPosLandmark> landmarks; CleanupClosePushL( landmarks ); landmarks.AppendL( landmark ); // send it to provider application mapview->AddLandmarksToShowL( landmarks ); // array and landmark can be destroyed now CleanupStack::PopAndDestroy( &landmarks ); CleanupStack::PopAndDestroy( landmark ); // 2b. Add some "linked" landmarks to show _LIT( KDatabaseUri, "file://c:testlandmarks.ldb" ); // must be URI of an existing database const TPosLmItemId KTestLandmarkId = 12345; // must be valid ID of a landmark in the database RArray<TPosLmItemId> landmarkIds; CleanupClosePushL( landmarkIds ); landmarkIds.AppendL( KTestLandmarkId ); mapview->AddLandmarksToShowL( KDatabaseUri, landmarkIds ); // id array can be destroyed now CleanupStack::PopAndDestroy( &landmarkIds ); // 3. Invoke map view // both landmarks will be drawn on the map mapview->ShowMapL(); // it is ok to disconnect now. Provider will not close // until user closes the view CleanupStack::PopAndDestroy( mapview ); }
![]() |
Use CMnMapView::SelectFromMapL to start user's selection of a location from the map. This is an asynchronous request, when it is completed, use CMnMapView::SelectionResultType to identify what type of location has been selected and then one of the CMnMapView::RetrieveSelectionResult overloads in order to retrieve actual data. Use CMnMapView::Cancel to cancel selection.
The following code example demonstrates how clients call an asynchronous selection from the map service, using active objects.
In this example, the application defines a class derived from CActive, which handles asynchronous selection operation. It also defines an observer class with a callback method, which is called once the selection operation is completed.
// The observer class class MSelectionObserver { public: // client of CActiveSelector must implement it virtual void HandleSelectionCompletedL( CMnMapView& aMapView, TInt aError ) = 0; }; // The asynchronous operation handler class class CActiveSelector : public CActive { public: CActiveSelector( MSelectionObserver& aObserver ); ~CActiveSelector(); // CActive-related methods void RunL(); void DoCancel(); TInt RunError( TInt aError ); // Initiates selection operation void SelectL( CMnProvider& aProvider ); private: // disconnects from provider, when operation is completed void Reset(); private: MSelectionObserver& iObserver; CMnMapView* iMapView; }; CActiveSelector::CActiveSelector( MSelectionObserver& aObserver ) : CActive( CActive::EPriorityStandard ), iObserver( aObserver ) { CActiveScheduler::Add( this ); } CActiveSelector::~CActiveSelector() { Cancel(); } void CActiveSelector::SelectL( CMnProvider& aProvider ) { if ( IsActive() ) { // avoid two simultaneous selection requests User::Leave( KErrInUse ); } // create connection iMapView = CMnMapView::NewChainedL( aProvider ); // start request iMapView->SelectFromMapL( iStatus ); SetActive(); } void CActiveSelector::RunL() { // request is completed, inform observer iObserver.HandleSelectionCompletedL( *iMapView, iStatus.Int() ); Reset(); // disconnect once observer has retrieved result } TInt CActiveSelector::RunError( TInt /*aError*/ ) { Reset(); return KErrNone; } void CActiveSelector::DoCancel() { if ( IsActive() && iMapView ) { iMapView->Cancel(); } Reset(); } void CActiveSelector::Reset() { delete iMapView; iMapView = NULL; }
The application can use this helper class as shown below. The client's class overrides MSelectionObserver::HandleSelectionCompletedL in order to be informed when the selection operation is completed and retrieve the selection result.
// Some client's class class CClient : public CBase, public MSelectionObserver { ... public: // this method starts selection void SelectFromMapL(); protected: void ConstructL(); protected: // from MSelectionObserver // this is called by CActiveSelector when selection is done void HandleSelectionCompletedL( CMnMapView& aMapView, TInt aError ); private: CActiveSelector* iSelector; CMnProvider* iProvider; ... }; void CClient::ConstructL() { ... iSelector = new (ELeave) CActiveSelector( *this ); } void CClient::SelectFromMapL() { // start selection using pre-chosen provider application // iProvider must be initialized to some provider application, // which supports CMnProvider::EServiceMapView iSelector->SelectL( *iProvider ); } void CClient::HandleSelectionCompletedL( CMnMapView& aMapView, TInt aError ) { // selection is done, analyze error code first... if ( aError ) { // selection failed or cancelled ( aError == KErrCancel ) } else { // ... and retrieve result switch ( aMapView.SelectionResultType() ) { case CMnMapView::ESelectionFreeLandmark: { // retrieve result landmark as free-location landmark CPosLandmark* landmark = aMapView.RetrieveSelectionResultL(); ... delete landmark; } break; case CMnMapView::ESelectionLandmarkIndex: { // retrieve result as index of one of non-linked landmarks, // passed to CMnMapView::AddLandmarksToShowL TInt index = KErrNotFound; aMapView.RetrieveSelectionResultL( index ); } break; case CMnMapView::ESelectionLinkedLandmark: { // retrieve result landmark as one of linked landmark TPosLmItemId id = KPosLmNullItemId; HBufC* uri = NULL; aMapView.RetrieveSelectionResultL( id, uri ); ... delete uri; } break; default: break; } } }
![]() |
Panic code | Reason |
KMnPanicDuplicateRequest | Raised if client issues a new asynchronous request before the previous one is completed or cancelled. For this API it happens if the client calls CMnMapView::SelectFromMapL before the previous request is completed or cancelled. |
![]() |
The main concern about RAM usage is related to specifying landmarks to be shown on the map. In order to reduce memory consumption it is recommended to use overloads that accept landmarks database URI and set of landmark IDs, if possible. Otherwise, all landmark data is copied when the landmark is prepared to be sent to the provider application and thus more memory is required.
![]() |