Subversion Repositories public

Compare Revisions

Ignore whitespace Rev 274 → Rev 275

/sportwatcher/trunk/src/render.cpp
17,6 → 17,7
#include <QXmlReader>
#include <QDir>
#include <QColor>
#include <QImage>
#include <KStandardDirs>
#include <KConfig>
#include <KLocale>
23,6 → 24,7
#include <KMessageBox>
#include <KGlobalSettings>
#include <KConfigGroup>
#include <KIconLoader>
 
#include "config.h"
#include "render.h"
65,6 → 67,7
#define ATT_ALLOWOVERLAP 314
#define ATT_STATUS 315
#define ATT_SRS 316
#define ATT_DX 317
 
#define FIRST_CON 100
#define LAST_CON 111
73,7 → 76,7
#define LAST_FLD 205
 
#define FIRST_ATT 300
#define LAST_ATT 316
#define LAST_ATT 317
 
using std::cout;
using std::cerr;
93,6 → 96,7
{ CON_LAYER, in_layer, QString("Layer") },
{ CON_DATASOURCE, in_datasource, QString("Datasource") },
{ CON_SHIELDSYMBOLIZER, in_shieldsymbolizer, QString("ShieldSymbolizer") },
{ CON_LINEPATTERNSYMBOLIZER, in_linepatternsymbolizer, QString("LinePatternSymbolizer") },
// Fields
{ FLD_FILTER, in_rule, QString("Filter") },
{ FLD_CSSPARAMETER, in_symbolizer, QString("CSSParameter") },
109,6 → 113,7
{ ATT_HEIGHT, in_symbolizer, QString("height") },
{ ATT_SIZE, in_symbolizer, QString("size") },
{ ATT_FACENAME, in_symbolizer, QString("face_name") },
{ ATT_DX, in_symbolizer, QString("dx") },
{ ATT_DY, in_symbolizer, QString("dy") },
{ ATT_HALORADIUS, in_symbolizer, QString("halo_radius") },
{ ATT_WRAPWIDTH, in_symbolizer, QString("wrap_width") },
136,6 → 141,8
PolygonPatternSymbolizer = 0;
ShieldSymbolizer = 0;
LinePatternSymbolizer = 0;
_lx = _ly = 180.0;
_rx = _ry = -180.0;
// This is true, when a XML file was parsed successfully
ControlSet = false;
 
181,6 → 188,9
{
startDocument(); // Clean everything
ControlSet = false;
 
if (!OutBuf.isEmpty())
unlink (OutBuf.toAscii().data());
}
 
bool SRender::startDocument()
286,6 → 296,18
}
 
Lay = firstLayer = lastLayer = 0;
Rule = 0;
LineSymbolizer = 0;
PolygonSymbolizer = 0;
TextSymbolizer = 0;
PointSymbolizer = 0;
PolygonPatternSymbolizer = 0;
ShieldSymbolizer = 0;
LinePatternSymbolizer = 0;
_lx = _ly = 180.0;
_rx = _ry = -180.0;
ControlSet = false;
XmlLine = 1;
Container = in_root;
return true;
}
314,19 → 336,30
 
if (ControlSet) // Must be false here!
{
KMessageBox::error(0, i18n("Error parsing %1: There is another MAP! Only one map information is allowed!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: There is another MAP! Only one map information is allowed!").arg(XmlPath).arg(XmlLine));
return false;
}
 
if ((index = att.index(QString("bgcolor"))) != -1)
{
color col;
 
MapPars.bgcolor = colorToUInt(att.value(index));
col.set_bgr(MapPars.bgcolor);
m.set_background(col);
}
 
if ((index = att.index(QString("buffer_size"))) != -1)
{
MapPars.buf_size = att.value(index).toInt();
m.set_buffer_size(MapPars.buf_size);
}
 
if ((index = att.index(QString("srs"))) != -1)
{
MapPars.srs = att.value(index);
cout << "<Map bgcolor=" << MapPars.bgcolor << " buffer_size=" << MapPars.buf_size << " srs=" << MapPars.srs.toAscii().data() << ">" << endl;
m.set_srs(MapPars.srs.toAscii().data());
}
break;
 
case CON_STYLE:
348,10 → 381,9
Style->name = att.value(index);
else
{
KMessageBox::error(0, i18n("Error parsing %1: Open STYLE without a name!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: Open STYLE without a name!").arg(XmlPath).arg(XmlLine));
return false;
}
cout << " <Style name=" << Style->name.toAscii().data() << ">" << endl;
break;
 
case CON_RULE:
359,7 → 391,7
 
if (!Style)
{
KMessageBox::error(0, i18n("Error parsing %1: Open RULE outside of a STYLE!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: Open RULE outside of a STYLE!").arg(XmlPath).arg(XmlLine));
return false;
}
 
375,7 → 407,6
Rule->next = allocRule();
Rule = Rule->next;
}
cout << " <Rule>" << endl;
break;
 
case CON_LAYER:
401,7 → 432,12
 
if ((index = att.index(QString("srs"))) != -1)
Lay->srs = att.value(index);
cout << " <Layer name=" << Lay->name.toAscii().data() << " status=" << Lay->status << " srs=" << Lay->srs.toAscii().data() << ">" << endl;
 
if ((index = att.index(QString("minzoom"))) != -1)
Lay->minzoom = att.value(index).toDouble();
 
if ((index = att.index(QString("maxzoom"))) != -1)
Lay->maxzoom = att.value(index).toDouble();
break;
 
case CON_DATASOURCE:
413,7 → 449,7
 
if (!Rule)
{
KMessageBox::error(0, i18n("Error parsing %1: Open POINTSYMBOLIZER outside of a RULE!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: Open POINTSYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
return false;
}
 
449,7 → 485,6
else
PointSymbolizer->allow_overlap = false;
}
cout << " <Pointsymbolizer file=" << PointSymbolizer->file.toAscii().data() << " ... >" << endl;
break;
 
break;
459,7 → 494,7
 
if (!Rule)
{
KMessageBox::error(0, i18n("Error parsing %1: Open LINESYMBOLIZER outside of a RULE!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: Open LINESYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
return false;
}
 
475,7 → 510,6
LineSymbolizer->next = allocLineSymbolizer();
LineSymbolizer = LineSymbolizer->next;
}
cout << " <Linesymbolizer>" << endl;
break;
 
case CON_POLYGONSYMBOLIZER:
483,7 → 517,7
 
if (!Rule)
{
KMessageBox::error(0, i18n("Error parsing %1: Open POLYGONSYMBOLIZER outside of a RULE!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: Open POLYGONSYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
return false;
}
 
499,7 → 533,6
PolygonSymbolizer->next = allocPolygonSymbolizer();
PolygonSymbolizer = PolygonSymbolizer->next;
}
cout << " <Polygonsymbolizer>" << endl;
break;
 
case CON_TEXTSYMBOLIZER:
507,7 → 540,7
 
if (!Rule)
{
KMessageBox::error(0, i18n("Error parsing %1: Open TEXTSYMBOLIZER outside of a RULE!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: Open TEXTSYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
return false;
}
 
542,6 → 575,9
if ((index = att.index(QString("wrap_width"))) != -1)
TextSymbolizer->wrap_width = att.value(index).toDouble();
 
if ((index = att.index(QString("dx"))) != -1)
TextSymbolizer->dx = att.value(index).toDouble();
 
if ((index = att.index(QString("dy"))) != -1)
TextSymbolizer->dy = att.value(index).toDouble();
 
550,7 → 586,6
 
if ((index = att.index(QString("min_distance"))) != -1)
TextSymbolizer->mindistance = att.value(index).toDouble();
cout << " <Textsymbolizer name=" << TextSymbolizer->name.toAscii().data() << " ... >" << endl;
break;
 
case CON_POLYGONPATTERNSYMBOLIZER:
558,7 → 593,7
 
if (!Rule)
{
KMessageBox::error(0, i18n("Error parsing %1: Open POLYGONPATTERNSYMBOLIZER outside of a RULE!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: Open POLYGONPATTERNSYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
return false;
}
 
589,7 → 624,6
 
if ((index = att.index(QString("allow_overlap"))) != -1)
PolygonPatternSymbolizer->allow_overlap = getBool(att.value(index));
cout << " <Polygonpatternsymbolizer file=" << PolygonPatternSymbolizer->file.toAscii().data() << " ... >" << endl;
break;
 
case CON_SHIELDSYMBOLIZER:
597,7 → 631,7
 
if (!Rule)
{
KMessageBox::error(0, i18n("Error parsing %1: Open SHIELDSYMBOLIZER outside of a RULE!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: Open SHIELDSYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
return false;
}
 
641,12 → 675,17
if ((index = att.index(QString("height"))) != -1)
ShieldSymbolizer->height = att.value(index).toDouble();
 
if ((index = att.index(QString("dx"))) != -1)
ShieldSymbolizer->dx = att.value(index).toDouble();
 
if ((index = att.index(QString("dy"))) != -1)
ShieldSymbolizer->dy = att.value(index).toDouble();
 
if ((index = att.index(QString("min_distance"))) != -1)
ShieldSymbolizer->mindistance = att.value(index).toDouble();
 
if ((index = att.index(QString("max_distance"))) != -1)
ShieldSymbolizer->maxdistance = att.value(index).toDouble();
cout << " <Shieldsymbolizer name=" << ShieldSymbolizer->name.toAscii().data() << " ... >" << endl;
break;
 
case CON_LINEPATTERNSYMBOLIZER:
654,7 → 693,7
 
if (!Rule)
{
KMessageBox::error(0, i18n("Error parsing %1: Open LINEPATTERNSYMBOLIZER outside of a RULE!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: Open LINEPATTERNSYMBOLIZER outside of a RULE!").arg(XmlPath).arg(XmlLine));
return false;
}
 
682,7 → 721,6
 
if ((index = att.index(QString("height"))) != -1)
LinePatternSymbolizer->height = att.value(index).toDouble();
cout << " <Linepatternsymbolizer file=" << LinePatternSymbolizer->file.toAscii().data() << " ... >" << endl;
break;
}
}
722,7 → 760,7
}
else
{
KMessageBox::error(0, i18n("Error parsing %1: Required attribute NAME is missing in CSSPARAMETER inside LINESYMBOLIZER!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: Required attribute NAME is missing in CSSPARAMETER inside LINESYMBOLIZER!").arg(XmlPath).arg(XmlLine));
return false;
}
}
742,7 → 780,7
}
else
{
KMessageBox::error(0, i18n("Error parsing %1: Required attribute NAME is missing in CSSPARAMETER inside POLYGONSYMBOLIZER!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: Required attribute NAME is missing in CSSPARAMETER inside POLYGONSYMBOLIZER!").arg(XmlPath).arg(XmlLine));
return false;
}
}
774,7 → 812,7
}
else
{
KMessageBox::error(0, i18n("Error parsing %1: Required attribute NAME is missing in PARAMETER inside DATASOURCE!").arg(XmlPath));
KMessageBox::error(0, i18n("Error parsing %1, line %2: Required attribute NAME is missing in PARAMETER inside DATASOURCE!").arg(XmlPath).arg(XmlLine));
return false;
}
}
851,208 → 889,247
}
else
{
cerr << "Warning: Layer with no source! Ingnoring!" << endl;
cerr << "Warning file " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Layer with no source! Ingnoring!" << endl;
return true;
}
 
Layer lyr(Lay->name.toAscii().data());
lyr.set_title(Lay->name.toAscii().data());
lyr.set_datasource(datasource_cache::instance()->create(p));
lyr.setActive(Lay->status);
 
if (Lay->minzoom > 0.0)
lyr.setMinZoom(Lay->minzoom);
 
if (Lay->maxzoom > 0.0)
lyr.setMaxZoom(Lay->maxzoom);
 
if (!Lay->srs.isEmpty())
lyr.set_srs(Lay->srs.toAscii().constData());
 
// Add the styles
for (int i = 0; i < Lay->Styles.size(); i++)
lyr.add_style(Lay->Styles.at(i).toAscii().constData());
{
if (findStyle (Lay->Styles.at(i)) != 0)
lyr.add_style(Lay->Styles.at(i).toAscii().constData());
else
cerr << "Warning file " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Style \"" << Lay->Styles.at(i).toAscii().data() << "\" does not exist!" << endl;
}
 
lyr.setActive(Lay->status);
m.addLayer(lyr);
Envelope <double>le(lyr.envelope());
setMaxExtent(le.minx(), le.miny(), le.maxx(), le.maxy());
}
else if (qName.toLower() == QString("map"))
{
color col;
 
Container = in_root;
col.set_bgr(MapPars.bgcolor);
m.set_background(col);
m.set_buffer_size(MapPars.buf_size);
ControlSet = true;
}
else if (qName.toLower() == QString("pointsymbol") ||
qName.toLower() == QString("linesymbol") ||
qName.toLower() == QString("polygonsymbol") ||
qName.toLower() == QString("textsymbol") ||
qName.toLower() == QString("polygonpatternsymbol") ||
qName.toLower() == QString("shieldsymbol") ||
qName.toLower() == QString("linepatternsymbol") ||
qName.toLower() == QString("filter") ||
qName.toLower() == QString("maxscaledenominator") ||
qName.toLower() == QString("minscaledenominator"))
else if (qName.toLower() == QString("pointsymbolizer"))
{
Container = in_rule;
else if (qName.toLower() == QString("rule"))
Container = in_style;
else if (qName.toLower() == QString("style"))
 
if (!Rule || !PointSymbolizer)
{
KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of POINTSYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
return false;
}
 
if (PointSymbolizer->file.length() == 0 || PointSymbolizer->width == 0 || PointSymbolizer->height == 0)
{
cerr << "Warning file " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Empty POINTSYMBOLIZER!" << endl;
point_symbolizer psym;
Rule->rl.append(psym);
}
else
{
point_symbolizer ps(PointSymbolizer->file.toAscii().data(), getTypeText(PointSymbolizer->type), PointSymbolizer->width, PointSymbolizer->height);
ps.set_allow_overlap (PointSymbolizer->allow_overlap);
Rule->rl.append(ps);
}
}
else if (qName.toLower() == QString("linesymbolizer"))
{
Container = in_map;
feature_type_style style;
Container = in_rule;
 
if (Style->rule)
if (!Rule || !LineSymbolizer)
{
rule_type rule;
Rule = Style->rule;
KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of LINESYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
return false;
}
 
while (Rule)
{
if (Rule->minscale >= 0.0)
rule.set_min_scale(Rule->minscale);
stroke st;
color col;
col.set_bgr(LineSymbolizer->stroke);
 
if (Rule->maxscale >= 0.0)
rule.set_max_scale(Rule->maxscale);
st.set_color (col);
 
if (!Rule->filter.isEmpty())
rule.set_filter(create_filter(Rule->filter.toAscii().data()));
if (LineSymbolizer->stroke_width != 0.0)
st.set_width (LineSymbolizer->stroke_width);
 
LineSymbolizer = Rule->LineSymbolizer;
if (!LineSymbolizer->stroke_linejoin.isEmpty())
{
if (LineSymbolizer->stroke_linejoin.toLower() == QString("miter"))
st.set_line_join (mapnik::MITER_JOIN);
else if (LineSymbolizer->stroke_linejoin.toLower() == QString("miter_revert") ||
LineSymbolizer->stroke_linejoin.toLower() == QString("miter-revert"))
st.set_line_join (mapnik::MITER_REVERT_JOIN);
else if (LineSymbolizer->stroke_linejoin.toLower() == QString("round"))
st.set_line_join (mapnik::ROUND_JOIN);
else if (LineSymbolizer->stroke_linejoin.toLower() == QString("bevel"))
st.set_line_join (mapnik::BEVEL_JOIN);
else
cerr << "Error parsing " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Unknown >>line_join<< \"" << LineSymbolizer->stroke_linejoin.toAscii().data() << "\" --> ignoring!" << endl;
}
 
while (LineSymbolizer)
{
stroke st;
color col;
col.set_bgr(LineSymbolizer->stroke);
if (!LineSymbolizer->stroke_linecap.isEmpty())
{
if (LineSymbolizer->stroke_linecap.toLower() == QString("butt"))
st.set_line_cap (mapnik::BUTT_CAP);
else if (LineSymbolizer->stroke_linecap.toLower() == QString("square"))
st.set_line_cap (mapnik::SQUARE_CAP);
else if (LineSymbolizer->stroke_linecap.toLower() == QString("round"))
st.set_line_cap (mapnik::ROUND_CAP);
else
cerr << "Error parsing " << XmlPath.toAscii().data() << ", line " << XmlLine << ": Unknown >>line_cap<< \"" << LineSymbolizer->stroke_linecap.toAscii().data() << "\" --> ignoring!" << endl;
}
 
st.set_color (col);
st.set_width (LineSymbolizer->stroke_width);
if (LineSymbolizer->stroke_dasharray[0] > 0 || LineSymbolizer->stroke_dasharray[1] > 0)
st.add_dash(LineSymbolizer->stroke_dasharray[0], LineSymbolizer->stroke_dasharray[1]);
 
if (!LineSymbolizer->stroke_linejoin.isEmpty())
{
if (LineSymbolizer->stroke_linejoin.toLower() == QString("miter"))
st.set_line_join (mapnik::MITER_JOIN);
else if (LineSymbolizer->stroke_linejoin.toLower() == QString("miter_revert") ||
LineSymbolizer->stroke_linejoin.toLower() == QString("miter-revert"))
st.set_line_join (mapnik::MITER_REVERT_JOIN);
else if (LineSymbolizer->stroke_linejoin.toLower() == QString("round"))
st.set_line_join (mapnik::ROUND_JOIN);
else if (LineSymbolizer->stroke_linejoin.toLower() == QString("bevel"))
st.set_line_join (mapnik::BEVEL_JOIN);
else
{
cerr << "Error parsing " << XmlPath.toAscii().data() << ": Unknown >>line_join<< \"" << LineSymbolizer->stroke_linejoin.toAscii().data() << "\" --> ignoring!" << endl;
LineSymbolizer = LineSymbolizer->next;
continue;
}
}
if (LineSymbolizer->stroke_opacity != 0)
st.set_opacity(LineSymbolizer->stroke_opacity);
 
if (!LineSymbolizer->stroke_linecap.isEmpty())
{
if (LineSymbolizer->stroke_linecap.toLower() == QString("butt"))
st.set_line_cap (mapnik::BUTT_CAP);
else if (LineSymbolizer->stroke_linecap.toLower() == QString("square"))
st.set_line_cap (mapnik::SQUARE_CAP);
else if (LineSymbolizer->stroke_linecap.toLower() == QString("round"))
st.set_line_cap (mapnik::ROUND_CAP);
else
{
cerr << "Error parsing " << XmlPath.toAscii().data() << ": Unknown >>line_cap<< \"" << LineSymbolizer->stroke_linecap.toAscii().data() << "\" --> ignoring!" << endl;
LineSymbolizer = LineSymbolizer->next;
continue;
}
}
Rule->rl.append(line_symbolizer(st));
}
else if (qName.toLower() == QString("polygonsymbolizer"))
{
Container = in_rule;
 
st.add_dash(LineSymbolizer->stroke_dasharray[0], LineSymbolizer->stroke_dasharray[1]);
st.set_opacity(LineSymbolizer->stroke_opacity);
rule.append(line_symbolizer(st));
LineSymbolizer = LineSymbolizer->next;
}
if (!Rule || !PolygonSymbolizer)
{
KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of POLYGONSYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
return false;
}
 
PointSymbolizer = Rule->PointSymbolizer;
color col;
col.set_bgr(PolygonSymbolizer->fill);
 
while (PointSymbolizer)
{
if (PointSymbolizer->file.length() == 0 || PointSymbolizer->width == 0 || PointSymbolizer->height == 0)
{
cerr << "Warning parsing " << XmlPath.toAscii().data() << ": Ignoring empty POINTSYMBOLIZER!" << endl;
break;
}
polygon_symbolizer ps(col);
 
point_symbolizer ps(PointSymbolizer->file.toAscii().data(), getTypeText(PointSymbolizer->type), PointSymbolizer->width, PointSymbolizer->height);
ps.set_allow_overlap (PointSymbolizer->allow_overlap);
rule.append(ps);
PointSymbolizer = PointSymbolizer->next;
}
if (PolygonSymbolizer->fill_opacity > 0.0)
ps.set_opacity(PolygonSymbolizer->fill_opacity);
 
PolygonSymbolizer = Rule->PolygonSymbolizer;
Rule->rl.append(ps);
}
else if (qName.toLower() == QString("textsymbolizer"))
{
Container = in_rule;
 
while (PolygonSymbolizer)
{
color col;
col.set_bgr(PolygonSymbolizer->fill);
if (!Rule || !TextSymbolizer)
{
KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of TEXTSYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
return false;
}
 
polygon_symbolizer ps(col);
ps.set_opacity(PolygonSymbolizer->fill_opacity);
rule.append(ps);
PolygonSymbolizer = PolygonSymbolizer->next;
}
color col;
col.set_bgr(TextSymbolizer->fill);
 
TextSymbolizer = Rule->TextSymbolizer;
text_symbolizer ts(TextSymbolizer->name.toAscii().data(), TextSymbolizer->face_name.toAscii().data(), TextSymbolizer->size, col);
 
while (TextSymbolizer)
{
color col;
col.set_bgr(TextSymbolizer->fill);
if (TextSymbolizer->halo_radius != 0.0)
ts.set_halo_radius((unsigned int)TextSymbolizer->halo_radius);
 
text_symbolizer ts(TextSymbolizer->name.toAscii().data(), TextSymbolizer->face_name.toAscii().data(), TextSymbolizer->size, col);
ts.set_halo_radius((unsigned int)TextSymbolizer->halo_radius);
ts.set_wrap_width((unsigned int)TextSymbolizer->wrap_width);
ts.set_max_char_angle_delta(TextSymbolizer->dy);
ts.set_displacement(TextSymbolizer->mindistance, TextSymbolizer->maxdistance);
rule.append(ts);
TextSymbolizer = TextSymbolizer->next;
}
if (TextSymbolizer->wrap_width != 0.0)
ts.set_wrap_width((unsigned int)TextSymbolizer->wrap_width);
 
PolygonPatternSymbolizer = Rule->PolygonPatternSymbolizer;
if (TextSymbolizer->mindistance != 0)
ts.set_label_spacing(TextSymbolizer->mindistance);
 
while (PolygonPatternSymbolizer)
{
// FIXME: The file name must be variable and KDE like!!
rule.append(polygon_pattern_symbolizer(PolygonPatternSymbolizer->file.toAscii().data(),
getTypeText(PolygonPatternSymbolizer->type),
PolygonPatternSymbolizer->width,
PolygonPatternSymbolizer->height));
PolygonPatternSymbolizer = PolygonPatternSymbolizer->next;
}
if (TextSymbolizer->dx != 0 || TextSymbolizer->dy != 0)
ts.set_displacement(TextSymbolizer->dx, TextSymbolizer->dy);
 
ShieldSymbolizer = Rule->ShieldSymbolizer;
Rule->rl.append(ts);
}
else if (qName.toLower() == QString("polygonpatternsymbolizer"))
{
Container = in_rule;
 
while (ShieldSymbolizer)
{
color col;
col.set_bgr(ShieldSymbolizer->fill);
// FIXME: The file name must be variable and KDE like!!
shield_symbolizer ss(ShieldSymbolizer->name.toAscii().data(),
ShieldSymbolizer->face_name.toAscii().data(),
ShieldSymbolizer->size, col,
ShieldSymbolizer->file.toAscii().data(),
getTypeText(ShieldSymbolizer->type),
ShieldSymbolizer->width, ShieldSymbolizer->height);
ss.set_label_placement((ShieldSymbolizer->placement.toLower() == QString("point")) ? mapnik::POINT_PLACEMENT : mapnik::LINE_PLACEMENT);
ss.set_displacement(ShieldSymbolizer->mindistance, ShieldSymbolizer->maxdistance);
rule.append(ss);
ShieldSymbolizer = ShieldSymbolizer->next;
}
if (!Rule || !PolygonPatternSymbolizer)
{
KMessageBox::error(0, i18n("Error parsing %1, line %2: Endin of POLYGONPATTERNSYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
return false;
}
 
LinePatternSymbolizer = Rule->LinePatternSymbolizer;
Rule->rl.append(polygon_pattern_symbolizer(findIcon(PolygonPatternSymbolizer->file).toAscii().data(),
getTypeText(PolygonPatternSymbolizer->type),
PolygonPatternSymbolizer->width,
PolygonPatternSymbolizer->height));
PolygonPatternSymbolizer = PolygonPatternSymbolizer->next;
}
else if (qName.toLower() == QString("shieldsymbolizer"))
{
Container = in_rule;
 
while (LinePatternSymbolizer)
{
// FIXME: The file name must be variable and KDE like!!
rule.append(line_pattern_symbolizer(LinePatternSymbolizer->file.toAscii().data(),
getTypeText(LinePatternSymbolizer->type),
LinePatternSymbolizer->width,
LinePatternSymbolizer->height));
LinePatternSymbolizer = LinePatternSymbolizer->next;
}
if (!Rule || !ShieldSymbolizer)
{
KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of SHIELDSYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
return false;
}
 
style.add_rule(rule);
color col;
col.set_bgr(ShieldSymbolizer->fill);
shield_symbolizer ss(ShieldSymbolizer->name.toAscii().data(),
ShieldSymbolizer->face_name.toAscii().data(),
ShieldSymbolizer->size, col,
findIcon(ShieldSymbolizer->file).toAscii().data(),
getTypeText(ShieldSymbolizer->type),
ShieldSymbolizer->width, ShieldSymbolizer->height);
 
if (!ShieldSymbolizer->placement.isEmpty())
ss.set_label_placement((ShieldSymbolizer->placement.toLower() == QString("point")) ? mapnik::POINT_PLACEMENT : mapnik::LINE_PLACEMENT);
 
if (ShieldSymbolizer->dx != 0 || ShieldSymbolizer->dy != 0)
ss.set_displacement(ShieldSymbolizer->dx, ShieldSymbolizer->dy);
 
if (ShieldSymbolizer->mindistance != 0)
ss.set_label_spacing(ShieldSymbolizer->mindistance);
 
Rule->rl.append(ss);
}
else if (qName.toLower() == QString("linepatternsymbolizer"))
{
Container = in_rule;
 
if (!Rule || !LinePatternSymbolizer)
{
KMessageBox::error(0, i18n("Error parsing %1, line %2: Ending of LINEPATTERNSYMBOLIZER without start, or outside of a RULE detected!").arg(XmlPath).arg(XmlLine));
return false;
}
 
Rule->rl.append(line_pattern_symbolizer(findIcon(LinePatternSymbolizer->file).toAscii().data(),
getTypeText(LinePatternSymbolizer->type),
LinePatternSymbolizer->width,
LinePatternSymbolizer->height));
}
else if (qName.toLower() == QString("filter") ||
qName.toLower() == QString("maxscaledenominator") ||
qName.toLower() == QString("minscaledenominator"))
Container = in_rule;
else if (qName.toLower() == QString("rule"))
Container = in_style;
else if (qName.toLower() == QString("style"))
{
Container = in_map;
feature_type_style style;
 
if (Style->rule)
{
Rule = Style->rule;
 
while (Rule)
{
style.add_rule(Rule->rl);
Rule = Rule->next;
}
}
1068,19 → 1145,40
* The reader calls this function when it has parsed a chunk of character data
* - either normal character data or character data inside a CDATA section.
*/
bool SRender::characters (const QString& ch)
bool SRender::characters (const QString& chraw)
{
if (ch.length() == 0 || ch.at(0) == QChar('\n'))
QString ch = chraw.trimmed();
 
if (ch.length() == 0)
return true;
 
if (ch.at(0) == QChar('\n'))
{
XmlLine++;
return true;
}
 
if (Container == in_rule && Rule)
{
if (Field == FLD_FILTER)
{
Rule->filter = ch;
 
if (!Rule->filter.isEmpty())
Rule->rl.set_filter(create_filter(Rule->filter.toAscii().data()));
else
cerr << "Warning in file " << XmlPath.toAscii().data() << " at line " << XmlLine << ": Ignoring empty filter!" << endl;
}
else if (Field == FLD_MAXSCALE)
{
Rule->maxscale = ch.toDouble();
Rule->rl.set_max_scale(Rule->maxscale);
}
else if (Field == FLD_MINSCALE)
{
Rule->minscale = ch.toDouble();
Rule->rl.set_min_scale(Rule->minscale);
}
}
else if (Container == in_linesymbolizer && LineSymbolizer)
{
1105,10 → 1203,7
list = arr.split(",", QString::SkipEmptyParts);
 
for (pos = 0; pos < list.size() && pos < 10; pos++)
{
LineSymbolizer->stroke_dasharray[pos] = list.at(pos).toDouble();
pos++;
}
 
LineSymbolizer->stroke_anz = pos;
}
1136,7 → 1231,26
if (Names == type)
Lay->Datasource.type = ch;
else if (Names == file)
Lay->Datasource.file = ch;
{
QFileInfo qf(ch);
QString hv0;
 
hv0 = shapePath;
 
if (hv0.right(1) != QString("/"))
hv0 += "/";
 
hv0 += qf.fileName();
qf.setFile (hv0 + ".shp");
 
if (!qf.exists())
{
KMessageBox::error(0, i18n("The shape file \"%1\" at line %2 does not exist!").arg(hv0+".shp").arg(XmlLine));
return false;
}
 
Lay->Datasource.file = hv0;
}
else if (Names == host)
Lay->Datasource.host = ch;
else if (Names == user)
1152,10 → 1266,18
QString arr = ch;
QStringList list;
list = arr.split(",");
Lay->Datasource.ext_lx = list.at(0).toDouble();
Lay->Datasource.ext_ly = list.at(1).toDouble();
Lay->Datasource.ext_rx = list.at(2).toDouble();
Lay->Datasource.ext_ry = list.at(3).toDouble();
 
if (list.size() >= 1)
Lay->Datasource.ext_lx = list.at(0).toDouble();
 
if (list.size() >= 2)
Lay->Datasource.ext_ly = list.at(1).toDouble();
 
if (list.size() >= 3)
Lay->Datasource.ext_rx = list.at(2).toDouble();
 
if (list.size() >= 4)
Lay->Datasource.ext_ry = list.at(3).toDouble();
}
}
}
1229,14 → 1351,25
 
bool SRender::getMap (double lx, double ly, double rx, double ry)
{
int width, height, pid;
int width, height;
QXmlSimpleReader reader;
QString hv0;
QFile file(XmlPath);
double plx, ply, prx, pry;
 
hv0 = pluginPath + "/";
OutBuf.clear();
hv0 = pluginPath;
 
if (hv0.right(1) != QString("/"))
hv0 += "/";
 
datasource_cache::instance()->register_datasources(hv0.toAscii().data());
hv0 = fontPath + "/DejaVuSans.ttf";
hv0 = fontPath;
 
if (hv0.right(1) != QString("/"))
hv0 += "/";
 
hv0 += "DejaVuSans.ttf";
freetype_engine::register_font(hv0.toAscii().data());
 
width = label->width();
1244,6 → 1377,7
 
m.setWidth(width);
m.setHeight(height);
// load_map(m, XmlPath.toAscii().data());
 
if (!ControlSet) // Initialize the map?
{
1252,26 → 1386,105
reader.parse (source);
}
 
save_map(m, "/home/andreas/.sportwatcher/spw.xml");
// save_map(m, "/home/andreas/.sportwatcher/spw1.xml");
plx = lx;
ply = ly;
prx = rx;
pry = ry;
projection pj(m.srs());
 
if (pj.is_geographic())
{
pj.inverse(plx, ply);
pj.inverse(prx, pry);
cout << "Geographic! Inverse projection." << endl;
}
else
{
// pj.forward(plx, ply);
// pj.forward(prx, pry);
cout << "NOT geographic!" << endl;
}
 
for (unsigned i = 0; i < m.layerCount(); i++)
{
bool vis = m.getLayer(i).isVisible(m.scale_denominator());
cout << "Layer " << i << ": " << m.getLayer(i).name();
cout << ", Visible: " << vis;
Envelope <double>e(m.getLayer(i).envelope());
cout << ", Extent: " << e.minx() << ", " << e.miny() << ", " << e.maxx() << ", " << e.maxy() << endl;
}
 
// First we use Mapnik to create the map
cout << lx << ", " << ly << ", " << rx << ", " << ry << endl;
//cout << DEG2RAD(lx) << ", " << DEG2RAD(ly) << ", " << DEG2RAD(rx) << ", " << DEG2RAD(ry) << endl;
m.zoomToBox(Envelope<double>(lx, ly, rx, ry));
m.zoomToBox(Envelope<double>(plx, ply, prx, pry));
 
Envelope <double>e(m.getCurrentExtent());
cout << std::setprecision(16) << "Parameter envelope: " << lx << ", " << ly << ", " << rx << ", " << ry << endl;
cout << std::setprecision(16) << "Converted envelope: " << plx << ", " << ply << ", " << prx << ", " << pry << endl;
cout << std::setprecision(16) << "Current extent: " << e.minx() << ", " << e.miny() << ", " << e.maxx() << ", " << e.maxy() << endl;
cout << "SRS: " << m.srs() << endl;
cout << std::setprecision(16) << "Scale: " << m.scale() << ", scale denominator: " << m.scale_denominator() << endl;
cout << "width=" << m.getWidth() << ", height=" << m.getHeight() << endl;
 
Image32 buf(m.getWidth(), m.getHeight());
agg_renderer<Image32> ren(m, buf);
ren.apply();
// Put the image into a Qt object
QImage image((uchar*)buf.raw_data(), m.getWidth(), m.getHeight(), QImage::Format_ARGB32);
label->setPixmap(QPixmap::fromImage(image.rgbSwapped()));
// Create a unique file name
pid = getpid();
hv0.sprintf("/var/tmp/SportWatcher_%d", pid);
save_to_file<ImageData32>(buf.data(), hv0.toAscii().data(), "png");
// pid = getpid();
// OutBuf.sprintf("/var/tmp/SportWatcher_%d.png", pid);
// save_to_file<ImageData32>(buf.data(), OutBuf.toAscii().data(), "png");
 
// Now we move the image into a QPixmap
QPixmap pm;
pm.load(hv0);
unlink(hv0.toAscii().data()); // delete the temporary file
label->setPixmap(pm);
return true;
}
 
void SRender::setMaxExtent(double lx, double ly, double rx, double ry)
{
if (lx > 0 && _lx > lx)
_lx = lx;
 
if (lx < 0 && _lx < lx)
_lx = lx;
 
if (ly > 0 && _ly > ly)
_ly = ly;
 
if (ly < 0 && _ly < ly)
_ly = ly;
 
if (rx > 0 && _rx < rx)
_rx = rx;
 
if (rx < 0 && _rx > rx)
_rx = rx;
 
if (ry > 0 && _ry < ry)
_ry = ry;
 
if (ry < 0 && _ry > ry)
_ry = ry;
}
 
QString SRender::findIcon(QString ic)
{
QString ptf, icon;
QFileInfo fi(ic);
 
icon = fi.fileName();
ptf = KStandardDirs::locate("data", QString("sportwatcher/icons/%1").arg(icon));
 
if (ptf.length() < icon.length())
{
KMessageBox::error(0, i18n("The icon %1 was not found!").arg(icon));
ptf.clear();
}
 
return ptf;
}
 
RULE *SRender::getLastRule(RULE *first)
{
RULE *akt = first;
1411,7 → 1624,7
{
QColor qc(col);
 
return (qc.red() * 65536) + (qc.green() * 256) + qc.blue();
return (qc.blue() * 65536) + (qc.green() * 256) + qc.red();
}
 
STYLE *SRender::allocStyle()
1449,6 → 1662,8
La->name.clear(); // The unique name
La->status = false; // Is it active?
La->srs.clear(); // Projection
La->minzoom = 0.0;
La->maxzoom = 0.0;
La->Datasource.type.clear();
La->Datasource.file.clear();
La->Datasource.host.clear();
1483,12 → 1698,14
ss->name.clear();
ss->face_name.clear();
ss->size = 0.0;
ss->fill = 0; // Color
ss->fill = 0; // Color
ss->placement.clear();
ss->file.clear();
ss->type = type_png; // enum TYPES
ss->width = 0.0;
ss->height = 0.0;
ss->dx = 0.0;
ss->dy = 0.0;
ss->mindistance = 0.0;
ss->maxdistance = 0.0;
ss->next = 0;
1531,6 → 1748,7
ts->fill = 0; // Color
ts->halo_radius = 0;
ts->wrap_width = 0;
ts->dx = 0.0;
ts->dy = 0.0;
ts->mindistance = 0.0;
ts->maxdistance = 0.0;
/sportwatcher/trunk/src/CMakeLists.txt
23,7 → 23,7
sportwatcherwidgetbase.ui
wmswidgetbase.ui)
 
add_definitions(-fexceptions)
add_definitions(-fexceptions -D_REENTRANT)
 
kde4_add_ui_files(sportwatcher_SRCS ${sportwatcher_UI})
kde4_add_app_icon(sportwatcher_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/../src/hi*-app-sportwatcher.png")
/sportwatcher/trunk/src/render.h
13,6 → 13,8
#define _RENDER_H
 
#include <mapnik/map.hpp>
#include <mapnik/load_map.hpp>
#include <mapnik/save_map.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/font_engine_freetype.hpp>
#include <mapnik/agg_renderer.hpp>
22,6 → 24,7
#include <mapnik/config_error.hpp>
#include <mapnik/color.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/rule.hpp>
 
/* conversions */
 
70,9 → 73,10
unsigned fill; // Color
double halo_radius;
double wrap_width;
double dx;
double dy;
double mindistance;
double maxdistance;
double mindistance; // min distance between labels
double maxdistance; // not used!
TEXTSYMBOLIZER *next;
}TEXTSYMBOLIZER;
 
107,8 → 111,10
TYPES type; // enum TYPES
double width;
double height;
double mindistance;
double maxdistance;
double dx;
double dy;
double mindistance; // min distance to next shield symbol
double maxdistance; // not used!
SHIELDSYMBOLIZER *next;
}SHIELDSYMBOLIZER;
 
133,6 → 139,7
POLYGONPATTERNSYMBOLIZER *PolygonPatternSymbolizer;
SHIELDSYMBOLIZER *ShieldSymbolizer;
LINEPATTERNSYMBOLIZER *LinePatternSymbolizer;
mapnik::rule_type rl; // the rule to be added to a style
RULE *next; // Pointer to next rule
}RULE;
 
163,6 → 170,8
QString name; // The unique name
bool status; // Is it active?
QString srs; // Projection
double minzoom;
double maxzoom;
QStringList Styles; // The names of the Styles
DATASOURCE Datasource;
LAYER *next; // Pointer to next layer
231,6 → 240,7
void setShapePath(const QString &str) { if (str.isNull()) return; shapePath = str; };
void setXmlPath(const QString &path) { if (path.isNull()) return; XmlPath = path; };
bool getMap(double lx, double ly, double rx, double ry);
QString getOutBuf () { return OutBuf; };
 
// Functions to parse the XML file
bool startDocument ();
238,6 → 248,10
bool endElement (const QString&, const QString&, const QString&);
bool characters (const QString&);
 
protected:
void setMaxExtent(double lx, double ly, double rx, double ry);
QString findIcon(QString ic);
 
private:
QString getKey (int pos);
TYPES getType(QString ty);
271,9 → 285,12
QString pluginPath;
QString fontPath;
QString XmlPath;
QString OutBuf;
CONTAINER Container;
bool ControlSet;
int Field;
int XmlLine; // Line number of the current position in XML file
double _lx, _ly, _rx, _ry;
TYPES Types;
NAMES Names;
MAP MapPars;
/sportwatcher/trunk/src/sportwatcherwidget.cpp
2749,18 → 2749,34
 
if (shpd.count() < 1)
{
KMessageBox::error(this, i18n("There is no shape file in directory ") + MAP);
KMessageBox::error(this, i18n("There is no shape file in directory %1").arg(MAP));
Fgeo = false;
}
else
{
SRender rd;
QColor bg(220, 220, 220); // background color
 
paint.end();
rd.setDrawArea(*ui_sportwatcherWidgetBase.imgMap);
rd.getMap(posLXY.lat, posLXY.lon, posRXY.lat, posRXY.lon);
pmMap = *ui_sportwatcherWidgetBase.imgMap->pixmap();
paint.begin(&pmMap);
if (curTab == 0)
rd.setDrawArea(*ui_sportwatcherWidgetBase.imgMap);
else
rd.setDrawArea(*ui_sportwatcherWidgetBase.grMap);
 
if (rd.getMap(posLXY.lon, posLXY.lat, posRXY.lon, posRXY.lat))
{
paint.fillRect(0, 0, width+2, height+2, bg);
// QPixmap qpx;
// qpx.load(rd.getOutBuf());
//cout << "Pixmap loaded from: " << rd.getOutBuf().toAscii().data() << endl;
if (curTab == 0)
paint.drawPixmap(0, 0, *ui_sportwatcherWidgetBase.imgMap->pixmap());
else
paint.drawPixmap(0, 0, *ui_sportwatcherWidgetBase.grMap->pixmap());
 
Fgeo = true;
}
else
Fgeo = false;
}
}
else