Sur cette page

Lieux (C++)

Présentation

L'API « Lieux » permet aux utilisateurs de découvrir des lieux ou des points d'intérêt et d'afficher des informations détaillées à leur sujet, telles que leur adresse et leurs coordonnées ; certains lieux peuvent même proposer du contenu enrichi, comme des images et des avis. L'API « Lieux » facilite également la gestion des lieux et des catégories, en permettant aux utilisateurs de les enregistrer et de les supprimer.

Définition d'un lieu

Un lieu est un point d'intérêt ; il peut s'agir d'un restaurant préféré, d'un parc ou du domicile d'une personne. Un objet « QPlace » représente un lieu en servant de conteneur pour diverses informations le concernant.

Ces informations peuvent être classées en deux grandes catégories

  • Détails
  • Contenu enrichi

Les détails relatifs à un lieu comprennent ses caractéristiques, telles que son nom, son emplacement, ses coordonnées, etc. Lorsqu'un lieu apparaît dans les résultats d'une recherche, ces détails sont renseignés. Parfois, afin d'économiser de la bande passante, des informations supplémentaires sur le lieu peuvent être récupérées au cas par cas, si l'utilisateur le souhaite. La fonction ` QPlace::detailsFetched()` permet de vérifier si toutes les informations disponibles ont été récupérées ; si ce n'est pas le cas, la fonction ` QPlaceManager::getPlaceDetails()` peut être utilisée pour les récupérer. Les informations qui sont automatiquement renseignées lors d'une recherche et celles qui doivent être récupérées individuellement peuvent varier d'un fournisseur à l'autre. Consultez la documentation du plugin pour plus de détails.

Le contenu enrichi d’un lieu se compose d’éléments tels que des images, des avis et des articles rédactionnels. Comme il peut y avoir un grand nombre d’éléments de contenu enrichi, ceux-ci sont traités séparément des détails du lieu. Ils peuvent être récupérés par pages via QPlaceManager::getPlaceContent(). Si nécessaire, le contenu peut être attribué à un lieu afin que celui-ci serve de conteneur pratique.

Opérations courantes

Initialisation d’un gestionnaire

Toutes les fonctionnalités liées aux lieux sont gérées par une instance de ` QPlaceManager `. Il faut spécifier un ` QGeoServiceProvider ` afin de créer le QPlaceManager

//The "provider name" is used to select a particular provider
QGeoServiceProvider *provider = new QGeoServiceProvider("provider name");
QPlaceManager *manager = provider->placeManager();

Pour effectuer une opération de recherche, il suffit de créer une instance de ` QPlaceSearchRequest ` et de définir les paramètres de recherche souhaités, tels qu’un terme de recherche et un centre de recherche.

//instantiate request and set parameters
QPlaceSearchRequest searchRequest;
searchRequest.setSearchTerm("ice cream");
searchRequest.setSearchArea(QGeoCircle(QGeoCoordinate(12.34, 56.78)));

//send off a search request
/*QPlaceSearchReply * */ searchReply = manager->search(searchRequest);

//connect a slot to handle the reply
connect(searchReply, &QPlaceSearchReply::finished, this, &RequestHandler::handleSearchReply);

La requête étant une opération asynchrone, nous avons besoin d’un slot pour gérer la fin de la requête. Dans le gestionnaire, nous vérifions qu’il n’y a pas d’erreurs et que le type de résultat de recherche correspond à un lieu. Si c’est le cas, nous pouvons alors récupérer certaines des informations essentielles concernant ce lieu. À la fin du slot, nous supprimons la réponse, car celle-ci n’est valable qu’une seule fois.

void handleSearchReply() {
    if (searchReply->error()== QPlaceReply::NoError) {
        for (const QPlaceSearchResult&result: searchReply->results()) {
            if (result.type()== QPlaceSearchResult::PlaceResult) {
                QPlaceResult placeResult = result;
                qDebug() << "Name: " << placeResult.place().name();
                qDebug() << "Coordinate " << placeResult.place().location().coordinate().toString();
                qDebug() << "Street: " << placeResult.place().location().address().street();
                qDebug() << "Distance: " << placeResult.distance();
            }
        }
    }
    searchReply->deleteLater();  // supprimer la réponse
    searchReply = nullptr;
}

Remarque : en fonction du backend du plugin choisi, les résultats de recherche peuvent contenir des lieux dont les détails supplémentaires peuvent être récupérés lieu par lieu. Pour récupérer ces autres détails, consultez la section Récupération des détails d’un lieu.

Recommandations

Les recommandations peuvent être récupérées en fournissant un identifiant de lieu via la méthode ` QPlaceSearchRequest::setRecommendationId()`. Tous les lieux similaires au lieu donné sont alors récupérés.

Pagination

Si le plugin prend en charge la pagination, le paramètre « limit » peut être fourni dans la requête de recherche.

QPlaceSearchRequest searchRequest;
searchRequest.setLimit(15); //specify how many results are to be retrieved.

Récupération des détails d'un lieu

Un lieu renvoyé par une requête de recherche peut comporter des informations supplémentaires pouvant être récupérées. L'exemple suivant montre comment vérifier s'il existe d'autres informations et, le cas échéant, comment les demander.

if (!place.detailsFetched()) {
    /*QPlaceDetailsReply * */ detailsReply = manager->getPlaceDetails(place.placeId());
    connect(detailsReply, &QPlaceDetailsReply::finished, this, &RequestHandler::handleDetailsReply);
}
    ...
    ...
void handleDetailsReply() {
    QPlace place;
    if (detailsReply->error() == QPlaceReply::NoError)
        place = detailsReply->place();

    detailsReply->deleteLater(); //discard reply
    detailsReply = nullptr;
}

Récupération de contenu enrichi

Le contenu enrichi, tel que les images et les avis, est récupéré via le gestionnaire, puis, si nécessaire, associé à un lieu.

QPlaceContentRequest request;
request.setContentType(QPlaceContent::ImageType);
request.setPlaceId(place.placeId());
request.setLimit(5);
/*QPlaceContentReply * */ contentReply = manager->getPlaceContent(request);
connect(contentReply, &QPlaceContentReply::finished, this, &RequestHandler::handleImagesReply);

Nous pouvons traiter la demande de contenu comme indiqué ci-dessous.

void handleImagesReply() {
    if (contentReply->error()== QPlaceReply::NoError) {
        const auto content = contentReply->content();
        for (auto iter = content.cbegin(), end = content.cend(); iter != end;++iter) {
            qDebug() << "Index: " << iter.key();
           QPlaceImage image = iter.value();
            qDebug() << image.url();
            qDebug() << image.mimeType();
        }

        // Sinon, si les index ne sont pas pertinents
        for (const QPlaceImage &image: contentReply->content()) {
            qDebug() << image.url();
            qDebug() << image.mimeType();
        }

        // Nous pouvons attribuer du contenu à l'emplacement auquel il appartient.
        //  L'objet « place » sert de conteneur dans lequel nous pouvons récupérer
        //  le contenu qui a déjà été récupéré
        place.insertContent(contentReply->request().contentType(), contentReply->content());
        place.setTotalContentCount(contentReply->request().contentType(), contentReply->totalCount());
    }

    contentReply->deleteLater();
    contentReply = nullptr;
}

Il est important de noter que les résultats dans ` QPlaceContentReply` sont de type ` QPlaceContent::Collection `, qui est essentiellement un ` QMap<int, QPlaceContent>`. La clé ` int ` correspond ici à l’index du contenu, et la valeur est le contenu lui-même. En raison de la manière dont `Content` est implémenté, il est possible de convertir un type de contenu comme suit

QPlaceImage image = content; //provided that 'content' has a type QPlace::ImageType

L'utilisation de l'interface QPlaceContent::Collection et la conversion entre le type « content » et ses sous-types permettent de partager facilement le code chargé de gérer les mécanismes de pagination des critiques, des images et des éditoriaux.

Suggestions de recherche

La récupération de suggestions de termes de recherche s'apparente fortement à une recherche de lieu. Un « QPlaceSearchRequest » est utilisé de la même manière que pour une recherche de lieu, la seule différence étant que le terme de recherche correspond à une chaîne partiellement renseignée.

QPlaceSearchRequest request;
request.setSearchTerm("piz");
request.setSearchArea(QGeoCircle(QGeoCoordinate(12.34, 56.78)));
/* QPlaceSearchSuggestion * */suggestionReply = manager->searchSuggestions(request);
connect(suggestionReply, &QPlaceSearchSuggestion::finished, this, &RequestHandler::handleSuggestionReply);

Une fois la requête effectuée, nous pouvons utiliser la réponse pour afficher les suggestions.

void handleSuggestionReply() {
    if (suggestionReply->error()== QPlaceReply::NoError) {
        for (const QString&suggestion: suggestionReply->suggestions())
            qDebug() << suggestion;
    }

    suggestionReply->deleteLater(); // annuler la réponse
    suggestionReply = nullptr;
}

Enregistrer un lieu

L'enregistrement d'un nouveau lieu s'effectue comme suit : nous créons une instance de ` QPlace ` et la remplissons avec des informations telles que le nom, l'adresse et les coordonnées. Une fois cela fait, nous pouvons appeler ` QPlaceManager::savePlace()` pour lancer l'opération d'enregistrement.

QPlace  place;
place.setName( "Fred's Ice Cream Parlor" );

QGeoLocation location;
location.setCoordinate(QGeoCoordinate(12.34, 56.78));

QGeoAddress address;
address.setStreet("111 Nother Street");
    ...
location.setAddress(address);
place.setLocation(location);

/* QPlaceIdReply * */savePlaceReply = manager->savePlace(place);
connect(savePlaceReply, &QPlaceIdReply::finished, this, &RequestHandler::handleSavePlaceReply);

Une fois le lieu enregistré, la réponse contient le nouvel identifiant de ce lieu.

void handleSavePlaceReply() {
    if (savePlaceReply->error()== QPlaceReply::NoError)
        qDebug() << savePlaceReply->id();

    savePlaceReply->deleteLater(); // ignorer la réponse
    savePlaceReply = nullptr;
}

Notez que pour enregistrer un lieu existant, la méthode QPlace::placeId() doit être appelée avec l'identifiant correct. Sinon, un nouveau lieu sera créé si le paramètre est vide, ou le lieu existant sera écrasé si l'identifiant est incorrect.

Lorsqu’un lieu est enregistré, la méthode ` QPlaceManager ` peut émettre les signaux `QPlaceManager::placedAdded()` ou ` QPlaceManager::placeUpdated()`. Cependant, le fait qu’un gestionnaire émette ou non ces signaux dépend du fournisseur : les gestionnaires accédant à des lieux via un service web n’émettent généralement pas ces signaux, tandis que ceux accédant à des lieux stockés localement le font généralement.

Mises en garde

L'API « Places » est actuellement conçue pour enregistrer uniquement les détails de l'core. L'enregistrement de contenus enrichis tels que des images et des avis, ou de détails tels que le fournisseur et la note, n'est pas pris en charge. En règle générale, un gestionnaire ignorera ces champs lors de l'enregistrement et pourra afficher un message d'avertissement s'ils sont renseignés.

L'API Places ne prend en charge l'enregistrement que des informations essentielles suivantes :

  • nom
  • identifiant du lieu
  • emplacement
  • coordonnées
  • icône
  • catégories (noms de type « balises » pour décrire un lieu)
  • champ d'application de la visibilité

Il est possible que certains fournisseurs ne prennent en charge qu’une partie de ces éléments. Consultez la documentation du plugin pour plus de détails.

L'enregistrement de propriétés telles que la note, les attributs étendus, les images, les avis, les articles rédactionnels et le fournisseur n'est explicitement pas pris en charge par l'API Places.

Enregistrement entre gestionnaires

Lors de l'enregistrement de lieux d'un gestionnaire à l'autre, il convient de tenir compte de certains éléments. Certains champs d'un lieu, tels que l'identifiant, les catégories et les icônes, sont des entités spécifiques à chaque gestionnaire ; par exemple, les catégories d'un gestionnaire peuvent ne pas être reconnues par un autre. Il n'est donc pas possible d'enregistrer un lieu directement d'un gestionnaire à un autre.

L’approche habituelle consiste à utiliser la fonction ` QPlaceManager::compatiblePlace()` : celle-ci crée une copie d’un lieu, mais ne copie que les données prises en charge par le gestionnaire. Les données spécifiques au gestionnaire, telles que l’identifiant du lieu, ne sont pas copiées. La nouvelle copie peut désormais être enregistrée dans le gestionnaire. Si le gestionnaire prend en charge la mise en correspondance à l’aide d’identifiants alternatifs, un attribut d’identifiant alternatif est attribué à la copie (voir Mise en correspondance des lieux entre gestionnaires)

//result retrieved from a different manager)
QPlace place = manager->compatiblePlace(result.place());
saveReply = manager->savePlace(place);

Suppression d’un lieu

La suppression d'un lieu s'effectue comme suit :

/* QPlaceIdReply * */removePlaceReply = manager->removePlace(place.placeId());
connect(removePlaceReply, &QPlaceIdReply::finished, this, &RequestHandler::handleRemovePlaceReply);
    ...
    ...
void handleRemovePlaceReply() {
    if (removePlaceReply->error()== QPlaceReply::NoError)
        qDebug() << "Removal of place identified by"
                << removePlaceReply->id() << "a réussi";

    removePlaceReply->deleteLater(); // supprimer la réponse
    removePlaceReply = nullptr;
}

Lorsqu’un lieu est supprimé, l’ QPlaceManager peut émettre le signal QPlaceManager::placeRemoved(). Le fait qu’un gestionnaire émette ou non ce signal dépend du fournisseur. Les gestionnaires accédant à des lieux via un service web n’émettent généralement pas ces signaux, tandis que ceux accédant à des lieux stockés localement le font généralement.

Utilisation des catégories

Les catégories sont des mots-clés permettant de décrire un lieu. Par exemple : « parc », « théâtre », « restaurant ». Un lieu peut être décrit par plusieurs catégories : il peut s’agir à la fois d’un parc, d’une salle de concert et d’un embarcadère ou d’un arrêt de bus.

Pour utiliser les catégories, il faut d'abord les initialiser.

/* QPlaceReply * */initCatReply = manager->initializeCategories();
connect(initCatReply, &QPlaceReply::finished, this, &RequestHandler::handleInitCatReply);
    ...
    ...
void handleInitCatReply() {
    if (initCatReply->error()== QPlaceReply::NoError)
        qDebug() << "Categories initialized";
   sinon
        qDebug() << "Failed to initialize categories";

    initCatReply->deleteLater();
    initCatReply = nullptr;
}

Une fois les catégories initialisées, nous pouvons alors utiliser ces fonctions de catégorie.

Pour récupérer les catégories de premier niveau, nous utilisons la fonction QPlaceManager::childCategories(), mais sans fournir d’identifiant de catégorie.

const QList<QPlaceCategory> topLevelCategories = manager->childCategories();
for (const QPlaceCategory&category: topLevelCategories)
    qDebug() << category.name();

Si nous fournissions un identifiant, nous pourrions alors récupérer les éléments enfants d'une catégorie.

QList<QPlaceCategory> childCategories = manager->childCategories(pizza.categoryId());

Enregistrement d'une catégorie

Voici comment enregistrer une catégorie

QPlaceCategory fastFood;

QPlaceCategory category;
category.setName("pizza");
/*QPlaceIdReply */ saveCategoryReply = manager->saveCategory(category);
connect(saveCategoryReply, &QPlaceIdReply::finished, this, &RequestHandler::handleSaveCategoryReply);

// Nous aurions pu enregistrer une catégorie en tant qu'enfant en fournissant un identifiant de parent.
saveCategoryReply = manager->saveCategory(category, fastFood.categoryId());
    ...
    ...
void handleSaveCategoryReply() {
    if (saveCategoryReply->error()== QPlaceReply::NoError) {
        qDebug() << "Saved category id =" << saveCategoryReply->id();
    }

    saveCategoryReply->deleteLater();
    saveCategoryReply = nullptr;
}

Lorsqu’une catégorie est enregistrée, l’ QPlaceManager peut émettre les signaux QPlaceManager::categoryAdded() ou QPlaceManager::categoryUpdated(). Cependant, le fait qu’un gestionnaire émette ou non ces signaux dépend du fournisseur : les gestionnaires accédant à des lieux via un service web n’émettent généralement pas ces signaux, tandis que ceux accédant à des lieux stockés localement le font généralement.

Suppression d’une catégorie

La suppression d'une catégorie s'effectue de manière très similaire à la suppression d'un lieu

/* QPlaceIdReply * */removeCategoryReply = manager->removeCategory(place.placeId());
connect(removeCategoryReply, &QPlaceIdReply::finished, this, &RequestHandler::handleRemoveCategoryReply);
    ...
    ...
void handleRemoveCategoryReply() {
    if (removeCategoryReply->error()== QPlaceReply::NoError)
        qDebug() << "Removal of category identified by"
                << removeCategoryReply->id() << "a réussi";

    removeCategoryReply->deleteLater() ; // ignorer la réponse
    removeCategoryReply = nullptr ;
}

Lorsqu’une catégorie est supprimée, l’ QPlaceManager peut émettre le signal QPlaceManager::categoryRemoved(). Le fait qu’un gestionnaire émette ou non ce signal dépend du fournisseur. Les gestionnaires accédant à des lieux via un service web n’émettent généralement pas ces signaux, tandis que ceux accédant à des lieux stockés localement le font généralement.

Correspondance des lieux entre gestionnaires

Il peut parfois être utile de vérifier si les lieux d’un gestionnaire correspondent à ceux d’un autre. Une telle situation peut se présenter 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 un nom de favori personnalisé plutôt que le nom d’origine.

Le mécanisme de mise en correspondance peut varier d’un gestionnaire à l’autre, mais s’effectue généralement via un identifiant alternatif. Dans le cadre du processus d’enregistrement, l’identifiant de lieu provenant du gestionnaire d’origine est enregistré en tant qu’attribut d’identifiant alternatif dans le gestionnaire de destination (qui peut disposer de son propre schéma d’identifiants de lieux). Dans l’exemple suivant, le gestionnaire d’origine provient du QGeoServiceProvider « here » ; par conséquent, dans le cadre du processus d’enregistrement, un attribut d’identifiant alternatif, x_id_here, est défini pour le lieu enregistré dans le gestionnaire de destination (lorsque la méthode QPlaceManager::compatiblePlace() est appelée).

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: ae246

Afin d’effectuer la mise en correspondance, nous créons une instance de ` QPlaceMatchRequest ` et lui attribuons les résultats de recherche provenant du gestionnaire d’origine. L’instance ` QPlaceMatchRequest ` sera utilisée sur le gestionnaire de destination pour renvoyer les lieux correspondants. Nous spécifions également des paramètres de mise en correspondance qui sont des paires clé-valeur. Comme mentionné précédemment, cela peut varier en fonction du gestionnaire, mais en général, la clé est « QPlaceMatchRequest::AlternativeId » pour indiquer que la mise en correspondance s’effectue par identifiant alternatif ; la valeur, dans ce cas, serait « x_id_here », qui précise quel attribut d’identifiant alternatif nous utilisons pour effectuer la mise en correspondance.

QPlaceMatchRequest request;
request.setResults(results);
QVariantMap paramètres;
paramètres.insert(QPlaceMatchRequest::AlternativeId, "x_id_here");
request.setParameters(parameters);
matchReply = manager->matchingPlaces(request);
    ...
    ...
void matchHandler() {
    if (matchReply->error()== QPlaceReply::NoError) {
        const auto places = matchReply->places();
        for (const QPlace&place: places) {
            if (place != QPlace())
                qDebug() << "Place is a favorite with name" << place.name();
           sinon
                qDebug() << "Place is not a favorite";
        }
    }

    matchReply->deleteLater();
    matchReply = nullptr;
}

Les classes dans Places

Classes de données

QGeoAddress

Représente l'adresse d'un QGeoLocation

QGeoLocation

Représente les informations de base sur un lieu

QPlace

Représente un ensemble de données concernant un lieu

QPlaceAttribute

Représente des informations d'attributs génériques concernant un lieu

QPlaceCategory

Représente une catégorie à laquelle un QPlace peut être associé

QPlaceContactDetail

Représente une coordonnée, telle qu'un numéro de téléphone ou l'URL d'un site web

QPlaceContent

Contient du contenu relatif à des lieux

QPlaceIcon

Représente une icône

QPlaceProposedSearchResult

Représente un résultat de recherche contenant une suggestion de recherche

QPlaceRatings

Contient des informations d'évaluation concernant un lieu

QPlaceResult

Représente un résultat de recherche contenant un lieu

QPlaceSearchResult

La classe de base pour les résultats de recherche

QPlaceUser

Représente un utilisateur individuel

Classes de requête

QPlaceContentRequest

Représente les paramètres d’une requête de contenu

QPlaceMatchRequest

Permet de rechercher des lieux d’un gestionnaire qui correspondent à ceux d’un autre. Représente un ensemble de paramètres de requête

QPlaceSearchRequest

Représente l'ensemble des paramètres d'une requête de recherche

Classes de réponse

QPlaceContentReply

Gère une opération de récupération de contenu lancée par une instance de QPlaceManager

QPlaceDetailsReply

Gère une opération de récupération des détails d’un lieu lancée par une instance de QPlaceManager

QPlaceIdReply

Gère les opérations qui renvoient un identifiant, telles que les opérations d’enregistrement et de suppression de lieux et de catégories

QPlaceMatchReply

Gère une opération de correspondance de lieux lancée par une instance de QPlaceManager

QPlaceReply

Gère une opération lancée par une instance de QPlaceManager et sert de classe de base pour des réponses plus spécialisées

QPlaceSearchReply

Gère une opération de recherche de lieu lancée par une instance de QPlaceManager

QPlaceSearchSuggestionReply

Gère une opération de suggestion de recherche lancée par une instance de QPlaceManager

Classes de gestion

QPlaceManager

Interface permettant aux clients d'accéder aux lieux stockés dans un backend particulier

QPlaceManagerEngine

Interface destinée aux développeurs de plugins QGeoServiceProvider souhaitant fournir un accès aux fonctionnalités liées aux lieux

© 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.