Subversion Repositories public

Rev

Rev 275 | Rev 277 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
273 andreas 1
//
274 andreas 2
// C++ Implementation: SRender
273 andreas 3
//
4
// Description: Renders a map from some shape files. This class assumes,
5
//              that the shape files are in open street map format!
6
//
7
//
8
// Author: Andreas Theofilu <andreas@theosys.at>, (C) 2009
9
//
10
// Copyright: See COPYING file that comes with this distribution
11
//
12
//
13
 
14
#define BOOST_SPIRIT_THREADSAFE
274 andreas 15
#include <QLabel>
16
#include <QString>
17
#include <QXmlReader>
18
#include <QDir>
19
#include <QColor>
275 andreas 20
#include <QImage>
274 andreas 21
#include <KStandardDirs>
22
#include <KConfig>
23
#include <KLocale>
24
#include <KMessageBox>
25
#include <KGlobalSettings>
26
#include <KConfigGroup>
275 andreas 27
#include <KIconLoader>
273 andreas 28
 
29
#include "config.h"
30
#include "render.h"
274 andreas 31
#include <iostream>
273 andreas 32
 
33
#define CON_MAP			100
34
#define CON_STYLE		101
35
#define CON_RULE		102
36
#define CON_LINESYMBOLIZER	103
37
#define CON_POINTSYMBOLIZER	104
38
#define CON_POLYGONSYMBOLIZER	105
39
#define CON_TEXTSYMBOLIZER	106
40
#define CON_POLYGONPATTERNSYMBOLIZER	107
41
#define CON_LAYER		108
42
#define CON_DATASOURCE		109
274 andreas 43
#define CON_SHIELDSYMBOLIZER	110
44
#define CON_LINEPATTERNSYMBOLIZER	111
276 andreas 45
#define CON_ELSEFILTER		112
273 andreas 46
 
47
#define FLD_FILTER		200
48
#define FLD_CSSPARAMETER	201
49
#define FLD_MINSCALE		202
50
#define FLD_MAXSCALE		203
51
#define FLD_STYLENAME		204
52
#define FLD_PARAMETER		205
53
 
54
#define ATT_FILL		300
55
#define ATT_FILE		301
56
#define ATT_TYPE		302
57
#define ATT_WIDTH		303
58
#define ATT_HEIGHT		304
59
#define ATT_SIZE		305
60
#define ATT_NAME		306
61
#define ATT_FACENAME		307
62
#define ATT_DY			308
63
#define ATT_HALORADIUS		309
64
#define ATT_WRAPWIDTH		310
65
#define ATT_MINDISTANCE		311
66
#define ATT_MAXDISTANCE		312
67
#define ATT_PLACEMENT		313
68
#define ATT_ALLOWOVERLAP	314
69
#define ATT_STATUS		315
70
#define ATT_SRS			316
275 andreas 71
#define ATT_DX			317
276 andreas 72
#define ATT_ALIGNMENT		318
273 andreas 73
 
74
#define FIRST_CON		100
276 andreas 75
#define LAST_CON		112
273 andreas 76
 
77
#define FIRST_FLD		200
78
#define LAST_FLD		205
79
 
80
#define FIRST_ATT		300
276 andreas 81
#define LAST_ATT		318
273 andreas 82
 
274 andreas 83
using std::cout;
84
using std::cerr;
85
using std::clog;
86
using std::endl;
87
 
88
TOKEN token[] = {
273 andreas 89
	// Containers
274 andreas 90
	{ CON_MAP,			in_map,			QString("Map") },
91
	{ CON_STYLE,			in_style,		QString("Style") },
92
	{ CON_RULE,			in_rule,		QString("Rule") },
93
	{ CON_LINESYMBOLIZER,		in_linesymbolizer,	QString("LineSymbolizer") },
94
	{ CON_POINTSYMBOLIZER,		in_pointsymbolizer,	QString("PointSymbolizer") },
95
	{ CON_POLYGONSYMBOLIZER,	in_polygonsymbolizer,	QString("PolygonSymbolizer") },
96
	{ CON_TEXTSYMBOLIZER,		in_textsymbolizer,	QString("TextSymbolizer") },
97
	{ CON_POLYGONPATTERNSYMBOLIZER,	in_polygonpatternsymbolizer,	QString("PolygonPatternSymbolizer") },
98
	{ CON_LAYER,			in_layer,		QString("Layer") },
99
	{ CON_DATASOURCE,		in_datasource,		QString("Datasource") },
100
	{ CON_SHIELDSYMBOLIZER,		in_shieldsymbolizer,	QString("ShieldSymbolizer") },
275 andreas 101
	{ CON_LINEPATTERNSYMBOLIZER,	in_linepatternsymbolizer, QString("LinePatternSymbolizer") },
276 andreas 102
	{ CON_ELSEFILTER,		in_rule,		QString("ElseFilter") },
273 andreas 103
	// Fields
274 andreas 104
	{ FLD_FILTER,			in_rule,		QString("Filter") },
105
	{ FLD_CSSPARAMETER,		in_symbolizer,		QString("CSSParameter") },
106
	{ FLD_MINSCALE,			in_rule,		QString("MinScaleDenominator") },
107
	{ FLD_MAXSCALE,			in_rule,		QString("MaxScaleDenominator") },
108
	{ FLD_STYLENAME,		in_style,		QString("StyleName") },
109
	{ FLD_PARAMETER,		in_datasource,		QString("Parameter") },
273 andreas 110
	// Attributes
274 andreas 111
	{ ATT_FILL,			in_symbolizer,		QString("fill") },
112
	{ ATT_NAME,			in_symbolizer,		QString("name") },
113
	{ ATT_FILE,			in_symbolizer,		QString("file") },
114
	{ ATT_TYPE,			in_symbolizer,		QString("type") },
115
	{ ATT_WIDTH,			in_symbolizer,		QString("width") },
116
	{ ATT_HEIGHT,			in_symbolizer,		QString("height") },
117
	{ ATT_SIZE,			in_symbolizer,		QString("size") },
118
	{ ATT_FACENAME,			in_symbolizer,		QString("face_name") },
275 andreas 119
	{ ATT_DX,			in_symbolizer,		QString("dx") },
274 andreas 120
	{ ATT_DY,			in_symbolizer,		QString("dy") },
121
	{ ATT_HALORADIUS,		in_symbolizer,		QString("halo_radius") },
122
	{ ATT_WRAPWIDTH,		in_symbolizer,		QString("wrap_width") },
123
	{ ATT_MINDISTANCE,		in_symbolizer,		QString("min_distance") },
124
	{ ATT_MAXDISTANCE,		in_symbolizer,		QString("max_distance") },
125
	{ ATT_PLACEMENT,		in_symbolizer,		QString("placement") },
126
	{ ATT_ALLOWOVERLAP,		in_symbolizer,		QString("allow_overlap") },
127
	{ ATT_STATUS,			in_layer,		QString("status") },
128
	{ ATT_SRS,			in_layer,		QString("srs") },
276 andreas 129
	{ ATT_ALIGNMENT,		in_symbolizer,		QString("alignment") },
274 andreas 130
	{ 0,				in_root,		QString::null }
273 andreas 131
};
132
 
274 andreas 133
SRender::SRender()
273 andreas 134
{
274 andreas 135
	label = 0;
136
	shapePath = QString::null;
137
	XmlPath = QString::null;
138
	Lay = firstLayer = lastLayer = 0;
139
	Style = firstStyle = lastStyle = 0;
273 andreas 140
	Rule = 0;
141
	LineSymbolizer = 0;
142
	PolygonSymbolizer = 0;
143
	TextSymbolizer = 0;
144
	PointSymbolizer = 0;
145
	PolygonPatternSymbolizer = 0;
146
	ShieldSymbolizer = 0;
147
	LinePatternSymbolizer = 0;
275 andreas 148
	_lx = _ly = 180.0;
149
	_rx = _ry = -180.0;
276 andreas 150
	__map_type = MAP_SHAPE;		// The default map type
274 andreas 151
	// This is true, when a XML file was parsed successfully
152
	ControlSet = false;
153
 
154
	// Read settings from config file
155
	KConfig cfg (QString("sportwatcher.rc"), KConfig::SimpleConfig);
156
	KConfigGroup ic (&cfg, "SportWatcher");
157
	KConfigGroup sh (&cfg, "ShapeFile");
158
	QString basePath = ic.readEntry("Data", QDir::home().absolutePath() + "/.sportwatcher");
159
	shapePath = ic.readEntry("MAP", basePath + "/shapefiles");
160
	// Read the shape specific informations
161
#ifdef MAPNIK_PLUGINS
162
	pluginPath = QString(MAPNIK_PLUGINS);
163
#else
164
	// Test some default path
165
	if (dir.exists(QString("/usr/lib/mapnik/input")))
166
	   pluginPath = sh.readEntry("PluginPath", QString("/usr/lib/mapnik/input"));
167
	else if (dir.exists(QString("/usr/local/lib/mapnik/input")))
168
	   pluginPath = sh.readEntry("PluginPath", QString("/usr/local/lib/mapnik/input"));
169
	else if (dir.exists(QString("/usr/lib/mapnik/0.6/input")))
170
	   pluginPath = sh.readEntry("PluginPath", QString("/usr/lib/mapnik/0.6/input"));
171
	else
172
	   pluginPath = sh.readEntry("PluginPath", QString(""));
173
#endif
174
#ifdef MAPNIK_FONTS
175
	fontPath = QString(MAPNIK_FONTS);
176
#else
177
	// Test some default path
178
	if (dir.exists(QString("/usr/lib/mapnik/fonts")))
179
	   fontPath = sh.readEntry("FontPath", QString("/usr/lib/mapnik/fonts"));
180
	else if (dir.exists(QString("/usr/local/lib/mapnik/fonts")))
181
	   fontPath = sh.readEntry("FontPath", QString("/usr/local/lib/mapnik/fonts"));
182
	else if (dir.exists(QString("/usr/share/mapnik/fonts")))
183
	   fontPath = sh.readEntry("FontPath", QString("/usr/share/mapnik/fonts"));
184
	else if (dir.exists(QString("/usr/share/fonts/truetype/ttf-dejavu")))
185
	   fontPath = sh.readEntry("FontPath", QString("/usr/share/fonts/truetype/ttf-dejavu"));
186
	else
187
	   fontPath = sh.readEntry("FontPath", QString(""));
188
#endif
189
	XmlPath = sh.readEntry("XmlFile", basePath + "/shapefiles/osm.xml");
273 andreas 190
}
191
 
274 andreas 192
SRender::~SRender()
273 andreas 193
{
274 andreas 194
	startDocument();	// Clean everything
195
	ControlSet = false;
275 andreas 196
 
197
	if (!OutBuf.isEmpty())
198
	   unlink (OutBuf.toAscii().data());
274 andreas 199
}
273 andreas 200
 
274 andreas 201
bool SRender::startDocument()
202
{
203
	m.remove_all();		// delete styles and layers from map
204
 
273 andreas 205
	if (firstStyle)		// free if allocated
206
	{
207
	   Style = firstStyle;
208
 
209
	   while (Style)
210
	   {
274 andreas 211
	      STYLE *sakt = Style->next;
212
 
273 andreas 213
	      if (Style->rule)
214
	      {
215
		 RULE *rule = Style->rule;
216
 
217
		 while (rule)
218
		 {
219
		    RULE *rakt = rule->next;
220
		    LINESYMBOLIZER *LineSymbolizer = rule->LineSymbolizer;
221
		    POLYGONSYMBOLIZER *PolygonSymbolizer = rule->PolygonSymbolizer;
222
		    TEXTSYMBOLIZER *TextSymbolizer = rule->TextSymbolizer;
223
		    POINTSYMBOLIZER *PointSymbolizer = rule->PointSymbolizer;
224
		    POLYGONPATTERNSYMBOLIZER *PolygonPatternSymbolizer = rule->PolygonPatternSymbolizer;
274 andreas 225
		    SHIELDSYMBOLIZER *ShieldSymbolizer = rule->ShieldSymbolizer;
273 andreas 226
		    LINEPATTERNSYMBOLIZER *LinePatternSymbolizer = rule->LinePatternSymbolizer;
227
 
228
		    while (LineSymbolizer)
229
		    {
230
		       LINESYMBOLIZER *akt = LineSymbolizer->next;
231
		       delete LineSymbolizer;
232
		       LineSymbolizer = akt;
233
		    }
234
 
235
		    while (PolygonSymbolizer)
236
		    {
237
		       POLYGONSYMBOLIZER *akt = PolygonSymbolizer->next;
238
		       delete PolygonSymbolizer;
239
		       PolygonSymbolizer = akt;
240
		    }
241
 
242
		    while (TextSymbolizer)
243
		    {
244
		       TEXTSYMBOLIZER *akt = TextSymbolizer->next;
245
		       delete TextSymbolizer;
246
		       TextSymbolizer = akt;
247
		    }
248
 
249
		    while (PointSymbolizer)
250
		    {
251
		       POINTSYMBOLIZER *akt = PointSymbolizer->next;
252
		       delete PointSymbolizer;
253
		       PointSymbolizer = akt;
254
		    }
255
 
256
		    while (PolygonPatternSymbolizer)
257
		    {
258
		       POLYGONPATTERNSYMBOLIZER *akt = PolygonPatternSymbolizer->next;
259
		       delete PolygonPatternSymbolizer;
260
		       PolygonPatternSymbolizer = akt;
261
		    }
262
 
263
		    while (ShieldSymbolizer)
264
		    {
265
		       SHIELDSYMBOLIZER *akt = ShieldSymbolizer->next;
266
		       delete ShieldSymbolizer;
267
		       ShieldSymbolizer = akt;
268
		    }
269
 
270
		    while (LinePatternSymbolizer)
271
		    {
272
		       LINEPATTERNSYMBOLIZER *akt = LinePatternSymbolizer->next;
273
		       delete LinePatternSymbolizer;
274
		       LinePatternSymbolizer = akt;
275
		    }
276
 
277
		    delete rule;
278
		    rule = rakt;
279
		 }
280
	      }
281
 
282
	      delete Style;
283
	      Style = sakt;
284
	   }
285
	}
286
 
287
	Style = firstStyle = lastStyle = 0;
274 andreas 288
 
289
	if (firstLayer)
290
	{
291
	   Lay = firstLayer;
292
 
293
	   while (Lay)
294
	   {
295
	   LAYER *akt;
296
 
297
	      akt = Lay->next;
298
	      delete Lay;
299
	      Lay = akt;
300
	   }
301
	}
302
 
303
	Lay = firstLayer = lastLayer = 0;
275 andreas 304
	Rule = 0;
305
	LineSymbolizer = 0;
306
	PolygonSymbolizer = 0;
307
	TextSymbolizer = 0;
308
	PointSymbolizer = 0;
309
	PolygonPatternSymbolizer = 0;
310
	ShieldSymbolizer = 0;
311
	LinePatternSymbolizer = 0;
312
	_lx = _ly = 180.0;
313
	_rx = _ry = -180.0;
314
	ControlSet = false;
315
	XmlLine = 1;
274 andreas 316
	Container = in_root;
273 andreas 317
	return true;
318
}
319
 
320
/*
321
 * This is called every time a new start element was parsed.
322
 */
274 andreas 323
bool SRender::startElement( const QString&, const QString&,
273 andreas 324
                                    const QString& qName,
325
                                    const QXmlAttributes& att)
326
{
327
int i = FIRST_CON;
328
int index;
274 andreas 329
QString hv0;
273 andreas 330
 
274 andreas 331
	while (i <= LAST_CON)
273 andreas 332
	{
333
	   if (qName.toLower() == getKey(i).toLower())
334
	   {
274 andreas 335
	      Container = token[i].con;
336
 
273 andreas 337
	      switch (i)
338
	      {
339
		 case CON_MAP:
274 andreas 340
		    Container = in_map;
341
 
342
		    if (ControlSet)	// Must be false here!
343
		    {
275 andreas 344
		       KMessageBox::error(0, i18n("Error parsing %1, line %2: There is another MAP! Only one map information is allowed!").arg(XmlPath).arg(XmlLine));
274 andreas 345
		       return false;
346
		    }
347
 
273 andreas 348
		    if ((index = att.index(QString("bgcolor"))) != -1)
275 andreas 349
		    {
350
		    color col;
351
 
274 andreas 352
		       MapPars.bgcolor = colorToUInt(att.value(index));
275 andreas 353
		       col.set_bgr(MapPars.bgcolor);
354
		       m.set_background(col);
355
		    }
273 andreas 356
 
357
		    if ((index = att.index(QString("buffer_size"))) != -1)
275 andreas 358
		    {
273 andreas 359
		       MapPars.buf_size = att.value(index).toInt();
275 andreas 360
		       m.set_buffer_size(MapPars.buf_size);
361
		    }
273 andreas 362
 
363
		    if ((index = att.index(QString("srs"))) != -1)
275 andreas 364
		    {
273 andreas 365
		       MapPars.srs = att.value(index);
275 andreas 366
		       m.set_srs(MapPars.srs.toAscii().data());
367
		    }
273 andreas 368
		 break;
369
 
370
		 case CON_STYLE:
274 andreas 371
		    Container = in_style;
372
 
273 andreas 373
		    if (!lastStyle)
374
		    {
274 andreas 375
		       Style = allocStyle();
376
		       firstStyle = lastStyle = Style;
273 andreas 377
		    }
378
		    else
379
		    {
274 andreas 380
		       Style = allocStyle();
273 andreas 381
		       lastStyle->next = Style;
382
		       lastStyle = Style;
383
		    }
384
 
385
		    if ((index = att.index(QString("name"))) != -1)
386
		       Style->name = att.value(index);
387
		    else
388
		    {
275 andreas 389
		       KMessageBox::error(0, i18n("Error parsing %1, line %2: Open STYLE without a name!").arg(XmlPath).arg(XmlLine));
273 andreas 390
		       return false;
391
		    }
392
		 break;
393
 
394
		 case CON_RULE:
274 andreas 395
		    Container = in_rule;
396
 
273 andreas 397
		    if (!Style)
398
		    {
275 andreas 399
		       KMessageBox::error(0, i18n("Error parsing %1, line %2: Open RULE outside of a STYLE!").arg(XmlPath).arg(XmlLine));
273 andreas 400
		       return false;
401
		    }
402
 
403
		    Rule = getLastRule (Style->rule);
404
 
405
		    if (!Rule)
406
		    {
274 andreas 407
		       Rule = allocRule();
273 andreas 408
		       Style->rule = Rule;
409
		    }
410
		    else
411
		    {
274 andreas 412
		       Rule->next = allocRule();
273 andreas 413
		       Rule = Rule->next;
414
		    }
276 andreas 415
 
416
		    if ((index = att.index(QString("name"))) != -1)
417
		    {
418
		       Rule->name = att.value(index);
419
		       Rule->rl.set_name(Rule->name.toAscii().data());
420
		    }
421
 
422
		    if ((index = att.index(QString("title"))) != -1)
423
		    {
424
		       Rule->title = att.value(index);
425
		       Rule->rl.set_title(Rule->title.toAscii().data());
426
		    }
273 andreas 427
		 break;
428
 
276 andreas 429
		 case CON_ELSEFILTER:
430
		    Container = in_elsefilter;
431
 
432
		    if (!Rule)
433
		    {
434
		       KMessageBox::error(0, i18n("Error parsing %1, line %2: Open ELSEFILTER outside of a RULE!").arg(XmlPath).arg(XmlLine));
435
		       return false;
436
		    }
437
		 break;
438
 
274 andreas 439
		 case CON_LAYER:
440
		    Container = in_layer;
441
 
442
		    if (!firstLayer)
443
		    {
444
		       Lay = allocLayer();
445
		       firstLayer = lastLayer = Lay;
446
		    }
447
		    else
448
		    {
449
		       Lay = allocLayer();
450
		       lastLayer->next = Lay;
451
		       lastLayer = Lay;
452
		    }
453
 
454
		    if ((index = att.index(QString("name"))) != -1)
455
		       Lay->name = att.value(index);
456
 
457
		    if ((index = att.index(QString("status"))) != -1)
458
		       Lay->status = getBool(att.value(index));
459
 
460
		    if ((index = att.index(QString("srs"))) != -1)
461
		       Lay->srs = att.value(index);
275 andreas 462
 
463
		    if ((index = att.index(QString("minzoom"))) != -1)
464
		       Lay->minzoom = att.value(index).toDouble();
465
 
466
		    if ((index = att.index(QString("maxzoom"))) != -1)
467
		       Lay->maxzoom = att.value(index).toDouble();
276 andreas 468
 
469
		    if ((index = att.index(QString("queryable"))) != -1)
470
		       Lay->queryable = getBool(att.value(index));
471
 
472
		    if ((index = att.index(QString("title"))) != -1)
473
		       Lay->title = att.value(index);
474
 
475
		    if ((index = att.index(QString("abstract"))) != -1)
476
		       Lay->abstract = att.value(index);
477
 
478
		    if ((index = att.index(QString("clear_label_cache"))) != -1)
479
		       Lay->clear_label = getBool(att.value(index));
274 andreas 480
		 break;
481
 
482
		 case CON_DATASOURCE:
483
		    Container = in_datasource;
484
		 break;
485
 
273 andreas 486
		 case CON_POINTSYMBOLIZER:
274 andreas 487
		    Container = in_pointsymbolizer;
488
 
273 andreas 489
		    if (!Rule)
490
		    {
275 andreas 491
		       KMessageBox::error(0, i18n("Error parsing %1, line %2: Open POINTSYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
273 andreas 492
		       return false;
493
		    }
494
 
495
		    PointSymbolizer = getLastPointSymbolizer(Rule->PointSymbolizer);
496
 
497
		    if (!PointSymbolizer)
498
		    {
274 andreas 499
		       PointSymbolizer = allocPointSymbolizer();
273 andreas 500
		       Rule->PointSymbolizer = PointSymbolizer;
501
		    }
502
		    else
503
		    {
274 andreas 504
		       PointSymbolizer->next = allocPointSymbolizer();
273 andreas 505
		       PointSymbolizer = PointSymbolizer->next;
506
		    }
507
 
508
		    if ((index = att.index(QString("file"))) != -1)
509
		       PointSymbolizer->file = att.value(index);
510
 
511
		    if ((index = att.index(QString("type"))) != -1)
274 andreas 512
		       PointSymbolizer->type = getType(att.value(index));
273 andreas 513
 
274 andreas 514
		    if ((index = att.index(QString("width"))) != -1)
273 andreas 515
		       PointSymbolizer->width = att.value(index).toDouble();
516
 
274 andreas 517
		    if ((index = att.index(QString("height"))) != -1)
273 andreas 518
		       PointSymbolizer->height = att.value(index).toDouble();
519
 
274 andreas 520
		    if ((index = att.index(QString("allow_overlap"))) != -1)
276 andreas 521
		       PointSymbolizer->allow_overlap = getBool(att.value(index));
273 andreas 522
		 break;
523
 
524
		 break;
525
 
526
		 case CON_LINESYMBOLIZER:
274 andreas 527
		    Container = in_linesymbolizer;
528
 
273 andreas 529
		    if (!Rule)
530
		    {
275 andreas 531
		       KMessageBox::error(0, i18n("Error parsing %1, line %2: Open LINESYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
273 andreas 532
		       return false;
533
		    }
534
 
535
		    LineSymbolizer = getLastLineSymbolizer(Rule->LineSymbolizer);
536
 
537
		    if (!LineSymbolizer)
538
		    {
274 andreas 539
		       LineSymbolizer = allocLineSymbolizer();
273 andreas 540
		       Rule->LineSymbolizer = LineSymbolizer;
541
		    }
542
		    else
543
		    {
274 andreas 544
		       LineSymbolizer->next = allocLineSymbolizer();
273 andreas 545
		       LineSymbolizer = LineSymbolizer->next;
546
		    }
547
		 break;
548
 
549
		 case CON_POLYGONSYMBOLIZER:
274 andreas 550
		    Container = in_polygonsymbolizer;
551
 
273 andreas 552
		    if (!Rule)
553
		    {
275 andreas 554
		       KMessageBox::error(0, i18n("Error parsing %1, line %2: Open POLYGONSYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
273 andreas 555
		       return false;
556
		    }
557
 
558
		    PolygonSymbolizer = getLastPolygonSymbolizer(Rule->PolygonSymbolizer);
559
 
560
		    if (!PolygonSymbolizer)
561
		    {
274 andreas 562
		       PolygonSymbolizer = allocPolygonSymbolizer();
273 andreas 563
		       Rule->PolygonSymbolizer = PolygonSymbolizer;
564
		    }
565
		    else
566
		    {
274 andreas 567
		       PolygonSymbolizer->next = allocPolygonSymbolizer();
273 andreas 568
		       PolygonSymbolizer = PolygonSymbolizer->next;
569
		    }
570
		 break;
571
 
572
		 case CON_TEXTSYMBOLIZER:
274 andreas 573
		    Container = in_textsymbolizer;
574
 
273 andreas 575
		    if (!Rule)
576
		    {
275 andreas 577
		       KMessageBox::error(0, i18n("Error parsing %1, line %2: Open TEXTSYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
273 andreas 578
		       return false;
579
		    }
580
 
581
		    TextSymbolizer = getLastTextSymbolizer(Rule->TextSymbolizer);
582
 
583
		    if (!TextSymbolizer)
584
		    {
274 andreas 585
		       TextSymbolizer = allocTextSymbolizer();
273 andreas 586
		       Rule->TextSymbolizer = TextSymbolizer;
587
		    }
588
		    else
589
		    {
274 andreas 590
		       TextSymbolizer->next = allocTextSymbolizer();
273 andreas 591
		       TextSymbolizer = TextSymbolizer->next;
592
		    }
593
 
594
		    if ((index = att.index(QString("name"))) != -1)
595
		       TextSymbolizer->name = att.value(index);
596
 
597
		    if ((index = att.index(QString("face_name"))) != -1)
598
		       TextSymbolizer->face_name = att.value(index);
599
 
276 andreas 600
		    if ((index = att.index(QString("placement"))) != -1)
601
		       TextSymbolizer->placement = att.value(index);
602
 
273 andreas 603
		    if ((index = att.index(QString("size"))) != -1)
604
		       TextSymbolizer->size = att.value(index).toDouble();
605
 
606
		    if ((index = att.index(QString("fill"))) != -1)
274 andreas 607
		       TextSymbolizer->fill = colorToUInt(att.value(index));
608
 
609
		    if ((index = att.index(QString("halo_radius"))) != -1)
610
		       TextSymbolizer->halo_radius = att.value(index).toDouble();
611
 
612
		    if ((index = att.index(QString("wrap_width"))) != -1)
613
		       TextSymbolizer->wrap_width = att.value(index).toDouble();
614
 
276 andreas 615
		    if ((index = att.index(QString("alignment"))) != -1)
616
		       TextSymbolizer->alignment = att.value(index);
617
 
275 andreas 618
		    if ((index = att.index(QString("dx"))) != -1)
619
		       TextSymbolizer->dx = att.value(index).toDouble();
620
 
274 andreas 621
		    if ((index = att.index(QString("dy"))) != -1)
622
		       TextSymbolizer->dy = att.value(index).toDouble();
623
 
624
		    if ((index = att.index(QString("max_distance"))) != -1)
625
		       TextSymbolizer->maxdistance = att.value(index).toDouble();
626
 
627
		    if ((index = att.index(QString("min_distance"))) != -1)
628
		       TextSymbolizer->mindistance = att.value(index).toDouble();
273 andreas 629
		 break;
274 andreas 630
 
631
		 case CON_POLYGONPATTERNSYMBOLIZER:
632
		    Container = in_polygonpatternsymbolizer;
633
 
634
		    if (!Rule)
635
		    {
275 andreas 636
		       KMessageBox::error(0, i18n("Error parsing %1, line %2: Open POLYGONPATTERNSYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
274 andreas 637
		       return false;
638
		    }
639
 
640
		    PolygonPatternSymbolizer = getLastPolygonPatternSymbolizer(Rule->PolygonPatternSymbolizer);
641
 
642
		    if (!PolygonPatternSymbolizer)
643
		    {
644
		       PolygonPatternSymbolizer = allocPolygonPatternSymbolizer();
645
		       Rule->PolygonPatternSymbolizer = PolygonPatternSymbolizer;
646
		    }
647
		    else
648
		    {
649
		       PolygonPatternSymbolizer->next = allocPolygonPatternSymbolizer();
650
		       PolygonPatternSymbolizer = PolygonPatternSymbolizer->next;
651
		    }
652
 
653
		    if ((index = att.index(QString("file"))) != -1)
654
		       PolygonPatternSymbolizer->file = att.value(index);
655
 
656
		    if ((index = att.index(QString("type"))) != -1)
657
		       PolygonPatternSymbolizer->type = getType(att.value(index));
658
 
659
		    if ((index = att.index(QString("width"))) != -1)
660
		       PolygonPatternSymbolizer->width = att.value(index).toDouble();
661
 
662
		    if ((index = att.index(QString("height"))) != -1)
663
		       PolygonPatternSymbolizer->height = att.value(index).toDouble();
664
 
665
		    if ((index = att.index(QString("allow_overlap"))) != -1)
666
		       PolygonPatternSymbolizer->allow_overlap = getBool(att.value(index));
667
		 break;
668
 
669
		 case CON_SHIELDSYMBOLIZER:
670
		    Container = in_shieldsymbolizer;
671
 
672
		    if (!Rule)
673
		    {
275 andreas 674
		       KMessageBox::error(0, i18n("Error parsing %1, line %2: Open SHIELDSYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
274 andreas 675
		       return false;
676
		    }
677
 
678
		    ShieldSymbolizer = getLastShieldSymbolizer(Rule->ShieldSymbolizer);
679
 
680
		    if (!ShieldSymbolizer)
681
		    {
682
		       ShieldSymbolizer = allocShieldSymbolizer();
683
		       Rule->ShieldSymbolizer = ShieldSymbolizer;
684
		    }
685
		    else
686
		    {
687
		       ShieldSymbolizer->next = allocShieldSymbolizer();
688
		       ShieldSymbolizer = ShieldSymbolizer->next;
689
		    }
690
 
691
		    if ((index = att.index(QString("name"))) != -1)
692
		       ShieldSymbolizer->name = att.value(index);
693
 
694
		    if ((index = att.index(QString("face_name"))) != -1)
695
		       ShieldSymbolizer->face_name = att.value(index);
696
 
697
		    if ((index = att.index(QString("fill"))) != -1)
698
		       ShieldSymbolizer->fill = colorToUInt(att.value(index));
699
 
700
		    if ((index = att.index(QString("placement"))) != -1)
701
		       ShieldSymbolizer->placement = att.value(index);
702
 
703
		    if ((index = att.index(QString("file"))) != -1)
704
		       ShieldSymbolizer->file = att.value(index);
705
 
706
		    if ((index = att.index(QString("type"))) != -1)
707
		       ShieldSymbolizer->type = getType(att.value(index));
708
 
709
		    if ((index = att.index(QString("size"))) != -1)
710
		       ShieldSymbolizer->size = att.value(index).toDouble();
711
 
712
		    if ((index = att.index(QString("width"))) != -1)
713
		       ShieldSymbolizer->width = att.value(index).toDouble();
714
 
715
		    if ((index = att.index(QString("height"))) != -1)
716
		       ShieldSymbolizer->height = att.value(index).toDouble();
717
 
275 andreas 718
		    if ((index = att.index(QString("dx"))) != -1)
719
		       ShieldSymbolizer->dx = att.value(index).toDouble();
720
 
721
		    if ((index = att.index(QString("dy"))) != -1)
722
		       ShieldSymbolizer->dy = att.value(index).toDouble();
723
 
274 andreas 724
		    if ((index = att.index(QString("min_distance"))) != -1)
725
		       ShieldSymbolizer->mindistance = att.value(index).toDouble();
726
 
727
		    if ((index = att.index(QString("max_distance"))) != -1)
728
		       ShieldSymbolizer->maxdistance = att.value(index).toDouble();
729
		 break;
730
 
731
		 case CON_LINEPATTERNSYMBOLIZER:
732
		    Container = in_linepatternsymbolizer;
733
 
734
		    if (!Rule)
735
		    {
275 andreas 736
		       KMessageBox::error(0, i18n("Error parsing %1, line %2: Open LINEPATTERNSYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
274 andreas 737
		       return false;
738
		    }
739
 
740
		    LinePatternSymbolizer = getLastLinePatternSymbolizer(Rule->LinePatternSymbolizer);
741
 
742
		    if (!LinePatternSymbolizer)
743
		    {
744
		       LinePatternSymbolizer = allocLinePatternSymbolizer();
745
		       Rule->LinePatternSymbolizer = LinePatternSymbolizer;
746
		    }
747
		    else
748
		    {
749
		       LinePatternSymbolizer->next = allocLinePatternSymbolizer();
750
		       LinePatternSymbolizer = LinePatternSymbolizer->next;
751
		    }
752
 
753
		    if ((index = att.index(QString("file"))) != -1)
754
		       LinePatternSymbolizer->file = att.value(index);
755
 
756
		    if ((index = att.index(QString("type"))) != -1)
757
		       LinePatternSymbolizer->type = getType(att.value(index));
758
 
759
		    if ((index = att.index(QString("width"))) != -1)
760
		       LinePatternSymbolizer->width = att.value(index).toDouble();
761
 
762
		    if ((index = att.index(QString("height"))) != -1)
763
		       LinePatternSymbolizer->height = att.value(index).toDouble();
764
		 break;
765
	      }
766
	   }
767
 
768
	   i++;
273 andreas 769
	}
274 andreas 770
 
771
	i = FIRST_FLD;
772
 
773
	while (i <= LAST_FLD)
774
	{
775
	   if (qName.toLower() == getKey(i).toLower())
776
	   {
777
	      Field = i;
778
 
779
	      switch(Container)
780
	      {
781
		 case in_linesymbolizer:
782
		    Names = empty;
783
 
784
		    if (i == FLD_CSSPARAMETER)
785
		    {
786
		       if ((index = att.index(QString("name"))) != -1)
787
		       {
788
			  if (att.value(index).toLower() == QString("stroke"))
789
			     Names = stroke_stroke;
790
			  else if (att.value(index).toLower() == QString("stroke-width"))
791
			     Names = stroke_width;
792
			  else if (att.value(index).toLower() == QString("stroke-opacity"))
793
			     Names = stroke_opacity;
794
			  else if (att.value(index).toLower() == QString("stroke-linejoin"))
795
			     Names = stroke_linejoin;
796
			  else if (att.value(index).toLower() == QString("stroke-linecap"))
797
			     Names = stroke_linecap;
798
			  else if (att.value(index).toLower() == QString("stroke-dasharray"))
799
			     Names = stroke_dasharray;
800
		       }
801
		       else
802
		       {
275 andreas 803
			  KMessageBox::error(0, i18n("Error parsing %1, line %2: Required attribute NAME is missing in CSSPARAMETER inside LINESYMBOLIZER!").arg(XmlPath).arg(XmlLine));
274 andreas 804
			  return false;
805
		       }
806
		    }
807
		 break;
808
 
809
		 case in_polygonsymbolizer:
810
		    Names = empty;
811
 
812
		    if (i == FLD_CSSPARAMETER)
813
		    {
814
		       if ((index = att.index(QString("name"))) != -1)
815
		       {
816
			  if (att.value(index).toLower() == QString("fill"))
817
			     Names = fill;
818
			  else if (att.value(index).toLower() == QString("fill-opacity"))
819
			     Names = fill_opacity;
820
		       }
821
		       else
822
		       {
275 andreas 823
			  KMessageBox::error(0, i18n("Error parsing %1, line %2: Required attribute NAME is missing in CSSPARAMETER inside POLYGONSYMBOLIZER!").arg(XmlPath).arg(XmlLine));
274 andreas 824
			  return false;
825
		       }
826
		    }
827
		 break;
828
 
829
		 case in_datasource:
830
		    Names = empty;
831
 
832
		    if (i == FLD_PARAMETER)
833
		    {
834
		       if ((index = att.index(QString("name"))) != -1)
835
		       {
836
			  if (att.value(index).toLower() == QString("type"))
837
			     Names = type;
838
			  else if (att.value(index).toLower() == QString("file"))
839
			     Names = file;
840
			  else if (att.value(index).toLower() == QString("host"))
841
			     Names = host;
842
			  else if (att.value(index).toLower() == QString("user"))
843
			     Names = user;
844
			  else if (att.value(index).toLower() == QString("dbname"))
845
			     Names = dbname;
846
			  else if (att.value(index).toLower() == QString("table"))
847
			     Names = table;
848
			  else if (att.value(index).toLower() == QString("estimate_extent"))
849
			     Names = estimate_extent;
850
			  else if (att.value(index).toLower() == QString("extent"))
851
			     Names = extent;
276 andreas 852
			  else if (att.value(index).toLower() == QString("parser"))
853
			     Names = parser__;
854
			  else if (att.value(index).toLower() == QString("url"))
855
			     Names = url;
856
			  else if (att.value(index).toLower() == QString("bbox"))
857
			     Names = bbox;
274 andreas 858
		       }
859
		       else
860
		       {
275 andreas 861
			  KMessageBox::error(0, i18n("Error parsing %1, line %2: Required attribute NAME is missing in PARAMETER inside DATASOURCE!").arg(XmlPath).arg(XmlLine));
274 andreas 862
			  return false;
863
		       }
864
		    }
865
		 break;
866
 
867
		 case in_root:
868
		    Names = empty;
869
		 break;
870
		 case in_map:
871
		    Names = empty;
872
		 break;
873
		 case in_style:
874
		    Names = empty;
875
		 break;
876
		 case in_rule:
877
		    Names = empty;
878
		 break;
879
		 case in_pointsymbolizer:
880
		    Names = empty;
881
		 break;
882
		 case in_textsymbolizer:
883
		    Names = empty;
884
		 break;
885
		 case in_polygonpatternsymbolizer:
886
		    Names = empty;
887
		 break;
888
		 case in_layer:
889
		    Names = empty;
890
		 break;
891
		 case in_symbolizer:
892
		    Names = empty;
893
		 break;
894
		 case in_shieldsymbolizer:
895
		    Names = empty;
896
		 break;
897
		 case in_linepatternsymbolizer:
898
		    Names = empty;
899
		 break;
276 andreas 900
		 case in_elsefilter:
901
		    Names = empty;
902
		 break;
274 andreas 903
	      }
904
	   }
905
 
906
	   i++;
907
	}
908
 
909
	return true;
273 andreas 910
}
911
 
912
/*
913
 * This is called every time an element is closed.
914
 */
274 andreas 915
bool SRender::endElement( const QString&, const QString&, const QString& qName)
273 andreas 916
{
274 andreas 917
	if (qName.toLower() == QString("datasource"))
918
	   Container = in_layer;
919
	else if (qName.toLower() == QString("layer"))
920
	{
921
	   parameters p;
922
	   Container = in_map;
923
 
276 andreas 924
	   if (Lay->Datasource.type.toLower() == QString("shape") && __map_type == MAP_SHAPE)
274 andreas 925
	   {
276 andreas 926
	   QFileInfo qdi(Lay->Datasource.file);
927
	   QString hv0;
928
 
929
	      hv0 = qdi.fileName();
930
 
931
	      if (shapePath.right(1) == QChar('/'))
932
		 hv0 = shapePath + hv0;
933
	      else
934
		 hv0 = shapePath + "/" + hv0;
935
 
274 andreas 936
	      p["type"] = "shape";
276 andreas 937
	      p["file"] = hv0.toAscii().data();
274 andreas 938
	   }
276 andreas 939
	   else if (Lay->Datasource.type.toLower() == QString("postgis") && __map_type == MAP_GIS)
274 andreas 940
	   {
941
	      p["type"] = "postgis";
276 andreas 942
	      p["host"] = Lay->Datasource.host.toAscii().data();
943
	      p["user"] = Lay->Datasource.user.toAscii().data();
944
	      p["dbname"] = Lay->Datasource.dbname.toAscii().data();
945
	      p["table"] = Lay->Datasource.table.toAscii().data();
274 andreas 946
	      p["estimate_extent"] = (Lay->Datasource.estimate_extent) ? "true" : "false";
947
	      p["extent"] = QString("%1,%2,%3,%4").arg(Lay->Datasource.ext_lx).arg(Lay->Datasource.ext_ly).arg(Lay->Datasource.ext_rx).arg(Lay->Datasource.ext_ry).toAscii().data();
948
	   }
276 andreas 949
	   else if (Lay->Datasource.type.toAscii() == QString("osm") && __map_type == MAP_OSM)
950
	   {
951
	      p["type"] = "osm";
952
 
953
	      if (Lay->Datasource.parser.length() <= 0)
954
		 p["parser"] = "libxml2";
955
	      else
956
		 p["parser"] = Lay->Datasource.parser.toAscii().data();
957
 
958
	      if (!Lay->Datasource.url.isEmpty() && !Lay->Datasource.bbox.isEmpty())
959
	      {
960
		 p["url"] = Lay->Datasource.url.toAscii().data();
961
		 p["bbox"] = Lay->Datasource.bbox.toAscii().data();
962
	      }
963
	      else
964
		 p["file"] = shapePath.toAscii().data();
965
	   }
274 andreas 966
	   else
967
	   {
275 andreas 968
	      cerr << "Warning file " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Layer with no source! Ingnoring!" << endl;
274 andreas 969
	      return true;
970
	   }
971
 
972
	   Layer lyr(Lay->name.toAscii().data());
276 andreas 973
 
974
	   if (!Lay->title.isEmpty())
975
	      lyr.set_title(Lay->title.toAscii().data());
976
 
977
	   if (!Lay->abstract.isEmpty())
978
	      lyr.set_abstract(Lay->abstract.toAscii().data());
979
 
274 andreas 980
	   lyr.set_datasource(datasource_cache::instance()->create(p));
981
 
276 andreas 982
	   if (!Lay->srs.isEmpty())
983
	      lyr.set_srs(Lay->srs.toAscii().data());
984
 
275 andreas 985
	   if (Lay->minzoom > 0.0)
986
	      lyr.setMinZoom(Lay->minzoom);
987
 
988
	   if (Lay->maxzoom > 0.0)
989
	      lyr.setMaxZoom(Lay->maxzoom);
990
 
276 andreas 991
	   lyr.set_clear_label_cache(Lay->clear_label);
274 andreas 992
 
993
	   // Add the styles
994
	   for (int i = 0; i < Lay->Styles.size(); i++)
275 andreas 995
	   {
996
	      if (findStyle (Lay->Styles.at(i)) != 0)
276 andreas 997
		 lyr.add_style(Lay->Styles.at(i).toAscii().data());
275 andreas 998
	      else
999
		 cerr << "Warning file " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Style \"" << Lay->Styles.at(i).toAscii().data() << "\" does not exist!" << endl;
1000
	   }
274 andreas 1001
 
275 andreas 1002
	   lyr.setActive(Lay->status);
276 andreas 1003
	   lyr.setQueryable(true);
274 andreas 1004
	   m.addLayer(lyr);
275 andreas 1005
	   Envelope <double>le(lyr.envelope());
1006
	   setMaxExtent(le.minx(), le.miny(), le.maxx(), le.maxy());
274 andreas 1007
	}
1008
	else if (qName.toLower() == QString("map"))
1009
	{
1010
	   Container = in_root;
1011
	   ControlSet = true;
1012
	}
275 andreas 1013
	else if (qName.toLower() == QString("pointsymbolizer"))
1014
	{
274 andreas 1015
	   Container = in_rule;
275 andreas 1016
 
1017
	   if (!Rule || !PointSymbolizer)
1018
	   {
1019
	      KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of POINTSYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
1020
	      return false;
1021
	   }
1022
 
1023
	   if (PointSymbolizer->file.length() == 0 || PointSymbolizer->width == 0 || PointSymbolizer->height == 0)
1024
	   {
1025
	      cerr << "Warning file " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Empty POINTSYMBOLIZER!" << endl;
1026
	      point_symbolizer psym;
1027
	      Rule->rl.append(psym);
1028
	   }
1029
	   else
1030
	   {
276 andreas 1031
	      point_symbolizer ps(findIcon(PointSymbolizer->file).toAscii().data(), getTypeText(PointSymbolizer->type), PointSymbolizer->width, PointSymbolizer->height);
275 andreas 1032
	      ps.set_allow_overlap (PointSymbolizer->allow_overlap);
1033
	      Rule->rl.append(ps);
1034
	   }
1035
	}
1036
	else if (qName.toLower() == QString("linesymbolizer"))
274 andreas 1037
	{
275 andreas 1038
	   Container = in_rule;
274 andreas 1039
 
275 andreas 1040
	   if (!Rule || !LineSymbolizer)
274 andreas 1041
	   {
275 andreas 1042
	      KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of LINESYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
1043
	      return false;
1044
	   }
274 andreas 1045
 
275 andreas 1046
	   stroke st;
1047
	   color col;
1048
	   col.set_bgr(LineSymbolizer->stroke);
274 andreas 1049
 
275 andreas 1050
	   st.set_color (col);
274 andreas 1051
 
275 andreas 1052
	   if (LineSymbolizer->stroke_width != 0.0)
1053
	      st.set_width (LineSymbolizer->stroke_width);
274 andreas 1054
 
275 andreas 1055
	   if (!LineSymbolizer->stroke_linejoin.isEmpty())
1056
	   {
1057
	      if (LineSymbolizer->stroke_linejoin.toLower() == QString("miter"))
1058
		 st.set_line_join (mapnik::MITER_JOIN);
1059
	      else if (LineSymbolizer->stroke_linejoin.toLower() == QString("miter_revert") ||
1060
			 LineSymbolizer->stroke_linejoin.toLower() == QString("miter-revert"))
1061
		 st.set_line_join (mapnik::MITER_REVERT_JOIN);
1062
	      else if (LineSymbolizer->stroke_linejoin.toLower() == QString("round"))
1063
		 st.set_line_join (mapnik::ROUND_JOIN);
1064
	      else if (LineSymbolizer->stroke_linejoin.toLower() == QString("bevel"))
1065
		 st.set_line_join (mapnik::BEVEL_JOIN);
1066
	      else
1067
		 cerr << "Error parsing " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Unknown >>line_join<< \"" << LineSymbolizer->stroke_linejoin.toAscii().data() << "\" --> ignoring!" << endl;
1068
	   }
274 andreas 1069
 
275 andreas 1070
	   if (!LineSymbolizer->stroke_linecap.isEmpty())
1071
	   {
1072
	      if (LineSymbolizer->stroke_linecap.toLower() == QString("butt"))
1073
		st.set_line_cap (mapnik::BUTT_CAP);
1074
	      else if (LineSymbolizer->stroke_linecap.toLower() == QString("square"))
1075
		st.set_line_cap (mapnik::SQUARE_CAP);
1076
	      else if (LineSymbolizer->stroke_linecap.toLower() == QString("round"))
1077
		st.set_line_cap (mapnik::ROUND_CAP);
1078
	      else
1079
		 cerr << "Error parsing " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Unknown >>line_cap<< \"" << LineSymbolizer->stroke_linecap.toAscii().data() << "\" --> ignoring!" << endl;
1080
	   }
274 andreas 1081
 
275 andreas 1082
	   if (LineSymbolizer->stroke_dasharray[0] > 0 || LineSymbolizer->stroke_dasharray[1] > 0)
1083
	      st.add_dash(LineSymbolizer->stroke_dasharray[0], LineSymbolizer->stroke_dasharray[1]);
274 andreas 1084
 
275 andreas 1085
	   if (LineSymbolizer->stroke_opacity != 0)
1086
	      st.set_opacity(LineSymbolizer->stroke_opacity);
274 andreas 1087
 
275 andreas 1088
	   Rule->rl.append(line_symbolizer(st));
1089
	}
1090
	else if (qName.toLower() == QString("polygonsymbolizer"))
1091
	{
1092
	   Container = in_rule;
274 andreas 1093
 
275 andreas 1094
	   if (!Rule || !PolygonSymbolizer)
1095
	   {
1096
	      KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of POLYGONSYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
1097
	      return false;
1098
	   }
274 andreas 1099
 
275 andreas 1100
	   color col;
1101
	   col.set_bgr(PolygonSymbolizer->fill);
274 andreas 1102
 
275 andreas 1103
	   polygon_symbolizer ps(col);
274 andreas 1104
 
275 andreas 1105
	   if (PolygonSymbolizer->fill_opacity > 0.0)
1106
	      ps.set_opacity(PolygonSymbolizer->fill_opacity);
274 andreas 1107
 
275 andreas 1108
	   Rule->rl.append(ps);
1109
	}
1110
	else if (qName.toLower() == QString("textsymbolizer"))
1111
	{
1112
	   Container = in_rule;
274 andreas 1113
 
275 andreas 1114
	   if (!Rule || !TextSymbolizer)
1115
	   {
1116
	      KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of TEXTSYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
1117
	      return false;
1118
	   }
274 andreas 1119
 
275 andreas 1120
	   color col;
1121
	   col.set_bgr(TextSymbolizer->fill);
274 andreas 1122
 
276 andreas 1123
	   if (TextSymbolizer->name.length() <= 0 || TextSymbolizer->face_name.length() <= 0 || TextSymbolizer->size <= 0)
1124
	      cerr << "Error parsing " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Empty TEXTSYMBOLIZER found --> ignoring!" << endl;
1125
	   else
1126
	   {
1127
	      text_symbolizer ts(TextSymbolizer->name.toAscii().data(), TextSymbolizer->face_name.toAscii().data(), TextSymbolizer->size, col);
274 andreas 1128
 
276 andreas 1129
	      if (TextSymbolizer->halo_radius != 0.0)
1130
		 ts.set_halo_radius((unsigned int)TextSymbolizer->halo_radius);
274 andreas 1131
 
276 andreas 1132
	      if (TextSymbolizer->wrap_width != 0.0)
1133
		 ts.set_wrap_width((unsigned int)TextSymbolizer->wrap_width);
274 andreas 1134
 
276 andreas 1135
	      if (TextSymbolizer->mindistance != 0)
1136
		 ts.set_label_spacing(TextSymbolizer->mindistance);
274 andreas 1137
 
276 andreas 1138
	      if (!TextSymbolizer->placement.isEmpty())
1139
	      {
1140
		 if (TextSymbolizer->placement.toLower() == QString("point"))
1141
		    ts.set_label_placement(mapnik::POINT_PLACEMENT);
1142
		 else if (TextSymbolizer->placement.toLower() == QString("line"))
1143
		    ts.set_label_placement(mapnik::LINE_PLACEMENT);
1144
		 else
1145
		    cerr << "Error parsing " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Unknown >>label placement<< \"" << TextSymbolizer->placement.toAscii().data() << "\" --> ignoring!" << endl;
1146
	      }
274 andreas 1147
 
276 andreas 1148
	      if (!TextSymbolizer->alignment.isEmpty())
1149
	      {
1150
		 if (TextSymbolizer->alignment.toLower() == QString("top"))
1151
		    ts.set_vertical_alignment(mapnik::TOP);
1152
		 else if (TextSymbolizer->alignment.toLower() == QString("middle"))
1153
		    ts.set_vertical_alignment(mapnik::MIDDLE);
1154
		 else if (TextSymbolizer->alignment.toLower() == QString("bottom"))
1155
		    ts.set_vertical_alignment(mapnik::BOTTOM);
1156
		 else
1157
		    cerr << "Error parsing " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Unknown >>vertical placement<< \"" << TextSymbolizer->alignment.toAscii().data() << "\" --> ignoring!" << endl;
1158
	      }
1159
 
1160
	      if (TextSymbolizer->dx != 0 || TextSymbolizer->dy != 0)
1161
		 ts.set_displacement(TextSymbolizer->dx, TextSymbolizer->dy);
1162
 
1163
	      Rule->rl.append(ts);
1164
	   }
275 andreas 1165
	}
1166
	else if (qName.toLower() == QString("polygonpatternsymbolizer"))
1167
	{
1168
	   Container = in_rule;
274 andreas 1169
 
275 andreas 1170
	   if (!Rule || !PolygonPatternSymbolizer)
1171
	   {
1172
	      KMessageBox::error(0, i18n("Error parsing %1, line %2: Endin of POLYGONPATTERNSYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
1173
	      return false;
1174
	   }
274 andreas 1175
 
276 andreas 1176
	   if (PolygonPatternSymbolizer->file.length() <= 0)
1177
	      cerr << "Error parsing " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Incomplete POLYGONPATTERNSYMBOLIZER --> ignoring!" << endl;
1178
	   else
1179
	   {
1180
	      Rule->rl.append(polygon_pattern_symbolizer(findIcon(PolygonPatternSymbolizer->file).toAscii().data(),
275 andreas 1181
						getTypeText(PolygonPatternSymbolizer->type),
1182
						PolygonPatternSymbolizer->width,
1183
						PolygonPatternSymbolizer->height));
276 andreas 1184
	   }
275 andreas 1185
	}
1186
	else if (qName.toLower() == QString("shieldsymbolizer"))
1187
	{
1188
	   Container = in_rule;
274 andreas 1189
 
275 andreas 1190
	   if (!Rule || !ShieldSymbolizer)
1191
	   {
1192
	      KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of SHIELDSYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
1193
	      return false;
1194
	   }
274 andreas 1195
 
275 andreas 1196
	   color col;
1197
	   col.set_bgr(ShieldSymbolizer->fill);
1198
	   shield_symbolizer ss(ShieldSymbolizer->name.toAscii().data(),
1199
				ShieldSymbolizer->face_name.toAscii().data(),
1200
				ShieldSymbolizer->size, col,
1201
				findIcon(ShieldSymbolizer->file).toAscii().data(),
1202
				getTypeText(ShieldSymbolizer->type),
1203
				ShieldSymbolizer->width, ShieldSymbolizer->height);
1204
 
1205
	   if (!ShieldSymbolizer->placement.isEmpty())
1206
	      ss.set_label_placement((ShieldSymbolizer->placement.toLower() == QString("point")) ? mapnik::POINT_PLACEMENT : mapnik::LINE_PLACEMENT);
1207
 
1208
	   if (ShieldSymbolizer->dx != 0 || ShieldSymbolizer->dy != 0)
1209
	      ss.set_displacement(ShieldSymbolizer->dx, ShieldSymbolizer->dy);
1210
 
1211
	   if (ShieldSymbolizer->mindistance != 0)
1212
	      ss.set_label_spacing(ShieldSymbolizer->mindistance);
1213
 
1214
	   Rule->rl.append(ss);
1215
	}
1216
	else if (qName.toLower() == QString("linepatternsymbolizer"))
1217
	{
1218
	   Container = in_rule;
1219
 
1220
	   if (!Rule || !LinePatternSymbolizer)
1221
	   {
1222
	      KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of LINEPATTERNSYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
1223
	      return false;
1224
	   }
1225
 
1226
	   Rule->rl.append(line_pattern_symbolizer(findIcon(LinePatternSymbolizer->file).toAscii().data(),
1227
						getTypeText(LinePatternSymbolizer->type),
1228
						LinePatternSymbolizer->width,
1229
						LinePatternSymbolizer->height));
1230
	}
1231
	else if (qName.toLower() == QString("filter") ||
1232
		 qName.toLower() == QString("maxscaledenominator") ||
1233
		 qName.toLower() == QString("minscaledenominator"))
1234
	   Container = in_rule;
1235
	else if (qName.toLower() == QString("rule"))
1236
	   Container = in_style;
276 andreas 1237
	else if (qName.toLower() == QString("elsefilter"))
1238
	{
1239
	   Container = in_rule;
1240
 
1241
	   if (!Rule)
1242
	   {
1243
	      KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of ELSEFILTER outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
1244
	      return false;
1245
	   }
1246
 
1247
	   Rule->rl.set_else(true);
1248
	}
275 andreas 1249
	else if (qName.toLower() == QString("style"))
1250
	{
1251
	   Container = in_map;
1252
	   feature_type_style style;
1253
 
1254
	   if (Style->rule)
1255
	   {
1256
	      Rule = Style->rule;
1257
 
1258
	      while (Rule)
1259
	      {
1260
		 style.add_rule(Rule->rl);
274 andreas 1261
		 Rule = Rule->next;
1262
	      }
1263
	   }
1264
 
1265
	   // Add style to map
1266
	   m.insert_style(Style->name.toAscii().data(), style);
1267
	}
1268
 
1269
	return true;
273 andreas 1270
}
1271
 
1272
/*
1273
 * The reader calls this function when it has parsed a chunk of character data
1274
 * - either normal character data or character data inside a CDATA section.
1275
 */
275 andreas 1276
bool SRender::characters (const QString& chraw)
273 andreas 1277
{
276 andreas 1278
	if (chraw.at(0) == QChar('\n'))
1279
	{
1280
	   XmlLine++;
1281
	   return true;
1282
	}
1283
 
275 andreas 1284
	QString ch = chraw.trimmed();
1285
 
1286
	if (ch.length() == 0)
274 andreas 1287
	   return true;
1288
 
1289
	if (Container == in_rule && Rule)
1290
	{
1291
	   if (Field == FLD_FILTER)
275 andreas 1292
	   {
274 andreas 1293
	      Rule->filter = ch;
275 andreas 1294
 
1295
	      if (!Rule->filter.isEmpty())
276 andreas 1296
		 Rule->rl.set_filter(create_filter(Rule->filter.toLatin1().data(), "latin1"));
275 andreas 1297
	      else
1298
		 cerr << "Warning in file " << XmlPath.toAscii().data() << " at line " << XmlLine << ": Ignoring empty filter!" << endl;
1299
	   }
274 andreas 1300
	   else if (Field == FLD_MAXSCALE)
275 andreas 1301
	   {
274 andreas 1302
	      Rule->maxscale = ch.toDouble();
275 andreas 1303
	      Rule->rl.set_max_scale(Rule->maxscale);
1304
	   }
274 andreas 1305
	   else if (Field == FLD_MINSCALE)
275 andreas 1306
	   {
274 andreas 1307
	      Rule->minscale = ch.toDouble();
275 andreas 1308
	      Rule->rl.set_min_scale(Rule->minscale);
1309
	   }
274 andreas 1310
	}
1311
	else if (Container == in_linesymbolizer && LineSymbolizer)
1312
	{
1313
	   if (Field == FLD_CSSPARAMETER)
1314
	   {
1315
	      if (Names == stroke_stroke)
1316
		 LineSymbolizer->stroke = colorToUInt(ch);
1317
	      else if (Names == stroke_width)
1318
		 LineSymbolizer->stroke_width = ch.toDouble();
1319
	      else if (Names == stroke_linejoin)
1320
		 LineSymbolizer->stroke_linejoin = ch;
1321
	      else if (Names == stroke_linecap)
1322
		 LineSymbolizer->stroke_linecap = ch;
1323
	      else if (Names == stroke_opacity)
1324
		 LineSymbolizer->stroke_opacity = ch.toDouble();
1325
	      else if (Names == stroke_dasharray)
1326
	      {
1327
	      int pos;
1328
	      QString arr = ch;
1329
	      QStringList list;
1330
 
1331
		 list = arr.split(",", QString::SkipEmptyParts);
1332
 
1333
		 for (pos = 0; pos < list.size() && pos < 10; pos++)
1334
		    LineSymbolizer->stroke_dasharray[pos] = list.at(pos).toDouble();
1335
 
1336
		 LineSymbolizer->stroke_anz = pos;
1337
	      }
1338
	   }
1339
	}
1340
	else if (Container == in_polygonsymbolizer && PolygonSymbolizer)
1341
	{
1342
	   if (Field == FLD_CSSPARAMETER)
1343
	   {
1344
	      if (Names == fill)
1345
		 PolygonSymbolizer->fill = colorToUInt(ch);
1346
	      else if (Names == fill_opacity)
1347
		 PolygonSymbolizer->fill_opacity = ch.toDouble();
1348
	   }
1349
	}
1350
	else if (Container == in_layer && Lay)
1351
	{
1352
	   if (Field == FLD_STYLENAME)
1353
	      Lay->Styles << ch;
1354
	}
1355
	else if (Container == in_datasource && Lay)
1356
	{
1357
	   if (Field == FLD_PARAMETER)
1358
	   {
1359
	      if (Names == type)
1360
		 Lay->Datasource.type = ch;
1361
	      else if (Names == file)
275 andreas 1362
	      {
1363
	      QFileInfo qf(ch);
1364
	      QString hv0;
1365
 
1366
		 hv0 = shapePath;
1367
 
1368
		 if (hv0.right(1) != QString("/"))
1369
		    hv0 += "/";
1370
 
1371
		 hv0 += qf.fileName();
1372
 
276 andreas 1373
		 if (__map_type == MAP_SHAPE)
1374
		    qf.setFile (hv0 + ".shp");
1375
		 else if (__map_type == MAP_OSM)
1376
		    qf.setFile (hv0 + ".osm");
1377
 
275 andreas 1378
		 if (!qf.exists())
1379
		 {
276 andreas 1380
		    if (__map_type == MAP_SHAPE)
1381
		       KMessageBox::error(0, i18n("The shape file \"%1\" at line %2 does not exist!").arg(hv0+".shp").arg(XmlLine));
1382
		    else if (__map_type == MAP_OSM)
1383
		       KMessageBox::error(0, i18n("The OSM file \"%1\" at line %2 does not exist!").arg(hv0+".osm").arg(XmlLine));
1384
 
275 andreas 1385
		    return false;
1386
		 }
1387
 
1388
		 Lay->Datasource.file = hv0;
1389
	      }
276 andreas 1390
	      else if (Names == parser__)
1391
		 Lay->Datasource.parser = ch;
1392
	      else if (Names == url)
1393
		 Lay->Datasource.url = ch;
1394
	      else if (Names == bbox)
1395
		 Lay->Datasource.bbox = ch;
274 andreas 1396
	      else if (Names == host)
1397
		 Lay->Datasource.host = ch;
1398
	      else if (Names == user)
1399
		 Lay->Datasource.user = ch;
1400
	      else if (Names == dbname)
1401
		 Lay->Datasource.dbname = ch;
1402
	      else if (Names == table)
1403
		 Lay->Datasource.table = ch;
1404
	      else if (Names == estimate_extent)
1405
		 Lay->Datasource.estimate_extent = getBool(ch);
1406
	      else if (Names == extent)
1407
	      {
1408
		 QString arr = ch;
1409
		 QStringList list;
1410
		 list = arr.split(",");
275 andreas 1411
 
1412
		 if (list.size() >= 1)
1413
		    Lay->Datasource.ext_lx = list.at(0).toDouble();
1414
 
1415
		 if (list.size() >= 2)
1416
		    Lay->Datasource.ext_ly = list.at(1).toDouble();
1417
 
1418
		 if (list.size() >= 3)
1419
		    Lay->Datasource.ext_rx = list.at(2).toDouble();
1420
 
1421
		 if (list.size() >= 4)
1422
		    Lay->Datasource.ext_ry = list.at(3).toDouble();
274 andreas 1423
	      }
1424
	   }
1425
	}
1426
 
1427
	return true;
273 andreas 1428
}
1429
 
274 andreas 1430
QString SRender::getKey (int pos)
273 andreas 1431
{
1432
int i = 0;
1433
 
274 andreas 1434
	while (token[i].id > 0)
273 andreas 1435
	{
274 andreas 1436
	   if (token[i].id == pos)
1437
	      return token[i].name;
273 andreas 1438
 
1439
	   i++;
1440
	}
1441
 
1442
	return QString::null;
1443
}
1444
 
274 andreas 1445
TYPES SRender::getType(QString ty)
273 andreas 1446
{
274 andreas 1447
	if (ty.toLower() == QString("png"))
1448
	   return type_png;
1449
	else if (ty.toLower() == QString("gif"))
1450
	   return type_gif;
1451
	else if (ty.toLower() == QString("jpg"))
1452
	   return type_jpg;
1453
	else if (ty.toLower() == QString("xpm"))
1454
	   return type_xpm;
1455
	else if (ty.toLower() == QString("bmp"))
1456
	   return type_bmp;
1457
	else if (ty.toLower() == QString("tif") || ty.toLower() == QString("tiff"))
1458
	   return type_tif;
273 andreas 1459
 
274 andreas 1460
	return type_png;
1461
}
273 andreas 1462
 
274 andreas 1463
char *grTypes[] = { (char *)"png", (char *)"gif", (char *)"jpg", (char*)"xpm",
1464
		    (char *)"bmp", (char *)"tif" };
273 andreas 1465
 
274 andreas 1466
char *SRender::getTypeText(TYPES type)
1467
{
1468
	switch (type)
1469
	{
1470
	   case type_png: return grTypes[0]; break;
1471
	   case type_gif: return grTypes[1]; break;
1472
	   case type_jpg: return grTypes[2]; break;
1473
	   case type_xpm: return grTypes[3]; break;
1474
	   case type_bmp: return grTypes[4]; break;
1475
	   case type_tif: return grTypes[5]; break;
1476
	}
273 andreas 1477
 
274 andreas 1478
	return 0;
1479
}
273 andreas 1480
 
274 andreas 1481
bool SRender::getBool(QString b)
1482
{
1483
	if (b.toLower() == QString("true") ||
1484
	    b.toLower() == QString("on") ||
1485
	    b.toLower() == QString("1") ||
1486
	    b.toLower() == QString("yes") ||
1487
	    b.toLower() == QString("t") ||
1488
	    b.toLower() == QString("y"))
1489
	   return true;
273 andreas 1490
 
274 andreas 1491
	return false;
1492
}
273 andreas 1493
 
274 andreas 1494
bool SRender::getMap (double lx, double ly, double rx, double ry)
1495
{
275 andreas 1496
int width, height;
274 andreas 1497
QXmlSimpleReader reader;
1498
QString hv0;
1499
QFile file(XmlPath);
275 andreas 1500
double plx, ply, prx, pry;
273 andreas 1501
 
275 andreas 1502
	OutBuf.clear();
1503
	hv0 = pluginPath;
1504
 
1505
	if (hv0.right(1) != QString("/"))
1506
	   hv0 += "/";
1507
 
274 andreas 1508
	datasource_cache::instance()->register_datasources(hv0.toAscii().data());
275 andreas 1509
	hv0 = fontPath;
1510
 
1511
	if (hv0.right(1) != QString("/"))
1512
	   hv0 += "/";
1513
 
1514
	hv0 += "DejaVuSans.ttf";
274 andreas 1515
	freetype_engine::register_font(hv0.toAscii().data());
273 andreas 1516
 
274 andreas 1517
	width = label->width();
1518
	height = label->height();
273 andreas 1519
 
274 andreas 1520
	m.setWidth(width);
1521
	m.setHeight(height);
275 andreas 1522
//	load_map(m, XmlPath.toAscii().data());
273 andreas 1523
 
276 andreas 1524
	try
274 andreas 1525
	{
276 andreas 1526
	   if (!ControlSet)	// Initialize the map?
1527
	   {
1528
	      QXmlInputSource source (&file);
1529
	      reader.setContentHandler (this);
1530
	      reader.parse (source);
1531
	   }
273 andreas 1532
 
276 andreas 1533
	   save_map(m, "/home/andreas/.sportwatcher/spw.xml");
1534
//	   save_map(m, "/home/andreas/.sportwatcher/spw1.xml");
1535
	   plx = lx;
1536
	   ply = ly;
1537
	   prx = rx;
1538
	   pry = ry;
1539
	   projection pj(m.srs());
275 andreas 1540
 
276 andreas 1541
	   if (pj.is_geographic())
1542
	   {
1543
	      pj.inverse(plx, ply);
1544
	      pj.inverse(prx, pry);
275 andreas 1545
cout << "Geographic! Inverse projection." << endl;
276 andreas 1546
	   }
1547
	   else
1548
	   {
1549
//	      pj.forward(plx, ply);
1550
//	      pj.forward(prx, pry);
275 andreas 1551
cout << "NOT geographic!" << endl;
276 andreas 1552
	   }
275 andreas 1553
 
1554
for (unsigned i = 0; i < m.layerCount(); i++)
1555
{
1556
   bool vis = m.getLayer(i).isVisible(m.scale_denominator());
276 andreas 1557
//   bool vis = m.getLayer(i).isVisible(m.scale());
275 andreas 1558
   cout << "Layer " << i << ": " << m.getLayer(i).name();
1559
   cout << ", Visible: " << vis;
276 andreas 1560
   cout << ", Active: " << m.getLayer(i).isActive();
275 andreas 1561
   Envelope <double>e(m.getLayer(i).envelope());
1562
   cout << ", Extent: " << e.minx() << ", " << e.miny() << ", " << e.maxx() << ", " << e.maxy() << endl;
1563
}
1564
 
276 andreas 1565
	   // First we use Mapnik to create the map
1566
	   m.zoomToBox(Envelope<double>(plx, ply, prx, pry));
275 andreas 1567
 
1568
Envelope <double>e(m.getCurrentExtent());
1569
cout << std::setprecision(16) << "Parameter envelope: " << lx << ", " << ly << ", " << rx << ", " << ry << endl;
1570
cout << std::setprecision(16) << "Converted envelope: " << plx << ", " << ply << ", " << prx << ", " << pry << endl;
1571
cout << std::setprecision(16) << "Current extent:     " << e.minx() << ", " << e.miny() << ", " << e.maxx() << ", " << e.maxy() << endl;
276 andreas 1572
Envelope <double>x(m.get_buffered_extent());
1573
cout << std::setprecision(16) << "Current buf.extent: " << x.minx() << ", " << x.miny() << ", " << x.maxx() << ", " << x.maxy() << endl;
275 andreas 1574
cout << "SRS: " << m.srs() << endl;
1575
cout << std::setprecision(16) << "Scale: " << m.scale() << ", scale denominator: " << m.scale_denominator() << endl;
1576
cout << "width=" << m.getWidth() << ", height=" << m.getHeight() << endl;
1577
 
276 andreas 1578
	   Image32 buf(m.getWidth(), m.getHeight());
1579
	   agg_renderer<Image32> ren(m, buf);
1580
	   ren.apply();
273 andreas 1581
 
276 andreas 1582
	   // Put the image into a Qt object
1583
	   QImage image((uchar*)buf.raw_data(), m.getWidth(), m.getHeight(), QImage::Format_ARGB32);
1584
	   label->setPixmap(QPixmap::fromImage(image.rgbSwapped()));
1585
	   // Create a unique file name
1586
//	   pid = getpid();
1587
//	   OutBuf.sprintf("/var/tmp/SportWatcher_%d.png", pid);
1588
//	   save_to_file<ImageData32>(buf.data(), OutBuf.toAscii().data(), "png");
1589
	}
1590
 
1591
	catch (const mapnik::config_error &ex)
1592
	{
1593
	   KMessageBox::error(0, i18n("Configuration error: %1").arg(ex.what()));
1594
	   return false;
1595
	}
1596
 
1597
	catch (const std::exception &ex)
1598
	{
1599
	   KMessageBox::error(0, i18n("Exception at file %1: %2").arg(XmlPath).arg(ex.what()));
1600
	   return false;
1601
	}
1602
 
1603
	catch (...)
1604
	{
1605
	   KMessageBox::error(0, i18n("Unknown exception occured!"));
1606
	   return false;
1607
	}
1608
 
274 andreas 1609
	return true;
1610
}
273 andreas 1611
 
275 andreas 1612
void SRender::setMaxExtent(double lx, double ly, double rx, double ry)
1613
{
1614
	if (lx > 0 && _lx > lx)
1615
	   _lx = lx;
1616
 
1617
	if (lx < 0 && _lx < lx)
1618
	   _lx = lx;
1619
 
1620
	if (ly > 0 && _ly > ly)
1621
	   _ly = ly;
1622
 
1623
	if (ly < 0 && _ly < ly)
1624
	   _ly = ly;
1625
 
1626
	if (rx > 0 && _rx < rx)
1627
	   _rx = rx;
1628
 
1629
	if (rx < 0 && _rx > rx)
1630
	   _rx = rx;
1631
 
1632
	if (ry > 0 && _ry < ry)
1633
	   _ry = ry;
1634
 
1635
	if (ry < 0 && _ry > ry)
1636
	   _ry = ry;
1637
}
1638
 
1639
QString SRender::findIcon(QString ic)
1640
{
1641
QString ptf, icon;
1642
QFileInfo fi(ic);
1643
 
1644
	icon = fi.fileName();
1645
	ptf = KStandardDirs::locate("data", QString("sportwatcher/icons/%1").arg(icon));
1646
 
1647
	if (ptf.length() < icon.length())
1648
	{
1649
	   KMessageBox::error(0, i18n("The icon %1 was not found!").arg(icon));
1650
	   ptf.clear();
1651
	}
1652
 
1653
	return ptf;
1654
}
1655
 
274 andreas 1656
RULE *SRender::getLastRule(RULE *first)
1657
{
1658
RULE *akt = first;
273 andreas 1659
 
274 andreas 1660
	while (akt)
1661
	{
1662
	   if (!akt->next)
1663
	      return akt;
1664
 
1665
	   akt = akt->next;
1666
	}
1667
 
1668
	return 0;
273 andreas 1669
}
1670
 
274 andreas 1671
POINTSYMBOLIZER *SRender::getLastPointSymbolizer(POINTSYMBOLIZER *first)
273 andreas 1672
{
274 andreas 1673
POINTSYMBOLIZER *akt = first;
273 andreas 1674
 
274 andreas 1675
	while (akt)
1676
	{
1677
	   if (!akt->next)
1678
	      return akt;
273 andreas 1679
 
274 andreas 1680
	   akt = akt->next;
1681
	}
273 andreas 1682
 
274 andreas 1683
	return 0;
1684
}
1685
 
1686
LINESYMBOLIZER *SRender::getLastLineSymbolizer(LINESYMBOLIZER *first)
1687
{
1688
LINESYMBOLIZER *akt = first;
1689
 
1690
	while (akt)
273 andreas 1691
	{
274 andreas 1692
	   if (!akt->next)
1693
	      return akt;
273 andreas 1694
 
274 andreas 1695
	   akt = akt->next;
273 andreas 1696
	}
1697
 
274 andreas 1698
	return 0;
1699
}
273 andreas 1700
 
274 andreas 1701
POLYGONSYMBOLIZER *SRender::getLastPolygonSymbolizer(POLYGONSYMBOLIZER *first)
1702
{
1703
POLYGONSYMBOLIZER *akt = first;
273 andreas 1704
 
274 andreas 1705
	while (akt)
273 andreas 1706
	{
274 andreas 1707
	   if (!akt->next)
1708
	      return akt;
273 andreas 1709
 
274 andreas 1710
	   akt = akt->next;
273 andreas 1711
	}
1712
 
274 andreas 1713
	return 0;
273 andreas 1714
}
1715
 
274 andreas 1716
TEXTSYMBOLIZER *SRender::getLastTextSymbolizer(TEXTSYMBOLIZER *first)
273 andreas 1717
{
274 andreas 1718
TEXTSYMBOLIZER *akt = first;
273 andreas 1719
 
274 andreas 1720
	while (akt)
273 andreas 1721
	{
274 andreas 1722
	   if (!akt->next)
1723
	      return akt;
273 andreas 1724
 
274 andreas 1725
	   akt = akt->next;
273 andreas 1726
	}
1727
 
274 andreas 1728
	return 0;
1729
}
273 andreas 1730
 
274 andreas 1731
POLYGONPATTERNSYMBOLIZER *SRender::getLastPolygonPatternSymbolizer(POLYGONPATTERNSYMBOLIZER *first)
1732
{
1733
POLYGONPATTERNSYMBOLIZER *akt = first;
273 andreas 1734
 
274 andreas 1735
	while (akt)
273 andreas 1736
	{
274 andreas 1737
	   if (!akt->next)
1738
	      return akt;
273 andreas 1739
 
274 andreas 1740
	   akt = akt->next;
273 andreas 1741
	}
1742
 
274 andreas 1743
	return 0;
273 andreas 1744
}
1745
 
274 andreas 1746
SHIELDSYMBOLIZER *SRender::getLastShieldSymbolizer(SHIELDSYMBOLIZER *first)
273 andreas 1747
{
274 andreas 1748
SHIELDSYMBOLIZER *akt = first;
273 andreas 1749
 
274 andreas 1750
	while (akt)
273 andreas 1751
	{
274 andreas 1752
	   if (!akt->next)
1753
	      return akt;
1754
 
1755
	   akt = akt->next;
273 andreas 1756
	}
1757
 
274 andreas 1758
	return 0;
273 andreas 1759
}
1760
 
274 andreas 1761
LINEPATTERNSYMBOLIZER *SRender::getLastLinePatternSymbolizer(LINEPATTERNSYMBOLIZER *first)
273 andreas 1762
{
274 andreas 1763
LINEPATTERNSYMBOLIZER *akt = first;
273 andreas 1764
 
1765
	while (akt)
1766
	{
1767
	   if (!akt->next)
1768
	      return akt;
1769
 
1770
	   akt = akt->next;
1771
	}
1772
 
1773
	return 0;
1774
}
1775
 
274 andreas 1776
STYLE *SRender::findStyle(QString name)
273 andreas 1777
{
274 andreas 1778
STYLE *akt = firstStyle;
273 andreas 1779
 
1780
	while (akt)
1781
	{
274 andreas 1782
	   if (akt->name.toLower() == name.toLower())
273 andreas 1783
	      return akt;
1784
 
1785
	   akt = akt->next;
1786
	}
1787
 
1788
	return 0;
1789
}
274 andreas 1790
 
1791
unsigned SRender::colorToUInt(QString col)
1792
{
1793
QColor qc(col);
1794
 
275 andreas 1795
	return (qc.blue() * 65536) + (qc.green() * 256) + qc.red();
274 andreas 1796
}
1797
 
1798
STYLE *SRender::allocStyle()
1799
{
1800
STYLE *St = new STYLE;
1801
 
1802
	St->name.clear();
1803
	St->rule = 0;
1804
	St->next = 0;
1805
	return St;
1806
}
1807
 
1808
RULE *SRender::allocRule()
1809
{
1810
RULE *Ru = new RULE;
1811
 
276 andreas 1812
	Ru->name.clear();
1813
	Ru->title.clear();
274 andreas 1814
	Ru->maxscale = 0;
1815
	Ru->minscale = 0;
276 andreas 1816
	Ru->elsefilter = false;
274 andreas 1817
	Ru->filter.clear();
1818
	Ru->LineSymbolizer = 0;
1819
	Ru->PolygonSymbolizer = 0;
1820
	Ru->TextSymbolizer = 0;
1821
	Ru->PointSymbolizer = 0;
1822
	Ru->PolygonPatternSymbolizer = 0;
1823
	Ru->ShieldSymbolizer = 0;
1824
	Ru->LinePatternSymbolizer = 0;
1825
	Ru->next = 0;
1826
	return Ru;
1827
}
1828
 
1829
LAYER *SRender::allocLayer()
1830
{
1831
LAYER *La = new LAYER;
1832
 
1833
	La->name.clear();	// The unique name
276 andreas 1834
	La->title.clear();
1835
	La->abstract.clear();
274 andreas 1836
	La->status = false;	// Is it active?
276 andreas 1837
	La->clear_label = false;
274 andreas 1838
	La->srs.clear();	// Projection
275 andreas 1839
	La->minzoom = 0.0;
1840
	La->maxzoom = 0.0;
276 andreas 1841
	La->queryable = false;
274 andreas 1842
	La->Datasource.type.clear();
1843
	La->Datasource.file.clear();
276 andreas 1844
	La->Datasource.parser.clear();
1845
	La->Datasource.url.clear();
1846
	La->Datasource.bbox.clear();
274 andreas 1847
	La->Datasource.host.clear();
1848
	La->Datasource.user.clear();
1849
	La->Datasource.dbname.clear();
1850
	La->Datasource.table.clear();
1851
	La->Datasource.estimate_extent = false;
1852
	La->Datasource.ext_lx = 0.0;
1853
	La->Datasource.ext_ly = 0.0;
1854
	La->Datasource.ext_rx = 0.0;
1855
	La->Datasource.ext_ry = 0.0;
1856
	La->next = 0;
1857
	return La;
1858
}
1859
 
1860
LINEPATTERNSYMBOLIZER *SRender::allocLinePatternSymbolizer()
1861
{
1862
LINEPATTERNSYMBOLIZER *lps = new LINEPATTERNSYMBOLIZER;
1863
 
1864
	lps->file.clear();
1865
	lps->type = type_png;		// enum TYPES
1866
	lps->width = 0.0;
1867
	lps->height = 0.0;
1868
	lps->next = 0;
1869
	return lps;
1870
}
1871
 
1872
SHIELDSYMBOLIZER *SRender::allocShieldSymbolizer()
1873
{
1874
SHIELDSYMBOLIZER *ss = new SHIELDSYMBOLIZER;
1875
 
1876
	ss->name.clear();
1877
	ss->face_name.clear();
1878
	ss->size = 0.0;
275 andreas 1879
	ss->fill = 0;			// Color
274 andreas 1880
	ss->placement.clear();
1881
	ss->file.clear();
1882
	ss->type = type_png;		// enum TYPES
1883
	ss->width = 0.0;
1884
	ss->height = 0.0;
275 andreas 1885
	ss->dx = 0.0;
1886
	ss->dy = 0.0;
274 andreas 1887
	ss->mindistance = 0.0;
1888
	ss->maxdistance = 0.0;
1889
	ss->next = 0;
1890
	return ss;
1891
}
1892
 
1893
POLYGONPATTERNSYMBOLIZER *SRender::allocPolygonPatternSymbolizer()
1894
{
1895
POLYGONPATTERNSYMBOLIZER *pps = new POLYGONPATTERNSYMBOLIZER;
1896
 
1897
	pps->file.clear();
1898
	pps->type = type_png;		// enum TYPES
1899
	pps->width = 0.0;
1900
	pps->height = 0.0;
1901
	pps->allow_overlap = false;
1902
	pps->next = 0;
1903
	return pps;
1904
}
1905
 
1906
POINTSYMBOLIZER *SRender::allocPointSymbolizer()
1907
{
1908
POINTSYMBOLIZER *ps = new POINTSYMBOLIZER;
1909
 
1910
	ps->file.clear();
1911
	ps->type = type_png;		// enum TYPES
1912
	ps->width = 0.0;
1913
	ps->height = 0.0;
1914
	ps->allow_overlap = false;
1915
	ps->next = 0;
1916
	return ps;
1917
}
1918
 
1919
TEXTSYMBOLIZER *SRender::allocTextSymbolizer()
1920
{
1921
TEXTSYMBOLIZER *ts = new TEXTSYMBOLIZER;
1922
 
1923
	ts->name.clear();
1924
	ts->face_name.clear();
276 andreas 1925
	ts->placement.clear();
1926
	ts->alignment.clear();
274 andreas 1927
	ts->size = 0;
1928
	ts->fill = 0;			// Color
1929
	ts->halo_radius = 0;
1930
	ts->wrap_width = 0;
275 andreas 1931
	ts->dx = 0.0;
274 andreas 1932
	ts->dy = 0.0;
1933
	ts->mindistance = 0.0;
1934
	ts->maxdistance = 0.0;
1935
	ts->next = 0;
1936
	return ts;
1937
}
1938
 
1939
POLYGONSYMBOLIZER *SRender::allocPolygonSymbolizer()
1940
{
1941
POLYGONSYMBOLIZER *ps = new POLYGONSYMBOLIZER;
1942
 
1943
	memset (ps, 0, sizeof(POLYGONSYMBOLIZER));
1944
	return ps;
1945
}
1946
 
1947
LINESYMBOLIZER *SRender::allocLineSymbolizer()
1948
{
1949
LINESYMBOLIZER *ls = new LINESYMBOLIZER;
1950
 
1951
	ls->stroke = 0;		// Color
1952
	ls->stroke_width = 0.0;
1953
	ls->stroke_linejoin.clear();
1954
	ls->stroke_linecap.clear();
1955
 
1956
	for (int i = 0; i < 10; i++)
1957
	   ls->stroke_dasharray[i] = 0.0;
1958
 
1959
	ls->stroke_anz = 0;		// number of entries in dasharray
1960
	ls->stroke_opacity = 0.0;
1961
	ls->next = 0;
1962
	return ls;
1963
}