The Road to Qt Location

The Qt Location module in Qt 5 provides functionality for geocoding and routing, for rendering maps and routes in a Qt Quick UI, and for accessing information about points of interests. Applications can use Qt Location to render maps, can add items on top of the map to highlight certain geographical areas, and the Qt Quick UI allows applications and users to pan, zoom, and tilt the map. Such applications will typically use the Qt Positioning module to be aware of the user's location. Qt Positioning has been available in Qt 6 since the Qt 6.2 release, and over the last months we have been working with customers, partners, and Open Source contributors to make the most important Qt Location functionality available in Qt 6 as well. The feedback in the respective JIRA ticket make us optimistic that we are on the right track, and in this blog post I'll try to give an broader update on where we are with this work.

Where we come from

The history of Qt Location started in the Nokia days, where the requirements were driven by smart phone functionality. Nokia's own HERE service needed to be supported, but also Open Street Maps as an Open Source solution. Over time, the requirements changed, and were increasingly driven by use-cases in the automotive space. Support for more backends was added, with new functionality such as points-of-interest features, and experimental support for turn-by-turn navigation.

After 10 years of changing requirements and realities in the GIS space, it was time to take a thorough look at the architecture. Before committing to Qt Location for Qt 6 we wanted to see what abstractions we really needed, and what improvements in Qt 6's rendering architecture and QML language we could benefit from. And last but not least, we wanted to understand what kind of applications Qt users were building with Qt Location.

Qt Location's mapviewer example based on the current dev branch, running in the iOS Simulator, with controls using the native iOS style we introduced with Qt 6.4

(Qt Location's mapviewer example based on the current dev branch, running in the iOS Simulator, with controls using the native iOS style we introduced with Qt 6.4)

Where we are going

The Qt Location that we plan to bring back for Qt 6 will provide APIs for basic mapping and GIS functionality in Qt Quick applications and HMIs. We want to focus on the basic features that covers the majority of use cases we have seen. We have removed the experimental APIs and the modules from qtlocation.labs - they were never quite finished or fully tested.

Reducing the number of included backends

And we have discussed whether and how to support the different backends through a generic API. The expertise for rendering GIS data efficiently into a scene graph is with our partners at e.g. Mapbox or Esri, who can pay full attention to this space and already provide high-quality SDKs. We have seen that there is little value in providing a backend-agnostic abstraction for rendering maps and items. Applications will be designed to work with a specific backend provider, and can therefore easily use provider-specific APIs. Much of the basic Qt Location functionality - such as projections, gesture handling, or routing and point-of-interest models - can be accessed through generic, backend-independent APIs. For provider specific functionality however, we believe that it might be better to instantiate a dedicated type, e.g. a MapboxMap that provides access to MapBox specific features, than to operate with a generic "Map" type and then using string-based extra and dynamic parameters.

And it is also better if the partners that operate and control the service APIs maintain the Qt Location client side, so that changes are made in both ends of the system at the same time.

In practice this means that for the initial Qt 6 version of Qt Location, we will reduce the number of service providers that are supported out of the box. We continue to support the OpenStreetMap backend, in addition to the ItemOverlay backend. The code for the other backend implementations is at the time of writing still part of the Qt Location repository, but they don't get built by default. The plan is to remove them from the repository later on, and to work with the service providers to make sure that they can provide optimally integrated solutions. The details for this are however not set in stone, and we will continue to discuss the practical implications of this with our partners and customers.

With this new backend strategy, most of the abstractions in the labs modules mentioned above become obsolete. Instead, we want to be able to evolve our backend APIs based on the actual needs. To enable that, the Qt Location APIs for backends will no longer be subject to binary and source compatibility between minor releases. If new or advanced services require changes, or additional virtual functions, in the Qt Location backend API, then it is important that we can make those modifications easily. As with RHI and QPA, the Qt Location backend APIs will remain stable within patch cycles.

Qt Location for Qt 6.5

The work in the dev branch is based on the upcoming Qt 6.5 release, and makes use of newly developed capabilities in the QML engine. This is work in progress, and I'd like to invite you to follow the ongoing work and participate in the respective discussions in our code review system.

One of the major changes we have made in this branch is making use of the QML capabitilities to support C++ value types in QML without the need for QObject-wrappers. Most of the QML element types in the Places and Routing submodules have been converted to QML value types. Applications can still receive those values from the respective models and through property getters, so in most cases, applications will not notice the change. Those values, just like in C++, do not change spontaneously. So there is no need to bind to any properties or signals of those values. And since there never was an API to write changed values back to the backend service, there is generally also no need to instantiate them - even though that will be possible in Qt 6.5 through properties.

With this change, you can expect substantially less memory and runtime overhead when operating with large data models or complex routes, as Qt Location doesn't have to create transient or even persistent QObject wrappers just so that applications can get the distance between two points.

Work is ongoing to improve the rendering code, in particular for map items. At the moment, Qt Location is still a 2D map renderer that recalculates the projection of geo coordinates to scene coordinates whenever the map is panned, rotated, or tilted. This is naturally inefficient, as we need to tesselate and triangulate lines and shapes frequently. We are investigating options to avoid this constant recalculation, to offload most of this work to the GPU without losing functionality, and to use regular Quick items and transformations.

In general however, we do want to give backend implementors more APIs to integrate with the Qt Quick scene graph: projection between map and screen space, handling of user input, and general C++ APIs that make it easier to implement backend-specific QML types. Making optimal use of GPU capabitilies is a difficult problem to solve generically in Qt. Application or backend developers can make more assumptions about the hardware for their target environment, and can make use of e.g. tesselation shaders to offload much of the computation heavy work to the GPU.

To build the Qt 6.5 version of Qt Location, assuming that you already have a local build of Qt's dev branches from git, you can run:

$ git clone --branch dev git://code.qt.io/qt/qtlocation.git
$ mkdir qtlocation-build
$ cd qtlocation-build
$ <QT_BUILD_TREE>/bin/qt-configure-module ../qtlocation
$ ninja && ninja install

If you already have a clone and toplevel build of the qt5.git super-module, then you can also run

$ init-repository --module-subset qtlocation
 

and then reconfigure your toplevel build so that Qt Location is included.

Qt Location for 6.2

Since many of our users continue to work with Qt 6.2 as a commercial LTS release, we have backported a subset of the changes to a special lts-6.2 branch in the Qt Location repository. That branch is tested against Qt 6.2 as released, and while some changes are not included, it might allow you to see how your application will be impacted by the changes above.

To build it from sources against a Qt 6.2 installation, run:

$ git clone --branch lts-6.2 git://code.qt.io/qt/qtlocation.git
$ mkdir qtlocation-build
$ cd qtlocation-build
$ <QT_INSTALLATION_PATH>/bin/qt-configure-module ../qtlocation
$ ninja && ninja install

With the exception of the reduction of supported backends, this version of Qt Location for Qt 6 is largely source compatible with the Qt 5.15 version. Changes that might impact existing applications includes the removal of experimental, unfinished, and labs functionality. In addition, some QML element types have already been converted into QML value types: CameraCapabilities and RouteManeuver, for instance, are no longer QML elements that can be instantiated as items. They are now value types that can only accessed as return values from respective properties.

If you need help with building this branch or integrating this version of Qt Location into your project, please contact your account manager in The Qt Company to see if our Professional Services team can assist you.

Porting from Qt 5 to Qt 6

We are making good progress with turning Qt Location into a modern Qt 6 module, with a reduced memory footprint and complexity. The feedback to the work so far makes me confident that we are on the right track. The reduction of supported backends will be a limitation in the beginning, but I believe that the simplified architecture will allow us to provide better functionality and integration with more GIS services in the long run.

I hope that many of you try out the currently available versions of Qt Location, be it from the dev branch or the lts-6.2 branch. We try to keep the porting documentation up-to-date as we are making changes.

We are actively working on the code, so remember to fetch new changes regularly. You are of course very welcome to participate in the discussions on the Qt Project code review system, to contribute with patches, or with feedback in our bug tracker, or through your account manager in The Qt Company. With broad participation in the work, I'm optimistic that we can bring Qt Location back as a proper, fully supported module.


Blog Topics:

Comments