7#include <QtNetwork/QNetworkAccessManager>
13 const QStringList fields = line.split(
';');
14 if (fields.size() < 18 || fields.at(0).trimmed().toUpper() != QStringLiteral(
"STR")) {
19 model->_mountpoint = fields.at(1).trimmed();
20 model->_identifier = fields.at(2).trimmed();
21 model->_format = fields.at(3).trimmed();
22 model->_formatDetails = fields.at(4).trimmed();
23 model->_carrier = fields.at(5).trimmed().toInt();
24 model->_navSystem = fields.at(6).trimmed();
25 model->_network = fields.at(7).trimmed();
26 model->_country = fields.at(8).trimmed();
27 model->_latitude = fields.at(9).trimmed().toDouble();
28 model->_longitude = fields.at(10).trimmed().toDouble();
29 model->_nmea = fields.at(11).trimmed() == QStringLiteral(
"1");
30 model->_solution = fields.at(12).trimmed() == QStringLiteral(
"1");
31 model->_generator = fields.at(13).trimmed();
32 model->_compression = fields.at(14).trimmed();
33 model->_authentication = fields.at(15).trimmed();
34 model->_fee = fields.at(16).trimmed() == QStringLiteral(
"Y");
35 model->_bitrate = fields.at(17).trimmed().toInt();
40void NTRIPMountpointModel::updateDistance(
const QGeoCoordinate& from)
42 if (!from.isValid() || (_latitude == 0.0 && _longitude == 0.0)) {
46 const QGeoCoordinate mountCoord(_latitude, _longitude);
47 const double dist = from.distanceTo(mountCoord) / 1000.0;
48 if (qFuzzyCompare(_distanceKm, dist)) {
59NTRIPSourceTableModel::NTRIPSourceTableModel(QObject* parent)
65int NTRIPSourceTableModel::count()
const
67 return _mountpoints ? _mountpoints->
count() : 0;
70void NTRIPSourceTableModel::parseSourceTable(
const QString& raw)
74 const QStringList lines = raw.split(
'\n');
75 for (
const QString& line : lines) {
76 const QString trimmed = line.trimmed();
77 if (trimmed.isEmpty() || trimmed.startsWith(QStringLiteral(
"ENDSOURCETABLE"))) {
89void NTRIPSourceTableModel::updateDistances(
const QGeoCoordinate& from)
94 for (
int i = 0; i < _mountpoints->
count(); ++i) {
95 auto* mp = qobject_cast<NTRIPMountpointModel*>(_mountpoints->
get(i));
97 mp->updateDistance(from);
103void NTRIPSourceTableModel::sortByDistance()
105 if (!_mountpoints || _mountpoints->
count() < 2) {
109 QObjectList sorted = *_mountpoints->
objectList();
110 std::sort(sorted.begin(), sorted.end(), [](QObject* a, QObject* b) {
111 auto* ma = qobject_cast<NTRIPMountpointModel*>(a);
112 auto* mb = qobject_cast<NTRIPMountpointModel*>(b);
113 if (!ma || !mb) return false;
114 const double da = ma->distanceKm();
115 const double db = mb->distanceKm();
116 if (da < 0 && db < 0) return false;
117 if (da < 0) return false;
118 if (db < 0) return true;
124void NTRIPSourceTableModel::clear()
137 const QString& username,
const QString& password,
143 , _username(username)
144 , _password(password)
153 url.setScheme(_useTls ? QStringLiteral(
"https") : QStringLiteral(
"http"));
156 url.setPath(QStringLiteral(
"/"));
160 config.
userAgent = QStringLiteral(
"QGC-NTRIP");
165 request.setRawHeader(
"Ntrip-Version",
"Ntrip/2.0");
166 if (!_username.isEmpty() || !_password.isEmpty()) {
170 _reply = _networkManager->get(request);
171 connect(_reply, &QNetworkReply::finished,
this, &NTRIPSourceTableFetcher::_onReplyFinished);
174void NTRIPSourceTableFetcher::_onReplyFinished()
177 emit
error(tr(
"No reply received"));
182 const QString body = QString::fromUtf8(_reply->readAll());
184 if (_reply->error() != QNetworkReply::NoError && !body.contains(QStringLiteral(
"ENDSOURCETABLE"))) {
186 _reply->deleteLater();
191 _reply->deleteLater();
194 if (!body.contains(QStringLiteral(
"ENDSOURCETABLE"))) {
195 emit
error(tr(
"Response does not contain a valid source table"));
#define QGC_LOGGING_CATEGORY(name, categoryStr)
static constexpr int kFetchTimeoutMs
void sourceTableReceived(const QString &table)
NTRIPSourceTableFetcher(const QString &host, int port, const QString &username, const QString &password, bool useTls=false, QObject *parent=nullptr)
void append(QObject *object)
Caller maintains responsibility for object ownership and deletion.
int count() const override final
void clearAndDeleteContents() override final
Clears the list and calls deleteLater on each entry.
QObjectList swapObjectList(const QObjectList &newlist)
QList< QObject * > * objectList()
QNetworkAccessManager * createNetworkManager(QObject *parent)
QNetworkRequest createRequest(const QUrl &url, const RequestConfig &config)
void setBasicAuth(QNetworkRequest &request, const QString &credentials)
QString errorMessage(const QNetworkReply *reply)
Common request configuration options.