source: ntrip/trunk/BNC/bnctabledlg.cpp@ 1306

Last change on this file since 1306 was 1306, checked in by mervart, 15 years ago

* empty log message *

File size: 15.1 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
27 * -------------------------------------------------------------------------
28 *
29 * Class: bncTableDlg
30 *
31 * Purpose: Displays the source table, allows mountpoints selection
32 *
33 * Author: L. Mervart
34 *
35 * Created: 24-Dec-2005
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include "bnctabledlg.h"
42#include "bncgetthread.h"
43/// #include "bncnetrequest.h"
44
45// Constructor
46////////////////////////////////////////////////////////////////////////////
47bncTableDlg::bncTableDlg(QWidget* parent) : QDialog(parent) {
48
49 setMinimumSize(600,400);
50 setWindowTitle(tr("Add Mountpoints"));
51
52 QVBoxLayout* mainLayout = new QVBoxLayout(this);
53
54 QSettings settings;
55 _casterHostLineEdit = new QComboBox();
56 _casterHostLineEdit->setDuplicatesEnabled(false);
57 _casterHostLineEdit->setEditable(true);
58 int ww = QFontMetrics(_casterHostLineEdit->font()).width('w');
59 _casterHostLineEdit->setMaximumWidth(20*ww);
60 QStringList casterHostList = settings.value("casterHostList").toStringList();
61 _casterHostLineEdit->addItem(settings.value("casterHost").toString());
62 for (int ii = 0; ii < casterHostList.count(); ii++) {
63 QString item = casterHostList[ii];
64 if (_casterHostLineEdit->findText(item, Qt::MatchFixedString) < 0) {
65 _casterHostLineEdit->addItem(item);
66 }
67 }
68 _casterPortLineEdit = new QLineEdit(settings.value("casterPort").toString());
69 _casterPortLineEdit->setMaximumWidth(9*ww);
70 _casterUserLineEdit = new QLineEdit(settings.value("casterUser").toString());
71 _casterUserLineEdit->setMaximumWidth(9*ww);
72 _casterPasswordLineEdit = new QLineEdit(settings.value("casterPassword").toString());
73 _casterPasswordLineEdit->setMaximumWidth(9*ww);
74 _casterPasswordLineEdit->setEchoMode(QLineEdit::Password);
75
76 // WhatsThis
77 // ---------
78 _casterUserLineEdit->setWhatsThis(tr("Access to some streams on NTRIP broadcasters may be restricted. You'll need to enter a valid 'User ID' and 'Password' for access to these protected streams. Accounts are usually provided per NTRIP broadcaster through a registration process. Register through <u>http://igs.bkg.bund.de/index_ntrip_reg.htm</u> for access to protected streams on <u>www.euref-ip.net</u> and <u>www.igs-ip.net</u>."));
79 _casterPortLineEdit->setWhatsThis(tr("Enter the NTRIP broadcaster hostname or IP number and port number. <u>http://www.rtcm-ntrip.org/home</u> provides information about known NTRIP broadcaster installations. Note that EUREF and IGS operate NTRIP broadcasters at <u>http://www.euref-ip.net/home</u> and <u>http://www.igs-ip.net/home</u>."));
80 _casterHostLineEdit->setWhatsThis(tr("Enter the NTRIP broadcaster hostname or IP number and port number. <u>http://www.rtcm-ntrip.org/home</u> provides information about known NTRIP broadcaster installations. Note that EUREF and IGS operate NTRIP broadcasters at <u>http://www.euref-ip.net/home</u> and <u>http://www.igs-ip.net/home</u>."));
81 _casterPasswordLineEdit->setWhatsThis(tr("Access to some streams on NTRIP broadcasters may be restricted. You'll need to enter a valid 'User ID' and 'Password' for access to these protected streams. Accounts are usually provided per NTRIP broadcaster through a registration procedure. Register through <u>http://igs.bkg.bund.de/index_ntrip_reg.htm</u> for access to protected streams on <u>www.euref-ip.net</u> and <u>www.igs-ip.net</u>."));
82
83 QGridLayout* editLayout = new QGridLayout;
84 editLayout->addWidget(new QLabel(tr("Caster host")), 0, 0);
85 editLayout->addWidget(_casterHostLineEdit, 0, 1);
86 editLayout->addWidget(new QLabel(tr("Caster port")), 0, 2);
87 editLayout->addWidget(_casterPortLineEdit, 0, 3);
88 editLayout->addWidget(new QLabel(tr("User")), 1, 0);
89 editLayout->addWidget(_casterUserLineEdit, 1, 1);
90 editLayout->addWidget(new QLabel(tr("Password")), 1, 2);
91 editLayout->addWidget(_casterPasswordLineEdit, 1, 3);
92
93 mainLayout->addLayout(editLayout);
94
95 _table = new QTableWidget(this);
96 _table->setWhatsThis(tr("<p>Use the 'Get Table' button to download the sourcetable from the NTRIP broadcaster. Select the desired streams line by line, using +Shift and +Ctrl when necessary. Hit 'OK' to return to the main window.</p><p>Pay attention to data fields 'format' and 'format-details'. Keep in mind that BNC can only decode and convert streams that come in RTCM Version 2.x, RTCM Version 3.x, or RTIGS format. RTCM Version 2.x streams must contain message Type 18 and 19 or 20 and 21 while RTCM Version 3.x streams must contain GPS or SBAS message Type 1002 or 1004 and may contain GLONASS message types 1010 or 1012. See data field 'format-details' for available message types and their repetition rates in brackets.</p><p>Note that in order to produce RINEX Navigation files, RTCM Version 3.x streams containing message Type 1019 (GPS) and 1020 (GLONASS) or RTIGS streams are required.</p><p>Search for RTCM Version 3.x streams containing (premature) message Types 4056 and 4057 if you need corrections to Broadcast Ephemeris.</p><p>The content of data field 'nmea' tells you whether a stream retrieval needs to be initiated by BNC by sending an NMEA-GGA message containing the user (or virtual reference station)'s coordinate.</p>"));
97 connect(_table, SIGNAL(itemSelectionChanged()),
98 this, SLOT(slotSelectionChanged()));
99 mainLayout->addWidget(_table);
100
101 _buttonWhatsThis = new QPushButton(tr("Help=Shift+F1"), this);
102 connect(_buttonWhatsThis, SIGNAL(clicked()), this, SLOT(slotWhatsThis()));
103
104 _buttonGet = new QPushButton(tr("Get table"), this);
105 _buttonGet->setDefault(true);
106 connect(_buttonGet, SIGNAL(clicked()), this, SLOT(slotGetTable()));
107
108 _buttonCancel = new QPushButton(tr("Cancel"), this);
109 connect(_buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
110
111 _buttonOK = new QPushButton(tr("OK"), this);
112 connect(_buttonOK, SIGNAL(clicked()), this, SLOT(accept()));
113
114 QHBoxLayout* buttonLayout = new QHBoxLayout;
115 buttonLayout->addWidget(_buttonWhatsThis);
116 buttonLayout->addStretch(1);
117 buttonLayout->addWidget(_buttonGet);
118 buttonLayout->addWidget(_buttonCancel);
119 buttonLayout->addWidget(_buttonOK);
120
121 mainLayout->addLayout(buttonLayout);
122}
123
124// Destructor
125////////////////////////////////////////////////////////////////////////////
126bncTableDlg::~bncTableDlg() {
127 if (_table) {
128 for (int ir = 0; ir < _table->rowCount(); ir++) {
129 for (int ic = 0; ic < _table->columnCount(); ic++) {
130 delete _table->item(ir,ic);
131 }
132 }
133 }
134}
135
136// Read Table the caster (static)
137////////////////////////////////////////////////////////////////////////////
138t_irc bncTableDlg::getFullTable(const QString& casterHost,
139 int casterPort, QStringList& allLines,
140 bool alwaysRead) {
141
142 static QMutex mutex;
143 static QMap<QString, QStringList> allTables;
144
145 QMutexLocker locker(&mutex);
146
147 if (!alwaysRead && allTables.find(casterHost) != allTables.end()) {
148 allLines = allTables.find(casterHost).value();
149 return success;
150 }
151
152 allLines.clear();
153
154 QUrl url;
155 url.setHost(casterHost);
156 url.setPort(casterPort);
157
158// //// beg test
159// bncNetRequest* req = new bncNetRequest;
160// req->request(url, "");
161// return success;
162// //// end test
163
164 // Send the Request
165 // ----------------
166 const int timeOut = 10*1000;
167 QString msg;
168 QByteArray _latitude;
169 QByteArray _longitude;
170 QByteArray _nmea;
171 QTcpSocket* socket = bncGetThread::request(url, _latitude, _longitude, _nmea, timeOut, msg);
172
173 if (!socket) {
174 return failure;
175 }
176
177 // Read Caster Response
178 // --------------------
179 bool proxyRespond = false;
180 bool first = true;
181 while (true) {
182 if (socket->canReadLine()) {
183 QString line = socket->readLine();
184
185 // Skip messages from proxy server
186 // -------------------------------
187 if (line.indexOf("SOURCETABLE 200 OK") == -1 &&
188 line.indexOf("200 OK") != -1 ) {
189 proxyRespond = true;
190 }
191 if (proxyRespond) {
192 if (line.trimmed().isEmpty()) {
193 proxyRespond = false;
194 }
195 continue;
196 }
197
198 allLines.push_back(line);
199 if (first) {
200 first = false;
201 if (line.indexOf("SOURCETABLE 200 OK") != 0) {
202 break;
203 }
204 }
205 else {
206 if (line.indexOf("ENDSOURCETABLE") == 0) {
207 break;
208 }
209 }
210 }
211 else {
212 socket->waitForReadyRead(timeOut);
213 if (socket->bytesAvailable() > 0) {
214 continue;
215 }
216 else {
217 break;
218 }
219 }
220 }
221 delete socket;
222
223 allTables.insert(casterHost, allLines);
224 return success;
225}
226
227// Read Table from Caster
228////////////////////////////////////////////////////////////////////////////
229void bncTableDlg::slotGetTable() {
230
231 _buttonGet->setEnabled(false);
232
233 _allLines.clear();
234
235 if ( getFullTable(_casterHostLineEdit->currentText(),
236 _casterPortLineEdit->text().toInt(),
237 _allLines) != success ) {
238 QMessageBox::warning(0, "BNC", "Cannot retrieve table of data");
239 _buttonGet->setEnabled(true);
240 return;
241 }
242
243 QStringList lines;
244 QStringListIterator it(_allLines);
245 while (it.hasNext()) {
246 QString line = it.next();
247 if (line.indexOf("STR") == 0) {
248 lines.push_back(line);
249 }
250 }
251
252 static const QStringList labels = QString("mountpoint,identifier,format,"
253 "format-details,carrier,system,network,country,latitude,longitude,"
254 "nmea,solution,generator,compress.,authentic.,fee,bitrate,"
255 "misc").split(",");
256
257 if (lines.size() > 0) {
258 _table->setSelectionMode(QAbstractItemView::ExtendedSelection);
259 _table->setSelectionBehavior(QAbstractItemView::SelectRows);
260
261 QStringList hlp = lines[0].split(";");
262 _table->setColumnCount(hlp.size()-1);
263 _table->setRowCount(lines.size());
264
265 QListIterator<QString> it(lines);
266 int nRow = -1;
267 while (it.hasNext()) {
268 QStringList columns = it.next().split(";");
269 ++nRow;
270 for (int ic = 0; ic < columns.size()-1; ic++) {
271
272 if (ic+1 == 11) { if (columns[ic+1] == "0") { columns[ic+1] = "no"; } else { columns[ic+1] = "yes"; }}
273
274 QTableWidgetItem* it = new QTableWidgetItem(columns[ic+1]);
275 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
276 _table->setItem(nRow, ic, it);
277 }
278 }
279 _table->sortItems(0);
280 _table->setHorizontalHeaderLabels(labels);
281 _table->setSortingEnabled(true);
282
283 int ww = QFontMetrics(this->font()).width('w');
284 _table->horizontalHeader()->resizeSection(0,10*ww);
285 _table->horizontalHeader()->resizeSection(2,8*ww);
286 _table->horizontalHeader()->resizeSection(3,15*ww);
287 _table->horizontalHeader()->resizeSection(4,8*ww);
288 _table->horizontalHeader()->resizeSection(5,8*ww);
289 _table->horizontalHeader()->resizeSection(6,8*ww);
290 _table->horizontalHeader()->resizeSection(7,8*ww);
291 _table->horizontalHeader()->resizeSection(8,8*ww);
292 _table->horizontalHeader()->resizeSection(9,8*ww);
293 _table->horizontalHeader()->resizeSection(10,8*ww);
294 _table->horizontalHeader()->resizeSection(11,8*ww);
295 _table->horizontalHeader()->resizeSection(12,15*ww);
296 _table->horizontalHeader()->resizeSection(13,8*ww);
297 _table->horizontalHeader()->resizeSection(14,8*ww);
298 _table->horizontalHeader()->resizeSection(15,8*ww);
299 _table->horizontalHeader()->resizeSection(16,8*ww);
300 _table->horizontalHeader()->resizeSection(17,15*ww);
301 }
302}
303
304// Accept slot
305////////////////////////////////////////////////////////////////////////////
306void bncTableDlg::accept() {
307
308 QSettings settings;
309 settings.setValue("casterHost", _casterHostLineEdit->currentText());
310 QStringList casterHostList;
311 for (int ii = 0; ii < _casterHostLineEdit->count(); ii++) {
312 casterHostList.push_back(_casterHostLineEdit->itemText(ii));
313 }
314 settings.setValue("casterHostList", casterHostList);
315 settings.setValue("casterPort", _casterPortLineEdit->text());
316 settings.setValue("casterUser", _casterUserLineEdit->text());
317 settings.setValue("casterPassword", _casterPasswordLineEdit->text());
318
319 QStringList* mountPoints = new QStringList;
320
321 if (_table) {
322 for (int ir = 0; ir < _table->rowCount(); ir++) {
323 QTableWidgetItem* item = _table->item(ir,0);
324 QString format = _table->item(ir,2)->text();
325 QString latitude = _table->item(ir,8)->text();
326 QString longitude = _table->item(ir,9)->text();
327 QString nmea = _table->item(ir,10)->text();
328 format.replace(" ", "_");
329 if (_table->isItemSelected(item)) {
330 QUrl url;
331 url.setUserName(QUrl::toPercentEncoding(_casterUserLineEdit->text()));
332 url.setPassword(QUrl::toPercentEncoding(_casterPasswordLineEdit->text()));
333 url.setHost(_casterHostLineEdit->currentText());
334 url.setPort(_casterPortLineEdit->text().toInt());
335 url.setPath(item->text());
336
337 mountPoints->push_back(url.toString() + " " + format + " " + latitude + " " + longitude + " " + nmea);
338 }
339 }
340 }
341 emit newMountPoints(mountPoints);
342
343 QDialog::accept();
344}
345
346// User changed the selection of mountPoints
347////////////////////////////////////////////////////////////////////////////
348void bncTableDlg::slotSelectionChanged() {
349 if (_table->selectedItems().isEmpty()) {
350 }
351}
352
353// Create RINEX skeleton header
354////////////////////////////////////////////////////////////////////////////
355void bncTableDlg::slotSkl() {
356
357 int nRows = _table->rowCount();
358 for (int iRow = 0; iRow < nRows; iRow++) {
359 if (_table->isItemSelected(_table->item(iRow,1))) {
360 QString staID = _table->item(iRow,0)->text();
361 QString net = _table->item(iRow,6)->text();
362
363 QString ftpDir;
364 QStringListIterator it(_allLines);
365 while (it.hasNext()) {
366 QString line = it.next();
367 if (line.indexOf("NET") == 0) {
368 QStringList tags = line.split(';');
369 if (tags.at(1) == net) {
370 ftpDir = tags.at(6);
371 break;
372 }
373 }
374 }
375
376 if (!ftpDir.isEmpty()) {
377 QUrl url(ftpDir);
378 QMessageBox::warning(0, "Warning", url.host() + "\n" + url.path() +
379 "\nnot yet implemented");
380 }
381 }
382 }
383}
384
385// Whats This Help
386void bncTableDlg::slotWhatsThis() {
387QWhatsThis::enterWhatsThisMode();
388}
389
390
Note: See TracBrowser for help on using the repository browser.