S60 Map Image API

DN0734846
CONFIDENTIAL

©Nokia Corporation and/or its subsidiaries 2007
This material, including documentation and any related computer programs, is protected by copyright controlled by Nokia. All rights are reserved. Copying, including reproducing, storing, adapting or translating, any or all of this material requires the prior written consent of Nokia. This material also contains confidential information, which may not be disclosed to others without the prior written consent of Nokia.

Nokia is a registered trademark of Nokia Corporation. S60 and logo is a trademark of Nokia Corporation. Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. Other company and product names mentioned herein may be trademarks or tradenames of their respective owners.

Change History

Version

Date

Status

Description

1.0

21.02.2007

Approved

 


Table of Contents

Purpose
API availability
API description
Use cases
API class structure
Using Map Image API
Map image parameters
Obtaining bitmap of specified world area
Converting between image and world coordinates
Security
Error handling
Memory overhead
Extensions to the API
See also
Glossary
Abbreviations
Definitions
References

 


Purpose

Map Image API allows clients to obtain map of a specified area of the world in bitmap form.

 


API availability

This API is available since S60 release 5.0.

 


API description

This API is intended for end-user applications, which desire to draw world maps in their views. This is a 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 implement actual rendering. Provider applications are application servers and perform in their own processes.

 


Use cases

The main use cases provided by the API are the following:
  • Obtaining bitmap of specified world area
  • Converting between image and world coordinates

 


API class structure

This API provides a single interface to map image features via the CMnMapImage class. It exposes methods for issuing map image rendering request, specifying related parameters and converting world coordinates to offsets in image and vice versa. Map image parameters are defined by TMnMapImageParams. Rendering is performed as an asynchronous request, which client can handle itself, or register to be notified about completion via MMnMapImageRenderCallback.

Figure 1: Map Image API class structure

 


Using Map Image API

This API relies on functionality provided by external applications, Provider Applications, which are executed in a separate process from client. Rendering services are accessed through the CMnMapImage class. Client creates it using the NewL method. The provider application is always executed in standalone mode.

Some methods of CMnMapImage are asynchronous (see CMnMapImage::RenderL), and they must be completed or cancelled before any other asynchronous requests are made. If an asynchronous method can leave, and it leaves, then no asynchronous request is outstanding.

The connection to the provider application is closed when this class is destroyed, but it does not necessarily mean that the provider application is closed too. This depends on user actions and/or provider application behavior.

 


Map image parameters

Map image parameters determine behavior of all use cases of this API: image rendering, as well as coordinate conversions. The parameters are collected within the TMnMapImageParams class and described below.

Parameter Description
Center Point The world coordinate in WGS-84, which should be positioned in the center of the rendered map image.
Size Width and height of needed image in pixels.
Area Width and height of the visible world area in meters. See more info below.
Direction "Heading" of the image. See more info below.
Image Type Type of the image: scalable vector map or satellite images.

Direction

Map image is by default directed to North (except if center point is at North Pole) but client can specify any other direction via TMnMapImageParams::SetDirection().

Image direction is defined as clockwise angle between two vectors:
  • vector from center point towards North Pole parallel to center’s longitude. If center is positioned at North Pole, then this vector is directed towards South Pole parallel to center’s longitude.
  • vector from center point towards center of image’s top side (vertical axis of the image).
This direction parameter can be thought of as "true heading" of the image.

Area

Area parameter describes the size of world area visible in the map image. It is defined via two arguments: width and height. Height is the length in meters of the line, parallel to the image direction and going through the center point. Width is the length of the line, orthogonal to the image direction and going through center point. These two parameters define an ellipse, covering the world area, which is required to be visible on the map.

Note, that the actual visible area may be larger than that specified by width and height, if the given image size and visible area have different aspect ratios. The actual aspect ratio of the map is determined by the projection algorithms used by the provider application.

The picture below describes the definition of center point, direction and area parameters. "Latitude" and "Longitude" are respectively center point's meridian and parallel.

Figure 2: Map area and direction description

Scale

There is no globe to plane projection that could preserve distances between any two points in the whole map extent. Therefore, the scale of a map cannot be constant on the whole map and will vary from place to place. (Printed maps almost always have a scale indicator, but it is only a so called principal scale, or "nominal" scale, which is the ratio of the Earth scale to the radius of the sphere, used for map generation. This scale matches the actual map image scale only at some points or lines.)

Therefore, it is not possible to reliably measure real world distances based on distance on map image. Instead, use the TCoordinate::Distance() method to calculate distances between world coordinates and CMnMapImage::GetWorldCoordinate() to find world coordinates corresponding to a given image point.

 


Obtaining bitmap of specified world area

The client application uses CMnMapImage to specify various parameters of map image it wants to receive and to issue rendering request. Rendering request is asynchronous and the client handles it itself or registers a listener, which will be informed about request completion. The listener must be derived from MMnMapImageRenderCallback.

The main steps of that use case are:
  1. Find Provider Application, which supports Map Image service, by using MnProviderFinder::FindProvidersL() from Map and Navigation Provider Discovery API.
  2. Create the CMnMapImage class with instance of CMnProvider, selected on step 1.
  3. Define map image parameters in CMnMapImage::MapImageParams(). It is recommended to explicitly define all the parameters without relying on default values.
  4. Optionally, set options, which are desired to be shown on map via SetShowOptions.
  5. Create a new instance of CFbsBitmap, size in pixels, sufficient to fit the image of size defined in TMnMapImageParams::SetSize() (taken CMnMapImage::SetTargetOrigin() into account as well). Or, reuse another instance, which meets these requirements.
  6. Issue rendering request by one of RenderL overloads with parameter selected on Step 5.
  7. When the asynchronous request is successfully completed, the resulting image is contained in the bitmap provided on Step 6.

This sequence (with slight changes) is described on the diagram below.

Figure 3: Obtaining bitmap image of an area

Note the callback object, it is one of client's classes, which implements the MMnMapImageRenderCallback interface. This object is notified when the rendering process is finished. This API uses an active object internally to realize that feature, and hence that callback is called only when client's thread is idle (i.e. its Active Scheduler is processing its active objects).

Alternatively, the client can define its own active object and use its iStatus member variable as parameter to the CMnMapImage::RenderL method.

The following example shows how to code the sequence described below. For simplicity, asynchronous rendering request is handled synchronously, though it is not recommended in real applications: either a callback class should be used, or client's own active object.

#include <fbs.h>
#include <gdi.h>
#include <mnmapimage.h>

CFbsBitmap* GetBitmapLC(
  TCoordinate& aCenter,
  TSize& aSize,
  TReal32 aVisibleArea, // in meters
  CMnProvider& aProvider )
{
// Create target bitmap
CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
CleanupStack::PushL( bitmap );
User::LeaveIfError( bitmap->Create( aSize, EColor16M ) );

// Create renderer
CMnMapImage* image = CMnMapImage::NewL( aProvider );
CleanupStack::PushL( image );

// Define map image parameters
TMnMapImageParams params;
params.SetCenterPoint( aCenter );
params.SetSize( aSize );
params.SetVisibleArea( aVisibleArea, aVisibleArea );
params.SetDirection( 0 ); // directly towards North
params.SetImageType( TMnMapImageParams::ETypeSatelliteImage );

image->SetMapImageParams( params );

// Optional settings
image->SetShowOptions(
  CMnMapImage::EShowOptionPois | CMnMapImage::EShowOptionText );

// Now render!

TRequestStatus status;
image->RenderL( *bitmap, status );
User::WaitForRequest( status );
User::LeaveIfError( status.Int() );

// Cleanup and return
CleanupStack::PopAndDestroy( image );
return bitmap; // left in cleanup stack
}

 


Converting between image and world coordinates

The actual rendering engine of the provider application can utilize any projection algorithms, which affect how world locations and areas are represented by the map image. Also, as said before, the client cannot calculate distances in the world, based on distances in the map image. To resolve such problems there is a coordinate conversion functionality, which converts world coordinates to map image offsets and vice versa.

In case the client application needs to draw something on top of map image, it must know how world coordinates are mapped to pixels of image. CMnMapImage provides the GetImageCoordinate() method to achieve that. It accepts world coordinate in WGS-84 as parameter an returns offset in pixels from the top left corner of the map image. (Note that this is not the top left corner of the bitmap image if CMnMapImage::TargetOrigin() is not TPoint(0,0). )

The given coordinate may even be outside of the area drawn on the map image, in which case negative values in the result value will denote a point to the left of the left border and/or above the top border of the image, and values bigger than width or height denote a point to the right of the right image border or below its bottom border. This can be used to estimate the relative position of a location, which is not visible on the map image. However, such estimation is not always possible, especially if that location is much far away from the image area borders. This function returns KErrUnknown in such cases.

If the client wants to identify a real world location, which corresponds to a given pixel in the map image, it can do so by calling CMnMapImage::GetWorldCoordinate(). The output is a WGS-84 coordinate. In this case it is required that the input image coordinate fits to the image borders, otherwise KErrArgument is returned.

It is also possible that a given image coordinate has no corresponding coordinate, as in the case when a semisphere of the globe is drawn and image corners contain no map data. In that case KErrUnknown is returned.

These methods are not asynchronous as they do not require IPC communication with server side of the provider application and are expected to be fast enough so that the client can call them quite often without big performance penalty.

In practice, the client application uses these two methods after an image has been rendered. Therefore, instead of a sequence diagram, only a code example is given for this use case.

void FindRealDiagonalLengthL(
  const CMnMapImage& image, TReal32 aDiagonal )
{
// Find coordinate of left top corner
TCoordinate leftTop;
User::LeaveIfError(
  image.GetWorldCoordinate( TPoint( 0, 0 ), leftTop ) );

// Find coordinate of right bottom corner
TCoordinate rightBottom;
User::LeaveIfError(
  image.GetWorldCoordinate(
    image.MapImageParameters().Size().AsPoint(),
    rightBottom ) );

// Calculate distance
TReal32 distance;
User::LeaveIfError( rightBottom.Distance( leftTop, distance ) );
aDiagonal = distance;
}

The usage of CMnMapImage::GetImageCoordinate() is very similar and is not shown here.

 


Security

This API itself does not require any capabilities from the client (except for the Location capability, when the current location option is required to be drawn, see CMnMapImage::SetShowOptions()).

However, the client must be aware that, as was mentioned above, the API utilizes provider applications for serving clients' requests. Provider applications run in their own process and might require some capabilities. For example, a provider application, which needs to access network in order to retrieve map content, might require NetworkServices capability. If the client does not have it, then the provider application refuses serving the client's request (or select a workaround, e.g. remain in offline mode). If the service is refused due to lack of capabilities, the error code is KErrPermissionDenied.

 


Error handling

This API uses only standard Symbian OS error and leave codes. Panic codes are defined in the mnerrors.h header file.

Panic code Reason
KMnPanicDuplicateRequest Raised if the client issues a new asynchronous request before the previous one is completed or cancelled. For this API it happens if the client calls CMnMapImage::RenderL before the previous request is completed or cancelled.

 


Memory overhead

The biggest memory consumption, which can be caused by using this API is determined by two factors:
  1. Rendering is implemented by the provider application, which is loaded, when the CMnMapImage class is created and remains in memory until it is destroyed. However, in client's heap only a small amount of memory is allocated, to maintain the session with the renderer, while most of the memory is allocated by the renderer itself from global memory.
  2. Bitmap size. Again, the main amount of memory is allocated in the heap of Font and Bitmap Server and not in the client's heap.
Despite the fact that largest portions of memory are allocated not in client's heap, the client still has to take responsibility of memory usage. The following practices can help overall system performance a lot:
  • Destroy CMnMapImage instances, when not needed. This will allow the provider application to exit and free some memory for other applications. Note: starting the provider application may take some time, so it is still not recommended to construct and destroy this class too frequently.
  • Do not keep too many bitmap objects allocated. Usually, the application needs only two: one for rendering purposes and another one for drawing on the screen, whenever CCoeControl::Draw() is called.

 


Extensions to the API

This API does not allow extending.

 


See also

See also related APIs:
  • Map and Navigation Provider Discovery API
  • Map and Navigation API
  • Map and Navigation AIW API
  • Geocoding API

 


Glossary

 


Abbreviations

Table:
None  

 


Definitions

Table:
None  

 


References

None  

Back to top