Subversion Repositories public

Rev

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