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"