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
for
checking if the database has to be initialized and a method CPosLandmarkDatabase
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.
Figure 7: Using database sequence diagram
It is recommended to execute initialization operation incrementally (i.e. asynchronously), see Executing incremental operations for more details.
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.
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
method
and compact the database if there is too much unused space. CPosLandmarkDatabase
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%.
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.
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
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);
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.
Figure 8: Partial read sequence diagram
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; }
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
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 ); }
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 );
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 ); }
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.
CPosLandmarkDatabase
instance.
CPosLandmarkDatabase
,
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.
NotifyDatabaseEvent()
request
to listen to the next event.
NotifyDatabaseEvent()
.
If the client has an outstanding request to NotifyDatabaseEvent()
,
it can cancel the request by calling NotifyDatabaseEvent()
.
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:
Event type | Description | Item Id |
EPosLmEventUnknownChanges
|
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.
|
|
|
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; }
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".
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
.
The sequence diagram below describes basic steps a client does to export landmarks from a database to a file.
Figure 9: Exporting landmarks sequence diagram
The following example shows how the client can export landmarks to a file
using the CPosLandmarkDatabase
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 ); }
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
first.
If the content is not already parsed, this will be handled by the import operation.
There are two different CPosLandmarkDatabase
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
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
method
cannot be executed synchronously using User::WaitForRequest()
for
the import operations. Doing so may cause the operation to hang. CPosLmOperation
must
be executed using an active object.
The diagram below describes general steps, which client does when imports landmarks from a file.
Figure 10: Importing landmarks sequence diagram
The following example shows how the client can import landmarks from file
using the CPosLandmarkDatabase
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 ); }
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
.
The Landmarks API method returns a CPosLmOperation
object,
which the client takes ownership of.
The client uses an active object and calls CPosLmOperation
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
instead
of CPosLmOperation
. 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; }
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
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".
Panic code | Panic name | Description |
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. |
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
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.
This API does not allow extensions.
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.