Subversion Repositories public

Rev

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