LocationThe Location API provides a library for location positioning, landmark management and mapping and navigation. NamespaceThe QtMobility APIs are placed into the QtMobility namespace. This is done to facilitate the future migration of Mobility APIs into Qt. See the Quickstart guide for an example on how the namespace impacts on application development. Location PositioningLocation data involves a precisely specified position on the Earth's surface — as provided by a latitude-longitude coordinate — along with associated data, such as:
This data can be extracted through a variety of methods. One of the most well known methods of positioning is GPS (Global Positioning System), a publicly available system that uses radiowave signals received from Earth-orbiting satellites to calculate the precise position and time of the receiver. Another popular method is Cell ID positioning, which uses the cell ID of the cell site that is currently serving the receiving device to calculate its approximate location. These and other positioning methods can all be used with the Location API; the only requirement for a location data source within the API is that it provides a latitude-longitude coordinate with a date/time value, with the option of providing the other attributes listed above. Location data sources are created by subclassing QGeoPositionInfoSource and providing QGeoPositionInfo objects through the QGeoPositionInfoSource::positionUpdated() signal. Clients that require location data can connect to the positionUpdated() signal and call startUpdates() or requestUpdate() to trigger the distribution of location data. A default position source may be available on some platforms. Call QGeoPositionInfoSource::createDefaultSource() to create an instance of the default position source; the method returns 0 if no default source is available for the platform. The QGeoAreaMonitor class enables client applications to be notified when the receiving device has moved in or out of a particular area, as specified by a coordinate and radius. If the platform provides built-in support for area monitoring, QGeoAreaMonitor::createDefaultMonitor() returns an instance of the default area monitor. Satellite information can also be distributed through the QGeoSatelliteInfoSource class. Call QGeoSatelliteInfoSource::createDefaultSource() to create an instance of the default satellite data source for the platform, if one is available. Alternatively, clients can subclass it to provide a custom satellite data source. Requesting location data from data sourcesTo receive data from a source, connect to its positionUpdated() signal, then call either startUpdates() or requestUpdate() to begin. Here is an example of a client that receives data from the default location data source, as returned by QGeoPositionInfoSource::createDefaultSource(): class MyClass : public QObject { Q_OBJECT public: MyClass(QObject *parent = 0) : QObject(parent) { QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(this); if (source) { connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo))); source->startUpdates(); } } private slots: void positionUpdated(const QGeoPositionInfo &info) { qDebug() << "Position updated:" << info; } }; Controlling aspects of data sourcesThe QGeoPositionInfoSource::setUpdateInterval() method can be used to control the rate at which position updates are received. For example, if the client application only requires updates once every 30 seconds, it can call setUpdateInterval(30000). (If no update interval is set, or setUpdateInterval() is called with a value of 0, the source uses a default interval or some other internal logic to determine when updates should be provided.) QGeoPositionInfoSource::setPreferredPositioningMethods() enables client applications to request that a certain type of positioning method be used. For example, if the application prefers to use only satellite positioning, which offers fairly precise outdoor positioning but can be a heavy user of power resources, it can call this method with the QGeoPositionInfoSource::SatellitePositioningMethods value. However, this method should only be used in specialized client applications; in most cases, the default positioning methods should not be changed, as a source may internally use a variety of positioning methods that can be useful to the application. Reading NMEA dataNMEA is a common text-based protocol for specifying navigational data. For convenience, the QNmeaPositionInfoSource is provided to enable client applications to read and distribute NMEA data in either real-time mode (for example, when streaming from a GPS device) or simulation mode (for example, when reading from a NMEA log file). In simulation mode, the source will emit updates according to the time stamp of each NMEA sentence to produce a "replay" of the recorded data. Example: Creating a custom location data sourceGenerally, the capabilities provided by the default position source as returned by QGeoPositionInfoSource::createDefaultSource(), along with the QNmeaPositionInfoSource class, are sufficient for retrieving location data. However, in some cases developers may wish to write their own custom location data sources. The LogFilePositionSource class in examples/logfilepositionsource shows how to subclass QGeoPositionInfoSource to create a custom location data source. This example class reads location data from a text file, log.txt. The file specifies location data using a simple text format: it contains one location update per line, where each line contains a date/time, a latitude and a longitude, separated by spaces. The date/time is in ISO 8601 format and the latitude and longitude are in degrees decimal format. Here is an excerpt from log.txt: 2009-08-24T22:25:01 -27.576082 153.092415 2009-08-24T22:25:02 -27.576223 153.092530 2009-08-24T22:25:03 -27.576364 153.092648 The class reads this data and distributes it via the positionUpdated() signal. Here is the definition of the LogFilePositionSource class: class LogFilePositionSource : public QGeoPositionInfoSource { Q_OBJECT public: LogFilePositionSource(QObject *parent = 0); QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const; PositioningMethods supportedPositioningMethods() const; int minimumUpdateInterval() const; public slots: virtual void startUpdates(); virtual void stopUpdates(); virtual void requestUpdate(int timeout = 5000); private slots: void readNextPosition(); private: QFile *logFile; QTimer *timer; QGeoPositionInfo lastPosition; }; The main methods overrided by the subclass are:
When a position update is available, the subclass emits the positionUpdated() signal. Here are the key methods in the class implementation: LogFilePositionSource::LogFilePositionSource(QObject *parent) : QGeoPositionInfoSource(parent), logFile(new QFile(this)), timer(new QTimer(this)) { connect(timer, SIGNAL(timeout()), this, SLOT(readNextPosition())); logFile->setFileName(QCoreApplication::applicationDirPath() + QDir::separator() + "simplelog.txt"); if (!logFile->open(QIODevice::ReadOnly)) qWarning() << "Error: cannot open source file" << logFile->fileName(); } void LogFilePositionSource::startUpdates() { int interval = updateInterval(); if (interval < minimumUpdateInterval()) interval = minimumUpdateInterval(); timer->start(interval); } void LogFilePositionSource::stopUpdates() { timer->stop(); } void LogFilePositionSource::requestUpdate(int /*timeout*/) { // For simplicity, ignore timeout - assume that if data is not available // now, no data will be added to the file later if (logFile->canReadLine()) readNextPosition(); else emit updateTimeout(); } void LogFilePositionSource::readNextPosition() { QByteArray line = logFile->readLine().trimmed(); if (!line.isEmpty()) { QList<QByteArray> data = line.split(' '); double latitude; double longitude; bool hasLatitude = false; bool hasLongitude = false; QDateTime timestamp = QDateTime::fromString(QString(data.value(0)), Qt::ISODate); latitude = data.value(1).toDouble(&hasLatitude); longitude = data.value(2).toDouble(&hasLongitude); if (hasLatitude && hasLongitude && timestamp.isValid()) { QGeoCoordinate coordinate(latitude, longitude); QGeoPositionInfo info(coordinate, timestamp); if (info.isValid()) { lastPosition = info; emit positionUpdated(info); } } } } The example includes a ClientApplication class that requests updates from the LogFilePositionSource class. Run the example to see the data that is received by ClientApplication. Before running the example, make sure you have done both make and make install. ExamplesFlickr DemoThe Flickr Demo uses the Location to download thumbnail images from Flickr relevant to the current location. Weather Info DemoThe Weather Info demo uses Location display data about the weather for the current location. Light Maps DemoThe Light Maps demo uses Location display a street map for the current location. Location classes
LandmarksThe Landmarks portion of the Location API facilitates the creation, retrieval, updating and deletion of landmarks from arbitrary data stores. A landmark is a location of some significance, also known as a point of interest and are represented as QLandmark objects. Related landmarks may be grouped into categories(QLandmarkCategory) such as restaurants or accommodation and each landmark can belong to more than one category. A landmark datastore is represented by a QLandmarkManager. The QLandmarkManager may be used to save, fetch and remove both landmarks and categories. When fetching landmarks we can provide various filters and sort orders to define the searching criteria and the order in which landmarks are returned. The QLandmarkManager also provides functionality to import and export landmarks as well as provide notifications whenever changes are detected. It should be noted that the Landmarks API provides both synchronous and asynchronous mechanisms to perform the above operations. Synchronous operations are provided the QLandmarkManager itself while the asynchronous operations are provided by various request classes. It is generally recommended that the asynchronous request classes classes be used as they are not subject to blocking which can be an issue if a datastore contains a significantly large number of landmarks or if the datastore is being accessed over a network. Landmark operation examplesFor more details see the Landmark Examples page for:
Managers and pluginsLandmark managers are identified by their manager name. Each manager name corresponds to a specific plugin/backend that implements the manager functionality. The manager name is typically a reverse domain string such as "com.nokia.qt.landmarks.engines.symbian". Typically a developer does not need to deal with the manager name as the default manager will be used when instantiating a QLandmarkManager without construction parameters. To implment your own plugin, you need to subclass QLandmarkManagerEngine and provide the implmementations for the virtual functions, and then create a QLandmarkMangerEngineFactory subclass that will instantiate your particular engine implementation. The following table shows names of the default managers for each platform and where the landmarks are stored.
These managers only store and retrieve landmark data locally. This landmark data is available to any application which accesses the manager and is thus shared between all applications. At present there are no managers which retrieve landmark data from online sources. For convenience, this documentations refers to the manager corresponding to com.nokia.qt.landmarks.engines.symbian as the symbian manager, the manager corresponding to com.nokia.qt.landmarks.engines.sqlite as the sqlite manager, and the manager corresponding to com.nokia.qt.landmarks.engines.sparql as the sparql manager. Variations between platforms/managersThe behaviour of some parts of the Landmarks API varies between platforms. A few of the major ones are mentioned below
Importing and Exporting LandmarksThe landmarks API supports import and exporting of landmarks. The file formats that are supported depends on the particular manager. The following table outline the formats that may be used for the default manager on each platform. You may also query the supported formats through the QLandmarkManager::supportedFormats() function.
During an import operation, every landmark from the import source will result in the creation of a new landmark, however any categories defined in the import source will be mapped to existing categories if possible. If a mappping cannot be found then a new category is created. During an import or export operation,the QLandmarkManager::TransferOption can be used to decide what to do with category data, provided the given format supports them. (For formats such as gpx which do not support categories, the transfer option is ignored). Typically, any categories are included as is with QLandmarkManager::IncludeCategoryData being the default option. You may choose to ignore any categories by providing using QLandmarkManager::ExcludeCategoryData. For an import operation, you can use QLandmarkManager::AttachSingleCategory in conjunction with a QLandmarkCategoryId, to have all imported landmarks be assigned to that category(any exisiting category associations defined in the import source are ignored). The export operation by default exports all landmarks within the manager. If you wish to export only a subset you can provide a list of landmark ids to do so. One caveat with exporting landmarks to gpx format is that the gpx does not support landmarks which have NaN latitude and longitude values. If you try to export all landmarks, then those landmarks with NaN values are skipped over. However if you provide a list of ids of landmarks to export, the export operation will fail if any one of those landmarks have NaN latitude or longitude values. Also note that when exporting landmarks in lmx format, the url of the landmark should be a valid URI as defined by RFC 2396 as amended by RFC 2732. The managers differ in behaviour with the symbian manager ignoring the url field during export if the URI is invalid while the sqlite and sparql manager will export the url and subsequently create an invalid lmx file (this issue is intended to be resolved in a future release). Landmark classesMain Landmark Classes
Landmark Selection classesLandmark selection is facilitated by filter and sort order classes. The filter classes define what criteria that landmarks must match and the sort order classes specify how the returned landmarks are sorted. Please note that sorting by distance is facilitated by the QLandmarkProximity class. Providing a QLandmarkProximity filter in an intersection filter will sort results in order of ascending distance (on the condition only a default sort order class is used in conjunction). The filter and sort order classes are used with either the QLandmarkManager class (for synchronous landmark selection) or the request classes for (asynchronous landmark selection) Filters
SortOrders
Asynchronous RequestsAsynchronous operations are facilitates by the request classes listed below:
Implementing backendsA manager backend may be implemented by subclassing QLandmarkManagerEngine, and providing a QLandmarkManagerEngineFactory which can instantiate it when required.
Maps and NavigationThe Maps and Navigation API is based on plugins. Since most providers of mapping, geocoding and routing information offer no guarantees that their data is interoperable with the data provided by other services, the plugins are used to group the functionality per service provider. The plugins are accessed via QGeoServiceProvider, and a Nokia based plugin is part of Qt Mobility. See the section The Nokia plugin for more details. QGeoMappingManager *mappingManager = 0; QGeoRoutingManager *routingManager = 0; QGeoSearchManager *searchManager = 0; QGeoServiceProvider serviceProvider("plugin name"); if (serviceProvider.error() == QGeoServiceProvider::NoError) { mappingManager = serviceProvider.mappingManager(); routingManager = serviceProvider.routingManager(); searchManager = serviceProvider.searchManager(); } Common classes
MappingThe QGraphicsGeoMap class is the main class used for displaying and interacting with maps. It is designed for use within the Graphics View Framework, and is a subclass of QGraphicsWidget. The QGeoMappingManager provides most of the functionality required by QGraphicsGeoMap. The details of QGeoMappingManager are mostly only important to plugin implementers, as regular users should not need to make use of QGeoMappingManager outside of the QGraphicsGeoMap constructor: QGraphicsGeoMap *map = new QGraphicsGeoMap(mappingManager);
Map objectsQGeoMapObject and its subclasses provide the ability to add graphics to the map specified in terms of coordinates and distances. QGeoMapObject instances can also be grouped into heirarchies in order to simplify the process of creating compound objects and managing groups of objects.
RoutingQGeoRoutingManager handles requests for routing information. The requests are created as QGeoRouteRequest instances, which are passed to QGeoRoutingManager::calculateRoute(). The returned QGeoRouteReply instance will contain the result of the request when it is completed. The QGeoRoute class describes the resulting route. Each route is broken up into a number of QGeoRouteSegment instances, with the division usually occurring at either user specified waypoints or at changes in the mode of transport, like when changing from a train to a bus. Each QGeoRouteSegment has a QGeoNavigationInstruction instance which describes the instructions that would be issued to a user attempting to follow a route. These instructions a location, which is typically somewhere near the end of the associated QGeoRouteSegment, and instruction text describing how the next QGeoRouteSegment should be reached.
Geocoding and searching for placesQGeoSearchManager handles geocoding, reverse geocoding and free-text search for places. The free-text search will attempt to geocode text that looks like an address while simultaneously searching any landmark databases that the service pro. It is even possibly to add additional QLandmarkManager instances to the soures of data, so that users can search online databases alongside their personal offline landmarks store.
The Nokia pluginQt Mobility ships with a Maps and Navigation API plugin which accesses the relevant Ovi services provided Nokia. The use of these services is governed by the terms and conditions available in the file plugins/geoservices/nokia/OVI_SERVICES_TERMS_AND_CONDITIONS.txt. The Ovi services plugin can be loaded by using the plugin key "nokia". Note that accepting the terms and conditions only applies those terms and conditions to the use of the Ovi Maps Services plugin and does not limit the use of the other maps and navigation API plugins that may be included with the Qt Mobility package. Implementing pluginsA plugin implementer needs to subclass QGeoServiceProviderFactory and as many of the ManagerEngine classes as they want to provide implementations for. Subclassing QGeoServiceProviderFactory will only involve exposing a name and a version by overriding QGeoServiceProviderFactory::providerName() and QGeoServiceProviderFactory::providerVersion(), and overriding QGeoServiceProviderFactory::createSearchManagerEngine(), QGeoServiceProviderFactory::createMappingManagerEngine() and QGeoServiceProviderFactory::createRoutingManagerEngine() as appropriate.
Tile-based map convenience classesMost of the current tile based mapping APIs are very similar, and so we provide a number of classes intended to make writing tile based mapping plugins much simpler. If the Mercator projection and the most common tile addressing scheme is used this will mainly involve subclassing QGeoTiledMappingManagerEngine and providing an implementation of QGeoTiledMappingManagerEngine::getTileImage().
QML ElementsFor details on the QML support provided for the Location API see the documentation for the Location QML Plugin. Note: At the time of the Qt Mobility 1.1.0 release the QML support for the Maps and Navigation API is incomplete and likely to be refined and improved in the next patch release. X
|