File indexing completed on 2024-04-14 03:48:07

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2007 Murad Tagirov <tmurad@gmail.com>
0004 // SPDX-FileCopyrightText: 2009 Patrick Spendrin <ps_ml@gmx.de>
0005 // SPDX-FileCopyrightText: 2015 Marius-Valeriu Stanciu <stanciumarius94@gmail.com>
0006 // SPDX-FileCopyrightText: 2016 Dennis Nienhüser <nienhueser@kde.org>
0007 //
0008 
0009 #include "StyleBuilder.h"
0010 
0011 #include "MarbleDirs.h"
0012 #include "OsmPlacemarkData.h"
0013 #include "OsmcSymbol.h"
0014 #include "GeoDataGeometry.h"
0015 #include "GeoDataLinearRing.h"
0016 #include "GeoDataLineString.h"
0017 #include "GeoDataPlacemark.h"
0018 #include "GeoDataPoint.h"
0019 #include "GeoDataPolygon.h"
0020 #include "GeoDataIconStyle.h"
0021 #include "GeoDataLabelStyle.h"
0022 #include "GeoDataLineStyle.h"
0023 #include "GeoDataPolyStyle.h"
0024 
0025 #include <QApplication>
0026 #include <QFont>
0027 #include <QImage>
0028 #include <QDate>
0029 #include <QSet>
0030 #include <QScreen>
0031 #include <QDebug>
0032 
0033 namespace Marble
0034 {
0035 
0036 class StyleBuilder::Private
0037 {
0038 public:
0039     Private();
0040 
0041     GeoDataStyle::ConstPtr presetStyle(GeoDataPlacemark::GeoDataVisualCategory visualCategory) const;
0042 
0043     static GeoDataStyle::Ptr createStyle(qreal width, qreal realWidth, const QColor& color,
0044                                   const QColor& outlineColor, bool fill, bool outline,
0045                                   Qt::BrushStyle brushStyle, Qt::PenStyle penStyle,
0046                                   Qt::PenCapStyle capStyle, bool lineBackground,
0047                                   const QVector< qreal >& dashPattern,
0048                                   const QFont& font, const QColor& fontColor = Qt::black,
0049                                   const QString& texturePath = QString());
0050     static GeoDataStyle::Ptr createPOIStyle(const QFont &font, const QString &bitmap,
0051                                      const QColor &textColor = Qt::black,
0052                                      const QColor &color = QColor(0xBE, 0xAD, 0xAD),
0053                                      const QColor &outline = QColor(0xBE, 0xAD, 0xAD).darker(),
0054                                      bool fill = true, bool renderOutline = true);
0055     static GeoDataStyle::Ptr createOsmPOIStyle(const QFont &font, const QString &bitmap,
0056                                         const QColor &textColor = Qt::black,
0057                                         const QColor &color = QColor(0xBE, 0xAD, 0xAD),
0058                                         const QColor &outline = QColor(0xBE, 0xAD, 0xAD).darker());
0059     static GeoDataStyle::Ptr createOsmPOIRingStyle(const QFont &font, const QString &bitmap,
0060                                             const QColor &textColor = Qt::black,
0061                                             const QColor &color = QColor(0xBE, 0xAD, 0xAD),
0062                                             const QColor &outline = QColor(0xBE, 0xAD, 0xAD).darker());
0063     static GeoDataStyle::Ptr createOsmPOIAreaStyle(const QFont &font, const QString &bitmap,
0064                                             const QColor &textColor = Qt::black,
0065                                             const QColor &color = QColor(0xBE, 0xAD, 0xAD),
0066                                             const QColor &outline = QColor(0xBE, 0xAD, 0xAD).darker());
0067     static GeoDataStyle::Ptr createHighwayStyle(const QColor& color, const QColor& outlineColor, const QFont& font,
0068                                          const QColor& fontColor = Qt::black,
0069                                          qreal width = 1, qreal realWidth = 0.0,
0070                                          Qt::PenStyle penStyle = Qt::SolidLine,
0071                                          Qt::PenCapStyle capStyle = Qt::RoundCap,
0072                                          bool lineBackground = false);
0073     GeoDataStyle::Ptr createWayStyle(const QColor& color, const QColor& outlineColor,
0074                                      bool fill = true, bool outline = true,
0075                                      Qt::BrushStyle brushStyle = Qt::SolidPattern,
0076                                      const QString& texturePath = QString()) const;
0077     static GeoDataStyle::Ptr createIconWayStyle(const QColor& color, const QFont &font, const QColor &textColor, double lineWidth=1.0, const QString& iconPath = QString());
0078 
0079     GeoDataStyle::ConstPtr createRelationStyle(const StyleParameters &parameters);
0080     GeoDataStyle::ConstPtr createPlacemarkStyle(const StyleParameters &parameters);
0081     GeoDataStyle::ConstPtr adjustPisteStyle(const StyleParameters &parameters, const GeoDataStyle::ConstPtr &style);
0082     static void adjustWayWidth(const StyleParameters &parameters, GeoDataLineStyle &lineStyle);
0083 
0084     // Having an outline with the same color as the fill results in degraded
0085     // performance and degraded display quality for no good reason
0086     // Q_ASSERT( !(outline && color == outlineColor && brushStyle == Qt::SolidPattern) );
0087     void initializeDefaultStyles();
0088 
0089     static QColor effectColor(const QColor& color);
0090 
0091     static QString createPaintLayerItem(const QString &itemType, GeoDataPlacemark::GeoDataVisualCategory visualCategory, const QString &subType = QString());
0092 
0093     static void initializeOsmVisualCategories();
0094     static void initializeMinimumZoomLevels();
0095 
0096     int m_maximumZoomLevel;
0097     QColor m_defaultLabelColor;
0098     QFont m_defaultFont;
0099     GeoDataStyle::Ptr m_defaultStyle[GeoDataPlacemark::LastIndex];
0100     GeoDataStyle::Ptr m_styleTreeAutumn;
0101     GeoDataStyle::Ptr m_styleTreeWinter;
0102     bool m_defaultStyleInitialized;
0103 
0104     QHash<QString, GeoDataStyle::Ptr> m_styleCache;
0105     QHash<GeoDataPlacemark::GeoDataVisualCategory, GeoDataStyle::Ptr> m_buildingStyles;
0106     QSet<QLocale::Country> m_oceanianCountries;
0107 
0108     /**
0109      * @brief s_visualCategories contains osm tag mappings to GeoDataVisualCategories
0110      */
0111     static QHash<OsmTag, GeoDataPlacemark::GeoDataVisualCategory> s_visualCategories;
0112     static int s_defaultMinZoomLevels[GeoDataPlacemark::LastIndex];
0113     static bool s_defaultMinZoomLevelsInitialized;
0114     static QHash<GeoDataPlacemark::GeoDataVisualCategory, qint64> s_popularities;
0115     static StyleEffect s_styleEffect;
0116 };
0117 
0118 QHash<StyleBuilder::OsmTag, GeoDataPlacemark::GeoDataVisualCategory> StyleBuilder::Private::s_visualCategories;
0119 int StyleBuilder::Private::s_defaultMinZoomLevels[GeoDataPlacemark::LastIndex];
0120 bool StyleBuilder::Private::s_defaultMinZoomLevelsInitialized = false;
0121 QHash<GeoDataPlacemark::GeoDataVisualCategory, qint64> StyleBuilder::Private::s_popularities;
0122 StyleEffect StyleBuilder::Private::s_styleEffect = NoEffect;
0123 
0124 StyleBuilder::Private::Private() :
0125     m_maximumZoomLevel(15),
0126     m_defaultLabelColor(Qt::black),
0127     m_defaultFont(QStringLiteral("Sans Serif")),
0128     m_defaultStyle(),
0129     m_defaultStyleInitialized(false),
0130     m_oceanianCountries(
0131 {
0132     QLocale::Australia, QLocale::NewZealand, QLocale::Fiji,
0133             QLocale::PapuaNewGuinea, QLocale::NewCaledonia, QLocale::SolomonIslands,
0134             QLocale::Samoa, QLocale::Vanuatu, QLocale::Guam,
0135             QLocale::FrenchPolynesia, QLocale::Tonga, QLocale::Palau,
0136             QLocale::Kiribati, QLocale::CookIslands, QLocale::Micronesia,
0137             QLocale::MarshallIslands, QLocale::NauruCountry,
0138             QLocale::AmericanSamoa, QLocale::Niue, QLocale::Pitcairn,
0139             QLocale::WallisAndFutunaIslands, QLocale::NorfolkIsland
0140 })
0141 {
0142     m_oceanianCountries << QLocale::TuvaluCountry << QLocale::OutlyingOceania;
0143     initializeMinimumZoomLevels();
0144     for (int i = 0; i < GeoDataPlacemark::LastIndex; ++i) {
0145         m_maximumZoomLevel = qMax(m_maximumZoomLevel, s_defaultMinZoomLevels[i]);
0146     }
0147 }
0148 
0149 GeoDataStyle::Ptr StyleBuilder::Private::createPOIStyle(const QFont &font, const QString &path,
0150         const QColor &textColor, const QColor &color, const QColor &outlineColor, bool fill, bool renderOutline)
0151 {
0152     GeoDataStyle::Ptr style =  createStyle(1, 0, effectColor(color), effectColor(outlineColor), fill, renderOutline, Qt::SolidPattern, Qt::SolidLine, Qt::RoundCap, false, QVector<qreal>(), font);
0153     style->setIconStyle(GeoDataIconStyle(path));
0154     auto const screen = QApplication::screens().first();
0155     double const physicalSize = 6.0; // mm
0156     int const pixelSize = qRound(physicalSize * screen->physicalDotsPerInch() / (IN2M * M2MM));
0157     style->iconStyle().setSize(QSize(pixelSize, pixelSize));
0158     style->setLabelStyle(GeoDataLabelStyle(font, effectColor(textColor)));
0159     style->labelStyle().setAlignment(GeoDataLabelStyle::Center);
0160     return style;
0161 }
0162 
0163 GeoDataStyle::Ptr StyleBuilder::Private::createOsmPOIStyle(const QFont &font, const QString &imagePath,
0164         const QColor &textColor, const QColor &color, const QColor &outlineColor)
0165 {
0166     QString const path = MarbleDirs::path(QLatin1String("svg/osmcarto/svg/") + imagePath + QLatin1String(".svg"));
0167     return createPOIStyle(font, path, textColor, color, outlineColor, false, false);
0168 }
0169 
0170 GeoDataStyle::Ptr StyleBuilder::Private::createOsmPOIRingStyle(const QFont &font, const QString &imagePath,
0171         const QColor &textColor, const QColor &color, const QColor &outlineColor)
0172 {
0173     QString const path = MarbleDirs::path(QLatin1String("svg/osmcarto/svg/") + imagePath + QLatin1String(".svg"));
0174     return createPOIStyle(font, path, textColor, color, outlineColor, false, true);
0175 }
0176 
0177 GeoDataStyle::Ptr StyleBuilder::Private::createOsmPOIAreaStyle(const QFont &font, const QString &imagePath,
0178         const QColor &textColor, const QColor &color, const QColor &outlineColor)
0179 {
0180     QString const path = MarbleDirs::path(QLatin1String("svg/osmcarto/svg/") + imagePath + QLatin1String(".svg"));
0181     return createPOIStyle(font, path, textColor, color, outlineColor, true, false);
0182 }
0183 
0184 
0185 GeoDataStyle::Ptr StyleBuilder::Private::createHighwayStyle(const QColor& color, const QColor& outlineColor, const QFont& font,
0186         const QColor& fontColor, qreal width, qreal realWidth, Qt::PenStyle penStyle,
0187         Qt::PenCapStyle capStyle, bool lineBackground)
0188 {
0189     return createStyle(width, realWidth, color, outlineColor, true, true, Qt::SolidPattern, penStyle, capStyle, lineBackground, QVector< qreal >(), font, fontColor);
0190 }
0191 
0192 GeoDataStyle::Ptr StyleBuilder::Private::createWayStyle(const QColor& color, const QColor& outlineColor,
0193         bool fill, bool outline, Qt::BrushStyle brushStyle, const QString& texturePath) const
0194 {
0195     return createStyle(1, 0, color, outlineColor, fill, outline, brushStyle, Qt::SolidLine, Qt::RoundCap, false, QVector<qreal>(), m_defaultFont, Qt::black, texturePath);
0196 }
0197 
0198 GeoDataStyle::Ptr StyleBuilder::Private::createIconWayStyle(const QColor &color, const QFont &font, const QColor &textColor, double lineWidth, const QString &iconPath)
0199 {
0200     auto const path = iconPath.isEmpty() ? iconPath : MarbleDirs::path(iconPath);
0201     auto style = createPOIStyle(font, path, textColor, color, color, true, true);
0202     style->lineStyle().setWidth(float(lineWidth));
0203     return style;
0204 }
0205 
0206 GeoDataStyle::ConstPtr StyleBuilder::Private::createRelationStyle(const StyleParameters &parameters)
0207 {
0208     Q_ASSERT(parameters.relation);
0209     const GeoDataPlacemark *const placemark = parameters.placemark;
0210     auto const visualCategory = placemark->visualCategory();
0211     bool const isHighway = visualCategory >= GeoDataPlacemark::HighwaySteps && visualCategory <= GeoDataPlacemark::HighwayMotorway;
0212     bool const isRailway = visualCategory >= GeoDataPlacemark::RailwayRail && visualCategory <= GeoDataPlacemark::RailwayFunicular;
0213     if (isHighway || isRailway) {
0214         if (parameters.relation->relationType() == GeoDataRelation::RouteHiking &&
0215             parameters.relation->osmData().containsTagKey(QStringLiteral("osmc:symbol"))) {
0216             QString const osmcSymbolValue = parameters.relation->osmData().tagValue(QStringLiteral("osmc:symbol"));
0217             // Take cached Style instance if possible
0218             QString const cacheKey = QStringLiteral("/route/hiking/%1").arg(osmcSymbolValue);
0219             if (m_styleCache.contains(cacheKey)) {
0220                 return m_styleCache[cacheKey];
0221             }
0222 
0223             auto style = presetStyle(visualCategory);
0224             auto lineStyle = style->lineStyle();
0225             if (isHighway) {
0226                 adjustWayWidth(parameters, lineStyle);
0227             }
0228             auto iconStyle = style->iconStyle();
0229             GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style));
0230             OsmcSymbol symbol = OsmcSymbol(osmcSymbolValue);
0231             lineStyle.setColor(symbol.wayColor());
0232             iconStyle.setIcon(symbol.icon());
0233             newStyle->setLineStyle(lineStyle);
0234             newStyle->setIconStyle(iconStyle);
0235             style = newStyle;
0236             m_styleCache.insert(cacheKey, newStyle);
0237             return style;
0238         }
0239 
0240         if (parameters.relation->relationType() >= GeoDataRelation::RouteRoad &&
0241             parameters.relation->relationType() <= GeoDataRelation::RouteInlineSkates) {
0242             auto const colorValue = parameters.relation->osmData().tagValue(QStringLiteral("colour"));
0243             QString color = colorValue;
0244             if (!QColor::isValidColor(colorValue)) {
0245                 switch (parameters.relation->relationType()) {
0246                 case GeoDataRelation::RouteTrain:
0247                     color = QStringLiteral("navy"); break;
0248                 case GeoDataRelation::RouteSubway:
0249                     color = QStringLiteral("cornflowerblue"); break;
0250                 case GeoDataRelation::RouteTram:
0251                     color = QStringLiteral("steelblue"); break;
0252                 case GeoDataRelation::RouteBus:
0253                 case GeoDataRelation::RouteTrolleyBus:
0254                     color = QStringLiteral("tomato"); break;
0255                 case GeoDataRelation::RouteBicycle:
0256                 case GeoDataRelation::RouteMountainbike:
0257                 case GeoDataRelation::RouteFoot:
0258                 case GeoDataRelation::RouteHiking:
0259                 case GeoDataRelation::RouteHorse:
0260                 case GeoDataRelation::RouteInlineSkates:
0261                     color = QStringLiteral("paleturquoise"); break;
0262                 case GeoDataRelation::UnknownType:
0263                 case GeoDataRelation:: RouteRoad:
0264                 case GeoDataRelation::RouteDetour:
0265                 case GeoDataRelation::RouteFerry:
0266                 case GeoDataRelation::RouteSkiDownhill:
0267                 case GeoDataRelation::RouteSkiNordic:
0268                 case GeoDataRelation::RouteSkitour:
0269                 case GeoDataRelation::RouteSled:
0270                     color = QString(); break;
0271                 }
0272             }
0273             // Take cached Style instance if possible
0274             QString const cacheKey = QStringLiteral("/route/%1/%2").arg(parameters.relation->relationType()).arg(color);
0275             if (m_styleCache.contains(cacheKey)) {
0276                 return m_styleCache[cacheKey];
0277             }
0278 
0279             auto style = presetStyle(visualCategory);
0280             auto lineStyle = style->lineStyle();
0281             if (isHighway) {
0282                 adjustWayWidth(parameters, lineStyle);
0283             }
0284             GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style));
0285             if (!color.isEmpty()) {
0286                 lineStyle.setColor(QColor(color));
0287                 auto labelStyle = style->labelStyle();
0288                 labelStyle.setColor(GeoDataColorStyle::contrastColor(color));
0289                 newStyle->setLabelStyle(labelStyle);
0290             }
0291             newStyle->setLineStyle(lineStyle);
0292             style = newStyle;
0293             m_styleCache.insert(cacheKey, newStyle);
0294             return style;
0295         }
0296     }
0297     return GeoDataStyle::ConstPtr();
0298 }
0299 
0300 GeoDataStyle::ConstPtr StyleBuilder::Private::createPlacemarkStyle(const StyleParameters &parameters)
0301 {
0302     const GeoDataPlacemark *const placemark = parameters.placemark;
0303     QString styleCacheKey;
0304 
0305     OsmPlacemarkData const & osmData = placemark->osmData();
0306     auto const visualCategory = placemark->visualCategory();
0307     if (visualCategory == GeoDataPlacemark::Building) {
0308         auto const tagMap = osmTagMapping();
0309         auto const & osmData = placemark->osmData();
0310         auto const buildingTag = QStringLiteral("building");
0311         for (auto iter = osmData.tagsBegin(), end = osmData.tagsEnd(); iter != end; ++iter) {
0312             auto const osmTag = StyleBuilder::OsmTag(iter.key(), iter.value());
0313             if (iter.key() != buildingTag && tagMap.contains(osmTag)) {
0314                 return m_buildingStyles.value(tagMap.value(osmTag), m_defaultStyle[visualCategory]);
0315             }
0316         }
0317     }
0318 
0319     GeoDataStyle::ConstPtr style = presetStyle(visualCategory);
0320 
0321     if (geodata_cast<GeoDataPoint>(placemark->geometry())) {
0322         if (visualCategory == GeoDataPlacemark::NaturalTree) {
0323             GeoDataCoordinates const coordinates = placemark->coordinate();
0324             qreal const lat = coordinates.latitude(GeoDataCoordinates::Degree);
0325             if (qAbs(lat) > 15) {
0326                 /** @todo Should maybe auto-adjust to MarbleClock at some point */
0327                 int const month = QDate::currentDate().month();
0328                 bool const southernHemisphere = lat < 0;
0329                 if (southernHemisphere) {
0330                     if (month >= 3 && month <= 5) {
0331                         style = m_styleTreeAutumn;
0332                     } else if (month >= 6 && month <= 8) {
0333                         style = m_styleTreeWinter;
0334                     }
0335                 } else {
0336                     if (month >= 9 && month <= 11) {
0337                         style = m_styleTreeAutumn;
0338                     } else if (month == 12 || month == 1 || month == 2) {
0339                         style = m_styleTreeWinter;
0340                     }
0341                 }
0342             }
0343         }
0344     } else if (geodata_cast<GeoDataLinearRing>(placemark->geometry())) {
0345         bool adjustStyle = false;
0346 
0347         GeoDataPolyStyle polyStyle = style->polyStyle();
0348         GeoDataLineStyle lineStyle = style->lineStyle();
0349         if (visualCategory == GeoDataPlacemark::NaturalWater) {
0350             if (osmData.containsTag(QStringLiteral("salt"), QStringLiteral("yes"))) {
0351                 polyStyle.setColor(effectColor("#ffff80"));
0352                 lineStyle.setPenStyle(Qt::DashLine);
0353                 lineStyle.setWidth(2);
0354                 adjustStyle = true;
0355             }
0356         } else if (visualCategory == GeoDataPlacemark::Bathymetry) {
0357             auto tagIter = osmData.findTag(QStringLiteral("ele"));
0358             if (tagIter != osmData.tagsEnd()) {
0359                 const QString& elevation = tagIter.value();
0360                 if (elevation == QLatin1String("4000")) {
0361                     polyStyle.setColor(effectColor("#94c2c2"));
0362                     lineStyle.setColor(effectColor("#94c2c2"));
0363                     adjustStyle = true;
0364                 }
0365             }
0366         } else if (visualCategory == GeoDataPlacemark::AmenityGraveyard || visualCategory == GeoDataPlacemark::LanduseCemetery) {
0367             auto tagIter = osmData.findTag(QStringLiteral("religion"));
0368             if (tagIter != osmData.tagsEnd()) {
0369                 const QString& religion = tagIter.value();
0370                 if (religion == QLatin1String("jewish")) {
0371                     polyStyle.setTexturePath(MarbleDirs::path("bitmaps/osmcarto/patterns/grave_yard_jewish.png"));
0372                     adjustStyle = true;
0373                 } else if (religion == QLatin1String("christian")) {
0374                     polyStyle.setTexturePath(MarbleDirs::path("bitmaps/osmcarto/patterns/grave_yard_christian.png"));
0375                     adjustStyle = true;
0376                 } else if (religion == QLatin1String("INT-generic")) {
0377                     polyStyle.setTexturePath(MarbleDirs::path("bitmaps/osmcarto/patterns/grave_yard_generic.png"));
0378                     adjustStyle = true;
0379                 }
0380             }
0381         } else if (visualCategory == GeoDataPlacemark::PisteDownhill) {
0382             return adjustPisteStyle(parameters, style);
0383         }
0384 
0385         if (adjustStyle) {
0386             GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style));
0387             newStyle->setPolyStyle(polyStyle);
0388             newStyle->setLineStyle(lineStyle);
0389             style = newStyle;
0390         }
0391 
0392         if (style->iconStyle().iconPath().isEmpty()) {
0393             const GeoDataPlacemark::GeoDataVisualCategory category = determineVisualCategory(osmData);
0394             const GeoDataStyle::ConstPtr categoryStyle = presetStyle(category);
0395             if (category != GeoDataPlacemark::None && !categoryStyle->iconStyle().scaledIcon().isNull()) {
0396                 GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style));
0397                 newStyle->setIconStyle(categoryStyle->iconStyle());
0398                 style = newStyle;
0399             }
0400         }
0401     } else if (geodata_cast<GeoDataLineString>(placemark->geometry())) {
0402         GeoDataPolyStyle polyStyle = style->polyStyle();
0403         GeoDataLineStyle lineStyle = style->lineStyle();
0404         GeoDataLabelStyle labelStyle = style->labelStyle();
0405         GeoDataIconStyle iconStyle = style->iconStyle();
0406         lineStyle.setCosmeticOutline(true);
0407 
0408         bool adjustStyle = false;
0409 
0410         if (visualCategory == GeoDataPlacemark::AdminLevel2) {
0411             if (osmData.containsTag(QStringLiteral("maritime"), QStringLiteral("yes"))) {
0412                 lineStyle.setColor(effectColor("#88b3bf"));
0413                 polyStyle.setColor(effectColor("#88b3bf"));
0414                 if (osmData.containsTag(QStringLiteral("marble:disputed"), QStringLiteral("yes"))) {
0415                     lineStyle.setPenStyle(Qt::DashLine);
0416                 }
0417                 adjustStyle = true;
0418             }
0419         } else if ((visualCategory >= GeoDataPlacemark::HighwayService &&
0420                     visualCategory <= GeoDataPlacemark::HighwayMotorway) ||
0421                    visualCategory == GeoDataPlacemark::TransportAirportRunway) {
0422             // Take cached Style instance if possible
0423             styleCacheKey = QStringLiteral("%1/%2").arg(parameters.tileLevel).arg(visualCategory);
0424             if (m_styleCache.contains(styleCacheKey)) {
0425                 style = m_styleCache[styleCacheKey];
0426                 return style;
0427             }
0428 
0429             adjustStyle = true;
0430             styleCacheKey = QStringLiteral("%1/%2").arg(parameters.tileLevel).arg(visualCategory);
0431             adjustWayWidth(parameters, lineStyle);
0432 
0433             QString const accessValue = osmData.tagValue(QStringLiteral("access"));
0434             if (accessValue == QLatin1String("private") ||
0435                 accessValue == QLatin1String("no") ||
0436                 accessValue == QLatin1String("agricultural") ||
0437                 accessValue == QLatin1String("delivery") ||
0438                 accessValue == QLatin1String("forestry")) {
0439                 QColor polyColor = polyStyle.color();
0440                 qreal hue, sat, val;
0441                 polyColor.getHsvF(&hue, &sat, &val);
0442                 polyColor.setHsvF(0.98, qMin(1.0, 0.2 + sat), val);
0443                 polyStyle.setColor(effectColor(polyColor));
0444                 lineStyle.setColor(effectColor(lineStyle.color().darker(150)));
0445             }
0446 
0447             if (osmData.containsTag("tunnel", "yes")) {
0448                 QColor polyColor = polyStyle.color();
0449                 qreal hue, sat, val;
0450                 polyColor.getHsvF(&hue, &sat, &val);
0451                 polyColor.setHsvF(hue, 0.25 * sat, 0.95 * val);
0452                 polyStyle.setColor(effectColor(polyColor));
0453                 lineStyle.setColor(effectColor(lineStyle.color().lighter(115)));
0454             }
0455 
0456         } else if (visualCategory >= GeoDataPlacemark::WaterwayCanal && visualCategory <= GeoDataPlacemark::WaterwayStream) {
0457 
0458             adjustStyle = true;
0459 
0460             // Take cached Style instance if possible
0461             styleCacheKey = QStringLiteral("%1/%2").arg(parameters.tileLevel).arg(visualCategory);
0462             if (m_styleCache.contains(styleCacheKey)) {
0463                 style = m_styleCache[styleCacheKey];
0464                 return style;
0465             }
0466 
0467 
0468             if (parameters.tileLevel <= 3) {
0469                 lineStyle.setWidth(1);
0470                 lineStyle.setPhysicalWidth(0.0);
0471                 styleCacheKey = QStringLiteral("%1/%2").arg(parameters.tileLevel).arg(visualCategory);
0472             } else if (parameters.tileLevel <= 7) {
0473                 lineStyle.setWidth(2);
0474                 lineStyle.setPhysicalWidth(0.0);
0475                 styleCacheKey = QStringLiteral("%1/%2").arg(parameters.tileLevel).arg(visualCategory);
0476             } else {
0477                 QString const widthValue = osmData.tagValue(QStringLiteral("width")).remove(QStringLiteral(" meters")).remove(QStringLiteral(" m"));
0478                 bool ok;
0479                 float const width = widthValue.toFloat(&ok);
0480                 lineStyle.setPhysicalWidth(ok ? qBound(0.1f, width, 200.0f) : 0.0f);
0481             }
0482         } else if (visualCategory == GeoDataPlacemark::PisteDownhill) {
0483             return adjustPisteStyle(parameters, style);
0484         }
0485 
0486         if (adjustStyle) {
0487             GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style));
0488             newStyle->setPolyStyle(polyStyle);
0489             newStyle->setLineStyle(lineStyle);
0490             newStyle->setLabelStyle(labelStyle);
0491             newStyle->setIconStyle(iconStyle);
0492             style = newStyle;
0493             if (!styleCacheKey.isEmpty()) {
0494                 m_styleCache.insert(styleCacheKey, newStyle);
0495             }
0496         }
0497 
0498     } else if (geodata_cast<GeoDataPolygon>(placemark->geometry())) {
0499         GeoDataPolyStyle polyStyle = style->polyStyle();
0500         GeoDataLineStyle lineStyle = style->lineStyle();
0501         bool adjustStyle = false;
0502         if (visualCategory == GeoDataPlacemark::Bathymetry) {
0503             auto tagIter = osmData.findTag(QStringLiteral("ele"));
0504             if (tagIter != osmData.tagsEnd()) {
0505                 const QString& elevation = tagIter.value();
0506                 if (elevation == QLatin1String("4000")) {
0507                     polyStyle.setColor(effectColor("#a5c9c9"));
0508                     lineStyle.setColor(effectColor("#a5c9c9"));
0509                     adjustStyle = true;
0510                 }
0511             }
0512         } else if (visualCategory == GeoDataPlacemark::PisteDownhill) {
0513             return adjustPisteStyle(parameters, style);
0514         }
0515 
0516         if (adjustStyle) {
0517             GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style));
0518             newStyle->setPolyStyle(polyStyle);
0519             newStyle->setLineStyle(lineStyle);
0520             style = newStyle;
0521         }
0522 
0523     }
0524 
0525     return style;
0526 }
0527 
0528 GeoDataStyle::ConstPtr StyleBuilder::Private::adjustPisteStyle(const StyleParameters &parameters, const GeoDataStyle::ConstPtr &style)
0529 {
0530     // Take cached Style instance if possible
0531     auto const & osmData = parameters.placemark->osmData();
0532     auto const visualCategory = parameters.placemark->visualCategory();
0533     auto const difficulty = osmData.tagValue("piste:difficulty");
0534     QString styleCacheKey = QStringLiteral("piste/%1/%2").arg(visualCategory).arg(difficulty);
0535     if (m_styleCache.contains(styleCacheKey)) {
0536         return m_styleCache[styleCacheKey];
0537     }
0538 
0539     GeoDataLineStyle lineStyle = style->lineStyle();
0540 
0541     auto green = QColor("#006600");
0542     auto red = QColor("#cc0000");
0543     auto black = QColor("#151515");
0544     auto yellow = Qt::yellow;
0545     auto blue = QColor("#000099");
0546     auto orange = QColor(255, 165, 0);
0547     auto fallBack = Qt::lightGray;
0548     auto country = QLocale::system().country();
0549     if (country == QLocale::Japan) {
0550         if (difficulty == "easy") {
0551             lineStyle.setColor(green);
0552         } else if (difficulty == "intermediate") {
0553             lineStyle.setColor(red);
0554         } else if (difficulty == "advanced") {
0555             lineStyle.setColor(black);
0556         } else {
0557             lineStyle.setColor(fallBack);
0558         }
0559     } else if (country == QLocale::UnitedStates ||
0560                country == QLocale::UnitedStatesMinorOutlyingIslands ||
0561                country == QLocale::Canada ||
0562                m_oceanianCountries.contains(country)) {
0563         if (difficulty == "easy") {
0564             lineStyle.setColor(green);
0565         } else if (difficulty == "intermediate") {
0566             lineStyle.setColor(blue);
0567         } else if (difficulty == "advanced" || difficulty == "expert") {
0568             lineStyle.setColor(black);
0569         } else {
0570             lineStyle.setColor(fallBack);
0571         }
0572         // fallback on Europe
0573     } else {
0574         if (difficulty == "novice") {
0575             lineStyle.setColor(green);
0576         } else if (difficulty == "easy") {
0577             lineStyle.setColor(blue);
0578         } else if (difficulty == "intermediate") {
0579             lineStyle.setColor(red);
0580         } else if (difficulty == "advanced") {
0581             lineStyle.setColor(black);
0582         } else if (difficulty == "expert") {
0583             // scandinavian countries have different colors then the rest of Europe
0584             if (country == QLocale::Denmark ||
0585                 country == QLocale::Norway ||
0586                 country == QLocale::Sweden) {
0587                 lineStyle.setColor(black);
0588             } else {
0589                 lineStyle.setColor(orange);
0590             }
0591         } else if (difficulty == "freeride") {
0592             lineStyle.setColor(yellow);
0593         } else {
0594             lineStyle.setColor(fallBack);
0595         }
0596     }
0597 
0598     GeoDataPolyStyle polyStyle = style->polyStyle();
0599     polyStyle.setColor(effectColor(lineStyle.color()));
0600     GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style));
0601     newStyle->setPolyStyle(polyStyle);
0602     newStyle->setLineStyle(lineStyle);
0603     m_styleCache.insert(styleCacheKey, newStyle);
0604     return newStyle;
0605 }
0606 
0607 void StyleBuilder::Private::adjustWayWidth(const StyleParameters &parameters, GeoDataLineStyle &lineStyle)
0608 {
0609     auto const & osmData = parameters.placemark->osmData();
0610     auto const visualCategory = parameters.placemark->visualCategory();
0611     if (parameters.tileLevel <= 8) {
0612         lineStyle.setPhysicalWidth(0.0);
0613         lineStyle.setWidth(2.0);
0614     } else if (parameters.tileLevel <= 10) {
0615         lineStyle.setPhysicalWidth(0.0);
0616         lineStyle.setWidth(3.0);
0617     } else if (parameters.tileLevel <= 12) {
0618         lineStyle.setPhysicalWidth(0.0);
0619         lineStyle.setWidth(4.0);
0620     } else {
0621         auto tagIter = osmData.findTag(QStringLiteral("width"));
0622         if (tagIter != osmData.tagsEnd()) {
0623             QString const widthValue = QString(tagIter.value()).remove(QStringLiteral(" meters")).remove(QStringLiteral(" m"));
0624             bool ok;
0625             float const width = widthValue.toFloat(&ok);
0626             lineStyle.setPhysicalWidth(ok ? qBound(0.1f, width, 200.0f) : 0.0f);
0627         } else {
0628             bool const isOneWay = osmData.containsTag(QStringLiteral("oneway"), QStringLiteral("yes")) ||
0629                                   osmData.containsTag(QStringLiteral("oneway"), QStringLiteral("-1"));
0630             int const lanes = isOneWay ? 1 : 2; // also for motorway which implicitly is one way, but has two lanes and each direction has its own highway
0631             double const laneWidth = 3.0;
0632             double const margins = visualCategory == GeoDataPlacemark::HighwayMotorway ? 2.0 : (isOneWay ? 1.0 : 0.0);
0633             double const physicalWidth = margins + lanes * laneWidth;
0634             lineStyle.setPhysicalWidth(physicalWidth);
0635         }
0636     }
0637 }
0638 
0639 GeoDataStyle::Ptr StyleBuilder::Private::createStyle(qreal width, qreal realWidth, const QColor& color,
0640         const QColor& outlineColor, bool fill, bool outline, Qt::BrushStyle brushStyle, Qt::PenStyle penStyle,
0641         Qt::PenCapStyle capStyle, bool lineBackground, const QVector< qreal >& dashPattern,
0642         const QFont& font, const QColor& fontColor, const QString& texturePath)
0643 {
0644     GeoDataStyle *style = new GeoDataStyle;
0645     GeoDataLineStyle lineStyle(effectColor(outlineColor));
0646     lineStyle.setCapStyle(capStyle);
0647     lineStyle.setPenStyle(penStyle);
0648     lineStyle.setWidth(width);
0649     lineStyle.setPhysicalWidth(realWidth);
0650     lineStyle.setBackground(lineBackground);
0651     lineStyle.setDashPattern(dashPattern);
0652     GeoDataPolyStyle polyStyle(effectColor(color));
0653     polyStyle.setOutline(outline);
0654     polyStyle.setFill(fill);
0655     polyStyle.setBrushStyle(brushStyle);
0656     polyStyle.setTexturePath(texturePath);
0657     GeoDataLabelStyle labelStyle(font, effectColor(fontColor));
0658     style->setLineStyle(lineStyle);
0659     style->setPolyStyle(polyStyle);
0660     style->setLabelStyle(labelStyle);
0661     return GeoDataStyle::Ptr(style);
0662 }
0663 
0664 void StyleBuilder::Private::initializeDefaultStyles()
0665 {
0666     // We need to do this similar to the way KCmdLineOptions works in
0667     // the future: Having a PlacemarkStyleProperty properties[] would
0668     // help here greatly.
0669 
0670     if (m_defaultStyleInitialized) {
0671         return;
0672     }
0673 
0674     m_defaultStyleInitialized = true;
0675 
0676     QString defaultFamily = m_defaultFont.family();
0677 
0678 #ifdef Q_OS_MACX
0679     int defaultSize = 10;
0680 #else
0681     int defaultSize = 8;
0682 #endif
0683 
0684     QColor const defaultLabelColor = effectColor(m_defaultLabelColor);
0685 
0686     m_defaultStyle[GeoDataPlacemark::None]
0687         = GeoDataStyle::Ptr(new GeoDataStyle(QString(),
0688                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0689 
0690     m_defaultStyle[GeoDataPlacemark::Default]
0691         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/default_location.png"),
0692                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0693 
0694     m_defaultStyle[GeoDataPlacemark::Unknown]
0695         = GeoDataStyle::Ptr(new GeoDataStyle(QString(),
0696                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0697 
0698     m_defaultStyle[GeoDataPlacemark::SmallCity]
0699         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_4_white.png"),
0700                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0701 
0702     m_defaultStyle[GeoDataPlacemark::SmallCountyCapital]
0703         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_4_yellow.png"),
0704                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0705 
0706     m_defaultStyle[GeoDataPlacemark::SmallStateCapital]
0707         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_4_orange.png"),
0708                             QFont(defaultFamily, defaultSize, 50, true), defaultLabelColor));
0709 
0710     m_defaultStyle[GeoDataPlacemark::SmallNationCapital]
0711         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_4_red.png"),
0712                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0713 
0714     m_defaultStyle[GeoDataPlacemark::MediumCity]
0715         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_3_white.png"),
0716                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0717 
0718     m_defaultStyle[GeoDataPlacemark::MediumCountyCapital]
0719         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_3_yellow.png"),
0720                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0721 
0722     m_defaultStyle[GeoDataPlacemark::MediumStateCapital]
0723         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_3_orange.png"),
0724                             QFont(defaultFamily, defaultSize, 50, true), defaultLabelColor));
0725 
0726     m_defaultStyle[GeoDataPlacemark::MediumNationCapital]
0727         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_3_red.png"),
0728                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0729 
0730     m_defaultStyle[GeoDataPlacemark::BigCity]
0731         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_2_white.png"),
0732                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0733 
0734     m_defaultStyle[GeoDataPlacemark::BigCountyCapital]
0735         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_2_yellow.png"),
0736                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0737 
0738     m_defaultStyle[GeoDataPlacemark::BigStateCapital]
0739         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_2_orange.png"),
0740                             QFont(defaultFamily, defaultSize, 50, true), defaultLabelColor));
0741 
0742     m_defaultStyle[GeoDataPlacemark::BigNationCapital]
0743         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_2_red.png"),
0744                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0745 
0746     m_defaultStyle[GeoDataPlacemark::LargeCity]
0747         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_1_white.png"),
0748                             QFont(defaultFamily, defaultSize, 75, false), defaultLabelColor));
0749 
0750     m_defaultStyle[GeoDataPlacemark::LargeCountyCapital]
0751         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_1_yellow.png"),
0752                             QFont(defaultFamily, defaultSize, 75, false), defaultLabelColor));
0753 
0754     m_defaultStyle[GeoDataPlacemark::LargeStateCapital]
0755         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_1_orange.png"),
0756                             QFont(defaultFamily, defaultSize, 75, true), defaultLabelColor));
0757 
0758     m_defaultStyle[GeoDataPlacemark::LargeNationCapital]
0759         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_1_red.png"),
0760                             QFont(defaultFamily, defaultSize, 75, false), defaultLabelColor));
0761 
0762     m_defaultStyle[GeoDataPlacemark::Nation]
0763         = GeoDataStyle::Ptr(new GeoDataStyle(QString(),
0764                             QFont(defaultFamily, int(defaultSize * 1.5), 75, false), QColor("#404040")));
0765     // Align area labels centered
0766     m_defaultStyle[GeoDataPlacemark::Nation]->labelStyle().setAlignment(GeoDataLabelStyle::Center);
0767 
0768     QFont osmCityFont = QFont(defaultFamily, int(defaultSize * 1.5), 75, false);
0769     m_defaultStyle[GeoDataPlacemark::PlaceCity] = createOsmPOIStyle(osmCityFont, "place/place-6", QColor("#202020"));
0770     m_defaultStyle[GeoDataPlacemark::PlaceCityCapital] = createOsmPOIStyle(osmCityFont, "place/place-capital-6", QColor("#202020"));
0771     m_defaultStyle[GeoDataPlacemark::PlaceCityNationalCapital] = createOsmPOIStyle(osmCityFont, "place/place-capital-adminlevel2", QColor("#202020"));
0772     m_defaultStyle[GeoDataPlacemark::PlaceSuburb] = createOsmPOIStyle(osmCityFont, QString(), QColor("#707070"));
0773     m_defaultStyle[GeoDataPlacemark::PlaceHamlet] = createOsmPOIStyle(osmCityFont, QString(), QColor("#707070"));
0774     QFont localityFont = osmCityFont;
0775     localityFont.setPointSize(defaultSize);
0776     m_defaultStyle[GeoDataPlacemark::PlaceLocality] = createOsmPOIStyle(localityFont, QString(), QColor("#707070"));
0777     m_defaultStyle[GeoDataPlacemark::PlaceTown] = createOsmPOIStyle(osmCityFont, "place/place-6", QColor("#404040"));
0778     m_defaultStyle[GeoDataPlacemark::PlaceTownCapital] = createOsmPOIStyle(osmCityFont, "place/place-capital-6", QColor("#404040"));
0779     m_defaultStyle[GeoDataPlacemark::PlaceTownNationalCapital] = createOsmPOIStyle(osmCityFont, "place/place-capital-adminlevel2", QColor("#404040"));
0780     m_defaultStyle[GeoDataPlacemark::PlaceVillage] = createOsmPOIStyle(osmCityFont, "place/place-6", QColor("#505050"));
0781     m_defaultStyle[GeoDataPlacemark::PlaceVillageCapital] = createOsmPOIStyle(osmCityFont, "place/place-capital-6", QColor("#505050"));
0782     m_defaultStyle[GeoDataPlacemark::PlaceVillageNationalCapital] = createOsmPOIStyle(osmCityFont, "place/place-capital-adminlevel2", QColor("#505050"));
0783     for (int i = GeoDataPlacemark::PlaceCity; i <= GeoDataPlacemark::PlaceVillageCapital; ++i) {
0784         m_defaultStyle[GeoDataPlacemark::GeoDataVisualCategory(i)]->polyStyle().setFill(false);
0785         m_defaultStyle[GeoDataPlacemark::GeoDataVisualCategory(i)]->polyStyle().setOutline(false);
0786         m_defaultStyle[GeoDataPlacemark::GeoDataVisualCategory(i)]->labelStyle().setAlignment(GeoDataLabelStyle::Center);
0787 
0788         if (i == GeoDataPlacemark::PlaceCityNationalCapital || i == GeoDataPlacemark::PlaceTownNationalCapital || i == GeoDataPlacemark::PlaceVillageNationalCapital) {
0789             m_defaultStyle[GeoDataPlacemark::GeoDataVisualCategory(i)]->iconStyle().setScale(0.55f);
0790         } else {
0791             m_defaultStyle[GeoDataPlacemark::GeoDataVisualCategory(i)]->iconStyle().setScale(0.25);
0792         }
0793     }
0794 
0795     m_defaultStyle[GeoDataPlacemark::Mountain]
0796         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/mountain_1.png"),
0797                             QFont(defaultFamily, int(defaultSize * 0.9), 50, false), defaultLabelColor));
0798 
0799     m_defaultStyle[GeoDataPlacemark::Volcano]
0800         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/volcano_1.png"),
0801                             QFont(defaultFamily, int(defaultSize * 0.9), 50, false), defaultLabelColor));
0802 
0803     m_defaultStyle[GeoDataPlacemark::Mons]
0804         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/mountain_1.png"),
0805                             QFont(defaultFamily, int(defaultSize * 0.9), 50, false), defaultLabelColor));
0806 
0807     m_defaultStyle[GeoDataPlacemark::Valley]
0808         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/valley.png"),
0809                             QFont(defaultFamily, int(defaultSize * 0.9), 50, false), defaultLabelColor));
0810 
0811     m_defaultStyle[GeoDataPlacemark::Continent]
0812         = GeoDataStyle::Ptr(new GeoDataStyle(QString(),
0813                             QFont(defaultFamily, int(defaultSize * 1.7), 50, false), QColor("#bf0303")));
0814     // Align area labels centered
0815     m_defaultStyle[GeoDataPlacemark::Continent]->labelStyle().setAlignment(GeoDataLabelStyle::Center);
0816 
0817     m_defaultStyle[GeoDataPlacemark::Ocean]
0818         = GeoDataStyle::Ptr(new GeoDataStyle(QString(),
0819                             QFont(defaultFamily, int(defaultSize * 1.7), 50, true), QColor("#2c72c7")));
0820     // Align area labels centered
0821     m_defaultStyle[GeoDataPlacemark::Ocean]->labelStyle().setAlignment(GeoDataLabelStyle::Center);
0822 
0823     m_defaultStyle[GeoDataPlacemark::OtherTerrain]
0824         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/other.png"),
0825                             QFont(defaultFamily, int(defaultSize * 0.9), 50, false), defaultLabelColor));
0826 
0827     m_defaultStyle[GeoDataPlacemark::Crater]
0828         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/crater.png"),
0829                             QFont(defaultFamily, int(defaultSize * 0.9), 50, false), defaultLabelColor));
0830 
0831     m_defaultStyle[GeoDataPlacemark::Mare]
0832         = GeoDataStyle::Ptr(new GeoDataStyle(QString(),
0833                             QFont(defaultFamily, int(defaultSize * 1.7), 50, false), QColor("#bf0303")));
0834     // Align area labels centered
0835     m_defaultStyle[GeoDataPlacemark::Mare]->labelStyle().setAlignment(GeoDataLabelStyle::Center);
0836 
0837     m_defaultStyle[GeoDataPlacemark::GeographicPole]
0838         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/pole_1.png"),
0839                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0840 
0841     m_defaultStyle[GeoDataPlacemark::MagneticPole]
0842         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/pole_2.png"),
0843                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0844 
0845     m_defaultStyle[GeoDataPlacemark::ShipWreck]
0846         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/shipwreck.png"),
0847                             QFont(defaultFamily, int(defaultSize * 0.8), 50, false), defaultLabelColor));
0848 
0849     m_defaultStyle[GeoDataPlacemark::AirPort]
0850         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/airport.png"),
0851                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0852 
0853     m_defaultStyle[GeoDataPlacemark::Observatory]
0854         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/observatory.png"),
0855                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0856 
0857     m_defaultStyle[GeoDataPlacemark::OsmSite]
0858         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/osm.png"),
0859                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0860 
0861     m_defaultStyle[GeoDataPlacemark::Coordinate]
0862         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/coordinate.png"),
0863                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0864 
0865 
0866     m_defaultStyle[GeoDataPlacemark::MannedLandingSite]
0867         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/manned_landing.png"),
0868                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0869 
0870     m_defaultStyle[GeoDataPlacemark::RoboticRover]
0871         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/robotic_rover.png"),
0872                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0873 
0874     m_defaultStyle[GeoDataPlacemark::UnmannedSoftLandingSite]
0875         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/unmanned_soft_landing.png"),
0876                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0877 
0878     m_defaultStyle[GeoDataPlacemark::UnmannedHardLandingSite]
0879         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/unmanned_hard_landing.png"),
0880                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
0881 
0882     m_defaultStyle[GeoDataPlacemark::Bookmark]
0883         = createPOIStyle(QFont(defaultFamily, defaultSize, 50, false),
0884                          MarbleDirs::path("svg/bookmark.svg"), m_defaultLabelColor);
0885     m_defaultStyle[GeoDataPlacemark::Bookmark]->iconStyle().setScale(0.75);
0886 
0887     QColor const shopColor("#ac39ac");
0888     QColor const transportationColor("#0092da");
0889     QColor const amenityColor("#734a08");
0890     QColor const healthColor("#da0092");
0891     QColor const airTransportColor("#8461C4");
0892     QColor const educationalAreasAndHospital("#f0f0d8");
0893     QColor const buildingColor("#beadad");
0894     QColor const waterColor("#b5d0d0");
0895     // Allows to visualize multiple repaints of buildings
0896 //    QColor const buildingColor(0, 255, 0, 64);
0897 
0898     QFont const osmFont(defaultFamily, 10, 50, false);
0899     m_defaultStyle[GeoDataPlacemark::AccomodationCamping]      = createOsmPOIRingStyle(osmFont, "transportation/camping.16", transportationColor);
0900     m_defaultStyle[GeoDataPlacemark::AccomodationHostel]       = createOsmPOIStyle(osmFont, "transportation/hostel.16", transportationColor);
0901     m_defaultStyle[GeoDataPlacemark::AccomodationHotel]        = createOsmPOIStyle(osmFont, "transportation/hotel.16", transportationColor);
0902     m_defaultStyle[GeoDataPlacemark::AccomodationMotel]        = createOsmPOIStyle(osmFont, "transportation/motel.16", transportationColor);
0903     m_defaultStyle[GeoDataPlacemark::AccomodationYouthHostel]  = createOsmPOIStyle(osmFont, "transportation/hostel.16", transportationColor);
0904     m_defaultStyle[GeoDataPlacemark::AccomodationGuestHouse]   = createOsmPOIStyle(osmFont, "transportation/guest_house.16", transportationColor);
0905     m_defaultStyle[GeoDataPlacemark::AmenityLibrary]           = createOsmPOIStyle(osmFont, "amenity/library.20", amenityColor);
0906     m_defaultStyle[GeoDataPlacemark::AmenityKindergarten]      = createOsmPOIAreaStyle(osmFont, QString(), amenityColor, educationalAreasAndHospital, amenityColor);
0907     m_defaultStyle[GeoDataPlacemark::EducationCollege]         = createOsmPOIAreaStyle(osmFont, QString(), amenityColor, educationalAreasAndHospital, amenityColor);
0908     m_defaultStyle[GeoDataPlacemark::EducationSchool]          = createOsmPOIAreaStyle(osmFont, QString(), amenityColor, educationalAreasAndHospital, amenityColor);
0909     m_defaultStyle[GeoDataPlacemark::EducationUniversity]      = createOsmPOIAreaStyle(osmFont, QString(), amenityColor, educationalAreasAndHospital, amenityColor);
0910     m_defaultStyle[GeoDataPlacemark::FoodBar]                  = createOsmPOIStyle(osmFont, "amenity/bar.16", amenityColor);
0911     m_defaultStyle[GeoDataPlacemark::FoodBiergarten]           = createOsmPOIStyle(osmFont, "amenity/biergarten.16", amenityColor);
0912     m_defaultStyle[GeoDataPlacemark::FoodCafe]                 = createOsmPOIStyle(osmFont, "amenity/cafe.16", amenityColor);
0913     m_defaultStyle[GeoDataPlacemark::FoodFastFood]             = createOsmPOIStyle(osmFont, "amenity/fast_food.16", amenityColor);
0914     m_defaultStyle[GeoDataPlacemark::FoodPub]                  = createOsmPOIStyle(osmFont, "amenity/pub.16", amenityColor);
0915     m_defaultStyle[GeoDataPlacemark::FoodRestaurant]           = createOsmPOIStyle(osmFont, "amenity/restaurant.16", amenityColor);
0916 
0917     m_defaultStyle[GeoDataPlacemark::HealthDentist]            = createOsmPOIStyle(osmFont, "health/dentist.16", healthColor);
0918     m_defaultStyle[GeoDataPlacemark::HealthDoctors]            = createOsmPOIStyle(osmFont, "health/doctors.16", healthColor);
0919     m_defaultStyle[GeoDataPlacemark::HealthHospital]           = createOsmPOIStyle(osmFont, "health/hospital.16", healthColor, educationalAreasAndHospital, amenityColor);
0920     m_defaultStyle[GeoDataPlacemark::HealthPharmacy]           = createOsmPOIStyle(osmFont, "health/pharmacy.16", healthColor);
0921     m_defaultStyle[GeoDataPlacemark::HealthVeterinary]         = createOsmPOIStyle(osmFont, "health/veterinary-14", healthColor);
0922 
0923     m_defaultStyle[GeoDataPlacemark::MoneyAtm]                 = createOsmPOIStyle(osmFont, "amenity/atm.16", amenityColor);
0924     m_defaultStyle[GeoDataPlacemark::MoneyBank]                = createOsmPOIStyle(osmFont, "amenity/bank.16", amenityColor);
0925 
0926     m_defaultStyle[GeoDataPlacemark::HistoricArchaeologicalSite] = createOsmPOIAreaStyle(osmFont, "amenity/archaeological_site.16", amenityColor, Qt::transparent);
0927     m_defaultStyle[GeoDataPlacemark::AmenityEmbassy]           = createOsmPOIStyle(osmFont, "transportation/embassy.16", transportationColor);
0928     m_defaultStyle[GeoDataPlacemark::AmenityEmergencyPhone]    = createOsmPOIStyle(osmFont, "amenity/emergency_phone.16", amenityColor);
0929     m_defaultStyle[GeoDataPlacemark::AmenityMountainRescue]    = createOsmPOIStyle(osmFont, "amenity/mountain_rescue.16", amenityColor);
0930     m_defaultStyle[GeoDataPlacemark::LeisureWaterPark]         = createOsmPOIStyle(osmFont, "amenity/water_park.16", amenityColor);
0931     m_defaultStyle[GeoDataPlacemark::AmenityCommunityCentre]   = createOsmPOIStyle(osmFont, "amenity/community_centre-14", amenityColor);
0932     m_defaultStyle[GeoDataPlacemark::AmenityFountain]          = createOsmPOIStyle(osmFont, "amenity/fountain-14", QColor("#7989de"), waterColor, waterColor.darker(150));
0933     m_defaultStyle[GeoDataPlacemark::AmenityNightClub]         = createOsmPOIStyle(osmFont, "amenity/nightclub.18", amenityColor);
0934     m_defaultStyle[GeoDataPlacemark::AmenityBench]             = createOsmPOIStyle(osmFont, "individual/bench.16", amenityColor);
0935     m_defaultStyle[GeoDataPlacemark::AmenityCourtHouse]        = createOsmPOIStyle(osmFont, "amenity/courthouse-16", amenityColor);
0936     m_defaultStyle[GeoDataPlacemark::AmenityFireStation]       = createOsmPOIStyle(osmFont, "amenity/firestation.16", amenityColor);
0937     m_defaultStyle[GeoDataPlacemark::AmenityHuntingStand]      = createOsmPOIStyle(osmFont, "manmade/hunting-stand.16", amenityColor);
0938     m_defaultStyle[GeoDataPlacemark::AmenityPolice]            = createOsmPOIStyle(osmFont, "amenity/police.16", amenityColor);
0939     m_defaultStyle[GeoDataPlacemark::AmenityPostBox]           = createOsmPOIStyle(osmFont, "amenity/post_box-12", amenityColor);
0940     m_defaultStyle[GeoDataPlacemark::AmenityPostOffice]        = createOsmPOIStyle(osmFont, "amenity/post_office-14", amenityColor);
0941     m_defaultStyle[GeoDataPlacemark::AmenityPrison]            = createOsmPOIStyle(osmFont, "amenity/prison.16", amenityColor);
0942     m_defaultStyle[GeoDataPlacemark::AmenityRecycling]         = createOsmPOIStyle(osmFont, "amenity/recycling.16", amenityColor);
0943     m_defaultStyle[GeoDataPlacemark::AmenityShelter]           = createOsmPOIStyle(osmFont, "transportation/shelter", transportationColor);
0944     m_defaultStyle[GeoDataPlacemark::AmenityTelephone]         = createOsmPOIStyle(osmFont, "amenity/telephone.16", amenityColor);
0945     m_defaultStyle[GeoDataPlacemark::AmenityToilets]           = createOsmPOIStyle(osmFont, "amenity/toilets.16", amenityColor);
0946     m_defaultStyle[GeoDataPlacemark::AmenityTownHall]          = createOsmPOIStyle(osmFont, "amenity/town_hall.16", amenityColor);
0947     m_defaultStyle[GeoDataPlacemark::AmenityWasteBasket]       = createOsmPOIStyle(osmFont, "individual/waste_basket.10", amenityColor);
0948     m_defaultStyle[GeoDataPlacemark::AmenityWasteBasket]->iconStyle().setScale(0.75);
0949     m_defaultStyle[GeoDataPlacemark::AmenityChargingStation]   = createOsmPOIStyle(osmFont, "transportation/charging_station");
0950     m_defaultStyle[GeoDataPlacemark::AmenityCarWash]           = createOsmPOIStyle(osmFont, "amenity/car_wash", amenityColor);
0951     m_defaultStyle[GeoDataPlacemark::AmenitySocialFacility]    = createOsmPOIStyle(osmFont, "amenity/social_facility", amenityColor);
0952 
0953     m_defaultStyle[GeoDataPlacemark::AmenityDrinkingWater]     = createOsmPOIStyle(osmFont, "amenity/drinking_water.16", amenityColor);
0954 
0955     m_defaultStyle[GeoDataPlacemark::NaturalPeak]              = createOsmPOIStyle(osmFont, "individual/peak", amenityColor);
0956     m_defaultStyle[GeoDataPlacemark::NaturalPeak]->iconStyle().setScale(0.33f);
0957     m_defaultStyle[GeoDataPlacemark::NaturalVolcano]           = createOsmPOIStyle(osmFont, "individual/volcano", amenityColor);
0958     m_defaultStyle[GeoDataPlacemark::NaturalVolcano]->iconStyle().setScale(0.33f);
0959     m_defaultStyle[GeoDataPlacemark::NaturalTree]              = createOsmPOIStyle(osmFont, "individual/tree-29", amenityColor); // tree-16 provides the official icon
0960     m_styleTreeAutumn                                          = createOsmPOIStyle(osmFont, "individual/tree-29-autumn", amenityColor);
0961     m_styleTreeWinter                                          = createOsmPOIStyle(osmFont, "individual/tree-29-winter", amenityColor);
0962     qreal const treeIconScale = 0.75;
0963     m_defaultStyle[GeoDataPlacemark::NaturalTree]->iconStyle().setScale(treeIconScale);
0964     m_styleTreeAutumn->iconStyle().setScale(treeIconScale);
0965     m_styleTreeWinter->iconStyle().setScale(treeIconScale);
0966 
0967     m_defaultStyle[GeoDataPlacemark::ShopBeverages]            = createOsmPOIStyle(osmFont, "shop/beverages-14", shopColor);
0968     m_defaultStyle[GeoDataPlacemark::ShopHifi]                 = createOsmPOIStyle(osmFont, "shop/hifi-14", shopColor);
0969     m_defaultStyle[GeoDataPlacemark::ShopSupermarket]          = createOsmPOIStyle(osmFont, "shop/shop_supermarket", shopColor);
0970     m_defaultStyle[GeoDataPlacemark::ShopAlcohol]              = createOsmPOIStyle(osmFont, "shop/shop_alcohol.16", shopColor);
0971     m_defaultStyle[GeoDataPlacemark::ShopBakery]               = createOsmPOIStyle(osmFont, "shop/shop_bakery.16", shopColor);
0972     m_defaultStyle[GeoDataPlacemark::ShopButcher]              = createOsmPOIStyle(osmFont, "shop/butcher-14", shopColor);
0973     m_defaultStyle[GeoDataPlacemark::ShopConfectionery]        = createOsmPOIStyle(osmFont, "shop/confectionery.14", shopColor);
0974     m_defaultStyle[GeoDataPlacemark::ShopConvenience]          = createOsmPOIStyle(osmFont, "shop/shop_convenience", shopColor);
0975     m_defaultStyle[GeoDataPlacemark::ShopGreengrocer]          = createOsmPOIStyle(osmFont, "shop/greengrocer-14", shopColor);
0976     m_defaultStyle[GeoDataPlacemark::ShopSeafood]              = createOsmPOIStyle(osmFont, "shop/seafood-14", shopColor);
0977     m_defaultStyle[GeoDataPlacemark::ShopDepartmentStore]      = createOsmPOIStyle(osmFont, "shop/department_store-16", shopColor);
0978     m_defaultStyle[GeoDataPlacemark::ShopKiosk]                = createOsmPOIStyle(osmFont, "shop/kiosk-14", shopColor);
0979     m_defaultStyle[GeoDataPlacemark::ShopBag]                  = createOsmPOIStyle(osmFont, "shop/bag-14", shopColor);
0980     m_defaultStyle[GeoDataPlacemark::ShopClothes]              = createOsmPOIStyle(osmFont, "shop/shop_clothes.16", shopColor);
0981     m_defaultStyle[GeoDataPlacemark::ShopFashion]              = createOsmPOIStyle(osmFont, "shop/shop_clothes.16", shopColor);
0982     m_defaultStyle[GeoDataPlacemark::ShopJewelry]              = createOsmPOIStyle(osmFont, "shop/shop_jewelry.16", shopColor);
0983     m_defaultStyle[GeoDataPlacemark::ShopShoes]                = createOsmPOIStyle(osmFont, "shop/shop_shoes.16", shopColor);
0984     m_defaultStyle[GeoDataPlacemark::ShopVarietyStore]         = createOsmPOIStyle(osmFont, "shop/variety_store-14", shopColor);
0985     m_defaultStyle[GeoDataPlacemark::ShopBeauty]               = createOsmPOIStyle(osmFont, "shop/beauty-14", shopColor);
0986     m_defaultStyle[GeoDataPlacemark::ShopChemist]              = createOsmPOIStyle(osmFont, "shop/chemist-14", shopColor);
0987     m_defaultStyle[GeoDataPlacemark::ShopCosmetics]            = createOsmPOIStyle(osmFont, "shop/perfumery-14", shopColor);
0988     m_defaultStyle[GeoDataPlacemark::ShopHairdresser]          = createOsmPOIStyle(osmFont, "shop/shop_hairdresser.16", shopColor);
0989     m_defaultStyle[GeoDataPlacemark::ShopOptician]             = createOsmPOIStyle(osmFont, "shop/shop_optician.16", shopColor);
0990     m_defaultStyle[GeoDataPlacemark::ShopPerfumery]            = createOsmPOIStyle(osmFont, "shop/perfumery-14", shopColor);
0991     m_defaultStyle[GeoDataPlacemark::ShopDoitYourself]         = createOsmPOIStyle(osmFont, "shop/shop_diy.16", shopColor);
0992     m_defaultStyle[GeoDataPlacemark::ShopFlorist]              = createOsmPOIStyle(osmFont, "shop/florist.16", shopColor);
0993     m_defaultStyle[GeoDataPlacemark::ShopHardware]             = createOsmPOIStyle(osmFont, "shop/shop_diy.16", shopColor);
0994     m_defaultStyle[GeoDataPlacemark::ShopFurniture]            = createOsmPOIStyle(osmFont, "shop/shop_furniture.16", shopColor);
0995     m_defaultStyle[GeoDataPlacemark::ShopElectronics]          = createOsmPOIStyle(osmFont, "shop/shop_electronics.16", shopColor);
0996     m_defaultStyle[GeoDataPlacemark::ShopMobilePhone]          = createOsmPOIStyle(osmFont, "shop/shop_mobile_phone.16", shopColor);
0997     m_defaultStyle[GeoDataPlacemark::ShopBicycle]              = createOsmPOIStyle(osmFont, "shop/shop_bicycle.16", shopColor);
0998     m_defaultStyle[GeoDataPlacemark::ShopCar]                  = createOsmPOIStyle(osmFont, "shop/shop_car", shopColor);
0999     m_defaultStyle[GeoDataPlacemark::ShopCarRepair]            = createOsmPOIStyle(osmFont, "shop/shopping_car_repair.16", shopColor);
1000     m_defaultStyle[GeoDataPlacemark::ShopCarParts]             = createOsmPOIStyle(osmFont, "shop/car_parts-14", shopColor);
1001     m_defaultStyle[GeoDataPlacemark::ShopMotorcycle]           = createOsmPOIStyle(osmFont, "shop/motorcycle-14", shopColor);
1002     m_defaultStyle[GeoDataPlacemark::ShopOutdoor]              = createOsmPOIStyle(osmFont, "shop/outdoor-14", shopColor);
1003     m_defaultStyle[GeoDataPlacemark::ShopSports]               = createOsmPOIStyle(osmFont, "shop/sports", shopColor);
1004     m_defaultStyle[GeoDataPlacemark::ShopCopy]                 = createOsmPOIStyle(osmFont, "shop/copyshop", shopColor);
1005     m_defaultStyle[GeoDataPlacemark::ShopArt]                  = createOsmPOIStyle(osmFont, "shop/art", shopColor);
1006     m_defaultStyle[GeoDataPlacemark::ShopMusicalInstrument]    = createOsmPOIStyle(osmFont, "shop/musical_instrument-14", shopColor);
1007     m_defaultStyle[GeoDataPlacemark::ShopPhoto]                = createOsmPOIStyle(osmFont, "shop/photo-14", shopColor);
1008     m_defaultStyle[GeoDataPlacemark::ShopBook]                 = createOsmPOIStyle(osmFont, "shop/shop_books.16", shopColor);
1009     m_defaultStyle[GeoDataPlacemark::ShopGift]                 = createOsmPOIStyle(osmFont, "shop/shop_gift.16", shopColor);
1010     m_defaultStyle[GeoDataPlacemark::ShopStationery]           = createOsmPOIStyle(osmFont, "shop/stationery-14", shopColor);
1011     m_defaultStyle[GeoDataPlacemark::ShopLaundry]              = createOsmPOIStyle(osmFont, "shop/laundry-14", shopColor);
1012     m_defaultStyle[GeoDataPlacemark::ShopPet]                  = createOsmPOIStyle(osmFont, "shop/shop_pet.16", shopColor);
1013     m_defaultStyle[GeoDataPlacemark::ShopToys]                 = createOsmPOIStyle(osmFont, "shop/toys-14", shopColor);
1014     m_defaultStyle[GeoDataPlacemark::ShopTravelAgency]         = createOsmPOIStyle(osmFont, "shop/travel_agency-14", shopColor);
1015     m_defaultStyle[GeoDataPlacemark::ShopDeli]                 = createOsmPOIStyle(osmFont, "shop/deli", shopColor);
1016     m_defaultStyle[GeoDataPlacemark::ShopTobacco]              = createOsmPOIStyle(osmFont, "shop/tobacco", shopColor);
1017     m_defaultStyle[GeoDataPlacemark::ShopTea]                  = createOsmPOIStyle(osmFont, "shop/tea", shopColor);
1018     m_defaultStyle[GeoDataPlacemark::ShopComputer]             = createOsmPOIStyle(osmFont, "shop/computer-14", shopColor);
1019     m_defaultStyle[GeoDataPlacemark::ShopGardenCentre]         = createOsmPOIStyle(osmFont, "shop/garden_centre-14", shopColor);
1020     m_defaultStyle[GeoDataPlacemark::Shop]                     = createOsmPOIStyle(osmFont, "shop/shop-14", shopColor);
1021 
1022     m_defaultStyle[GeoDataPlacemark::ManmadeBridge]            = createWayStyle(QColor("#b8b8b8"), Qt::transparent, true, true);
1023     m_defaultStyle[GeoDataPlacemark::ManmadeLighthouse]        = createOsmPOIStyle(osmFont, "transportation/lighthouse.16", transportationColor, "#f2efe9", QColor("#f2efe9").darker());
1024     m_defaultStyle[GeoDataPlacemark::ManmadePier]              = createStyle(0.0, 3.0, "#f2efe9", "#f2efe9", true, false, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector<qreal>(), osmFont);
1025     m_defaultStyle[GeoDataPlacemark::ManmadeWaterTower]        = createOsmPOIStyle(osmFont, "amenity/water_tower.16", amenityColor);
1026     m_defaultStyle[GeoDataPlacemark::ManmadeWindMill]          = createOsmPOIStyle(osmFont, "amenity/windmill.16", amenityColor);
1027     m_defaultStyle[GeoDataPlacemark::ManmadeCommunicationsTower] = createOsmPOIStyle(osmFont, "manmade/communications.16", amenityColor);
1028 
1029     m_defaultStyle[GeoDataPlacemark::HistoricCastle]           = createOsmPOIRingStyle(osmFont, "amenity/cinema.16", amenityColor);
1030     m_defaultStyle[GeoDataPlacemark::HistoricMemorial]         = createOsmPOIStyle(osmFont, "amenity/tourist_memorial.16", amenityColor);
1031     m_defaultStyle[GeoDataPlacemark::HistoricMonument]         = createOsmPOIStyle(osmFont, "amenity/monument.16", amenityColor);
1032     m_defaultStyle[GeoDataPlacemark::HistoricRuins]             = createOsmPOIRingStyle(osmFont, QString(), amenityColor);
1033 
1034     m_defaultStyle[GeoDataPlacemark::TourismAttraction]        = createOsmPOIStyle(osmFont, "amenity/tourist_memorial.16", amenityColor);
1035     m_defaultStyle[GeoDataPlacemark::TourismArtwork]           = createOsmPOIStyle(osmFont, "amenity/artwork", amenityColor);
1036     m_defaultStyle[GeoDataPlacemark::AmenityCinema]            = createOsmPOIStyle(osmFont, "amenity/cinema.16", amenityColor);
1037     m_defaultStyle[GeoDataPlacemark::TourismInformation]       = createOsmPOIStyle(osmFont, "amenity/information.16", amenityColor);
1038     m_defaultStyle[GeoDataPlacemark::TourismMuseum]            = createOsmPOIStyle(osmFont, "amenity/museum.16", amenityColor);
1039     m_defaultStyle[GeoDataPlacemark::AmenityTheatre]           = createOsmPOIStyle(osmFont, "amenity/theatre.16", amenityColor);
1040     m_defaultStyle[GeoDataPlacemark::TourismThemePark]         = createOsmPOIStyle(osmFont, QString(), amenityColor);
1041     m_defaultStyle[GeoDataPlacemark::TourismViewPoint]         = createOsmPOIStyle(osmFont, "amenity/viewpoint.16", amenityColor);
1042     m_defaultStyle[GeoDataPlacemark::TourismZoo]               = createOsmPOIRingStyle(osmFont, QString(), amenityColor, Qt::transparent);
1043     m_defaultStyle[GeoDataPlacemark::TourismAlpineHut]         = createOsmPOIStyle(osmFont, "transportation/alpinehut.16", transportationColor);
1044     m_defaultStyle[GeoDataPlacemark::TourismWildernessHut]     = createOsmPOIStyle(osmFont, "transportation/wilderness_hut", transportationColor);
1045     m_defaultStyle[GeoDataPlacemark::TransportAerodrome]       = createOsmPOIStyle(osmFont, "airtransport/aerodrome", airTransportColor);
1046     m_defaultStyle[GeoDataPlacemark::TransportHelipad]         = createOsmPOIStyle(osmFont, "airtransport/helipad", airTransportColor);
1047     m_defaultStyle[GeoDataPlacemark::TransportAirportTerminal] = createOsmPOIAreaStyle(osmFont, QString(), airTransportColor);
1048     m_defaultStyle[GeoDataPlacemark::TransportAirportGate]     = createOsmPOIAreaStyle(osmFont, QString(), airTransportColor);
1049     m_defaultStyle[GeoDataPlacemark::TransportBusStation]      = createOsmPOIStyle(osmFont, "transportation/bus_station.16", transportationColor);
1050     m_defaultStyle[GeoDataPlacemark::TransportBusStop]         = createOsmPOIStyle(osmFont, "transportation/bus_stop.12", transportationColor);
1051     m_defaultStyle[GeoDataPlacemark::TransportCarShare]        = createOsmPOIStyle(osmFont, "transportation/car_share.16", transportationColor);
1052     m_defaultStyle[GeoDataPlacemark::TransportFuel]            = createOsmPOIStyle(osmFont, "transportation/fuel.16", transportationColor);
1053     m_defaultStyle[GeoDataPlacemark::TransportParking]         = createOsmPOIAreaStyle(osmFont, "transportation/parking", transportationColor, "#F6EEB6", QColor("#F6EEB6").darker());
1054     m_defaultStyle[GeoDataPlacemark::TransportBicycleParking]  = createOsmPOIAreaStyle(osmFont, "transportation/bicycle_parking.16", transportationColor);
1055     m_defaultStyle[GeoDataPlacemark::TransportMotorcycleParking] = createOsmPOIAreaStyle(osmFont, "transportation/motorcycle_parking.16", transportationColor);
1056     qreal const parkingIconScale = 0.75;
1057     m_defaultStyle[GeoDataPlacemark::TransportParking]->iconStyle().setScale(parkingIconScale);
1058     m_defaultStyle[GeoDataPlacemark::TransportBicycleParking]->iconStyle().setScale(parkingIconScale);
1059     m_defaultStyle[GeoDataPlacemark::TransportMotorcycleParking]->iconStyle().setScale(parkingIconScale);
1060     m_defaultStyle[GeoDataPlacemark::TransportParkingSpace]    = createWayStyle("#F6EEB6", QColor("#F6EEB6").darker(), true, true);
1061     m_defaultStyle[GeoDataPlacemark::TransportPlatform]        = createWayStyle("#bbbbbb", Qt::transparent, true, false);
1062     m_defaultStyle[GeoDataPlacemark::TransportTrainStation]    = createOsmPOIStyle(osmFont, "individual/railway_station", transportationColor);
1063     m_defaultStyle[GeoDataPlacemark::TransportTrainStation]->iconStyle().setScale(0.5);
1064     m_defaultStyle[GeoDataPlacemark::TransportTramStop]        = createOsmPOIStyle(osmFont, "individual/railway_station", transportationColor);
1065     m_defaultStyle[GeoDataPlacemark::TransportTramStop]->iconStyle().setScale(0.33f);
1066     m_defaultStyle[GeoDataPlacemark::TransportRentalBicycle]   = createOsmPOIStyle(osmFont, "transportation/rental_bicycle.16", transportationColor);
1067     m_defaultStyle[GeoDataPlacemark::TransportRentalCar]       = createOsmPOIStyle(osmFont, "transportation/rental_car.16", transportationColor);
1068     m_defaultStyle[GeoDataPlacemark::TransportRentalSki]       = createOsmPOIStyle(osmFont, "transportation/rental_ski.16", transportationColor);
1069     m_defaultStyle[GeoDataPlacemark::TransportTaxiRank]        = createOsmPOIStyle(osmFont, "transportation/taxi.16", transportationColor);
1070     m_defaultStyle[GeoDataPlacemark::TransportSubwayEntrance]  = createOsmPOIStyle(osmFont, "transportation/subway_entrance", transportationColor);
1071     m_defaultStyle[GeoDataPlacemark::ReligionPlaceOfWorship]   = createOsmPOIStyle(osmFont, "black/place_of_worship.16");
1072     m_defaultStyle[GeoDataPlacemark::ReligionBahai]            = createOsmPOIStyle(osmFont, QString());
1073     m_defaultStyle[GeoDataPlacemark::ReligionBuddhist]         = createOsmPOIStyle(osmFont, "black/buddhist.16");
1074     m_defaultStyle[GeoDataPlacemark::ReligionChristian]        = createOsmPOIStyle(osmFont, "black/christian.16");
1075     m_defaultStyle[GeoDataPlacemark::ReligionMuslim]           = createOsmPOIStyle(osmFont, "black/muslim.16");
1076     m_defaultStyle[GeoDataPlacemark::ReligionHindu]            = createOsmPOIStyle(osmFont, "black/hinduist.16");
1077     m_defaultStyle[GeoDataPlacemark::ReligionJain]             = createOsmPOIStyle(osmFont, QString());
1078     m_defaultStyle[GeoDataPlacemark::ReligionJewish]           = createOsmPOIStyle(osmFont, "black/jewish.16");
1079     m_defaultStyle[GeoDataPlacemark::ReligionShinto]           = createOsmPOIStyle(osmFont, "black/shintoist.16");
1080     m_defaultStyle[GeoDataPlacemark::ReligionSikh]             = createOsmPOIStyle(osmFont, "black/sikhist.16");
1081     m_defaultStyle[GeoDataPlacemark::ReligionTaoist]           = createOsmPOIStyle(osmFont, "black/taoist.16");
1082 
1083     m_defaultStyle[GeoDataPlacemark::IndoorDoor]               = createOsmPOIRingStyle(osmFont, "indoor/door_b.16");
1084     m_defaultStyle[GeoDataPlacemark::IndoorWall]               = createOsmPOIStyle(osmFont, QString());
1085     m_defaultStyle[GeoDataPlacemark::IndoorRoom]               = createWayStyle(buildingColor.darker(), QColor(Qt::black));
1086 
1087     m_defaultStyle[GeoDataPlacemark::HighwayTrafficSignals]    = createOsmPOIStyle(osmFont, "individual/traffic_light");
1088     m_defaultStyle[GeoDataPlacemark::HighwayTrafficSignals]->iconStyle().setScale(0.75);
1089 
1090     m_defaultStyle[GeoDataPlacemark::HighwayElevator]    = createOsmPOIStyle(osmFont, "transportation/elevator-12", transportationColor);
1091     m_defaultStyle[GeoDataPlacemark::HighwayElevator]->iconStyle().setScale(0.75);
1092 
1093     m_defaultStyle[GeoDataPlacemark::PowerTower]               = createOsmPOIStyle(osmFont, "individual/power_tower", QColor("#888888"));
1094     m_defaultStyle[GeoDataPlacemark::PowerTower]->iconStyle().setScale(0.6f);
1095 
1096     m_defaultStyle[GeoDataPlacemark::BarrierCityWall]          = createStyle(6.0, 3.0, "#787878", Qt::transparent, true, false, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector<qreal>(), osmFont, Qt::transparent);
1097     m_defaultStyle[GeoDataPlacemark::BarrierGate]              = createOsmPOIStyle(osmFont, "individual/gate");
1098     m_defaultStyle[GeoDataPlacemark::BarrierGate]->iconStyle().setScale(0.75);
1099     m_defaultStyle[GeoDataPlacemark::BarrierLiftGate]          = createOsmPOIStyle(osmFont, "individual/liftgate");
1100     m_defaultStyle[GeoDataPlacemark::BarrierLiftGate]->iconStyle().setScale(0.75);
1101     m_defaultStyle[GeoDataPlacemark::BarrierWall]              = createStyle(2.0, 0.0, "#787878", Qt::transparent, true, false, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector<qreal>(), osmFont, Qt::transparent);
1102 
1103     m_defaultStyle[GeoDataPlacemark::HighwaySteps]             = createStyle(0.0, 2.0, "#fa8072", QColor(Qt::white), true, true, Qt::SolidPattern, Qt::CustomDashLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont);
1104     m_defaultStyle[GeoDataPlacemark::HighwayUnknown]           = createHighwayStyle("#dddddd", "#bbbbbb", osmFont, "000000", 0, 1);
1105     m_defaultStyle[GeoDataPlacemark::HighwayPath]              = createHighwayStyle("#dddde8", "#999999", osmFont, "000000", 0, 1, Qt::DotLine, Qt::SquareCap, true);
1106     m_defaultStyle[GeoDataPlacemark::HighwayTrack]             = createHighwayStyle("#996600", QColor(Qt::white), osmFont, QColor(Qt::transparent), 1, 1, Qt::DashLine, Qt::SquareCap, true);
1107     m_defaultStyle[GeoDataPlacemark::HighwayPedestrian]        = createHighwayStyle("#dddde8", "#999999", osmFont, "000000", 0, 2);
1108     m_defaultStyle[GeoDataPlacemark::HighwayPedestrian]->polyStyle().setOutline(false);
1109     m_defaultStyle[GeoDataPlacemark::HighwayFootway]           = createHighwayStyle("#fa8072", QColor(Qt::white), osmFont, "000000", 0, 2, Qt::DotLine, Qt::SquareCap, true);
1110     m_defaultStyle[GeoDataPlacemark::HighwayCycleway]          = createHighwayStyle(QColor(Qt::blue), QColor(Qt::white), osmFont, "000000", 0, 2, Qt::DotLine, Qt::SquareCap, true);
1111     m_defaultStyle[GeoDataPlacemark::HighwayService]           = createHighwayStyle("#ffffff", "#bbbbbb", osmFont, "000000", 1, 6);
1112     m_defaultStyle[GeoDataPlacemark::HighwayResidential]       = createHighwayStyle("#ffffff", "#bbbbbb", osmFont, "000000", 3, 6);
1113     m_defaultStyle[GeoDataPlacemark::HighwayLivingStreet]      = createHighwayStyle("#ffffff", "#bbbbbb", osmFont, "000000", 3, 6);
1114     m_defaultStyle[GeoDataPlacemark::HighwayRoad]              = createHighwayStyle("#dddddd", "#bbbbbb", osmFont, "000000", 3, 6);
1115     m_defaultStyle[GeoDataPlacemark::HighwayUnclassified]      = createHighwayStyle("#ffffff", "#bbbbbb", osmFont, "000000", 3, 6);
1116     m_defaultStyle[GeoDataPlacemark::HighwayTertiary]          = createHighwayStyle("#ffffff", "#8f8f8f", osmFont, "000000", 6, 6);
1117     m_defaultStyle[GeoDataPlacemark::HighwayTertiaryLink]      = createHighwayStyle("#ffffff", "#8f8f8f", osmFont, "000000", 6, 6);
1118     m_defaultStyle[GeoDataPlacemark::HighwaySecondary]         = createHighwayStyle("#f7fabf", "#707d05", osmFont, "000000", 6, 6);
1119     m_defaultStyle[GeoDataPlacemark::HighwaySecondaryLink]     = createHighwayStyle("#f7fabf", "#707d05", osmFont, "000000", 6, 6);
1120     m_defaultStyle[GeoDataPlacemark::HighwayPrimary]           = createHighwayStyle("#fcd6a4", "#a06b00", osmFont, "000000", 9, 6);
1121     m_defaultStyle[GeoDataPlacemark::HighwayPrimaryLink]       = createHighwayStyle("#fcd6a4", "#a06b00", osmFont, "000000", 6, 6);
1122     m_defaultStyle[GeoDataPlacemark::HighwayRaceway]           = createHighwayStyle("#ffc0cb", "#ffc0cb", osmFont, "000000", 1, 5);
1123     m_defaultStyle[GeoDataPlacemark::HighwayTrunk]             = createHighwayStyle("#f9b29c", "#c84e2f", osmFont, "000000", 9, 6);
1124     m_defaultStyle[GeoDataPlacemark::HighwayTrunkLink]         = createHighwayStyle("#f9b29c", "#c84e2f", osmFont, "000000", 9, 6);
1125     m_defaultStyle[GeoDataPlacemark::HighwayMotorway]          = createHighwayStyle("#e892a2", "#dc2a67", osmFont, "000000", 9, 10);
1126     m_defaultStyle[GeoDataPlacemark::HighwayMotorwayLink]      = createHighwayStyle("#e892a2", "#dc2a67", osmFont, "000000", 9, 10);
1127     m_defaultStyle[GeoDataPlacemark::HighwayCorridor]          = createHighwayStyle("#ffffff", "#bbbbbb", osmFont, "000000", 1, 3);
1128     m_defaultStyle[GeoDataPlacemark::TransportAirportRunway]   = createHighwayStyle("#bbbbcc", "#bbbbcc", osmFont, "000000", 0, 1, Qt::NoPen);
1129     m_defaultStyle[GeoDataPlacemark::TransportAirportTaxiway]  = createHighwayStyle("#bbbbcc", "#bbbbcc", osmFont, "000000", 0, 1, Qt::NoPen);
1130     m_defaultStyle[GeoDataPlacemark::TransportAirportApron]    = createWayStyle("#e9d1ff", Qt::transparent, true, false);
1131     m_defaultStyle[GeoDataPlacemark::TransportSpeedCamera]     = createOsmPOIStyle(osmFont, "individual/speedcamera");
1132 
1133     m_defaultStyle[GeoDataPlacemark::NaturalWater]             = createStyle(4, 0, waterColor, waterColor, true, false,
1134             Qt::SolidPattern, Qt::SolidLine, Qt::RoundCap, false, QVector< qreal >(),
1135             osmFont, waterColor.darker(150));
1136     m_defaultStyle[GeoDataPlacemark::WaterwayRiver]            = createStyle(4, 0, waterColor, waterColor, true, false,
1137             Qt::SolidPattern, Qt::SolidLine, Qt::RoundCap, false, QVector< qreal >(),
1138             osmFont, waterColor.darker(150));
1139     m_defaultStyle[GeoDataPlacemark::WaterwayCanal]           = m_defaultStyle[GeoDataPlacemark::WaterwayRiver];
1140     m_defaultStyle[GeoDataPlacemark::WaterwayDitch]           = m_defaultStyle[GeoDataPlacemark::WaterwayRiver];
1141     m_defaultStyle[GeoDataPlacemark::WaterwayDrain]           = m_defaultStyle[GeoDataPlacemark::WaterwayRiver];
1142     m_defaultStyle[GeoDataPlacemark::WaterwayStream]          = m_defaultStyle[GeoDataPlacemark::WaterwayRiver];
1143     m_defaultStyle[GeoDataPlacemark::WaterwayWeir]            = createStyle(4, 0, "#ffffff", "#87939b", true, false,
1144             Qt::SolidPattern, Qt::DotLine, Qt::RoundCap, true, QVector< qreal >(),
1145             osmFont, waterColor.darker(150));
1146 
1147     m_defaultStyle[GeoDataPlacemark::CrossingIsland]          = createOsmPOIStyle(osmFont, "transportation/zebra_crossing", transportationColor);
1148     m_defaultStyle[GeoDataPlacemark::CrossingIsland]->iconStyle().setScale(0.75);
1149     m_defaultStyle[GeoDataPlacemark::CrossingRailway]         = createOsmPOIStyle(osmFont, "transportation/railway_crossing", transportationColor);
1150     m_defaultStyle[GeoDataPlacemark::CrossingRailway]->iconStyle().setScale(0.5);
1151     m_defaultStyle[GeoDataPlacemark::CrossingSignals]         = createOsmPOIStyle(osmFont, "transportation/traffic_light_crossing", transportationColor);
1152     m_defaultStyle[GeoDataPlacemark::CrossingSignals]->iconStyle().setScale(0.75);
1153     m_defaultStyle[GeoDataPlacemark::CrossingZebra]           = createOsmPOIStyle(osmFont, "transportation/zebra_crossing", transportationColor);
1154     m_defaultStyle[GeoDataPlacemark::CrossingZebra]->iconStyle().setScale(0.75);
1155 
1156     m_defaultStyle[GeoDataPlacemark::NaturalReef]              = createStyle(5.5, 0, "#36677c", "#36677c", true, false,
1157             Qt::Dense7Pattern, Qt::DotLine, Qt::RoundCap, false, QVector< qreal >(),
1158             osmFont, waterColor.darker(150));
1159 
1160     m_defaultStyle[GeoDataPlacemark::AmenityGraveyard]         = createWayStyle("#AACBAF", "#AACBAF", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/grave_yard_generic.png"));
1161 
1162     m_defaultStyle[GeoDataPlacemark::NaturalWood]              = createWayStyle("#8DC46C", "#8DC46C", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/forest.png"));
1163     m_defaultStyle[GeoDataPlacemark::NaturalBeach]             = createWayStyle("#FFF1BA", "#FFF1BA", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/beach.png"));
1164     m_defaultStyle[GeoDataPlacemark::NaturalWetland]           = createWayStyle("#DDECEC", "#DDECEC", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/wetland.png"));
1165     m_defaultStyle[GeoDataPlacemark::NaturalGlacier]           = createWayStyle("#DDECEC", "#DDECEC", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/glacier.png"));
1166     m_defaultStyle[GeoDataPlacemark::NaturalIceShelf]          = createWayStyle("#8ebebe", "#8ebebe", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/glacier.png"));
1167     m_defaultStyle[GeoDataPlacemark::NaturalScrub]             = createWayStyle("#B5E3B5", "#B5E3B5", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/scrub.png"));
1168     m_defaultStyle[GeoDataPlacemark::NaturalCliff]             = createWayStyle(Qt::transparent, Qt::transparent, true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/cliff2.png"));
1169     m_defaultStyle[GeoDataPlacemark::NaturalCave]              = createOsmPOIStyle(osmFont, "amenities/cave", amenityColor);
1170     m_defaultStyle[GeoDataPlacemark::NaturalHeath]             = createWayStyle("#d6d99f", QColor("#d6d99f").darker(150), true, false);
1171 
1172     m_defaultStyle[GeoDataPlacemark::LeisureGolfCourse]        = createOsmPOIAreaStyle(osmFont, "leisure/golf", "#39ac39", "#b5e3b5", QColor(Qt::transparent));
1173     m_defaultStyle[GeoDataPlacemark::LeisureMinigolfCourse]    = createOsmPOIAreaStyle(osmFont, "leisure/miniature_golf", "#39ac39", "#b5e3b5", QColor(Qt::transparent));
1174     m_defaultStyle[GeoDataPlacemark::LeisureMarina]            = createOsmPOIStyle(osmFont, QString(), QColor("#95abd5"), QColor("#aec8d1"), QColor("#95abd5").darker(150));
1175     m_defaultStyle[GeoDataPlacemark::LeisurePark]              = createWayStyle(QColor("#c8facc"), QColor("#c8facc").darker(150), true, true);
1176     m_defaultStyle[GeoDataPlacemark::LeisurePlayground]        = createOsmPOIAreaStyle(osmFont, "amenity/playground.16", amenityColor, "#CCFFF1", "#BDFFED");
1177     m_defaultStyle[GeoDataPlacemark::LeisurePitch]             = createWayStyle("#8ad3af", QColor("#8ad3af").darker(150), true, true);
1178     m_defaultStyle[GeoDataPlacemark::LeisureSportsCentre]      = createWayStyle("#33cc99", QColor("#33cc99").darker(150), true, true);
1179     m_defaultStyle[GeoDataPlacemark::LeisureStadium]           = createWayStyle("#33cc99", QColor("#33cc99").darker(150), true, true);
1180     m_defaultStyle[GeoDataPlacemark::LeisureTrack]             = createWayStyle("#74dcba", QColor("#74dcba").darker(150), true, true);
1181     m_defaultStyle[GeoDataPlacemark::LeisureSwimmingPool]      = createWayStyle(waterColor, waterColor.darker(150), true, true);
1182 
1183     m_defaultStyle[GeoDataPlacemark::LanduseAllotments]        = createWayStyle("#E4C6AA", "#E4C6AA", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/allotments.png"));
1184     m_defaultStyle[GeoDataPlacemark::LanduseBasin]             = createWayStyle(QColor(0xB5, 0xD0, 0xD0, 0x80), QColor(0xB5, 0xD0, 0xD0));
1185     m_defaultStyle[GeoDataPlacemark::LanduseCemetery]          = createWayStyle("#AACBAF", "#AACBAF", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/grave_yard_generic.png"));
1186     m_defaultStyle[GeoDataPlacemark::LanduseCommercial]        = createWayStyle("#F2DAD9", "#D1B2B0", true, true);
1187     m_defaultStyle[GeoDataPlacemark::LanduseConstruction]      = createWayStyle("#b6b592", "#b6b592", true, false);
1188     m_defaultStyle[GeoDataPlacemark::LanduseFarmland]          = createWayStyle("#EDDDC9", "#C8B69E", true, true);
1189     m_defaultStyle[GeoDataPlacemark::LanduseFarmyard]          = createWayStyle("#EFD6B5", "#D1B48C", true, true);
1190     m_defaultStyle[GeoDataPlacemark::LanduseGarages]           = createWayStyle("#E0DDCD", "#E0DDCD", true, false);
1191     m_defaultStyle[GeoDataPlacemark::LanduseGrass]             = createWayStyle("#A8C8A5", "#A8C8A5", true, false);
1192     m_defaultStyle[GeoDataPlacemark::LanduseIndustrial]        = createWayStyle("#DED0D5", "#DED0D5", true, false);
1193     m_defaultStyle[GeoDataPlacemark::LanduseLandfill]          = createWayStyle("#b6b592", "#b6b592", true, false);
1194     m_defaultStyle[GeoDataPlacemark::LanduseMeadow]            = createWayStyle("#cdebb0", "#cdebb0", true, false);
1195     m_defaultStyle[GeoDataPlacemark::LanduseMilitary]          = createWayStyle("#F3D8D2", "#F3D8D2", true, true, Qt::BDiagPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/military_red_hatch.png"));
1196     m_defaultStyle[GeoDataPlacemark::LanduseQuarry]            = createWayStyle("#C4C2C2", "#C4C2C2", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/quarry.png"));
1197     m_defaultStyle[GeoDataPlacemark::LanduseRailway]           = createWayStyle("#DED0D5", "#DED0D5", true, false);
1198     m_defaultStyle[GeoDataPlacemark::LanduseReservoir]         = createWayStyle(waterColor, waterColor, true, false);
1199     m_defaultStyle[GeoDataPlacemark::LanduseResidential]       = createWayStyle("#DCDCDC", "#DCDCDC", true, false);
1200     m_defaultStyle[GeoDataPlacemark::LanduseRetail]            = createWayStyle("#FFD6D1", "#D99C95", true, true);
1201     m_defaultStyle[GeoDataPlacemark::LanduseOrchard]           = createWayStyle("#AEDFA3", "#AEDFA3", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/orchard.png"));
1202     m_defaultStyle[GeoDataPlacemark::LanduseVineyard]          = createWayStyle("#AEDFA3", "#AEDFA3", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/vineyard.png"));
1203 
1204     m_defaultStyle[GeoDataPlacemark::MilitaryDangerArea]       = createWayStyle("#FFC0CB", "#FFC0CB", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/danger.png"));
1205 
1206     m_defaultStyle[GeoDataPlacemark::RailwayRail]              = createStyle(2.0, 1.435, "#706E70", "#EEEEEE", true, true, Qt::SolidPattern, Qt::CustomDashLine, Qt::FlatCap, true, QVector< qreal >() << 2 << 3, osmFont, QColor(Qt::transparent));
1207     m_defaultStyle[GeoDataPlacemark::RailwayNarrowGauge]       = createStyle(2.0, 1.0, "#706E70", "#EEEEEE", true, true, Qt::SolidPattern, Qt::CustomDashLine, Qt::FlatCap, true, QVector< qreal >() << 2 << 3, osmFont, QColor(Qt::transparent));
1208     // FIXME: the tram is currently being rendered as a polygon.
1209     m_defaultStyle[GeoDataPlacemark::RailwayTram]              = createStyle(2.0, 1.435, "#706E70", "#B7B6B7", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector<qreal>(), osmFont, QColor(Qt::transparent));
1210     m_defaultStyle[GeoDataPlacemark::RailwayLightRail]         = createStyle(2.0, 1.435, "#706E70", "#706E70", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector<qreal>(), osmFont, QColor(Qt::transparent));
1211     m_defaultStyle[GeoDataPlacemark::RailwayAbandoned]         = createStyle(2.0, 1.435, Qt::transparent, "#706E70", false, false, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, false, QVector<qreal>(), osmFont, QColor(Qt::transparent));
1212     m_defaultStyle[GeoDataPlacemark::RailwaySubway]            = createStyle(2.0, 1.435, "#706E70", "#EEEEEE", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector<qreal>(), osmFont, QColor(Qt::transparent));
1213     m_defaultStyle[GeoDataPlacemark::RailwayPreserved]         = createStyle(2.0, 1.435, "#EEEEEE", "#706E70", true, true, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, true, QVector<qreal>(), osmFont, QColor(Qt::transparent));
1214     m_defaultStyle[GeoDataPlacemark::RailwayMiniature]         = createStyle(2.0, 1.435, "#706E70", "#EEEEEE", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector<qreal>(), osmFont, QColor(Qt::transparent));
1215     m_defaultStyle[GeoDataPlacemark::RailwayConstruction]      = createStyle(2.0, 1.435, "#EEEEEE", "#706E70", true, true, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, true, QVector<qreal>(), osmFont, QColor(Qt::transparent));
1216     m_defaultStyle[GeoDataPlacemark::RailwayMonorail]          = createStyle(2.0, 1.435, "#706E70", "#EEEEEE", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector<qreal>(), osmFont, QColor(Qt::transparent));
1217     m_defaultStyle[GeoDataPlacemark::RailwayFunicular]         = createStyle(2.0, 1.435, "#706E70", "#EEEEEE", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector<qreal>(), osmFont, QColor(Qt::transparent));
1218 
1219     m_defaultStyle[GeoDataPlacemark::Landmass]                 = createWayStyle("#F1EEE8", "#F1EEE8", true, false);
1220     m_defaultStyle[GeoDataPlacemark::UrbanArea]                = createWayStyle("#E6E3DD", "#E6E3DD", true, false);
1221     m_defaultStyle[GeoDataPlacemark::InternationalDateLine]    = createStyle(1.0, 0.0, "#000000", "#000000", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector<qreal>(), osmFont);
1222     m_defaultStyle[GeoDataPlacemark::Bathymetry]               = createWayStyle("#a5c9c9", "#a5c9c9", true, false);
1223 
1224     m_defaultStyle[GeoDataPlacemark::AerialwayStation]         = createOsmPOIStyle(osmFont, "individual/railway_station", transportationColor);
1225     m_defaultStyle[GeoDataPlacemark::AerialwayStation]->iconStyle().setScale(0.33f);
1226     m_defaultStyle[GeoDataPlacemark::AerialwayPylon]           = createOsmPOIStyle(osmFont, "individual/pylon", QColor("#dddddd"));
1227     m_defaultStyle[GeoDataPlacemark::AerialwayPylon]->iconStyle().setScale(0.33f);
1228     m_defaultStyle[GeoDataPlacemark::AerialwayCableCar]        = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-583813-cable-car.svg"));
1229     m_defaultStyle[GeoDataPlacemark::AerialwayGondola]         = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-21636-gondola.svg"));
1230     m_defaultStyle[GeoDataPlacemark::AerialwayChairLift]       = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-231-chair-lift.svg"));
1231     m_defaultStyle[GeoDataPlacemark::AerialwayMixedLift]       = createIconWayStyle("#bbbbbb", osmFont, transportationColor);
1232     m_defaultStyle[GeoDataPlacemark::AerialwayDragLift]        = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-8803-platter-lift.svg"));
1233     m_defaultStyle[GeoDataPlacemark::AerialwayTBar]            = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-8803-platter-lift.svg"));
1234     m_defaultStyle[GeoDataPlacemark::AerialwayJBar]            = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-8803-platter-lift.svg"));
1235     m_defaultStyle[GeoDataPlacemark::AerialwayPlatter]         = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-8803-platter-lift.svg"));
1236     m_defaultStyle[GeoDataPlacemark::AerialwayRopeTow]         = createIconWayStyle("#bbbbbb", osmFont, transportationColor);
1237     m_defaultStyle[GeoDataPlacemark::AerialwayMagicCarpet]     = createIconWayStyle("#bbbbbb", osmFont, transportationColor);
1238     m_defaultStyle[GeoDataPlacemark::AerialwayZipLine]         = createIconWayStyle("#bbbbbb", osmFont, transportationColor);
1239     m_defaultStyle[GeoDataPlacemark::AerialwayGoods]           = createIconWayStyle("#bbbbbb", osmFont, transportationColor);
1240 
1241     m_defaultStyle[GeoDataPlacemark::PisteDownhill]            = createStyle(9, 0.0, "#dddddd", Qt::transparent, true, false, Qt::SolidPattern, Qt::SolidLine, Qt::RoundCap, false, QVector< qreal >(), osmFont, Qt::transparent);
1242     m_defaultStyle[GeoDataPlacemark::PisteNordic]              = createStyle(3, 0.0, "#fffafa", "#006666", true, false, Qt::SolidPattern, Qt::SolidLine, Qt::RoundCap, false, QVector< qreal >(), osmFont, Qt::transparent, MarbleDirs::path("bitmaps/osmcarto/patterns/ice.png"));
1243     m_defaultStyle[GeoDataPlacemark::PisteSkitour]             = m_defaultStyle[GeoDataPlacemark::PisteNordic];
1244     m_defaultStyle[GeoDataPlacemark::PisteSled]                = m_defaultStyle[GeoDataPlacemark::PisteNordic];
1245     m_defaultStyle[GeoDataPlacemark::PisteHike]                = m_defaultStyle[GeoDataPlacemark::PisteNordic];
1246     m_defaultStyle[GeoDataPlacemark::PisteSleigh]              = m_defaultStyle[GeoDataPlacemark::PisteNordic];
1247     m_defaultStyle[GeoDataPlacemark::PisteIceSkate]            = m_defaultStyle[GeoDataPlacemark::PisteNordic];
1248     m_defaultStyle[GeoDataPlacemark::PisteSnowPark]            = m_defaultStyle[GeoDataPlacemark::PisteNordic];
1249     m_defaultStyle[GeoDataPlacemark::PistePlayground]          = m_defaultStyle[GeoDataPlacemark::PisteNordic];
1250     m_defaultStyle[GeoDataPlacemark::PisteSkiJump]             = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/sports-245-ski-jump.svg"));
1251 
1252     m_defaultStyle[GeoDataPlacemark::AdminLevel1]              = createStyle(0.0, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::CustomDashLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont);
1253     m_defaultStyle[GeoDataPlacemark::AdminLevel2]              = createStyle(2.0, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont);
1254     m_defaultStyle[GeoDataPlacemark::AdminLevel3]              = createStyle(1.8, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DashLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont);
1255     m_defaultStyle[GeoDataPlacemark::AdminLevel4]              = createStyle(1.5, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont);
1256     m_defaultStyle[GeoDataPlacemark::AdminLevel5]              = createStyle(1.25, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DashDotDotLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont);
1257     m_defaultStyle[GeoDataPlacemark::AdminLevel6]              = createStyle(1, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DashDotLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont);
1258     m_defaultStyle[GeoDataPlacemark::AdminLevel7]              = createStyle(1, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DashLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont);
1259     m_defaultStyle[GeoDataPlacemark::AdminLevel8]              = createStyle(1, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DashLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont);
1260     m_defaultStyle[GeoDataPlacemark::AdminLevel9]              = createStyle(1.5, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont);
1261     m_defaultStyle[GeoDataPlacemark::AdminLevel10]             = createStyle(1.5, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont);
1262     m_defaultStyle[GeoDataPlacemark::AdminLevel11]             = createStyle(1.5, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont);
1263 
1264     m_defaultStyle[GeoDataPlacemark::BoundaryMaritime]         = createStyle(2.0, 0.0, "#88b3bf", "#88b3bf", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector<qreal>(), osmFont);
1265 
1266     m_defaultStyle[GeoDataPlacemark::Satellite]
1267         = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/satellite.png"),
1268                             QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor));
1269 
1270     QFont tmp;
1271 
1272     // Fonts for areas ...
1273     tmp = m_defaultStyle[GeoDataPlacemark::Continent]->labelStyle().font();
1274     tmp.setLetterSpacing(QFont::AbsoluteSpacing, 2);
1275     tmp.setCapitalization(QFont::AllUppercase);
1276     tmp.setBold(true);
1277     m_defaultStyle[GeoDataPlacemark::Continent]->labelStyle().setFont(tmp);
1278 
1279     // Fonts for areas ...
1280     tmp = m_defaultStyle[GeoDataPlacemark::Mare]->labelStyle().font();
1281     tmp.setLetterSpacing(QFont::AbsoluteSpacing, 2);
1282     tmp.setCapitalization(QFont::AllUppercase);
1283     tmp.setBold(true);
1284     m_defaultStyle[GeoDataPlacemark::Mare]->labelStyle().setFont(tmp);
1285 
1286     // Now we need to underline the capitals ...
1287 
1288     tmp = m_defaultStyle[GeoDataPlacemark::SmallNationCapital]->labelStyle().font();
1289     tmp.setUnderline(true);
1290     m_defaultStyle[GeoDataPlacemark::SmallNationCapital]->labelStyle().setFont(tmp);
1291 
1292     tmp = m_defaultStyle[GeoDataPlacemark::MediumNationCapital]->labelStyle().font();
1293     tmp.setUnderline(true);
1294     m_defaultStyle[GeoDataPlacemark::MediumNationCapital]->labelStyle().setFont(tmp);
1295 
1296     tmp = m_defaultStyle[GeoDataPlacemark::BigNationCapital]->labelStyle().font();
1297     tmp.setUnderline(true);
1298     m_defaultStyle[GeoDataPlacemark::BigNationCapital]->labelStyle().setFont(tmp);
1299 
1300     tmp = m_defaultStyle[GeoDataPlacemark::LargeNationCapital]->labelStyle().font();
1301     tmp.setUnderline(true);
1302     m_defaultStyle[GeoDataPlacemark::LargeNationCapital]->labelStyle().setFont(tmp);
1303 
1304     // Buildings
1305     m_defaultStyle[GeoDataPlacemark::Building] = createStyle(1, 0, buildingColor, buildingColor.darker(),
1306             true, true, Qt::SolidPattern, Qt::SolidLine, Qt::RoundCap, false, QVector<qreal>(), osmFont);
1307     for (int i = 0; i < GeoDataPlacemark::LastIndex; ++i) {
1308         if (m_defaultStyle[i] && !m_defaultStyle[i]->iconStyle().iconPath().isEmpty()) {
1309             auto const category = GeoDataPlacemark::GeoDataVisualCategory(i);
1310             m_buildingStyles[category] = GeoDataStyle::Ptr(new GeoDataStyle(*m_defaultStyle[GeoDataPlacemark::Building]));
1311             m_buildingStyles[category]->iconStyle() = m_defaultStyle[i]->iconStyle();
1312             m_buildingStyles[category]->labelStyle() = m_defaultStyle[i]->labelStyle();
1313         }
1314     }
1315 
1316 }
1317 
1318 QColor StyleBuilder::Private::effectColor(const QColor& color)
1319 {
1320     int gray;
1321     switch (s_styleEffect) {
1322     case InvertedEffect:
1323         return QColor(255 - color.red(), 255 - color.green(), 255 - color.blue());
1324     case GrayscaleEffect:
1325         gray = qMin(255, static_cast<int>(7 * qGray(color.darker(800).rgb())));
1326         return QColor(gray, gray, gray);
1327     case RedModeEffect:
1328         gray = qMin(255, static_cast<int>(7 * qGray(color.darker(800).rgb())));
1329         return QColor(gray, 0, 0);
1330     case NoEffect:
1331         return color;
1332     }
1333 
1334     return color;
1335 }
1336 
1337 QString StyleBuilder::Private::createPaintLayerItem(const QString &itemType, GeoDataPlacemark::GeoDataVisualCategory visualCategory, const QString &subType)
1338 {
1339     QString const category = visualCategoryName(visualCategory);
1340     if (subType.isEmpty()) {
1341         return itemType + QLatin1Char('/') + category;
1342     } else {
1343         return itemType + QLatin1Char('/') + category + QLatin1Char('/') + subType;
1344     }
1345 }
1346 
1347 void StyleBuilder::Private::initializeOsmVisualCategories()
1348 {
1349     // Only initialize the map once
1350     if (!s_visualCategories.isEmpty()) {
1351         return;
1352     }
1353 
1354     s_visualCategories[OsmTag("admin_level", "1")]              = GeoDataPlacemark::AdminLevel1;
1355     s_visualCategories[OsmTag("admin_level", "2")]              = GeoDataPlacemark::AdminLevel2;
1356     s_visualCategories[OsmTag("admin_level", "3")]              = GeoDataPlacemark::AdminLevel3;
1357     s_visualCategories[OsmTag("admin_level", "4")]              = GeoDataPlacemark::AdminLevel4;
1358     s_visualCategories[OsmTag("admin_level", "5")]              = GeoDataPlacemark::AdminLevel5;
1359     s_visualCategories[OsmTag("admin_level", "6")]              = GeoDataPlacemark::AdminLevel6;
1360     s_visualCategories[OsmTag("admin_level", "7")]              = GeoDataPlacemark::AdminLevel7;
1361     s_visualCategories[OsmTag("admin_level", "8")]              = GeoDataPlacemark::AdminLevel8;
1362     s_visualCategories[OsmTag("admin_level", "9")]              = GeoDataPlacemark::AdminLevel9;
1363     s_visualCategories[OsmTag("admin_level", "10")]             = GeoDataPlacemark::AdminLevel10;
1364     s_visualCategories[OsmTag("admin_level", "11")]             = GeoDataPlacemark::AdminLevel11;
1365 
1366     s_visualCategories[OsmTag("boundary", "maritime")]          = GeoDataPlacemark::BoundaryMaritime;
1367 
1368     s_visualCategories[OsmTag("amenity", "restaurant")]         = GeoDataPlacemark::FoodRestaurant;
1369     s_visualCategories[OsmTag("amenity", "fast_food")]          = GeoDataPlacemark::FoodFastFood;
1370     s_visualCategories[OsmTag("amenity", "pub")]                = GeoDataPlacemark::FoodPub;
1371     s_visualCategories[OsmTag("amenity", "bar")]                = GeoDataPlacemark::FoodBar;
1372     s_visualCategories[OsmTag("amenity", "cafe")]               = GeoDataPlacemark::FoodCafe;
1373     s_visualCategories[OsmTag("amenity", "biergarten")]         = GeoDataPlacemark::FoodBiergarten;
1374 
1375     s_visualCategories[OsmTag("amenity", "college")]            = GeoDataPlacemark::EducationCollege;
1376     s_visualCategories[OsmTag("amenity", "school")]             = GeoDataPlacemark::EducationSchool;
1377     s_visualCategories[OsmTag("amenity", "university")]         = GeoDataPlacemark::EducationUniversity;
1378 
1379     s_visualCategories[OsmTag("amenity", "childcare")]          = GeoDataPlacemark::AmenityKindergarten;
1380     s_visualCategories[OsmTag("amenity", "kindergarten")]       = GeoDataPlacemark::AmenityKindergarten;
1381     s_visualCategories[OsmTag("amenity", "library")]            = GeoDataPlacemark::AmenityLibrary;
1382 
1383     s_visualCategories[OsmTag("amenity", "bus_station")]        = GeoDataPlacemark::TransportBusStation;
1384     s_visualCategories[OsmTag("amenity", "car_sharing")]        = GeoDataPlacemark::TransportCarShare;
1385     s_visualCategories[OsmTag("amenity", "fuel")]               = GeoDataPlacemark::TransportFuel;
1386     s_visualCategories[OsmTag("amenity", "parking")]            = GeoDataPlacemark::TransportParking;
1387     s_visualCategories[OsmTag("amenity", "parking_space")]      = GeoDataPlacemark::TransportParkingSpace;
1388 
1389     s_visualCategories[OsmTag("amenity", "atm")]                = GeoDataPlacemark::MoneyAtm;
1390     s_visualCategories[OsmTag("amenity", "bank")]               = GeoDataPlacemark::MoneyBank;
1391 
1392     s_visualCategories[OsmTag("historic", "archaeological_site")] = GeoDataPlacemark::HistoricArchaeologicalSite;
1393     s_visualCategories[OsmTag("historic", "castle")]            = GeoDataPlacemark::HistoricCastle;
1394     s_visualCategories[OsmTag("historic", "fort")]              = GeoDataPlacemark::HistoricCastle;
1395     s_visualCategories[OsmTag("historic", "memorial")]          = GeoDataPlacemark::HistoricMemorial;
1396     s_visualCategories[OsmTag("historic", "monument")]          = GeoDataPlacemark::HistoricMonument;
1397     s_visualCategories[OsmTag("historic", "ruins")]             = GeoDataPlacemark::HistoricRuins;
1398 
1399     s_visualCategories[OsmTag("amenity", "bench")]              = GeoDataPlacemark::AmenityBench;
1400     s_visualCategories[OsmTag("amenity", "car_wash")]           = GeoDataPlacemark::AmenityCarWash;
1401     s_visualCategories[OsmTag("amenity", "charging_station")]   = GeoDataPlacemark::AmenityChargingStation;
1402     s_visualCategories[OsmTag("amenity", "cinema")]             = GeoDataPlacemark::AmenityCinema;
1403     s_visualCategories[OsmTag("amenity", "community_centre")]   = GeoDataPlacemark::AmenityCommunityCentre;
1404     s_visualCategories[OsmTag("amenity", "courthouse")]         = GeoDataPlacemark::AmenityCourtHouse;
1405     s_visualCategories[OsmTag("amenity", "drinking_water")]     = GeoDataPlacemark::AmenityDrinkingWater;
1406     s_visualCategories[OsmTag("amenity", "embassy")]            = GeoDataPlacemark::AmenityEmbassy;
1407     s_visualCategories[OsmTag("amenity", "fire_station")]       = GeoDataPlacemark::AmenityFireStation;
1408     s_visualCategories[OsmTag("amenity", "fountain")]           = GeoDataPlacemark::AmenityFountain;
1409     s_visualCategories[OsmTag("amenity", "graveyard")]          = GeoDataPlacemark::AmenityGraveyard;
1410     s_visualCategories[OsmTag("amenity", "hunting_stand")]      = GeoDataPlacemark::AmenityHuntingStand;
1411     s_visualCategories[OsmTag("amenity", "nightclub")]          = GeoDataPlacemark::AmenityNightClub;
1412     s_visualCategories[OsmTag("amenity", "police")]             = GeoDataPlacemark::AmenityPolice;
1413     s_visualCategories[OsmTag("amenity", "post_box")]           = GeoDataPlacemark::AmenityPostBox;
1414     s_visualCategories[OsmTag("amenity", "post_office")]        = GeoDataPlacemark::AmenityPostOffice;
1415     s_visualCategories[OsmTag("amenity", "prison")]             = GeoDataPlacemark::AmenityPrison;
1416     s_visualCategories[OsmTag("amenity", "recycling")]          = GeoDataPlacemark::AmenityRecycling;
1417     s_visualCategories[OsmTag("amenity", "shelter")]            = GeoDataPlacemark::AmenityShelter;
1418     s_visualCategories[OsmTag("amenity", "social_facility")]    = GeoDataPlacemark::AmenitySocialFacility;
1419     s_visualCategories[OsmTag("amenity", "telephone")]          = GeoDataPlacemark::AmenityTelephone;
1420     s_visualCategories[OsmTag("amenity", "theatre")]            = GeoDataPlacemark::AmenityTheatre;
1421     s_visualCategories[OsmTag("amenity", "toilets")]            = GeoDataPlacemark::AmenityToilets;
1422     s_visualCategories[OsmTag("amenity", "townhall")]           = GeoDataPlacemark::AmenityTownHall;
1423     s_visualCategories[OsmTag("amenity", "waste_basket")]       = GeoDataPlacemark::AmenityWasteBasket;
1424     s_visualCategories[OsmTag("emergency", "phone")]            = GeoDataPlacemark::AmenityEmergencyPhone;
1425     s_visualCategories[OsmTag("amenity", "mountain_rescue")]    = GeoDataPlacemark::AmenityMountainRescue;
1426     s_visualCategories[OsmTag("amenity", "dentist")]            = GeoDataPlacemark::HealthDentist;
1427     s_visualCategories[OsmTag("amenity", "doctors")]            = GeoDataPlacemark::HealthDoctors;
1428     s_visualCategories[OsmTag("amenity", "hospital")]           = GeoDataPlacemark::HealthHospital;
1429     s_visualCategories[OsmTag("amenity", "pharmacy")]           = GeoDataPlacemark::HealthPharmacy;
1430     s_visualCategories[OsmTag("amenity", "veterinary")]         = GeoDataPlacemark::HealthVeterinary;
1431 
1432     s_visualCategories[OsmTag("amenity", "place_of_worship")]   = GeoDataPlacemark::ReligionPlaceOfWorship;
1433 
1434     s_visualCategories[OsmTag("tourism", "information")]        = GeoDataPlacemark::TourismInformation;
1435 
1436     s_visualCategories[OsmTag("natural", "cave_entrance")]      = GeoDataPlacemark::NaturalCave;
1437     s_visualCategories[OsmTag("natural", "peak")]               = GeoDataPlacemark::NaturalPeak;
1438     s_visualCategories[OsmTag("natural", "tree")]               = GeoDataPlacemark::NaturalTree;
1439     s_visualCategories[OsmTag("natural", "volcano")]            = GeoDataPlacemark::NaturalVolcano;
1440 
1441     s_visualCategories[OsmTag("shop", "alcohol")]               = GeoDataPlacemark::ShopAlcohol;
1442     s_visualCategories[OsmTag("shop", "art")]                   = GeoDataPlacemark::ShopArt;
1443     s_visualCategories[OsmTag("shop", "bag")]                   = GeoDataPlacemark::ShopBag;
1444     s_visualCategories[OsmTag("shop", "bakery")]                = GeoDataPlacemark::ShopBakery;
1445     s_visualCategories[OsmTag("shop", "beauty")]                = GeoDataPlacemark::ShopBeauty;
1446     s_visualCategories[OsmTag("shop", "beverages")]             = GeoDataPlacemark::ShopBeverages;
1447     s_visualCategories[OsmTag("shop", "bicycle")]               = GeoDataPlacemark::ShopBicycle;
1448     s_visualCategories[OsmTag("shop", "books")]                 = GeoDataPlacemark::ShopBook;
1449     s_visualCategories[OsmTag("shop", "butcher")]               = GeoDataPlacemark::ShopButcher;
1450     s_visualCategories[OsmTag("shop", "car")]                   = GeoDataPlacemark::ShopCar;
1451     s_visualCategories[OsmTag("shop", "car_parts")]             = GeoDataPlacemark::ShopCarParts;
1452     s_visualCategories[OsmTag("shop", "car_repair")]            = GeoDataPlacemark::ShopCarRepair;
1453     s_visualCategories[OsmTag("shop", "chemist")]               = GeoDataPlacemark::ShopChemist;
1454     s_visualCategories[OsmTag("shop", "clothes")]               = GeoDataPlacemark::ShopClothes;
1455     s_visualCategories[OsmTag("shop", "confectionery")]         = GeoDataPlacemark::ShopConfectionery;
1456     s_visualCategories[OsmTag("shop", "convenience")]           = GeoDataPlacemark::ShopConvenience;
1457     s_visualCategories[OsmTag("shop", "copy")]                  = GeoDataPlacemark::ShopCopy;
1458     s_visualCategories[OsmTag("shop", "cosmetics")]             = GeoDataPlacemark::ShopCosmetics;
1459     s_visualCategories[OsmTag("shop", "deli")]                  = GeoDataPlacemark::ShopDeli;
1460     s_visualCategories[OsmTag("shop", "department_store")]      = GeoDataPlacemark::ShopDepartmentStore;
1461     s_visualCategories[OsmTag("shop", "doityourself")]          = GeoDataPlacemark::ShopDoitYourself;
1462     s_visualCategories[OsmTag("shop", "electronics")]           = GeoDataPlacemark::ShopElectronics;
1463     s_visualCategories[OsmTag("shop", "fashion")]               = GeoDataPlacemark::ShopFashion;
1464     s_visualCategories[OsmTag("shop", "florist")]               = GeoDataPlacemark::ShopFlorist;
1465     s_visualCategories[OsmTag("shop", "furniture")]             = GeoDataPlacemark::ShopFurniture;
1466     s_visualCategories[OsmTag("shop", "gift")]                  = GeoDataPlacemark::ShopGift;
1467     s_visualCategories[OsmTag("shop", "greengrocer")]           = GeoDataPlacemark::ShopGreengrocer;
1468     s_visualCategories[OsmTag("shop", "hairdresser")]           = GeoDataPlacemark::ShopHairdresser;
1469     s_visualCategories[OsmTag("shop", "hardware")]              = GeoDataPlacemark::ShopHardware;
1470     s_visualCategories[OsmTag("shop", "hifi")]                  = GeoDataPlacemark::ShopHifi;
1471     s_visualCategories[OsmTag("shop", "jewelry")]               = GeoDataPlacemark::ShopJewelry;
1472     s_visualCategories[OsmTag("shop", "kiosk")]                 = GeoDataPlacemark::ShopKiosk;
1473     s_visualCategories[OsmTag("shop", "laundry")]               = GeoDataPlacemark::ShopLaundry;
1474     s_visualCategories[OsmTag("shop", "mobile_phone")]          = GeoDataPlacemark::ShopMobilePhone;
1475     s_visualCategories[OsmTag("shop", "motorcycle")]            = GeoDataPlacemark::ShopMotorcycle;
1476     s_visualCategories[OsmTag("shop", "musical_instrument")]    = GeoDataPlacemark::ShopMusicalInstrument;
1477     s_visualCategories[OsmTag("shop", "optician")]              = GeoDataPlacemark::ShopOptician;
1478     s_visualCategories[OsmTag("shop", "outdoor")]               = GeoDataPlacemark::ShopOutdoor;
1479     s_visualCategories[OsmTag("shop", "perfumery")]             = GeoDataPlacemark::ShopPerfumery;
1480     s_visualCategories[OsmTag("shop", "pet")]                   = GeoDataPlacemark::ShopPet;
1481     s_visualCategories[OsmTag("shop", "photo")]                 = GeoDataPlacemark::ShopPhoto;
1482     s_visualCategories[OsmTag("shop", "seafood")]               = GeoDataPlacemark::ShopSeafood;
1483     s_visualCategories[OsmTag("shop", "shoes")]                 = GeoDataPlacemark::ShopShoes;
1484     s_visualCategories[OsmTag("shop", "sports")]                = GeoDataPlacemark::ShopSports;
1485     s_visualCategories[OsmTag("shop", "stationery")]            = GeoDataPlacemark::ShopStationery;
1486     s_visualCategories[OsmTag("shop", "supermarket")]           = GeoDataPlacemark::ShopSupermarket;
1487     s_visualCategories[OsmTag("shop", "tea")]                   = GeoDataPlacemark::ShopTea;
1488     s_visualCategories[OsmTag("shop", "computer")]              = GeoDataPlacemark::ShopComputer;
1489     s_visualCategories[OsmTag("shop", "garden_centre")]         = GeoDataPlacemark::ShopGardenCentre;
1490     s_visualCategories[OsmTag("shop", "tobacco")]               = GeoDataPlacemark::ShopTobacco;
1491     s_visualCategories[OsmTag("shop", "toys")]                  = GeoDataPlacemark::ShopToys;
1492     s_visualCategories[OsmTag("shop", "travel_agency")]         = GeoDataPlacemark::ShopTravelAgency;
1493     s_visualCategories[OsmTag("shop", "variety_store")]         = GeoDataPlacemark::ShopVarietyStore;
1494 
1495 
1496     // Default for all other shops
1497     for (const QString &value: shopValues()) {
1498         s_visualCategories[OsmTag("shop", value)]               = GeoDataPlacemark::Shop;
1499     }
1500 
1501     s_visualCategories[OsmTag("man_made", "bridge")]            = GeoDataPlacemark::ManmadeBridge;
1502     s_visualCategories[OsmTag("man_made", "lighthouse")]        = GeoDataPlacemark::ManmadeLighthouse;
1503     s_visualCategories[OsmTag("man_made", "pier")]              = GeoDataPlacemark::ManmadePier;
1504     s_visualCategories[OsmTag("man_made", "water_tower")]       = GeoDataPlacemark::ManmadeWaterTower;
1505     s_visualCategories[OsmTag("man_made", "windmill")]          = GeoDataPlacemark::ManmadeWindMill;
1506     s_visualCategories[OsmTag("man_made", "communications_tower")] = GeoDataPlacemark::ManmadeCommunicationsTower;
1507     s_visualCategories[OsmTag("tower:type", "communication")]   = GeoDataPlacemark::ManmadeCommunicationsTower;
1508 
1509     s_visualCategories[OsmTag("religion", "")]                  = GeoDataPlacemark::ReligionPlaceOfWorship;
1510     s_visualCategories[OsmTag("religion", "bahai")]             = GeoDataPlacemark::ReligionBahai;
1511     s_visualCategories[OsmTag("religion", "buddhist")]          = GeoDataPlacemark::ReligionBuddhist;
1512     s_visualCategories[OsmTag("religion", "christian")]         = GeoDataPlacemark::ReligionChristian;
1513     s_visualCategories[OsmTag("religion", "hindu")]             = GeoDataPlacemark::ReligionHindu;
1514     s_visualCategories[OsmTag("religion", "jain")]              = GeoDataPlacemark::ReligionJain;
1515     s_visualCategories[OsmTag("religion", "jewish")]            = GeoDataPlacemark::ReligionJewish;
1516     s_visualCategories[OsmTag("religion", "muslim")]            = GeoDataPlacemark::ReligionMuslim;
1517     s_visualCategories[OsmTag("religion", "shinto")]            = GeoDataPlacemark::ReligionShinto;
1518     s_visualCategories[OsmTag("religion", "sikh")]              = GeoDataPlacemark::ReligionSikh;
1519     s_visualCategories[OsmTag("religion", "taoist")]            = GeoDataPlacemark::ReligionTaoist;
1520 
1521     s_visualCategories[OsmTag("tourism", "camp_site")]          = GeoDataPlacemark::AccomodationCamping;
1522     s_visualCategories[OsmTag("tourism", "guest_house")]        = GeoDataPlacemark::AccomodationGuestHouse;
1523     s_visualCategories[OsmTag("tourism", "hostel")]             = GeoDataPlacemark::AccomodationHostel;
1524     s_visualCategories[OsmTag("tourism", "hotel")]              = GeoDataPlacemark::AccomodationHotel;
1525     s_visualCategories[OsmTag("tourism", "motel")]              = GeoDataPlacemark::AccomodationMotel;
1526 
1527     s_visualCategories[OsmTag("tourism", "alpine_hut")]         = GeoDataPlacemark::TourismAlpineHut;
1528     s_visualCategories[OsmTag("tourism", "artwork")]            = GeoDataPlacemark::TourismArtwork;
1529     s_visualCategories[OsmTag("tourism", "attraction")]         = GeoDataPlacemark::TourismAttraction;
1530     s_visualCategories[OsmTag("tourism", "museum")]             = GeoDataPlacemark::TourismMuseum;
1531     s_visualCategories[OsmTag("tourism", "theme_park")]         = GeoDataPlacemark::TourismThemePark;
1532     s_visualCategories[OsmTag("tourism", "viewpoint")]          = GeoDataPlacemark::TourismViewPoint;
1533     s_visualCategories[OsmTag("tourism", "wilderness_hut")]     = GeoDataPlacemark::TourismWildernessHut;
1534     s_visualCategories[OsmTag("tourism", "zoo")]                = GeoDataPlacemark::TourismZoo;
1535 
1536     s_visualCategories[OsmTag("barrier", "city_wall")]          = GeoDataPlacemark::BarrierCityWall;
1537     s_visualCategories[OsmTag("barrier", "gate")]               = GeoDataPlacemark::BarrierGate;
1538     s_visualCategories[OsmTag("barrier", "lift_gate")]          = GeoDataPlacemark::BarrierLiftGate;
1539     s_visualCategories[OsmTag("barrier", "wall")]               = GeoDataPlacemark::BarrierWall;
1540 
1541     s_visualCategories[OsmTag("highway", "traffic_signals")]    = GeoDataPlacemark::HighwayTrafficSignals;
1542     s_visualCategories[OsmTag("highway", "elevator")]           = GeoDataPlacemark::HighwayElevator;
1543 
1544     s_visualCategories[OsmTag("highway", "cycleway")]           = GeoDataPlacemark::HighwayCycleway;
1545     s_visualCategories[OsmTag("highway", "footway")]            = GeoDataPlacemark::HighwayFootway;
1546     s_visualCategories[OsmTag("highway", "living_street")]      = GeoDataPlacemark::HighwayLivingStreet;
1547     s_visualCategories[OsmTag("highway", "motorway")]           = GeoDataPlacemark::HighwayMotorway;
1548     s_visualCategories[OsmTag("highway", "motorway_link")]      = GeoDataPlacemark::HighwayMotorwayLink;
1549     s_visualCategories[OsmTag("highway", "path")]               = GeoDataPlacemark::HighwayPath;
1550     s_visualCategories[OsmTag("highway", "pedestrian")]         = GeoDataPlacemark::HighwayPedestrian;
1551     s_visualCategories[OsmTag("highway", "primary")]            = GeoDataPlacemark::HighwayPrimary;
1552     s_visualCategories[OsmTag("highway", "primary_link")]       = GeoDataPlacemark::HighwayPrimaryLink;
1553     s_visualCategories[OsmTag("highway", "raceway")]            = GeoDataPlacemark::HighwayRaceway;
1554     s_visualCategories[OsmTag("highway", "residential")]        = GeoDataPlacemark::HighwayResidential;
1555     s_visualCategories[OsmTag("highway", "road")]               = GeoDataPlacemark::HighwayRoad;
1556     s_visualCategories[OsmTag("highway", "secondary")]          = GeoDataPlacemark::HighwaySecondary;
1557     s_visualCategories[OsmTag("highway", "secondary_link")]     = GeoDataPlacemark::HighwaySecondaryLink;
1558     s_visualCategories[OsmTag("highway", "service")]            = GeoDataPlacemark::HighwayService;
1559     s_visualCategories[OsmTag("highway", "steps")]              = GeoDataPlacemark::HighwaySteps;
1560     s_visualCategories[OsmTag("highway", "tertiary")]           = GeoDataPlacemark::HighwayTertiary;
1561     s_visualCategories[OsmTag("highway", "tertiary_link")]      = GeoDataPlacemark::HighwayTertiaryLink;
1562     s_visualCategories[OsmTag("highway", "track")]              = GeoDataPlacemark::HighwayTrack;
1563     s_visualCategories[OsmTag("highway", "trunk")]              = GeoDataPlacemark::HighwayTrunk;
1564     s_visualCategories[OsmTag("highway", "trunk_link")]         = GeoDataPlacemark::HighwayTrunkLink;
1565     s_visualCategories[OsmTag("highway", "unclassified")]       = GeoDataPlacemark::HighwayUnclassified;
1566     s_visualCategories[OsmTag("highway", "unknown")]            = GeoDataPlacemark::HighwayUnknown;
1567     s_visualCategories[OsmTag("highway", "corridor")]           = GeoDataPlacemark::HighwayCorridor;
1568 
1569     s_visualCategories[OsmTag("natural", "bay")]                = GeoDataPlacemark::NaturalWater;
1570     s_visualCategories[OsmTag("natural", "coastline")]          = GeoDataPlacemark::NaturalWater;
1571     s_visualCategories[OsmTag("natural", "reef")]               = GeoDataPlacemark::NaturalReef;
1572     s_visualCategories[OsmTag("natural", "water")]              = GeoDataPlacemark::NaturalWater;
1573 
1574     s_visualCategories[OsmTag("waterway", "canal")]             = GeoDataPlacemark::WaterwayCanal;
1575     s_visualCategories[OsmTag("waterway", "ditch")]             = GeoDataPlacemark::WaterwayDitch;
1576     s_visualCategories[OsmTag("waterway", "drain")]             = GeoDataPlacemark::WaterwayDrain;
1577     s_visualCategories[OsmTag("waterway", "river")]             = GeoDataPlacemark::WaterwayRiver;
1578     s_visualCategories[OsmTag("waterway", "riverbank")]         = GeoDataPlacemark::NaturalWater;
1579     s_visualCategories[OsmTag("waterway", "weir")]              = GeoDataPlacemark::WaterwayWeir;
1580     s_visualCategories[OsmTag("waterway", "stream")]            = GeoDataPlacemark::WaterwayStream;
1581 
1582     s_visualCategories[OsmTag("natural", "beach")]              = GeoDataPlacemark::NaturalBeach;
1583     s_visualCategories[OsmTag("natural", "cliff")]              = GeoDataPlacemark::NaturalCliff;
1584     s_visualCategories[OsmTag("natural", "glacier")]            = GeoDataPlacemark::NaturalGlacier;
1585     s_visualCategories[OsmTag("glacier:type", "shelf")]         = GeoDataPlacemark::NaturalIceShelf;
1586     s_visualCategories[OsmTag("natural", "scrub")]              = GeoDataPlacemark::NaturalScrub;
1587     s_visualCategories[OsmTag("natural", "wetland")]            = GeoDataPlacemark::NaturalWetland;
1588     s_visualCategories[OsmTag("natural", "wood")]               = GeoDataPlacemark::NaturalWood;
1589 
1590     s_visualCategories[OsmTag("military", "danger_area")]       = GeoDataPlacemark::MilitaryDangerArea;
1591 
1592     s_visualCategories[OsmTag("landuse", "allotments")]         = GeoDataPlacemark::LanduseAllotments;
1593     s_visualCategories[OsmTag("landuse", "basin")]              = GeoDataPlacemark::LanduseBasin;
1594     s_visualCategories[OsmTag("landuse", "brownfield")]         = GeoDataPlacemark::LanduseConstruction;
1595     s_visualCategories[OsmTag("landuse", "cemetery")]           = GeoDataPlacemark::LanduseCemetery;
1596     s_visualCategories[OsmTag("landuse", "commercial")]         = GeoDataPlacemark::LanduseCommercial;
1597     s_visualCategories[OsmTag("landuse", "construction")]       = GeoDataPlacemark::LanduseConstruction;
1598     s_visualCategories[OsmTag("landuse", "farm")]               = GeoDataPlacemark::LanduseFarmland;
1599     s_visualCategories[OsmTag("landuse", "farmland")]           = GeoDataPlacemark::LanduseFarmland;
1600     s_visualCategories[OsmTag("landuse", "farmyard")]           = GeoDataPlacemark::LanduseFarmland;
1601     s_visualCategories[OsmTag("landuse", "forest")]             = GeoDataPlacemark::NaturalWood;
1602     s_visualCategories[OsmTag("landuse", "garages")]            = GeoDataPlacemark::LanduseGarages;
1603     s_visualCategories[OsmTag("landuse", "grass")]              = GeoDataPlacemark::LanduseGrass;
1604     s_visualCategories[OsmTag("landuse", "greenfield")]         = GeoDataPlacemark::LanduseConstruction;
1605     s_visualCategories[OsmTag("landuse", "greenhouse_horticulture")] = GeoDataPlacemark::LanduseFarmland;
1606     s_visualCategories[OsmTag("landuse", "industrial")]         = GeoDataPlacemark::LanduseIndustrial;
1607     s_visualCategories[OsmTag("landuse", "landfill")]           = GeoDataPlacemark::LanduseLandfill;
1608     s_visualCategories[OsmTag("landuse", "meadow")]             = GeoDataPlacemark::LanduseMeadow;
1609     s_visualCategories[OsmTag("landuse", "military")]           = GeoDataPlacemark::LanduseMilitary;
1610     s_visualCategories[OsmTag("landuse", "orchard")]            = GeoDataPlacemark::LanduseFarmland;
1611     s_visualCategories[OsmTag("landuse", "orchard")]            = GeoDataPlacemark::LanduseOrchard;
1612     s_visualCategories[OsmTag("landuse", "quarry")]             = GeoDataPlacemark::LanduseQuarry;
1613     s_visualCategories[OsmTag("landuse", "railway")]            = GeoDataPlacemark::LanduseRailway;
1614     s_visualCategories[OsmTag("landuse", "recreation_ground")]  = GeoDataPlacemark::LeisurePark;
1615     s_visualCategories[OsmTag("landuse", "reservoir")]          = GeoDataPlacemark::LanduseReservoir;
1616     s_visualCategories[OsmTag("landuse", "residential")]        = GeoDataPlacemark::LanduseResidential;
1617     s_visualCategories[OsmTag("landuse", "retail")]             = GeoDataPlacemark::LanduseRetail;
1618     s_visualCategories[OsmTag("landuse", "village_green")]      = GeoDataPlacemark::LanduseGrass;
1619     s_visualCategories[OsmTag("landuse", "vineyard")]           = GeoDataPlacemark::LanduseVineyard;
1620 
1621     s_visualCategories[OsmTag("leisure", "common")]             = GeoDataPlacemark::LanduseGrass;
1622     s_visualCategories[OsmTag("leisure", "garden")]             = GeoDataPlacemark::LanduseGrass;
1623 
1624     s_visualCategories[OsmTag("leisure", "golf_course")]        = GeoDataPlacemark::LeisureGolfCourse;
1625     s_visualCategories[OsmTag("leisure", "marina")]             = GeoDataPlacemark::LeisureMarina;
1626     s_visualCategories[OsmTag("leisure", "miniature_golf")]     = GeoDataPlacemark::LeisureMinigolfCourse;
1627     s_visualCategories[OsmTag("leisure", "park")]               = GeoDataPlacemark::LeisurePark;
1628     s_visualCategories[OsmTag("leisure", "pitch")]              = GeoDataPlacemark::LeisurePitch;
1629     s_visualCategories[OsmTag("leisure", "playground")]         = GeoDataPlacemark::LeisurePlayground;
1630     s_visualCategories[OsmTag("leisure", "sports_centre")]      = GeoDataPlacemark::LeisureSportsCentre;
1631     s_visualCategories[OsmTag("leisure", "stadium")]            = GeoDataPlacemark::LeisureStadium;
1632     s_visualCategories[OsmTag("leisure", "swimming_pool")]      = GeoDataPlacemark::LeisureSwimmingPool;
1633     s_visualCategories[OsmTag("leisure", "track")]              = GeoDataPlacemark::LeisureTrack;
1634     s_visualCategories[OsmTag("leisure", "water_park")]         = GeoDataPlacemark::LeisureWaterPark;
1635 
1636     s_visualCategories[OsmTag("railway", "abandoned")]          = GeoDataPlacemark::RailwayAbandoned;
1637     s_visualCategories[OsmTag("railway", "construction")]       = GeoDataPlacemark::RailwayConstruction;
1638     s_visualCategories[OsmTag("railway", "disused")]            = GeoDataPlacemark::RailwayAbandoned;
1639     s_visualCategories[OsmTag("railway", "funicular")]          = GeoDataPlacemark::RailwayFunicular;
1640     s_visualCategories[OsmTag("railway", "halt")]               = GeoDataPlacemark::TransportTrainStation;
1641     s_visualCategories[OsmTag("railway", "light_rail")]         = GeoDataPlacemark::RailwayLightRail;
1642     s_visualCategories[OsmTag("railway", "miniature")]          = GeoDataPlacemark::RailwayMiniature;
1643     s_visualCategories[OsmTag("railway", "monorail")]           = GeoDataPlacemark::RailwayMonorail;
1644     s_visualCategories[OsmTag("railway", "narrow_gauge")]       = GeoDataPlacemark::RailwayNarrowGauge;
1645     s_visualCategories[OsmTag("railway", "platform")]           = GeoDataPlacemark::TransportPlatform;
1646     s_visualCategories[OsmTag("railway", "preserved")]          = GeoDataPlacemark::RailwayPreserved;
1647     s_visualCategories[OsmTag("railway", "rail")]               = GeoDataPlacemark::RailwayRail;
1648     s_visualCategories[OsmTag("railway", "razed")]              = GeoDataPlacemark::RailwayAbandoned;
1649     s_visualCategories[OsmTag("railway", "station")]            = GeoDataPlacemark::TransportTrainStation;
1650     s_visualCategories[OsmTag("public_transport", "station")]   = GeoDataPlacemark::TransportTrainStation;
1651     s_visualCategories[OsmTag("railway", "subway")]             = GeoDataPlacemark::RailwaySubway;
1652     s_visualCategories[OsmTag("railway", "tram")]               = GeoDataPlacemark::RailwayTram;
1653 
1654     s_visualCategories[OsmTag("power", "tower")]                = GeoDataPlacemark::PowerTower;
1655 
1656     s_visualCategories[OsmTag("aeroway", "aerodrome")]          = GeoDataPlacemark::TransportAerodrome;
1657     s_visualCategories[OsmTag("aeroway", "apron")]              = GeoDataPlacemark::TransportAirportApron;
1658     s_visualCategories[OsmTag("aeroway", "gate")]               = GeoDataPlacemark::TransportAirportGate;
1659     s_visualCategories[OsmTag("aeroway", "helipad")]            = GeoDataPlacemark::TransportHelipad;
1660     s_visualCategories[OsmTag("aeroway", "runway")]             = GeoDataPlacemark::TransportAirportRunway;
1661     s_visualCategories[OsmTag("aeroway", "taxiway")]            = GeoDataPlacemark::TransportAirportTaxiway;
1662     s_visualCategories[OsmTag("aeroway", "terminal")]           = GeoDataPlacemark::TransportAirportTerminal;
1663 
1664     s_visualCategories[OsmTag("piste:type", "downhill")]        = GeoDataPlacemark::PisteDownhill;
1665     s_visualCategories[OsmTag("piste:type", "nordic")]          = GeoDataPlacemark::PisteNordic;
1666     s_visualCategories[OsmTag("piste:type", "skitour")]         = GeoDataPlacemark::PisteSkitour;
1667     s_visualCategories[OsmTag("piste:type", "sled")]            = GeoDataPlacemark::PisteSled;
1668     s_visualCategories[OsmTag("piste:type", "hike")]            = GeoDataPlacemark::PisteHike;
1669     s_visualCategories[OsmTag("piste:type", "sleigh")]          = GeoDataPlacemark::PisteSleigh;
1670     s_visualCategories[OsmTag("piste:type", "ice_skate")]       = GeoDataPlacemark::PisteIceSkate;
1671     s_visualCategories[OsmTag("piste:type", "snow_park")]       = GeoDataPlacemark::PisteSnowPark;
1672     s_visualCategories[OsmTag("piste:type", "playground")]      = GeoDataPlacemark::PistePlayground;
1673     s_visualCategories[OsmTag("piste:type", "ski_jump")]        = GeoDataPlacemark::PisteSkiJump;
1674 
1675     s_visualCategories[OsmTag("amenity", "bicycle_parking")]    = GeoDataPlacemark::TransportBicycleParking;
1676     s_visualCategories[OsmTag("amenity", "bicycle_rental")]     = GeoDataPlacemark::TransportRentalBicycle;
1677     s_visualCategories[OsmTag("rental", "bicycle")]             = GeoDataPlacemark::TransportRentalBicycle;
1678     s_visualCategories[OsmTag("amenity", "car_rental")]         = GeoDataPlacemark::TransportRentalCar;
1679     s_visualCategories[OsmTag("rental", "car")]                 = GeoDataPlacemark::TransportRentalCar;
1680     s_visualCategories[OsmTag("amenity", "ski_rental")]         = GeoDataPlacemark::TransportRentalSki;
1681     s_visualCategories[OsmTag("rental", "ski")]                 = GeoDataPlacemark::TransportRentalSki;
1682     s_visualCategories[OsmTag("amenity", "motorcycle_parking")] = GeoDataPlacemark::TransportMotorcycleParking;
1683     s_visualCategories[OsmTag("amenity", "taxi")]               = GeoDataPlacemark::TransportTaxiRank;
1684     s_visualCategories[OsmTag("highway", "bus_stop")]           = GeoDataPlacemark::TransportBusStop;
1685     s_visualCategories[OsmTag("highway", "speed_camera")]       = GeoDataPlacemark::TransportSpeedCamera;
1686     s_visualCategories[OsmTag("public_transport", "platform")]  = GeoDataPlacemark::TransportPlatform;
1687     s_visualCategories[OsmTag("railway", "subway_entrance")]    = GeoDataPlacemark::TransportSubwayEntrance;
1688     s_visualCategories[OsmTag("railway", "tram_stop")]          = GeoDataPlacemark::TransportTramStop;
1689 
1690     s_visualCategories[OsmTag("place", "city")]                 = GeoDataPlacemark::PlaceCity;
1691     s_visualCategories[OsmTag("place", "hamlet")]               = GeoDataPlacemark::PlaceHamlet;
1692     s_visualCategories[OsmTag("place", "locality")]             = GeoDataPlacemark::PlaceLocality;
1693     s_visualCategories[OsmTag("place", "suburb")]               = GeoDataPlacemark::PlaceSuburb;
1694     s_visualCategories[OsmTag("place", "town")]                 = GeoDataPlacemark::PlaceTown;
1695     s_visualCategories[OsmTag("place", "village")]              = GeoDataPlacemark::PlaceVillage;
1696 
1697     s_visualCategories[OsmTag("aerialway", "station")]          = GeoDataPlacemark::AerialwayStation;
1698     s_visualCategories[OsmTag("aerialway", "pylon")]            = GeoDataPlacemark::AerialwayPylon;
1699     s_visualCategories[OsmTag("aerialway", "cable_car")]        = GeoDataPlacemark::AerialwayCableCar;
1700     s_visualCategories[OsmTag("aerialway", "gondola")]          = GeoDataPlacemark::AerialwayGondola;
1701     s_visualCategories[OsmTag("aerialway", "chair_lift")]       = GeoDataPlacemark::AerialwayChairLift;
1702     s_visualCategories[OsmTag("aerialway", "mixed_lift")]       = GeoDataPlacemark::AerialwayMixedLift;
1703     s_visualCategories[OsmTag("aerialway", "drag_lift")]        = GeoDataPlacemark::AerialwayDragLift;
1704     s_visualCategories[OsmTag("aerialway", "t-bar")]            = GeoDataPlacemark::AerialwayTBar;
1705     s_visualCategories[OsmTag("aerialway", "j-bar")]            = GeoDataPlacemark::AerialwayJBar;
1706     s_visualCategories[OsmTag("aerialway", "platter")]          = GeoDataPlacemark::AerialwayPlatter;
1707     s_visualCategories[OsmTag("aerialway", "rope_tow")]         = GeoDataPlacemark::AerialwayRopeTow;
1708     s_visualCategories[OsmTag("aerialway", "magic_carpet")]     = GeoDataPlacemark::AerialwayMagicCarpet;
1709     s_visualCategories[OsmTag("aerialway", "zip_line")]         = GeoDataPlacemark::AerialwayZipLine;
1710     s_visualCategories[OsmTag("aerialway", "goods")]            = GeoDataPlacemark::AerialwayGoods;
1711 
1712     s_visualCategories[OsmTag("indoor", "door")]                = GeoDataPlacemark::IndoorDoor;
1713     s_visualCategories[OsmTag("indoor", "wall")]                = GeoDataPlacemark::IndoorWall;
1714     s_visualCategories[OsmTag("indoor", "room")]                = GeoDataPlacemark::IndoorRoom;
1715 
1716     //Custom Marble OSM Tags
1717     s_visualCategories[OsmTag("marble_land", "landmass")]       = GeoDataPlacemark::Landmass;
1718     s_visualCategories[OsmTag("settlement", "yes")]             = GeoDataPlacemark::UrbanArea;
1719     s_visualCategories[OsmTag("marble_line", "date")]           = GeoDataPlacemark::InternationalDateLine;
1720     s_visualCategories[OsmTag("marble:feature", "bathymetry")]  = GeoDataPlacemark::Bathymetry;
1721 
1722     // Default for buildings
1723     for (const auto &tag: buildingTags()) {
1724         s_visualCategories[tag]                                 = GeoDataPlacemark::Building;
1725     }
1726 }
1727 
1728 void StyleBuilder::Private::initializeMinimumZoomLevels()
1729 {
1730     if (s_defaultMinZoomLevelsInitialized) {
1731         return;
1732     }
1733 
1734     s_defaultMinZoomLevelsInitialized = true;
1735     for (int i = 0; i < GeoDataPlacemark::LastIndex; i++) {
1736         s_defaultMinZoomLevels[i] = -1;
1737     }
1738 
1739     s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel10] = 8;
1740     s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel11] = 8;
1741     s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel1] = 0;
1742     s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel2] = 1;
1743     s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel3] = 1;
1744     s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel4] = 2;
1745     s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel5] = 4;
1746     s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel6] = 5;
1747     s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel7] = 5;
1748     s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel8] = 7;
1749     s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel9] = 7;
1750 
1751     s_defaultMinZoomLevels[GeoDataPlacemark::HistoricArchaeologicalSite] = 16;
1752     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityBench] = 19;
1753     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityFountain]     = 17;
1754     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityGraveyard]    = 16;
1755     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityTelephone]  = 17;
1756     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityKindergarten]  = 16;
1757     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityLibrary]  = 16;
1758     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityWasteBasket]  = 19;
1759     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityToilets] = 17;
1760     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityTownHall] = 15;
1761     s_defaultMinZoomLevels[GeoDataPlacemark::LeisureWaterPark]  = 15;
1762     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityDrinkingWater] = 17;
1763     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityEmbassy] = 15;
1764     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityEmergencyPhone] = 17;
1765     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityMountainRescue] = 16;
1766     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityCommunityCentre] = 17;
1767     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityFountain] = 17;
1768     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityNightClub] = 16;
1769     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityCourtHouse] = 16;
1770     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityFireStation] = 16;
1771     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityHuntingStand] = 17;
1772     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityPolice] = 16;
1773     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityPostBox] = 17;
1774     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityPostOffice] = 17;
1775     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityPrison] = 17;
1776     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityRecycling] = 17;
1777     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityShelter] = 17;
1778     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityChargingStation] = 17;
1779     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityCarWash] = 17;
1780     s_defaultMinZoomLevels[GeoDataPlacemark::AmenitySocialFacility] = 17;
1781 
1782     s_defaultMinZoomLevels[GeoDataPlacemark::BarrierCityWall] = 15;
1783     s_defaultMinZoomLevels[GeoDataPlacemark::BarrierGate]     = 17;
1784     s_defaultMinZoomLevels[GeoDataPlacemark::BarrierLiftGate] = 17;
1785     s_defaultMinZoomLevels[GeoDataPlacemark::BarrierWall]     = 17;
1786 
1787     s_defaultMinZoomLevels[GeoDataPlacemark::Bathymetry]  = 1;
1788 
1789     s_defaultMinZoomLevels[GeoDataPlacemark::BoundaryMaritime]    = 1;
1790 
1791     s_defaultMinZoomLevels[GeoDataPlacemark::Building]    = 17;
1792 
1793     s_defaultMinZoomLevels[GeoDataPlacemark::Default]     = 1;
1794 
1795     s_defaultMinZoomLevels[GeoDataPlacemark::EducationCollege]  = 15;
1796     s_defaultMinZoomLevels[GeoDataPlacemark::EducationSchool]  = 15;
1797     s_defaultMinZoomLevels[GeoDataPlacemark::EducationUniversity]  = 15;
1798 
1799     s_defaultMinZoomLevels[GeoDataPlacemark::FoodBar]  = 16;
1800     s_defaultMinZoomLevels[GeoDataPlacemark::FoodBiergarten]  = 16;
1801     s_defaultMinZoomLevels[GeoDataPlacemark::FoodCafe]  = 16;
1802     s_defaultMinZoomLevels[GeoDataPlacemark::FoodFastFood]  = 16;
1803     s_defaultMinZoomLevels[GeoDataPlacemark::FoodPub]  = 16;
1804     s_defaultMinZoomLevels[GeoDataPlacemark::FoodRestaurant]  = 16;
1805 
1806     s_defaultMinZoomLevels[GeoDataPlacemark::HealthHospital]  = 15;
1807     s_defaultMinZoomLevels[GeoDataPlacemark::HealthPharmacy]  = 17;
1808     s_defaultMinZoomLevels[GeoDataPlacemark::HealthDentist]  = 17;
1809     s_defaultMinZoomLevels[GeoDataPlacemark::HealthDoctors]  = 17;
1810     s_defaultMinZoomLevels[GeoDataPlacemark::HealthVeterinary]  = 17;
1811 
1812     s_defaultMinZoomLevels[GeoDataPlacemark::HistoricMemorial]    = 17;
1813 
1814     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayCycleway]     = 16;
1815     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayFootway]      = 17;
1816     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayLivingStreet] = 15;
1817     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayMotorwayLink] = 10;
1818     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayMotorway]     = 6;
1819     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayPath] = 13;
1820     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayPedestrian]   = 13;
1821     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayPrimaryLink]  = 10;
1822     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayPrimary]      = 8;
1823     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayRaceway]      = 12;
1824     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayResidential]  = 14;
1825     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayRoad] = 13;
1826     s_defaultMinZoomLevels[GeoDataPlacemark::HighwaySecondaryLink] = 10;
1827     s_defaultMinZoomLevels[GeoDataPlacemark::HighwaySecondary]    = 9;
1828     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayService]      = 15;
1829     s_defaultMinZoomLevels[GeoDataPlacemark::HighwaySteps] = 15;
1830     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayTertiaryLink] = 10;
1831     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayTertiary]     = 10;
1832     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayTrack] = 15;
1833     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayTrunkLink]    = 10;
1834     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayTrunk] = 7;
1835     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayUnknown]      = 16;
1836     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayUnclassified] = 16;
1837     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayTrafficSignals]      = 17;
1838     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayCorridor]     = 18;
1839     s_defaultMinZoomLevels[GeoDataPlacemark::HighwayElevator] = 17;
1840 
1841     s_defaultMinZoomLevels[GeoDataPlacemark::AccomodationCamping] = 16;
1842     s_defaultMinZoomLevels[GeoDataPlacemark::AccomodationHostel] = 16;
1843     s_defaultMinZoomLevels[GeoDataPlacemark::AccomodationHotel] = 16;
1844     s_defaultMinZoomLevels[GeoDataPlacemark::AccomodationMotel] = 16;
1845     s_defaultMinZoomLevels[GeoDataPlacemark::AccomodationYouthHostel] = 16;
1846     s_defaultMinZoomLevels[GeoDataPlacemark::AccomodationGuestHouse] = 16;
1847 
1848     s_defaultMinZoomLevels[GeoDataPlacemark::InternationalDateLine]      = 1;
1849 
1850     s_defaultMinZoomLevels[GeoDataPlacemark::Landmass]    = 0;
1851 
1852     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseAllotments]   = 11;
1853     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseBasin] = 11;
1854     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseCemetery]     = 11;
1855     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseCommercial]   = 13;
1856     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseConstruction] = 11;
1857     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseFarmland]     = 13;
1858     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseFarmyard]     = 13;
1859     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseGarages]      = 11;
1860     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseGrass] = 13;
1861     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseIndustrial]   = 13;
1862     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseLandfill]     = 11;
1863     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseMeadow]       = 13;
1864     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseMilitary]     = 11;
1865     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseOrchard]      = 14;
1866     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseQuarry]       = 11;
1867     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseRailway]      = 11;
1868     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseReservoir]    = 11;
1869     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseResidential]  = 11;
1870     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseRetail]       = 13;
1871     s_defaultMinZoomLevels[GeoDataPlacemark::LanduseVineyard]     = 14;
1872 
1873     s_defaultMinZoomLevels[GeoDataPlacemark::LeisureGolfCourse]   = 15;
1874     s_defaultMinZoomLevels[GeoDataPlacemark::LeisureMarina]       = 13;
1875     s_defaultMinZoomLevels[GeoDataPlacemark::LeisurePark] = 11;
1876     s_defaultMinZoomLevels[GeoDataPlacemark::LeisurePlayground]   = 17;
1877     s_defaultMinZoomLevels[GeoDataPlacemark::LeisurePitch]   = 15;
1878     s_defaultMinZoomLevels[GeoDataPlacemark::LeisureStadium]   = 13;
1879     s_defaultMinZoomLevels[GeoDataPlacemark::LeisureSwimmingPool]   = 17;
1880     s_defaultMinZoomLevels[GeoDataPlacemark::LeisureSportsCentre]   = 15;
1881     s_defaultMinZoomLevels[GeoDataPlacemark::LeisureTrack]   = 16;
1882     s_defaultMinZoomLevels[GeoDataPlacemark::LeisureMinigolfCourse] = 16;
1883 
1884     s_defaultMinZoomLevels[GeoDataPlacemark::ManmadeBridge]       = 15;
1885     s_defaultMinZoomLevels[GeoDataPlacemark::ManmadeLighthouse]       = 15;
1886     s_defaultMinZoomLevels[GeoDataPlacemark::ManmadePier]       = 15;
1887     s_defaultMinZoomLevels[GeoDataPlacemark::ManmadeWaterTower]       = 15;
1888     s_defaultMinZoomLevels[GeoDataPlacemark::ManmadeWindMill]       = 15;
1889     s_defaultMinZoomLevels[GeoDataPlacemark::ManmadeCommunicationsTower]       = 15;
1890 
1891     s_defaultMinZoomLevels[GeoDataPlacemark::MilitaryDangerArea]  = 11;
1892 
1893     s_defaultMinZoomLevels[GeoDataPlacemark::MoneyAtm]    = 16;
1894     s_defaultMinZoomLevels[GeoDataPlacemark::MoneyBank]    = 16;
1895 
1896     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalBeach] = 13;
1897     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalCliff] = 15;
1898     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalGlacier]      = 3;
1899     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalHeath]      = 13;
1900     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalIceShelf]     = 3;
1901     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalVolcano]      = 13;
1902     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalPeak] = 11;
1903     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalReef] = 3;
1904     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalScrub] = 13;
1905     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalTree] = 17;
1906     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalCave] = 16;
1907     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalWater] = 3;
1908     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalWetland]      = 10;
1909     s_defaultMinZoomLevels[GeoDataPlacemark::NaturalWood] = 8;
1910 
1911     s_defaultMinZoomLevels[GeoDataPlacemark::PlaceCityNationalCapital] = 9;
1912     s_defaultMinZoomLevels[GeoDataPlacemark::PlaceCityCapital]    = 9;
1913     s_defaultMinZoomLevels[GeoDataPlacemark::PlaceCity]   = 9;
1914     s_defaultMinZoomLevels[GeoDataPlacemark::PlaceHamlet] = 15;
1915     s_defaultMinZoomLevels[GeoDataPlacemark::PlaceLocality]       = 15;
1916     s_defaultMinZoomLevels[GeoDataPlacemark::PlaceSuburb] = 13;
1917     s_defaultMinZoomLevels[GeoDataPlacemark::PlaceTownNationalCapital] = 11;
1918     s_defaultMinZoomLevels[GeoDataPlacemark::PlaceTownCapital]    = 11;
1919     s_defaultMinZoomLevels[GeoDataPlacemark::PlaceTown]   = 11;
1920     s_defaultMinZoomLevels[GeoDataPlacemark::PlaceVillageNationalCapital] = 13;
1921     s_defaultMinZoomLevels[GeoDataPlacemark::PlaceVillageCapital] = 13;
1922     s_defaultMinZoomLevels[GeoDataPlacemark::PlaceVillage] = 13;
1923 
1924     s_defaultMinZoomLevels[GeoDataPlacemark::PowerTower] = 18;
1925 
1926     s_defaultMinZoomLevels[GeoDataPlacemark::RailwayAbandoned]    = 10;
1927     s_defaultMinZoomLevels[GeoDataPlacemark::RailwayConstruction] = 10;
1928     s_defaultMinZoomLevels[GeoDataPlacemark::RailwayFunicular]    = 13;
1929     s_defaultMinZoomLevels[GeoDataPlacemark::RailwayLightRail]    = 12;
1930     s_defaultMinZoomLevels[GeoDataPlacemark::RailwayMiniature]    = 16;
1931     s_defaultMinZoomLevels[GeoDataPlacemark::RailwayMonorail]     = 12;
1932     s_defaultMinZoomLevels[GeoDataPlacemark::RailwayNarrowGauge]  = 6;
1933     s_defaultMinZoomLevels[GeoDataPlacemark::RailwayPreserved]    = 13;
1934     s_defaultMinZoomLevels[GeoDataPlacemark::RailwayRail] = 6;
1935     s_defaultMinZoomLevels[GeoDataPlacemark::RailwaySubway]       = 13;
1936     s_defaultMinZoomLevels[GeoDataPlacemark::RailwayTram] = 14;
1937 
1938     s_defaultMinZoomLevels[GeoDataPlacemark::Satellite]   = 0;
1939 
1940     for (int shop = GeoDataPlacemark::ShopBeverages; shop <= GeoDataPlacemark::Shop; ++shop) {
1941         s_defaultMinZoomLevels[shop] = 17;
1942     }
1943     s_defaultMinZoomLevels[GeoDataPlacemark::ShopSupermarket] = 16;
1944     s_defaultMinZoomLevels[GeoDataPlacemark::ShopDepartmentStore] = 16;
1945     s_defaultMinZoomLevels[GeoDataPlacemark::ShopDoitYourself] = 16;
1946 
1947     s_defaultMinZoomLevels[GeoDataPlacemark::TourismAlpineHut]  = 13;
1948     s_defaultMinZoomLevels[GeoDataPlacemark::TourismWildernessHut] = 13;
1949     s_defaultMinZoomLevels[GeoDataPlacemark::TourismAttraction]  = 17;
1950     s_defaultMinZoomLevels[GeoDataPlacemark::TourismArtwork] = 17;
1951     s_defaultMinZoomLevels[GeoDataPlacemark::HistoricCastle]  = 15;
1952     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityCinema]  = 16;
1953     s_defaultMinZoomLevels[GeoDataPlacemark::TourismMuseum]  = 16;
1954     s_defaultMinZoomLevels[GeoDataPlacemark::HistoricRuins]  = 16;
1955     s_defaultMinZoomLevels[GeoDataPlacemark::AmenityTheatre]  = 16;
1956     s_defaultMinZoomLevels[GeoDataPlacemark::TourismThemePark]  = 15;
1957     s_defaultMinZoomLevels[GeoDataPlacemark::TourismViewPoint]  = 15;
1958     s_defaultMinZoomLevels[GeoDataPlacemark::TourismZoo]  = 15;
1959     s_defaultMinZoomLevels[GeoDataPlacemark::HistoricMonument]  = 16;
1960     s_defaultMinZoomLevels[GeoDataPlacemark::TourismInformation]  = 17;
1961     s_defaultMinZoomLevels[GeoDataPlacemark::TransportAerodrome] = 9;
1962     s_defaultMinZoomLevels[GeoDataPlacemark::TransportAirportApron] = 15;
1963     s_defaultMinZoomLevels[GeoDataPlacemark::TransportAirportRunway] = 15;
1964     s_defaultMinZoomLevels[GeoDataPlacemark::TransportAirportTaxiway] = 15;
1965     s_defaultMinZoomLevels[GeoDataPlacemark::TransportBusStation]  = 15;
1966     s_defaultMinZoomLevels[GeoDataPlacemark::TransportCarShare]  = 16;
1967     s_defaultMinZoomLevels[GeoDataPlacemark::TransportFuel]  = 16;
1968     s_defaultMinZoomLevels[GeoDataPlacemark::TransportHelipad] = 16;
1969     s_defaultMinZoomLevels[GeoDataPlacemark::TransportAirportTerminal] = 17;
1970     s_defaultMinZoomLevels[GeoDataPlacemark::TransportAirportGate] = 17;
1971     s_defaultMinZoomLevels[GeoDataPlacemark::TransportPlatform]   = 16;
1972     s_defaultMinZoomLevels[GeoDataPlacemark::TransportSpeedCamera] = 16;
1973     s_defaultMinZoomLevels[GeoDataPlacemark::TransportRentalCar] = 16;
1974     s_defaultMinZoomLevels[GeoDataPlacemark::TransportRentalBicycle] = 17;
1975     s_defaultMinZoomLevels[GeoDataPlacemark::TransportRentalSki] = 17;
1976     s_defaultMinZoomLevels[GeoDataPlacemark::TransportTaxiRank]  = 16;
1977     s_defaultMinZoomLevels[GeoDataPlacemark::TransportParking]  = 16;
1978     s_defaultMinZoomLevels[GeoDataPlacemark::TransportBusStop]  = 16;
1979     s_defaultMinZoomLevels[GeoDataPlacemark::TransportTrainStation]  = 13;
1980     s_defaultMinZoomLevels[GeoDataPlacemark::TransportTramStop]  = 15;
1981     s_defaultMinZoomLevels[GeoDataPlacemark::TransportParkingSpace]  = 17;
1982     s_defaultMinZoomLevels[GeoDataPlacemark::TransportBicycleParking]  = 17;
1983     s_defaultMinZoomLevels[GeoDataPlacemark::TransportMotorcycleParking]  = 17;
1984     s_defaultMinZoomLevels[GeoDataPlacemark::TransportSubwayEntrance]  = 17;
1985 
1986     for (int religion = GeoDataPlacemark::ReligionPlaceOfWorship; religion <= GeoDataPlacemark::ReligionTaoist; ++religion) {
1987         s_defaultMinZoomLevels[religion] = 17;
1988     }
1989 
1990     s_defaultMinZoomLevels[GeoDataPlacemark::UrbanArea]   = 3;
1991 
1992     s_defaultMinZoomLevels[GeoDataPlacemark::WaterwayCanal] = 15;
1993     s_defaultMinZoomLevels[GeoDataPlacemark::WaterwayDitch] = 17;
1994     s_defaultMinZoomLevels[GeoDataPlacemark::WaterwayDrain] = 17;
1995     s_defaultMinZoomLevels[GeoDataPlacemark::WaterwayStream] = 15;
1996     s_defaultMinZoomLevels[GeoDataPlacemark::WaterwayRiver] = 3;
1997     s_defaultMinZoomLevels[GeoDataPlacemark::WaterwayWeir] = 17;
1998 
1999     s_defaultMinZoomLevels[GeoDataPlacemark::CrossingIsland] = 18;
2000     s_defaultMinZoomLevels[GeoDataPlacemark::CrossingRailway] = 18;
2001     s_defaultMinZoomLevels[GeoDataPlacemark::CrossingSignals] = 18;
2002     s_defaultMinZoomLevels[GeoDataPlacemark::CrossingZebra] = 18;
2003 
2004     s_defaultMinZoomLevels[GeoDataPlacemark::PisteDownhill] = 15;
2005     s_defaultMinZoomLevels[GeoDataPlacemark::PisteNordic] = 15;
2006     s_defaultMinZoomLevels[GeoDataPlacemark::PisteSkitour] = 15;
2007     s_defaultMinZoomLevels[GeoDataPlacemark::PisteSled] = 15;
2008     s_defaultMinZoomLevels[GeoDataPlacemark::PisteHike] = 15;
2009     s_defaultMinZoomLevels[GeoDataPlacemark::PisteSleigh] = 15;
2010     s_defaultMinZoomLevels[GeoDataPlacemark::PisteIceSkate] = 15;
2011     s_defaultMinZoomLevels[GeoDataPlacemark::PisteSnowPark] = 15;
2012     s_defaultMinZoomLevels[GeoDataPlacemark::PistePlayground] = 15;
2013     s_defaultMinZoomLevels[GeoDataPlacemark::PisteSkiJump] = 15;
2014 
2015     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayStation] = 15;
2016     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayPylon] = 16;
2017     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayCableCar] = 15;
2018     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayGondola] = 15;
2019     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayChairLift] = 15;
2020     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayMixedLift] = 15;
2021     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayDragLift] = 15;
2022     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayTBar] = 15;
2023     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayJBar] = 15;
2024     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayPlatter] = 15;
2025     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayRopeTow] = 15;
2026     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayMagicCarpet] = 15;
2027     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayZipLine] = 15;
2028     s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayGoods] = 15;
2029 
2030     s_defaultMinZoomLevels[GeoDataPlacemark::IndoorDoor] = 17;
2031     s_defaultMinZoomLevels[GeoDataPlacemark::IndoorWall] = 17;
2032     s_defaultMinZoomLevels[GeoDataPlacemark::IndoorRoom] = 17;
2033 
2034     for (int i = GeoDataPlacemark::PlaceCity; i < GeoDataPlacemark::LastIndex; i++) {
2035         if (s_defaultMinZoomLevels[i] < 0) {
2036             qDebug() << "Missing default min zoom level for GeoDataPlacemark::GeoDataVisualCategory " << i;
2037             Q_ASSERT(false && "StyleBuilder::Private::initializeMinimumZoomLevels is incomplete");
2038             s_defaultMinZoomLevels[i] = 15;
2039         }
2040     }
2041 
2042 }
2043 
2044 StyleBuilder::StyleBuilder() :
2045     d(new Private)
2046 {
2047     // nothing to do
2048 }
2049 
2050 StyleBuilder::~StyleBuilder()
2051 {
2052     delete d;
2053 }
2054 
2055 QFont StyleBuilder::defaultFont() const
2056 {
2057     return d->m_defaultFont;
2058 }
2059 
2060 void StyleBuilder::setDefaultFont(const QFont& font)
2061 {
2062     d->m_defaultFont = font;
2063     reset();
2064 }
2065 
2066 QColor StyleBuilder::defaultLabelColor() const
2067 {
2068     return d->m_defaultLabelColor;
2069 }
2070 
2071 void StyleBuilder::setDefaultLabelColor(const QColor& color)
2072 {
2073     d->m_defaultLabelColor = color;
2074     reset();
2075 }
2076 
2077 GeoDataStyle::ConstPtr StyleBuilder::createStyle(const StyleParameters &parameters) const
2078 {
2079     const GeoDataPlacemark *const placemark = parameters.placemark;
2080 
2081     if (!placemark) {
2082         Q_ASSERT(false && "Must not pass a null placemark to StyleBuilder::createStyle");
2083         return GeoDataStyle::Ptr();
2084     }
2085 
2086     if (placemark->customStyle()) {
2087         return placemark->customStyle();
2088     }
2089 
2090     if (parameters.relation) {
2091         auto style = d->createRelationStyle(parameters);
2092         if (style) {
2093             return style;
2094         }
2095     }
2096 
2097     return d->createPlacemarkStyle(parameters);
2098 }
2099 
2100 GeoDataStyle::ConstPtr StyleBuilder::Private::presetStyle(GeoDataPlacemark::GeoDataVisualCategory visualCategory) const
2101 {
2102     if (!m_defaultStyleInitialized) {
2103         const_cast<StyleBuilder::Private *>(this)->initializeDefaultStyles(); // const cast due to lazy initialization
2104     }
2105 
2106     if (m_defaultStyle[visualCategory]) {
2107         return m_defaultStyle[visualCategory];
2108     } else {
2109         return m_defaultStyle[GeoDataPlacemark::Default];
2110     }
2111 }
2112 
2113 
2114 QStringList StyleBuilder::renderOrder() const
2115 {
2116     static QStringList paintLayerOrder;
2117 
2118     if (paintLayerOrder.isEmpty()) {
2119         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::Landmass);
2120         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::UrbanArea);
2121         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseResidential);
2122         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseAllotments);
2123         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseBasin);
2124         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseCemetery);
2125         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseCommercial);
2126         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseConstruction);
2127         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseFarmland);
2128         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseFarmyard);
2129         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseGarages);
2130         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseIndustrial);
2131         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseLandfill);
2132         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseMeadow);
2133         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseMilitary);
2134         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseQuarry);
2135         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseRailway);
2136         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseReservoir);
2137         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseRetail);
2138         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseOrchard);
2139         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseVineyard);
2140 
2141         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::Bathymetry);
2142         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureGolfCourse);
2143         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureMinigolfCourse);
2144         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalBeach);
2145         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalWetland);
2146         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalGlacier);
2147         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalIceShelf);
2148         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalVolcano);
2149         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalCliff);
2150         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalPeak);
2151         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::MilitaryDangerArea);
2152         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisurePark);
2153         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisurePitch);
2154         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureSportsCentre);
2155         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureStadium);
2156         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalWood);
2157         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseGrass);
2158         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::HighwayPedestrian);
2159         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisurePlayground);
2160         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalScrub);
2161         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureTrack);
2162         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::TransportParking);
2163         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::TransportParkingSpace);
2164         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::ManmadeBridge);
2165         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::BarrierCityWall);
2166 
2167         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::AmenityGraveyard);
2168 
2169         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::AmenityKindergarten);
2170         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::EducationCollege);
2171         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::EducationSchool);
2172         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::EducationUniversity);
2173         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::HealthHospital);
2174         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureSwimmingPool);
2175 
2176         paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::Landmass);
2177 
2178         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalWater);
2179         for (int i = GeoDataPlacemark::WaterwayCanal; i <= GeoDataPlacemark::WaterwayStream; ++i) {
2180             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "outline");
2181             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "inline");
2182             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "label");
2183         }
2184 
2185         paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::NaturalReef, "outline");
2186         paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::NaturalReef, "inline");
2187         paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::NaturalReef, "label");
2188         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureMarina);
2189         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::ManmadePier);
2190         paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::ManmadePier, "outline");
2191         paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::ManmadePier, "inline");
2192         paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::ManmadePier, "label");
2193 
2194         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::TransportAirportApron);
2195 
2196         for (int i = GeoDataPlacemark::HighwaySteps; i <= GeoDataPlacemark::HighwayMotorway; i++) {
2197             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "outline");
2198         }
2199         for (int i = GeoDataPlacemark::HighwaySteps; i <= GeoDataPlacemark::HighwayMotorway; i++) {
2200             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "inline");
2201         }
2202         for (int i = GeoDataPlacemark::RailwayRail; i <= GeoDataPlacemark::RailwayFunicular; i++) {
2203             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "outline");
2204         }
2205         for (int i = GeoDataPlacemark::RailwayRail; i <= GeoDataPlacemark::RailwayFunicular; i++) {
2206             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "inline");
2207         }
2208         // Highway labels shall appear on top of railways, hence here and not already above
2209         for (int i = GeoDataPlacemark::HighwaySteps; i <= GeoDataPlacemark::HighwayMotorway; i++) {
2210             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "label");
2211         }
2212         for (int i = GeoDataPlacemark::RailwayRail; i <= GeoDataPlacemark::RailwayFunicular; i++) {
2213             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "label");
2214         }
2215 
2216         paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::TransportPlatform);
2217         paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::TransportPlatform, "outline");
2218         paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::TransportPlatform, "inline");
2219         paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::TransportPlatform, "label");
2220 
2221         for (int i = GeoDataPlacemark::PisteDownhill; i <= GeoDataPlacemark::PisteSkiJump; ++i) {
2222             paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::GeoDataVisualCategory(i));
2223             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "outline");
2224             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "inline");
2225             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "label");
2226         }
2227         for (int i = GeoDataPlacemark::AerialwayCableCar; i <= GeoDataPlacemark::AerialwayGoods; ++i) {
2228             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "outline");
2229             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "inline");
2230             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "label");
2231         }
2232 
2233         for (int i = GeoDataPlacemark::AdminLevel1; i <= GeoDataPlacemark::AdminLevel11; i++) {
2234             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "outline");
2235         }
2236         for (int i = GeoDataPlacemark::AdminLevel1; i <= GeoDataPlacemark::AdminLevel11; i++) {
2237             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "inline");
2238         }
2239         for (int i = GeoDataPlacemark::AdminLevel1; i <= GeoDataPlacemark::AdminLevel11; i++) {
2240             paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "label");
2241         }
2242 
2243         paintLayerOrder << QStringLiteral("Polygon/Building/frame");
2244         paintLayerOrder << QStringLiteral("Polygon/Building/roof");
2245 
2246         paintLayerOrder << QStringLiteral("Photo");
2247 
2248         // This assert checks that all the values in paintLayerOrder are unique.
2249         Q_ASSERT(QSet<QString>(paintLayerOrder.constBegin(), paintLayerOrder.constEnd()).size() == paintLayerOrder.size());
2250     }
2251 
2252     return paintLayerOrder;
2253 }
2254 
2255 void StyleBuilder::reset()
2256 {
2257     d->m_defaultStyleInitialized = false;
2258 }
2259 
2260 int StyleBuilder::minimumZoomLevel(const GeoDataPlacemark &placemark) const
2261 {
2262     Q_ASSERT(Private::s_defaultMinZoomLevelsInitialized);
2263     return Private::s_defaultMinZoomLevels[placemark.visualCategory()];
2264 }
2265 
2266 int StyleBuilder::minimumZoomLevel(const GeoDataPlacemark::GeoDataVisualCategory &visualCategory)
2267 {
2268     Private::initializeMinimumZoomLevels();
2269     return Private::s_defaultMinZoomLevels[visualCategory];
2270 }
2271 
2272 qint64 StyleBuilder::popularity(const GeoDataPlacemark *placemark)
2273 {
2274     qint64 const defaultValue = 100;
2275     int const offset = 10;
2276     if (StyleBuilder::Private::s_popularities.isEmpty()) {
2277         QVector<GeoDataPlacemark::GeoDataVisualCategory> popularities;
2278         popularities << GeoDataPlacemark::PlaceCityNationalCapital;
2279         popularities << GeoDataPlacemark::PlaceTownNationalCapital;
2280         popularities << GeoDataPlacemark::PlaceCityCapital;
2281         popularities << GeoDataPlacemark::PlaceTownCapital;
2282         popularities << GeoDataPlacemark::PlaceCity;
2283         popularities << GeoDataPlacemark::PlaceTown;
2284         popularities << GeoDataPlacemark::PlaceSuburb;
2285         popularities << GeoDataPlacemark::PlaceVillageNationalCapital;
2286         popularities << GeoDataPlacemark::PlaceVillageCapital;
2287         popularities << GeoDataPlacemark::PlaceVillage;
2288         popularities << GeoDataPlacemark::PlaceHamlet;
2289         popularities << GeoDataPlacemark::PlaceLocality;
2290 
2291         popularities << GeoDataPlacemark::AmenityEmergencyPhone;
2292         popularities << GeoDataPlacemark::AmenityMountainRescue;
2293         popularities << GeoDataPlacemark::HealthHospital;
2294         popularities << GeoDataPlacemark::AmenityToilets;
2295         popularities << GeoDataPlacemark::MoneyAtm;
2296         popularities << GeoDataPlacemark::TransportSpeedCamera;
2297 
2298         popularities << GeoDataPlacemark::NaturalPeak;
2299         popularities << GeoDataPlacemark::NaturalVolcano;
2300 
2301         popularities << GeoDataPlacemark::AccomodationHotel;
2302         popularities << GeoDataPlacemark::AccomodationMotel;
2303         popularities << GeoDataPlacemark::AccomodationGuestHouse;
2304         popularities << GeoDataPlacemark::AccomodationYouthHostel;
2305         popularities << GeoDataPlacemark::AccomodationHostel;
2306         popularities << GeoDataPlacemark::AccomodationCamping;
2307 
2308         popularities << GeoDataPlacemark::HealthDentist;
2309         popularities << GeoDataPlacemark::HealthDoctors;
2310         popularities << GeoDataPlacemark::HealthPharmacy;
2311         popularities << GeoDataPlacemark::HealthVeterinary;
2312 
2313         popularities << GeoDataPlacemark::AmenityLibrary;
2314         popularities << GeoDataPlacemark::EducationCollege;
2315         popularities << GeoDataPlacemark::EducationSchool;
2316         popularities << GeoDataPlacemark::EducationUniversity;
2317 
2318         popularities << GeoDataPlacemark::FoodBar;
2319         popularities << GeoDataPlacemark::FoodBiergarten;
2320         popularities << GeoDataPlacemark::FoodCafe;
2321         popularities << GeoDataPlacemark::FoodFastFood;
2322         popularities << GeoDataPlacemark::FoodPub;
2323         popularities << GeoDataPlacemark::FoodRestaurant;
2324 
2325         popularities << GeoDataPlacemark::MoneyBank;
2326 
2327         popularities << GeoDataPlacemark::HistoricArchaeologicalSite;
2328         popularities << GeoDataPlacemark::AmenityCarWash;
2329         popularities << GeoDataPlacemark::AmenityEmbassy;
2330         popularities << GeoDataPlacemark::LeisureWaterPark;
2331         popularities << GeoDataPlacemark::AmenityCommunityCentre;
2332         popularities << GeoDataPlacemark::AmenityFountain;
2333         popularities << GeoDataPlacemark::AmenityNightClub;
2334         popularities << GeoDataPlacemark::AmenityCourtHouse;
2335         popularities << GeoDataPlacemark::AmenityFireStation;
2336         popularities << GeoDataPlacemark::AmenityShelter;
2337         popularities << GeoDataPlacemark::AmenityHuntingStand;
2338         popularities << GeoDataPlacemark::AmenityPolice;
2339         popularities << GeoDataPlacemark::AmenityPostBox;
2340         popularities << GeoDataPlacemark::AmenityPostOffice;
2341         popularities << GeoDataPlacemark::AmenityPrison;
2342         popularities << GeoDataPlacemark::AmenityRecycling;
2343         popularities << GeoDataPlacemark::AmenitySocialFacility;
2344         popularities << GeoDataPlacemark::AmenityTelephone;
2345         popularities << GeoDataPlacemark::AmenityTownHall;
2346         popularities << GeoDataPlacemark::AmenityDrinkingWater;
2347         popularities << GeoDataPlacemark::AmenityGraveyard;
2348 
2349         popularities << GeoDataPlacemark::ManmadeBridge;
2350         popularities << GeoDataPlacemark::ManmadeLighthouse;
2351         popularities << GeoDataPlacemark::ManmadePier;
2352         popularities << GeoDataPlacemark::ManmadeWaterTower;
2353         popularities << GeoDataPlacemark::ManmadeWindMill;
2354         popularities << GeoDataPlacemark::ManmadeCommunicationsTower;
2355 
2356         popularities << GeoDataPlacemark::TourismAttraction;
2357         popularities << GeoDataPlacemark::TourismArtwork;
2358         popularities << GeoDataPlacemark::HistoricCastle;
2359         popularities << GeoDataPlacemark::AmenityCinema;
2360         popularities << GeoDataPlacemark::TourismInformation;
2361         popularities << GeoDataPlacemark::HistoricMonument;
2362         popularities << GeoDataPlacemark::TourismMuseum;
2363         popularities << GeoDataPlacemark::HistoricRuins;
2364         popularities << GeoDataPlacemark::AmenityTheatre;
2365         popularities << GeoDataPlacemark::TourismThemePark;
2366         popularities << GeoDataPlacemark::TourismViewPoint;
2367         popularities << GeoDataPlacemark::TourismZoo;
2368         popularities << GeoDataPlacemark::TourismAlpineHut;
2369         popularities << GeoDataPlacemark::TourismWildernessHut;
2370 
2371         popularities << GeoDataPlacemark::HistoricMemorial;
2372 
2373         popularities << GeoDataPlacemark::TransportAerodrome;
2374         popularities << GeoDataPlacemark::TransportHelipad;
2375         popularities << GeoDataPlacemark::TransportAirportTerminal;
2376         popularities << GeoDataPlacemark::TransportBusStation;
2377         popularities << GeoDataPlacemark::TransportBusStop;
2378         popularities << GeoDataPlacemark::TransportCarShare;
2379         popularities << GeoDataPlacemark::TransportFuel;
2380         popularities << GeoDataPlacemark::TransportParking;
2381         popularities << GeoDataPlacemark::TransportParkingSpace;
2382         popularities << GeoDataPlacemark::TransportPlatform;
2383         popularities << GeoDataPlacemark::TransportRentalBicycle;
2384         popularities << GeoDataPlacemark::TransportRentalCar;
2385         popularities << GeoDataPlacemark::TransportRentalSki;
2386         popularities << GeoDataPlacemark::TransportTaxiRank;
2387         popularities << GeoDataPlacemark::TransportTrainStation;
2388         popularities << GeoDataPlacemark::TransportTramStop;
2389         popularities << GeoDataPlacemark::TransportBicycleParking;
2390         popularities << GeoDataPlacemark::TransportMotorcycleParking;
2391         popularities << GeoDataPlacemark::TransportSubwayEntrance;
2392         popularities << GeoDataPlacemark::AerialwayStation;
2393 
2394         popularities << GeoDataPlacemark::ShopBeverages;
2395         popularities << GeoDataPlacemark::ShopHifi;
2396         popularities << GeoDataPlacemark::ShopSupermarket;
2397         popularities << GeoDataPlacemark::ShopAlcohol;
2398         popularities << GeoDataPlacemark::ShopBakery;
2399         popularities << GeoDataPlacemark::ShopButcher;
2400         popularities << GeoDataPlacemark::ShopConfectionery;
2401         popularities << GeoDataPlacemark::ShopConvenience;
2402         popularities << GeoDataPlacemark::ShopGreengrocer;
2403         popularities << GeoDataPlacemark::ShopSeafood;
2404         popularities << GeoDataPlacemark::ShopDepartmentStore;
2405         popularities << GeoDataPlacemark::ShopKiosk;
2406         popularities << GeoDataPlacemark::ShopBag;
2407         popularities << GeoDataPlacemark::ShopClothes;
2408         popularities << GeoDataPlacemark::ShopFashion;
2409         popularities << GeoDataPlacemark::ShopJewelry;
2410         popularities << GeoDataPlacemark::ShopShoes;
2411         popularities << GeoDataPlacemark::ShopVarietyStore;
2412         popularities << GeoDataPlacemark::ShopBeauty;
2413         popularities << GeoDataPlacemark::ShopChemist;
2414         popularities << GeoDataPlacemark::ShopCosmetics;
2415         popularities << GeoDataPlacemark::ShopHairdresser;
2416         popularities << GeoDataPlacemark::ShopOptician;
2417         popularities << GeoDataPlacemark::ShopPerfumery;
2418         popularities << GeoDataPlacemark::ShopDoitYourself;
2419         popularities << GeoDataPlacemark::ShopFlorist;
2420         popularities << GeoDataPlacemark::ShopHardware;
2421         popularities << GeoDataPlacemark::ShopFurniture;
2422         popularities << GeoDataPlacemark::ShopElectronics;
2423         popularities << GeoDataPlacemark::ShopMobilePhone;
2424         popularities << GeoDataPlacemark::ShopBicycle;
2425         popularities << GeoDataPlacemark::ShopCar;
2426         popularities << GeoDataPlacemark::ShopCarRepair;
2427         popularities << GeoDataPlacemark::ShopCarParts;
2428         popularities << GeoDataPlacemark::ShopMotorcycle;
2429         popularities << GeoDataPlacemark::ShopOutdoor;
2430         popularities << GeoDataPlacemark::ShopSports;
2431         popularities << GeoDataPlacemark::ShopCopy;
2432         popularities << GeoDataPlacemark::ShopArt;
2433         popularities << GeoDataPlacemark::ShopMusicalInstrument;
2434         popularities << GeoDataPlacemark::ShopPhoto;
2435         popularities << GeoDataPlacemark::ShopBook;
2436         popularities << GeoDataPlacemark::ShopGift;
2437         popularities << GeoDataPlacemark::ShopStationery;
2438         popularities << GeoDataPlacemark::ShopLaundry;
2439         popularities << GeoDataPlacemark::ShopPet;
2440         popularities << GeoDataPlacemark::ShopToys;
2441         popularities << GeoDataPlacemark::ShopTravelAgency;
2442         popularities << GeoDataPlacemark::ShopDeli;
2443         popularities << GeoDataPlacemark::ShopTobacco;
2444         popularities << GeoDataPlacemark::ShopTea;
2445         popularities << GeoDataPlacemark::ShopComputer;
2446         popularities << GeoDataPlacemark::ShopGardenCentre;
2447         popularities << GeoDataPlacemark::Shop;
2448 
2449         popularities << GeoDataPlacemark::LeisureGolfCourse;
2450         popularities << GeoDataPlacemark::LeisureMinigolfCourse;
2451         popularities << GeoDataPlacemark::LeisurePark;
2452         popularities << GeoDataPlacemark::LeisurePlayground;
2453         popularities << GeoDataPlacemark::LeisurePitch;
2454         popularities << GeoDataPlacemark::LeisureSportsCentre;
2455         popularities << GeoDataPlacemark::LeisureStadium;
2456         popularities << GeoDataPlacemark::LeisureTrack;
2457         popularities << GeoDataPlacemark::LeisureSwimmingPool;
2458 
2459         popularities << GeoDataPlacemark::CrossingIsland;
2460         popularities << GeoDataPlacemark::CrossingRailway;
2461         popularities << GeoDataPlacemark::CrossingSignals;
2462         popularities << GeoDataPlacemark::CrossingZebra;
2463         popularities << GeoDataPlacemark::HighwayTrafficSignals;
2464         popularities << GeoDataPlacemark::HighwayElevator;
2465 
2466         popularities << GeoDataPlacemark::BarrierGate;
2467         popularities << GeoDataPlacemark::BarrierLiftGate;
2468         popularities << GeoDataPlacemark::AmenityBench;
2469         popularities << GeoDataPlacemark::NaturalTree;
2470         popularities << GeoDataPlacemark::NaturalCave;
2471         popularities << GeoDataPlacemark::AmenityWasteBasket;
2472         popularities << GeoDataPlacemark::AerialwayPylon;
2473         popularities << GeoDataPlacemark::PowerTower;
2474 
2475         int value = defaultValue + offset * popularities.size();
2476         for (auto popularity : popularities) {
2477             StyleBuilder::Private::s_popularities[popularity] = value;
2478             value -= offset;
2479         }
2480     }
2481 
2482     bool const isPrivate = placemark->osmData().containsTag(QStringLiteral("access"), QStringLiteral("private"));
2483     int const base = defaultValue + (isPrivate ? 0 : offset * StyleBuilder::Private::s_popularities.size());
2484     return base + StyleBuilder::Private::s_popularities.value(placemark->visualCategory(), defaultValue);
2485 }
2486 
2487 int StyleBuilder::maximumZoomLevel() const
2488 {
2489     return d->m_maximumZoomLevel;
2490 }
2491 
2492 QString StyleBuilder::visualCategoryName(GeoDataPlacemark::GeoDataVisualCategory category)
2493 {
2494     static QHash<GeoDataPlacemark::GeoDataVisualCategory, QString> visualCategoryNames;
2495 
2496     if (visualCategoryNames.isEmpty()) {
2497         visualCategoryNames[GeoDataPlacemark::None] = "None";
2498         visualCategoryNames[GeoDataPlacemark::Default] = "Default";
2499         visualCategoryNames[GeoDataPlacemark::Unknown] = "Unknown";
2500         visualCategoryNames[GeoDataPlacemark::SmallCity] = "SmallCity";
2501         visualCategoryNames[GeoDataPlacemark::SmallCountyCapital] = "SmallCountyCapital";
2502         visualCategoryNames[GeoDataPlacemark::SmallStateCapital] = "SmallStateCapital";
2503         visualCategoryNames[GeoDataPlacemark::SmallNationCapital] = "SmallNationCapital";
2504         visualCategoryNames[GeoDataPlacemark::MediumCity] = "MediumCity";
2505         visualCategoryNames[GeoDataPlacemark::MediumCountyCapital] = "MediumCountyCapital";
2506         visualCategoryNames[GeoDataPlacemark::MediumStateCapital] = "MediumStateCapital";
2507         visualCategoryNames[GeoDataPlacemark::MediumNationCapital] = "MediumNationCapital";
2508         visualCategoryNames[GeoDataPlacemark::BigCity] = "BigCity";
2509         visualCategoryNames[GeoDataPlacemark::BigCountyCapital] = "BigCountyCapital";
2510         visualCategoryNames[GeoDataPlacemark::BigStateCapital] = "BigStateCapital";
2511         visualCategoryNames[GeoDataPlacemark::BigNationCapital] = "BigNationCapital";
2512         visualCategoryNames[GeoDataPlacemark::LargeCity] = "LargeCity";
2513         visualCategoryNames[GeoDataPlacemark::LargeCountyCapital] = "LargeCountyCapital";
2514         visualCategoryNames[GeoDataPlacemark::LargeStateCapital] = "LargeStateCapital";
2515         visualCategoryNames[GeoDataPlacemark::LargeNationCapital] = "LargeNationCapital";
2516         visualCategoryNames[GeoDataPlacemark::Nation] = "Nation";
2517         visualCategoryNames[GeoDataPlacemark::PlaceCity] = "PlaceCity";
2518         visualCategoryNames[GeoDataPlacemark::PlaceCityCapital] = "PlaceCityCapital";
2519         visualCategoryNames[GeoDataPlacemark::PlaceCityNationalCapital] = "PlaceCityNationalCapital";
2520         visualCategoryNames[GeoDataPlacemark::PlaceSuburb] = "PlaceSuburb";
2521         visualCategoryNames[GeoDataPlacemark::PlaceHamlet] = "PlaceHamlet";
2522         visualCategoryNames[GeoDataPlacemark::PlaceLocality] = "PlaceLocality";
2523         visualCategoryNames[GeoDataPlacemark::PlaceTown] = "PlaceTown";
2524         visualCategoryNames[GeoDataPlacemark::PlaceTownCapital] = "PlaceTownCapital";
2525         visualCategoryNames[GeoDataPlacemark::PlaceTownNationalCapital] = "PlaceTownNationalCapital";
2526         visualCategoryNames[GeoDataPlacemark::PlaceVillage] = "PlaceVillage";
2527         visualCategoryNames[GeoDataPlacemark::PlaceVillageCapital] = "PlaceVillageCapital";
2528         visualCategoryNames[GeoDataPlacemark::PlaceVillageNationalCapital] = "PlaceVillageNationalCapital";
2529         visualCategoryNames[GeoDataPlacemark::Mountain] = "Mountain";
2530         visualCategoryNames[GeoDataPlacemark::Volcano] = "Volcano";
2531         visualCategoryNames[GeoDataPlacemark::Mons] = "Mons";
2532         visualCategoryNames[GeoDataPlacemark::Valley] = "Valley";
2533         visualCategoryNames[GeoDataPlacemark::Continent] = "Continent";
2534         visualCategoryNames[GeoDataPlacemark::Ocean] = "Ocean";
2535         visualCategoryNames[GeoDataPlacemark::OtherTerrain] = "OtherTerrain";
2536         visualCategoryNames[GeoDataPlacemark::Crater] = "Crater";
2537         visualCategoryNames[GeoDataPlacemark::Mare] = "Mare";
2538         visualCategoryNames[GeoDataPlacemark::GeographicPole] = "GeographicPole";
2539         visualCategoryNames[GeoDataPlacemark::MagneticPole] = "MagneticPole";
2540         visualCategoryNames[GeoDataPlacemark::ShipWreck] = "ShipWreck";
2541         visualCategoryNames[GeoDataPlacemark::AirPort] = "AirPort";
2542         visualCategoryNames[GeoDataPlacemark::Observatory] = "Observatory";
2543         visualCategoryNames[GeoDataPlacemark::MilitaryDangerArea] = "MilitaryDangerArea";
2544         visualCategoryNames[GeoDataPlacemark::OsmSite] = "OsmSite";
2545         visualCategoryNames[GeoDataPlacemark::Coordinate] = "Coordinate";
2546         visualCategoryNames[GeoDataPlacemark::MannedLandingSite] = "MannedLandingSite";
2547         visualCategoryNames[GeoDataPlacemark::RoboticRover] = "RoboticRover";
2548         visualCategoryNames[GeoDataPlacemark::UnmannedSoftLandingSite] = "UnmannedSoftLandingSite";
2549         visualCategoryNames[GeoDataPlacemark::UnmannedHardLandingSite] = "UnmannedHardLandingSite";
2550         visualCategoryNames[GeoDataPlacemark::Bookmark] = "Bookmark";
2551         visualCategoryNames[GeoDataPlacemark::NaturalWater] = "NaturalWater";
2552         visualCategoryNames[GeoDataPlacemark::NaturalReef] = "NaturalReef";
2553         visualCategoryNames[GeoDataPlacemark::NaturalWood] = "NaturalWood";
2554         visualCategoryNames[GeoDataPlacemark::NaturalBeach] = "NaturalBeach";
2555         visualCategoryNames[GeoDataPlacemark::NaturalWetland] = "NaturalWetland";
2556         visualCategoryNames[GeoDataPlacemark::NaturalGlacier] = "NaturalGlacier";
2557         visualCategoryNames[GeoDataPlacemark::NaturalIceShelf] = "NaturalIceShelf";
2558         visualCategoryNames[GeoDataPlacemark::NaturalScrub] = "NaturalScrub";
2559         visualCategoryNames[GeoDataPlacemark::NaturalCliff] = "NaturalCliff";
2560         visualCategoryNames[GeoDataPlacemark::NaturalHeath] = "NaturalHeath";
2561         visualCategoryNames[GeoDataPlacemark::HighwayTrafficSignals] = "HighwayTrafficSignals";
2562         visualCategoryNames[GeoDataPlacemark::HighwaySteps] = "HighwaySteps";
2563         visualCategoryNames[GeoDataPlacemark::HighwayUnknown] = "HighwayUnknown";
2564         visualCategoryNames[GeoDataPlacemark::HighwayPath] = "HighwayPath";
2565         visualCategoryNames[GeoDataPlacemark::HighwayFootway] = "HighwayFootway";
2566         visualCategoryNames[GeoDataPlacemark::HighwayTrack] = "HighwayTrack";
2567         visualCategoryNames[GeoDataPlacemark::HighwayPedestrian] = "HighwayPedestrian";
2568         visualCategoryNames[GeoDataPlacemark::HighwayCycleway] = "HighwayCycleway";
2569         visualCategoryNames[GeoDataPlacemark::HighwayService] = "HighwayService";
2570         visualCategoryNames[GeoDataPlacemark::HighwayRoad] = "HighwayRoad";
2571         visualCategoryNames[GeoDataPlacemark::HighwayResidential] = "HighwayResidential";
2572         visualCategoryNames[GeoDataPlacemark::HighwayLivingStreet] = "HighwayLivingStreet";
2573         visualCategoryNames[GeoDataPlacemark::HighwayUnclassified] = "HighwayUnclassified";
2574         visualCategoryNames[GeoDataPlacemark::HighwayTertiaryLink] = "HighwayTertiaryLink";
2575         visualCategoryNames[GeoDataPlacemark::HighwayTertiary] = "HighwayTertiary";
2576         visualCategoryNames[GeoDataPlacemark::HighwaySecondaryLink] = "HighwaySecondaryLink";
2577         visualCategoryNames[GeoDataPlacemark::HighwaySecondary] = "HighwaySecondary";
2578         visualCategoryNames[GeoDataPlacemark::HighwayPrimaryLink] = "HighwayPrimaryLink";
2579         visualCategoryNames[GeoDataPlacemark::HighwayPrimary] = "HighwayPrimary";
2580         visualCategoryNames[GeoDataPlacemark::HighwayRaceway] = "HighwayRaceway";
2581         visualCategoryNames[GeoDataPlacemark::HighwayTrunkLink] = "HighwayTrunkLink";
2582         visualCategoryNames[GeoDataPlacemark::HighwayTrunk] = "HighwayTrunk";
2583         visualCategoryNames[GeoDataPlacemark::HighwayMotorwayLink] = "HighwayMotorwayLink";
2584         visualCategoryNames[GeoDataPlacemark::HighwayMotorway] = "HighwayMotorway";
2585         visualCategoryNames[GeoDataPlacemark::HighwayCorridor] = "HighwayCorridor";
2586         visualCategoryNames[GeoDataPlacemark::HighwayElevator] = "HighwayElevator";
2587         visualCategoryNames[GeoDataPlacemark::Building] = "Building";
2588         visualCategoryNames[GeoDataPlacemark::AccomodationCamping] = "AccomodationCamping";
2589         visualCategoryNames[GeoDataPlacemark::AccomodationHostel] = "AccomodationHostel";
2590         visualCategoryNames[GeoDataPlacemark::AccomodationHotel] = "AccomodationHotel";
2591         visualCategoryNames[GeoDataPlacemark::AccomodationMotel] = "AccomodationMotel";
2592         visualCategoryNames[GeoDataPlacemark::AccomodationYouthHostel] = "AccomodationYouthHostel";
2593         visualCategoryNames[GeoDataPlacemark::AccomodationGuestHouse] = "AccomodationGuestHouse";
2594         visualCategoryNames[GeoDataPlacemark::AmenityLibrary] = "AmenityLibrary";
2595         visualCategoryNames[GeoDataPlacemark::AmenityKindergarten] = "AmenityKindergarten";
2596         visualCategoryNames[GeoDataPlacemark::EducationCollege] = "EducationCollege";
2597         visualCategoryNames[GeoDataPlacemark::EducationSchool] = "EducationSchool";
2598         visualCategoryNames[GeoDataPlacemark::EducationUniversity] = "EducationUniversity";
2599         visualCategoryNames[GeoDataPlacemark::FoodBar] = "FoodBar";
2600         visualCategoryNames[GeoDataPlacemark::FoodBiergarten] = "FoodBiergarten";
2601         visualCategoryNames[GeoDataPlacemark::FoodCafe] = "FoodCafe";
2602         visualCategoryNames[GeoDataPlacemark::FoodFastFood] = "FoodFastFood";
2603         visualCategoryNames[GeoDataPlacemark::FoodPub] = "FoodPub";
2604         visualCategoryNames[GeoDataPlacemark::FoodRestaurant] = "FoodRestaurant";
2605         visualCategoryNames[GeoDataPlacemark::HealthDentist] = "HealthDentist";
2606         visualCategoryNames[GeoDataPlacemark::HealthDoctors] = "HealthDoctors";
2607         visualCategoryNames[GeoDataPlacemark::HealthHospital] = "HealthHospital";
2608         visualCategoryNames[GeoDataPlacemark::HealthPharmacy] = "HealthPharmacy";
2609         visualCategoryNames[GeoDataPlacemark::HealthVeterinary] = "HealthVeterinary";
2610         visualCategoryNames[GeoDataPlacemark::MoneyAtm] = "MoneyAtm";
2611         visualCategoryNames[GeoDataPlacemark::MoneyBank] = "MoneyBank";
2612         visualCategoryNames[GeoDataPlacemark::AmenityEmbassy] = "AmenityEmbassy";
2613         visualCategoryNames[GeoDataPlacemark::AmenityEmergencyPhone] = "AmenityEmergencyPhone";
2614         visualCategoryNames[GeoDataPlacemark::AmenityMountainRescue] = "AmenityMountainRescue";
2615         visualCategoryNames[GeoDataPlacemark::LeisureWaterPark] = "LeisureWaterPark";
2616         visualCategoryNames[GeoDataPlacemark::AmenityCommunityCentre] = "AmenityCommunityCentre";
2617         visualCategoryNames[GeoDataPlacemark::AmenityFountain] = "AmenityFountain";
2618         visualCategoryNames[GeoDataPlacemark::AmenityNightClub] = "AmenityNightClub";
2619         visualCategoryNames[GeoDataPlacemark::AmenityBench] = "AmenityBench";
2620         visualCategoryNames[GeoDataPlacemark::AmenityCourtHouse] = "AmenityCourtHouse";
2621         visualCategoryNames[GeoDataPlacemark::AmenityFireStation] = "AmenityFireStation";
2622         visualCategoryNames[GeoDataPlacemark::AmenityHuntingStand] = "AmenityHuntingStand";
2623         visualCategoryNames[GeoDataPlacemark::AmenityPolice] = "AmenityPolice";
2624         visualCategoryNames[GeoDataPlacemark::AmenityPostBox] = "AmenityPostBox";
2625         visualCategoryNames[GeoDataPlacemark::AmenityPostOffice] = "AmenityPostOffice";
2626         visualCategoryNames[GeoDataPlacemark::AmenityPrison] = "AmenityPrison";
2627         visualCategoryNames[GeoDataPlacemark::AmenityRecycling] = "AmenityRecycling";
2628         visualCategoryNames[GeoDataPlacemark::AmenityShelter] = "AmenityShelter";
2629         visualCategoryNames[GeoDataPlacemark::AmenityTelephone] = "AmenityTelephone";
2630         visualCategoryNames[GeoDataPlacemark::AmenityToilets] = "AmenityToilets";
2631         visualCategoryNames[GeoDataPlacemark::AmenityTownHall] = "AmenityTownHall";
2632         visualCategoryNames[GeoDataPlacemark::AmenityWasteBasket] = "AmenityWasteBasket";
2633         visualCategoryNames[GeoDataPlacemark::AmenityDrinkingWater] = "AmenityDrinkingWater";
2634         visualCategoryNames[GeoDataPlacemark::AmenityGraveyard] = "AmenityGraveyard";
2635         visualCategoryNames[GeoDataPlacemark::AmenityChargingStation] = "ChargingStation";
2636         visualCategoryNames[GeoDataPlacemark::AmenityCarWash] = "CarWash";
2637         visualCategoryNames[GeoDataPlacemark::AmenitySocialFacility] = "SocialFacility";
2638         visualCategoryNames[GeoDataPlacemark::BarrierCityWall] = "BarrierCityWall";
2639         visualCategoryNames[GeoDataPlacemark::BarrierGate] = "BarrierGate";
2640         visualCategoryNames[GeoDataPlacemark::BarrierLiftGate] = "BarrierLiftGate";
2641         visualCategoryNames[GeoDataPlacemark::BarrierWall] = "BarrierWall";
2642         visualCategoryNames[GeoDataPlacemark::NaturalVolcano] = "NaturalVolcano";
2643         visualCategoryNames[GeoDataPlacemark::NaturalPeak] = "NaturalPeak";
2644         visualCategoryNames[GeoDataPlacemark::NaturalTree] = "NaturalTree";
2645         visualCategoryNames[GeoDataPlacemark::NaturalCave] = "NaturalCave";
2646         visualCategoryNames[GeoDataPlacemark::ShopBeverages] = "ShopBeverages";
2647         visualCategoryNames[GeoDataPlacemark::ShopHifi] = "ShopHifi";
2648         visualCategoryNames[GeoDataPlacemark::ShopSupermarket] = "ShopSupermarket";
2649         visualCategoryNames[GeoDataPlacemark::ShopAlcohol] = "ShopAlcohol";
2650         visualCategoryNames[GeoDataPlacemark::ShopBakery] = "ShopBakery";
2651         visualCategoryNames[GeoDataPlacemark::ShopButcher] = "ShopButcher";
2652         visualCategoryNames[GeoDataPlacemark::ShopConfectionery] = "ShopConfectionery";
2653         visualCategoryNames[GeoDataPlacemark::ShopConvenience] = "ShopConvenience";
2654         visualCategoryNames[GeoDataPlacemark::ShopGreengrocer] = "ShopGreengrocer";
2655         visualCategoryNames[GeoDataPlacemark::ShopSeafood] = "ShopSeafood";
2656         visualCategoryNames[GeoDataPlacemark::ShopDepartmentStore] = "ShopDepartmentStore";
2657         visualCategoryNames[GeoDataPlacemark::ShopKiosk] = "ShopKiosk";
2658         visualCategoryNames[GeoDataPlacemark::ShopBag] = "ShopBag";
2659         visualCategoryNames[GeoDataPlacemark::ShopClothes] = "ShopClothes";
2660         visualCategoryNames[GeoDataPlacemark::ShopFashion] = "ShopFashion";
2661         visualCategoryNames[GeoDataPlacemark::ShopJewelry] = "ShopJewelry";
2662         visualCategoryNames[GeoDataPlacemark::ShopShoes] = "ShopShoes";
2663         visualCategoryNames[GeoDataPlacemark::ShopVarietyStore] = "ShopVarietyStore";
2664         visualCategoryNames[GeoDataPlacemark::ShopBeauty] = "ShopBeauty";
2665         visualCategoryNames[GeoDataPlacemark::ShopChemist] = "ShopChemist";
2666         visualCategoryNames[GeoDataPlacemark::ShopCosmetics] = "ShopCosmetics";
2667         visualCategoryNames[GeoDataPlacemark::ShopHairdresser] = "ShopHairdresser";
2668         visualCategoryNames[GeoDataPlacemark::ShopOptician] = "ShopOptician";
2669         visualCategoryNames[GeoDataPlacemark::ShopPerfumery] = "ShopPerfumery";
2670         visualCategoryNames[GeoDataPlacemark::ShopDoitYourself] = "ShopDoitYourself";
2671         visualCategoryNames[GeoDataPlacemark::ShopFlorist] = "ShopFlorist";
2672         visualCategoryNames[GeoDataPlacemark::ShopHardware] = "ShopHardware";
2673         visualCategoryNames[GeoDataPlacemark::ShopFurniture] = "ShopFurniture";
2674         visualCategoryNames[GeoDataPlacemark::ShopElectronics] = "ShopElectronics";
2675         visualCategoryNames[GeoDataPlacemark::ShopMobilePhone] = "ShopMobilePhone";
2676         visualCategoryNames[GeoDataPlacemark::ShopBicycle] = "ShopBicycle";
2677         visualCategoryNames[GeoDataPlacemark::ShopCar] = "ShopCar";
2678         visualCategoryNames[GeoDataPlacemark::ShopCarRepair] = "ShopCarRepair";
2679         visualCategoryNames[GeoDataPlacemark::ShopCarParts] = "ShopCarParts";
2680         visualCategoryNames[GeoDataPlacemark::ShopMotorcycle] = "ShopMotorcycle";
2681         visualCategoryNames[GeoDataPlacemark::ShopOutdoor] = "ShopOutdoor";
2682         visualCategoryNames[GeoDataPlacemark::ShopSports] = "ShopSports";
2683         visualCategoryNames[GeoDataPlacemark::ShopCopy] = "ShopCopy";
2684         visualCategoryNames[GeoDataPlacemark::ShopArt] = "ShopArt";
2685         visualCategoryNames[GeoDataPlacemark::ShopMusicalInstrument] = "ShopMusicalInstrument";
2686         visualCategoryNames[GeoDataPlacemark::ShopPhoto] = "ShopPhoto";
2687         visualCategoryNames[GeoDataPlacemark::ShopBook] = "ShopBook";
2688         visualCategoryNames[GeoDataPlacemark::ShopGift] = "ShopGift";
2689         visualCategoryNames[GeoDataPlacemark::ShopStationery] = "ShopStationery";
2690         visualCategoryNames[GeoDataPlacemark::ShopLaundry] = "ShopLaundry";
2691         visualCategoryNames[GeoDataPlacemark::ShopPet] = "ShopPet";
2692         visualCategoryNames[GeoDataPlacemark::ShopToys] = "ShopToys";
2693         visualCategoryNames[GeoDataPlacemark::ShopTravelAgency] = "ShopTravelAgency";
2694         visualCategoryNames[GeoDataPlacemark::ShopDeli] = "ShopDeli";
2695         visualCategoryNames[GeoDataPlacemark::ShopTobacco] = "ShopTobacco";
2696         visualCategoryNames[GeoDataPlacemark::ShopTea] = "ShopTea";
2697         visualCategoryNames[GeoDataPlacemark::ShopComputer] = "ShopComputer";
2698         visualCategoryNames[GeoDataPlacemark::ShopGardenCentre] = "ShopGardenCentre";
2699         visualCategoryNames[GeoDataPlacemark::Shop] = "Shop";
2700         visualCategoryNames[GeoDataPlacemark::ManmadeBridge] = "ManmadeBridge";
2701         visualCategoryNames[GeoDataPlacemark::ManmadeLighthouse] = "ManmadeLighthouse";
2702         visualCategoryNames[GeoDataPlacemark::ManmadePier] = "ManmadePier";
2703         visualCategoryNames[GeoDataPlacemark::ManmadeWaterTower] = "ManmadeWaterTower";
2704         visualCategoryNames[GeoDataPlacemark::ManmadeWindMill] = "ManmadeWindMill";
2705         visualCategoryNames[GeoDataPlacemark::ManmadeCommunicationsTower] = "ManmadeCommunicationsTower";
2706         visualCategoryNames[GeoDataPlacemark::TourismAttraction] = "TouristAttraction";
2707         visualCategoryNames[GeoDataPlacemark::TourismArtwork] = "TouristArtwork";
2708         visualCategoryNames[GeoDataPlacemark::HistoricArchaeologicalSite] = "HistoricArchaeologicalSite";
2709         visualCategoryNames[GeoDataPlacemark::HistoricCastle] = "HistoricCastle";
2710         visualCategoryNames[GeoDataPlacemark::HistoricMemorial] = "HistoricMemorial";
2711         visualCategoryNames[GeoDataPlacemark::HistoricMonument] = "HistoricMonument";
2712         visualCategoryNames[GeoDataPlacemark::AmenityCinema] = "TouristCinema";
2713         visualCategoryNames[GeoDataPlacemark::TourismInformation] = "TouristInformation";
2714         visualCategoryNames[GeoDataPlacemark::TourismMuseum] = "TouristMuseum";
2715         visualCategoryNames[GeoDataPlacemark::HistoricRuins] = "TouristRuin";
2716         visualCategoryNames[GeoDataPlacemark::AmenityTheatre] = "TouristTheatre";
2717         visualCategoryNames[GeoDataPlacemark::TourismThemePark] = "TouristThemePark";
2718         visualCategoryNames[GeoDataPlacemark::TourismViewPoint] = "TouristViewPoint";
2719         visualCategoryNames[GeoDataPlacemark::TourismZoo] = "TouristZoo";
2720         visualCategoryNames[GeoDataPlacemark::TourismAlpineHut] = "TouristAlpineHut";
2721         visualCategoryNames[GeoDataPlacemark::TourismWildernessHut] = "TouristWildernessHut";
2722         visualCategoryNames[GeoDataPlacemark::TransportAerodrome] = "TransportAerodrome";
2723         visualCategoryNames[GeoDataPlacemark::TransportHelipad] = "TransportHelipad";
2724         visualCategoryNames[GeoDataPlacemark::TransportAirportTerminal] = "TransportAirportTerminal";
2725         visualCategoryNames[GeoDataPlacemark::TransportAirportGate] = "TransportAirportGate";
2726         visualCategoryNames[GeoDataPlacemark::TransportAirportRunway] = "TransportAirportRunway";
2727         visualCategoryNames[GeoDataPlacemark::TransportAirportTaxiway] = "TransportAirportTaxiway";
2728         visualCategoryNames[GeoDataPlacemark::TransportAirportApron] = "TransportAirportApron";
2729         visualCategoryNames[GeoDataPlacemark::TransportBusStation] = "TransportBusStation";
2730         visualCategoryNames[GeoDataPlacemark::TransportBusStop] = "TransportBusStop";
2731         visualCategoryNames[GeoDataPlacemark::TransportCarShare] = "TransportCarShare";
2732         visualCategoryNames[GeoDataPlacemark::TransportFuel] = "TransportFuel";
2733         visualCategoryNames[GeoDataPlacemark::TransportParking] = "TransportParking";
2734         visualCategoryNames[GeoDataPlacemark::TransportParkingSpace] = "TransportParkingSpace";
2735         visualCategoryNames[GeoDataPlacemark::TransportPlatform] = "TransportPlatform";
2736         visualCategoryNames[GeoDataPlacemark::TransportRentalBicycle] = "TransportRentalBicycle";
2737         visualCategoryNames[GeoDataPlacemark::TransportRentalCar] = "TransportRentalCar";
2738         visualCategoryNames[GeoDataPlacemark::TransportRentalSki] = "TransportRentalSki";
2739         visualCategoryNames[GeoDataPlacemark::TransportTaxiRank] = "TransportTaxiRank";
2740         visualCategoryNames[GeoDataPlacemark::TransportTrainStation] = "TransportTrainStation";
2741         visualCategoryNames[GeoDataPlacemark::TransportTramStop] = "TransportTramStop";
2742         visualCategoryNames[GeoDataPlacemark::TransportSpeedCamera] = "TransportSpeedCamera";
2743         visualCategoryNames[GeoDataPlacemark::TransportBicycleParking] = "TransportBicycleParking";
2744         visualCategoryNames[GeoDataPlacemark::TransportMotorcycleParking] = "TransportMotorcycleParking";
2745         visualCategoryNames[GeoDataPlacemark::TransportSubwayEntrance] = "TransportSubwayEntrance";
2746         visualCategoryNames[GeoDataPlacemark::ReligionPlaceOfWorship] = "ReligionPlaceOfWorship";
2747         visualCategoryNames[GeoDataPlacemark::ReligionBahai] = "ReligionBahai";
2748         visualCategoryNames[GeoDataPlacemark::ReligionBuddhist] = "ReligionBuddhist";
2749         visualCategoryNames[GeoDataPlacemark::ReligionChristian] = "ReligionChristian";
2750         visualCategoryNames[GeoDataPlacemark::ReligionMuslim] = "ReligionMuslim";
2751         visualCategoryNames[GeoDataPlacemark::ReligionHindu] = "ReligionHindu";
2752         visualCategoryNames[GeoDataPlacemark::ReligionJain] = "ReligionJain";
2753         visualCategoryNames[GeoDataPlacemark::ReligionJewish] = "ReligionJewish";
2754         visualCategoryNames[GeoDataPlacemark::ReligionShinto] = "ReligionShinto";
2755         visualCategoryNames[GeoDataPlacemark::ReligionSikh] = "ReligionSikh";
2756         visualCategoryNames[GeoDataPlacemark::ReligionTaoist] = "ReligionTaoist";
2757         visualCategoryNames[GeoDataPlacemark::LeisureGolfCourse] = "LeisureGolfCourse";
2758         visualCategoryNames[GeoDataPlacemark::LeisureMarina] = "LeisureMarina";
2759         visualCategoryNames[GeoDataPlacemark::LeisurePark] = "LeisurePark";
2760         visualCategoryNames[GeoDataPlacemark::LeisurePlayground] = "LeisurePlayground";
2761         visualCategoryNames[GeoDataPlacemark::LeisurePitch] = "LeisurePitch";
2762         visualCategoryNames[GeoDataPlacemark::LeisureSportsCentre] = "LeisureSportsCentre";
2763         visualCategoryNames[GeoDataPlacemark::LeisureStadium] = "LeisureStadium";
2764         visualCategoryNames[GeoDataPlacemark::LeisureTrack] = "LeisureTrack";
2765         visualCategoryNames[GeoDataPlacemark::LeisureSwimmingPool] = "LeisureSwimmingPool";
2766         visualCategoryNames[GeoDataPlacemark::LeisureMinigolfCourse] = "LeisureMinigolfCourse";
2767         visualCategoryNames[GeoDataPlacemark::LanduseAllotments] = "LanduseAllotments";
2768         visualCategoryNames[GeoDataPlacemark::LanduseBasin] = "LanduseBasin";
2769         visualCategoryNames[GeoDataPlacemark::LanduseCemetery] = "LanduseCemetery";
2770         visualCategoryNames[GeoDataPlacemark::LanduseCommercial] = "LanduseCommercial";
2771         visualCategoryNames[GeoDataPlacemark::LanduseConstruction] = "LanduseConstruction";
2772         visualCategoryNames[GeoDataPlacemark::LanduseFarmland] = "LanduseFarmland";
2773         visualCategoryNames[GeoDataPlacemark::LanduseFarmyard] = "LanduseFarmyard";
2774         visualCategoryNames[GeoDataPlacemark::LanduseGarages] = "LanduseGarages";
2775         visualCategoryNames[GeoDataPlacemark::LanduseGrass] = "LanduseGrass";
2776         visualCategoryNames[GeoDataPlacemark::LanduseIndustrial] = "LanduseIndustrial";
2777         visualCategoryNames[GeoDataPlacemark::LanduseLandfill] = "LanduseLandfill";
2778         visualCategoryNames[GeoDataPlacemark::LanduseMeadow] = "LanduseMeadow";
2779         visualCategoryNames[GeoDataPlacemark::LanduseMilitary] = "LanduseMilitary";
2780         visualCategoryNames[GeoDataPlacemark::LanduseQuarry] = "LanduseQuarry";
2781         visualCategoryNames[GeoDataPlacemark::LanduseRailway] = "LanduseRailway";
2782         visualCategoryNames[GeoDataPlacemark::LanduseReservoir] = "LanduseReservoir";
2783         visualCategoryNames[GeoDataPlacemark::LanduseResidential] = "LanduseResidential";
2784         visualCategoryNames[GeoDataPlacemark::LanduseRetail] = "LanduseRetail";
2785         visualCategoryNames[GeoDataPlacemark::LanduseOrchard] = "LanduseOrchard";
2786         visualCategoryNames[GeoDataPlacemark::LanduseVineyard] = "LanduseVineyard";
2787         visualCategoryNames[GeoDataPlacemark::RailwayRail] = "RailwayRail";
2788         visualCategoryNames[GeoDataPlacemark::RailwayNarrowGauge] = "RailwayNarrowGauge";
2789         visualCategoryNames[GeoDataPlacemark::RailwayTram] = "RailwayTram";
2790         visualCategoryNames[GeoDataPlacemark::RailwayLightRail] = "RailwayLightRail";
2791         visualCategoryNames[GeoDataPlacemark::RailwayAbandoned] = "RailwayAbandoned";
2792         visualCategoryNames[GeoDataPlacemark::RailwaySubway] = "RailwaySubway";
2793         visualCategoryNames[GeoDataPlacemark::RailwayPreserved] = "RailwayPreserved";
2794         visualCategoryNames[GeoDataPlacemark::RailwayMiniature] = "RailwayMiniature";
2795         visualCategoryNames[GeoDataPlacemark::RailwayConstruction] = "RailwayConstruction";
2796         visualCategoryNames[GeoDataPlacemark::RailwayMonorail] = "RailwayMonorail";
2797         visualCategoryNames[GeoDataPlacemark::RailwayFunicular] = "RailwayFunicular";
2798         visualCategoryNames[GeoDataPlacemark::PowerTower] = "PowerTower";
2799         visualCategoryNames[GeoDataPlacemark::AerialwayStation] = "AerialwayStation";
2800         visualCategoryNames[GeoDataPlacemark::AerialwayPylon] = "AerialwayPylon";
2801         visualCategoryNames[GeoDataPlacemark::AerialwayCableCar] = "AerialwayCableCar";
2802         visualCategoryNames[GeoDataPlacemark::AerialwayGondola] = "AerialwayGondola";
2803         visualCategoryNames[GeoDataPlacemark::AerialwayChairLift] = "AerialwayChairLift";
2804         visualCategoryNames[GeoDataPlacemark::AerialwayMixedLift] = "AerialwayMixedLift";
2805         visualCategoryNames[GeoDataPlacemark::AerialwayDragLift] = "AerialwayDragLift";
2806         visualCategoryNames[GeoDataPlacemark::AerialwayTBar] = "AerialwayTBar";
2807         visualCategoryNames[GeoDataPlacemark::AerialwayJBar] = "AerialwayJBar";
2808         visualCategoryNames[GeoDataPlacemark::AerialwayPlatter] = "AerialwayPlatter";
2809         visualCategoryNames[GeoDataPlacemark::AerialwayRopeTow] = "AerialwayRopeTow";
2810         visualCategoryNames[GeoDataPlacemark::AerialwayMagicCarpet] = "AerialwayMagicCarpet";
2811         visualCategoryNames[GeoDataPlacemark::AerialwayZipLine] = "AerialwayZipLine";
2812         visualCategoryNames[GeoDataPlacemark::AerialwayGoods] = "AerialwayGoods";
2813         visualCategoryNames[GeoDataPlacemark::PisteDownhill] = "PisteDownhill";
2814         visualCategoryNames[GeoDataPlacemark::PisteNordic] = "PisteNordic";
2815         visualCategoryNames[GeoDataPlacemark::PisteSkitour] = "PisteSkitour";
2816         visualCategoryNames[GeoDataPlacemark::PisteSled] = "PisteSled";
2817         visualCategoryNames[GeoDataPlacemark::PisteHike] = "PisteHike";
2818         visualCategoryNames[GeoDataPlacemark::PisteSleigh] = "PisteSleigh";
2819         visualCategoryNames[GeoDataPlacemark::PisteIceSkate] = "PisteIceSkate";
2820         visualCategoryNames[GeoDataPlacemark::PisteSnowPark] = "PisteSnowPark";
2821         visualCategoryNames[GeoDataPlacemark::PistePlayground] = "PistePlayground";
2822         visualCategoryNames[GeoDataPlacemark::PisteSkiJump] = "PisteSkiJump";
2823         visualCategoryNames[GeoDataPlacemark::Satellite] = "Satellite";
2824         visualCategoryNames[GeoDataPlacemark::Landmass] = "Landmass";
2825         visualCategoryNames[GeoDataPlacemark::UrbanArea] = "UrbanArea";
2826         visualCategoryNames[GeoDataPlacemark::InternationalDateLine] = "InternationalDateLine";
2827         visualCategoryNames[GeoDataPlacemark::Bathymetry] = "Bathymetry";
2828         visualCategoryNames[GeoDataPlacemark::AdminLevel1] = "AdminLevel1";
2829         visualCategoryNames[GeoDataPlacemark::AdminLevel2] = "AdminLevel2";
2830         visualCategoryNames[GeoDataPlacemark::AdminLevel3] = "AdminLevel3";
2831         visualCategoryNames[GeoDataPlacemark::AdminLevel4] = "AdminLevel4";
2832         visualCategoryNames[GeoDataPlacemark::AdminLevel5] = "AdminLevel5";
2833         visualCategoryNames[GeoDataPlacemark::AdminLevel6] = "AdminLevel6";
2834         visualCategoryNames[GeoDataPlacemark::AdminLevel7] = "AdminLevel7";
2835         visualCategoryNames[GeoDataPlacemark::AdminLevel8] = "AdminLevel8";
2836         visualCategoryNames[GeoDataPlacemark::AdminLevel9] = "AdminLevel9";
2837         visualCategoryNames[GeoDataPlacemark::AdminLevel10] = "AdminLevel10";
2838         visualCategoryNames[GeoDataPlacemark::AdminLevel11] = "AdminLevel11";
2839         visualCategoryNames[GeoDataPlacemark::BoundaryMaritime] = "BoundaryMaritime";
2840         visualCategoryNames[GeoDataPlacemark::WaterwayCanal] = "WaterwayCanal";
2841         visualCategoryNames[GeoDataPlacemark::WaterwayDitch] = "WaterwayDitch";
2842         visualCategoryNames[GeoDataPlacemark::WaterwayDrain] = "WaterwayDrain";
2843         visualCategoryNames[GeoDataPlacemark::WaterwayStream] = "WaterwayStream";
2844         visualCategoryNames[GeoDataPlacemark::WaterwayRiver] = "WaterwayRiver";
2845         visualCategoryNames[GeoDataPlacemark::WaterwayWeir] = "WaterwayWeir";
2846         visualCategoryNames[GeoDataPlacemark::CrossingIsland] = "CrossingIsland";
2847         visualCategoryNames[GeoDataPlacemark::CrossingRailway] = "CrossingRailway";
2848         visualCategoryNames[GeoDataPlacemark::CrossingSignals] = "CrossingSignals";
2849         visualCategoryNames[GeoDataPlacemark::CrossingZebra] = "CrossingZebra";
2850         visualCategoryNames[GeoDataPlacemark::IndoorDoor] = "IndoorDoor";
2851         visualCategoryNames[GeoDataPlacemark::IndoorWall] = "IndoorWall";
2852         visualCategoryNames[GeoDataPlacemark::IndoorRoom] = "IndoorRoom";
2853         visualCategoryNames[GeoDataPlacemark::LastIndex] = "LastIndex";
2854     }
2855 
2856     Q_ASSERT(visualCategoryNames.contains(category));
2857     return visualCategoryNames[category];
2858 }
2859 
2860 QColor StyleBuilder::effectColor(const QColor& color)
2861 {
2862     return Private::effectColor(color);
2863 }
2864 
2865 StyleEffect StyleBuilder::styleEffect()
2866 {
2867     return Private::s_styleEffect;
2868 }
2869 
2870 void StyleBuilder::setStyleEffect(StyleEffect effect)
2871 {
2872     Private::s_styleEffect = effect;
2873 }
2874 
2875 QHash<StyleBuilder::OsmTag, GeoDataPlacemark::GeoDataVisualCategory> StyleBuilder::osmTagMapping()
2876 {
2877     Private::initializeOsmVisualCategories();
2878     return Private::s_visualCategories;
2879 }
2880 
2881 QStringList StyleBuilder::shopValues()
2882 {
2883     // from https://taginfo.openstreetmap.org/keys/building#values
2884     static const QStringList osmShopValues = QStringList()
2885             << "cheese" << "chocolate" << "coffee" << "dairy" << "farm"
2886             << "pasta" << "pastry" << "wine" << "general" << "mall"
2887             << "baby_goods" << "boutique" << "fabric" << "leather" << "tailor" << "watches"
2888             << "charity" << "second_hand" << "erotic" << "hearing_aids" << "herbalist" << "massage"
2889             << "medical_supply" << "tattoo" << "bathroom_furnishing" << "electrical" << "energy" << "furnace"
2890             << "garden_furniture" << "gas" << "glaziery" << "houseware" << "locksmith"
2891             << "paint" << "trade" << "antiques" << "bed" << "candles" << "carpet"
2892             << "curtain" << "interior_decoration" << "kitchen" << "lamps" << "window_blind"
2893             << "radiotechnics" << "vacuum_cleaner" << "fishing" << "free_flying" << "hunting" << "outdoor"
2894             << "scuba_diving" << "sports" << "tyres" << "swimming_pool" << "art" << "craft"
2895             << "frame" << "games" << "model" << "music" << "trophy" << "video"
2896             << "video_games" << "anime" << "ticket" << "copyshop" << "dry_cleaning" << "e-cigarette"
2897             << "funeral_directors" << "money_lender" << "pawnbroker" << "pyrotechnics" << "religion" << "storage_rental"
2898             << "weapons" << "user defined";
2899 
2900     return osmShopValues;
2901 }
2902 
2903 QSet<StyleBuilder::OsmTag> StyleBuilder::buildingTags()
2904 {
2905     static const QString building = QStringLiteral("building");
2906     // from https://taginfo.openstreetmap.org/keys/building#values
2907     static const QSet<OsmTag> osmBuildingTags = QSet<OsmTag>()
2908             << OsmTag(building, "yes")
2909             << OsmTag(building, "house")
2910             << OsmTag(building, "residential")
2911             << OsmTag(building, "garage")
2912             << OsmTag(building, "apartments")
2913             << OsmTag(building, "hut")
2914             << OsmTag(building, "industrial")
2915             << OsmTag(building, "detached")
2916             << OsmTag(building, "roof")
2917             << OsmTag(building, "garages")
2918             << OsmTag(building, "commercial")
2919             << OsmTag(building, "terrace")
2920             << OsmTag(building, "shed")
2921             << OsmTag(building, "school")
2922             << OsmTag(building, "retail")
2923             << OsmTag(building, "farm_auxiliary")
2924             << OsmTag(building, "church")
2925             << OsmTag(building, "cathedral")
2926             << OsmTag(building, "greenhouse")
2927             << OsmTag(building, "barn")
2928             << OsmTag(building, "service")
2929             << OsmTag(building, "manufacture")
2930             << OsmTag(building, "construction")
2931             << OsmTag(building, "cabin")
2932             << OsmTag(building, "farm")
2933             << OsmTag(building, "warehouse")
2934             << OsmTag(building, "House")
2935             << OsmTag(building, "office")
2936             << OsmTag(building, "civic")
2937             << OsmTag(building, "Residential")
2938             << OsmTag(building, "hangar")
2939             << OsmTag(building, "public")
2940             << OsmTag(building, "university")
2941             << OsmTag(building, "hospital")
2942             << OsmTag(building, "chapel")
2943             << OsmTag(building, "hotel")
2944             << OsmTag(building, "train_station")
2945             << OsmTag(building, "dormitory")
2946             << OsmTag(building, "kindergarten")
2947             << OsmTag(building, "stable")
2948             << OsmTag(building, "storage_tank")
2949             << OsmTag(building, "shop")
2950             << OsmTag(building, "college")
2951             << OsmTag(building, "supermarket")
2952             << OsmTag(building, "factory")
2953             << OsmTag(building, "bungalow")
2954             << OsmTag(building, "tower")
2955             << OsmTag(building, "silo")
2956             << OsmTag(building, "storage")
2957             << OsmTag(building, "station")
2958             << OsmTag(building, "education")
2959             << OsmTag(building, "carport")
2960             << OsmTag(building, "houseboat")
2961             << OsmTag(building, "castle")
2962             << OsmTag(building, "social_facility")
2963             << OsmTag(building, "water_tower")
2964             << OsmTag(building, "container")
2965             << OsmTag(building, "exhibition_hall")
2966             << OsmTag(building, "monastery")
2967             << OsmTag(building, "bunker")
2968             << OsmTag(building, "shelter")
2969             << OsmTag("building:part", "yes")
2970             << OsmTag("building:part", "antenna");
2971 
2972     return osmBuildingTags;
2973 }
2974 
2975 GeoDataPlacemark::GeoDataVisualCategory StyleBuilder::determineVisualCategory(const OsmPlacemarkData &osmData)
2976 {
2977     QString const yes(QStringLiteral("yes"));
2978     if (osmData.containsTagKey(QStringLiteral("area:highway")) ||              // Not supported yet
2979         osmData.containsTag(QStringLiteral("boundary"), QStringLiteral("protected_area")) ||   // Not relevant for the default map
2980         osmData.containsTag(QStringLiteral("boundary"), QStringLiteral("postal_code")) ||
2981         osmData.containsTag(QStringLiteral("boundary"), QStringLiteral("aerial_views")) ||     // Created by OSM editor(s) application for digitalization
2982         osmData.containsTagKey(QStringLiteral("closed:highway")) ||
2983         osmData.containsTagKey(QStringLiteral("abandoned:highway")) ||
2984         osmData.containsTagKey(QStringLiteral("abandoned:natural")) ||
2985         osmData.containsTagKey(QStringLiteral("abandoned:building")) ||
2986         osmData.containsTagKey(QStringLiteral("abandoned:leisure")) ||
2987         osmData.containsTagKey(QStringLiteral("disused:highway")) ||
2988         osmData.containsTag(QStringLiteral("highway"), QStringLiteral("razed")) ||
2989         osmData.containsTag(QStringLiteral("piste:abandoned"), yes)) {
2990         return GeoDataPlacemark::None;
2991     }
2992 
2993     if (osmData.containsTag(QStringLiteral("building"), yes)) {
2994         return GeoDataPlacemark::Building;
2995     }
2996 
2997     if (osmData.containsTag(QStringLiteral("historic"), QStringLiteral("castle")) && osmData.containsTag(QStringLiteral("castle_type"), QStringLiteral("kremlin"))) {
2998         return GeoDataPlacemark::None;
2999     }
3000 
3001     if (osmData.containsTag(QStringLiteral("natural"), QStringLiteral("glacier")) && osmData.containsTag(QStringLiteral("glacier:type"), QStringLiteral("shelf"))) {
3002         return GeoDataPlacemark::NaturalIceShelf;
3003     }
3004 
3005     if (osmData.containsTag(QStringLiteral("highway"), QStringLiteral("crossing"))) {
3006         QStringList const crossings = osmData.tagValue(QStringLiteral("crossing")).split(';');
3007         QString const crossingRef = osmData.tagValue(QStringLiteral("crossing_ref"));
3008         if (crossingRef == QStringLiteral("zebra") ||
3009             crossingRef == QStringLiteral("tiger") ||
3010             crossings.contains(QStringLiteral("zebra")) ||
3011             crossings.contains(QStringLiteral("tiger"))) {
3012             return GeoDataPlacemark::CrossingZebra;
3013         } else if (crossingRef == QStringLiteral("toucan") ||
3014                    crossingRef == QStringLiteral("pelican") ||
3015                    crossings.contains(QStringLiteral("traffic_signals")) ||
3016                    crossings.contains(QStringLiteral("toucan")) ||
3017                    crossings.contains(QStringLiteral("pelican"))) {
3018             return GeoDataPlacemark::CrossingSignals;
3019         } else if (crossings.contains(QStringLiteral("island"))) {
3020             return GeoDataPlacemark::CrossingIsland;
3021         }
3022     }
3023     if (osmData.containsTag(QStringLiteral("railway"), QStringLiteral("crossing")) ||
3024         osmData.containsTag(QStringLiteral("railway"), QStringLiteral("level_crossing"))) {
3025         return GeoDataPlacemark::CrossingRailway;
3026     }
3027 
3028     Private::initializeOsmVisualCategories();
3029 
3030     auto const pisteType = osmData.tagValue(QStringLiteral("piste:type"));
3031     if (!pisteType.isEmpty()) {
3032         auto const tag = OsmTag(QStringLiteral("piste:type"), pisteType);
3033         auto category = Private::s_visualCategories.value(tag, GeoDataPlacemark::None);
3034         if (category != GeoDataPlacemark::None) {
3035             return category;
3036         }
3037     }
3038 
3039     QString const capital(QStringLiteral("capital"));
3040     QString const admin_level(QStringLiteral("admin_level"));
3041     // National capitals have admin_level=2
3042     // More at https://wiki.openstreetmap.org/wiki/Key:capital#Using_relations_for_capitals
3043     QString const national_level(QStringLiteral("2"));
3044 
3045     for (auto iter = osmData.tagsBegin(), end = osmData.tagsEnd(); iter != end; ++iter) {
3046         const auto tag = OsmTag(iter.key(), iter.value());
3047         GeoDataPlacemark::GeoDataVisualCategory category = Private::s_visualCategories.value(tag, GeoDataPlacemark::None);
3048         if (category != GeoDataPlacemark::None) {
3049             if (category == GeoDataPlacemark::PlaceCity && osmData.containsTag(admin_level, national_level)) {
3050                 category = GeoDataPlacemark::PlaceCityNationalCapital;
3051             } else if (category == GeoDataPlacemark::PlaceCity && osmData.containsTag(capital, yes)) {
3052                 category = GeoDataPlacemark::PlaceCityCapital;
3053             } else if (category == GeoDataPlacemark::PlaceTown && osmData.containsTag(admin_level, national_level)) {
3054                 category = GeoDataPlacemark::PlaceTownNationalCapital;
3055             } else if (category == GeoDataPlacemark::PlaceTown && osmData.containsTag(capital, yes)) {
3056                 category = GeoDataPlacemark::PlaceTownCapital;
3057             } else if (category == GeoDataPlacemark::PlaceVillage && osmData.containsTag(admin_level, national_level)) {
3058                 category = GeoDataPlacemark::PlaceVillageNationalCapital;
3059             } else if (category == GeoDataPlacemark::PlaceVillage && osmData.containsTag(capital, yes)) {
3060                 category = GeoDataPlacemark::PlaceVillageCapital;
3061             }
3062         }
3063 
3064         if (category != GeoDataPlacemark::None) {
3065             return category;
3066         }
3067     }
3068 
3069     return GeoDataPlacemark::None;
3070 }
3071 
3072 StyleParameters::StyleParameters(const GeoDataPlacemark *placemark_, int tileLevel_) :
3073     placemark(placemark_),
3074     tileLevel(tileLevel_),
3075     relation(nullptr)
3076 {
3077     // nothing to do
3078 }
3079 
3080 }