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 |
}
|