From 25f9c7e12505b1ce7a043b7665dfc12779f79571 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Wed, 14 Jun 2023 17:54:09 +0200 Subject: [PATCH] Compute live location bounding box and center the map accordingly --- src/models/livelocationsmodel.cpp | 18 ++++++++++++++++++ src/models/livelocationsmodel.h | 7 +++++++ .../Timeline/LiveLocationDelegate.qml | 4 ++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/models/livelocationsmodel.cpp b/src/models/livelocationsmodel.cpp index 4fed3b275..5de4871ce 100644 --- a/src/models/livelocationsmodel.cpp +++ b/src/models/livelocationsmodel.cpp @@ -38,6 +38,9 @@ LiveLocationsModel::LiveLocationsModel(QObject *parent) }); }, Qt::QueuedConnection); // deferred so we are sure the eventId filter is set + + connect(this, &LiveLocationsModel::dataChanged, this, &LiveLocationsModel::boundingBoxChanged); + connect(this, &LiveLocationsModel::rowsInserted, this, &LiveLocationsModel::boundingBoxChanged); } int LiveLocationsModel::rowCount(const QModelIndex &parent) const @@ -101,6 +104,21 @@ QHash LiveLocationsModel::roleNames() const return r; } +QRectF LiveLocationsModel::boundingBox() const +{ + QRectF bbox(QPointF(180.0, 90.0), QPointF(-180.0, -90.0)); + for (auto i = 0; i < rowCount(); ++i) { + const auto lat = data(index(i, 0), LatitudeRole).toDouble(); + const auto lon = data(index(i, 0), LongitudeRole).toDouble(); + + bbox.setLeft(std::min(bbox.left(), lon)); + bbox.setRight(std::max(bbox.right(), lon)); + bbox.setTop(std::min(bbox.top(), lat)); + bbox.setBottom(std::max(bbox.bottom(), lat)); + } + return bbox; +} + void LiveLocationsModel::addEvent(const Quotient::RoomEvent *event) { if (event->isStateEvent() && event->matrixType() == "org.matrix.msc3672.beacon_info") { diff --git a/src/models/livelocationsmodel.h b/src/models/livelocationsmodel.h index 979762779..9f95d1b1c 100644 --- a/src/models/livelocationsmodel.h +++ b/src/models/livelocationsmodel.h @@ -8,6 +8,7 @@ #include #include +#include namespace Quotient { @@ -36,6 +37,9 @@ class LiveLocationsModel : public QAbstractListModel */ Q_PROPERTY(QString eventId MEMBER m_eventId NOTIFY eventIdChanged) + /** Bounding box of all live location beacons covered by this model. */ + Q_PROPERTY(QRectF boundingBox READ boundingBox NOTIFY boundingBoxChanged) + public: explicit LiveLocationsModel(QObject *parent = nullptr); @@ -52,9 +56,12 @@ public: QVariant data(const QModelIndex &index, int roleName) const override; QHash roleNames() const override; + QRectF boundingBox() const; + Q_SIGNALS: void roomChanged(); void eventIdChanged(); + void boundingBoxChanged(); private: void addEvent(const Quotient::RoomEvent *event); diff --git a/src/qml/Component/Timeline/LiveLocationDelegate.qml b/src/qml/Component/Timeline/LiveLocationDelegate.qml index 8d4a1715c..b69741865 100644 --- a/src/qml/Component/Timeline/LiveLocationDelegate.qml +++ b/src/qml/Component/Timeline/LiveLocationDelegate.qml @@ -34,8 +34,8 @@ TimelineContainer { Layout.fillWidth: true Layout.preferredHeight: root.contentMaxWidth / 16 * 9 - // center: QtPositioning.coordinate(root.latitude, root.longitude) - // zoomLevel: 15 + center: QtPositioning.coordinate(liveLocationModel.boundingBox.y, liveLocationModel.boundingBox.x) + zoomLevel: 15 plugin: OsmLocationPlugin.plugin onCopyrightLinkActivated: Qt.openUrlExternally(link)