MeeGo 1.2 Harmattan Developer Documentation Develop for the Nokia N9

Landmark Examples

The Landmarks portion of the Location API enables the creation, retrieval, updating and deletion of landmarks from arbitrary data stores. The following page demonstrates how to perform these operations.

Namespace

The QtMobility APIs are placed into the QtMobility namespace. This is done to facilitate the future migration of QtMobility APIs into Qt. See the Quickstart guide for an example on how the namespace impacts on application development.

Creating/saving categories and landmarks

Synchronous

Creating/saving a category

The following example demonstrates how to synchronously add a category. We create a QLandmarkCategory instance, set the desired properties and then use a QLandmarkManager instance to save it. When the category is saved, it is assigned a QLandmarkCategoryId which is why it passed as a pointer.

     QLandmarkCategory cafes;
     cafes.setName("Cafes");
     cafes.setIconUrl(QUrl("cafe.png"));
     lmManager->saveCategory(&cafes);  //lmManager is a QLandmarkManager *

Creating/saving a landmark

The following example demonstrates synchronously adding a landmark. We create a QLandmark instance, set the desired properties and then use a QLandmarkManger instance to save it. When the landmark is saved, it is assigned a QLandmarkId, which is why it is passed as a pointer.

     QLandmark monks;
     monks.setName("Monk's cafe");
     monks.setCoordinate(QGeoCoordinate(40.81, 73.97));

     QGeoAddress address;
     address.setStreet("2880 112th Street");
     address.setCity("New York City");
     address.setState("New York");
     address.setCountry("United States");
     address.setCountryCode("US");
     monks.setAddress(address);

     monks.setDescription("Jerry's favourite diner");
     monks.addCategoryId(cafes.categoryId());

     lmManager->saveLandmark(&monks); //lmManager  is a QLandmarkManager*

Asynchronous

Creating/saving a category

We create a QLandmarkCategory instance and set the desired properties. Next we have an instance of a QLandmarkCategorySaveRequest and set the category we want to save. We then connect the stateChanged() signal up to a slot which watches the state of the request. To begin the request we invoke start().

 void RequestExample::categorySaveRequest()
 {
     QLandmarkCategory cafes;
     cafes.setName("Cafes");
     cafes.setIconUrl(QUrl("cafe.png"));

     //catSaveRequest was previously created with catSaveRequest = new QLandmarkCategorySaveRequest(lmManager)
     //where lmManager is a QLandmarkManager *
     catSaveRequest->setCategory(cafes);

     connect(catSaveRequest, SIGNAL(stateChanged(QLandmarkAbstractRequest::State)), this,
             SLOT(categorySaveRequestHandler(QLandmarkAbstractRequest::State)));
     if (!catSaveRequest->start())
         qDebug() << "Unable to save category, error code: " << catSaveRequest->error();
     else
         qDebug() << "Saveing category; awaiting results...";
 }

For brevity, the slot does not process all the different request states or error codes. In our example we watch for the QLandmarkAbstractRequest::FinishedState and see if there are any errors or not. We may reuse the QLandmarkCategorySaveRequest by setting another category and running start() again.

 void RequestExample::categorySaveRequestHandler(QLandmarkAbstractRequest::State state)
 {
     if (state == QLandmarkAbstractRequest::FinishedState) {
         if (catSaveRequest->error() == QLandmarkManager::NoError) {
             qDebug() << "Category save successfully completed";
         }
         else {
             qDebug() << "Category save was unsuccessful";
         }
     }
 }

Creating/saving a landmark

We create a QLandmark instance and set the desired properties. Next we have an instance of a QLandmarkSaveRequest and set the landmark we want to save. We then connect the stateChanged() signal up to a slot which watches the state of the request. To begin the request we invoke start().

 void RequestExample::landmarkSaveRequest()
 {
     //Creating and saving a landmark
     QLandmark monks;
     monks.setName("Monk's cafe");
     monks.setCoordinate(QGeoCoordinate(40.81, 73.97));

     QGeoAddress address;
     address.setStreet("2880 112th Street");
     // ...
     address.setCountryCode("US");
     monks.setAddress(address);
     monks.setDescription("Jerry's favourite diner");

     //lmSaveRequest was previously created with lmSaveRequest = new QLandmarkSaveRequest(lmManager);
     //where lmManager is a QLandamrkManager *
     lmSaveRequest->setLandmark(monks);

     connect(lmSaveRequest, SIGNAL(stateChanged(QLandmarkAbstractRequest::State)), this,
             SLOT(landmarkSaveRequestHandler(QLandmarkAbstractRequest::State)));
     if (!lmSaveRequest->start())
         qDebug() << "Unable to save landmark, error code: " << lmSaveRequest->error();
     else
         qDebug() << "Saving landmark; awaiting results...";
 }

For brevity, the slot does not process all the different request states. In our example we watch for the QLandmarkAbstractRequest::FinishedState and see if there are any errors or not. We may reuse the QLandmarkSaveRequest by setting another landmark and running start() again.

 void RequestExample::landmarkSaveRequestHandler(QLandmarkAbstractRequest::State state)
 {
     if (state == QLandmarkAbstractRequest::FinishedState) {
         if (lmSaveRequest->error() == QLandmarkManager::NoError) {
             qDebug() << "Landmark save successfully completed";
         }
         else {
             qDebug() << "Landmark save was unsuccessful";
         }
     }
 }

Retrieving categories and landmarks

Synchronous

Retrieving categories

To retrieve categories we simply make the appropriate call to the QLandmarkManager:

 QList<QLandmarkCategory> categories = lmManager->categories();
 foreach(QLandmarkCategory category, categories) {
     qDebug() << "Found category: " << category.name();
 }

When retrieving categories we may do so by the category ids. When the category data is needed we may use the id to retrieve a category object:

 QList<QLandmarkCategoryId> categoryIds = lmManager->categoryIds();
 foreach(QLandmarkCategoryId id, categoryIds) {
     qDebug() << "Found category: " << lmManager->category(id).name();
 }

Retrieving landmarks

To retrieve landmarks we create an appropriate filter, in this case a category filter. In this example, we also provide a limit of 5 and offset of 0 to only retrieve the first five landmarks and we provide a sort order to the QLandmarkManager.

 QList<QLandmark> landmarks;
 QLandmarkCategoryFilter filter;
 //category is a previously retrieved QLandmarkCategory
 filter.setCategory(category);
 QLandmarkNameSort sortOrder(Qt::AscendingOrder);
 landmarks = lmManager->landmarks(filter, 5, 0, sortOrder);
 foreach(const QLandmark &landmark, landmarks) {
     qDebug() << "Found landmark:" << landmark.name();
 }

Alternatively we can retrieve just the landmark ids. When the landmark data is needed at a later time we can use the id to retrieve the landmark object:

 //retrieval via ids
 QList<QLandmarkId> landmarkIds;
 QLandmarkCategoryFilter filter;
 //category is a previously retrieved QLandmarkCategory
 filter.setCategory(category);
 QLandmarkNameSort sortOrder(Qt::AscendingOrder);
 landmarkIds = lmManager->landmarkIds(filter, 5, 0, sortOrder);
 foreach(const QLandmarkId &id, landmarkIds) {
     qDebug() << "Found landmark:" << lmManager->landmark(id).name();
 }

Asynchronous

Retrieving categories

To retrieve categories we can use a QLandmarkCategoryFetchRequest (or if we wish to fetch id's then a QLandmarkCategoryIdFetchRequest). The request's stateChanged() signal is connected to a slot which detects whether the operation is complete. To begin the request we invoke start().

 //catFetchRequest was previously created with catFetchRequest = new QLandmarkCategoryFetchRequest(lmManager);
 //where lmManager is a QLandmarkManager*

 connect(catFetchRequest, SIGNAL(stateChanged(QLandmarkAbstractRequest::State)),
         this, SLOT(categoryFetchRequestHandler(QLandmarkAbstractRequest::State)));

 if(!catFetchRequest->start()) {
     qDebug() << "Unable to request categories, error code:" << catFetchRequest->error();
     QCoreApplication::exit(0);
 } else {
     qDebug() << "Requested categories, awaiting results...";
 }

For brevity, the slot does not process all the different request states. In our example, we watch for the QLandmarkAbstractRequest::FinishedState and if there are no errors, print out the categories.

 void RequestExample::categoryFetchRequestHandler(QLandmarkAbstractRequest::State state)
 {
     if (state == QLandmarkAbstractRequest::FinishedState) {
         if (catFetchRequest->error() == QLandmarkManager::NoError) {
             QList<QLandmarkCategory> categories = catFetchRequest->categories();
             qDebug() << "Category fetch successfully completed";
             for(int i=0; i < categories.count(); ++i) {
                 qDebug() << categories[i].name();
             }
         }
         else {
             qDebug() << "Category fetch was unsuccessful";
         }
     }
 }

Retrieving landmarks

To retrieve landmarks we create an appropriate filter, in this case a category filter, and set it in a QLandmarkFetchRequest. In this example, we also provide a limit of 5 and offset of 0 to only retrieve the first five landmarks and we provide a sort order to the QLandmarkFetchRequest. (If we wanted to operate with ids we would use a QLandmarkIdFetchRequest instead). The request's stateChanged() signal is connected to a slot which detects whether the operation is complete. To begin the request we invoke start().

 QLandmarkCategoryFilter filter;
 //category is a previously retrieved QLandmarkCategory
 filter.setCategory(category);
 QLandmarkNameSort sortOrder(Qt::AscendingOrder);

 //lmFetchRequest was previously created with lmFetchRequest = new QLandmarkFetchRequest(lmManager);
 //where lmManager is a QLandmarkManger *
 lmFetchRequest->setFilter(filter);
 lmFetchRequest->setLimit(5);
 lmFetchRequest->setOffset(0);
 lmFetchRequest->setSorting(sortOrder);

 connect(lmFetchRequest, SIGNAL(stateChanged(QLandmarkAbstractRequest::State)),
         this, SLOT(landmarkFetchRequestHandler(QLandmarkAbstractRequest::State)));

 if(!lmFetchRequest->start()) {
     qDebug() << "Unable to request landmarks, error code:" << lmFetchRequest->error();
     QCoreApplication::exit(0);
 } else {
     qDebug() << "Requested landmarks, awaiting results...";
 }

For brevity, the slot does not process all the different request states. In our example, we watch for the QLandmarkAbstractRequest::FinishedState and if there are no errors, print out the landmarks.

 void RequestExample::landmarkFetchRequestHandler(QLandmarkAbstractRequest::State state)
 {
     if (state == QLandmarkAbstractRequest::FinishedState) {
         previousLastIndex = 0;
         if (lmFetchRequest->error() == QLandmarkManager::NoError) {
             qDebug() << "Landmark fetch successfully completed";
             QList<QLandmark> landmarks = lmFetchRequest->landmarks();
             for(int i=0; i < landmarks.count(); ++i) {
                 qDebug() << landmarks[i].name();
             }
         }
         else {
             qDebug() << "Landmark fetch was unsuccessful";
         }
     }
 }

Deleting categories and landmarks

Synchronous

Deleting a category

To remove a category we simply pass the category id to a QLandmarkManager.

 //category is a previously retrieved QLandmarkCategory object
 lmManager->removeCategory(category);

Deleting a landmark

To remove a landmark we simply pass the landmark id to a QLandmarkManager.

 //landmark is a previously retrieved QLandmark object
 lmManager->removeLandmark(landmark);

Asynchronous

Deleting a category

To remove a category we use a QLandmarkCategoryRemoveRequest and set the id of the category we want to remove. We then connect the stateChanged() signal up to a slot which watches the state of the request. To begin the request we invoke start()

 void RequestExample::categoryRemoveRequest()
 {
     //catRemoveRequest was created previously with catRemoveRequest = new QLandmarkCategoryRemoveRequest(lmManager);
     //where lmManager is a QLandmarkManager*
     catRemoveRequest->setCategory(category); //category is a previously retrieved QLandmarkCategory

     connect(catRemoveRequest, SIGNAL(stateChanged(QLandmarkAbstractRequest::State)),
         this, SLOT(categoryRemoveRequestHandler(QLandmarkAbstractRequest::State)));

     if(!catRemoveRequest->start()) {
         qDebug() << "Unable to request category removal, error code:" << catRemoveRequest->error();
         QCoreApplication::exit(0);
     } else {
         qDebug() << "Requested category removal, awaiting results...";
     }
 }

For brevity, the slot does not process all the different request states. In our example we watch for the QLandmarkAbstractRequest::FinishedState and see if there are any errors or not. We may reuse the QLandmarkCategoryRemoveRequest by setting another category id and running start() again.

 void RequestExample::categoryRemoveRequestHandler(QLandmarkAbstractRequest::State state)
 {
     if (state == QLandmarkAbstractRequest::FinishedState) {
         if (catRemoveRequest->error() == QLandmarkManager::NoError) {
             qDebug() << "Category remove successfully completed";
         }
         else {
             qDebug() << "Category remove was unsuccessful";
         }
     }
 }

Deleting a landmark

To remove a landmark we use a QLandmarkRemoveRequest and set the id of the landmark we want to remove. We then connect the stateChanged() signal up to a slot which watches the state of the request. To begin the request we invoke start()

 void RequestExample::landmarkRemoveRequest()
 {
     //lmRemoveRequest was created previously with lmRemoveRequest = new QLandmarkRemoveRequest(lmManager);
     //where lmManager is a QLandmarkManager*
     lmRemoveRequest->setLandmark(landmark);  //landmark is a previously retrieved QLandmark

     connect(lmRemoveRequest, SIGNAL(stateChanged(QLandmarkAbstractRequest::State)), this,
             SLOT(landmarkRemoveRequestHandler(QLandmarkAbstractRequest::State)));
     if (!lmRemoveRequest->start())
         qDebug() << "Unable to remove landmark, error code: " << lmRemoveRequest->error();
     else
         qDebug() << "Removing landmark; awaiting results...";
 }

For brevity, the slot does not process all the different request states. In our example we watch for the QLandmarkAbstractRequest::FinishedState and see if there are any errors or not. We may reuse the QLandmarkRemoveRequest by setting another landmark id and running start() again.

 void RequestExample::landmarkRemoveRequestHandler(QLandmarkAbstractRequest::State state)
 {
     if (state == QLandmarkAbstractRequest::FinishedState) {
         if (lmRemoveRequest->error() == QLandmarkManager::NoError) {
             qDebug() << "Landmark removal successfully completed";
         }
         else {
             qDebug() << "Landmark removal was unsuccessful";
         }
     }
 }

Importing Landmarks

Synchronous

To import landmarks from a file we can simply provide the filename to the manager (the manager will try to automatically detect the file format). If we know the format we can provide one of the format strings as a parameter. Using a QLandmarkManager::TransferOption, an option for controlling import/export behavior, we can choose to include category data that comes with the landmarks(default), exclude category data meaning that the landmarks will not be associated with any categories or we can attach the landmarks to a single category meaning all the imported landmarks will be assigned to the given category.

Note: Typically an import operation will take a long time to execute, it is therefore recommended that landmarks be imported asynchronously rather than synchronously.

 //Import landmarks by providing just a file name.
 landmarkManager->importLandmarks("places.lmx");

 //Import landmarks by providing a given format.
 landmarkManager->importLandmarks("places.xml", QLandmarkManager::Lmx);

 //Import landmarks but ignore all categories
 landmarkManager->importLandmarks("places.lmx",QLandmarkManager::Lmx,QLandmarkManager::ExcludeCategoryData);

 //Import landmarks and assign them all to a single category.
 landmarkManager->importLandmarks("places.lmx", QLandmarkManager::Lmx, QLandmarkManager::AttachSingleCategory,categoryId);

Asynchronous

To import landmarks we use a QLandmarkImportRequest and set the filename of the file we want to import. We can set other import parameters as necessary such as the file format or the transfer option. We then connect the stateChanged() signal up to a slot which watches the state of the request. To begin the request we invoke start()

 void RequestExample::landmarkImportRequest()
 {
     //lmImportRequest was created with lmImportRequest = new QLandmarkImportRequest(lmManager)
     //in the ctor, where lmManager is a QLandmarkManager*
     lmImportRequest->setFileName("places.lmx");

     //if we wanted to we could specify various import parameters
     // lmImportRequest->setFormat(...);
     // lmImportRequest->setTransferOption(...);

     connect(lmImportRequest, SIGNAL(stateChanged(QLandmarkAbstractRequest::State)), this,
             SLOT(landmarkImportRequestHandler(QLandmarkAbstractRequest::State)));
     if (!lmImportRequest->start())
         qDebug() << "Unable to import landmarks, error code: " << lmImportRequest->error();
     else
         qDebug() << "Importing landmarks; awaiting results...";
 }

For brevity, the slot does not process all the different request states. In our example we watch for the QLandmarkAbstractRequest::FinishedState and see if there are any errors or not. We may reuse the QLandmarkImportRequest by setting filename and running start() again.

 void RequestExample::landmarkImportRequestHandler(QLandmarkAbstractRequest::State state)
 {
     if (state == QLandmarkAbstractRequest::FinishedState) {
         if (lmImportRequest->error() == QLandmarkManager::NoError) {
             qDebug() << "Landmark import successfully completed";
         }
         else {
             qDebug() << "Landmark import was unsuccessful";
         }
     }
 }

Exporting Landmarks

Synchronous

To export landmarks we can pass a filename and format to the manager. If we only want to export a subset of landmarks we can provide a list of landmark ids to export. We may also use a QLandmarkManager::TransferOption to decide whether we want to include(default) or exclude category data for the export (This will only have an affect if the supplied format supports categories.) Typically an export operation will take a long time to execute, it is therefore recommended that landmarks be exported asynchronously rather than synchronously.

 //export to a given file with a specified format
 landmarkManager->exportLandmarks("places.lmx", QLandmarkManager::Lmx);

 //export a subset of landmarks defined by a set of landmark ids
 landmarkManager->exportLandmarks("places.lmx", QLandmarkManager::Lmx,landmarkIds);

 //Export landmarks but do not include any category data.
 //(If we provide an empty list of landmark ids, then all landmarks are exported)
 landmarkManager->exportLandmarks("places.lmx", QLandmarkManager::Lmx,landmarkIds, QLandmarkManager::ExcludeCategoryData);

Asynchronous

To export landmarks we use a QLandmarkExportRequest and set the filename of the file we want to export to, as well as the format we wish to use. We can set other export parameters as necessary, such as a list of ids of landmarks we want to export or the transfer option. We then connect the stateChanged() signal up to a slot which watches the state of the request. To begin the request we invoke start()

 void RequestExample::landmarkExportRequest()
 {
     //lmExportRequest was created with lmExportRequest = new QLandmarkExportRequest(lmManager)
     //in the ctor, where lmManager is a QLandmarkManager*
     lmExportRequest->setFileName("places.lmx");
     lmExportRequest->setFormat(QLandmarkManager::Lmx);

     //if we wanted to we could specify various export parameters
     // lmExportRequest->setLandmarkIds(...);
     // lmExportRequest->setTransferOption(...);

     connect(lmExportRequest, SIGNAL(stateChanged(QLandmarkAbstractRequest::State)), this,
             SLOT(landmarkExportRequestHandler(QLandmarkAbstractRequest::State)));
     if (!lmExportRequest->start())
         qDebug() << "Unable to export landmarks, error code: " << lmExportRequest->error();
     else
         qDebug() << "Exporting landmarks; awaiting results...";
 }

For brevity, the slot does not process all the different request states. In our example we watch for the QLandmarkAbstractRequest::FinishedState and see if there are any errors or not. We may reuse the QLandmarkExportRequest by setting another filename and/or format and running start() again.

 void RequestExample::landmarkExportRequestHandler(QLandmarkAbstractRequest::State state)
 {
     if (state == QLandmarkAbstractRequest::FinishedState) {
         if (lmExportRequest->error() == QLandmarkManager::NoError) {
             qDebug() << "Landmark export successfully completed";
         }
         else {
             qDebug() << "Landmark export was unsuccessful";
         }
     }
 }

C++ Examples

There are no C++ only, documented examples of the Landmarks API. However, there is the Maps Demo Tutorial which is C++ only, though being a tutorial it is longer and more complicated than an example.

QML Examples

Landmark Map QML Example

The Landmark Map Example shows how a mobile application might display some map information which includes landmark information imported from a landmark file.

Map Viewer QML Example

The Map Viewer example displays a map of the current location or failing that a hard-coded default location to display a typical map navigation application in form typical of a mobile phone.