Backend de Lugares
Visión general
La interfaz QPlaceManager, proporcionada a los clientes para permitir el acceso a la información de lugares, depende directamente de una implementación de QPlaceManagerEngine. El motor proporciona las implementaciones de las funciones backend que son llamadas por el gestor.
Un implementador de backend de lugares necesita derivar de QPlaceManagerEngine y proporcionar implementaciones para las funciones virtuales relevantes para su backend. La mayoría de estas funciones son asíncronas, por lo que los implementadores también tendrán que derivar las clases de respuesta apropiadas. Los objetos de respuesta se encargan de gestionar las peticiones asíncronas; se utilizan para notificar cuándo se ha completado una petición y para guardar los resultados de la misma. QPlaceManagerEngine proporciona una implementación por defecto para todas las funciones virtuales. Las implementaciones por defecto para las funciones asíncronas devuelven una respuesta que emitirá las señales errorOccurred() y finished() en la siguiente iteración a través del bucle de eventos.
Implementación/herencia de objetos respuesta
Un objeto de respuesta se hereda de la siguiente manera:
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; };
La implementación de un QPlaceManagerEngine debe garantizar que cualquier señal emitida por los objetos de respuesta se retrase hasta que las funciones de solicitud hayan regresado y el código de la aplicación tenga la oportunidad de conectar esas señales a las ranuras. El enfoque típico es utilizar QMetaObject::invokeMethod() con un Qt::QueuedConnection para emitir las señales.
void SearchSuggestionReply::triggerDone(QPlaceReply::Error error, const QString &errorString) { if (error != QPlaceReply::NoError) { this->setError(error,errorString); QMetaObject::invokeMethod(m_engine, "errorOccurred", Qt::QueuedConnection, Q_ARG(QPlaceReply *,this), Q_ARG(QPlaceReply::Error, error), Q_ARG(QString, errorString)); QMetaObject::invokeMethod(this, "errorOccurred", 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); }
Tenga en cuenta que las señales finished siempre deben emitirse cuando se completa una respuesta, incluso si se ha encontrado un error, es decir, si hay un error, deben emitirse tanto las señales error como finished mientras que si no hay error, sólo se emiten las señales finished.
Las funciones protegidas de QPlaceSearchReply::setResults() y QPlaceSearchReply::setRequest() se hacen accesibles públicamente para que el plugin pueda asignar resultados y peticiones. Como estas funciones no se exportan públicamente, la accesibilidad no es un problema tan importante. Una alternativa habría sido declarar una clase amiga en SearchReply.
Típicamente la instancia del motor se convertiría en el parent de la respuesta. Si el desarrollador no descarta las respuestas al terminar, el motor puede limpiarlas al destruirlas. Comúnmente, la respuesta también tiene un puntero de referencia al motor, que puede ser utilizado para emitir las señales QPlaceManagerEngine::finished() y QPlaceManagerEngine::error(). Esta es sólo una de las muchas formas en que se puede implementar la respuesta.
URL de iconos
Las URLs de iconos se proporcionan a través de la función QPlaceManagerEngine::constructIconUrl(). El comportamiento esperado es que el motor utilice la función QPlaceIcon::parameters() para construir una URL apropiada. Cuando el gestor devuelva un objeto QPlace, ya sea mediante una búsqueda o una consulta para obtener información sobre un lugar, se espera que el motor rellene correctamente los parámetros necesarios.
El backend es libre de elegir la clave y los valores de los parámetros, pero si un backend sólo tiene una URL por icono, se recomienda utilizar QPlaceIcon::SingleUrl como clave.
Categorías
Las categorías de un motor gestor son entidades relativamente estáticas; para los motores que acceden a almacenes de datos de lugares remotos puede ser conveniente almacenar en caché la estructura de categorías en lugar de consultar un servidor cada vez que se llama a QPlaceManagerEngine::initializeCategories(). Dependiendo de lo dinámicas que sean las categorías, puede ser más apropiado descargar siempre el conjunto de categorías más reciente.
Guardar lugares en el Gestor
Un lugar generalmente no puede guardarse directamente entre gestores tal cual porque contiene datos específicos del gestor como iconos y categorías. Para facilitar el guardado en el propio gestor, los implementadores del motor deberían implementar la función QPlaceManagerEngine::compatiblePlace(). Esta función devuelve una copia del lugar de entrada con las propiedades podadas o modificadas según sea necesario para que la copia pueda guardarse en el gestor.
La construcción de un lugar compatible puede implicar ignorar ciertas propiedades del lugar original, por ejemplo, si no se admiten datos de contacto, éstos se omiten en el lugar compatible. Otras veces puede implicar modificar ciertas propiedades, por ejemplo modificar los parámetros del icono para facilitar la copia o descarga del icono del lugar original a una ubicación a la que el backend pueda acceder.
Referencia cruzada de lugares entre gestores
A veces puede surgir una situación en la que deseemos hacer referencias cruzadas y emparejar lugares entre gestores. Esta situación puede darse cuando un gestor proporciona acceso de sólo lectura a los lugares (gestor de origen), mientras que otro segundo gestor r/w (gestor de destino) se utiliza para guardar los favoritos seleccionados del primero. Durante una búsqueda en el gestor de origen, es posible que queramos saber cuáles han sido "favoritos" en el gestor de destino y quizás mostrar el nombre personalizado del favorito en lugar del nombre original.
Referencias cruzadas de identificadores alternativos
Para poder realizar referencias cruzadas, es necesario que exista un vínculo entre el lugar original y el lugar favorito, y esto se suele gestionar mediante un atributo de identificador alternativo. El lugar preferido contiene un atributo de identificador alternativo que contiene el identificador del lugar original.
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
Existen 3 requisitos previos para implementar la referencia cruzada por identificador alternativo. El primero es que el gestor de origen debe proporcionar el atributo x_provider cuyo valor es el nombre del gestor QGeoServiceProvider. La etiqueta del atributo debe mantenerse vacía, lo que indica que el atributo no debe mostrarse a los usuarios.
Nota: Por lo general, se espera que todos los gestores establezcan el atributo x_provider.
La segunda es que QPlaceManager::compatiblePlace() del gestor de destino utilice el atributo x_provider del lugar inicial y establezca un atributo identificador alternativo del lugar que se va a guardar. La clave del atributo identificador alternativo es x_id_<provider name> y el valor del texto es el identificador del lugar inicial. El atributo x_provider no debe pasarse al lugar compatible. Cuando se guarda, se considera que el x_provider del lugar guardado es el gestor de destino.
La tercera es que QPlaceManager::matchingPlaces() del gestor de destino acepta el QPlaceMatchRequest::AlternativeId como parámetro clave y el atributo identificador alternativo clave como valor, en este caso x_id_<provider nombre> sería el valor esperado. Esto indica que los identificadores de lugares en el QPlaceMatchRequest deben cotejarse con los atributos de identificador alternativo x_id_<provider nombre>.
Nótese que si el gestor de destino debe facilitar el guardado y las referencias cruzadas desde cualquier gestor arbitrario, internamente debe acomodar el guardado de pares clave-valor arbitrarios, ya que no podemos conocer los nombres de los proveedores de antemano, ni podemos saber qué estructura tendrán los ids.
Otros métodos de enlace
Si un gestor de origen no proporciona un identificador de lugar, puede ser necesario proporcionar algún otro medio de referencia cruzada/emparejamiento. Un enfoque podría ser hacerlo a través de las coordenadas de lugar, si la coordenada de un lugar en el gestor de origen es idéntica o cercana a un lugar en el gestor de destino, hay una alta probabilidad de que sean el mismo lugar. En este caso, el gestor podría implementar QPlaceManager::matchingPlaces() para aceptar un QPlaceMatchRequest con una clave de parámetro de "proximidad" y un valor de parámetro de la distancia a la que deben estar dos lugares para detectar una coincidencia. por ejemplo, si un lugar de origen y un lugar de destino están a menos de 50 m el uno del otro, pueden considerarse el mismo lugar.
No obstante, en general se recomienda que las referencias cruzadas se realicen mediante identificadores alternativos, como se ha mencionado anteriormente.
Atributos ampliados legibles por el usuario y no legibles por el usuario
Si se pretende que un atributo no sea legible por los usuarios finales, el campo de etiqueta debe mantenerse vacío como indicador de este hecho.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.