diff --git a/data/svg/osmc-symbols/3rdparty/COPYRIGHT b/data/svg/osmc-symbols/3rdparty/COPYRIGHT
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/3rdparty/COPYRIGHT
@@ -0,0 +1,11 @@
+This file explains who has the credit for all the images in this directory.
+
+horse.svg: Horse by Eren ÜLÜŞ from the Noun Project
+heart.svg: Heart by dilayorganci from the Noun Project
+tower.svg: Castle by Les Lunettes Bleues from the Noun Project
+mine.svg: Mining Tools by Rob Armes from the Noun Project
+hiker.svg: Hiker by National Park Service Collection from the Noun Project
+bridleway.svg: By user:Andreas 06 [Public domain], via Wikimedia Commons
+ammonit.svg: Shell by Caitlin McCormick from the Noun Project
+shell.svg: Shell by Ricardo Luciano from the Noun Project
+shell_modern.svg: Shell by B Barrett from the Noun Project
diff --git a/data/svg/osmc-symbols/3rdparty/ammonit.svg b/data/svg/osmc-symbols/3rdparty/ammonit.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/3rdparty/ammonit.svg
@@ -0,0 +1,48 @@
+
+
diff --git a/data/svg/osmc-symbols/3rdparty/bridleway.svg b/data/svg/osmc-symbols/3rdparty/bridleway.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/3rdparty/bridleway.svg
@@ -0,0 +1,56 @@
+
+
diff --git a/data/svg/osmc-symbols/3rdparty/heart.svg b/data/svg/osmc-symbols/3rdparty/heart.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/3rdparty/heart.svg
@@ -0,0 +1,34 @@
+
+
diff --git a/data/svg/osmc-symbols/3rdparty/hiker.svg b/data/svg/osmc-symbols/3rdparty/hiker.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/3rdparty/hiker.svg
@@ -0,0 +1,46 @@
+
+
diff --git a/data/svg/osmc-symbols/3rdparty/horse.svg b/data/svg/osmc-symbols/3rdparty/horse.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/3rdparty/horse.svg
@@ -0,0 +1,33 @@
+
+
diff --git a/data/svg/osmc-symbols/3rdparty/mine.svg b/data/svg/osmc-symbols/3rdparty/mine.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/3rdparty/mine.svg
@@ -0,0 +1,33 @@
+
+
diff --git a/data/svg/osmc-symbols/3rdparty/shell.svg b/data/svg/osmc-symbols/3rdparty/shell.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/3rdparty/shell.svg
@@ -0,0 +1,51 @@
+
+
diff --git a/data/svg/osmc-symbols/3rdparty/shell_modern.svg b/data/svg/osmc-symbols/3rdparty/shell_modern.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/3rdparty/shell_modern.svg
@@ -0,0 +1,107 @@
+
+
diff --git a/data/svg/osmc-symbols/3rdparty/tower.svg b/data/svg/osmc-symbols/3rdparty/tower.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/3rdparty/tower.svg
@@ -0,0 +1,33 @@
+
+
diff --git a/data/svg/osmc-symbols/L.svg b/data/svg/osmc-symbols/L.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/L.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/arch.svg b/data/svg/osmc-symbols/arch.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/arch.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/backslash.svg b/data/svg/osmc-symbols/backslash.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/backslash.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/bar.svg b/data/svg/osmc-symbols/bar.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/bar.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/bowl.svg b/data/svg/osmc-symbols/bowl.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/bowl.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/circle.svg b/data/svg/osmc-symbols/circle.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/circle.svg
@@ -0,0 +1,14 @@
+
+
+
diff --git a/data/svg/osmc-symbols/corner.svg b/data/svg/osmc-symbols/corner.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/corner.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/cross.svg b/data/svg/osmc-symbols/cross.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/cross.svg
@@ -0,0 +1,14 @@
+
+
+
diff --git a/data/svg/osmc-symbols/diamond.svg b/data/svg/osmc-symbols/diamond.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/diamond.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/dot.svg b/data/svg/osmc-symbols/dot.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/dot.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/drop_line.svg b/data/svg/osmc-symbols/drop_line.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/drop_line.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/fork.svg b/data/svg/osmc-symbols/fork.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/fork.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/lower.svg b/data/svg/osmc-symbols/lower.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/lower.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/pointer.svg b/data/svg/osmc-symbols/pointer.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/pointer.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/rectangle.svg b/data/svg/osmc-symbols/rectangle.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/rectangle.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/rectangle_line.svg b/data/svg/osmc-symbols/rectangle_line.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/rectangle_line.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/slash.svg b/data/svg/osmc-symbols/slash.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/slash.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/stripe.svg b/data/svg/osmc-symbols/stripe.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/stripe.svg
@@ -0,0 +1,35 @@
+
+
diff --git a/data/svg/osmc-symbols/triangle.svg b/data/svg/osmc-symbols/triangle.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/triangle.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/triangle_line.svg b/data/svg/osmc-symbols/triangle_line.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/triangle_line.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/triangle_turned.svg b/data/svg/osmc-symbols/triangle_turned.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/triangle_turned.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/turned_T.svg b/data/svg/osmc-symbols/turned_T.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/turned_T.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/data/svg/osmc-symbols/wolfshook.svg b/data/svg/osmc-symbols/wolfshook.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/wolfshook.svg
@@ -0,0 +1,15 @@
+
+
diff --git a/data/svg/osmc-symbols/x.svg b/data/svg/osmc-symbols/x.svg
new file mode 100644
--- /dev/null
+++ b/data/svg/osmc-symbols/x.svg
@@ -0,0 +1,19 @@
+
+
+
diff --git a/src/lib/marble/CMakeLists.txt b/src/lib/marble/CMakeLists.txt
--- a/src/lib/marble/CMakeLists.txt
+++ b/src/lib/marble/CMakeLists.txt
@@ -272,6 +272,8 @@
NewstuffModel.cpp
MarbleZip.cpp
+ OsmcSymbol.cpp
+
StyleBuilder.cpp
BatchedPlacemarkRenderer.cpp
@@ -618,6 +620,8 @@
routing/RoutingModel.h
routing/RoutingProfile.h
+ OsmcSymbol.h
+
BatchedPlacemarkRenderer.h
DESTINATION ${INCLUDE_INSTALL_DIR}/marble
diff --git a/src/lib/marble/OsmcSymbol.h b/src/lib/marble/OsmcSymbol.h
new file mode 100644
--- /dev/null
+++ b/src/lib/marble/OsmcSymbol.h
@@ -0,0 +1,53 @@
+//
+// This file is part of the Marble Virtual Globe.
+//
+// This program is free software licensed under the GNU LGPL. You can
+// find a copy of this license in LICENSE.txt in the top directory of
+// the source code.
+//
+// Copyright 2017 Sergey Popov
+//
+
+#ifndef OSMCSYMBOL_H
+#define OSMCSYMBOL_H
+
+#include
+#include
+#include
+#include
+
+class OsmcSymbol
+{
+public:
+ OsmcSymbol(const QString &tag, const int side = 20);
+ ~OsmcSymbol();
+
+ QImage icon();
+ QColor wayColor();
+
+private:
+ bool parseTag(const QString &tag);
+ bool parseBackground(const QString &bg);
+ QSvgRenderer* parseForeground(const QString &fg);
+
+ void render();
+
+ QColor m_wayColor;
+ QColor m_backgroundColor;
+ QString m_backgroundType;
+ QSvgRenderer *m_foreground;
+ QSvgRenderer *m_foreground2;
+ QString m_text;
+ QColor m_textColor;
+
+ QImage m_image;
+
+ QStringList m_backgroundTypes;
+ QStringList m_foregroundTypes;
+ QStringList m_precoloredForegroundTypes;
+
+ int m_side;
+ int m_wayWidth;
+};
+
+#endif // OSMCSYMBOL_H
diff --git a/src/lib/marble/OsmcSymbol.cpp b/src/lib/marble/OsmcSymbol.cpp
new file mode 100644
--- /dev/null
+++ b/src/lib/marble/OsmcSymbol.cpp
@@ -0,0 +1,243 @@
+//
+// This file is part of the Marble Virtual Globe.
+//
+// This program is free software licensed under the GNU LGPL. You can
+// find a copy of this license in LICENSE.txt in the top directory of
+// the source code.
+//
+// Copyright 2017 Sergey Popov
+//
+
+#include
+#include
+#include
+#include
+
+#include "OsmcSymbol.h"
+
+OsmcSymbol::OsmcSymbol(const QString &tag, const int side)
+ : m_wayColor(Qt::white)
+ , m_backgroundColor(Qt::black)
+ , m_foreground(nullptr)
+ , m_foreground2(nullptr)
+ , m_textColor(Qt::black)
+ , m_side(side)
+{
+ m_backgroundTypes
+ << "round" << "circle" << "frame";
+
+ m_foregroundTypes
+ << "dot" << "bowl" << "circle" << "bar"
+ << "stripe" << "cross" << "x" << "slash"
+ << "backslash" << "rectangle" << "rectangle_line"
+ << "triangle" << "triangle_turned" << "triangle_line"
+ << "diamond" << "pointer" << "fork" << "arch"
+ << "turned_T" << "L" << "lower" << "corner"
+ << "drop_line" << "horse" << "hiker";
+
+ m_precoloredForegroundTypes
+ << "wolfshook" << "shell" << "shell_modern" << "ammonit"
+ << "mine" << "hiker" << "heart" << "tower" << "bridleway";
+
+ if (parseTag(tag))
+ render();
+}
+
+OsmcSymbol::~OsmcSymbol()
+{
+ if (m_foreground)
+ delete m_foreground;
+ if (m_foreground2)
+ delete m_foreground2;
+}
+
+bool OsmcSymbol::parseTag(const QString &tag)
+{
+ QStringList parts = tag.split(":");
+
+ if (parts.size() < 2) {
+ return false;
+ }
+
+ if (m_foreground) { delete m_foreground; m_foreground = nullptr; }
+ if (m_foreground2) { delete m_foreground2; m_foreground2 = nullptr; }
+
+ // Determine way color
+ if (QColor::isValidColor(parts.at(0)))
+ m_wayColor.setNamedColor(parts.at(0));
+ else
+ return false;
+
+ if (!parseBackground(parts.at(1)))
+ return false;
+
+ qDebug() << tag;
+
+ if (parts.size() == 3) {
+ m_foreground = parseForeground(parts.at(2));
+ } else if (parts.size() == 4) {
+ if (QColor::isValidColor(parts.at(3))) {
+ m_text = parts.at(2);
+ m_textColor = parts.at(3);
+ } else {
+ m_foreground = parseForeground(parts.at(2));
+ m_foreground2 = parseForeground(parts.at(3));
+ }
+ } else if (parts.size() == 5) {
+ m_foreground = parseForeground(parts.at(2));
+ if (QColor::isValidColor(parts.at(4))) {
+ m_text = parts.at(3);
+ m_textColor = parts.at(4);
+ } else
+ return false;
+ } else if (parts.size() == 6) {
+ m_foreground = parseForeground(parts.at(2));
+ m_foreground2 = parseForeground(parts.at(3));
+ if (QColor::isValidColor(parts.at(5))) {
+ m_text = parts.at(4);
+ m_textColor.setNamedColor(parts.at(5));
+ } else
+ return false;
+ } else
+ return false;
+
+ return true;
+}
+
+bool OsmcSymbol::parseBackground(const QString &bg)
+{
+ QString color = bg.section("_", 0, 0);
+ QString type = bg.section("_", 1, -1);
+
+ if (!QColor::isValidColor(color))
+ return false;
+
+ // Plain color was provided
+ if (type.isEmpty()) {
+ m_backgroundColor.setNamedColor(color);
+ m_backgroundType = type;
+ } else if (m_backgroundTypes.contains(type)) {
+ m_backgroundColor.setNamedColor(color);
+ m_backgroundType = type;
+ } else
+ return false;
+
+ return true;
+}
+
+void setXMLAttribute(QDomElement &elem, QString tag, QString attr, QString attrValue);
+
+QSvgRenderer* OsmcSymbol::parseForeground(const QString &fg)
+{
+ if (m_precoloredForegroundTypes.contains(fg)) {
+ return new QSvgRenderer(QString(":/osmc-symbols/%1.svg").arg(fg));
+ }
+
+ QString color = fg.section("_", 0, 0);
+ QString type = fg.section("_", 1, -1);
+ if (QColor::isValidColor(color) && m_foregroundTypes.contains(type)) {
+ // Open svg resource and load contents to QByteArray
+ QFile file(QString(":/osmc-symbols/%1.svg").arg(type));
+ file.open(QIODevice::ReadOnly);
+ QByteArray baData = file.readAll();
+
+ // Load svg contents to xml document
+ QDomDocument doc;
+ doc.setContent(baData);
+
+ // Recurively change color
+ QDomElement rootElement = doc.documentElement();
+ setXMLAttribute(rootElement, "path", "fill", color);
+
+ // Create and return svg renderer with edited contents
+ return new QSvgRenderer(doc.toByteArray());
+ }
+
+ return nullptr;
+}
+
+void OsmcSymbol::render()
+{
+ m_image = QImage(m_side, m_side, QImage::Format_ARGB32);
+ m_image.fill(Qt::transparent);
+
+ QPainter painter(&m_image);
+ painter.setRenderHint(QPainter::Antialiasing);
+
+ // Default size of background
+ int w = m_side, h = m_side;
+
+ // If there is some text, our background size must be recalculated
+ if (m_text != QString()) {
+ QFont font = painter.font();
+ font.setPixelSize(m_side * 0.8);
+ font.setBold(true);
+ painter.setFont(font);
+ QFontMetrics fm = QFontMetrics(font);
+
+ w = fm.width(m_text);
+ h = fm.height();
+ w = w > h ? w : h;
+ }
+
+ const QRect bgRect = QRect((m_side - w)/2, (m_side - h)/2, w, h);
+
+ // Draw symbol's background
+ if (m_backgroundType.isEmpty()) {
+ painter.fillRect(bgRect, m_backgroundColor);
+ } else if (m_backgroundType == "round") {
+ painter.setBrush(m_backgroundColor);
+ painter.setPen(m_backgroundColor);
+ painter.drawEllipse(bgRect);
+ } else if (m_backgroundType == "circle") {
+ painter.setBrush(Qt::white);
+ painter.setPen(QPen(m_backgroundColor, m_side/10));
+ painter.drawEllipse(bgRect);
+ } else if (m_backgroundType == "frame") {
+ painter.setPen(QPen(m_backgroundColor, m_side/10));
+ painter.fillRect(bgRect, Qt::white);
+ painter.drawRect(bgRect);
+ }
+
+ QPixmap foregrounds(bgRect.size());
+ foregrounds.fill(Qt::transparent);
+ QPainter fgPainter(&foregrounds);
+ m_foreground ? m_foreground->render(&fgPainter) : void();
+ m_foreground2 ? m_foreground2->render(&fgPainter) : void();
+ painter.drawPixmap(bgRect, foregrounds);
+
+ if (m_text != QString()) {
+ // Draw text with provided color
+ painter.setPen(m_textColor);
+ painter.drawText(bgRect, Qt::AlignCenter, m_text);
+ }
+
+ painter.end();
+}
+
+QImage OsmcSymbol::icon()
+{
+ return m_image;
+}
+
+QColor OsmcSymbol::wayColor()
+{
+ return m_wayColor;
+}
+
+void setXMLAttribute(QDomElement &elem, QString tag, QString attr, QString attrValue)
+{
+ // If elem's tag is equal to the provided one then overwrite desired attribute
+ if (elem.tagName() == tag)
+ elem.setAttribute(attr, attrValue);
+
+ // Do the same for all the child nodes
+ for (int i = 0; i < elem.childNodes().count(); i++)
+ {
+ if (!elem.childNodes().at(i).isElement())
+ continue;
+
+ QDomElement child = elem.childNodes().at(i).toElement();
+ setXMLAttribute(child, tag, attr, attrValue);
+ }
+}
diff --git a/src/lib/marble/StyleBuilder.cpp b/src/lib/marble/StyleBuilder.cpp
--- a/src/lib/marble/StyleBuilder.cpp
+++ b/src/lib/marble/StyleBuilder.cpp
@@ -15,6 +15,7 @@
#include "MarbleDirs.h"
#include "OsmPlacemarkData.h"
+#include "OsmcSymbol.h"
#include "GeoDataTypes.h"
#include "GeoDataGeometry.h"
#include "GeoDataPlacemark.h"
@@ -1604,6 +1605,7 @@
GeoDataPolyStyle polyStyle = style->polyStyle();
GeoDataLineStyle lineStyle = style->lineStyle();
GeoDataLabelStyle labelStyle = style->labelStyle();
+ GeoDataIconStyle iconStyle = style->iconStyle();
lineStyle.setCosmeticOutline(true);
bool adjustStyle = false;
@@ -1719,13 +1721,22 @@
float const width = widthValue.toFloat(&ok);
lineStyle.setPhysicalWidth(ok ? qBound(0.1f, width, 200.0f) : 0.0f);
}
+ } else if (visualCategory == GeoDataPlacemark::RouteHiking && osmData.containsTagKey(QStringLiteral("osmc:symbol"))) {
+ adjustStyle = true;
+
+ QString const osmcSymbolValue = osmData.tagValue(QStringLiteral("osmc:symbol"));
+ OsmcSymbol symbol = OsmcSymbol(osmcSymbolValue);
+
+ lineStyle.setColor(symbol.wayColor());
+ iconStyle.setIcon(symbol.icon());
}
if (adjustStyle) {
GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style));
newStyle->setPolyStyle(polyStyle);
newStyle->setLineStyle(lineStyle);
newStyle->setLabelStyle(labelStyle);
+ newStyle->setIconStyle(iconStyle);
style = newStyle;
if (cacheSpecialStyle) {
d->m_specialStyleCache.insert(specialStyleCacheKey, newStyle);
diff --git a/src/lib/marble/libmarble.qrc b/src/lib/marble/libmarble.qrc
--- a/src/lib/marble/libmarble.qrc
+++ b/src/lib/marble/libmarble.qrc
@@ -104,4 +104,38 @@
htmlfeatures/bootstrap.min.css
htmlfeatures/bootstrap.inc
+
+ ../../../data/svg/osmc-symbols/dot.svg
+ ../../../data/svg/osmc-symbols/bowl.svg
+ ../../../data/svg/osmc-symbols/circle.svg
+ ../../../data/svg/osmc-symbols/bar.svg
+ ../../../data/svg/osmc-symbols/stripe.svg
+ ../../../data/svg/osmc-symbols/x.svg
+ ../../../data/svg/osmc-symbols/backslash.svg
+ ../../../data/svg/osmc-symbols/slash.svg
+ ../../../data/svg/osmc-symbols/triangle.svg
+ ../../../data/svg/osmc-symbols/triangle_turned.svg
+ ../../../data/svg/osmc-symbols/triangle_line.svg
+ ../../../data/svg/osmc-symbols/diamond.svg
+ ../../../data/svg/osmc-symbols/rectangle.svg
+ ../../../data/svg/osmc-symbols/rectangle_line.svg
+ ../../../data/svg/osmc-symbols/pointer.svg
+ ../../../data/svg/osmc-symbols/fork.svg
+ ../../../data/svg/osmc-symbols/arch.svg
+ ../../../data/svg/osmc-symbols/turned_T.svg
+ ../../../data/svg/osmc-symbols/L.svg
+ ../../../data/svg/osmc-symbols/lower.svg
+ ../../../data/svg/osmc-symbols/corner.svg
+ ../../../data/svg/osmc-symbols/drop_line.svg
+ ../../../data/svg/osmc-symbols/wolfshook.svg
+ ../../../data/svg/osmc-symbols/3rdparty/ammonit.svg
+ ../../../data/svg/osmc-symbols/3rdparty/bridleway.svg
+ ../../../data/svg/osmc-symbols/3rdparty/heart.svg
+ ../../../data/svg/osmc-symbols/3rdparty/hiker.svg
+ ../../../data/svg/osmc-symbols/3rdparty/horse.svg
+ ../../../data/svg/osmc-symbols/3rdparty/mine.svg
+ ../../../data/svg/osmc-symbols/3rdparty/shell_modern.svg
+ ../../../data/svg/osmc-symbols/3rdparty/shell.svg
+ ../../../data/svg/osmc-symbols/3rdparty/tower.svg
+