Backend des lieux
Présentation
L'interface QPlaceManager, fournie aux clients pour leur permettre d'accéder aux informations sur les lieux, dépend directement d'une implémentation de QPlaceManagerEngine. Le moteur fournit les implémentations des fonctions du backend qui sont appelées par le gestionnaire.
Un développeur de backend de lieux doit dériver de ` QPlaceManagerEngine ` et fournir des implémentations pour les fonctions virtuelles pertinentes pour son backend. La plupart de ces fonctions sont asynchrones ; les développeurs devront donc également dériver les classes de réponse appropriées. Les objets de réponse sont chargés de gérer une requête asynchrone ; ils servent à signaler qu’une requête est terminée et contiennent les résultats de cette requête. QPlaceManagerEngine fournit une implémentation par défaut pour toutes les fonctions virtuelles. Les implémentations par défaut des fonctions asynchrones renvoient une réponse qui émettra les signaux errorOccurred() et finished() lors de la prochaine itération de la boucle d’événements.
Implémentation/Héritage des objets de réponse
Un objet de réponse s’hérite comme suit :
class SearchReply : public QPlaceSearchReply
{
public:
explicit SearchReply(ManagerEngine *engine)
: QPlaceSearchReply(engine), m_engine(engine){}
~SearchReply();
void setResults(const QList<QPlaceSearchResult> &results);
void setRequest(const QPlaceSearchRequest &request);
...
void triggerDone(QPlaceReply::Error error = QPlaceReply::NoError,
const QString &errorString = QString());
ManagerEngine *m_engine;
};L’implémentation d’un objet ` QPlaceManagerEngine ` doit garantir que tous les signaux émis par les objets de réponse soient différés jusqu’à ce que les fonctions de requête aient renvoyé un résultat et que le code de l’application ait eu le temps de connecter ces signaux à des slots. L’approche classique consiste à utiliser ` QMetaObject::invokeMethod()` avec un ` Qt::QueuedConnection ` pour émettre les signaux.
void SearchSuggestionReply::triggerDone(QPlaceReply::Error error,
const QString &errorString)
{
if (error != QPlaceReply::NoError) {
this->setError(error,errorString);
QMetaObject::invokeMethod(m_engine, "errorOccurred", Qt::QueuedConnection,
Q_ARG(QPlaceReply *,this),
Q_ARG(QPlaceReply::Error, error),
Q_ARG(QString, errorString));
QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
Q_ARG(QPlaceReply::Error, error),
Q_ARG(QString, errorString));
}
this->setFinished(true);
QMetaObject::invokeMethod(m_engine, "finished", Qt::QueuedConnection,
Q_ARG(QPlaceReply *,this));
QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
}Notez que les signaux de ` finished ` doivent toujours être émis lorsqu’une réponse est terminée, même si une erreur s’est produite ; c’est-à-dire qu’en cas d’erreur, les signaux ` error ` et ` finished ` doivent tous deux être émis, tandis qu’en l’absence d’erreur, seuls les signaux ` finished ` sont émis.
Les fonctions protégées ` QPlaceSearchReply::setResults()` et ` QPlaceSearchReply::setRequest()` sont rendues accessibles publiquement afin que le plugin puisse attribuer des résultats et des requêtes. Comme ces fonctions ne sont pas exportées publiquement, leur accessibilité ne pose pas vraiment de problème. Une alternative aurait été de déclarer une classe amie dans `SearchReply`.
En règle générale, l’instance du moteur serait désignée comme ` parent ` de la réponse. Si le développeur oublie de supprimer les réponses une fois qu’il a terminé, le moteur peut s’en charger lors de sa destruction. Généralement, la réponse dispose également d’un pointeur renvoyant vers le moteur, qui peut être utilisé pour émettre les signaux ` QPlaceManagerEngine::finished()` et `QPlaceManagerEngine::error()`. Ce n’est là qu’une des nombreuses façons dont la réponse pourrait être implémentée.
URL des icônes
Les URL d’icônes sont fournies via la fonction QPlaceManagerEngine::constructIconUrl(). Le comportement attendu est que le moteur utilise la fonction QPlaceIcon::parameters() afin de construire une URL appropriée. Lorsqu’un objet QPlace est renvoyé par le gestionnaire, soit à la suite d’une recherche, soit d’une requête visant à obtenir les détails d’un lieu, le moteur est censé remplir correctement les paramètres si nécessaire.
Le backend est libre de choisir la clé et les valeurs des paramètres ; toutefois, si un backend ne dispose que d’une seule URL par icône, il est recommandé d’utiliser l’ QPlaceIcon::SingleUrl comme clé.
Catégories
Les catégories d’un moteur de gestion sont des entités relativement statiques ; pour les moteurs accédant à des bases de données de lieux distantes, il peut être préférable de mettre en cache la structure des catégories plutôt que d’interroger un serveur à chaque appel de la méthode ` QPlaceManagerEngine::initializeCategories()`. Selon le degré de dynamisme des catégories, il peut être plus approprié de toujours télécharger l’ensemble le plus récent de catégories.
Enregistrement des lieux dans le gestionnaire
Un lieu ne peut généralement pas être enregistré tel quel d’un gestionnaire à l’autre, car il contient des données spécifiques au gestionnaire, telles que des icônes et des catégories. Afin de faciliter l’enregistrement dans son propre gestionnaire, les développeurs de moteurs doivent implémenter la fonction QPlaceManagerEngine::compatiblePlace(). Cette fonction renvoie une copie du lieu d’entrée dont les propriétés ont été supprimées ou modifiées si nécessaire, de sorte que la copie puisse être enregistrée dans le gestionnaire.
La création d’un lieu compatible peut impliquer d’ignorer certaines propriétés du lieu d’origine ; par exemple, si les coordonnées ne sont pas prises en charge, celles-ci sont omises du lieu compatible. Dans d’autres cas, cela peut impliquer de modifier certaines propriétés, par exemple en modifiant les paramètres de l’icône afin de faciliter la copie ou le téléchargement de l’icône du lieu d’origine vers un emplacement accessible au backend.
Références croisées entre gestionnaires de lieux
Il peut parfois arriver que l’on souhaite établir des références croisées et faire correspondre des lieux entre différents gestionnaires. Une telle situation peut se produire lorsqu’un gestionnaire fournit un accès en lecture seule aux lieux (gestionnaire d’origine), tandis qu’un deuxième gestionnaire en lecture/écriture (gestionnaire de destination) est utilisé pour enregistrer les favoris sélectionnés à partir du premier. Lors d’une recherche dans le gestionnaire d’origine, on peut souhaiter savoir lesquels ont été « ajoutés aux favoris » dans le gestionnaire de destination et éventuellement afficher le nom personnalisé du favori plutôt que son nom d’origine.
Référencement croisé via un identifiant alternatif
Pour permettre ce recoupement, il doit exister un lien entre le lieu d’origine et le lieu ajouté aux favoris, ce qui est généralement géré via un attribut d’identifiant alternatif. Le lieu ajouté aux favoris contient un attribut d’identifiant alternatif qui prend la valeur de l’identifiant du lieu d’origine.
origin R/O manager(here) destination R/W manager (places_jsondb)
Save
Place id: ae246 ---> Place id: 0001
Attribute type: x_provider Attribute type: x_id_here
Attribute value: here Attribute text value: ae246La mise en œuvre des références croisées par identifiant alternatif repose sur trois conditions préalables. La première est que le gestionnaire d’origine doit fournir l’attribut `x_provider` dont la valeur correspond au nom de l’ QGeoServiceProvider du gestionnaire. Le libellé de l’attribut doit rester vide, ce qui indique que l’attribut ne doit pas être affiché aux utilisateurs.
Remarque : on s’attend généralement à ce que tous les gestionnaires définissent l’attribut ` x_provider `.
La deuxième consiste pour le gestionnaire de destination QPlaceManager::compatiblePlace() à utiliser l’attribut x_provider du lieu initial et à définir un attribut d’identifiant alternatif pour le lieu à enregistrer. La clé de l’attribut d’identifiant alternatif est x_id_<provider name> et la valeur textuelle correspond à l’identifiant du lieu d’origine. L’attribut x_provider ne doit pas être transmis au lieu compatible. Une fois enregistré, le x_provider du lieu enregistré est considéré comme étant le gestionnaire de destination.
La troisième consiste à ce que la fonction QPlaceManager::matchingPlaces() du gestionnaire de destination accepte l’attribut « QPlaceMatchRequest::AlternativeId » comme clé de paramètre et la clé de l’attribut d’identifiant alternatif comme valeur ; dans ce cas, x_id_<provider name> serait la valeur attendue. Cela indique que les identifiants des emplacements contenus dans l’attribut « QPlaceMatchRequest » doivent être mis en correspondance avec les attributs d’identifiant alternatif « x_id_<provider name> ».
Notez que si le gestionnaire de destination doit permettre l’enregistrement et les références croisées à partir de n’importe quel gestionnaire arbitraire, il doit en interne prendre en charge l’enregistrement de paires clé-valeur arbitraires, car nous ne pouvons pas connaître à l’avance les noms des fournisseurs, ni la structure que prendront les identifiants.
Autres méthodes de liaison
Si un gestionnaire d’origine ne fournit pas d’identifiant de lieu, il peut s’avérer nécessaire de recourir à d’autres moyens de recoupement ou de mise en correspondance. Une approche pourrait consister à utiliser les coordonnées du lieu : si les coordonnées d’un lieu dans le gestionnaire d’origine sont identiques ou proches de celles d’un lieu dans le gestionnaire de destination, il y a de fortes chances qu’il s’agisse du même lieu. Dans ce cas, le gestionnaire pourrait implémenter la méthode ` QPlaceManager::matchingPlaces()` pour accepter une requête ` QPlaceMatchRequest ` avec une clé de paramètre « proximity » et une valeur de paramètre correspondant à la distance à laquelle deux lieux doivent se trouver pour qu’une correspondance soit détectée. Par exemple, si un lieu d’origine et un lieu de destination se trouvent à moins de 50 m l’un de l’autre, ils peuvent être considérés comme un même lieu.
En règle générale, il est toutefois recommandé de mettre en œuvre les références croisées via des identifiants alternatifs, comme mentionné ci-dessus.
Attributs étendus lisibles par l’utilisateur vs non lisibles par l’utilisateur
Si un attribut n’est pas destiné à être lu par les utilisateurs finaux, le champ « label » doit être laissé vide pour indiquer ce fait.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.