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

Last change on this file since 682 was 682, checked in by weber, 16 years ago

* empty log message *

File size: 14.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
44// Constructor
45////////////////////////////////////////////////////////////////////////////
46bncTableDlg::bncTableDlg(QWidget* parent) : QDialog(parent) {
47
48 setMinimumSize(600,400);
49 setWindowTitle(tr("Add Mountpoints"));
50
51 QVBoxLayout* mainLayout = new QVBoxLayout(this);
52
53 QSettings settings;
54 _casterHostLineEdit = new QLineEdit(settings.value("casterHost").toString());
55 int ww = QFontMetrics(_casterHostLineEdit->font()).width('w');
56 _casterHostLineEdit->setMaximumWidth(18*ww);
57 _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>."));
58 _casterPortLineEdit = new QLineEdit(settings.value("casterPort").toString());
59 _casterPortLineEdit->setMaximumWidth(9*ww);
60 _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>."));
61 _casterUserLineEdit = new QLineEdit(settings.value("casterUser").toString());
62 _casterUserLineEdit->setMaximumWidth(9*ww);
63 _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>."));
64 _casterPasswordLineEdit = new QLineEdit(settings.value("casterPassword").toString());
65 _casterPasswordLineEdit->setMaximumWidth(9*ww);
66 _casterPasswordLineEdit->setEchoMode(QLineEdit::Password);
67 _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>."));
68
69 QGridLayout* editLayout = new QGridLayout;
70 editLayout->addWidget(new QLabel(tr("Caster host")), 0, 0);
71 editLayout->addWidget(_casterHostLineEdit, 0, 1);
72 editLayout->addWidget(new QLabel(tr("Caster port")), 0, 2);
73 editLayout->addWidget(_casterPortLineEdit, 0, 3);
74 editLayout->addWidget(new QLabel(tr("User")), 1, 0);
75 editLayout->addWidget(_casterUserLineEdit, 1, 1);
76 editLayout->addWidget(new QLabel(tr("Password")), 1, 2);
77 editLayout->addWidget(_casterPasswordLineEdit, 1, 3);
78
79 mainLayout->addLayout(editLayout);
80
81 _table = new QTableWidget(this);
82 _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 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>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>"));
83 connect(_table, SIGNAL(itemSelectionChanged()),
84 this, SLOT(slotSelectionChanged()));
85 mainLayout->addWidget(_table);
86
87 _buttonWhatsThis = new QPushButton(tr("Help=Shift+F1"), this);
88 connect(_buttonWhatsThis, SIGNAL(clicked()), this, SLOT(slotWhatsThis()));
89
90 _buttonGet = new QPushButton(tr("Get table"), this);
91 _buttonGet->setDefault(true);
92 connect(_buttonGet, SIGNAL(clicked()), this, SLOT(slotGetTable()));
93
94 _buttonCancel = new QPushButton(tr("Cancel"), this);
95 connect(_buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
96
97 _buttonOK = new QPushButton(tr("OK"), this);
98 connect(_buttonOK, SIGNAL(clicked()), this, SLOT(accept()));
99
100 QHBoxLayout* buttonLayout = new QHBoxLayout;
101 buttonLayout->addWidget(_buttonWhatsThis);
102 buttonLayout->addStretch(1);
103 buttonLayout->addWidget(_buttonGet);
104 buttonLayout->addWidget(_buttonCancel);
105 buttonLayout->addWidget(_buttonOK);
106
107 mainLayout->addLayout(buttonLayout);
108}
109
110// Destructor
111////////////////////////////////////////////////////////////////////////////
112bncTableDlg::~bncTableDlg() {
113 if (_table) {
114 for (int ir = 0; ir < _table->rowCount(); ir++) {
115 for (int ic = 0; ic < _table->columnCount(); ic++) {
116 delete _table->item(ir,ic);
117 }
118 }
119 }
120}
121
122// Read Table the caster (static)
123////////////////////////////////////////////////////////////////////////////
124t_irc bncTableDlg::getFullTable(const QString& casterHost,
125 int casterPort, QStringList& allLines,
126 bool alwaysRead) {
127
128 static QMutex mutex;
129 static QMap<QString, QStringList> allTables;
130
131 QMutexLocker locker(&mutex);
132
133 if (!alwaysRead && allTables.find(casterHost) != allTables.end()) {
134 allLines = allTables.find(casterHost).value();
135 return success;
136 }
137
138 allLines.clear();
139
140 QUrl url;
141 url.setHost(casterHost);
142 url.setPort(casterPort);
143
144 // Send the Request
145 // ----------------
146 const int timeOut = 10*1000;
147 QString msg;
148 QByteArray _latitude;
149 QByteArray _longitude;
150 QByteArray _nmea;
151 QTcpSocket* socket = bncGetThread::request(url, _latitude, _longitude, _nmea, timeOut, msg);
152
153 if (!socket) {
154 return failure;
155 }
156
157 // Read Caster Response
158 // --------------------
159 bool proxyRespond = false;
160 bool first = true;
161 while (true) {
162 if (socket->canReadLine()) {
163 QString line = socket->readLine();
164
165 // Skip messages from proxy server
166 // -------------------------------
167 if (line.indexOf("SOURCETABLE 200 OK") == -1 &&
168 line.indexOf("200 OK") != -1 ) {
169 proxyRespond = true;
170 }
171 if (proxyRespond) {
172 if (line.trimmed().isEmpty()) {
173 proxyRespond = false;
174 }
175 continue;
176 }
177
178 allLines.push_back(line);
179 if (first) {
180 first = false;
181 if (line.indexOf("SOURCETABLE 200 OK") != 0) {
182 break;
183 }
184 }
185 else {
186 if (line.indexOf("ENDSOURCETABLE") == 0) {
187 break;
188 }
189 }
190 }
191 else {
192 socket->waitForReadyRead(timeOut);
193 if (socket->bytesAvailable() > 0) {
194 continue;
195 }
196 else {
197 break;
198 }
199 }
200 }
201 delete socket;
202
203 allTables.insert(casterHost, allLines);
204 return success;
205}
206
207// Read Table from Caster
208////////////////////////////////////////////////////////////////////////////
209void bncTableDlg::slotGetTable() {
210
211 _buttonGet->setEnabled(false);
212
213 _allLines.clear();
214
215 if ( getFullTable(_casterHostLineEdit->text(),
216 _casterPortLineEdit->text().toInt(),
217 _allLines) != success ) {
218 QMessageBox::warning(0, "BNC", "Cannot retrieve table of data");
219 _buttonGet->setEnabled(true);
220 return;
221 }
222
223 QStringList lines;
224 QStringListIterator it(_allLines);
225 while (it.hasNext()) {
226 QString line = it.next();
227 if (line.indexOf("STR") == 0) {
228 lines.push_back(line);
229 }
230 }
231
232 static const QStringList labels = QString("mountpoint,identifier,format,"
233 "format-details,carrier,system,network,country,latitude,longitude,"
234 "nmea,solution,generator,compress.,authentic.,fee,bitrate,"
235 "misc").split(",");
236
237 if (lines.size() > 0) {
238 _table->setSelectionMode(QAbstractItemView::ExtendedSelection);
239 _table->setSelectionBehavior(QAbstractItemView::SelectRows);
240
241 QStringList hlp = lines[0].split(";");
242 _table->setColumnCount(hlp.size()-1);
243 _table->setRowCount(lines.size());
244
245 QListIterator<QString> it(lines);
246 int nRow = -1;
247 while (it.hasNext()) {
248 QStringList columns = it.next().split(";");
249 ++nRow;
250 for (int ic = 0; ic < columns.size()-1; ic++) {
251
252 if (ic+1 == 11) { if (columns[ic+1] == "0") { columns[ic+1] = "no"; } else { columns[ic+1] = "yes"; }}
253
254 QTableWidgetItem* it = new QTableWidgetItem(columns[ic+1]);
255 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
256 _table->setItem(nRow, ic, it);
257 }
258 }
259 _table->sortItems(0);
260 _table->setHorizontalHeaderLabels(labels);
261 _table->setSortingEnabled(true);
262
263 int ww = QFontMetrics(this->font()).width('w');
264 _table->horizontalHeader()->resizeSection(0,10*ww);
265 _table->horizontalHeader()->resizeSection(2,8*ww);
266 _table->horizontalHeader()->resizeSection(3,15*ww);
267 _table->horizontalHeader()->resizeSection(4,8*ww);
268 _table->horizontalHeader()->resizeSection(5,8*ww);
269 _table->horizontalHeader()->resizeSection(6,8*ww);
270 _table->horizontalHeader()->resizeSection(7,8*ww);
271 _table->horizontalHeader()->resizeSection(8,8*ww);
272 _table->horizontalHeader()->resizeSection(9,8*ww);
273 _table->horizontalHeader()->resizeSection(10,8*ww);
274 _table->horizontalHeader()->resizeSection(11,8*ww);
275 _table->horizontalHeader()->resizeSection(12,15*ww);
276 _table->horizontalHeader()->resizeSection(13,8*ww);
277 _table->horizontalHeader()->resizeSection(14,8*ww);
278 _table->horizontalHeader()->resizeSection(15,8*ww);
279 _table->horizontalHeader()->resizeSection(16,8*ww);
280 _table->horizontalHeader()->resizeSection(17,15*ww);
281 }
282}
283
284// Accept slot
285////////////////////////////////////////////////////////////////////////////
286void bncTableDlg::accept() {
287
288 QSettings settings;
289 settings.setValue("casterHost", _casterHostLineEdit->text());
290 settings.setValue("casterPort", _casterPortLineEdit->text());
291 settings.setValue("casterUser", _casterUserLineEdit->text());
292 settings.setValue("casterPassword", _casterPasswordLineEdit->text());
293
294 QStringList* mountPoints = new QStringList;
295
296 if (_table) {
297 for (int ir = 0; ir < _table->rowCount(); ir++) {
298 QTableWidgetItem* item = _table->item(ir,0);
299 QString format = _table->item(ir,2)->text();
300 QString latitude = _table->item(ir,8)->text();
301 QString longitude = _table->item(ir,9)->text();
302 QString nmea = _table->item(ir,10)->text();
303 format.replace(" ", "_");
304 if (_table->isItemSelected(item)) {
305 QUrl url;
306 url.setUserName(QUrl::toPercentEncoding(_casterUserLineEdit->text()));
307 url.setPassword(QUrl::toPercentEncoding(_casterPasswordLineEdit->text()));
308 url.setHost(_casterHostLineEdit->text());
309 url.setPort(_casterPortLineEdit->text().toInt());
310 url.setPath(item->text());
311
312 mountPoints->push_back(url.toString() + " " + format + " " + latitude + " " + longitude + " " + nmea);
313 }
314 }
315 }
316 emit newMountPoints(mountPoints);
317
318 QDialog::accept();
319}
320
321// User changed the selection of mountPoints
322////////////////////////////////////////////////////////////////////////////
323void bncTableDlg::slotSelectionChanged() {
324 if (_table->selectedItems().isEmpty()) {
325 }
326}
327
328// Create RINEX skeleton header
329////////////////////////////////////////////////////////////////////////////
330void bncTableDlg::slotSkl() {
331
332 int nRows = _table->rowCount();
333 for (int iRow = 0; iRow < nRows; iRow++) {
334 if (_table->isItemSelected(_table->item(iRow,1))) {
335 QString staID = _table->item(iRow,0)->text();
336 QString net = _table->item(iRow,6)->text();
337
338 QString ftpDir;
339 QStringListIterator it(_allLines);
340 while (it.hasNext()) {
341 QString line = it.next();
342 if (line.indexOf("NET") == 0) {
343 QStringList tags = line.split(';');
344 if (tags.at(1) == net) {
345 ftpDir = tags.at(6);
346 break;
347 }
348 }
349 }
350
351 if (!ftpDir.isEmpty()) {
352 QUrl url(ftpDir);
353 QMessageBox::warning(0, "Warning", url.host() + "\n" + url.path() +
354 "\nnot yet implemented");
355 }
356 }
357 }
358}
359
360// Whats This Help
361void bncTableDlg::slotWhatsThis() {
362QWhatsThis::enterWhatsThisMode();
363}
364
365
Note: See TracBrowser for help on using the repository browser.