Marble

PlacemarkPositionProviderPlugin.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2011 Guillaume Martres <smarter@ubuntu.com>
4// SPDX-FileCopyrightText: 2011, 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
5//
6
7#include "PlacemarkPositionProviderPlugin.h"
8
9#include "GeoDataPlacemark.h"
10#include "MarbleClock.h"
11#include "MarbleDebug.h"
12#include "MarbleModel.h"
13
14#include <QIcon>
15
16using namespace Marble;
17
18PlacemarkPositionProviderPlugin::PlacemarkPositionProviderPlugin(MarbleModel *marbleModel, QObject *parent)
20 , m_marbleModel(marbleModel)
21 , m_placemark(nullptr)
22 , m_speed(0)
23 , m_direction(0.0)
24 , m_status(PositionProviderStatusUnavailable)
25 , m_isInitialized(false)
26{
27 m_accuracy.level = GeoDataAccuracy::Detailed;
28}
29
30QString PlacemarkPositionProviderPlugin::name() const
31{
32 return tr("Placemark position provider Plugin");
33}
34
35QString PlacemarkPositionProviderPlugin::nameId() const
36{
37 return QStringLiteral("Placemark");
38}
39
40QString PlacemarkPositionProviderPlugin::guiString() const
41{
42 return tr("Placemark");
43}
44
45QString PlacemarkPositionProviderPlugin::version() const
46{
47 return QStringLiteral("1.0");
48}
49
50QString PlacemarkPositionProviderPlugin::description() const
51{
52 return tr("Reports the position of a placemark");
53}
54
55QString PlacemarkPositionProviderPlugin::copyrightYears() const
56{
57 return QStringLiteral("2011, 2012");
58}
59
60QList<PluginAuthor> PlacemarkPositionProviderPlugin::pluginAuthors() const
61{
62 return QList<PluginAuthor>() << PluginAuthor(QStringLiteral("Guillaume Martres"), QStringLiteral("smarter@ubuntu.com"))
63 << PluginAuthor(QStringLiteral("Bernhard Beschow"), QStringLiteral("bbeschow@cs.tu-berlin.de"));
64}
65
66QIcon PlacemarkPositionProviderPlugin::icon() const
67{
68 return {};
69}
70
71void PlacemarkPositionProviderPlugin::initialize()
72{
73 if (m_marbleModel) {
74 setPlacemark(m_marbleModel->trackedPlacemark());
75 connect(m_marbleModel, SIGNAL(trackedPlacemarkChanged(const GeoDataPlacemark *)), this, SLOT(setPlacemark(const GeoDataPlacemark *)));
76 } else {
77 mDebug() << "PlacemarkPositionProviderPlugin: MarbleModel not set, cannot track placemarks.";
78 }
79 m_isInitialized = true;
80}
81
82bool PlacemarkPositionProviderPlugin::isInitialized() const
83{
84 return m_isInitialized;
85}
86
87PositionProviderPlugin *PlacemarkPositionProviderPlugin::newInstance() const
88{
89 return new PlacemarkPositionProviderPlugin(m_marbleModel);
90}
91
92PositionProviderStatus PlacemarkPositionProviderPlugin::status() const
93{
94 return m_status;
95}
96
97GeoDataCoordinates PlacemarkPositionProviderPlugin::position() const
98{
99 return m_coordinates;
100}
101
102GeoDataAccuracy PlacemarkPositionProviderPlugin::accuracy() const
103{
104 return m_accuracy;
105}
106
107qreal PlacemarkPositionProviderPlugin::speed() const
108{
109 return m_speed;
110}
111
112qreal PlacemarkPositionProviderPlugin::direction() const
113{
114 return m_direction;
115}
116
117QDateTime PlacemarkPositionProviderPlugin::timestamp() const
118{
119 return m_marbleModel->clockDateTime();
120}
121
122void PlacemarkPositionProviderPlugin::setPlacemark(const GeoDataPlacemark *placemark)
123{
124 const GeoDataPlacemark *const oldPlacemark = m_placemark;
125
126 if (oldPlacemark != nullptr) {
127 Q_EMIT statusChanged(PositionProviderStatusUnavailable);
128 }
129
130 m_placemark = placemark;
131 m_timestamp = placemark ? m_marbleModel->clockDateTime() : QDateTime();
132 GeoDataCoordinates const newCoordinates = placemark ? placemark->coordinate(m_timestamp) : GeoDataCoordinates();
133 if (m_coordinates.isValid() && newCoordinates.isValid()) {
134 m_direction = m_coordinates.bearing(newCoordinates, GeoDataCoordinates::Degree, GeoDataCoordinates::FinalBearing);
135 }
136 m_coordinates = newCoordinates;
137 m_status = placemark ? PositionProviderStatusAvailable : PositionProviderStatusUnavailable;
138 m_speed = 0.0;
139
140 disconnect(m_marbleModel->clock(), SIGNAL(timeChanged()), this, SLOT(updatePosition()));
141 if (placemark) {
142 connect(m_marbleModel->clock(), SIGNAL(timeChanged()), this, SLOT(updatePosition()));
143 }
144
145 if (oldPlacemark != m_placemark && m_placemark != nullptr) {
146 Q_EMIT statusChanged(m_status);
147 }
148
149 if (m_status == PositionProviderStatusAvailable) {
150 Q_EMIT positionChanged(m_coordinates, m_accuracy);
151 }
152}
153
154void PlacemarkPositionProviderPlugin::updatePosition()
155{
156 if (m_placemark == nullptr) {
157 return;
158 }
159
160 Q_ASSERT(m_marbleModel && "MarbleModel missing in PlacemarkPositionProviderPlugin");
161
162 const GeoDataCoordinates previousCoordinates = m_coordinates;
163 m_coordinates = m_placemark->coordinate(m_marbleModel->clock()->dateTime());
164 m_direction = previousCoordinates.bearing(m_coordinates, GeoDataCoordinates::Degree, GeoDataCoordinates::FinalBearing);
165
166 if (m_timestamp.isValid()) {
167 const qreal averageAltitude = (m_coordinates.altitude() + m_coordinates.altitude()) / 2.0 + m_marbleModel->planetRadius();
168 const qreal distance = previousCoordinates.sphericalDistanceTo(m_coordinates) * averageAltitude;
169 const qreal seconds = m_timestamp.msecsTo(m_marbleModel->clockDateTime()) / 1000.0;
170 m_speed = (seconds > 0) ? (distance / seconds) : 0;
171 } else {
172 m_speed = 0;
173 }
174
175 m_timestamp = m_marbleModel->clockDateTime();
176
177 Q_EMIT positionChanged(m_coordinates, m_accuracy);
178}
179
180#include "moc_PlacemarkPositionProviderPlugin.cpp"
This file contains the headers for MarbleModel.
A 3d point representation.
qreal bearing(const GeoDataCoordinates &other, Unit unit=Radian, BearingType type=InitialBearing) const
Returns the bearing (true bearing, the angle between the line defined by this point and the other and...
qreal sphericalDistanceTo(const GeoDataCoordinates &other) const
This method calculates the shortest distance between two points on a sphere.
a class representing a point of interest on the map
GeoDataCoordinates coordinate(const QDateTime &dateTime=QDateTime(), bool *iconAtCoordinates=nullptr) const
Return the coordinates of the placemark at time dateTime as a GeoDataCoordinates.
The data model (not based on QAbstractModel) for a MarbleWidget.
Definition MarbleModel.h:84
The abstract class that provides position information.
Binds a QML item to a specific geodetic location in screen coordinates.
KOSM_EXPORT double distance(const std::vector< const OSM::Node * > &path, Coordinate coord)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QString tr(const char *sourceText, const char *disambiguation, int n)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:52:10 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.