Subversion Repositories public

Rev

Rev 274 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
273 andreas 1
//
2
// C++ Implementation: render
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
15
#include <mapnik/map.hpp>
16
#include <mapnik/datasource_cache.hpp>
17
#include <mapnik/font_engine_freetype.hpp>
18
#include <mapnik/agg_renderer.hpp>
19
#include <mapnik/filter_factory.hpp>
20
#include <mapnik/color_factory.hpp>
21
#include <mapnik/image_util.hpp>
22
#include <mapnik/config_error.hpp>
23
 
24
#include "config.h"
25
#include "render.h"
26
 
27
#define CON_MAP			100
28
#define CON_STYLE		101
29
#define CON_RULE		102
30
#define CON_LINESYMBOLIZER	103
31
#define CON_POINTSYMBOLIZER	104
32
#define CON_POLYGONSYMBOLIZER	105
33
#define CON_TEXTSYMBOLIZER	106
34
#define CON_POLYGONPATTERNSYMBOLIZER	107
35
#define CON_LAYER		108
36
#define CON_DATASOURCE		109
37
 
38
#define FLD_FILTER		200
39
#define FLD_CSSPARAMETER	201
40
#define FLD_MINSCALE		202
41
#define FLD_MAXSCALE		203
42
#define FLD_STYLENAME		204
43
#define FLD_PARAMETER		205
44
 
45
#define ATT_FILL		300
46
#define ATT_FILE		301
47
#define ATT_TYPE		302
48
#define ATT_WIDTH		303
49
#define ATT_HEIGHT		304
50
#define ATT_SIZE		305
51
#define ATT_NAME		306
52
#define ATT_FACENAME		307
53
#define ATT_DY			308
54
#define ATT_HALORADIUS		309
55
#define ATT_WRAPWIDTH		310
56
#define ATT_MINDISTANCE		311
57
#define ATT_MAXDISTANCE		312
58
#define ATT_PLACEMENT		313
59
#define ATT_ALLOWOVERLAP	314
60
#define ATT_STATUS		315
61
#define ATT_SRS			316
62
 
63
#define FIRST_CON		100
64
#define LAST_CON		109
65
 
66
#define FIRST_FLD		200
67
#define LAST_FLD		205
68
 
69
#define FIRST_ATT		300
70
#define LAST_ATT		316
71
 
72
KEYS keys[] = {
73
	// Containers
74
	{ CON_MAP			QString("Map") },
75
	{ CON_STYLE			QString("Style") },
76
	{ CON_RULE			QString("Rule") },
77
	{ CON_LINESYMBOLIZER		QString("LineSymbolizer") },
78
	{ CON_POINTSYMBOLIZER		QString("PointSymbolizer") },
79
	{ CON_POLYGONSYMBOLIZER		QString("PolygonSymbolizer") },
80
	{ CON_TEXTSYMBOLIZER		QString("TextSymbolizer") },
81
	{ CON_POLYGONPATTERNSYMBOLIZER	QString("PolygonPatternSymbolizer") },
82
	{ CON_LAYER			QString("Layer") },
83
	{ CON_DATASOURCE		QString("Datasource") },
84
	// Fields
85
	{ FLD_FILTER			QString("Filter") },
86
	{ FLD_CSSPARAMETER		QString("CSSParameter") },
87
	{ FLD_MINSCALE			QString("MinScaleDenominator") },
88
	{ FLD_MAXSCALE			QString("MaxScaleDenominator") },
89
	{ FLD_STYLENAME			QString("StyleName") },
90
	{ FLD_PARAMETER			QString("Parameter") },
91
	// Attributes
92
	{ ATT_FILL			QString("fill") },
93
	{ ATT_NAME			QString("name") },
94
	{ ATT_FILE			QString("file") },
95
	{ ATT_TYPE			QString("type") },
96
	{ ATT_WIDTH			QString("width") },
97
	{ ATT_HEIGHT			QString("height") },
98
	{ ATT_SIZE			QString("size") },
99
	{ ATT_FACENAME			QString("face_name") },
100
	{ ATT_DY			QString("dy") },
101
	{ ATT_HALORADIUS		QString("halo_radius") },
102
	{ ATT_WRAPWIDTH			QString("wrap_width") },
103
	{ ATT_MINDISTANCE		QString("min_distance") },
104
	{ ATT_MAXDISTANCE		QString("max_distance") },
105
	{ ATT_PLACEMAENT		QString("placement") },
106
	{ ATT_ALLOWOVERLAP		QString("allow_overlap") },
107
	{ ATT_STATUS			QString("status") },
108
	{ ATT_SRS			QString("srs") },
109
	{ 0				QString::null }
110
};
111
 
112
render::render()
113
{
114
	Layer = 0;
115
	Style = 0;
116
	Rule = 0;
117
	LineSymbolizer = 0;
118
	PolygonSymbolizer = 0;
119
	TextSymbolizer = 0;
120
	PointSymbolizer = 0;
121
	PolygonPatternSymbolizer = 0;
122
	ShieldSymbolizer = 0;
123
	LinePatternSymbolizer = 0;
124
}
125
 
126
bool render::startDocument()
127
{
128
	indent = 0;
129
 
130
	if (firstStyle)		// free if allocated
131
	{
132
	   Style = firstStyle;
133
 
134
	   while (Style)
135
	   {
136
	      if (Style->rule)
137
	      {
138
		 RULE *rule = Style->rule;
139
		 STYLE *sakt = Style->next;
140
 
141
		 while (rule)
142
		 {
143
		    RULE *rakt = rule->next;
144
		    LINESYMBOLIZER *LineSymbolizer = rule->LineSymbolizer;
145
		    POLYGONSYMBOLIZER *PolygonSymbolizer = rule->PolygonSymbolizer;
146
		    TEXTSYMBOLIZER *TextSymbolizer = rule->TextSymbolizer;
147
		    POINTSYMBOLIZER *PointSymbolizer = rule->PointSymbolizer;
148
		    POLYGONPATTERNSYMBOLIZER *PolygonPatternSymbolizer = rule->PolygonPatternSymbolizer;
149
		    SHIELDSYMBOLIZER *ShieldSymbolizer = rule->ShielSymbolizer;
150
		    LINEPATTERNSYMBOLIZER *LinePatternSymbolizer = rule->LinePatternSymbolizer;
151
 
152
		    while (LineSymbolizer)
153
		    {
154
		       LINESYMBOLIZER *akt = LineSymbolizer->next;
155
		       delete LineSymbolizer;
156
		       LineSymbolizer = akt;
157
		    }
158
 
159
		    while (PolygonSymbolizer)
160
		    {
161
		       POLYGONSYMBOLIZER *akt = PolygonSymbolizer->next;
162
		       delete PolygonSymbolizer;
163
		       PolygonSymbolizer = akt;
164
		    }
165
 
166
		    while (TextSymbolizer)
167
		    {
168
		       TEXTSYMBOLIZER *akt = TextSymbolizer->next;
169
		       delete TextSymbolizer;
170
		       TextSymbolizer = akt;
171
		    }
172
 
173
		    while (PointSymbolizer)
174
		    {
175
		       POINTSYMBOLIZER *akt = PointSymbolizer->next;
176
		       delete PointSymbolizer;
177
		       PointSymbolizer = akt;
178
		    }
179
 
180
		    while (PolygonPatternSymbolizer)
181
		    {
182
		       POLYGONPATTERNSYMBOLIZER *akt = PolygonPatternSymbolizer->next;
183
		       delete PolygonPatternSymbolizer;
184
		       PolygonPatternSymbolizer = akt;
185
		    }
186
 
187
		    while (ShieldSymbolizer)
188
		    {
189
		       SHIELDSYMBOLIZER *akt = ShieldSymbolizer->next;
190
		       delete ShieldSymbolizer;
191
		       ShieldSymbolizer = akt;
192
		    }
193
 
194
		    while (LinePatternSymbolizer)
195
		    {
196
		       LINEPATTERNSYMBOLIZER *akt = LinePatternSymbolizer->next;
197
		       delete LinePatternSymbolizer;
198
		       LinePatternSymbolizer = akt;
199
		    }
200
 
201
		    delete rule;
202
		    rule = rakt;
203
		 }
204
	      }
205
 
206
	      delete Style;
207
	      Style = sakt;
208
	   }
209
	}
210
 
211
	Style = firstStyle = lastStyle = 0;
212
	return true;
213
}
214
 
215
/*
216
 * This is called every time a new start element was parsed.
217
 */
218
bool render::startElement( const QString&, const QString&,
219
                                    const QString& qName,
220
                                    const QXmlAttributes& att)
221
{
222
int i = FIRST_CON;
223
int index;
224
 
225
	indent++;
226
 
227
	while (i < LAST_CON)
228
	{
229
	   if (qName.toLower() == getKey(i).toLower())
230
	   {
231
	      switch (i)
232
	      {
233
		 case CON_MAP:
234
		    if ((index = att.index(QString("bgcolor"))) != -1)
235
		       MapPars.bgcolor = color_factory::from_string(att.value(index).toAscii().data());
236
 
237
		    if ((index = att.index(QString("buffer_size"))) != -1)
238
		       MapPars.buf_size = att.value(index).toInt();
239
 
240
		    if ((index = att.index(QString("srs"))) != -1)
241
		       MapPars.srs = att.value(index);
242
		 break;
243
 
244
		 case CON_STYLE:
245
		    if (!lastStyle)
246
		    {
247
		       Style = new STYLE;
248
		       fistStyle = lastStyle = Style;
249
		       memset (Style, 0, sizeof (STYLE));
250
		    }
251
		    else
252
		    {
253
		       Style = new STYLE;
254
		       memset (Style, 0, sizeof (STYLE));
255
		       lastStyle->next = Style;
256
		       lastStyle = Style;
257
		    }
258
 
259
		    if ((index = att.index(QString("name"))) != -1)
260
		       Style->name = att.value(index);
261
		    else
262
		    {
263
		       KMessageBox::error(0, i18n("Error parsing %1: Open STYLE wihout a name!").arg(XmlPath));
264
		       return false;
265
		    }
266
		 break;
267
 
268
		 case CON_RULE:
269
		    if (!Style)
270
		    {
271
		       KMessageBox::error(0, i18n("Error parsing %1: Open RULE outside of a STYLE!").arg(XmlPath));
272
		       return false;
273
		    }
274
 
275
		    Rule = getLastRule (Style->rule);
276
 
277
		    if (!Rule)
278
		    {
279
		       Rule = new RULE;
280
		       memset (Rule, 0, sizeof(RULE));
281
		       Style->rule = Rule;
282
		    }
283
		    else
284
		    {
285
		       Rule->next = new RULE;
286
		       Rule = Rule->next;
287
		       memset (Rule, 0, sizeof(RULE));
288
		    }
289
		 break;
290
 
291
		 case CON_POINTSYMBOLIZER:
292
		    if (!Rule)
293
		    {
294
		       KMessageBox::error(0, i18n("Error parsing %1: Open POINTSYMBOLIZER outside of a RULE!").arg(XmlPath));
295
		       return false;
296
		    }
297
 
298
		    PointSymbolizer = getLastPointSymbolizer(Rule->PointSymbolizer);
299
 
300
		    if (!PointSymbolizer)
301
		    {
302
		       PointSymbolizer = new POINTSYMBOLIZER;
303
		       memset (PointSymbolizer, 0, sizeof(POINTSYMBOLIZER));
304
		       Rule->PointSymbolizer = PointSymbolizer;
305
		    }
306
		    else
307
		    {
308
		       PointSymbolizer->next = new POINTSYMBOLIZER;
309
		       PointSymbolizer = PointSymbolizer->next;
310
		       memset (PointSymbolizer, 0, sizeof(POINTSYMBOLIZER));
311
		    }
312
 
313
		    if ((index = att.index(QString("file"))) != -1)
314
		       PointSymbolizer->file = att.value(index);
315
 
316
		    if ((index = att.index(QString("type"))) != -1)
317
		    {
318
		       QString ty = att.value(index);
319
 
320
		       if (ty.toLower() == QString("png"))
321
			  PointSymbolizer->type = type_png;
322
		       else if (ty.toLower() == QString("gif"))
323
			  PointSymbolizer->type = type_gif;
324
		       else if (ty.toLower() == QString("jpg"))
325
			  PointSymbolizer->type = type_jpg;
326
		       else if (ty.toLower() == QString("xpm"))
327
			  PointSymbolizer->type = type_xpm;
328
		       else if (ty.toLower() == QString("bmp"))
329
			  PointSymbolizer->type = type_xmp;
330
		       else if (ty.toLower() == QString("tif") || ty.toLower() == QString("tiff"))
331
			  PointSymbolizer->type = type_tif;
332
		    }
333
 
334
		    if ((index = add.index(QString("width"))) != -1)
335
		       PointSymbolizer->width = att.value(index).toDouble();
336
 
337
		    if ((index = add.index(QString("height"))) != -1)
338
		       PointSymbolizer->height = att.value(index).toDouble();
339
 
340
		    if ((index = add.index(QString("allow_overlap"))) != -1)
341
		    {
342
		       if (att.value(index).toLower() == QString("true"))
343
			  PointSymbolizer->allow_overlap = true;
344
		       else
345
			  PointSymbolizer->allow_overlap = false;
346
		    }
347
		 break;
348
 
349
		 break;
350
 
351
		 case CON_LINESYMBOLIZER:
352
		    if (!Rule)
353
		    {
354
		       KMessageBox::error(0, i18n("Error parsing %1: Open LINESYMBOLIZER outside of a RULE!").arg(XmlPath));
355
		       return false;
356
		    }
357
 
358
		    LineSymbolizer = getLastLineSymbolizer(Rule->LineSymbolizer);
359
 
360
		    if (!LineSymbolizer)
361
		    {
362
		       LineSymbolizer = new LINESYMBOLIZER;
363
		       memset (LineSymbolizer, 0, sizeof(LINESYMBOLIZER));
364
		       Rule->LineSymbolizer = LineSymbolizer;
365
		    }
366
		    else
367
		    {
368
		       LineSymbolizer->next = new LINESYMBOLIZER;
369
		       LineSymbolizer = LineSymbolizer->next;
370
		       memset (LineSymbolizer, 0, sizeof(LINESYMBOLIZER));
371
		    }
372
		 break;
373
 
374
		 case CON_POLYGONSYMBOLIZER:
375
		    if (!Rule)
376
		    {
377
		       KMessageBox::error(0, i18n("Error parsing %1: Open POLYGONSYMBOLIZER outside of a RULE!").arg(XmlPath));
378
		       return false;
379
		    }
380
 
381
		    PolygonSymbolizer = getLastPolygonSymbolizer(Rule->PolygonSymbolizer);
382
 
383
		    if (!PolygonSymbolizer)
384
		    {
385
		       PolygonSymbolizer = new POLYGONSYMBOLIZER;
386
		       memset (PolygonSymbolizer, 0, sizeof(POLYGONSYMBOLIZER));
387
		       Rule->PolygonSymbolizer = PolygonSymbolizer;
388
		    }
389
		    else
390
		    {
391
		       PolygonSymbolizer->next = new POLYGONSYMBOLIZER;
392
		       PolygonSymbolizer = PolygonSymbolizer->next;
393
		       memset (PolygonSymbolizer, 0, sizeof(POLYGONSYMBOLIZER));
394
		    }
395
		 break;
396
 
397
		 case CON_TEXTSYMBOLIZER:
398
		    if (!Rule)
399
		    {
400
		       KMessageBox::error(0, i18n("Error parsing %1: Open TEXTSYMBOLIZER outside of a RULE!").arg(XmlPath));
401
		       return false;
402
		    }
403
 
404
		    TextSymbolizer = getLastTextSymbolizer(Rule->TextSymbolizer);
405
 
406
		    if (!TextSymbolizer)
407
		    {
408
		       TextSymbolizer = new TEXTSYMBOLIZER;
409
		       memset (TextSymbolizer, 0, sizeof(TEXTSYMBOLIZER));
410
		       Rule->TextSymbolizer = TextSymbolizer;
411
		    }
412
		    else
413
		    {
414
		       TextSymbolizer->next = new TEXTSYMBOLIZER;
415
		       TextSymbolizer = TextSymbolizer->next;
416
		       memset (TextSymbolizer, 0, sizeof(TEXTSYMBOLIZER));
417
		    }
418
 
419
		    if ((index = att.index(QString("name"))) != -1)
420
		       TextSymbolizer->name = att.value(index);
421
 
422
		    if ((index = att.index(QString("face_name"))) != -1)
423
		       TextSymbolizer->face_name = att.value(index);
424
 
425
		    if ((index = att.index(QString("size"))) != -1)
426
		       TextSymbolizer->size = att.value(index).toDouble();
427
 
428
		    if ((index = att.index(QString("fill"))) != -1)
429
		       TextSymbolizer->fill = 
430
		 break;
431
	}
432
}
433
 
434
/*
435
 * This is called every time an element is closed.
436
 */
437
bool render::endElement( const QString&, const QString&, const QString& qName)
438
{
439
}
440
 
441
/*
442
 * The reader calls this function when it has parsed a chunk of character data
443
 * - either normal character data or character data inside a CDATA section.
444
 */
445
bool render::characters (const QString& ch)
446
{
447
}
448
 
449
QString render::getKey (int pos)
450
{
451
int i = 0;
452
 
453
	while (keys[i].id > 0)
454
	{
455
	   if (keys[i].id == pos)
456
	      return keys[i].name;
457
 
458
	   i++;
459
	}
460
 
461
	return QString::null;
462
}
463
 
464
bool render::getMap (double lx, double ly, double rx double ry)
465
{
466
int width, height;
467
 
468
	datasource_cache::instance()->register_datasources(MAPNIK_PLUGIN_PATH + "/");
469
	freetype_engine::register_font(MAPNIK_FONTS + "/DejaVuSans.ttf");
470
 
471
	width = label.width();
472
	height = label.height();
473
 
474
	Map m(width, height, "+proj=merc +datum=WGS84  +k=1.0 +units=m +over +no_defs");
475
	m.set_background(color_factory::from_string("white"));
476
 
477
	// create styles
478
	// world1
479
	feature_type_style world1_style;
480
	addRule(&world1_style, 0, 6000000.0, 250000000000.0, Color(0xf2, 0xef, 0xe9), Color(0xb5, 0xd0, 0xd0), 0.5, 0, 0, 0);
481
 
482
	// world
483
	feature_type_style world_style;
484
	addRule(&world_style, 0, 600000.0, 6000000.0, Color(0xf2, 0xef, 0xe9), 0, 0.0, 0, 0, 0);
485
 
486
	// coast_poly
487
	feature_type_style coast_poly_style;
488
	addRule(&coas_poly_style, 0, -1.0, 600000.0, Color(0xf2, 0xef, 0xe9), 0, 0.0, 0, 0, 0);
489
 
490
	// builtup
491
	feature_type_style builtup_style;
492
	addRule(&builtup_style, 0, 500000.0, 2500000.0, Color(0x0d, 0x0d, 0x0d), 0, 0.0, 0, 0, 0);
493
 
494
	// places
495
	feature_type_style places_style;
496
	text_symbolizer places_ts = addTextSymbolizer("place_name", "DejaVu Sans Book", 10, Color(0x04, 0x04, 0x04), 1, 0.0);
497
	places_style.append(places_ts);
498
	addRule(&places_style, 0, 10000000.0, 50000000.0, 0, 0, 0.0, 0, 0, 0);
499
 
500
	// stations
501
	feature_type_style stations_style;
502
	addRulePoint(&stations_style, "[railway]='station'", 25000.0, 250000.0, 0, 0, 0.0, QString("station_small.png"), 5, 5);
503
	addRulePoint(&stations_style, "[railway]='station'", -1.0, 25000.0, 0, 0, 0.0, QString("station.png", 9, 9);
504
	addRulePoint(&stations_style, "[railway]='halt' or [railway]='tram_stop'", -1.0, 100000.0, 0, 0, 0.0, QString("halt.png"), 3, 3);
505
 
506
	text_symbolizer stations_ts = addTextSymbolizer("name", "DejaVu Sans Bold", 8, Color(0, 0, 0), 1, 0, -8.0);
507
	stations_style.append(stations_ts);
508
	addRulePoint(&stations_style, "[railway]='halt'", 25000.0, 50000.0, 0, 0, 0.0, 0, 0, 0, 0);
509
 
510
	text_symbolizer stations_ts1 = addTextSymbolizer("name", "DejaVu Sans Bold", 10, Color(0, 0, 0), 1, 0, -14.0);
511
	stations_style.append(stations_ts1);
512
	addRule(&stations_style, "[railway] ='halt'", -1.0, 25000.0, 0, 0, 0.0, 0, 0, 0);
513
 
514
	text_symbolizer stations_ts2 = addTextSymbolizer("name", "DejaVu Sans Bold", 9, Color(0, 0, 0), 1, 0, -8.0);
515
	stations_style.append(stations_ts2);
516
	addRule(&stations_style, "[railway]='station'", 25000.0, 50000.0, 0, 0, 0.0, 0, 0, 0);
517
 
518
	text_symbolizer stations_ts3 = addTextSymbolizer("name", "DejaVu Sans Bold", 12, Color(0, 0, 0), 1, 0, -14.0);
519
	stations_style.append(stations_ts3);
520
	addRule(&stations_style, "[railway]='station'", -1.0, 25000.0, 0, 0, 0.0, 0, 0, 0);
521
	addRulePoint(&stations_style, "[railway]='level_crossing'", 10000.0, 50000.0, 0, 0, 0.0, QString("level_crossing.png"), 7, 7);
522
 
523
	// leisure
524
	feature_type_style leisure_style;
525
 
526
	addRule(&leisure_style, "[man_made] = 'pier'", -1.0, 100000.0, Color(0xed, 0xed, 0xed), color_factory::from_string("grey"), 0.3, 0, 0, 0);
527
	addRule(&leisure_style, "[highway] = 'residential'", -1.0, 50000.0, Color(255, 255, 255), Color(0x09, 0x09, 0x09), 1.0, 0, 0, 0);
528
	addRule(&leisure_style, "[highway] = 'pedestrian'", -1.0, 50000.0, Color(0xed, 0xed, 0xed), color_factory::from_string("grey"), 0.5, 0, 0, 0);
529
	addRule(&leisure_style, "[leisure] = 'playground'", -1.0, 100000.0, Color(0xcc, 0xff, 0xff), Color(0x06, 0x06, 0x06), 0.3, 0, 0, 0);
530
	addRule(&leisure_style, "[tourism] = 'attraction'", -1.0, 100000.0, Color(0xf2, 0xca, 0xea), 0, -1.0, 0, 0, 0);
531
	addRule(&leisure_style, "[landuse] = 'quarry'", -1.0, 500000.0, 0, color_factory::from_string("grey"), 0.5, QString("quarry2.png"), 30, 30);
532
	addRule(&leisure_style, "[leisure] = 'nature_reserve' or [landuse] = 'vineyard'", 100000.0, 1000000.0, Color(0xab, 0xdf, 0x96), 0, 0.0, 0, 0, 0);
533
	addRule(&leisure_style, "[landuse] = 'vineyard'", 20000.0, 100000.0, 0, 0, 0.0, QString("vineyard.png"), 19, 21);
534
	addRule(&leisure_style, "[landuse] = 'vineyard'", -1.0, 100000.0, 0, 0, 0.0, QString("vineyard.png"), 29, 29);
535
	addRule(&leisure_style, "[leisure] = 'nature_reserve'", 50000.0, 100000.0, 0, 0, 0.0, QString("nature_reserve.png"), 21, 24);
536
	addRule(&leisure_style, "[leisure] = 'nature_reserve'", -1.0, 50000.0, 0, 0, 0.0, QString("nature_reserve2.png"), 42, 48);
537
	addRule(&leisure_style, "[landuse] = 'cemetery'", 20000.0, 1000000.0, Color(0xaa, 0xcb, 0xaf), 0, 0.0, 0, 0, 0);
538
	addRule(&leisure_style, "[landuse] = 'residential'", 1000.0, 1000000.0, Color(0x0d, 0x0d, 0x0d), 0, 0.0, 0, 0, 0);
539
	addRule(&leisure_style, "[military] = 'barracks'", 1000.0, 1000000.0, Color(0xff, 0x8f, 0x8f), 0, 0.0, 0, 0, 0);
540
	addRule(&leisure_style, "[military] = 'danger_area'", 500000.0, 2000000.0, color_factory::from_string("pink"), 0, 0.0, 0, 0, 0); // FIXME: fill-opacity 0.3 is missing!
541
	addRule(&leisure_style, "[military] = 'danger_area'", 1000.0, 500000.0, 0, 0, 0.0, QString("danger.png"), 30, 30);
542
	addRule(&leisure_style, "[landuse] = 'cemetery'", -1.0, 50000.0, 0, 0, 0.0, QString("grave_yard.png"), 16, 16);
543
	addRule(&leisure_style, "[landuse] = 'meadow'", -1.0, 1000000.0, Color(0xcf, 0xec, 0xa8), 0, 0.0, 0, 0, 0);
544
	addRule(&leisure_style, "[leisure] = 'park'", -1.0, 1000000.0, Color(0xb6, 0xfd, 0xb6), 0, 0.0, 0, 0, 0);
545
	addRule(&leisure_style, "[tourism] = 'zoo'", -1.0, 1000000.0, 0, 0, 0.0, QString("zoo.png"), 21, 24);
546
	addRule(&leisure_style, "[leisure] = 'common'", -1.0, 1000000.0, Color(0xcf, 0xec, 0xa8), 0, 0.0, 0, 0, 0);
547
	addRule(&leisure_style, "[leisure] = 'garden'", -1.0, 1000000.0, Color(0xcf, 0xec, 0xa8), 0, 0.0, 0, 0, 0);
548
	addRule(&leisure_style, "[leisure] = 'golf_course'", -1.0, 1000000.0, Color(0xb5, 0xe3, 0xb5), 0, 0.0, 0, 0, 0);
549
	addRule(&leisure_style, "[landuse] = 'allotments'", -1.0, 1000000.0, Color(0xc8, 0xb0, 0x84), 0, 0.0, 0, 0, 0);
550
	addRule(&leisure_style, "[landuse] = 'forest'", 50000.0, 2000000.0, Color(0x8d, 0xc5, 0x6c), 0, 0.0, 0, 0, 0);
551
	addRule(&leisure_style, "[landuse] = 'forest'", -1.0, 50000.0, 0, 0, 0.0, QString("forest.png"), 21, 24);
552
	addRule(&leisure_style, "[landuse] = 'farm'", -1.0, 2000000.0, Color(0xea, 0xd8, 0xbd), 0, 0.0, 0, 0, 0);
553
	addRule(&leisure_style, "[landuse] = 'recreation_ground'", -1.0, 1000000.0, Color(0xcf, 0xec, 0xa8), 0, 0.0, 0, 0, 0);
554
	addRule(&leisure_style, "[landuse] = 'village_green'", -1.0, 500000.0, Color(0xcf, 0xec, 0xa8), 0, 0.0, 0, 0, 0);
555
	addRule(&leisure_style, "[landuse] = 'retail'", -1.0, 1000000.0, Color(0xf1, 0xda, 0xda), 0, 0.0, 0, 0, 0);
556
	addRule(&leisure_style, "[landuse] = 'retail'", -1.0, 25000.0, 0, color_factory::from_string("red"), 0.3, 0, 0, 0);
557
	addRule(&leisure_style, "[landuse] = 'industrial'", -1.0, 1000000.0, Color(0xff, 0xae, 0xb9), 0, 0.0, 0, 0, 0);
558
	addRule(&leisure_style, "[power] = 'station'", 200000.0, 1000000.0, Color(0x0b, 0x0b, 0x0b), 0, 0.0, 0, 0, 0);
559
	addRule(&leisure_style, "[power] = 'station'", -1.0, 200000.0, Color(0x0b, 0x0b, 0x0b), Color(0x05, 0x05, 0x05), 0.4, 0, 0, 0);
560
	addRule(&leisure_style, "[power] = 'sub_station'", -1.0, 100000.0, Color(0x0b, 0x0b, 0x0b), Color(0x05, 0x05, 0x05), 0.4, 0, 0, 0);
561
	addRule(&leisure_style, "[landuse] = 'commercial'", -1.0, 1000000.0, Color(0xef, 0xc8, 0xc8), 0, 0.0, 0, 0, 0);
562
	addRule(&leisure_style, "[landuse] = 'brownfield' or [landuse]='landfill'", -1, 1000000.0, Color(0x9d, 0x9d, 0x6c), 0, 0.0, 0, 0, 0);
563
	addRule(&leisure_style, "[natural] = 'wood' or [landuse] = 'wood'", -1.0, 1000000.0, Color(0xae, 0xd1, 0xa0), 0, 0.0, 0, 0, 0);
564
	addRule(&leisure_style, "[natural] = 'heath'", -1.0, 1000000.0, Color(0xff, 0xff, 0xc0), 0, 0.0, 0, 0, 0);
565
	addRule(&leisure_style, "[landuse] = 'basin'", -1.0, 5000000.0, Color(0xb5, 0xd0, 0xd0), 0, 0.0, 0, 0, 0);
566
	addRule(&leisure_style, "[amenity] = 'university' or [amenity] = 'college' or [amenity] = 'school' or [amenity]='hospital'", -1.0, 1000000.0, Color(0xf0, 0xf0, 0xd8), 0, 0.0, 0, 0, 0);
567
	addRule(&leisure_style, "[amenity] = 'university' or [amenity] = 'college' or [amenity] = 'school' or [amenity]='hospital'", -1.0, 250000.0, 0, color_factory::from_string("brown"), 0.3, 0, 0, 0);
568
	addRule(&leisure_style, "[amenity] = 'parking'", -1.0, 1000000.0, Color(0xf7, 0xef, 0xb7),  0, 0.0, 0, 0, 0);
569
	addRule(&leisure_style, "[amenity] = 'parking'", -1.0, 25000.0, 0, Color(0xee, 0xee, 0xd1), 0.3, 0, 0, 0);
570
	addRule(&leisure_style, "[railway] = 'station' or [building] = 'station'", -1.0, 1000000.0, Color(0xff, 0xf6, 0x8f), 0, 0.0, 0, 0, 0); // FIXME: fill-opacity = 0.5 is missing!
571
	addRule(&leisure_style, "[building] = 'supermarket'", -1.0, 1000000.0, color_factory::from_string("pink"), 0, 0.0, 0, 0, 0); // FIXME: fill-opacity = 0.5 is missing!
572
	addRule(&leisure_style, "[building] <> 'station' and [building] <> 'supermarket' and [building] <> ''", -1.0, 1000000.0, Color(0xcc, 0x99, 0x99), 0, 0.0, 0, 0, 0);
573
	addRule(&leisure_style, "[amenity] = 'place_of_worship'", 20000.0, 1000000.0, Color(0x07, 0x07, 0x07), 0, 0.0, 0, 0, 0); // FIXME: fill-opacity = 0.5 is missing!
574
	addRule(&leisure_style, "[amenity] = 'place_of_worship'", -1.0, 20000.0, Color(0x07, 0x07, 0x07), Color(0x01, 0x01, 0x01), 0.3, 0, 0, 0);
575
	addRule(&leisure_style, "[leisure] = 'sports_centre' or [leisure]='stadium' or [leisure]='track'", -1.0, 1000000.0, Color(0x33, 0xcc, 0x99), 0, 0.0, 0, 0, 0);
576
	addRule(&leisure_style, "[leisure] = 'pitch'", -1.0, 1000000.0, Color(0x8a, 0xd3, 0xaf), 0, 0.0, 0, 0, 0);
577
	addRule(&leisure_style, "[aeroway] = 'terminal'", -1.0, 200000.0, Color(0xcc, 0x99, 0xff), 0, 0.0, 0, 0, 0);
578
	addRule(&leisure_style, "[aeroway] = 'terminal'", -1.0, 50000.0, 0, Color(0x33, 0x00, 0x66), 0.2, 0, 0, 0);
579
	addRule(&leisure_style, "[aeroway] = 'apron'", -1.0, 200000.0, Color(0xf0, 0xe0, 0xff), 0, 0.0, 0, 0, 0);
580
	addRule(&leisure_style, "[natural] = 'beach'", -1.0, 100000.0, 0, 0, 0.0, QString("beach.png"), 10, 10);
581
}
582
 
583
void render::addRule (feature_type_style &fts, char *filter, double minscale, double maxscale, Color &polcol, Color &symcol, double symwidth, QString &pattern, int pw, int ph)
584
{
585
	rule_type rule;
586
 
587
	if (minscale >= 0.0)
588
	   rule.set_min_scale(minscale);
589
 
590
	if (maxscale >= 0.0)
591
	   rule.set_max_scale(maxscale);
592
 
593
	if (pattern && pw > 0 && ph > 0)
594
	{
595
	QString ptf = KStandardDirs::findRessource("icon", pattern);
596
 
597
	   rule.append(polygon_pattern_symbolizer(ptf.toAscii().data(), "png", pw, ph));
598
	}
599
 
600
	if (filter)
601
	   rule.set_filter(create_filter(filter));
602
 
603
	if (polcol)
604
	   rule.append(polygon_symbolizer(polcol));
605
 
606
	if (symcol)
607
	{
608
	   stroke stk (symcol);
609
 
610
	   if (symwidth >= 0.0)
611
	      stk.set_width(0.3);
612
 
613
	   rule.append(line_symbolizer(stk));
614
	}
615
 
616
	fts.add_rule(rule);
617
}
618
 
619
void render::addRulePoint (feature_type_style &fts, char *filter, double minscale, double maxscale, Color &polcol, Color &symcol, double symwidth, QString &pattern, int pw, int ph)
620
{
621
	rule_type rule;
622
 
623
	if (minscale >= 0.0)
624
	   rule.set_min_scale(minscale);
625
 
626
	if (maxscale >= 0.0)
627
	   rule.set_max_scale(maxscale);
628
 
629
	if (pattern && pw > 0 && ph > 0)
630
	{
631
	QString ptf = KStandardDirs::findRessource("icon", pattern);
632
 
633
	   rule.append(point_symbolizer(ptf.toAscii().data(), "png", pw, ph));
634
	}
635
 
636
	if (filter)
637
	   rule.set_filter(create_filter(filter));
638
 
639
	if (polcol)
640
	   rule.append(polygon_symbolizer(polcol));
641
 
642
	if (symcol)
643
	{
644
	   stroke stk (symcol);
645
 
646
	   if (symwidth >= 0.0)
647
	      stk.set_width(0.3);
648
 
649
	   rule.append(line_symbolizer(stk));
650
	}
651
 
652
	fts.add_rule(rule);
653
}
654
 
655
text_symbolizer &render::addTextSymbolizer (char *name, char *font, int size, Color &col, int radius, int wrap, double dy)
656
{
657
text_symbolizer ts(name, font, size, Color(0, 0, 0));
658
 
659
	if (vol && radius > 0)
660
	{
661
	   ts.set_halo_fill(halo);
662
	   ts.set_halo_radius(radius);
663
	}
664
 
665
	if (dy < 0.0)
666
	   ts.set_max_char_angle_delta(dy);
667
 
668
	if (wrap >= 0)
669
	   ts.set_wrap_width(wrap);
670
 
671
	return &ts;
672
}
673
 
674
RULE *render::getLastRule(RULE *first)
675
{
676
RULE *akt = first;
677
 
678
	while (akt)
679
	{
680
	   if (!akt->next)
681
	      return akt;
682
 
683
	   akt = akt->next;
684
	}
685
 
686
	return 0;
687
}
688
 
689
POINTSYMBOLIZER *render::getLastPointSymbolizer(POINTSYMBOLIZER *first)
690
{
691
POINTSYMBOLIZER *akt = first;
692
 
693
	while (akt)
694
	{
695
	   if (!akt->next)
696
	      return akt;
697
 
698
	   akt = akt->next;
699
	}
700
 
701
	return 0;
702
}