File indexing completed on 2024-05-05 03:49:19

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2017 Sergey Popov <sergobot@protonmail.com>
0004 //
0005 
0006 #include "RouteRelationModel.h"
0007 
0008 #include "MarbleColors.h"
0009 #include "MarbleDirs.h"
0010 #include "osm/OsmPlacemarkData.h"
0011 #include "GeoDataColorStyle.h"
0012 
0013 namespace Marble
0014 {
0015 
0016 RouteRelationModel::RouteRelationModel(QObject *parent) :
0017     QAbstractListModel(parent)
0018 {
0019     m_networks[QStringLiteral("iwn")] = tr("International walking route");
0020     m_networks[QStringLiteral("nwn")] = tr("National walking route");
0021     m_networks[QStringLiteral("rwn")] = tr("Regional walking route");
0022     m_networks[QStringLiteral("lwn")] = tr("Local walking route");
0023     m_networks[QStringLiteral("icn")] = tr("International cycling route");
0024     m_networks[QStringLiteral("ncn")] = tr("National cycling route");
0025     m_networks[QStringLiteral("rcn")] = tr("Regional cycling route");
0026     m_networks[QStringLiteral("lcn")] = tr("Local cycling route");
0027     m_networks[QStringLiteral("US:TX:FM")] = tr("Farm to Market Road", "State or county road in Texas, USA");
0028     m_networks[QStringLiteral("regional")] = tr("Regional route");
0029     m_networks[QStringLiteral("national")] = tr("National route");
0030     m_networks[QStringLiteral("municipal")] = tr("Municipal route");
0031     m_networks[QStringLiteral("territorial")] = tr("Territorial route");
0032     m_networks[QStringLiteral("local")] = tr("Local route");
0033     m_networks[QStringLiteral("prefectural")] = tr("Prefectural route");
0034     m_networks[QStringLiteral("US")] = tr("United States route");
0035 }
0036 
0037 void RouteRelationModel::setRelations(const QSet<const GeoDataRelation*> &relations)
0038 {
0039     if (!m_relations.isEmpty()) {
0040         beginRemoveRows(QModelIndex(), 0, m_relations.count() - 1);
0041         m_relations.clear();
0042         endRemoveRows();
0043     }
0044 
0045     if (!relations.isEmpty()) {
0046         beginInsertRows(QModelIndex(), 0, relations.count() - 1);
0047         m_relations.reserve(relations.size());
0048         for (auto relation: relations) {
0049             if (relation->relationType() >= GeoDataRelation::RouteRoad && relation->relationType() <= GeoDataRelation::RouteSled) {
0050                 m_relations << new GeoDataRelation(*relation);
0051             }
0052         }
0053         std::sort(m_relations.begin(), m_relations.end(),
0054         [](const GeoDataRelation * a, const GeoDataRelation * b) {
0055             return *a < *b;
0056         });
0057         endInsertRows();
0058     }
0059 }
0060 
0061 int RouteRelationModel::rowCount(const QModelIndex & parent) const
0062 {
0063     return parent.isValid() ? 0 : m_relations.count();
0064 }
0065 
0066 QVariant RouteRelationModel::data(const QModelIndex & index, int role) const
0067 {
0068     if (!index.isValid() || index.row() < 0 || index.row() >= m_relations.count()) {
0069         return QVariant();
0070     }
0071 
0072     if (role == Qt::DisplayRole) {
0073         return m_relations.at(index.row())->name();
0074     } else if (role == IconSource) {
0075         switch (m_relations.at(index.row())->relationType()) {
0076         case GeoDataRelation::RouteRoad:         return QStringLiteral("material/directions-car.svg");
0077         case GeoDataRelation::RouteDetour:       return QStringLiteral("material/directions-car.svg");
0078         case GeoDataRelation::RouteFerry:        return QStringLiteral("material/directions-boat.svg");
0079         case GeoDataRelation::RouteTrain:        return QStringLiteral("material/directions-railway.svg");
0080         case GeoDataRelation::RouteSubway:       return QStringLiteral("material/directions-subway.svg");
0081         case GeoDataRelation::RouteTram:         return QStringLiteral("material/directions-tram.svg");
0082         case GeoDataRelation::RouteBus:          return QStringLiteral("material/directions-bus.svg");
0083         case GeoDataRelation::RouteTrolleyBus:   return QStringLiteral("material/directions-bus.svg");
0084         case GeoDataRelation::RouteBicycle:      return QStringLiteral("material/directions-bike.svg");
0085         case GeoDataRelation::RouteMountainbike: return QStringLiteral("material/directions-bike.svg");
0086         case GeoDataRelation::RouteFoot:         return QStringLiteral("material/directions-walk.svg");
0087         case GeoDataRelation::RouteHiking:       return QStringLiteral("thenounproject/204712-hiker.svg");
0088         case GeoDataRelation::RouteHorse:        return QStringLiteral("thenounproject/78374-horse-riding.svg");
0089         case GeoDataRelation::RouteInlineSkates: return QStringLiteral("thenounproject/101965-inline-skater.svg");
0090         case GeoDataRelation::RouteSkiDownhill:  return QStringLiteral("thenounproject/2412-skiing-downhill.svg");
0091         case GeoDataRelation::RouteSkiNordic:    return QStringLiteral("thenounproject/30231-skiing-cross-country.svg");
0092         case GeoDataRelation::RouteSkitour:      return QStringLiteral("thenounproject/29366-skitour.svg");
0093         case GeoDataRelation::RouteSled:         return QStringLiteral("thenounproject/365217-sled.svg");
0094         case GeoDataRelation::UnknownType:       return QVariant(QString());
0095         }
0096     } else if (role == Description) {
0097         return m_relations.at(index.row())->osmData().tagValue(QStringLiteral("description"));
0098     } else if (role == Network) {
0099         auto const network = m_relations.at(index.row())->osmData().tagValue(QStringLiteral("network"));
0100         auto iter = m_networks.find(network);
0101         if (iter != m_networks.end()) {
0102             return *iter;
0103         }
0104         auto const fields = network.split(':', QString::SkipEmptyParts);
0105         for (auto const &field: fields) {
0106             auto iter = m_networks.find(field);
0107             if (iter != m_networks.end()) {
0108                 return *iter;
0109             }
0110         }
0111         return network;
0112     } else if (role == RouteColor) {
0113         auto const color = m_relations.at(index.row())->osmData().tagValue(QStringLiteral("colour"));
0114         return color.isEmpty() ? QStringLiteral("white") : color;
0115     } else if (role == TextColor) {
0116         auto const colorValue = m_relations.at(index.row())->osmData().tagValue(QStringLiteral("colour"));
0117         auto const color = QColor(colorValue.isEmpty() ? QStringLiteral("white") : colorValue);
0118         return GeoDataColorStyle::contrastColor(color);
0119     } else if (role == RouteFrom) {
0120         return m_relations.at(index.row())->osmData().tagValue(QStringLiteral("from"));
0121     } else if (role == RouteTo) {
0122         return m_relations.at(index.row())->osmData().tagValue(QStringLiteral("to"));
0123     } else if (role == RouteRef) {
0124         auto const ref = m_relations.at(index.row())->osmData().tagValue(QStringLiteral("ref"));
0125         return ref.isEmpty() ? m_relations.at(index.row())->name() : ref;
0126     } else if (role == RouteVia) {
0127         auto const viaValue = m_relations.at(index.row())->osmData().tagValue(QStringLiteral("via"));
0128         auto viaList = viaValue.split(';', QString::SkipEmptyParts);
0129         for (auto &via: viaList) {
0130             via = via.trimmed();
0131         }
0132         return viaList;
0133     } else if (role == OsmId) {
0134         return m_relations.at(index.row())->osmData().oid();
0135     } else if (role == RouteVisible) {
0136         return m_relations.at(index.row())->isVisible();
0137     }
0138 
0139     return QVariant();
0140 }
0141 
0142 QHash<int, QByteArray> RouteRelationModel::roleNames() const
0143 {
0144     QHash<int, QByteArray> roles;
0145     roles[Qt::DisplayRole] = "display";
0146     roles[IconSource] = "iconSource";
0147     roles[Description] = "description";
0148     roles[Network] = "network";
0149     roles[RouteColor] = "routeColor";
0150     roles[TextColor] = "textColor";
0151     roles[RouteFrom] = "routeFrom";
0152     roles[RouteTo] = "routeTo";
0153     roles[RouteRef] = "routeRef";
0154     roles[RouteVia] = "routeVia";
0155     roles[OsmId] = "oid";
0156     roles[RouteVisible] = "routeVisible";
0157     return roles;
0158 }
0159 
0160 QString RouteRelationModel::svgFile(const QString &path)
0161 {
0162 #ifdef Q_OS_ANDROID
0163     return MarbleDirs::path(QStringLiteral("svg/%1").arg(path));
0164 #else
0165     return QStringLiteral("file:///") + MarbleDirs::path(QStringLiteral("svg/%1").arg(path));
0166 #endif
0167 }
0168 
0169 }
0170 
0171 #include "moc_RouteRelationModel.cpp"