Lock map tracking to corrected IMU output
This commit is contained in:
+8
-3
@@ -465,9 +465,14 @@ void GlobeWidget::drawBlueMarble(QPainter &painter) const
|
||||
}
|
||||
|
||||
const double radius = std::min(width(), height()) * 0.255 * m_zoom;
|
||||
const double pixelRatio = std::min(devicePixelRatioF(), 2.0);
|
||||
const int textureSize = std::clamp(
|
||||
static_cast<int>(std::ceil(radius * 2.0 * pixelRatio)), 420, 1200);
|
||||
// Interactive rotation favors latency; mouse release immediately causes
|
||||
// a full Retina-quality rebuild. Satellite animation frames reuse the
|
||||
// cached texture and therefore do not repeat this projection work.
|
||||
const double pixelRatio = m_dragging ? std::min(devicePixelRatioF(), 1.0)
|
||||
: std::min(devicePixelRatioF(), 2.0);
|
||||
const int textureSize = m_dragging
|
||||
? std::clamp(static_cast<int>(std::ceil(radius * 2.0 * pixelRatio)), 280, 650)
|
||||
: std::clamp(static_cast<int>(std::ceil(radius * 2.0 * pixelRatio)), 420, 1200);
|
||||
const QPointF center(width() * 0.5, height() * 0.52);
|
||||
const QRectF target(center.x() - radius, center.y() - radius,
|
||||
radius * 2.0, radius * 2.0);
|
||||
|
||||
@@ -164,6 +164,7 @@ LocationAnalysis analyzeLocations(const QVector<TelemetryPoint> &points)
|
||||
QVector<TelemetryPoint> preferredAnalysisPoints(const QVector<TelemetryPoint> &points)
|
||||
{
|
||||
QVector<TelemetryPoint> corrected;
|
||||
corrected.reserve(points.size());
|
||||
for (const TelemetryPoint &point : points) {
|
||||
if (point.source == LocationSource::ImuCorrected) {
|
||||
corrected.push_back(point);
|
||||
|
||||
+30
-16
@@ -91,9 +91,9 @@ void MapWidget::setPoints(const QVector<TelemetryPoint> &points)
|
||||
m_points = points;
|
||||
|
||||
if (!m_points.isEmpty() && m_autoFollow) {
|
||||
const TelemetryPoint &last = m_points.last();
|
||||
m_centerLat = last.latitude;
|
||||
m_centerLon = last.longitude;
|
||||
const TelemetryPoint &focus = m_points[preferredFocusIndex()];
|
||||
m_centerLat = focus.latitude;
|
||||
m_centerLon = focus.longitude;
|
||||
if (wasEmpty) {
|
||||
m_zoom = MaxZoom;
|
||||
}
|
||||
@@ -232,9 +232,9 @@ void MapWidget::setAutoFollow(bool enabled)
|
||||
|
||||
m_autoFollow = enabled;
|
||||
if (m_autoFollow && !m_points.isEmpty()) {
|
||||
const TelemetryPoint &last = m_points.last();
|
||||
m_centerLat = last.latitude;
|
||||
m_centerLon = last.longitude;
|
||||
const TelemetryPoint &focus = m_points[preferredFocusIndex()];
|
||||
m_centerLat = focus.latitude;
|
||||
m_centerLon = focus.longitude;
|
||||
update();
|
||||
}
|
||||
emit autoFollowChanged(m_autoFollow);
|
||||
@@ -522,9 +522,10 @@ void MapWidget::drawTelemetry(QPainter &painter)
|
||||
drawCepMarker(painter);
|
||||
|
||||
const bool drawNumbers = m_points.size() <= 150;
|
||||
const int firstPoint = m_showRecentPoints ? 0 : m_points.size() - 1;
|
||||
for (int i = firstPoint; i < m_points.size(); ++i) {
|
||||
const bool isLast = i == m_points.size() - 1;
|
||||
const int focusIndex = preferredFocusIndex();
|
||||
for (int i = 0; i < m_points.size(); ++i) {
|
||||
if (!m_showRecentPoints && i != focusIndex) continue;
|
||||
const bool isLast = i == focusIndex;
|
||||
const QPointF screen = coordinateToScreen(m_points[i].latitude, m_points[i].longitude);
|
||||
const double radius = isLast ? 8.0 : 5.0;
|
||||
|
||||
@@ -547,7 +548,7 @@ void MapWidget::drawTelemetry(QPainter &painter)
|
||||
}
|
||||
}
|
||||
|
||||
const TelemetryPoint &last = m_points.last();
|
||||
const TelemetryPoint &last = m_points[focusIndex];
|
||||
const QPointF lastScreen = coordinateToScreen(last.latitude, last.longitude);
|
||||
QStringList lines;
|
||||
const QString latitudeText = last.latitudeText.isEmpty()
|
||||
@@ -655,9 +656,10 @@ void MapWidget::drawCepMarker(QPainter &painter)
|
||||
painter.drawLine(QPointF(screen.x(), screen.y() - 11.0),
|
||||
QPointF(screen.x(), screen.y() + 11.0));
|
||||
|
||||
const bool overlapsLast = !m_points.isEmpty()
|
||||
&& QLineF(screen, coordinateToScreen(m_points.last().latitude,
|
||||
m_points.last().longitude)).length() < 30.0;
|
||||
const int focusIndex = preferredFocusIndex();
|
||||
const bool overlapsLast = focusIndex >= 0
|
||||
&& QLineF(screen, coordinateToScreen(m_points[focusIndex].latitude,
|
||||
m_points[focusIndex].longitude)).length() < 30.0;
|
||||
if (!overlapsLast) {
|
||||
painter.setFont(QFont(painter.font().family(), 9, QFont::Bold));
|
||||
painter.setPen(QColor(20, 83, 78));
|
||||
@@ -691,9 +693,10 @@ void MapWidget::drawAverageOverlay(QPainter &painter)
|
||||
painter.drawLine(QPointF(screen.x() - 12.0, screen.y()), QPointF(screen.x() + 12.0, screen.y()));
|
||||
painter.drawLine(QPointF(screen.x(), screen.y() - 12.0), QPointF(screen.x(), screen.y() + 12.0));
|
||||
|
||||
const bool overlapsLast = !m_points.isEmpty()
|
||||
&& QLineF(screen, coordinateToScreen(m_points.last().latitude,
|
||||
m_points.last().longitude)).length() < 30.0;
|
||||
const int focusIndex = preferredFocusIndex();
|
||||
const bool overlapsLast = focusIndex >= 0
|
||||
&& QLineF(screen, coordinateToScreen(m_points[focusIndex].latitude,
|
||||
m_points[focusIndex].longitude)).length() < 30.0;
|
||||
if (!overlapsLast) {
|
||||
painter.setFont(QFont(painter.font().family(), 9, QFont::Bold));
|
||||
const QRectF labelRect(screen + QPointF(12.0, 8.0), QSizeF(72.0, 20.0));
|
||||
@@ -773,3 +776,14 @@ void MapWidget::disableAutoFollowFromUserAction()
|
||||
m_autoFollow = false;
|
||||
emit autoFollowChanged(false);
|
||||
}
|
||||
|
||||
int MapWidget::preferredFocusIndex() const
|
||||
{
|
||||
// Once corrected ESKF output is present, both camera and detail bubble
|
||||
// stay locked to its newest point. Raw GPS and truth records may arrive
|
||||
// later in an interleaved stream and must not pull the camera away.
|
||||
for (int index = m_points.size() - 1; index >= 0; --index) {
|
||||
if (m_points[index].source == LocationSource::ImuCorrected) return index;
|
||||
}
|
||||
return m_points.isEmpty() ? -1 : m_points.size() - 1;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
void setCepMarker(double latitude, double longitude,
|
||||
const std::optional<double> &radiusMeters);
|
||||
void clearCepMarker();
|
||||
[[nodiscard]] QPointF centerCoordinate() const { return {m_centerLat, m_centerLon}; }
|
||||
|
||||
public slots:
|
||||
void setAutoFollow(bool enabled);
|
||||
@@ -66,6 +67,7 @@ private:
|
||||
void requestTile(int tileX, int tileY, int zoom);
|
||||
void setZoomKeepingPoint(int newZoom, const QPointF &screenAnchor);
|
||||
void disableAutoFollowFromUserAction();
|
||||
int preferredFocusIndex() const;
|
||||
|
||||
QVector<TelemetryPoint> m_points;
|
||||
QNetworkAccessManager *m_network = nullptr;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <QTemporaryFile>
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -93,6 +94,27 @@ int main(int argc, char **argv)
|
||||
assert(toggleSerialAction != nullptr && !toggleSerialAction->shortcut().isEmpty());
|
||||
assert(rinexUpdateAction != nullptr && !rinexUpdateAction->shortcut().isEmpty());
|
||||
|
||||
QVector<TelemetryPoint> followPoints;
|
||||
TelemetryPoint gpsPoint;
|
||||
gpsPoint.source = LocationSource::Gps;
|
||||
gpsPoint.latitude = 40.0;
|
||||
gpsPoint.longitude = 29.0;
|
||||
followPoints.push_back(gpsPoint);
|
||||
TelemetryPoint correctedPoint = gpsPoint;
|
||||
correctedPoint.source = LocationSource::ImuCorrected;
|
||||
correctedPoint.latitude = 40.25;
|
||||
correctedPoint.longitude = 29.5;
|
||||
followPoints.push_back(correctedPoint);
|
||||
TelemetryPoint trajectoryPoint = gpsPoint;
|
||||
trajectoryPoint.source = LocationSource::Trajectory;
|
||||
trajectoryPoint.latitude = 41.0;
|
||||
trajectoryPoint.longitude = 30.0;
|
||||
followPoints.push_back(trajectoryPoint);
|
||||
map->setPoints(followPoints);
|
||||
assert(std::abs(map->centerCoordinate().x() - 40.25) < 0.000001);
|
||||
assert(std::abs(map->centerCoordinate().y() - 29.5) < 0.000001);
|
||||
map->clearPoints();
|
||||
|
||||
assert(QMetaObject::invokeMethod(map, "referenceLocationSelected", Qt::DirectConnection,
|
||||
Q_ARG(double, 40.25), Q_ARG(double, 29.5)));
|
||||
assert(referenceLatInput->text() == QStringLiteral("40.250000000000000"));
|
||||
|
||||
Reference in New Issue
Block a user