Subversion Repositories public

Rev

Rev 289 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
283 andreas 1
//
2
// C++ Implementation:
3
//
4
// Description:
5
//
6
//
7
// Author: Andreas Theofilu <andreas@theosys.at>, (C) 2009
8
//
9
// Copyright: See COPYING file that comes with this distribution
10
//
11
//
12
 
13
#include <iostream>
14
 
15
#include <QPixmap>
16
#include <QBitmap>
17
#include <QDir>
18
#include <QFile>
19
#include <QImage>
20
#include <QtNetwork>
21
#include <QListWidget>
22
#include <QPainter>
23
#include <QCheckBox>
284 andreas 24
#include <QSlider>
283 andreas 25
#include <KStandardDirs>
26
#include <KConfig>
27
#include <KLocale>
28
#include <KMessageBox>
29
#include <KGlobalSettings>
30
#include <KConfigGroup>
31
#include <KIconLoader>
32
#include <KUrl>
33
#include <KUrlRequester>
34
#include <KFile>
35
 
36
#include "config.h"
37
 
38
#if defined HAVE_GDAL
39
   #include <gdal/gdal_priv.h>
40
   #include <gdal/ogr_spatialref.h>
41
   #include <gdal/ogrsf_frmts.h>
42
   #include <gdal/gdalwarper.h>
43
   #include <gdal/ogrsf_frmts.h>
44
   #include "GDALError.h"
45
#endif
46
 
47
#include "wmsselectorwidget.h"
48
#include "ui_authenticationdialog.h"
49
#include "wmscapabilitieswidget.h"
50
 
290 andreas 51
#if QT_VERSION < 0x040500
52
QStringList removeDuplicates(QStringList &sl);
53
#endif
54
 
283 andreas 55
// The capital cities from all countries of the world
56
// Source: Wikipedia, Google
57
CITIES Cities[] = {
284 andreas 58
	{ " - - - - - - -", 0.0, 0.0 },
283 andreas 59
	{ "Abidjan", 5.3363, -4.0277 },
60
	{ "Abu Dhabi", 24.4758, 54.3714 },
61
	{ "Abuja", 9.0578, 7.4892 },
62
	{ "Accora", 5.5555, -0.196 },
63
	{ "Addis Abeba", 9.0164, 38.7579 },
64
	{ "Algier", 36.7527, 3.0422 },
65
	{ "Amman", 31.9565, 35.9457 },
66
	{ "Amsterdam", 52.3737, 4.8911 },
67
	{ "Andorra la Vella", 42.5074, 1.5219 },
68
	{ "Ankara", 39.9438, 32.856 },
69
	{ "Antananarivo", -18.915, 47.5318 },
70
	{ "Apia", -13.8314, -171.7516 },
71
	{ "Aschgabat", 37.9501, 58.3802 },
72
	{ "Asmara", 15.3324, 38.9261 },
73
	{ "Astana", 51.1798, 71.4466 },
74
	{ "Asuncion", -25.3003, -57.6363 },
75
	{ "Athen", 37.9792, 23.7166 },
76
	{ "Bagdad", 33.3158, 44.3921 },
77
	{ "Baku", 40.4167, 49.8236 },
78
	{ "Bamako", 12.6529, -7.9865 },
79
	{ "Bandar Seri Begawan", 4.9431, 114.9424 },
80
	{ "Bankok", 13.7211, 100.4765 },
81
	{ "Bangui", 4.3616, 18.556 },
82
	{ "Banjul", 13.4548, -16.579 },
83
	{ "Basseterre", 17.2968, -62.7137 },
84
	{ "Beirut", 33.8886, 35.4954 },
85
	{ "Belgrad", 44.8024, 20.4651 },
86
	{ "Belmopan", 17.2617, -88.7785 },
87
	{ "Berlin", 52.5234, 13.4105 },
88
	{ "Bern", 46.9479, 7.4479 },
89
	{ "Bratislava", 48.1483, 17.1068 },
90
	{ "Bridgetown", 13.0935, -59.6106 },
284 andreas 91
	{ "Bruessel", 50.8462, 4.3545 },
283 andreas 92
	{ "Budapest", 47.4984, 19.0403 },
93
	{ "Buenos Aires", -34.6084, -58.3733 },
94
	{ "Bukarest", 44.4304, 26.1225 },
95
	{ "Den Haag", 52.0782, 4.3134 },
96
	{ "Dublin", 53.3441, -6.2677 },
97
	{ "Helsinki", 60.1698, 24.9379 },
98
	{ "Kopenhagen", 55.6762, 12.5678 },
99
	{ "Lissabon", 38.7071, -9.1357 },
100
	{ "Ljubljana", 46.0514, 14.5055 },
101
	{ "London", 51.5001, -0.1262 },
102
	{ "Luxemburg", 49.8152, 6.1286 },
103
	{ "Madrid", 40.4167, -3.7036 },
104
	{ "Mexiko City", 19.427, -99.128 },
105
	{ "Minsk", 53.8996, 27.5753 },
106
	{ "Monaco", 43.7326, 7.4189 },
107
	{ "Moskau", 55.7554, 37.6203 },
108
	{ "Oslo", 59.9136, 10.7394 },
109
	{ "Ottawa", 45.4218, -75.6964 },
110
	{ "Paris", 48.856, 2.3515 },
111
	{ "Peking", 39.9077, 116.3994 },
112
	{ "Prag", 50.088, 14.4217 },
113
	{ "Reykjavik", 64.1352, -21.8951 },
114
	{ "Riga", 56.9462, 24.1049 },
115
	{ "Rom", 41.8945, 12.4826 },
116
	{ "San Marino", 43.9322, 12.4484 },
117
	{ "Sofia", 42.6963, 23.3236 },
118
	{ "Stockholm", 59.3329, 18.0652 },
119
	{ "Tirana", 41.3309, 19.8325 },
120
	{ "Tokio", 35.688, 139.6932 },
121
	{ "Vaduz", 47.1407, 9.5218 },
122
	{ "Valletta", 35.9009, 14.5154 },
123
	{ "Vilnius", 54.6888, 25.2801 },
124
	{ "Warschau", 52.2291, 21.0123 },
125
	{ "Washington D.C.", 38.8917, -77.0239 },
126
	{ "Wien", 48.2091, 16.3727 },
127
	{ "Zagreb", 45.8149, 15.9784 },
128
	{ "", 0.0, 0.0 }
129
};
130
 
284 andreas 131
ZOOM zoom[] = {
132
	{ 0.014108, 0.003554 },
133
	{ 0.028216, 0.007108 },
134
	{ 0.056432, 0.014216 },
135
	{ 0.112864, 0.028432 },
136
	{ 0.225728, 0.056864 },
137
	{ 0.451456, 0.113728 },
138
	{ 0.902912, 0.227456 },
139
	{ 1.805824, 0.454912 },
140
	{ 3.611648, 0.909824 },
141
	{ 7.223296, 1.819648 }
142
};
143
 
283 andreas 144
wmsSelectorWidget::wmsSelectorWidget (QWidget* parent, Qt::WFlags fl)
145
		: QDialog (parent, fl), Ui::wmsSelectorWidgetBase()
146
{
147
	// Initialize some variables
148
	http = 0;
149
	httpRequestAborted = false;
150
	progressDialog = 0;
151
	id = 0;
152
	Layer = 0;
153
	firstLayer = 0;
284 andreas 154
	zLevel = 0;
283 andreas 155
	initializeParser();
156
	// Initialize the GUI elements
157
	setupUi (this);
158
	// Initialize the environment
159
	urlWMS->setMode(KFile::File | KFile::ExistingOnly);
160
	KConfig cfg (QString("sportwatcher.rc"), KConfig::SimpleConfig);
161
	KConfigGroup ic (&cfg, "WMS");
162
	urlWMS->setUrl (ic.readEntry("ServerURL", "http://onearth.jpl.nasa.gov/wms.cgi"));
163
	Data = ic.readEntry("Data", QDir::home().absolutePath() + "/.sportwatcher");
164
	MAP = ic.readEntry("MAP", QDir::home().absolutePath() + "/.sportwatcher/track.wms");
165
	file.setFileName(Data + "/capabilities.xml");	// File to save WMS capabilities
166
	edBands->setValue(ic.readEntry("Bands", 3));
284 andreas 167
	Layers = ic.readEntry("Layer", QString("modis,global_mosaic"));
283 andreas 168
	StyleCommas = true;
169
	cbStyles->setChecked(StyleCommas);
170
	// Fill the cities combo box
171
	int i = 0;
172
 
173
	while (!Cities[i].city.isEmpty())
174
	{
175
	   cbCities->addUrl(KUrl(Cities[i].city));
176
	   i++;
177
	}
178
 
179
	// Connect the http module
180
	progressDialog = new KProgressDialog(this);
181
	http = new QHttp(this);
182
	connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(WMSrequestFinished(int, bool)));
183
	connect(http, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
184
	connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)), this, SLOT(readResponseHeader(const QHttpResponseHeader &)));
185
	connect(http, SIGNAL(authenticationRequired(const QString &, quint16, QAuthenticator *)),
186
		this, SLOT(slotAuthenticationRequired(const QString &, quint16, QAuthenticator *)));
187
	connect(progressDialog, SIGNAL(cancelClicked()), this, SLOT(cancelDownload()));
188
#ifndef QT_NO_OPENSSL
189
	connect(http, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors(const QList<QSslError> &)));
190
#endif
191
	getCapabilities();
284 andreas 192
	Init = true;
283 andreas 193
}
194
 
195
wmsSelectorWidget::~wmsSelectorWidget()
196
{
197
	if (file.exists())
198
	   file.remove();
199
 
200
	destroyErrors();
201
}
202
 
203
/*$SPECIALIZATION$*/
204
void wmsSelectorWidget::slotGetCapabilities()
205
{
206
	actionLayer->availableListWidget()->clear();
207
	actionLayer->selectedListWidget()->clear();
208
	getCapabilities();
209
}
210
 
211
void wmsSelectorWidget::slotDetails()
212
{
285 andreas 213
int i;
214
 
283 andreas 215
	wmsCapabilitiesWidget *dlg = new wmsCapabilitiesWidget(this);
285 andreas 216
	dlg->setName(Service.Name);
217
	dlg->setTitle(Service.Title);
218
	dlg->setAbstract(Service.Abstract);
219
	dlg->setOnline(Service.OnlineResource);
220
 
283 andreas 221
	dlg->setPerson(Service.ContactPerson);
222
	dlg->setOrg(Service.ContactOrganisation);
223
	dlg->setPhone(Service.ContactVoiceTelephone);
224
	dlg->setFax(Service.ContactFacsimileTelephone);
225
	dlg->setMail(Service.ContactElectronicMailAddress);
285 andreas 226
 
227
	dlg->setAddress(Service.Address);
228
	dlg->setCity(Service.City);
229
	dlg->setState(Service.StateOrProvince);
230
	dlg->setPostCode(Service.PostCode);
231
	dlg->setCountry(Service.Country);
232
 
283 andreas 233
	dlg->setCapabilitiesGet(Request.GetCapabilities.Get);
234
	dlg->setCapabilitiesPost(Request.GetCapabilities.Post);
235
 
236
	if (Request.GetCapabilities.Format.size() > 0)
237
	   dlg->setFormat(Request.GetCapabilities.Format.at(0));
238
 
239
	dlg->setMapGet(Request.GetMap.Get);
240
	dlg->setMapPost(Request.GetMap.Post);
241
 
285 andreas 242
	for (i = 0; i < Request.GetMap.Format.size(); ++i)
283 andreas 243
	   dlg->addFormats(Request.GetMap.Format.at(i));
244
 
285 andreas 245
	for (i = 0; i < Request.GetFeatureInfo.Format.size(); ++i)
246
	   dlg->addFeatures(Request.GetFeatureInfo.Format.at(i));
247
 
248
	if (firstLayer)
249
	{
250
	LAYER *akt = firstLayer;
251
	QStringList sl;
252
 
253
	   while (akt)
254
	   {
255
	      for (i = 0; i < akt->SRS.size(); ++i)
256
	         sl << akt->SRS.at(i);
257
 
258
	      akt = akt->next;
259
	   }
260
 
290 andreas 261
#if QT_VERSION >= 0x040500
285 andreas 262
	   sl.removeDuplicates();
290 andreas 263
#else
264
	   removeDuplicates(sl);
265
#endif
285 andreas 266
	   for (i = 0; i < sl.size(); ++i)
267
	      dlg->addDate(sl.at(i));
268
	}
269
 
283 andreas 270
	dlg->exec();
271
	delete dlg;
272
}
273
 
274
void wmsSelectorWidget::slotAdded(QListWidgetItem *item)
275
{
276
double minx, miny, maxx, maxy;
277
 
278
	setDimension(minx, miny, maxx, maxy, item);
279
	grabPicture(minx, miny, maxx, maxy);
280
}
281
 
282
void wmsSelectorWidget::slotRemoved(QListWidgetItem *item)
283
{
284
double minx, miny, maxx, maxy;
285
 
286
	setDimension(minx, miny, maxx, maxy, item);
287
	grabPicture(minx, miny, maxx, maxy);
288
}
289
 
290
void wmsSelectorWidget::slotUp(QListWidgetItem *item)
291
{
292
double minx, miny, maxx, maxy;
293
 
294
	setDimension(minx, miny, maxx, maxy, item);
295
	grabPicture(minx, miny, maxx, maxy);
296
}
297
 
298
void wmsSelectorWidget::slotDown(QListWidgetItem *item)
299
{
300
double minx, miny, maxx, maxy;
301
 
302
	setDimension(minx, miny, maxx, maxy, item);
303
	grabPicture(minx, miny, maxx, maxy);
304
}
305
 
306
void wmsSelectorWidget::slotCities(QString city)
307
{
308
int i = 0;
309
double minx, miny, maxx, maxy;
310
 
311
	while (!Cities[i].city.isEmpty())
312
	{
313
	   if (Cities[i].city == city)
314
	   {
315
	      edLat->setValue(Cities[i].lat);
316
	      edLon->setValue(Cities[i].lon);
317
	      break;
318
	   }
319
 
320
	   i++;
321
	}
322
 
323
	if (actionLayer->selectedListWidget()->count() > 0)
324
	{
325
	   setDimension(minx, miny, maxx, maxy, 0);
326
	   grabPicture(minx, miny, maxx, maxy);
327
	}
328
}
329
 
330
void wmsSelectorWidget::slotStyles(bool mode)
331
{
332
	StyleCommas = mode;
333
}
334
 
284 andreas 335
void wmsSelectorWidget::slotSliderPressed()
336
{
337
	sliderPressed = true;
338
}
339
 
340
void wmsSelectorWidget::slotSliderReleased()
341
{
342
double minx, miny, maxx, maxy;
343
 
344
	sliderPressed = false;
345
 
346
	if (!sliderPressed && actionLayer->selectedListWidget()->count() > 0)
347
	{
348
	   setDimension(minx, miny, maxx, maxy, 0);
349
	   grabPicture(minx, miny, maxx, maxy);
350
	}
351
}
352
 
353
void wmsSelectorWidget::slotValueChanged(int val)
354
{
355
double minx, miny, maxx, maxy;
356
 
357
	zLevel = val;
358
 
359
	if (!sliderPressed && actionLayer->selectedListWidget()->count() > 0)
360
	{
361
	   setDimension(minx, miny, maxx, maxy, 0);
362
	   grabPicture(minx, miny, maxx, maxy);
363
	}
364
}
365
 
283 andreas 366
/*
367
 * This functions try to get a small example picture from the WMS server
368
 */
369
bool wmsSelectorWidget::grabPicture(double minx, double miny, double maxx, double maxy)
370
{
371
#if defined HAVE_GDAL
372
QPixmap pm;
373
GDALDataset *poDataset = 0;
374
GDALRasterBand *poBand = 0;
375
unsigned char *pafScanline = 0;
376
unsigned char *pafScanlineRed = 0;
377
unsigned char *pafScanlineGreen = 0;
378
unsigned char *pafScanlineBlue = 0;
379
unsigned char *pafScanlineAlpha = 0;
380
int nXSize, nYSize;
381
int width, height;
382
bool Fgeo = false;
383
QPainter paint;
384
 
385
	QApplication::setOverrideCursor (QCursor(Qt::WaitCursor));
386
	width = lbPreview->width();
284 andreas 387
	height = lbPreview->height() - 6;	// necessary to prevent growing of dialog window
283 andreas 388
	nXSize = nYSize = 0;
389
 
390
	if (!writeWMSTag(minx, miny, maxx, maxy, width, height))
391
	{
392
	   QApplication::restoreOverrideCursor();
393
	   KMessageBox::error(this, i18n("Error writing a tag file!"));
394
	   return false;
395
	}
396
 
397
	// set the dimensions of the pixmap
398
	pm = QPixmap(width, height);
399
	// start painting the map
400
	paint.begin(&pm);
401
	QColor background(220, 220, 220);
402
	paint.fillRect(0, 0, width, height, background);
403
 
404
	if ((poDataset = (GDALDataset *)GDALOpen (MAP.toAscii().constData(), GA_ReadOnly)) != NULL)
405
	{
406
	   int nRasterCount = poDataset->GetRasterCount();
407
	   int nXBlock, nYBlock;
408
	   GDALColorTable *pCT, *pCTb, *pCTr, *pCTg, *pCTa;
409
 
410
	   int             bGotMin, bGotMax;
411
	   int             tTypeLen, tColor, tColorEntrys;
412
	   GDALDataType    tRasterType;
413
	   double          adfMinMax[2];
414
 
415
	   pCT = pCTb = pCTr = pCTg = pCTa = 0;
416
	   tTypeLen = 0;
417
	   pafScanlineRed = pafScanlineGreen = pafScanlineBlue = pafScanlineAlpha = 0;
418
	   Fgeo = true;
419
 
420
	   for (int a = 1; a <= nRasterCount; a++)
421
	   {
422
	      if (!Fgeo)
423
	        break;
424
 
425
	      if (!(poBand = poDataset->GetRasterBand (a)))
426
	      {
427
		 paint.end();
428
		 QApplication::restoreOverrideCursor();
429
		 KMessageBox::error(this, i18n("Error getting a raster band:\n%1").arg(catGDALError()));
430
 
431
		 if (pafScanlineRed)
432
		    delete pafScanlineRed;
433
 
434
		 if (pafScanlineGreen)
435
		    delete pafScanlineGreen;
436
 
437
		 if (pafScanlineBlue)
438
		    delete pafScanlineBlue;
439
 
440
		 if (pafScanlineAlpha)
441
		    delete pafScanlineAlpha;
442
 
443
		 GDALClose (poDataset);
444
		    poDataset = 0;
445
 
446
		 return false;
447
	      }
448
 
449
	      poBand->GetBlockSize (&nXBlock, &nYBlock);
450
	      nXSize = poBand->GetXSize();
451
	      nYSize = poBand->GetYSize();
452
	      tRasterType = poBand->GetRasterDataType ();
453
	      tTypeLen = GDALGetDataTypeSize (tRasterType) / 8;	// We need Bytes not Bits!
454
	      tColor = poBand->GetColorInterpretation ();
455
 
456
	      adfMinMax[0] = poBand->GetMinimum (&bGotMin);
457
	      adfMinMax[1] = poBand->GetMaximum (&bGotMax);
458
 
459
	      if (!(bGotMin && bGotMax))
460
		 GDALComputeRasterMinMax ((GDALRasterBandH)poBand, TRUE, adfMinMax);
461
 
462
	      if ((pCT = poBand->GetColorTable()) != NULL)
463
		 tColorEntrys = poBand->GetColorTable()->GetColorEntryCount();
464
 
465
	      switch (a)
466
	      {
467
		 case 1: pafScanlineRed   = new unsigned char[tTypeLen * nXSize * nYSize]; pafScanline = pafScanlineRed; pCTr = pCT; break;
468
		 case 2: pafScanlineGreen = new unsigned char[tTypeLen * nXSize * nYSize]; pafScanline = pafScanlineGreen; pCTg = pCT; break;
469
		 case 3: pafScanlineBlue  = new unsigned char[tTypeLen * nXSize * nYSize]; pafScanline = pafScanlineBlue; pCTb = pCT; break;
470
		 case 4: pafScanlineAlpha  = new unsigned char[tTypeLen * nXSize * nYSize]; pafScanline = pafScanlineAlpha; pCTa = pCT; break;
471
	      }
472
 
473
	      if (!pafScanline)
474
	      {
475
		 paint.end();
476
		 QApplication::restoreOverrideCursor();
477
		 KMessageBox::error(this, i18n("Not enough memory for a raster operation!"));
478
 
479
		 if (pafScanlineRed)
480
		    delete pafScanlineRed;
481
 
482
		 if (pafScanlineGreen)
483
		    delete pafScanlineGreen;
484
 
485
		 if (pafScanlineBlue)
486
		    delete pafScanlineBlue;
487
 
488
		 if (pafScanlineAlpha)
489
		    delete pafScanlineAlpha;
490
 
491
		 GDALClose (poDataset);
492
		    poDataset = 0;
493
 
494
		 return false;
495
	      }
496
 
497
	      memset (pafScanline, 0, tTypeLen * nXSize * nYSize);
498
 
499
	      /*
500
	       * Get the image (from the server) and put the tiles together.
501
	       *
502
	       * The function reads only one raster band. This is,
503
	       * because the function is called for every raster band and
504
	       * every raster band is stored into a separate array.
505
	       */
506
	      if (poBand->RasterIO (GF_Read, 0, 0, nXSize, nYSize, pafScanline, nXSize, nYSize, tRasterType, 0, 0) == CE_Failure)
507
	      {
508
		 paint.end();
509
		 QApplication::restoreOverrideCursor();
510
		 KMessageBox::error(this, i18n("Error reading a raster band:\n%1").arg(catGDALError()));
511
		 QApplication::setOverrideCursor (QCursor(Qt::WaitCursor));
512
		 paint.begin(&pm);
513
		 Fgeo = false;
514
		 break;
515
	      }
516
	      else
517
		 Fgeo = true;
518
	   }
519
 
520
	   /*
521
	    * Only if Fgeo is TRUE, we've read successfully all raster
522
	    * bands. Now we have to put the bands together to get
523
	    * an image.
524
	    */
525
	   if (Fgeo)
526
	   {
527
	   unsigned char *pCombinedBytes = new unsigned char[(tTypeLen * nXSize * nYSize * nRasterCount)];
528
	   unsigned char *ptr_dest, *ptr_src;
529
	   int j, x1, y1, a;
530
 
531
	      ptr_dest = ptr_src = 0;
532
 
533
	      /*
534
	       * We need two nested loops to set the pixels in the wanted
535
	       * order.
536
	       */
537
	      for (a = 0, j = 0; a < (nXSize * nYSize * nRasterCount); a += nRasterCount, j++)
538
	      {
539
		 int k = a;
540
 
541
		 for (int m = nRasterCount - 1; m >= 0; m--, k++)
542
		 {
543
		    unsigned char *pBytes = 0;
544
 
545
		    switch (m)
546
		    {
547
		       case 3: pBytes = pafScanlineAlpha; pCT = pCTa; break;
548
		       case 2: pBytes = pafScanlineBlue; pCT = pCTb; break;
549
		       case 1: pBytes = pafScanlineGreen; pCT = pCTg; break;
550
		       default: pBytes = pafScanlineRed; pCT = pCTr;
551
		    }
552
 
553
		    ptr_dest = pCombinedBytes + k;
554
		    unsigned char b = pBytes[j];
555
 
556
		    /*
557
		     * If we have a color table, the pixels are pointers
558
		     * to the color table. We need to convert them into
559
		     * 24 bit pixels plus an optional alpha channel.
560
		     */
561
		    if (pCT != NULL)
562
		    {
563
		       GDALColorEntry ce;
564
		       unsigned int c = (unsigned int)b;
565
		       c = pCT->GetColorEntryAsRGB (c, &ce);
566
 
567
		       if  (m == 0) c = ce.c1;
568
		       if  (m == 1) c = ce.c2;
569
		       if  (m == 2) c = ce.c3;
570
		       if  (m == 3) c = ce.c4;
571
 
572
		       b = (unsigned char)c;
573
		    }
574
 
575
		    ptr_src = &b;
576
		    memcpy (ptr_dest, ptr_src, 1);
577
		 }
578
	      }
579
 
580
	      x1 = y1 = 0;
581
 
582
	      /*
583
	       * The following loop is QT specific! It sets the pixels
584
	       * of the raw image, pixel by pixel. This may be slow, but
585
	       * everything else didn't work :-(
586
	       *
587
	       * FIXME: We need a more effective routine to put the
588
	       *        raw image into QT's "painter" class.
589
	       */
590
	      for (a = 0; a < (nXSize * nYSize * nRasterCount); a += nRasterCount)
591
	      {
592
		 if (x1 < width && y1 < height)
593
		 {
594
		    if (nRasterCount == 3)
595
		       paint.setPen (QPen(QColor((int)pCombinedBytes[a+2], (int)pCombinedBytes[a+1], (int)pCombinedBytes[a]), Qt::SolidLine));
596
		    else if (nRasterCount > 3)
597
		       paint.setPen (QPen(QColor(qRgba((int)pCombinedBytes[a+3], (int)pCombinedBytes[a+2], (int)pCombinedBytes[a+1], (int)pCombinedBytes[a])), Qt::SolidLine));
598
		    else if (nRasterCount == 2)
599
		       paint.setPen (QPen(QColor((int)pCombinedBytes[a+1], (int)pCombinedBytes[a], (int)pCombinedBytes[a+1]), Qt::SolidLine));
600
		    else if (nRasterCount == 1)
601
		       paint.setPen (QPen(QColor((int)pCombinedBytes[a], (int)pCombinedBytes[a], (int)pCombinedBytes[a]), Qt::SolidLine));
602
 
603
		    paint.drawPoint(x1, y1);
604
		 }
605
 
606
		 x1++;
607
 
608
		 if (x1 >= nXSize)
609
		 {
610
		    x1 = 0;
611
		    y1++;
612
		 }
613
	      }
614
 
615
	      delete pCombinedBytes;
616
	      pCombinedBytes = 0;
617
	   }
618
 
619
	   if (pafScanlineRed)
620
	      delete pafScanlineRed;
621
 
622
	   if (pafScanlineGreen)
623
	      delete pafScanlineGreen;
624
 
625
	   if (pafScanlineBlue)
626
	      delete pafScanlineBlue;
627
 
628
	   if (pafScanlineAlpha)
629
	      delete pafScanlineAlpha;
630
 
631
	   GDALClose (poDataset);
632
	      poDataset = 0;
633
	}
634
	else
635
	{
636
	   paint.end();
637
	   lbPreview->setPixmap(pm);
638
	   QApplication::restoreOverrideCursor();
639
	   KMessageBox::error(this, i18n("Error initializing GDAL:\n%1").arg(catGDALError()));
640
	   return false;
641
	}
642
 
643
	paint.end();
644
	lbPreview->setPixmap(pm);
645
	QApplication::restoreOverrideCursor();
646
#endif
647
	return true;
648
}
649
 
650
/*
651
 * This part is a parser, able to read an XML-file produced by a WMS-server.
652
 * The file contains informations about the layers and styles the server
653
 * supports.
654
 */
655
bool wmsSelectorWidget::startDocument()
656
{
657
	initializeParser();
658
	Exception.clear();
659
	WMSVersion.clear();
660
	element = el2 = el_none;
661
	attribute = at_none;
662
	line = 0;
663
	lcount = 0;
664
	return true;
665
}
666
 
667
bool wmsSelectorWidget::startElement( const QString&, const QString&,
668
                                    const QString& qName,
669
                                    const QXmlAttributes& att)
670
{
671
int index;
672
 
673
	attribute = at_none;
674
 
675
	if (qName.toLower() == QString("wmt_ms_capabilities"))
676
	{
677
	   element = el_WMT_MS_Capabilities;
678
 
679
	   if ((index = att.index(QString("version"))) != -1)
680
	      WMSVersion = att.value(index);
681
	}
682
	else if (qName.toLower() == QString("service"))
683
	   element = el_Service;
684
	else if (qName.toLower() == QString("name"))
685
	   attribute = at_Name;
686
	else if (qName.toLower() == QString("title"))
687
	   attribute = at_Title;
688
	else if (qName.toLower() == QString("onlineresource"))
689
	{
690
	   if (element == el_Service)
691
	   {
285 andreas 692
	      if ((index = att.index(QString("href"))) != -1 || (index = att.index(QString("xlink:href"))) != -1)
283 andreas 693
		 Service.OnlineResource = att.value(index);
694
 
695
	      if ((index = att.index(QString("type"))) != -1)
696
		 Service.Type = att.value(index);
697
	   }
698
	   else if (element == el_GetCapabilities && el2 == el_Get)
699
	   {
285 andreas 700
	      if ((index = att.index(QString("href"))) != -1 || (index = att.index(QString("xlink:href"))) != -1)
283 andreas 701
		 Request.GetCapabilities.Get = att.value(index);
702
	   }
703
	   else if (element == el_GetCapabilities && el2 == el_Post)
704
	   {
285 andreas 705
	      if ((index = att.index(QString("href"))) != -1 || (index = att.index(QString("xlink:href"))) != -1)
283 andreas 706
		 Request.GetCapabilities.Post = att.value(index);
707
	   }
708
	   else if (element == el_GetMap && el2 == el_Get)
709
	   {
285 andreas 710
	      if ((index = att.index(QString("href"))) != -1 || (index = att.index(QString("xlink:href"))) != -1)
283 andreas 711
		 Request.GetMap.Get = att.value(index);
712
	   }
713
	   else if (element == el_GetMap && el2 == el_Post)
714
	   {
285 andreas 715
	      if ((index = att.index(QString("href"))) != -1 || (index = att.index(QString("xlink:href"))) != -1)
283 andreas 716
		 Request.GetMap.Post = att.value(index);
717
	   }
718
	   else if (element == el_GetFeatureInfo && el2 == el_Get)
719
	   {
285 andreas 720
	      if ((index = att.index(QString("href"))) != -1 || (index = att.index(QString("xlink:href"))) != -1)
283 andreas 721
		 Request.GetFeatureInfo.Get = att.value(index);
722
	   }
723
	   else if (element == el_GetFeatureInfo && el2 == el_Post)
724
	   {
285 andreas 725
	      if ((index = att.index(QString("href"))) != -1 || (index = att.index(QString("xlink:href"))) != -1)
283 andreas 726
		 Request.GetFeatureInfo.Post = att.value(index);
727
	   }
728
	}
729
	else if (qName.toLower() == QString("contactinformation"))
730
	   element = el_ContactInformation;
731
	else if (qName.toLower() == QString("contactpersonprimary"))
732
	   element = el_ContactPersonPrimary;
733
	else if (qName.toLower() == QString("contactperson"))
734
	   attribute = at_ContactPerson;
285 andreas 735
	else if (qName.toLower() == QString("contactorganization"))
283 andreas 736
	   attribute = at_ContactOrganisation;
737
	else if (qName.toLower() == QString("contactposition"))
738
	   attribute = at_ContactPosition;
739
	else if (qName.toLower() == QString("contactaddress"))
740
	   element = el_ContactAddress;
741
	else if (qName.toLower() == QString("addresstype"))
742
	   attribute = at_AddressType;
743
	else if (qName.toLower() == QString("address"))
744
	   attribute = at_Address;
745
	else if (qName.toLower() == QString("city"))
746
	   attribute = at_City;
747
	else if (qName.toLower() == QString("stateorprovince"))
748
	   attribute = at_StateOrProvince;
749
	else if (qName.toLower() == QString("postcode"))
750
	   attribute = at_PostCode;
751
	else if (qName.toLower() == QString("country"))
752
	   attribute = at_Country;
753
	else if (qName.toLower() == QString("contactvoicetelephone"))
754
	   attribute = at_ContactVoiceTelephone;
755
	else if (qName.toLower() == QString("contactfacsimiletelephone"))
756
	   attribute = at_ContactFacsimileTelephone;
757
	else if (qName.toLower() == QString("contactelectronicmailaddress"))
758
	   attribute = at_ContactElectronicMailAddress;
759
	else if (qName.toLower() == QString("fees"))
760
	   attribute = at_Fees;
761
	else if (qName.toLower() == QString("accessconstraints"))
762
	   attribute = at_AccessConstraints;
763
	else if (qName.toLower() == QString("capability"))
764
	   element = el_Capability;
765
	else if (qName.toLower() == QString("request"))
766
	   element = el_Request;
767
	else if (qName.toLower() == QString("getcapabilities"))
768
	   element = el_GetCapabilities;
769
	else if (qName.toLower() == QString("format"))
770
	   attribute = at_Format;
771
	else if (qName.toLower() == QString("dcptype"))
772
	   el2 = el_DCPType;
773
	else if (qName.toLower() == QString("http"))
774
	   el2 = el_HTTP;
775
	else if (qName.toLower() == QString("get"))
776
	   el2 = el_Get;
777
	else if (qName.toLower() == QString("post"))
778
	   el2 = el_Post;
779
	else if (qName.toLower() == QString("getmap"))
780
	   element = el_GetMap;
781
	else if (qName.toLower() == QString("getfeatureinfo"))
782
	   element = el_GetFeatureInfo;
783
	else if (qName.toLower() == QString("exception"))
784
	   element = el_Exception;
785
	else if (qName.toLower() == QString("layer"))
786
	{
787
	LAYER *akt;
788
 
789
	   element = el_Layer;
790
	   lcount++;
791
	   akt = allocateLayer();
792
 
793
	   if (firstLayer == 0)
794
	      firstLayer = akt;
795
 
796
	   if ((index = att.index(QString("opaque"))) != -1)
797
	      akt->opaque = (att.value(index).toInt() == 0) ? false : true;
798
 
799
	   if ((index = att.index(QString("noSubsets"))) != -1)
800
	      akt->noSubsets = (att.value(index).toInt() == 0) ? false : true;
801
 
802
	   if ((index = att.index(QString("queryable"))) != -1)
803
	      akt->queryable = (att.value(index).toInt() == 0) ? false : true;
804
 
805
	   if ((index = att.index(QString("cascaded"))) != -1)
806
	      akt->cascaded = (att.value(index).toInt() == 0) ? false : true;
807
	}
808
	else if (qName.toLower() == QString("srs"))
809
	   attribute = at_SRS;
810
	else if (qName.toLower() == QString("crs"))
811
	   attribute = at_CRS;
812
	else if (qName.toLower() == QString("abstract"))
813
	   attribute = at_Abstract;
814
	else if (qName.toLower() == QString("latlonboundingbox"))
815
	{
816
	   if (lcount < 1)
817
	   {
818
	      KMessageBox::error(this, i18n("Error at line %1: Element LatLonBoundingBox was found outside of a Layer element!").arg(line));
819
	      return false;
820
	   }
821
 
822
	   if (!Layer || !firstLayer)
823
	   {
824
	      KMessageBox::error(this, i18n("Fatal error at line %1: Layer was not initialized!").arg(line));
825
	      return false;
826
	   }
827
 
828
	   if ((index = att.index(QString("maxx"))) != -1)
829
	      Layer->LatLon.maxx = att.value(index).toDouble();
830
 
831
	   if ((index = att.index(QString("maxy"))) != -1)
832
	      Layer->LatLon.maxy = att.value(index).toDouble();
833
 
834
	   if ((index = att.index(QString("minx"))) != -1)
835
	      Layer->LatLon.minx = att.value(index).toDouble();
836
 
837
	   if ((index = att.index(QString("miny"))) != -1)
838
	      Layer->LatLon.miny = att.value(index).toDouble();
839
	}
840
	else if (qName.toLower() == QString("boundingbox"))
841
	{
842
	   if (lcount < 1)
843
	   {
844
	      KMessageBox::error(this, i18n("Error at line %1: Element BoundingBox was found outside of a Layer element!").arg(line));
845
	      return false;
846
	   }
847
 
848
	   if (!Layer || !firstLayer)
849
	   {
850
	      KMessageBox::error(this, i18n("Fatal error at line %1: Layer was not initialized!").arg(line));
851
	      return false;
852
	   }
853
 
854
	   if ((index = att.index(QString("maxx"))) != -1)
855
	      Layer->Bounding.maxx = att.value(index).toDouble();
856
 
857
	   if ((index = att.index(QString("maxy"))) != -1)
858
	      Layer->Bounding.maxy = att.value(index).toDouble();
859
 
860
	   if ((index = att.index(QString("minx"))) != -1)
861
	      Layer->Bounding.minx = att.value(index).toDouble();
862
 
863
	   if ((index = att.index(QString("miny"))) != -1)
864
	      Layer->Bounding.miny = att.value(index).toDouble();
865
 
866
	   if ((index = att.index(QString("srs"))) != -1)
867
	      Layer->Bounding.SRS = att.value(index);
868
	}
869
	else if (qName.toLower() == QString("metadataurl"))
870
	   element = el_MetadataURL;
871
	else if (qName.toLower() == QString("legendurl"))
872
	   element = el_LegendURL;
873
	else if (qName.toLower() == QString("style"))
874
	{
875
	   element = el_Style;
876
 
877
	   if (!Layer || !firstLayer)
878
	   {
879
	      KMessageBox::error(this, i18n("Fatal error at line %1: Layer was not initialized!").arg(line));
880
	      return false;
881
	   }
882
 
883
	   if (!Layer->style)
884
	      Layer->style = allocateStyle();
885
	   else
886
	   {
887
	   STYLE *akt = findLastStyle(Layer);
888
 
889
	      akt->next = allocateStyle();
890
	   }
891
	}
892
	else if (qName.toLower() == QString("scalehint"))
893
	{
894
	   if (lcount < 1)
895
	   {
896
	      KMessageBox::error(this, i18n("Error at line %1: Element ScaleHint was found outside of a Layer element!").arg(line));
897
	      return false;
898
	   }
899
 
900
	   if (!Layer || !firstLayer)
901
	   {
902
	      KMessageBox::error(this, i18n("Fatal error at line %1: Layer was not initialized!").arg(line));
903
	      return false;
904
	   }
905
 
906
	   if ((index = att.index(QString("min"))) != -1)
907
	      Layer->scaleMin = att.value(index).toDouble();
908
 
909
	   if ((index = att.index(QString("max"))) != -1)
910
	      Layer->scaleMax = att.value(index).toDouble();
911
	}
912
 
913
	return true;
914
}
915
 
916
bool wmsSelectorWidget::endElement( const QString&, const QString&, const QString& qName)
917
{
918
	attribute = at_none;
919
 
920
	if (qName.toLower() == QString("wmt_ms_Capabilities"))
921
	   element = el_none;
922
	else if (qName.toLower() == QString("service"))
923
	   element = el_WMT_MS_Capabilities;
924
	else if (qName.toLower() == QString("keywordlist"))
925
	   element = el_Service;
926
	else if (qName.toLower() == QString("contactinformation"))
927
	   element = el_Service;
928
	else if (qName.toLower() == QString("contactpersonprimary"))
929
	   element = el_ContactInformation;
930
	else if (qName.toLower() == QString("contactaddress"))
931
	   element = el_ContactInformation;
932
	else if (qName.toLower() == QString("capability"))
933
	   element = el_WMT_MS_Capabilities;
934
	else if (qName.toLower() == QString("request"))
935
	   element = el_Capability;
936
	else if (qName.toLower() == QString("getcapabilities"))
937
	   element = el_Request;
938
	else if (qName.toLower() == QString("dcptype"))
939
	   el2 = el_none;
940
	else if (qName.toLower() == QString("http"))
941
	   el2 = el_DCPType;
942
	else if (qName.toLower() == QString("get"))
943
	   el2 = el_HTTP;
944
	else if (qName.toLower() == QString("post"))
945
	   el2 = el_HTTP;
946
	else if (qName.toLower() == QString("getmap"))
947
	   element = el_Request;
948
	else if (qName.toLower() == QString("getfeatureinfo"))
949
	   element = el_Request;
950
	else if (qName.toLower() == QString("exception"))
951
	   element = el_Capability;
952
	else if (qName.toLower() == QString("layer"))
953
	{
954
	   lcount--;
955
 
956
	   if (lcount == 0)
957
	      element = el_Capability;
958
	   else
959
	      element = el_Layer;
960
	}
961
	else if (qName.toLower() == QString("metadataurl"))
962
	   element = el_Layer;
963
	else if (qName.toLower() == QString("legendurl"))
964
	   element = el_Layer;
965
	else if (qName.toLower() == QString("style"))
966
	   element = el_Layer;
967
 
968
	return true;
969
}
970
 
971
bool wmsSelectorWidget::characters (const QString& chraw)
972
{
973
	if (chraw.at(0) == QChar('\n'))
974
	{
975
	   line++;
976
	   return true;
977
	}
978
 
979
	QString ch = chraw.trimmed();
980
 
981
	if (ch.length() == 0)
982
	   return true;
983
 
984
	if (element == el_Service || element == el_ContactInformation ||
985
	    element == el_ContactPersonPrimary || element == el_ContactAddress)
986
	{
987
	   if (attribute == at_Name)
988
	      Service.Name = ch;
989
	   else if (attribute == at_Title)
990
	      Service.Title = ch;
991
	   else if (attribute == at_Abstract)
992
	      Service.Abstract = ch;
993
	   else if (attribute == at_ContactPerson)
994
	      Service.ContactPerson = ch;
995
	   else if (attribute == at_ContactOrganisation)
996
	      Service.ContactOrganisation = ch;
997
	   else if (attribute == at_ContactElectronicMailAddress)
998
	      Service.ContactElectronicMailAddress = ch;
999
	   else if (attribute == at_ContactPosition)
1000
	      Service.ContactPosition = ch;
1001
	   else if (attribute == at_AddressType)
1002
	      Service.AddressType = ch;
1003
	   else if (attribute == at_Address)
1004
	      Service.Address = ch;
1005
	   else if (attribute == at_City)
1006
	      Service.City = ch;
1007
	   else if (attribute == at_StateOrProvince)
1008
	      Service.StateOrProvince = ch;
1009
	   else if (attribute == at_PostCode)
1010
	      Service.PostCode = ch;
1011
	   else if (attribute == at_Country)
1012
	      Service.Country = ch;
1013
	   else if (attribute == at_ContactVoiceTelephone)
1014
	      Service.ContactVoiceTelephone = ch;
1015
	   else if (attribute == at_ContactFacsimileTelephone)
1016
	      Service.ContactFacsimileTelephone = ch;
1017
	   else if (attribute == at_Fees)
1018
	      Service.Fees = ch;
1019
	   else if (attribute == at_AccessConstraints)
1020
	      Service.AccessConstraints = ch;
1021
	}
1022
	else if (element == el_GetCapabilities)
1023
	{
1024
	   if (attribute == at_Format)
1025
	      Request.GetCapabilities.Format << ch;
1026
	}
1027
	else if (element == el_GetMap)
1028
	{
1029
	   if (attribute == at_Format)
1030
	      Request.GetMap.Format << ch;
1031
	}
1032
	else if (element == el_GetFeatureInfo)
1033
	{
1034
	   if (attribute == at_Format)
1035
	      Request.GetFeatureInfo.Format << ch;
1036
	}
1037
	else if (element == el_Exception)
1038
	{
1039
	   if (attribute == at_Format)
1040
	      Exception << ch;
1041
	}
1042
	else if (element == el_Layer)
1043
	{
1044
	   if (attribute == at_Name)
1045
	      Layer->Name = ch;
1046
	   else if (attribute == at_Title)
1047
	      Layer->Title = ch;
1048
	   else if (attribute == at_Abstract)
1049
	      Layer->Abstract = ch;
1050
	   else if (attribute == at_SRS)
1051
	      Layer->SRS << ch;
1052
	   else if (attribute == at_CRS)
1053
	      Layer->CRS << ch;
1054
	}
1055
	else if (element == el_Style)
1056
	{
1057
	STYLE *akt = findLastStyle(Layer);
1058
 
1059
	   if (!Layer->style)
1060
	   {
1061
	      Layer->style = allocateStyle();
1062
	      akt = Layer->style;
1063
	   }
1064
 
1065
	   if (!akt)
1066
	   {
1067
	      KMessageBox::error(this, i18n("Fatal error at line %1: No, or unable to allocate memory for a style!").arg(line));
1068
	      return false;
1069
	   }
1070
 
1071
	   if (attribute == at_Name)
1072
	      akt->Name = ch;
1073
	   else if (attribute == at_Title)
1074
	      akt->Title = ch;
1075
	}
1076
 
1077
	return true;
1078
}
1079
 
1080
void wmsSelectorWidget::getCapabilities()
1081
{
1082
	if (file.exists())
1083
	   file.remove();
1084
 
1085
	if (!file.open(QIODevice::WriteOnly))
1086
	{
1087
	   KMessageBox::information(this,
1088
		i18n("Unable to save the file %1: %2.").arg(file.fileName()).arg(file.errorString()),
1089
		i18n("WMS capabilities"));
1090
 
1091
	   return;
1092
	}
1093
 
1094
#ifndef QT_NO_OPENSSL
1095
	QHttp::ConnectionMode mode = (urlWMS->url().protocol().toLower() == "https") ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp;
1096
#else
1097
	QHttp::ConnectionMode mode = QHttp::ConnectionModeHttp;
1098
#endif
1099
	http->setHost(urlWMS->url().host(), mode, (urlWMS->url().port() == -1) ? 0 : urlWMS->url().port());
1100
 
1101
	if (!urlWMS->url().user().isEmpty())
1102
	   http->setUser(urlWMS->url().user(), urlWMS->url().pass());
1103
 
1104
	httpRequestAborted = false;
1105
	id = http->get(urlWMS->url().url() + "?VERSION=1.1.1&REQUEST=GetCapabilities&SERVICE=WMS", &file);
1106
	// Show a progress dialog
1107
	progressDialog->setVisible(true);
1108
	progressDialog->setWindowTitle(i18n("Getting capabilities"));
1109
	progressDialog->setLabelText(i18n("Downloading capabilities."));
1110
}
1111
 
1112
bool wmsSelectorWidget::parseWMS()
1113
{
1114
QXmlSimpleReader reader;
1115
LAYER *aktLayer;
1116
 
1117
	QXmlInputSource source (&file);
1118
	reader.setContentHandler (this);
1119
	reader.parse (source);
1120
 
1121
	// Put the result into the elements of the mask
1122
	aktLayer = firstLayer;
1123
 
1124
	while (aktLayer)
1125
	{
1126
	   if (!aktLayer->Name.isEmpty())	// Do we have a valid layer?
1127
	      actionLayer->availableListWidget()->addItem(aktLayer->Name);
1128
 
1129
	   aktLayer = aktLayer->next;
1130
	}
1131
 
1132
	return true;
1133
}
1134
 
284 andreas 1135
QString wmsSelectorWidget::getLayers()
1136
{
1137
QString la;
1138
QListWidget *lw = actionLayer->selectedListWidget();
1139
 
289 andreas 1140
	for (int i = 0; i < lw->count(); i++)
284 andreas 1141
	{
1142
	   QListWidgetItem *item = lw->item(i);
1143
	   la += item->text();
1144
 
289 andreas 1145
	   if (i < lw->count() - 1)
284 andreas 1146
	      la += ",";
1147
	}
1148
 
1149
	return la;
1150
}
1151
 
1152
QString wmsSelectorWidget::getStyles()
1153
{
1154
QString la;
1155
QListWidget *lw = actionLayer->selectedListWidget();
1156
int anz = lw->count();
1157
 
1158
	if (cbStyles->isChecked() && anz > 1)
1159
	   la.fill(',', anz - 1);
1160
 
1161
	return la;
1162
}
1163
 
283 andreas 1164
void wmsSelectorWidget::cancelDownload()
1165
{
1166
	httpRequestAborted = true;
1167
	http->abort();
1168
}
1169
 
1170
void wmsSelectorWidget::WMSrequestFinished(int requestId, bool error)
1171
{
1172
	if (requestId != id)
1173
           return;
1174
 
1175
	if (httpRequestAborted)
1176
	{
1177
	   file.close();
1178
	   file.remove();
1179
	   progressDialog->hide();
1180
	   return;
1181
	}
1182
 
1183
	progressDialog->hide();
1184
	file.close();
1185
 
1186
	if (error)
1187
	{
1188
	   file.remove();
1189
	   KMessageBox::information(this, i18n("Download failed: %1.").arg(http->errorString()), i18n("WMS capabilities"));
1190
	}
1191
	else
1192
	{
1193
	   parseWMS();
284 andreas 1194
 
1195
	   if (Init)
1196
	   {
1197
	      // Set the already selected layers to the selected box
1198
	      // This will be done only, if the box with the available layers
1199
	      // is not empty. Otherwise we've to assume, that there was an
1200
	      // error getting the capabilities of the server.
1201
	      if (actionLayer->availableListWidget()->count() > 0)
1202
	      {
1203
	      QListWidget *item = actionLayer->selectedListWidget();
1204
	      QListWidget *av = actionLayer->availableListWidget();
1205
	      QStringList laList = Layers.split(',');
1206
 
1207
		 for (int i = 0; i < laList.size(); i++)
1208
		 {
1209
		    QList<QListWidgetItem*> qlwi = av->findItems(laList.at(i), Qt::MatchExactly);
1210
 
1211
		    if (qlwi.size() == 1)
1212
		    {
1213
		       item->addItem(laList.at(i));
1214
		       av->takeItem(av->row(qlwi.at(0)));
1215
		    }
1216
		 }
1217
	      }
1218
 
1219
	      Init = false;
1220
	   }
283 andreas 1221
	}
1222
}
1223
 
1224
void wmsSelectorWidget::readResponseHeader(const QHttpResponseHeader &responseHeader)
1225
{
1226
	switch (responseHeader.statusCode())
1227
	{
1228
	   case 200:                   // Ok
1229
	   case 301:                   // Moved Permanently
1230
	   case 302:                   // Found
1231
	   case 303:                   // See Other
1232
	   case 307:                   // Temporary Redirect
1233
		// these are not error conditions
1234
	   break;
1235
 
1236
	   default:
1237
	      KMessageBox::information(this,
1238
	        i18n("Download failed: %1.").arg(responseHeader.reasonPhrase()),
1239
		i18n("WMS capabilities"));
1240
		httpRequestAborted = true;
1241
		progressDialog->hide();
1242
		http->abort();
1243
	}
1244
}
1245
 
1246
void wmsSelectorWidget::updateDataReadProgress(int bytesRead, int totalBytes)
1247
 {
1248
	if (httpRequestAborted)
1249
	   return;
1250
 
1251
	progressDialog->progressBar()->setMaximum(totalBytes);
1252
	progressDialog->progressBar()->setValue(bytesRead);
1253
 }
1254
 
1255
void wmsSelectorWidget::slotAuthenticationRequired(const QString &hostName, quint16, QAuthenticator *authenticator)
1256
{
1257
QDialog dlg;
1258
Ui::Dialog ui;
1259
 
1260
	ui.setupUi(&dlg);
1261
	dlg.adjustSize();
1262
	ui.siteDescription->setText(i18n("%1 at %2").arg(authenticator->realm()).arg(hostName));
1263
 
1264
	if (dlg.exec() == QDialog::Accepted)
1265
	{
1266
	   authenticator->setUser(ui.userEdit->text());
1267
	   authenticator->setPassword(ui.passwordEdit->text());
1268
	}
1269
}
1270
 
1271
#ifndef QT_NO_OPENSSL
1272
void wmsSelectorWidget::sslErrors(const QList<QSslError> &errors)
1273
{
1274
QString errorString;
1275
 
1276
	foreach (const QSslError &error, errors)
1277
	{
1278
	   if (!errorString.isEmpty())
1279
	      errorString += ", ";
1280
 
1281
	   errorString += error.errorString();
1282
	}
1283
 
1284
	if (KMessageBox::warningContinueCancel(this,
1285
		i18n("One or more SSL errors has occurred: %1").arg(errorString),
1286
		i18n("WMS capabilities")) == KMessageBox::Continue)
1287
	{
1288
           http->ignoreSslErrors();
1289
	}
1290
}
1291
#endif
1292
 
1293
void wmsSelectorWidget::initializeParser()
1294
{
1295
LAYER *aktLayer;
1296
 
1297
	Service.Name.clear();
1298
	Service.Title.clear();
1299
	Service.Abstract.clear();
1300
	Service.OnlineResource.clear();
1301
	Service.Type.clear();
1302
	Service.ContactPerson.clear();
1303
	Service.ContactOrganisation.clear();
1304
	Service.ContactPosition.clear();
1305
	Service.AddressType.clear();
1306
	Service.Address.clear();
1307
	Service.City.clear();
1308
	Service.StateOrProvince.clear();
1309
	Service.PostCode.clear();
1310
	Service.Country.clear();
1311
	Service.ContactVoiceTelephone.clear();
1312
	Service.ContactFacsimileTelephone.clear();
1313
	Service.ContactElectronicMailAddress.clear();
1314
	Service.Fees.clear();
1315
	Service.AccessConstraints.clear();
1316
 
1317
	Request.GetCapabilities.Format.clear();
1318
	Request.GetCapabilities.Get.clear();
1319
	Request.GetCapabilities.Post.clear();
1320
 
1321
	Request.GetMap.Format.clear();
1322
	Request.GetMap.Get.clear();
1323
	Request.GetMap.Post.clear();
1324
 
1325
	Request.GetFeatureInfo.Format.clear();
1326
	Request.GetFeatureInfo.Get.clear();
1327
	Request.GetFeatureInfo.Post.clear();
1328
 
1329
	if (Layer)
1330
	{
1331
	LAYER *nl;
1332
 
1333
	   aktLayer = Layer;
1334
 
1335
	   while (aktLayer)
1336
	   {
1337
	      aktLayer->opaque = false;
1338
	      aktLayer->noSubsets = false;
1339
	      aktLayer->queryable = false;
1340
	      aktLayer->cascaded = false;
1341
	      aktLayer->Name.clear();
1342
	      aktLayer->Title.clear();
1343
	      aktLayer->Abstract.clear();
1344
	      aktLayer->SRS.clear();
1345
	      aktLayer->LatLon.maxx = 0.0;
1346
	      aktLayer->LatLon.maxy = 0.0;
1347
	      aktLayer->LatLon.minx = 0.0;
1348
	      aktLayer->LatLon.miny = 0.0;
1349
	      aktLayer->Bounding.maxx = 0.0;
1350
	      aktLayer->Bounding.maxy = 0.0;
1351
	      aktLayer->Bounding.minx = 0.0;
1352
	      aktLayer->Bounding.miny = 0.0;
1353
	      aktLayer->scaleMin = 0.0;
1354
	      aktLayer->scaleMax = 0.0;
1355
 
1356
	      if (aktLayer->style)
1357
	      {
1358
	      STYLE *ns, *akt;
1359
 
1360
		 akt = aktLayer->style;
1361
 
1362
		 while (akt)
1363
		 {
1364
		    akt->Name.clear();
1365
		    akt->Title.clear();
1366
		    akt->Format.clear();
1367
		    akt->LegendURL.clear();
1368
		    ns = akt->next;
1369
		    delete akt;
1370
		    akt = ns;
1371
		 }
1372
 
1373
		 aktLayer->style = 0;
1374
	      }
1375
 
1376
	      nl = aktLayer->next;
1377
	      delete aktLayer;
1378
	      aktLayer = nl;
1379
	   }
1380
 
1381
	   Layer = 0;
1382
	   firstLayer = 0;
1383
	}
1384
}
1385
 
1386
LAYER *wmsSelectorWidget::allocateLayer()
1387
{
1388
LAYER *aktLayer, *last;
1389
 
1390
	if (Layer)
1391
	{
1392
	   last = Layer;
1393
 
1394
	   while (last)
1395
	   {
1396
	      if (!last->next)
1397
		 break;
1398
 
1399
	      last = last->next;
1400
	   }
1401
 
1402
	   aktLayer = new LAYER;
1403
	   aktLayer->next = 0;
1404
	   last->next = aktLayer;
1405
	   Layer = aktLayer;
1406
	}
1407
	else
1408
	{
1409
	   aktLayer = new LAYER;
1410
	   aktLayer->next = 0;
1411
	   Layer = last = firstLayer = aktLayer;
1412
	}
1413
 
1414
	aktLayer->opaque = false;
1415
	aktLayer->noSubsets = false;
1416
	aktLayer->queryable = false;
1417
	aktLayer->cascaded = false;
1418
	aktLayer->Name.clear();
1419
	aktLayer->Title.clear();
1420
	aktLayer->Abstract.clear();
1421
	aktLayer->SRS.clear();
1422
	aktLayer->LatLon.maxx = 0.0;
1423
	aktLayer->LatLon.maxy = 0.0;
1424
	aktLayer->LatLon.minx = 0.0;
1425
	aktLayer->LatLon.miny = 0.0;
1426
	aktLayer->LatLon.SRS.clear();
1427
	aktLayer->Bounding.maxx = 0.0;
1428
	aktLayer->Bounding.maxy = 0.0;
1429
	aktLayer->Bounding.minx = 0.0;
1430
	aktLayer->Bounding.miny = 0.0;
1431
	aktLayer->Bounding.SRS.clear();
1432
	aktLayer->scaleMin = 0.0;
1433
	aktLayer->scaleMax = 0.0;
1434
	aktLayer->style = 0;
1435
	return aktLayer;
1436
}
1437
 
1438
STYLE *wmsSelectorWidget::allocateStyle()
1439
{
1440
STYLE *akt;
1441
 
1442
	akt = new STYLE;
1443
	akt->Name.clear();
1444
	akt->Title.clear();
1445
	akt->Format.clear();
1446
	akt->LegendURL.clear();
1447
	akt->next = 0;
1448
	return akt;
1449
}
1450
 
1451
STYLE *wmsSelectorWidget::findLastStyle(LAYER *l)
1452
{
1453
STYLE *akt;
1454
 
1455
	if (!l)
1456
	   return 0;
1457
 
1458
	akt = l->style;
1459
 
1460
	while (akt)
1461
	{
1462
	   if (!akt->next)
1463
	      return akt;
1464
 
1465
	   akt = akt->next;
1466
	}
1467
 
1468
	return 0;
1469
}
1470
 
1471
bool wmsSelectorWidget::writeWMSTag(double llat, double llon, double rlat, double rlon, int width, int height)
1472
{
1473
#if defined HAVE_GDAL
1474
QFile fl(MAP);
1475
QString xml, s, srs, crs, styles, bSize, ext;
1476
QDir dir = QDir::home();
1477
QString path = dir.absolutePath();
285 andreas 1478
QStringList sl;
284 andreas 1479
//int item;
283 andreas 1480
double _llat, _llon, _rlat, _rlon;
1481
 
1482
	if (!fl.open(QIODevice::ReadWrite | QIODevice::Truncate))
1483
	{
1484
	   KMessageBox::error (this, i18n("Error opening or creating the WMS tag file!\nPlease check file name and/or permissions."));
1485
	   return false;
1486
	}
1487
 
1488
	KConfig cfg (QString("sportwatcher.rc"), KConfig::SimpleConfig);
1489
	KConfigGroup wms (&cfg, "WMS");
1490
 
1491
	xml = "<GDAL_WMS>\n";
1492
	xml += "   <Service name=\"WMS\">\n";
284 andreas 1493
 
1494
	if (!WMSVersion.isEmpty())
1495
	   xml += "      <Version>" + WMSVersion + "</Version>\n";
1496
	else
1497
	   xml += "      <Version>1.1.1</Version>\n";
1498
 
283 andreas 1499
	xml += "      <ServerURL>" + urlWMS->url().url() + "?</serverURL>\n";
1500
	_llon = llon;
1501
	_llat = llat;
1502
	_rlon = rlon;
1503
	_rlat = rlat;
1504
 
285 andreas 1505
	if (firstLayer)
1506
	{
1507
	LAYER *akt = firstLayer;
1508
 
1509
	   while (akt)
1510
	   {
1511
	      for (int i = 0; i < akt->SRS.size(); ++i)
1512
	         sl << akt->SRS.at(i);
1513
 
1514
	      akt = akt->next;
1515
	   }
290 andreas 1516
#if QT_VERSION >= 0x040500
285 andreas 1517
	   sl.removeDuplicates();
290 andreas 1518
#else
1519
	   removeDuplicates(sl);
1520
#endif
285 andreas 1521
	   if (sl.contains("EPSG:4326") || sl.contains("WGS:84"))
1522
	      srs = QString("EPSG:4326");
1523
	   else
1524
	      srs = sl.at(0);
1525
	}
283 andreas 1526
	else
1527
	   srs = QString("EPSG:4326");
1528
 
1529
	xml += "      <SRS>" + srs + "</SRS>\n";
1530
 
1531
	if (firstLayer && firstLayer->CRS.size())
285 andreas 1532
	{
1533
	LAYER *akt = firstLayer;
1534
 
1535
	   sl.clear();
1536
 
1537
	   while (akt)
1538
	   {
1539
	      for (int i = 0; i < akt->CRS.size(); ++i)
1540
	         sl << akt->CRS.at(i);
1541
 
1542
	      akt = akt->next;
1543
	   }
1544
 
290 andreas 1545
#if QT_VERSION >= 0x040500
285 andreas 1546
	   sl.removeDuplicates();
290 andreas 1547
#else
1548
	   removeDuplicates(sl);
1549
#endif
285 andreas 1550
	   if (sl.contains("EPSG:4326") || sl.contains("CRS:84"))
1551
	      crs = QString("EPSG:4326");
1552
	   else
1553
	      crs = sl.at(0);
1554
	}
283 andreas 1555
	else
1556
	   crs = QString("EPSG:4326");
1557
 
1558
	xml += "      <CRS>" + crs + "</CRS>\n";
1559
	xml += "      <ImageFormat>image/";
1560
	xml += "png";
1561
	ext = QString(".png");
1562
	xml += "</ImageFormat>\n";
1563
 
1564
	xml += "      <Layers>";
1565
	QListWidget *lw = actionLayer->selectedListWidget();
1566
	s.clear();
1567
 
1568
	for (int i = 0; i < lw->count(); i++)
1569
	{
1570
	QListWidgetItem *lwi;
1571
 
1572
	   if (i > 0 && i < lw->count())
1573
	   {
1574
	      xml += ",";
1575
	      s += ",";
1576
	   }
1577
 
1578
	   lwi = lw->item(i);
1579
	   xml += lwi->text();
1580
	}
1581
 
1582
	xml += "</Layers>\n";
1583
 
1584
	if (StyleCommas)
1585
	   xml += "      <Styles>" + s + "</Styles>\n";
1586
	else
1587
	   xml += "      <Styles></Styles>\n";
1588
 
1589
	xml += "      <BBoxOrder>xyXY</BBoxOrder>\n";
1590
	xml += "   </Service>\n";
1591
	xml += "   <DataWindow>\n";
1592
	s.sprintf ("%f", _llat);
1593
	xml += "      <UpperLeftX>" + s + "</UpperLeftX>\n";
1594
	s.sprintf ("%f", _llon);
1595
	xml += "      <UpperLeftY>" + s + "</UpperLeftY>\n";
1596
	s.sprintf ("%f", _rlat);
1597
	xml += "      <LowerRightX>" + s + "</LowerRightX>\n";
1598
	s.sprintf ("%f", _rlon);
1599
	xml += "      <LowerRightY>" + s + "</LowerRightY>\n";
1600
	s.sprintf ("%d", width);
1601
	xml += "      <SizeX>" + s + "</SizeX>\n";
1602
	s.sprintf ("%d", height);
1603
	xml += "      <SizeY>" + s + "</SizeY>\n";
1604
	xml += "   </DataWindow>\n";
1605
 
1606
	xml += "   <Projection>" + srs + "</Projection>\n";
1607
	xml += "   <BandsCount>" + QString("%1").arg(edBands->value()) + "</BandsCount>\n";
284 andreas 1608
/*	item = wms.readEntry("Tile", 2);
283 andreas 1609
 
1610
	switch (item)
1611
	{
1612
	   case 0: bSize = QString("64"); break;
1613
	   case 1: bSize = QString("128"); break;
1614
	   case 2: bSize = QString("256"); break;
1615
	   case 3: bSize = QString("512"); break;
1616
	   case 4: bSize = QString("1024"); break;
1617
	   default: bSize = QString("256");
1618
	}
284 andreas 1619
*/
1620
	bSize = QString("256");
283 andreas 1621
	xml += "   <BlockSizeX>" + bSize + "</BlockSizeX>\n";
1622
	xml += "   <BlockSizeY>" + bSize + "</BlockSizeY>\n";
1623
	xml += "   <OverviewCount>" + wms.readEntry("Overview", QString("10")) + "</OverviewCount>\n";
1624
	xml += "   <Cache>\n";
1625
	xml += "      <Path>" + path + "/.gdalwmscache" + "</Path>\n";
1626
	xml += "      <Depth>" + wms.readEntry("Depth", QString("2")) + "</Depth>\n";
1627
	xml += "      <Extension>" + ext + "</Extension>\n";
1628
	xml += "   </Cache>\n";
1629
	QString adv((wms.readEntry("Advice", true)) ? "true" : "false");
1630
	QString ver((wms.readEntry("Verify", false)) ? "true" : "false");
1631
 
1632
	xml += "   <OfflineMode>false</OfflineMode>\n";
1633
	xml += "   <AdviseRead>" + adv + "</AdviseRead>\n";
1634
	xml += "   <VerifyAdviseRead>" + ver + "</VerifyAdviseRead>\n";
1635
	xml += "</GDAL_WMS>\n";
1636
 
1637
	write (fl.handle(), xml.toAscii().data(), strlen (xml.toAscii().data()));
1638
	fl.close();
1639
#endif
1640
	return true;
1641
}
1642
 
1643
void wmsSelectorWidget::setDimension(double &minx, double &miny, double &maxx, double &maxy, QListWidgetItem *item = 0)
1644
{
284 andreas 1645
double cx, cy, levX, levY;
1646
LAYER *akt;
283 andreas 1647
 
1648
	cx = cy = 0.0;
1649
	akt = firstLayer;
1650
 
284 andreas 1651
	if (zLevel >= 0 && zLevel < 10)
283 andreas 1652
	{
284 andreas 1653
	   levX = zoom[zLevel].x;
1654
	   levY = zoom[zLevel].y;
1655
	}
1656
	else
1657
	{
1658
	   levX = zoom[0].x;
1659
	   levY = zoom[0].y;
1660
	}
283 andreas 1661
 
284 andreas 1662
	cx = edLat->value();
1663
	cy = edLon->value();
283 andreas 1664
 
284 andreas 1665
	if (cx == 0.0 && cy == 0.0)
1666
	{
1667
	   while (akt)
1668
	   {
1669
	      cx = akt->LatLon.minx + (akt->LatLon.maxx - akt->LatLon.minx) / 2.0;
1670
	      cy = akt->LatLon.miny + (akt->LatLon.maxy - akt->LatLon.miny) / 2.0;
283 andreas 1671
 
284 andreas 1672
	      if ((cx != 0.0 || cy != 0.0) && !item)
1673
	         break;
283 andreas 1674
 
284 andreas 1675
	      if (item && item->text() == akt->Name && cx != 0.0 && cy != 0.0)
1676
	         break;
1677
 
1678
	      akt = akt->next;
1679
	   }
1680
 
1681
	   if (cx == 0.0 && cy == 0.0)
1682
	   {	// Schloss Schoenbrunn in Vienna
1683
	      cx = 16.298223 + (0.014108 / 2.0);
1684
	      cy = 48.177103 + (0.003554 / 2.0);
1685
	   }
1686
 
1687
	   edLat->setValue(cx);
1688
	   edLon->setValue(cy);
283 andreas 1689
	}
1690
 
284 andreas 1691
	minx = cx - (levX / 2.0);
1692
	maxx = cx + (levX / 2.0);
1693
	miny = cy + (levY / 2.0);
1694
	maxy = cy - (levY / 2.0);
283 andreas 1695
}
1696
 
290 andreas 1697
#if QT_VERSION < 0x040500
1698
QStringList removeDuplicates(QStringList &sl)
1699
{
1700
QStringList res;
1701
 
1702
	for (int i = 0; i < sl.size(); i++)
1703
	{
1704
	   if (res.indexOf(sl.at(i)) == -1)
1705
	      res << sl.at(i);
1706
	}
1707
 
1708
	sl = res;
1709
	return res;
1710
}
1711
#endif
1712
 
283 andreas 1713
#include "wmsselectorwidget.moc"
1714