Maps and Navigation API

From Qt Wiki
Jump to navigation Jump to search


Qt Mobility 1.1 Features

Qt Mobility 1.1.3 Release is available now for commercial app development and deployment on Ovi store. Qt Mobility 1.2.0 release is available now.


Summary

The Maps and Navigation API provides access to mapping, routing and geocoding services.

The API is designed so that the core functionality it provided by a plugin. Qt Mobility will ship with a plugin that accesses Nokia services by default but there should be nothing to stop someone from writing plugins that work with other services (provided that we designed the API correctly).

What we have at the moment should give you some idea of what we're aiming at in terms of functionality offered and the API which provides access to it.

The current code can be viewed as a draft of the API which we'll be releasing. We have applied some of the API review feedback although there are still some changes which will still have to make, and there is some additional functionality we'd like to add to the API, so some of the classes and methods might be renamed between now and the release.

Functionality

Since most providers of mapping, routing and geocoding 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. This doesn't mean that you can't mix and match your sources of data, although it's a hint from us that you may want to be really sure that the "matching" part is done with care.

Plugin are loaded using the QGeoServiceProvider class, which give access to instances of the classes reponsible for each area of functionality in the API.

QGeoMappingManager *mappingManager = 0;
QGeoRoutingManager *routingManager = 0;
QGeoSearchManager *searchManager = 0;

QGeoServiceProvider serviceProvider("nokia");

if (serviceProvider.error() == QGeoServiceProvider::NoError) {
 mappingManager = serviceProvider.mappingManager();
 routingManager = serviceProvider.routingManager();
 searchManager = serviceProvider.searchManager();
}

For the communications with the routing and search services we borrowed quite a bit of API from the Qt Network module.

The QGeoRoutingManager and QGeoSearchManager classes have methods which return QGeoRouteReply and QGeoSearchReply instances respectively, in the same way that QNetworkAccessManager returns QNetworkReply instances, and those classes are heavily influences by QNetworkReply. The class documentation for the QGeoRoutingManager and QGeoSearchManager contain example code which should help users get started in these areas.

Maps

The class at the center of the mapping functionality is QGeoMapWidget. This will be renamed before the beta release since it's not a widget at all.

You can get hold of an instance of QGeoMapWidget with:

QGeoMapWidget *widget = new QGeoMapWidget(mappingManager);

The widget instance allows the user to set or get the coordinate at the center of the map

  • set or get the zoom level
  • set or get the map type (street map, satellite map, etc…)
  • pan the map
  • convert between coordinates and positions on the screen
  • add, remove and retrieve map objects
  • get the minimum and maximum zoom levels supported by the mapping service
  • get the map types supported by the mapping service

Multiple widgets can make use of the same QGeoMappingManager in the one application.

We're not quite done with the map objects at the moment, but in the future they'll include

  • a rectangle object
  • a circle object (all points within a given distance of a center point)
  • a polygon object
  • a polyline object
  • an image object for map markers
  • possibly some others

The MapsViewer example is available for those who'd like to see the code in action before diving in.

Current status

The Nokia plugin provides basic mapping functionality, although the performance is undergoing a major overhaul and the map objects are not complete.

We haven't finished the map objects yet.

We are looking at ways in which we might be able to allow users to specify map overlays, and are working on a set of convenience classes to form a tiled mapping API in order to assist plugin implementers who are working with tile-based mapping services.

We have some work to do before we're ready for vector based mapping services, but it's on our list.

Routing

Routes can be calculated using

QGeoRouteReply* QGeoRoutingManager::calculateRoute(const QGeoRouteRequest &request)

The QGeoRouteRequest class contains:

  • the waypoints of the route
  • the number of alternative routes to provide
  • the travel mode (or modes)

Car, Pedestrian, Bicycle, PublicTransit, Truck

  • the route optimization to use

Shortest, Fastest, MostEconomic, MostScenic

  • the features to avoid

Tolls, Highways, etc

  • geographic areas to exclude from the route
  • whether to retrieve the route segment information
  • whether to retrueve the navigation instruction information

The QGeoRoutingManager instance has a related set of functions which can be used to determine whether the service supports a particular feature or constraint.

The QGeoRouteReply instance returned by calculateRoute() will contain one or more QGeoRoute instances, depending on whether alternative routes were requested.

The routing information may contain a number of instructions to be issued at various locations along the route - these instructions are described by the QGeoNavigationInstruction class.

We break the route up into a number of QGeoRouteSegment instances which correspond to the segments of the route which occur between two consecutive instructions.

The QGeoRoute class contains summary information for the route:

  • the estimated travel time for the route
  • the estimated total distance covered by the route
  • a route ID, for use when updating the route
  • a geographical bounding box for the route
  • the travel mode used by the route

as well as a list of QGeoRouteSegment instances

The QGeoRouteSegment contains:

  • the estimated travel time for the route
  • the estimated total distance covered by the route
  • a list of QGeoCoordinates which defines the path taken by the route segment
  • a QGeoNavigationInstruction instance

and the QGeoNavigationInstruction contains:

  • the instruction text
  • the distance and time to the next instruction
  • the position of the instruction

this might be before the end of the corresponding segment * especially if the speed limit is high

We plan to provide a QGeoMapObject subclass to assist with displaying routes on maps soon.

Current status

The Nokia plugin provides routing functionality.

The relationships between QGeoRoute, QGeoRouteSegment and QGeoNavigationInstruction are going to be re-examined, and QGeoRouteSegment and QGeoNavigationInstruction will probably be renamed.

The ability to specify features to avoid will probably be enhanced in order to support more fine-grained preferences with regard to features.

Geocoding and places searching

Geocoding and reverse geocoding are used to convert between address and coordinates:

QGeoSearchReply* QGeoSearchManager::geocode(const QGeoCoordinate &coordinate,
 const QGeoBoundingBox &boundingBox = QGeoBoundingBox());
QGeoSearchReply* QGeoSearchManager::geocode(const QGeoAddress &address,
 const QGeoBoundingBox &boundingBox = QGeoBoundingBox());

The QGeoSearchReply class contains a list of QGeoPlace instances, each of which contains a coordinate, and address and an optional bounding box. We return both pieces of information as the address or coordinate that was used in the geocode() function may be slightly different from the corresponding address or coordinate in the reply.

The optional bounds parameters is used to limit the results to those within a certain geographical area - usually the area corresponding to what a user has in their map viewport. When converting from address to coordinate the bounds parameter is most useful when a partially filled out address object is used - a QGeoAddress with city set to "London" could represent London, Great Britain or London, Kentucky, USA.

When converting from coordinate to address some geocoding services will give the coordinate/address pairs at multiple levels of detail - for the street address, the suburb, the city, the state and the country - and the bounds parameter can be used to limit that behaviour.

These functions will only work if

bool QGeoSearchManager::supportsGeocoding() const

returns true.

To do a free text search, use:

QGeoSearchReply* QGeoSearchManager::placeSearch(const QString &searchString,
 SearchTypes searchTypes = SearchTypes( SearchAll ),
 const QGeoBoundingBox & bounds = QGeoBoundingBox());

The searchTypes parameter is used to specify whether searchString is to be used for geocoding (in which case it will be treated as an address), for landmarks searching (in which case it will be used to search the services landmarks database) or both.

The values of searchType supported by the plugin can be found with:

SearchTypes QGeoSearchManager::supportedSearchTypes()

The return type for this method is still a list of QGeoPlace objects. The QLandmark class from the Landmarks API is a subclass of QGeoPlace, and users can check QGeoPlace instances to see if they’re actually QLandmark instances and make a conversion from a QGeoPlace instance to a QLandmark instance if necessary.

The user can also specify additional QLandmarkManager instances to be used with QGeoSearchManager. This can be used so that a single search can make use of the plugins landmark database and a users personal landmark database at the same time.

For more involved handling of landmarks, the Qt Mobility Landmarks API should be used.

Current status

The Nokia plugin provides geocoding and reverse geocoding, but does not search online landmark databases at present.

We still need to work out the best way to do paging, in order to handle the case where someone searches for landmarks containing the text "the". The current method (return them all) is not exactly network friendly.

We also need to write the code to combine the placeSearch results from the plugin implementation and from the additional landmark managers.

Writing a new plugin

A plugin implementer needs to subclass QGeoServiceProviderFactory.

In addition to specifying the name and version of the plugin, the QGeoServiceProviderFactory subclass can provide implementations of createMappingManagerEngine(), createRoutingManagerEngine() and createSearchManagerEngine() as appropriate. The default implementations of these last three functions will be suitable if the plugin does not provide that particular set of functionality.

The plugin implementer should subclass QGeoMappingManagerEngine, QGeoRoutingManagerEngine and QGeoSearchManagerEngine in order to provide the requried functionality, and should take care to set the various metadata associated with each so that clients of the plugin can determine the specific capabilities of any particular plugin. See the class documentation for more informaiton.

Example applications

There are two example applications provided.

The first is the Map Viewer example, which demonstrates the Mapping functionality.

Users can double click to center and zoom, drag to change position, and use the + and - keys to change the zoom level. Right clicking will bring up a menu which can be used to add objects to the map.

The second is QGeoAPIUI (which will be renamed soon) which demonstrates the routing and geocoding functionality.