Бэкенд мест
Обзор
Интерфейс QPlaceManager, предоставляемый клиентам для доступа к информации о местах, напрямую зависит от реализации QPlaceManagerEngine. Движок предоставляет реализации функций бэкенда, которые вызываются менеджером.
Реализатор бэкенда мест должен наследовать от QPlaceManagerEngine и предоставить реализации виртуальных функций, относящихся к его бэкенду. Большинство этих функций асинхронны, поэтому реализаторам также потребуется наследоваться от соответствующих классов ответов. Объекты ответов отвечают за управление асинхронным запросом; они используются для уведомления о завершении запроса и хранения результатов этого запроса. QPlaceManagerEngine предоставляет реализацию по умолчанию для всех виртуальных функций. Реализации по умолчанию для асинхронных функций возвращают ответ, который будет излучать сигналы error() и finished() на следующей итерации цикла обработки событий.
Реализация/Наследование объектов ответов
Объект ответа будет наследоваться следующим образом:
class SearchReply : public QPlaceSearchReply
{
public:
explicit SearchReply(ManagerEngine *engine)
: QPlaceSearchReply(engine), m_engine(engine){}
~SearchReply();
void setResults(const QList<QPlaceSearchResult> &results);
void setRequest(const QPlaceSearchRequest &request);
...
void triggerDone(QPlaceReply::Error error = QPlaceReply::NoError,
const QString &errorString = QString());
ManagerEngine *m_engine;
}; Реализация QPlaceManagerEngine должна гарантировать, что любые сигналы, излучаемые объектами ответов, отложены до возврата функций запроса и возможности кода приложения подключить эти сигналы к слотам. Типичный подход — использование QMetaObject::invokeMethod() с Qt::QueuedConnection для излучения сигналов.
void SearchSuggestionReply::triggerDone(QPlaceReply::Error error,
const QString &errorString)
{
if (error != QPlaceReply::NoError) {
this->setError(error,errorString);
QMetaObject::invokeMethod(m_engine, "error", Qt::QueuedConnection,
Q_ARG(QPlaceReply *,this),
Q_ARG(QPlaceReply::Error, error),
Q_ARG(QString, errorString));
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
Q_ARG(QPlaceReply::Error, error),
Q_ARG(QString, errorString));
}
this->setFinished(true);
QMetaObject::invokeMethod(m_engine, "finished", Qt::QueuedConnection,
Q_ARG(QPlaceReply *,this));
QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
} Обратите внимание, что сигналы finished должны всегда излучаться при завершении ответа, даже если возникла ошибка. То есть, если есть ошибка, должны излучаться сигналы error и finished, а если ошибки нет, только сигналы finished.
Защищенные функции QPlaceSearchReply::setResults() и QPlaceSearchReply::setRequest() сделаны общедоступными, чтобы плагин мог назначать результаты и запросы. Поскольку эти функции не экспортируются публично, доступность не столь важна. Альтернативой было бы объявление дружественного класса в SearchReply.
Обычно экземпляр движка будет parent для ответа. Если разработчик не удаляет ответы при завершении, движок может очистить их при уничтожении. Часто ответ также имеет ссылку на движок, которая может использоваться для излучения сигналов QPlaceManagerEngine::finished() и QPlaceManagerEngine::error(). Это всего лишь один из многих способов реализации ответа.
URL-адреса значков
URL-адреса значков предоставляются через функцию QPlaceManagerEngine::constructIconUrl(). Ожидается, что движок будет использовать QPlaceIcon::parameters() для построения соответствующего URL-адреса. Когда объект QPlace возвращается менеджером, либо при поиске, либо при запросе деталей места, ожидается, что движок корректно заполнит параметры по мере необходимости.
Бэкенд свободен выбирать ключи и значения параметров, однако, если у бэкенда всегда только один URL на значок, рекомендуется использовать QPlaceIcon::SingleUrl в качестве ключа.
Категории
Категории движка менеджера — это относительно статические сущности; для движков, получающих доступ к удалённым хранилищам данных о местах, может быть целесообразно кешировать структуру категорий, а не выполнять запросы к серверу каждый раз, когда вызывается QPlaceManagerEngine::initializeCategories(). В зависимости от того, насколько динамичны категории, всегда загрузка самого последнего набора категорий может быть более уместным.
Сохранение мест в менеджере
Место обычно не может быть сохранёно напрямую между менеджерами, поскольку оно содержит данные, специфичные для менеджера, такие как значки и категории. Для сохранения в собственном менеджере реализаторы движка должны реализовать функцию QPlaceManagerEngine::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 Для реализации перекрёстного ссылания по альтернативному идентификатору существуют три предварительных условия. Первое — исходный менеджер должен предоставить атрибут x_provider со значением — именем QGeoServiceProvider менеджера. Метка атрибута должна оставаться пустой, что указывает на то, что атрибут не должен отображаться пользователю.
Примечание: Обычно ожидается, что все менеджеры должны установить атрибут x_provider.
Второе — функция QPlaceManager::compatiblePlace() менеджера назначения должна использовать атрибут x_provider исходного места и установить атрибут альтернативного идентификатора сохраняемого места. Ключ атрибута альтернативного идентификатора — x_id_<provider name>, а текстовое значение — идентификатор исходного места. Атрибут x_provider не должен передаваться в совместимое место. При сохранении x_provider сохранённого места считается менеджером назначения.
Третье — функция QPlaceManager::matchingPlaces() менеджера назначения должна принимать QPlaceMatchRequest::AlternativeId в качестве параметра ключа и ключ атрибута альтернативного идентификатора в качестве значения, в этом случае ожидаемым значением будет x_id_<provider name>. Это указывает, что идентификаторы мест в QPlaceMatchRequest должны быть сопоставлены с атрибутами альтернативного идентификатора x_id_<provider name>.
Обратите внимание, что если менеджер назначения должен обеспечивать сохранение и перекрёстное ссылание из любого произвольного менеджера, он должен внутренне поддерживать сохранение произвольных пар ключ-значение, так как мы не можем знать имена поставщиков заранее, а также не можем знать структуру идентификаторов.
Другие способы связывания
Если исходный менеджер не предоставляет идентификатор места, может потребоваться предоставить другие средства перекрёстного ссылания/сопоставления. Один подход — сделать это через координаты места, если координаты места в исходном менеджере совпадают или близки к месту в менеджере назначения, высокая вероятность, что это одно и то же место. В этом случае менеджер может реализовать QPlaceManager::matchingPlaces() для принятия QPlaceMatchRequest с параметром ключа 'proximity' и значением параметра — расстояния, на котором должны находиться два места, чтобы распознать совпадение. Например, если исходное место и место назначения находятся на расстоянии 50 м друг от друга, их можно считать одним и тем же местом.
Однако, как правило, рекомендуется реализовывать перекрёстное ссылание с помощью альтернативных идентификаторов, как описано выше.
Атрибуты для отображения пользователю и не для отображения
Если атрибут не предназначен для чтения конечными пользователями, поле метки должно оставаться пустым как индикатор этого факта.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.13/location-places-backend.html