Spec-Zone.ru › Qt 5.11

Места (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', поэтому в рамках процесса сохранения для сохраненного в целевом менеджере места устанавливается атрибут альтернативного идентификатора 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

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

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/archives/qt-5.11/location-places-cpp.html

Spec-Zone.ru

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