Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qgeopositioninfosource_wasm.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6
7#include <QtCore/QDebug>
8#include <QtCore/QPermission>
9#include <QtCore/QCoreApplication>
10
11#include <emscripten/val.h>
12#include <emscripten/bind.h>
13
14
15// QGeoPositionInfoSource implemented using the Web Geolocation API
16
18
20
23{
24 // QGeoPositionInfoSourceWasm should not be constructed if
25 // geolocation support is missing.
26 Q_ASSERT(!geolocation().isUndefined());
27
29 m_instanceId = m_dispatcher->registerInfoSourceInstance(this);
30
31 successCallback = val::module_property("qtGeolocationPositionSuccess").call<val>("bind", val::undefined(), m_instanceId);
32 errorCallback = val::module_property("qtGeolocationPositionError").call<val>("bind", val::undefined(), m_instanceId);
33
34}
35
37{
38 return val::global("navigator")["geolocation"];
39}
40
42{
44 m_dispatcher->unregisterInfoSourceInstance(m_instanceId);
45}
46
48{
49 // If msec is 0 we send updates as data becomes available, otherwise we force msec to be equal
50 // to or larger than the minimum update interval.
51 if (msec != 0 && msec < minimumUpdateInterval())
53
54 QGeoPositionInfoSource::setUpdateInterval(msec);
55}
56
57void QGeoPositionInfoSourceWasm::startUpdates()
58{
59 if (m_updates_running) {
60 qDebug() << "startUpdates() is called, but an update is already running.";
61 return;
62 }
63
64 if (preferredPositioningMethods() == 0) {
65 m_lastError = QGeoPositionInfoSource::UnknownSourceError;
66 return;
67 }
68
69 m_updates_running = true;
70 m_lastError = QGeoPositionInfoSource::NoError;
71
72 val options = val::object();
73 options.set("maximumAge", 0);
74
75 if (preferredPositioningMethods() & PositioningMethod::SatellitePositioningMethods)
76 options.set("enableHighAccuracy", true);
77
78 m_handlerId = geolocation().call<val>("watchPosition", successCallback, errorCallback, options);
79}
80
82{
83 geolocation().call<void>("clearWatch", m_handlerId);
84 m_updates_running = false;
85}
86
88{
89 if (timeout < minimumUpdateInterval()) {
90 emit errorOccurred(UpdateTimeoutError);
91 return;
92 }
93
94 if (m_singleUpdatePending) {
95 qDebug() << "requestUpdate() called while a previous update is still pending. Ignoring.";
96 return;
97 }
98
99 m_singleUpdatePending = true;
100 m_lastError = QGeoPositionInfoSource::NoError;
101
102 val options = val::object();
103 options.set("maximumAge", 0); // maximum cache age: 0: don't use cache
104 options.set("timeout", timeout);
105
106 if (preferredPositioningMethods() & PositioningMethod::SatellitePositioningMethods)
107 options.set("enableHighAccuracy", true);
108
109 geolocation().call<void>("getCurrentPosition", successCallback, errorCallback, options);
110}
111
113{
114 return QGeoPositionInfoSource::AllPositioningMethods;
115}
116
118{
119 PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods();
120 QGeoPositionInfoSource::setPreferredPositioningMethods(methods);
121 if (previousPreferredPositioningMethods == preferredPositioningMethods())
122 return;
123
124 if (m_updates_running)
125 reconfigureRunningSystem();
126}
127
128
130{
131 return 1000;
132}
133
134QGeoPositionInfo QGeoPositionInfoSourceWasm::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
135{
136 Q_UNUSED(fromSatellitePositioningMethodsOnly);
137 return m_lastKnownPosition;
138}
139
141{
142 qDebug() << "QGeoPositionInfoSourceWasm::error";
143 return m_lastError;
144}
145
147{
148 // Populate a QGeoPositionInfo from the native GeolocationPosition. Some
149 // attributes are optional and may be null.
150 QGeoPositionInfo info;
151 info.setTimestamp(QDateTime::fromMSecsSinceEpoch(position["timestamp"].as<double>()));
152
153 GeolocationCoordinates coords = position["coords"];
154 val latitude = coords["latitude"];
155 val longitude = coords["longitude"];
156 val altitude = coords["altitude"];
157 info.setCoordinate(altitude.isNull() ?
158 QGeoCoordinate(latitude.as<double>(), longitude.as<double>()) :
159 QGeoCoordinate(latitude.as<double>(), longitude.as<double>(), altitude.as<double>())
160 );
161
162 if (val speed = coords["speed"]; !speed.isNull())
163 info.setAttribute(QGeoPositionInfo::GroundSpeed, speed.as<double>());
164 if (val heading = coords["heading"]; !heading.isNull())
165 info.setAttribute(QGeoPositionInfo::Direction, heading.as<double>());
166
167 info.setAttribute(QGeoPositionInfo::HorizontalAccuracy, coords["accuracy"].as<double>());
168 if (val altitudeAccuracy = coords["altitudeAccuracy"]; !altitudeAccuracy.isNull())
169 info.setAttribute(QGeoPositionInfo::VerticalAccuracy, altitudeAccuracy.as<double>());
170
171 m_lastKnownPosition = info;
172 m_singleUpdatePending = false;
173
174 emit positionUpdated(info);
175}
176
178{
179 qDebug() << "geolocationError";
180 qDebug() << "Handler ID:" << m_handlerId.as<int>();
181
182 int code = error["code"].as<int>();
183 QString message = error["message"].as<QString>();
184
185 QGeoPositionInfoSource::Error qtError = QGeoPositionInfoSource::UnknownSourceError;
186
187 switch (code) {
188 case 1:
189 qtError = QGeoPositionInfoSource::AccessError; // -> PERMISSION_DENIED
190 break;
191 case 2:
192 qtError = QGeoPositionInfoSource::UnknownSourceError; // -> POSITION_UNAVAILABLE
193 break;
194 case 3:
195 qtError = QGeoPositionInfoSource::UpdateTimeoutError; // -> TIMEOUT
196 break;
197 }
198
199 qDebug() << "Message: " << message;
200
201 m_lastError = qtError;
202 m_singleUpdatePending = false;
203
204 emit errorOccurred(qtError);
205}
206
207void QGeoPositionInfoSourceWasm::reconfigureRunningSystem()
208{
209 if (!m_updates_running)
210 return;
211
213 startUpdates();
214}
215
216
217QT_END_NAMESPACE
218
219#include "moc_qgeopositioninfosource_wasm_p.cpp"
static QGeoPositionInfoDispatcherWasm * instance()
void geolocationError(GeolocationPositionError error)
Error error() const override
Returns the type of error that last occurred.
void setPreferredPositioningMethods(PositioningMethods methods) override
void requestUpdate(int timeout=0) override
PositioningMethods supportedPositioningMethods() const override
Returns the positioning methods available to this source.
void geolocationSuccess(GeolocationPosition position)
QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly=false) const override
Returns an update containing the last known position, or a null update if none is available.
Combined button and popup list for selecting options.
QT_BEGIN_NAMESPACE typedef emscripten::val GeolocationCoordinates
emscripten::val Geolocation
emscripten::val GeolocationPositionError
emscripten::val GeolocationPosition