Spec-Zone.ru › Qt 5.15

Места (C++)

Обзор

API Места позволяет пользователям находить места/точки интереса и просматривать подробности о них, такие как адрес и контактная информация; некоторые места могут содержать богатый контент, такой как изображения и отзывы. API Места также упрощает управление местами и категориями, позволяя пользователям сохранять и удалять их.

Определение места

Место — это точка интереса, это может быть любимый ресторан, парк или чья-то квартира. Объект QPlace представляет место, действуя как контейнер для различной информации об этом месте.

Эту информацию можно разделить на две основные категории:

  • Подробности
  • Богатый контент

Подробности места состоят из свойств места, таких как имя, местоположение, контактная информация и так далее. Когда место возвращается во время поиска, эти подробности заполняются. Иногда, чтобы сэкономить пропускную способность, есть дополнительная информация о месте, которую можно получить для каждого отдельного места по запросу пользователя, если он заинтересован. Функция QPlace::detailsFetched() может быть запрошена для проверки, были ли получены все доступные подробности, и если нет, то QPlaceManager::getPlaceDetails() может быть использована для их получения. Точно какие подробности заполняются во время поиска, а какие нужно получать индивидуально, может различаться в зависимости от поставщика. Более подробную информацию см. в документации плагина.

Богатый контент места состоит из таких элементов, как изображения, отзывы и статьи. Возможно, может быть много элементов богатого контента, поэтому они обрабатываются отдельно от подробностей места. Их можно получить по страницам с помощью QPlaceManager::getPlaceContent(). При необходимости контент можно назначить месту, чтобы он действовал как удобный контейнер.

Общие операции

Инициализация менеджера

Все функциональные возможности мест обеспечиваются экземпляром QPlaceManager. Для создания QPlaceManager необходимо указать QGeoServiceProvider.

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

Обнаружение/Поиск

Для выполнения операции поиска достаточно создать QPlaceSearchRequest и установить желаемые параметры поиска, такие как поисковый термин и центр поиска.

//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, SIGNAL(finished()), this, SLOT(handleSearchReply()));

Запрос является асинхронной операцией, поэтому нам нужен слот для обработки завершения запроса. В обработчике мы проверяем отсутствие ошибок и то, что тип результата поиска — это место. Если это так, мы можем получить некоторые основные подробности о месте. В конце слота мы удаляем ответ, так как они предназначены только для однократного использования.

void handleSearchReply() {
    if (searchReply->error() == QPlaceReply::NoError) {
        foreach (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();  //discard reply
    searchReply = 0;
}

Примечание: В зависимости от выбранного плагина-бекенда, результаты поиска могут содержать места, для которых есть дополнительные подробности, которые можно получить по отдельности для каждого места. Чтобы получить эти дополнительные подробности, см. Получение подробностей о месте.

Рекомендации

Рекомендации можно получить, предоставив идентификатор места через QPlaceSearchRequest::setRecommendationId(). Получаются все места, похожие на данное место.

Странирование

Если плагин поддерживает странирование, можно предоставить параметр ограничения в запрос поиска.

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

Получение подробностей о месте

У места, возвращённого запросом поиска, могут быть дополнительные подробности, которые можно получить. Следующее демонстрирует, как проверить, есть ли дополнительные подробности, и если есть, как их запросить.

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

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

Получение богатого контента

Богатый контент, такой как изображения и отзывы, извлекается через менеджер, а затем, при необходимости, назначается месту.

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

Мы можем обработать запрос на контент, как показано ниже.

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();
        }

        //alternatively if indexes are irrelevant
        foreach (const QPlaceImage &image, contentReply->content()) {
            qDebug() << image.url();
            qDebug() << image.mimeType();
        }

        //we can assign content to the place that it belongs to.
        //the place object serves as a container where we can retrieve
        //content that has already been fetched
        place.insertContent(contentReply->request().contentType(), contentReply->content());
        place.setTotalContentCount(contentReply->request().contentType(), contentReply->totalCount());
    }

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

Важно отметить, что результаты в QPlaceContentReply — это QPlaceContent::Collection, что по сути является QMap<int, QPlaceContent>. Ключ int в этом случае — индекс контента, а значение — сам контент. Из-за способа реализации контента можно преобразовать тип контента следующим образом

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

Использование QPlaceContent::Collection и преобразование между контентом и его подтипами означает, что код для обработки механики странирования отзывов, изображений и статей можно легко использовать повторно.

Предложения по поиску

Получение предложений по поисковым запросам очень похоже на выполнение поиска мест. QPlaceSearchRequest используется так же, как и для поиска мест, единственное отличие заключается в том, что поисковый термин задаётся как частично завершённая строка.

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

И когда запрос завершён, мы можем использовать ответ для отображения предложений.

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

    suggestionReply->deleteLater(); //discard reply
    suggestionReply = 0;
}

Сохранение места

Сохранение нового места выполняется следующим образом: создаётся экземпляр QPlace и заполняется информация, такая как имя, адрес и координаты. После этого можно вызвать QPlaceManager::savePlace() для начала операции сохранения.

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, SIGNAL(finished()), this, SLOT(handleSavePlaceReply()));

После сохранения места ответ содержит новый идентификатор этого места.

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

    savePlaceReply->deleteLater(); //discard reply
    savePlaceReply = 0;
}

Обратите внимание, что для сохранения уже существующего места, QPlace::placeId() необходимо заполнить правильным идентификатором. В противном случае, если поле пустое, будет создано новое место, или, если идентификатор неверный, будет перезаписано не то место.

При сохранении места QPlaceManager может генерировать сигналы QPlaceManager::placedAdded() или QPlaceManager::placeUpdated(). Однако, генерируется ли менеджер эти сигналы или нет, зависит от поставщика. Менеджеры, обращающиеся к местам через веб-сервис, обычно не генерируют эти сигналы, в то время как менеджеры, обращающиеся к местам, хранящимся локально, обычно их генерируют.

Ограничения

В настоящее время API Места разработан только для сохранения основных подробностей. Сохранение богатого контента, такого как изображения и отзывы, или подробностей, таких как поставщик и рейтинг, не является поддерживаемой областью применения. Обычно менеджер игнорирует эти поля при сохранении и может вывести сообщение об ошибке, если они заполнены.

API Места поддерживает только сохранение следующих основных подробностей:

  • имя
  • идентификатор места
  • местоположение
  • контактные данные
  • иконка
  • категории (подобные тегам имена для описания места)
  • сфера видимости

Возможные ситуации, когда поставщики поддерживают только часть из них. Более подробную информацию см. в документации плагина.

Сохранение таких свойств, как рейтинг, расширенные атрибуты, изображения, отзывы, статьи и поставщик, явно не поддерживается API Места.

Сохранение между менеджерами

При сохранении мест между менеджерами нужно учитывать несколько моментов. Некоторые поля места, такие как идентификатор, категории и значки, являются специфическими для менеджера, например, категории в одном менеджере могут быть не распознаны в другом. Поэтому попытка напрямую сохранить место из одного менеджера в другой невозможна.

Типичный подход — использовать функцию QPlaceManager::compatiblePlace(), она создаёт копию места, но копирует только данные, которые поддерживает менеджер. Управляющая информация менеджера, такая как идентификатор места, не копируется. Новая копия теперь подходит для сохранения в менеджере. Если менеджер поддерживает сопоставление по альтернативным идентификаторам, атрибут альтернативного идентификатора назначается копии (см. Сопоставление мест между менеджерами)

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

Удаление места

Удаление места выполняется следующим образом:

/* QPlaceIdReply * */removePlaceReply = manager->removePlace(place.placeId());
connect(removePlaceReply, SIGNAL(finished()), this, SLOT(handleRemovePlaceReply()));
    ...
    ...
void handleRemovePlaceReply() {
    if (removePlaceReply->error() == QPlaceReply::NoError)
        qDebug() << "Removal of place identified by"
                 << removePlaceReply->id() << "was successful";

    removePlaceReply->deleteLater(); //discard reply
    removePlaceReply = 0;
}

При удалении места QPlaceManager может генерировать сигнал QPlaceManager::placeRemoved(). Генерируется ли менеджером сигнал, зависит от поставщика. Менеджеры, обращающиеся к местам через веб-сервис, как правило, не генерируют эти сигналы, в то время как менеджеры, обращающиеся к локально хранящимся местам, обычно генерируют.

Использование категорий

Категории — это ключевые слова, которые могут описывать место. Например, «парк», «театр», «ресторан». Место может быть описано многими категориями, это может быть парк, музыкальное заведение и остановка автобуса или парома.

Для использования категорий их сначала нужно инициализировать.

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

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

После инициализации категорий можно использовать эти функции категорий.

  • QPlaceManager::childCategories()
  • QPlaceManager::category()
  • QPlaceManager::parentCategoryId()
  • QPlaceManager::childCategoryIds();

Для получения категорий верхнего уровня используется функция QPlaceManager::childCategories(), но не предоставляется идентификатор категории.

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

Если мы предоставим идентификатор, то мы можем получить дочерние категории.

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

Сохранение категории

Следующее показывает, как сохранить категорию

QPlaceCategory fastFood;

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

//we could have saved a category as a child by supplying a parent identifier.
saveCategoryReply = manager->saveCategory(category, fastFood.categoryId());
    ...
    ...
void handleSaveCategoryReply() {
    if (saveCategoryReply->error() == QPlaceReply::NoError) {
        qDebug() << "Saved category id =" << saveCategoryReply->id();
    }

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

При сохранении категории QPlaceManager может генерировать сигналы QPlaceManager::categoryAdded() или QPlaceManager::categoryUpdated(). Однако, генерируется ли менеджер эти сигналы или нет, зависит от поставщика. Менеджеры, обращающиеся к местам через веб-сервис, обычно не генерируют эти сигналы, в то время как менеджеры, обращающиеся к местам, хранящимся локально, обычно их генерируют.

Удаление категории

Удаление категории очень похоже на удаление места

/* QPlaceIdReply * */removeCategoryReply = manager->removeCategory(place.placeId());
connect(removeCategoryReply, SIGNAL(finished()), this, SLOT(handleRemoveCategoryReply()));
    ...
    ...
void handleRemoveCategoryReply() {
    if (removeCategoryReply->error() == QPlaceReply::NoError)
        qDebug() << "Removal of category identified by"
                 << removeCategoryReply->id() << "was successful";

    removeCategoryReply->deleteLater(); //discard reply
    removeCategoryReply = 0;
}

При удалении категории QPlaceManager может генерировать сигнал QPlaceManager::categoryRemoved(). Генерируется ли менеджером сигнал, зависит от поставщика. Менеджеры, обращающиеся к местам через веб-сервис, как правило, не генерируют эти сигналы, в то время как менеджеры, обращающиеся к местам, хранящимся локально, обычно генерируют.

Сопоставление мест между менеджерами

Иногда вам может понадобиться проверить, соответствуют ли места от одного менеджера местам от другого менеджера. Такая ситуация может возникнуть, когда один менеджер предоставляет только чтение мест (исходный менеджер), а другой менеджер чтения/записи (менеджер назначения) используется для сохранения избранных мест из первого. При поиске в исходном менеджере мы можем узнать, какие из них были «избраны» в менеджер назначения и, возможно, отобразить настроенное имя избранного вместо исходного.

Механизм сопоставления может различаться между менеджерами, но обычно достигается с помощью альтернативного идентификатора. В рамках процесса сохранения идентификатор места из исходного менеджера сохраняется как атрибут альтернативного идентификатора в целевом менеджере (который может иметь свою собственную схему идентификатора места). В следующем примере исходный менеджер из QGeoServiceProider 'here', поэтому в рамках процесса сохранения атрибут альтернативного идентификатора x_id_here устанавливается для места, сохраненного в целевом менеджере (при вызове QPlaceManager::compatiblePlace()

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

Для выполнения сопоставления мы создаем QPlaceMatchRequest и присваиваем ему результаты поиска из исходного менеджера. QPlaceMatchRequest будет использоваться в целевом менеджере для возврата соответствующих мест. Мы также указываем параметры сопоставления, которые являются парами «ключ-значение». Как упоминалось ранее, это может варьироваться в зависимости от менеджера, но обычно ключ — QPlaceMatchRequest::AlternativeId, чтобы указать, что мы выполняем сопоставление по альтернативному идентификатору, значение в данном случае будет x_id_here, которое определяет, какой атрибут альтернативного идентификатора мы используем для сопоставления.

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

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

Классы мест

Классы данных

QGeoAddress

Представляет адрес QGeoLocation

QGeoLocation

Представляет основную информацию о местоположении

QPlace

Представляет набор данных о месте

QPlaceAttribute

Представляет общую информацию об атрибуте места

QPlaceCategory

Представляет категорию, к которой можно отнести QPlace

QPlaceContactDetail

Представляет контактные данные, такие как номер телефона или URL веб-сайта

QPlaceContent

Служит базовым классом для типов богатого контента

QPlaceEditorial

Представляет статью издателя, описывающую место

QPlaceIcon

Представляет значок

QPlaceImage

Представляет ссылку на изображение

QPlaceProposedSearchResult

Представляет результат поиска, содержащий предполагаемый поиск

QPlaceRatings

Содержит информацию об оценках места

QPlaceResult

Представляет результат поиска, содержащий место

QPlaceReview

Представляет отзыв о месте

QPlaceSearchResult

Базовый класс для результатов поиска

QPlaceSupplier

Представляет поставщика места или контента, связанного с местом

QPlaceUser

Представляет отдельного пользователя

Классы запросов

QPlaceContentRequest

Представляет параметры запроса контента

QPlaceMatchRequest

Используется для поиска мест из одного менеджера, соответствующих местам из другого. Представляет набор параметров запроса

QPlaceSearchRequest

Представляет набор параметров для запроса поиска

Классы ответов

QPlaceContentReply

Управляет операцией извлечения контента, начатой экземпляром QPlaceManager

QPlaceDetailsReply

Управляет операцией получения подробностей о месте, начатой экземпляром QPlaceManager

QPlaceIdReply

Управляет операциями, возвращающими идентификатор, такими как операции сохранения и удаления мест и категорий

QPlaceMatchReply

Управляет операцией сопоставления мест, начатой экземпляром QPlaceManager

QPlaceReply

Управляет операцией, начатой экземпляром QPlaceManager, и служит базовым классом для более специализированных ответов

QPlaceSearchReply

Управляет операцией поиска мест, начатой экземпляром QPlaceManager

QPlaceSearchSuggestionReply

Управляет операцией предоставления подсказок поиска, начатой экземпляром QPlaceManager

Классы менеджеров

QPlaceManager

Интерфейс, позволяющий клиентам получать доступ к местам, хранящимся в определенном бэкенде

QPlaceManagerEngine

Интерфейс для разработчиков плагинов QGeoServiceProvider, желающих предоставить доступ к функциональности мест

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.15/location-places-cpp.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API