Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qgeoserviceprovider.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
7
8#include "qgeocodingmanager.h"
10#include "qgeoroutingmanager.h"
11#include "qplacemanager.h"
15#include "qplacemanagerengine.h"
17
18#include <QList>
19#include <QString>
20#include <QVariant>
21#include <QCborArray>
22
23#include <QDebug>
24#include <QStringList>
25#include <QCoreApplication>
26#include <QObject>
27#include <QMetaObject>
28#include <QMetaEnum>
29#include <QtCore/private/qfactoryloader_p.h>
30
32
34 ("org.qt-project.qt.geoservice.serviceproviderfactory/6.0",
35 QLatin1String("/geoservices")))
36
37
179QStringList QGeoServiceProvider::availableServiceProviders()
180{
182}
183
203 const QVariantMap &parameters,
204 bool allowExperimental)
205 : d_ptr(new QGeoServiceProviderPrivate())
206{
207 d_ptr->experimental = allowExperimental;
208 d_ptr->parameterMap = parameters;
209 // TODO Qt 6 Remove silent nokia rename
210 if (providerName == QStringLiteral("nokia"))
211 d_ptr->providerName = QStringLiteral("here");
212 else
213 d_ptr->providerName = providerName;
214 d_ptr->loadMeta();
215}
216
221{
222 delete d_ptr;
223}
224
225/* Template for the routingFeatures(), geocodingFeatures() etc methods.
226 * Ideally, the enumName would be a template parameter, but strings
227 * are not a valid const expr. :( */
228template <class Flags>
230{
231 const QMetaObject *mo = &QGeoServiceProvider::staticMetaObject;
232 const QMetaEnum en = mo->enumerator(
233 mo->indexOfEnumerator(enumName));
234
235 /* We need the typename keyword here, or Flags::enum_type will be parsed
236 * as a non-type and lead to an error */
237 Flags ret = typename Flags::enum_type(0);
238 if (this->metaData.contains(QStringLiteral("Features"))
239 && this->metaData.value(QStringLiteral("Features")).isArray()) {
240 const QCborArray features = this->metaData.value(QStringLiteral("Features")).toArray();
241 for (const QCborValueConstRef v : features) {
242 int val = en.keyToValue(v.toString().toLatin1().constData());
243 if (v.isString() && val != -1) {
244 ret |= typename Flags::enum_type(val);
245 }
246 }
247 }
248
249 return ret;
250}
251
255QGeoServiceProvider::RoutingFeatures QGeoServiceProvider::routingFeatures() const
256{
257 return d_ptr->features<RoutingFeatures>("RoutingFeatures");
258}
259
263QGeoServiceProvider::GeocodingFeatures QGeoServiceProvider::geocodingFeatures() const
264{
265 return d_ptr->features<GeocodingFeatures>("GeocodingFeatures");
266}
267
271QGeoServiceProvider::MappingFeatures QGeoServiceProvider::mappingFeatures() const
272{
273 return d_ptr->features<MappingFeatures>("MappingFeatures");
274}
275
279QGeoServiceProvider::PlacesFeatures QGeoServiceProvider::placesFeatures() const
280{
281 return d_ptr->features<PlacesFeatures>("PlacesFeatures");
282}
283
289QGeoServiceProvider::NavigationFeatures QGeoServiceProvider::navigationFeatures() const
290{
291 return d_ptr->features<NavigationFeatures>("NavigationFeatures");
292}
293
294/* Sadly, these are necessary to figure out which of the factory->createX
295 * methods we need to call. Ideally it would be nice to find a way to embed
296 * these into the manager() template. */
297template <class Engine>
299{
300 return nullptr;
301}
318
319/* Template for generating the code for each of the geocodingManager(),
320 * mappingManager() etc methods */
321template <class Manager, class Engine>
323 QString *_errorString)
324{
325 // make local references just so this method is easier to read
327 QString &errorString = *_errorString;
328 Manager *manager = nullptr;
329
330 if (!factory) {
333 }
334
335 if (!factory) {
336 error = this->error;
337 errorString = this->errorString;
338 return nullptr;
339 }
340
341 if (!manager) {
342 Engine *engine = createEngine<Engine>(this); // this sets the specific error variables directly,
343 // from now on the local error, errorString refs should be set.
344
345 if (engine) {
346 engine->setManagerName(
347 metaData.value(QStringLiteral("Provider")).toString());
348 engine->setManagerVersion(
349 int(metaData.value(QStringLiteral("Version")).toDouble()));
350 manager = new Manager(engine);
351 } else if (error == QGeoServiceProvider::NoError) {
353 errorString = QLatin1String("The service provider does not support the %1 type.")
354 .arg(QLatin1String(Manager::staticMetaObject.className()));
355 }
356
358 delete manager;
359 manager = nullptr;
360 this->error = error;
361 this->errorString = errorString;
362 }
363
364 if (manager && localeSet)
365 manager->setLocale(locale);
366 }
367
368 if (manager) {
369 this->error = QGeoServiceProvider::NoError;
370 this->errorString.clear();
371 }
372
373 return manager;
374}
375
398{
399 if (!d_ptr->geocodingManager) {
401 &(d_ptr->geocodeError), &(d_ptr->geocodeErrorString)));
402 if (!d_ptr->geocodingManager)
403 qDebug() << d_ptr->error << ", " << d_ptr->errorString;
404 }
405 return d_ptr->geocodingManager.get();
406}
407
431{
432 if (!d_ptr->mappingManager) {
434 &(d_ptr->mappingError), &(d_ptr->mappingErrorString)));
435 if (!d_ptr->mappingManager)
436 qDebug() << d_ptr->error << ", " << d_ptr->errorString;
437 }
438 return d_ptr->mappingManager.get();
439}
440
462{
463 if (!d_ptr->routingManager) {
465 &(d_ptr->routingError), &(d_ptr->routingErrorString)));
466 if (!d_ptr->routingManager)
467 qDebug() << d_ptr->error << ", " << d_ptr->errorString;
468 }
469 return d_ptr->routingManager.get();
470}
471
489{
490 if (!d_ptr->placeManager) {
492 &(d_ptr->placeError), &(d_ptr->placeErrorString)));
493 if (!d_ptr->placeManager)
494 qDebug() << d_ptr->error << ", " << d_ptr->errorString;
495 }
496 return d_ptr->placeManager.get();
497}
498
507
513{
514 return d_ptr->errorString;
515}
516
527
538
549
560
571
582
593
604
615
626
636{
637 d_ptr->experimental = allow;
638 d_ptr->unload();
639 d_ptr->loadMeta();
640}
641
646
661{
662 d_ptr->parameterMap = parameters;
663 d_ptr->unload();
664 d_ptr->loadMeta();
665}
666
673{
674 d_ptr->locale = locale;
675 d_ptr->localeSet = true;
676
677 if (d_ptr->geocodingManager)
678 d_ptr->geocodingManager->setLocale(locale);
679 if (d_ptr->routingManager)
680 d_ptr->routingManager->setLocale(locale);
681 if (d_ptr->mappingManager)
682 d_ptr->mappingManager->setLocale(locale);
683 if (d_ptr->placeManager)
684 d_ptr->placeManager->setLocale(locale);
685}
686
687/*******************************************************************************
688*******************************************************************************/
689
694
698
700{
701 geocodingManager.reset();
702 routingManager.reset();
703 mappingManager.reset();
704 placeManager.reset();
705
706 factory = nullptr;
709 metaData = QCborMap();
710 metaData.insert(QStringLiteral("index"), -1);
711}
712
713/* Filter out any parameter that doesn't match any plugin */
715{
716 const auto availablePlugins = QGeoServiceProviderPrivate::plugins();
717
719 for (auto it = availablePlugins.keyBegin(), end = availablePlugins.keyEnd(); it != end; ++it) {
720 if (*it == providerName) // don't remove parameters for current provider
721 continue;
722
723 QVariantMap::iterator i = cleanedParameterMap.begin();
724 while (i != cleanedParameterMap.end()) {
725 // remove every parameter meant for other plugins
726 if (i.key().startsWith(QString(*it + QLatin1Char('.'))))
728 else
729 ++i;
730 }
731 }
732}
733
735{
736 factory = nullptr;
737 metaData = QCborMap();
738 metaData.insert(QStringLiteral("index"), -1);
740 errorString = QString(QLatin1String("The geoservices provider %1 is not supported.")).arg(providerName);
741
742 const QList<QCborMap> candidates = QGeoServiceProviderPrivate::plugins().values(providerName);
743
744 int versionFound = -1;
745 int idx = -1;
746
747 // figure out which version of the plugin we want
748 // (always latest unless experimental)
749 for (qsizetype i = 0; i < candidates.size(); ++i) {
750 QCborMap meta = candidates[i];
751 if (meta.contains(QStringLiteral("Version"))
752 && meta.value(QStringLiteral("Version")).isInteger()
753 && meta.contains(QStringLiteral("Experimental"))
754 && meta.value(QStringLiteral("Experimental")).isBool()) {
755 int ver = int(meta.value(QStringLiteral("Version")).toDouble());
756 if (ver > versionFound && !(!experimental && meta.value(QStringLiteral("Experimental")).toBool())) {
757 versionFound = ver;
758 idx = i;
759 }
760 }
761 }
762
763 if (idx != -1) {
766 metaData = candidates[idx];
767 }
768}
769
771{
772 Q_UNUSED(parameters);
773
774 if (int(metaData.value(QStringLiteral("index")).toDouble()) < 0) {
776 errorString = QString(QLatin1String("The geoservices provider is not supported."));
777 factory = nullptr;
778 return;
779 }
780
783
784 int idx = int(metaData.value(QStringLiteral("index")).toDouble());
785
786 // load the actual plugin
787 factory = qobject_cast<QGeoServiceProviderFactory *>(loader()->instance(idx));
788 if (!factory) {
790 errorString = QLatin1String("loader()->instance(idx) failed to return an instance. Set the environment variable QT_DEBUG_PLUGINS to see more details.");
791 return;
792 }
794}
795
796QMultiHash<QString, QCborMap> QGeoServiceProviderPrivate::plugins(bool reload)
797{
798 static QMultiHash<QString, QCborMap> plugins;
799 static bool alreadyDiscovered = false;
800
801 if (reload == true)
802 alreadyDiscovered = false;
803
804 if (!alreadyDiscovered) {
806 alreadyDiscovered = true;
807 }
808 return plugins;
809}
810
811void QGeoServiceProviderPrivate::loadPluginMetadata(QMultiHash<QString, QCborMap> &list)
812{
813 QFactoryLoader *l = loader();
814 const QList<QPluginParsedMetaData> meta = l->metaData();
815 for (qsizetype i = 0; i < meta.size(); ++i) {
816 QCborMap obj = meta.at(i).value(QtPluginMetaDataKeys::MetaData).toMap();
817 obj.insert(QStringLiteral("index"), i);
818 list.insert(obj.value(QStringLiteral("Provider")).toString(), obj);
819 }
820}
821
822
824
\inmodule QtCore\reentrant
Definition qcborarray.h:20
\inmodule QtCore\reentrant
Definition qcbormap.h:21
QCborValue value(qint64 key) const
Returns the QCborValue element in this map that corresponds to key key, if there is one.
Definition qcbormap.h:248
bool contains(qint64 key) const
Returns true if this map contains a key-value pair identified by key key.
Definition qcbormap.h:293
iterator insert(qint64 key, const QCborValue &value_)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qcbormap.h:341
QCborArray toArray() const
MetaDataList metaData() const
\inmodule QtLocation
\inmodule QtLocation
\inmodule QtLocation
virtual QPlaceManagerEngine * createPlaceManagerEngine(const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString) const
Returns a new QPlaceManagerEngine instance, initialized with parameters, which implements the place s...
virtual void setQmlEngine(QQmlEngine *engine)
Notify the plugin when the qml engine is ready.
virtual QGeoMappingManagerEngine * createMappingManagerEngine(const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString) const
Returns a new QGeoMappingManagerEngine instance, initialized with parameters, which implements mappin...
virtual QGeoCodingManagerEngine * createGeocodingManagerEngine(const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString) const
Returns a new QGeoCodingManagerEngine instance, initialized with parameters, which implements the loc...
virtual QGeoRoutingManagerEngine * createRoutingManagerEngine(const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString) const
Returns a new QGeoRoutingManagerEngine instance, initialized with parameters, which implements routin...
std::unique_ptr< QGeoRoutingManager > routingManager
QGeoServiceProvider::Error geocodeError
QGeoServiceProvider::Error routingError
QGeoServiceProvider::Error mappingError
std::unique_ptr< QGeoMappingManager > mappingManager
void loadPlugin(const QVariantMap &parameters)
Manager * manager(QGeoServiceProvider::Error *error, QString *errorString)
QGeoServiceProvider::Error placeError
static void loadPluginMetadata(QMultiHash< QString, QCborMap > &list)
std::unique_ptr< QPlaceManager > placeManager
QGeoServiceProvider::Error navigationError
static QMultiHash< QString, QCborMap > plugins(bool reload=false)
QGeoServiceProvider::Error error
Flags features(const char *enumName) const
QGeoServiceProviderFactory * factory
std::unique_ptr< QGeoCodingManager > geocodingManager
\inmodule QtLocation
Error routingError() const
Returns an error code describing the error which occurred during the last attempt to create a routing...
MappingFeatures mappingFeatures() const
Returns the mapping features supported by the geo service provider.
QGeoMappingManager * mappingManager() const
Returns the QGeoMappingManager made available by the service provider.
Error mappingError() const
Returns an error code describing the error which occurred during the last attempt to create a mapping...
Error placesError() const
Returns an error code describing the error which occurred during the last attempt to create a places ...
void setQmlEngine(QQmlEngine *engine)
~QGeoServiceProvider()
Destroys the service provider object.
QString navigationErrorString() const
Returns a string describing the error which occurred during the last attempt to create a navigation m...
void setLocale(const QLocale &locale)
Sets the locale used by this service provider to locale.
QGeoServiceProvider(const QString &providerName, const QVariantMap &parameters=QVariantMap(), bool allowExperimental=false)
Constructs a QGeoServiceProvider whose backend has the name providerName, using the provided paramete...
PlacesFeatures placesFeatures() const
Returns the places features supported by the geo service provider.
Error
Describes an error related to the loading and setup of a service provider plugin.
RoutingFeatures routingFeatures() const
Returns the routing features supported by the geo service provider.
Error navigationError() const
Returns an error code describing the error which occurred during the last attempt to create a navigat...
Error geocodingError() const
Returns an error code describing the error which occurred during the last attempt to create a geocodi...
GeocodingFeatures geocodingFeatures() const
Returns the geocoding features supported by the geo service provider.
Error error() const
Returns an error code describing the error which occurred during the last operation that was performe...
void setAllowExperimental(bool allow)
Sets whether experimental plugins are considered when locating the correct plugin library for this se...
QString mappingErrorString() const
Returns a string describing the error which occurred during the last attempt to create a mapping mana...
QString geocodingErrorString() const
Returns a string describing the error which occurred during the last attempt to create a geocoding ma...
QString routingErrorString() const
Returns a string describing the error which occurred during the last attempt to create a routing mana...
NavigationFeatures navigationFeatures() const
Returns the navigation features supported by the geo service provider.
void setParameters(const QVariantMap &parameters)
Sets the parameters used to construct individual manager classes for this service provider to paramet...
QPlaceManager * placeManager() const
Returns the QPlaceManager made available by the service provider.
QGeoCodingManager * geocodingManager() const
Returns the QGeoCodingManager made available by the service provider.
QString errorString() const
Returns a string describing the error which occurred during the last operation that was performed by ...
QGeoRoutingManager * routingManager() const
Returns the QGeoRoutingManager made available by the service provider.
QString placesErrorString() const
Returns a string describing the error which occurred during the last attempt to create a places manag...
QString arg(Args &&...args) const
iterator insert(qsizetype i, parameter_type t)
Definition qlist.h:488
iterator erase(const_iterator it)
Definition qmap.h:619
iterator begin()
Definition qmap.h:598
iterator end()
Definition qmap.h:602
\inmodule QtCore
\inmodule QtLocation
\inmodule QtLocation
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1252
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
Definition qstring.cpp:8870
QSet< QString >::iterator it
auto mo
[7]
Combined button and popup list for selecting options.
Flags
QGeoCodingManagerEngine * createEngine< QGeoCodingManagerEngine >(QGeoServiceProviderPrivate *d_ptr)
Engine * createEngine(QGeoServiceProviderPrivate *)
QGeoRoutingManagerEngine * createEngine< QGeoRoutingManagerEngine >(QGeoServiceProviderPrivate *d_ptr)
QPlaceManagerEngine * createEngine< QPlaceManagerEngine >(QGeoServiceProviderPrivate *d_ptr)
QGeoMappingManagerEngine * createEngine< QGeoMappingManagerEngine >(QGeoServiceProviderPrivate *d_ptr)
#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS)
#define qDebug
[1]
Definition qlogging.h:164
return ret
GLsizei const GLfloat * v
[13]
GLuint GLuint end
GLhandleARB obj
[2]
GLuint GLfloat * val
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
#define Q_UNUSED(x)
ptrdiff_t qsizetype
Definition qtypes.h:165
static double toDouble(Value v)
const char className[16]
[1]
Definition qwizard.cpp:100
QList< int > list
[14]
QNetworkAccessManager manager
char * toString(const MyType &t)
[31]
QJSEngine engine
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18
\inmodule QtCore
QT_BEGIN_NAMESPACE bool toBool(const QString &str)
Definition utils.h:14