Landmarks API Specification
Changes in Landmarks API documentation
1.0
|
11.07.2005
|
Approved
|
|
2.0
|
18.11.2005
|
Approved
|
Landmark and category serialization support added.
|
3.0
|
10.10.2006
|
Approved
|
Documentation revised
|
4.0
|
09.05.2007
|
Approved
|
GPX format import support added
|
5.0
|
26.09.2008
|
Approved
|
KML format import support added
|
6.0
|
10.06.2009
|
Approved
|
URL Encoding & Decoding support added
|
Changes in Landmarks API
1.0
|
First version
|
2.0
|
Landmark and category serialization support added.
|
3.0
|
Documentation revised
|
4.0
|
GPX format import support added
|
5.0
|
KML format import support added
|
6.0
|
URL Encoding & Decoding support added
|
Purpose
The purpose of Landmarks API is to enable terminal applications to manage
landmarks in a consistent way. For instance, if a landmark is received in
an email and the user chooses to store the landmark in the terminal, the landmark
is instantly available for a map application. It is available from S60 3rd Edition onwards and ehnaced version of this API in Symbian^3 supports:
This API does not provide search functionality. Search is provided by Landmarks
Search API.
API Description
Landmarks API is mainly targeted for end-user applications. It lets clients
access landmark databases and read/edit their content.
This API uses position classes and generic position field IDs from Location
Acquisition API to define the location of a landmark.
Landmarks API enables defining landmark categories. Landmark categories
are labels, which can be assigned to a landmark to define the type of the
landmark. For instance, a landmark of some restaurant could be a assigned
with category “Restaurants”.
Landmarks API provides an interface for listening to database events. Clients
can be notified when a landmark database is edited.
Landmarks API also offers methods for exporting landmark data to and importing
from exchange format, which enables exchanging landmarks between terminals.
As a part of the exchange format support,it provides encoding of a landmark
object into an URL & parsing of an URL and decoding it into a landmark
object.
The logical type of the API is Library API. Technically it is method-call
interface. Landmarks API loads the implementation at run time but the implementation
consists only of local objects.
Landmarks
Landmark is a location with a name and it may also contain other data,
such as description, icon, address details etc. Landmarks are organized in
landmark databases, which reside on terminal or may be remote. Client can
read landmarks from a database, add new, modify and remove existing landmarks.
Landmark attributes
A landmark can contain the following attributes:
Landmark attributes
Item ID
|
This ID is a reference to the landmark in a landmark database. It is
locally unique within one database.
|
Landmark name
|
The name of the landmark can contain a maximum of 255 characters. The
landmark name does not have to be unique in a database.
|
Position
|
The WGS84 coordinate for the landmark.
|
Coverage radius
|
Coverage radius is set if the landmark is big, for example, a city.
It defines the size of the area, which the landmark represents. The coverage
area is specified in meters.
|
Category info
|
The categories related to the landmark, e.g. restaurant, gas station,
grocery store, etc. For more information about categories, see section
Landmark categories
.
|
Icon
|
A reference to an icon in an icon file which can be used to symbolize
the landmark in a UI. An icon mask can also be specified from the same icon
file.
|
Description
|
A textual description of the landmark, for example, “Chinese restaurant.
Nice atmosphere and the service is superb”. The description has a maximum
length of 4095 characters.
|
Position fields
|
Generic position fields as defined by Location Acquisition API . A
position field can, for instance, be the street address of the landmark or
the name of the city where the landmark is found. Landmarks API only supports
text position fields. If the client wants to store a non-text field, the value
must first be converted to a textual representation. A landmark can contain
any number of position fields.
|
Place ID
|
The unique id specified by the client for any location.
|
TimeStamp
|
The time associated with a landmark.The format that is used for timestamp
is YYYYMMDD:HHMMSS.MMMMMM wherein the date field is mandatory.Validations
for this field are the same as in TTime object.
|
Landmark categories
A landmark may be assigned to one or many categories (or none at all).
Categories help to classify landmarks, group them, enable finer search criteria
etc. Landmark categories are also stored in landmark databases.
Local and global landmark categories
Landmark categories may be local or global. Local categories are defined
by the user. They are stored in a database and cannot be reused by multiple
databases unless the user creates the same category in several databases.
Global categories are predefined in the terminal and may be reused in multiple
databases and multiple phones and on different platforms. The Global Category
ID uniquely specifies a global category, which makes global categories localizable.
The names and icons of global categories are predefined in a resource file
and the category name is automatically changed in the database when it is
open if the terminal language changes since the last usage of the database.
Note:
The
global category name will not be changed to the newly selected language if
the user has previously renamed this category.
The predefined global landmark categories are listed in the following table:
Predefined global landmark categories
3000
|
Accommodation
|
Hotel, Camping site
|
6000
|
Business
|
Bank, Factory, Office
|
9000
|
Communication
|
Internet Access Point, Public Telephone, Wireless LAN Hot Spot
|
12000
|
Educational institute
|
School, College
|
15000
|
Entertainment
|
Amusement park, Cinema, Concert hall, Night club
|
18000
|
Food & Beverage
|
Fast food, Restaurant, Café, Bar
|
21000
|
Geographical area
|
City, City center, Town
|
24000
|
Outdoor activities
|
Camping site, Fishing place, Hunting, National park, Playground
|
27000
|
People
|
My home, My friend’s home, Father’s summer cottage, Child’s school
|
30000
|
Public service
|
Tourist information office, Government office, Library, Post office,
Hospital, Police
|
33000
|
Religious places
|
Church, Mosque
|
36000
|
Shopping
|
Market Place, Pharmacy, Shop, Shopping Center
|
39000
|
Sightseeing
|
Monument, Mountain top, Museum
|
42000
|
Sports
|
Bowling, Golf course, Ice hockey hall, Stadium
|
45000
|
Transport
|
Airport, Bus stop, Harbour, Railway Station, Rest area
|
Other IDs are reserved for future use. Names are given only
for reference purposes, localized names are defined for all languages supported
by the platform.
Category attributes
A landmark category contains the following attributes:
Landmark category attributes
Item ID
|
This ID is a reference to the category in a landmark database. It is
locally unique within one database.
|
Category name
|
The name of the category can contain a maximum of 124 characters. The
category name must be unique in a database. If the client tries to change
the name of a category and that name is already occupied by another category,
the update fails.
|
Global category ID
|
This ID refers to a category in a globally defined category set.
|
Icon
|
A reference to an icon in an icon file, which can be used to symbolize
the category in a UI. An icon mask can also be specified from the same icon
file.
|
Landmark URL format specification
The URL that is required to be encoded or parsed should be specified according
to the following format.Check
References
section
for more details.
Notations Used
* - 0 or more occurences
1* - 1 or more occurrences
[] - optional contents
‘’ - literals
X*Y - between X & Y occurences ( For Eg : 2*5 - between 2 & 5
occurences )
Grammar Definition
url -> [ protocol ‘://’ ] hostname ‘/?’ location *[ ‘??’ location ]
protocol -> ‘http’ | ‘https’
hostname -> [‘www.’] ‘maps.ovi.com’
location -> locationparams *[ '&' locationparams ]
locationparams -> placeid | latitude | longitude | name | street | housenumber
| postalcode | city | state | country | telephone | web | category | description
| positionaccuracy | altitude | altitudeaccuracy | speed | heading | timestamp
placeid -> ‘pid =’ placeidvalue
placeidvalue -> 0*255 [ alphanum | escaped ]
alphanum -> alpha | digit
alpha -> lowalpha | upalpha
lowalpha -> ‘a’ | ‘b’ | ‘c’ | ‘d’ | ‘e’ | ‘f’ | ‘g’ | ‘h’ | ‘i’ | ‘j’ |
‘k’ | ‘l’ | ‘m’ | ‘n’ | ‘o’ | ‘p’ | ‘q’ | ‘r’ | ‘s’ | ‘t’ | ‘u’ | ‘v’ | ‘w’
| ‘x’ | ‘y’ | ‘z’
upalpha -> ‘A’ | ‘B’ | ‘C’ | ‘D’ | ‘E’ | ‘F’ | ‘G’ | ‘H’ | ‘I’ | ‘J’ |
‘K’ | ‘L’ | ‘M’ | ‘N’ | ‘O’ | ‘P’ | ‘Q’ | ‘R’ | ‘S’ | ‘T’ | ‘U’ | ‘V’ | ‘W’
| ‘X’ | ‘Y’ | ‘Z’
digit -> ‘0’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’ | ‘6’ | ‘7’ | ‘8’ | ‘9’
escaped -> ‘%’ hex hex
hex -> digit | ‘a’ | ‘b’ | ‘c’ | ‘d’ | ‘e’ | ‘f’ | ‘A’ | ‘B’ | ‘C’ | ‘D’
| ‘E’ | ‘F’
latitude -> ‘la =’ latitudevalue
latitudevalue -> [sign] 1*2 digit [ ‘.’0 *6 digit ]
sign -> ‘+’ | ‘-’
longitude -> ‘lo =’ longitudevalue
longitudevalue -> [sign] 1*3 digit [ ‘.’0 *6 digit ]
name -> ‘n =’ namevalue
namevalue -> 0*255 ( alphanum | escaped )
street -> ‘s =’ streetvalue
streetvalue -> 0*255 ( alphanum | escaped )
housenumber -> ‘sn =’ housenumbervalue
housenumbervalue -> 0*255 ( alphanum | escaped )
postalcode -> ‘pz =’ postalcodevalue
postalcodevalue -> 0*255 ( alphanum | escaped )
city -> ‘c =’ cityvalue
cityvalue -> 0*255 ( alphanum | escaped )
state -> ‘sp =’ statevalue
statevalue -> 0*255 ( alphanum | escaped )
country -> ‘cr =’ countryvalue
countryvalue -> 0*255 ( alphanum | escaped )
telephone -> ‘t =’ telephonevalue
telephonevalue -> 0*255 ( alphanum | escaped )
web -> ‘w =’ webvalue
webvalue ->0 *255 ( alphanum | escaped )
category -> ‘cat =’ categoryvalue
categoryvalue -> 0*124 ( alphanum | escaped )
description -> ‘d =’ descriptionvalue
descriptionvalue -> 0*4095 ( alphanum | escaped )
positionaccuracy -> ‘pa =’ positionaccuracyvalue
positionaccuracyvalue -> 1* digit [ ‘.’ 0*2digit ]
altitude -> ‘a=’ altitudevalue
altitudevalue -> [sign] 1* digit [ ‘.’ 0*2 digit ]
altitudeaccuracy -> ‘aa =’ altitudeaccuracyvalue
altitudeaccuracyvalue -> 1* digit [ ‘.’0 *2 digit ]
speed -> ‘v =’ speedvalue
speedvalue -> 1* digit [ ‘.’0 *2 digit ]
heading -> ‘h =’ headingvalue
headingvalue -> 1* digit [ ‘.’0 *2 digit ]
timestamp -> ‘ts =’ timestampvalue
timestampvalue -> full-date ':' [ full-time ]
full-date -> date-fullyear date-month date-mday
full-time -> time-hour time-minute time-second ['.'time-microseconds]
time-microseconds -> 0*6digit
time-second -> 2digit
time-minute -> 2digit
time-hour -> 2digit
date-mday -> 2digit
date-month -> 2digit
date-fullyear -> 4digit
Restrictions
locationparams
|
Latitude & longitude params are mandatory.Except the category param
( cat ),if there is repetition of any other params then only the value of
the first occurrence is considered.The category param is allowed to be repeated
in order to support multiple categories to be associated with a single landmark.
|
latitudevalue
|
Value ranges between -90 and +90,where negative values indicate southern
hemisphere & positive values indicate northern hemisphere.The decimal
number is rounded upto 6 decimal digits.
|
longitudevalue
|
Value ranges between -180 and +180,where negative values indicate western
hemisphere & positive values indicate eastern hemisphere.The decimal number
is rounded upto 6 decimal digits.
|
escaped
|
Only special characters whose Ascii value ( provided in hex ) ranges
between these are to be escaped : 20 – 2F , 3A – 40 , 5B – 60 , 7B – 7E
. Refer
References
section for ascii table
|
positionaccuracyvalue
|
Max value is that of max value of TReal32 .The metric considered here
is metres.The decimal number is rounded upto 2 decimal digits.
|
altitudevalue
|
Max value is that of max value of TReal32 .The metric considered here
is metres.The decimal number is rounded upto 2 decimal digits.
|
altitudeaccuracyvalue
|
Max value is that of max value of TReal32 The metric considered here
is metres.The decimal number is rounded upto 2 decimal digits.
|
speedvalue
|
Max value is that of max value of TReal32 .The metric considered here
is metres/second.The decimal number is rounded upto 2 decimal digits.
|
headingvalue
|
Max value is that of max value of TReal32 .The metric considered here
is degrees.The decimal number is rounded upto 2 decimal digits.
|
timestampvalue
|
The full date is mandatory for this field to be encoded/parsed whereas
if the full time is not specified then the default value assumed for time
will be 0.
|
Example URL
Sample URL containing all the location information and conforming to the
grammar as defined above.
"http://www.maps.ovi.com/?la=23.134&lo=120.22&pid=12&n=Placemark&s=HighStreet&sn=1234&pz=123457&c=Bangalore&sp=Karnataka&cr=India&t=9812434125&w=www.weburl.com&cat=MyLandmarks&cat=MyFavouritePlaces&d=Placemark%20from%20Bangalore&pa=12.22&a=43215&v=0&h=0&ts=20090304:121209.123456"
Use cases
These a main use cases for Landmarks API:
-
Opening landmark databases
-
Managing landmarks
-
Managing landmark categories
-
Assigning categories to landmarks
-
Exchanging landmarks
-
Observing landmark database events
API class structure
The following subchapters describe the Landmarks API class structure.
UML diagrams are used to present the classes and their dependencies.
Note
:
The UML diagrams do not show all the available methods, and some of or all
of the method parameters may be left out.
Database access
Landmarks are stored in databases. A client accesses landmark
databases through the
CPosLandmarkDatabase
class.
Each instance of CPosLandmarkDatabase is a handle to exactly one landmark
database. All operations upon a landmark database are performed through instances
of
CPosLandmarkDatabase
.
CPosLandmark
represents the content
of a landmark, for example the landmark name and landmark position. This class
is used in
CPosLandmarkDatabase
methods to let
the client read or edit a landmark in the database.
A landmark stored in a database is referenced by an ID (
TPosLmItemId
),
which is unique within the database. To access a landmark through CPosLandmarkDatabase,
the client must specify the ID of the landmark.
It is common that a client needs to retrieve a set of landmarks,
for instance when listing the content of a landmark database. In Landmarks
API, a landmark set is accessed by using an iterator object.
CPosLmItemIterator
lets
the client retrieve the IDs of the iterated landmarks. The client can iterate
all the landmarks in a database by retrieving a
CPosLmItemIterator
instance
from
CPosLandmarkDatabase
.
Clients may require retrieving landmarks in a certain sort order.
In Landmarks API, the client specifies sort preference by using a
TPosLmSortPref
object.
If a client is not interested in full landmark information,
it can perform a partial read. For instance, the client may only be interested
in the name of the landmark. By using a
CPosLmPartialReadParameters
object,
the client can specify which landmark information is of interest.
Related APIs
-
CPosLandmark
-
CPosLandmarkDatabase
-
CPosLmItemIterator
-
CPosLmPartialReadParameters
-
TPosLmItemId
-
TPosLmSortPref
Category management
A landmark database can contain landmark categories. To access
categories in the database, the client must create a
CPosLmCategoryManager
object
connected to the database. Through this object, the client can retrieve information
about the categories in the database or edit the category content.
CPosLandmarkCategory
represents
information about a landmark category. It is used in the
CPosLmCategoryManager
interface
to pass category information from/to the client.
A landmark category stored in a database is referenced by an
ID (
TPosLmItemId
), which is unique within the
database. To refer to a landmark category, the client specifies the ID of
the category.
Note:
The same type,
TPosLmItemId
,
is used to refer to landmarks and categories. It is possible that a landmark
and a category have the same ID.
Categories can be iterated, just like landmarks.
CPosLmItemIterator
is
used for iterating both landmark and category sets.
Note:
The
iterator is never used to iterate a mixed set of landmarks and categories.
Related APIs
-
CPosLandmarkCategory
-
CPosLmCategoryManager
-
CPosLmItemIterator
-
TPosLmItemId
Database events
A client can listen to events from landmark databases. To listen
to the next event, the client calls
CPosLandmarkDatabase::NotifyDatabaseEvent()
.
The client passes a
TRequestStatus
, which will
be completed when an event is detected. When an event has been retrieved,
the client must renew the
NotifyDatabaseEvent()
request
to listen to further events.
Related APIs
-
CPosLandmarkDatabase::NotifyDatabaseEvent()
-
NotifyDatabaseEvent()
-
TRequestStatus
Exchange operations
A client can exchange landmark data with another party by using the import
and export functionality. If a client has received a file or buffer containing
landmark data and the client is connected to a landmark database, the client
can use Landmarks API to import landmarks to the landmark database. To import
landmarks, the client has to create an instance of the
CPosLandmarkParser
class.
The client can also use Landmarks API to export landmarks from the landmark
database. This will result in a file or buffer containing the landmark data.
To export landmarks, the client has to create an instance of the
CPosLandmarkEncoder
class.
The exchange of landmarks is also supported via an URL.The client can encode
a landmark object into an URL containing all the location inforamtion.To encode
a landmark to an URL ,the client has to create an instance of the
CPosLandmarkEncoder
class.
Also the client can parse a given URL to decode the location
information present in the URL and create a landmark object.To parse an URL
,the client has to create an instance of the
CPosLandmarkParser
class.
Related APIs
-
CPosLandmarkEncoder
-
CPosLandmarkParser
Incremental operations
Some operations in Landmarks API can potentially take a long
time. These operations can therefore be run incrementally. The client retrieves
a
CPosLmOperation
object, which can either be
run incrementally or all at once.
If the operation is run incrementally, the client can read the
operation progress between incremental steps.
Related APIs
Serialization support
A client can pack a landmark or a landmark category object into
a buffer for further serialization. This can be used e.g. for sending data
over process boundaries. On the receiving side packed objects can be unpacked
from buffer. The
PosLandmarkSerialization
class
contains static methods
PackL()
and
UnpackL()
for
packing and unpacking
CPosLandmark
instances.
PosLmCategorySerialization
class
contains appropriate methods for packing and unpacking
CPosLandmarkCategory
instances.
Related APIs
-
CPosLandmark
-
CPosLandmarkCategory
-
PackL()
-
PosLandmarkSerialization
-
PosLmCategorySerialization
-
UnpackL()
Using the Landmarks API
Using landmarks database
To start accessing landmarks in a landmark database, the client only has
to create an instance of the
CPosLandmarkDatabase
class.
This is accomplished by calling one of the
CPosLandmarkDatabase::OpenL()
overloads.
The default landmark database is opened by calling the overload with no parameters.
(If the client wants to open any other landmark database, a URI is used to
specify which database to open, which is described in
Database URI
chapter).
When the client has opened a landmark database, the database may have to
be initialized. There is a method
CPosLandmarkDatabase::IsInitializingNeeded()
for
checking if the database has to be initialized and a method
CPosLandmarkDatabase::InitializeL()
for
performing initialization. If the database is not initialized, the client
will not be able to access the database. The client may also be required to
call
InitializeL()
in the case when the database needs recovery
(which may happen if a modifying transaction has failed).
When the client has a
CPosLandmarkDatabase
object, it
can start reading or editing the database content.
Note:
It is not
possible to edit the database content if the database is read-only.
The database handle is closed by destroying the
CPosLandmarkDatabase
object.
Closing the handle is not allowed while there are still operations running
on it. Doing so will result in a panic.
When the client is done using Landmarks API, it has to call the global
method
ReleaseLandmarkResources()
.
If this method is not called, the client may get a memory leak. This method
is described in
Releasing resources
section.
It is recommended to execute initialization operation incrementally (i.e.
asynchronously), see
Executing incremental operations
for more details.
Database URI
CPosLandmarkDatabase
contains a method
OpenL()
,
which takes a database URI as input. The URI consists of a scheme and the
database location, i.e.
<scheme>://<location>
. If the
scheme is left out, it is understood that the database is local on the terminal
and is accessed through the file system. The URI
c:landmarks.LDB
is
therefore the same thing as
file://c:landmarks.ldb
.
The location part of a landmark database URI for a database residing in
the terminal is specified by a drive letter, a database name and the LDB extension.
The format is
<drive>:<database name>.ldb
, e.g.
c:landmarks.ldb
.
Note:
A
path cannot be specified. If the URI does not specify the drive letter, for
example
landmarks.ldb
, the default landmark database drive will be
assumed.
CPosLandmarkDatabase
provides also method
DatabaseUriLC()
,
which retrieves the URI of the open database.
Related APIs
-
<scheme>://<location>
-
CPosLandmarkDatabase
-
DatabaseUriLC()
-
OpenL()
Compacting database
When modifying a landmark database, the database size increases. Some of
this memory is not really used. The client should therefore supervise the
database usage using the
CPosLandmarkDatabase::SizeL()
method
and compact the database if there is too much unused space.
CPosLandmarkDatabase::CompactL()
is
used to perform compacting and it can be run incrementally.
Compaction is done internally in Landmarks as fallback in case the client
does not do it. This will lock the database and clients will not be able to
access the database until the compaction is complete. This is unexpected behavior
from the user’s point of view and it is therefore recommended that the client
performs the compaction itself.
It is recommended to perform compaction when the usage level drops below
70%.
Related APIs
-
CPosLandmarkDatabase::CompactL()
-
CPosLandmarkDatabase::SizeL()
Releasing resources
The Landmarks subsystem uses ECom plug-ins that provide the implementation
for accessing landmark databases. ECom allocates resources that are not released
when the plug-in is unloaded. These must be explicitly released by the client
at shutdown. This is done by calling the global method
ReleaseLandmarkResources()
, which has
the same effect as
REComSession::FinalClose()
.
The most common way to release landmark resources is to call
ReleaseLandmarkResources()
last in the
client’s destructor.
Related APIs
-
REComSession::FinalClose()
Related APIs
-
CPosLandmarkDatabase
-
CPosLandmarkDatabase::InitializeL()
-
CPosLandmarkDatabase::IsInitializingNeeded()
-
CPosLandmarkDatabase::OpenL()
-
InitializeL()
Managing landmarks
Landmark properties are maintained by
CPosLandmark
class.
Client uses this class to get and set landmark data.
The following example shows how to open database and read landmarks.
// Open a handle to the default landmark database.
CPosLandmarkDatabase* db = CPosLandmarkDatabase::OpenL();
CleanupStack::PushL( db );
// Perform initialization.
// If initialization is not needed, this method will not do anything.
ExecuteAndDeleteLD( db->InitializeL() );
// Create an iterator for iterating the landmarks in the database
CPosLmItemIterator* iter = db->LandmarkIteratorL();
CleanupStack::PushL( iter );
// Read each landmark in the database and do something.
TPosLmItemId lmID = KPosLmNullItemId;
while ( ( lmID = iter->NextL() ) != KPosLmNullItemId )
{
CPosLandmark* lm = db->ReadLandmarkLC( lmID );
// Do something with the landmark information
CleanupStack::PopAndDestroy( lm );
}
// Close the iterator and the database handle.
CleanupStack::PopAndDestroy( iter );
CleanupStack::PopAndDestroy( db );
The client can also edit the attributes of a landmark in the database.
In order to save changes permanently in database the
CPosLandmarkDatabase::UpdateLandmarkL
method
needs to be used.
The following example shows how to change the name of a landmark (
aDatabase
is
an open
CPosLandmarkDatabase
handle).
void RenameLandmarkL(
CPosLandmarkDatabase& aDatabase,
TPosLmItemId aLandmarkId,
const TDesC& aNewName )
{
// Read the landmark from the database.
CPosLandmark* lm = aDatabase.ReadLandmarkLC( aLandmarkId );
// Set the new name and update the database
lm->SetLandmarkNameL( aNewName );
aDatabase.UpdateLandmarkL( *lm );
CleanupStack::PopAndDestroy( lm );
}
The following example shows how a landmark is added to a landmark database
(
aDatabase
is an open
CPosLandmarkDatabase
pointer).
_LIT( KName, "My Thai" );
_LIT( KDescription, "Best Thai restaurant ever. Spicy food." );
TLocality pos;
pos.SetCoordinate( 61.1120, 23.4231 );
// Create the landmark object and set available information.
CPosLandmark* lm = CPosLandmark::NewLC();
lm->SetLandmarkNameL( KName );
lm->SetLandmarkDescriptionL( KDescription );
lm->SetPositionL( pos );
// Add the landmark to the database.
aDatabase->AddLandmarkL(*lm);
CleanupStack::PopAndDestroy(lm);
Reading partial landmarks
Landmark data could be spread among different tables in the landmark database.
When landmark is read from database, all those tables need to be accessed.
However, in many cases when many landmarks are read (e.g. for landmark list)
applications need only partial information for every landmark. In this case
amount of tables accessed and data transferred during reading can be reduced
(thus improving performance) by using "partial read" mechanism of Landmarks
API. Following diagram shows basic steps of partial read.
The following example shows how the client can efficiently read just the
names of all the landmarks using partial read.
aDatabase
is
an open
CPosLandmarkDatabase
handle. For simplicity the
incremental operation is executed in one batch in this example.
CArrayPtr<CPosLandmark>* ReadLandmarkNamesOnlyLC( CPosLandmarkDatabase& aDatabase )
{
// Retrieve IDs for all landmarks in the database.
RArray<TPosLmItemId> landmarkIds;
CleanupClosePushL( landmarkIds );
CPosLmItemIterator* iter = aDatabase->LandmarkIteratorL();
CleanupStack::PushL( iter );
iter->GetItemIdsL( landmarkIds, 0, iter->NumOfItemsL() );
CleanupStack::PopAndDestroy(iter);
// Set partial parameters so that only the landmark name will be retrieved.
CPosLmPartialReadParameters* part = CPosLmPartialReadParameters::NewLC();
part->SetRequestedAttributes( CPosLandmark::ELandmarkName );
aDatabase->SetPartialReadParametersL( *part );
CleanupStack::PopAndDestroy( part );
// Start collecting the partial landmark data. Note that
// this will be quicker than reading full landmarks.
CPosLmOperation* op = aDatabase->PreparePartialLandmarksL( landmarkIds );
CleanupStack::PushL( op );
op->ExecuteL();
// The landmark objects can be retrieved from the operation object. These
// landmark objects now contain only the names of the landmarks so
// the heap is used efficiently.
CArrayPtr<CPosLandmark>* lmData = aDatabase->TakePreparedPartialLandmarksL( op );
CleanupStack::PopAndDestroy(op);
CleanupStack::PopAndDestroy( &landmarkIds );
CleanupStack::PushL( lmData ); // there is a slot for it freed by previous Pop
return lmData;
}
Related APIs
-
CPosLandmarkDatabase
-
aDatabase
Related APIs
-
CPosLandmark
-
CPosLandmarkDatabase
-
CPosLandmarkDatabase::UpdateLandmarkL
-
aDatabase
Managing categories
To access categories in a landmark database, the classes described in section
Category
management
are used. The client must first have a handle to a landmark
database (
CPosLandmarkDatabase
). This handle is passed
to
CPosLmCategoryManager::NewL()
to create a category
manager. After this, the client can read and edit category content in the
database. Category properties are maintained by
CPosLandmarkCategory
class.
The following example shows how to read all landmark categories in a database
and retrieve their names. aDb is an open database handle.
void ReadAllCategoriesInDatabase( CPosLandmarkDatabase& aDb )
{
// Create the category manager
CPosLmCategoryManager* categoryManager = CPosLmCategoryManager::NewL( aDb );
CleanupStack::PushL( categoryManager );
// Create an iterator for iterating the landmarks in the database
CPosLmItemIterator* iter = categoryManager->CategoryIteratorL();
CleanupStack::PushL( iter );
// Read each category in the database and do something.
TPosLmItemId catID;
while ( ( catID = iter->NextL() ) != KPosLmNullItemId )
{
CPosLandmarkCategory* cat = categoryManager->ReadCategoryLC( catID );
// do something with the category information
TPtrC catName;
cat->GetCategoryName( catName );
// if any changes made, following code saves them to database
// categoryManager->UpdateCategoryL( *cat );
CleanupStack::PopAndDestroy( cat );
}
// Close the iterator and the category manager.
CleanupStack::PopAndDestroy( iter );
CleanupStack::PopAndDestroy( categoryManager );
}
Creating local category
The following example shows how the client can create a new category and
add it to database.
// Create a local category object
CPosLandmarkCategory* category = CPosLandmarkCategory::NewLC();
_LIT( KRestaurant, "Restaurant" );
category->SetCategoryNameL( KRestaurant );
// Add it to database
TPosLmItemId categoryId = aCategoryManager->AddCategoryL( *category );
CleanupStack::PopAndDestroy( category );
Related APIs
-
CPosLandmarkCategory
-
CPosLandmarkDatabase
-
CPosLmCategoryManager::NewL()
Assigning categories to landmarks
There is a "many-to-many" relationship between landmarks and landmarks
categories: landmark can be assigned to zero or more categories and one category
may be assigned to zero or more landmarks.
The following example shows how the client can add a category to a landmark.
void AddCategoryToLandmarkL(
CPosLandmarkDatabase& aDatabase,
TPosLmItemId aLandmarkId,
TPosLmItemId aCategoryId )
{
// Find landmark in database
CPosLandmark* landmark = aDatabase.ReadLandmarkLC( aLandmarkId );
// Add category. If it is already added, nothing happens
landmark->AddCategoryL( aCategoryId );
// Save to database
aDatabase.UpdateLandmarkL( *landmark );
// Cleanup
CleanupStack::PopAndDestroy( landmark );
}
The following code example shows how the client can add a category to multiple
landmarks. A global category is assigned to a set of landmarks in this example.
void AddLandmarksToGlobalCategoryL(
CPosLandmarkDatabase& aDatabase,
RPointerArray<TPosLmItemId>& aLandmarkIds,
TPosLmGlobalCategory aGlobalCategoryID )
{
CPosLmCategoryManager* categoryManager = CPosLmCategoryManager::NewL( aDatabase );
CleanupStack::PushL( categoryManager );
// Find ID of the given global category in given database
TPosLmItemId categoryId = categoryManager->GetGlobalCategory( aGlobalCategoryID );
// Add given landmarks to this category
ExecuteAndDeleteLD(
categoryManager->AddCategoryToLandmarksL( categoryId, aLandmarkIds ) );
CleanupStack::PopAndDestroy( categoryManager );
}
Listening to database events
To listen to changes in a landmark database, the classes described in
Database events
are
used. The following sequence shows how a client can listen to database events.
-
The client has a handle to a landmark database; that is, a
CPosLandmarkDatabase
instance.
-
The client calls
CPosLandmarkDatabase::NotifyDatabaseEvent()
,
which takes a
TPosLmEvent
object and
TRequestStatus
.
-
TRequestStatus
is completed when there is an event.
Information about the event is found in the
TPosLmEvent
object
supplied by the client.
-
When the event is handled, the client renews the
NotifyDatabaseEvent()
request
to listen to the next event.
-
When the client does not want to listen to events any more, it stops calling
NotifyDatabaseEvent()
.
If the client has an outstanding request to
NotifyDatabaseEvent()
,
it can cancel the request by calling
NotifyDatabaseEvent()
.
The
TPosLmEvent
object consists of an event type and
an item ID. The event type specifies what has happened and in some events
the item ID specifies a database item involved in the event (for example,
the ID of a newly added landmark).
The following table lists defined events:
Landmark database events
|
Unknown change event. Something has been changed in the database but
no further details are given. All content, which is of interest for the client,
should be read again from the database. This event may be received if there
are big changes in the database.
|
|
EPosLmEventNewDefaultDatabaseLocation
|
This event is received if the default landmark database location is
changed. The client has to open a new
CPosLandmarkDatabase
handle
to access the default database from the new location.
|
|
EPosLmEventMediaRemoved
|
This event is received if the media where the database is stored is
removed. After this, the database cannot be accessed. If the media is inserted
again, the database must still be reopened by the client.
|
|
EPosLmEventLandmarkUnknownChanges
|
Unknown change event concerns only landmarks. This is analogous to
EPosLmEventUnknownChanges
but
it is known that only landmark data has been modified.
|
|
EPosLmEventLandmarkCreated
|
A new landmark has been created in the database.
|
The ID of the new landmark.
|
EPosLmEventLandmarkDeleted
|
A landmark has been deleted from the database.
|
The ID of the deleted landmark.
|
EPosLmEventLandmarkUpdated
|
A landmark in the database has been updated.
|
The ID of the updated landmark.
|
EPosLmEventCategoryUnknownChanges
|
Unknown change event concerning only landmark categories. This is analogous
to
EPosLmEventUnknownChanges
but it is known that only landmark
category data has been modified.
|
|
EPosLmEventCategoryCreated
|
A new landmark category has been created in the database.
|
The ID of the new landmark category.
|
EPosLmEventCategoryDeleted
|
A landmark category has been deleted from the database.
Note:
No
events relating to landmarks are sent even if the deleted category was assigned
to some landmarks.
|
The ID of the deleted landmark category.
|
EPosLmEventCategoryUpdated
|
A landmark category in the database has been updated.
|
The ID of the updated landmark category.
|
The following code example shows how to implement a class, which listens
to changes in a landmark database. The following code section shows how the
class is defined.
class CLandmarkEventListener : public CActive
{
public: // constructor and destructor
static CLandmarkEventListener* NewL( CPosLandmarkDatabase* aDatabase );
virtual ~CLandmarkEventListener();
public: // From CActive
void RunL();
void DoCancel();
TInt RunError( TInt aError );
private:
CLandmarkEventListener( CPosLandmarkDatabase* aDatabase );
void ConstructL();
private:
CPosLandmarkDatabase* iDatabase;
TPosLmEvent iEvent;
};
The following code section shows the source code for
CLandmarkEventListener
.
CLandmarkEventListener::CLandmarkEventListener( CPosLandmarkDatabase* aDatabase )
: CActive( EPriorityStandard ), iDatabase( aDatabase )
{
}
void CLandmarkEventListener::ConstructL()
{
// Start listening for events.
iDatabase->NotifyDatabaseEvent( iEvent, iStatus );
SetActive();
}
CLandmarkEventListener* CLandmarkEventListener::NewL(
CPosLandmarkDatabase* aDatabase)
{
CLandmarkEventListener* self =
new (ELeave) CLandmarkEventListener( aDatabase );
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
CLandmarkEventListener::~CLandmarkEventListener()
{
// Cancel any outstanding event request.
Cancel();
}
void CLandmarkEventListener::RunL()
{
if ( iStatus != KErrNone )
{
// Unexpected error. This should be handled in some way, e.g.
// shut down application, try to listen again, notify user, etc.
}
switch ( iEvent.iEventType )
{
case EPosLmEventLandmarkCreated :
{
TPosLmItemId newLandmarkId = iEvent.iLandmarkItemId;
// Read new landmark from database and add it to UI.
}
break;
case EPosLmEventLandmarkDeleted :
{
TPosLmItemId deletedLandmarkId = iEvent.iLandmarkItemId;
// Remove the landmark from the UI.
}
break;
}
// Resume event listening
iDatabase->NotifyDatabaseEvent( iEvent, iStatus );
SetActive();
}
void CLandmarkEventListener::DoCancel()
{
iDatabase->CancelNotifyDatabaseEvent();
}
TInt CLandmarkEventListener::RunError( TInt /*aError*/ )
{
// process leaves from RunL, if any
return KErrNone;
}
Related APIs
-
CLandmarkEventListener
-
CPosLandmarkDatabase
-
CPosLandmarkDatabase::NotifyDatabaseEvent()
-
EPosLmEventCategoryCreated
-
EPosLmEventCategoryDeleted
-
EPosLmEventCategoryUnknownChanges
-
EPosLmEventCategoryUpdated
-
EPosLmEventLandmarkCreated
-
EPosLmEventLandmarkDeleted
-
EPosLmEventLandmarkUnknownChanges
-
EPosLmEventLandmarkUpdated
-
EPosLmEventMediaRemoved
-
EPosLmEventNewDefaultDatabaseLocation
-
EPosLmEventUnknownChanges
-
NotifyDatabaseEvent()
-
TPosLmEvent
-
TRequestStatus
Exchanging landmarks
A client can exchange landmark data with another party by using the import
and export functionality. Two classes,
CPosLandmarkEncoder
and
CPosLandmarkParser
are
used to convert landmark data to exchange format and from. The exchange format
is defined by specifying its MIME type. The recommended format is "application/vnd.nokia.landmarkcollection+xml".
The parser classes also support GPX format, which is identified
by MIME type, "application/gps+xml".
KML/KMZ format parsing supported. KML format is identified
by MIME "application/vnd.google-earth.kml+xml " and KMZ formate is identified
by MIME "application/vnd.google-earth.kmz "
Encoding and Parsing of an URL is also supported.The mime
type to be specified here ,while creating an instance of the
CPosLandmarkEncoder
and
CPosLandmarkParser
class
is the hostname of the URL to be parsed.For eg: If the URL to be parsed is
"http://www.maps.ovi.com/? la = 23.45 & lo = 45.65 " then the mime type
to be passed will be " maps.ovi.com" . Currently there is support only for
this hostname.
Exporting landmarks
To export a set of landmarks, the client must first create a
CPosLandmarkEncoder
object
for the landmark content format in which the landmarks should be encoded.
The client can add some information of the landmark collection in the encoder
as well.
The client must also provide a list of the landmarks to be exported. If
some of the landmarks are not found in the database, the export operation
fails with the error code
KErrNotFound
. The client does not
have to add any landmarks to the encoder object. The export operation will
add the ones specified in the ID array. The method returns an operation object,
which can be run in incremental mode (see
Executing incremental operations
). If it is run incrementally, the client can
supervise the progress of the operation.
If the
CPosLmOperation
object is deleted before the
operation is complete, it is possible that only a subset of the landmarks
is exported. The client takes ownership of the returned operation object.
When all the landmarks have been exported, the client must finalize the encoding
by calling
CPosLandmarkEncoder::FinalizeEncodingL()
.
The sequence diagram below describes basic steps a client does to export
landmarks from a database to a file.
The following example shows how the client can export landmarks to a file
using the
CPosLandmarkDatabase::ExportLandmarksL()
method.
aDatabase is an open
CPosLandmarkDatabase
handle. In this
example incremental operations are executed synchronously.
void ExportSelectedLandmarksL(
CPosLandmarkDatabase& aDatabase,
RArray<TPosLmItemId>& aSelectedLandmarks)
{
_LIT( KExportFilePath, "c:\\eposLmExport.lmx" );
// Mime type of landmarks exchange format
_LIT8( KPosMimeTypeLandmarkCollectionXml,
"application/vnd.nokia.landmarkcollection+xml" );
// Create the encoder to be used for exporting landmarks
CPosLandmarkEncoder* encoder =
CPosLandmarkEncoder::NewL( KPosMimeTypeLandmarkCollectionXml );
CleanupStack::PushL( encoder );
// Point out the file to export landmark data to
encoder->SetOutputFileL( KExportFilePath );
// Execute the operation in one batch
// Note: There must be landmarks for specified IDs in the database,
// otherwise operation will fail with KErrNotFound leave code
ExecuteAndDeleteLD( aDatabase->ExportLandmarksL(
*encoder, aSelectedLandmarks, CPosLandmarkDatabase::EIncludeCategories ) );
// Finalize encoding to complete export
ExecuteAndDeleteLD( encoder->FinalizeEncodingL() );
CleanupStack::PopAndDestroy( encoder );
}
Related APIs
-
CPosLandmarkDatabase
-
CPosLandmarkDatabase::ExportLandmarksL()
-
CPosLandmarkEncoder
-
CPosLandmarkEncoder::FinalizeEncodingL()
-
CPosLmOperation
-
KErrNotFound
Importing landmarks
To import landmark content, the client must first create a parser object
of class
CPosLandmarkParser
, which can parse the landmark
content. The client does not have to call
CPosLandmarkParser::ParseContentL()
first.
If the content is not already parsed, this will be handled by the import operation.
There are two different
CPosLandmarkDatabase::ImportLandmarksL()
overloads
defined that can be used to import landmark data. In one of them, the client
can pass an array defining a subset of the landmarks in the parser object.
This way the client can select to import only a part of the landmark content.
The other method does not take any parameters and imports all landmarks. Both
the import methods return an operation object, which can be run in incremental
mode (see
Executing incremental operations
). If it is run incrementally, the client can
supervise the progress of the operation.
If the
CPosLmOperation
object is deleted before the
operation is complete, it is possible that only a subset of the landmarks
is imported. The client takes ownership of the returned operation object.
After completion,
CPosLandmarkDatabase::ImportedLandmarksIteratorL()
can
be called to retrieve the IDs of the added landmarks. If the database is read-only,
this operation will complete with the error code
KErrAccessDenied
.
If the client specifies invalid transfer option values, this operation will
panic.
Note:
The
CPosLmOperation::NextStep()
method
cannot be executed synchronously using
User::WaitForRequest()
for
the import operations. Doing so may cause the operation to hang.
CPosLmOperation::NextStep()
must
be executed using an active object.
The diagram below describes general steps, which client does when imports
landmarks from a file.
The following example shows how the client can import landmarks from file
using the
CPosLandmarkDatabase::ImportLandmarksL()
method.
aDatabase is an open
CPosLandmarkDatabase
handle.
void ImportLandmarksL(
CPosLandmarkDatabase& aDatabase,
const TDesC& aImportFilePath )
{
// Mime type of landmarks exchange format
_LIT8( KPosMimeTypeLandmarkCollectionXml,
"application/vnd.nokia.landmarkcollection+xml");
// Create the parser to be used for importing landmarks
CPosLandmarkParser* parser =
CPosLandmarkParser::NewL( KPosMimeTypeLandmarkCollectionXml );
CleanupStack::PushL( parser );
// Point out the file to import landmark data from
parser->SetInputFileL( aImportFilePath );
CPosLmOperation* op = aDatabase->ImportLandmarksL(
*parser, CPosLandmarkDatabase::EDefaultOptions );
CleanupStack::PushL( op );
// Execute the operation in one batch
op->ExecuteL();
// Fetch the landmark iterator of imported landmark IDs
CPosLmItemIterator* iter = aDatabase->ImportedLandmarksIteratorL( op );
CleanupStack::PushL( iter );
// Fetch imported landmark data using this iterator
// Cleanup
CleanupStack::PopAndDestroy( iter );
CleanupStack::PopAndDestroy( op );
CleanupStack::PopAndDestroy( parser );
}
Related APIs
-
CPosLandmarkDatabase
-
CPosLandmarkDatabase::ImportLandmarksL()
-
CPosLandmarkDatabase::ImportedLandmarksIteratorL()
-
CPosLandmarkParser
-
CPosLandmarkParser::ParseContentL()
-
CPosLmOperation
-
CPosLmOperation::NextStep()
-
KErrAccessDenied
-
User::WaitForRequest()
Encoding of Landmarks to URL
To encode a landmark to an URL ,the client has to first create an instance
of
CPosLandmarkEncoder
class with the URL hostname as the
MIME type.( which is 'maps.ovi.com' ).The output buffer into which the encoded
URL is written can be set using the
CPosLandmarkEncoder::SetUseOutputBufferL.The
output can also be encoded into a file by setting the output file using CPosLandmarkEncoder::SetUseOutputFileL.
The client can specify the landmark to be encoded by using
CPosLandmarkEncoder::AddLandmarkL()
method.When
the landmark has been encoded, the client must finalize the encoding by calling
CPosLandmarkEncoder::FinalizeEncodingL().
The sequence diagram below describes basic steps a client does to encode
landmark to a URL.Currently encoding of only a single landmark is supported.Therefore
if AddLandmarkL() method is called more than once during the encoding process
KErrNotSupported is returned.
The following example shows how the client can encode landmark to an URL
using
CPosLandmarkEncoder class.
void EncodeLandmarktoUrl ( CPosLandmark& aLandmark )
{
//Mime type used for encoding URL
_LIT8( KUrlMimeType , "maps.ovi.com" );
// Create the encoder to be used for encoding landmark to URL
CPosLandmarkEncoder* encoder =
CPosLandmarkEncoder::NewL( KUrlMimeType );
CleanupStack::PushL( encoder );
// Set output buffer into which the encoded URL will be written
CBufBase* outputBuffer = encoder->SetUseOutputBufferL();
// Add the landmark to be encoded
encoder->AddLandmarkL( aLandmark );
// Perform required operation on the outputBuffer
// Delete the buffer
delete outputBuffer;
// Finalize encoding
ExecuteAndDeleteLD( encoder->FinalizeEncodingL() );
CleanupStack::PopAndDestroy( encoder );
}
Related APIs
-
CPosLandmarkEncoder
-
CPosLandmarkEncoder::AddLandmarkL()
-
CPosLandmarkEncoder::FinalizeEncodingL().
Parsing URL to obtain a landmark
The client can parse an URL and decode the landmark information present
in the URL by using the
CPosLandmarkParser
class.In order
to do this,the client has to first create an instance of the
CPosLandmarkParser
with
the MIME type as the hostname of the URL( which is 'maps.ovi.com' ).
The URL can be provided as an input buffer or input file by using the
CPosLandmarkParser::SetInputBuffer
method and CPosLandmarkParser::SetInputFileL or CPosLandmarkParser::SetInputFileHandleL
methods respectively.
The URL can then be parsed by calling the CPosLandmarkParser::ParseContentL
method.This method returns a pointer to the
CPosLmOperation class
, which is then used to call the
CPosLmOperation::ExecuteL
method to complete the parsing operation.
The parsed landmark can then be retrieved using the
CPosLandmarkParser::LandmarkLC
method.
The sequence diagram below describes basic steps a client does to parse
an URLand decode it to a landmark Currently decoding of only a single landmark
is supported.
The following example shows how the client can parse an URL using
CPosLandmarkParser
class.
void ParseURLtoLandmark ( TDesC& aUrl )
{
//Mime type used for encoding URL
_LIT8( KUrlMimeType , "maps.ovi.com" );
// Create the parser to be used for parsing the URL
CPosLandmarkParser* parser =
CPosLandmarkParser::NewL( KUrlMimeType );
CleanupStack::PushL( parser );
// Set the input buffer that contains the URL to be parsed
parser->SetInputBuffer( aUrl );
// Parse the URL
CPosLmOperation* op = parser->ParseContentL();
CleanupStack::PushL( op );
// Execute the operation in one batch
op -> ExecuteL();
// Retrieve the parsed landmark
CPosLandmark* parsedLandmark = parser->LandmarkLC();
// Client can perform required operation on the parsedLandmark
CleanupStack::PopAndDestroy( parsedLandmark );
CleanupStack::PopAndDestroy( op );
CleanupStack::PopAndDestroy( parser );
}
Related APIs
Related APIs
-
CPosLandmarkEncoder
-
CPosLandmarkParser
Incremental operations
Some operations in Landmarks API can take a long time to complete. It is
recommended to run them incrementally. The client can use an active object
to run the incremental operations in the background so that other tasks can
be handled in the meantime, in particular handling UI events. To use an incremental
operation in Landmarks API, the classes described in the
Incremental operations
section
are used.
The following sequence shows a typical usage of an incremental operation.
-
The client requests an incremental operation, for example
CPosLandmarkDatabase::CompactL()
.
-
The Landmarks API method returns a
CPosLmOperation
object,
which the client takes ownership of.
-
The client uses an active object and calls
CPosLmOperation::NextStep()
once
every time the active object is scheduled.
NextStep()
returns
a progress value, which the client uses to display a progress bar to the user.
The client stops when
NextStep()
reports the status
KErrNone
or
an error code.
-
When
NextStep()
reports that the operation is complete,
the client is responsible for deleting the
CPosLmOperation
object.
The operation can be cancelled by deleting the operation object before
the operation is complete.
Note:
Changes that were already done before
the operation was cancelled are not rolled back. These changes will be a part
of the database.
Note:
It is still possible to run the operation all at once. This
is done by calling
CPosLmOperation::ExecuteL()
instead
of
CPosLmOperation::NextStep()
. If there is some error,
ExecuteL()
will
leave. There is a utility method,
ExecuteAndDeleteLD()
,
which first calls
ExecuteL()
and then deletes the operation
object. The utility method leaves if the operation fails. This utility method
is useful when the client does not need to use the operation object after
it has completed.
ExecuteAndDeleteLD( database->InitializeL() );
Note:
The usage of
ExecuteL()
and
NextStep()
cannot
be mixed. For instance, if
NextStep()
has been called, any
call to
ExecuteL()
will panic.
The next example shows how to handle the compaction of a landmark database
using incremental execution of operations.
CCompactHandler
is
responsible for the compact operation, and to be able to handle incremental
execution asynchronously, it inherits from
CActive
.
The
CCompactHandler
class is defined as follows:
class CCompactHandler : public CActive
{
public:
CCompactHandler( CPosLandmarkDatabase* aDatabase );
virtual ~CCompactHandler();
void CompactIfNeededL();
public: // from CActive
void RunL();
void DoCancel();
private:
CPosLandmarkDatabase* iDatabase;
CPosLmOperation* iCompactOperation;
TReal32 iProgress;
};
The following code section shows implementation of
CCompactHandler
.
CCompactHandler::CCompactHandler( CPosLandmarkDatabase* aDatabase )
: CActive( EPriorityIdle ), iDatabase( aDatabase )
{
}
CCompactHandler::~CCompactHandler()
{
Cancel();
delete iCompactOperation;
}
void CCompactHandler::CompactIfNeededL()
{
// Only compact if not started yet.
if ( !iCompactOperation )
{
CPosLandmarkDatabase::TSize size = iDatabase->SizeL();
// When to compact is up to the client.
// In this example we compact when
// less than 70% of the database is used.
const TReal32 KPercentage = 0.70f;
if ( size.iUsage < KPercentage )
{
iCompactOperation = iDatabase->CompactL();
}
iCompactOperation->NextStep( iStatus, iProgress );
SetActive();
}
}
void CCompactHandler::RunL()
{
if ( iStatus == KPosLmOperationNotComplete )
{ // The compact operation has not completed.
// Use the value iProgress to show progress bar to the phone user.
// Perform the next compact step
iCompactOperation->NextStep( iStatus, iProgress );
SetActive();
}
else
{ // The compact operation has completed.
if ( iStatus != KErrNone )
{
// Notify user of error
}
delete iCompactOperation;
iCompactOperation = NULL;
}
}
void CCompactHandler::DoCancel()
{
// Cancel is done by deleting the operation object.
delete iCompactOperation;
iCompactOperation = NULL;
}
Related APIs
-
CActive
-
CCompactHandler
-
CPosLandmarkDatabase::CompactL()
-
CPosLmOperation
-
CPosLmOperation::ExecuteL()
-
CPosLmOperation::NextStep()
-
ExecuteL()
-
KErrNone
-
NextStep()
Error handling
Landmarks API uses the standard Symbian error reporting mechanism. In case
of an irrecoverable error, panics are used. Otherwise, errors are reported
through return codes or leaves.
For incremental operations (see
Executing incremental operations
section),
CPosLmOperation::NextStep()
returns
a status, which indicates if there has been an error.
The following table lists the panic codes defined by Landmarks API and
other Landmarks APIs (Landmarks Search API and Landmarks Database Management
API). The panic category is "Landmarks Client".
Landmarks panic codes
0
|
EPosInvalidPositionFieldId
|
A client has specified a position field ID that is invalid for the
landmark.
|
1
|
EPosNoneOrMultipleLandmarkAttributeSet
|
A client has specified none or multiple landmark attributes.
|
2
|
EPosSpecifiedIntervalLiesOutsideIteratedSet
|
A client has specified an interval that lies partially outside the
iterated set.
|
3
|
EPosNaNCoordinate
|
A client has specified a coordinate with latitude and/or longitude
set to NaN.
|
4
|
EPosInvalidLandmarkAttribute
|
A client has specified a landmark attribute that is invalid.
|
5
|
EPosInvalidValueSpecifiedInResourceFile
|
An invalid value has been detected in an internal resource file. Configuration
problem.
|
6
|
EPosInvalidPartialReadParameters
|
The client has specified invalid partial read parameters in
CPosLmPartialReadParameters
.
|
7
|
EPosInvalidRequestedPositionFields
|
The client has specified invalid requested position fields in
CPosLmPartialReadParameters
.
|
8
|
EPosNegativeValue
|
The client specified a negative value where a negative value was not
allowed.
|
9
|
EPosInvalidOperationMode
|
Invalid operation mode. Caused by mixed calls to
NextStep
and
ExecuteL
for
a
CPosLmOperation
object or subsequent calls to
NextStep
.
|
10
|
EPosInvalidEnumValue
|
Invalid enumeration value.
|
11
|
EPosLmProtocolBreak
|
The protocol of
CPosLandmarkEncoder
or
CPosLandmarkParser
is
not followed.
|
12
|
EPosLmInvalidArgument
|
A client has passed an invalid argument.
|
14
|
EPosInvalidIndex
|
A client has specified an invalid index.
|
15
|
EPosInvalidItemType
|
A client has specified an invalid item type.
|
16
|
EPosSearchOperationInUse
|
A client has tried to set/unset display data during an ongoing search.
|
Related APIs
-
CPosLandmarkEncoder
-
CPosLandmarkParser
-
CPosLmOperation
-
CPosLmOperation::NextStep()
-
CPosLmPartialReadParameters
-
ExecuteL
-
NextStep
Memory overhead
When using Landmarks API, the memory overhead is dependent on the amount
of classes instantiated by the client, but there are also some cases where
extra memory usage can be involved and cannot be controlled by the client.
CPosLmItemIterator
objects may use a caching scheme
to enable fast access to landmarks that have already been read. This means
that the iterator can use memory that the client cannot control. This memory
will be released when the iterator is destroyed.
CPosLandmarkDatabase::PreparePartialLandmarksL()
allocates
a lot of information on the heap if many landmarks are read, especially if
partial read parameters are set to include a lot of landmark attributes. These
landmark objects are stored inside the
CPosLmOperation
object
until retrieved by the client.
Clients take ownership of the
CPosLmOperation
objects
and should delete them as soon as they are not needed in order to release
unused heap memory.
Related APIs
-
CPosLandmarkDatabase::PreparePartialLandmarksL()
-
CPosLmItemIterator
-
CPosLmOperation
Extensions to the API
This API does not allow extensions.
Security issues
Landmarks are considered as important user data and this applies some access
limitations to client applications. For example, in order to be able to read
landmarks from landmark database client must have
ReadUserData
capability
and
WriteUserData
in order to modify it. Whenever special
capabilities are needed to work with landmarks database, they are listed in
appropriate class and method descriptions.
Related APIs
-
ReadUserData
-
WriteUserData
Glossary
Abbreviations
Abbreviations
WGS 84
|
World Geodetic System 1984
|
GPX
|
GPS Exchange (format)
|
Definitions
Definitions
Landmark
|
A landmark is a named object that contains a location. The location
can be defined by various attributes, e.g. WGS 84 coordinates or a textual
address.
|
Landmark category
|
A landmark can be categorized by assigning a landmark category to it.
A typical landmark category is “Restaurant”.
|
Landmark database
|
Persistent storage of a collection of landmarks and landmark categories.
|
|