Spec-Zone.ru › Qt 5.6

Места (C++)

Обзор

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

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

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

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

  • Детали
  • Богатый контент

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

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

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

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

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

//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(). Возвращаются любые места, похожие на заданное место.

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

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

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 Места.

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

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

Типичный подход заключается в использовании функции 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 «здесь», поэтому в процессе сохранения атрибут альтернативного идентификатора 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;
}

Классы в местах

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

QPlace

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

QPlaceAttribute

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

QPlaceCategory

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

QPlaceContactDetail

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

QPlaceContent

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

QPlaceEditorial

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

QPlaceIcon

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

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

Spec-Zone.ru

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