Spec-Zone.ru › Qt 5.13

Места (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) {
        QMapIterator<int, QPlaceContent> iter(contentReply->content());
        while (iter.hasNext()) {
            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», поэтому в процессе сохранения для места, сохраненного в целевом менеджере (когда вызывается QPlaceManager::compatiblePlace()), устанавливается атрибут альтернативного идентификатора x_id_here.

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

Классы мест

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

QPlace

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

QPlaceIcon

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

QPlaceAttribute

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

QPlaceCategory

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

QPlaceContactDetail

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

QPlaceContent

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

QPlaceEditorial

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

QPlaceImage

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

QPlaceProposedSearchResult

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

QPlaceRatings

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

QPlaceResult

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

QPlaceReview

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

QPlaceSearchResult

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

QPlaceSupplier

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

QPlaceUser

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

QGeoAddress

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

QGeoLocation

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

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

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.13/location-places-cpp.html

Spec-Zone.ru

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