Subversion Repositories public

Rev

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