diff --git a/src/apps/marble-maps/PlacemarkDialog.qml b/src/apps/marble-maps/PlacemarkDialog.qml --- a/src/apps/marble-maps/PlacemarkDialog.qml +++ b/src/apps/marble-maps/PlacemarkDialog.qml @@ -66,6 +66,14 @@ font.pointSize: 20 } + ListView { + model: placemark ? placemark.relationModel : undefined + header: Text { text: "Appears in these relations:" } + width: parent.width + height: 150 + delegate: Text { text: name } + } + IconText { width: parent.width visible: text.length > 0 diff --git a/src/lib/marble/declarative/CMakeLists.txt b/src/lib/marble/declarative/CMakeLists.txt --- a/src/lib/marble/declarative/CMakeLists.txt +++ b/src/lib/marble/declarative/CMakeLists.txt @@ -27,6 +27,7 @@ OfflineDataModel.cpp RouteRequestModel.cpp Settings.cpp + RouteRelationModel.cpp ) generate_export_header(marbledeclarative BASE_NAME marble_declarative) diff --git a/src/lib/marble/declarative/MarbleDeclarativePlugin.cpp b/src/lib/marble/declarative/MarbleDeclarativePlugin.cpp --- a/src/lib/marble/declarative/MarbleDeclarativePlugin.cpp +++ b/src/lib/marble/declarative/MarbleDeclarativePlugin.cpp @@ -66,6 +66,8 @@ QStringLiteral("MarblePlacemarkModel is not instantiable")); qmlRegisterUncreatableType(uri, 0, 20, "RoutingModel", QStringLiteral("RoutingModel is not instantiable")); + qmlRegisterUncreatableType(uri, 0, 20, "RouteRelationModel", + QStringLiteral("RouteRelationModel is not instantiable")); qmlRegisterUncreatableType(uri, 0, 20, "BookmarksModel", QStringLiteral("Do not create")); qmlRegisterUncreatableType(uri, 0, 20, "FloatItem", diff --git a/src/lib/marble/declarative/MarbleQuickItem.cpp b/src/lib/marble/declarative/MarbleQuickItem.cpp --- a/src/lib/marble/declarative/MarbleQuickItem.cpp +++ b/src/lib/marble/declarative/MarbleQuickItem.cpp @@ -610,16 +610,18 @@ d->m_placemark = new Placemark(this); d->m_placemark->setGeoDataPlacemark(*placemark); if (placemark->parent() && placemark->parent()->nodeType() == GeoDataTypes::GeoDataDocumentType) { + QVector relations; auto const document = static_cast(placemark->parent()); for (auto feature: document->featureList()) { if (feature->nodeType() == GeoDataTypes::GeoDataRelationType) { - auto const relation = static_cast(feature); + auto relation = static_cast(feature); if (relation->memberIds().contains(placemark->osmData().oid())) { - // @TODO Can be used to present relations to the user, e.g. - // selecting a hiking route for highlighting + relations.push_back(relation); } } } + if (!relations.isEmpty()) + d->m_placemark->setRelations(relations); } } delete d->m_placemarkItem; diff --git a/src/lib/marble/declarative/Placemark.h b/src/lib/marble/declarative/Placemark.h --- a/src/lib/marble/declarative/Placemark.h +++ b/src/lib/marble/declarative/Placemark.h @@ -12,6 +12,7 @@ #define MARBLE_DECLARATIVE_PLACEMARK_H #include "GeoDataPlacemark.h" +#include "RouteRelationModel.h" #include #include @@ -39,6 +40,8 @@ Q_PROPERTY(double latitude READ latitude NOTIFY coordinatesChanged) Q_PROPERTY(QStringList tags READ tags NOTIFY tagsChanged) + Q_PROPERTY(RouteRelationModel* relationModel READ relationModel NOTIFY relationModelChanged) + public: /** Constructor */ explicit Placemark( QObject *parent = 0 ); @@ -61,6 +64,9 @@ double latitude() const; const QStringList & tags() const; + void setRelations(const QVector &relations); + RouteRelationModel* relationModel(); + public Q_SLOTS: void setName(const QString &name); @@ -76,6 +82,8 @@ void wifiAvailabilityChanged(); void tagsChanged(); + void relationModelChanged(); + private: bool addTagValue(QString &target, const QString &key, const QString &format=QString(), const QString separator = QStringLiteral(" ยท ")) const; void addFirstTagValueOf(QString &target, const QStringList &keys) const; @@ -94,6 +102,8 @@ mutable QString m_wheelchairInfo; mutable QString m_wifiAvailable; QStringList m_tags; + + RouteRelationModel m_relationModel; }; } diff --git a/src/lib/marble/declarative/Placemark.cpp b/src/lib/marble/declarative/Placemark.cpp --- a/src/lib/marble/declarative/Placemark.cpp +++ b/src/lib/marble/declarative/Placemark.cpp @@ -589,6 +589,17 @@ emit nameChanged(); } +void Placemark::setRelations(const QVector &relations) +{ + m_relationModel.setRelations(relations); + emit relationModelChanged(); +} + +RouteRelationModel* Placemark::relationModel() +{ + return &m_relationModel; +} + double Placemark::longitude() const { return m_placemark.coordinate().longitude(GeoDataCoordinates::Degree); diff --git a/src/lib/marble/declarative/RouteRelationModel.h b/src/lib/marble/declarative/RouteRelationModel.h new file mode 100644 --- /dev/null +++ b/src/lib/marble/declarative/RouteRelationModel.h @@ -0,0 +1,46 @@ +// +// 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 MARBLE_DECLARATIVE_ROUTERELATIONMODEL_H +#define MARBLE_DECLARATIVE_ROUTERELATIONMODEL_H + +#include +#include + +#include "GeoDataRelation.h" + +namespace Marble { + +class RouteRelationModel : public QAbstractListModel +{ + Q_OBJECT +public: + enum RelationRoles { + RelationName = Qt::UserRole + 1 + }; + + RouteRelationModel(QObject* parent = 0); + + void setRelations(const QVector &relations); + + int rowCount(const QModelIndex & parent = QModelIndex()) const; + + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + +protected: + QHash roleNames() const; + +private: + QVector m_relations; +}; + +} + +#endif // ROUTERELATIONMODEL diff --git a/src/lib/marble/declarative/RouteRelationModel.cpp b/src/lib/marble/declarative/RouteRelationModel.cpp new file mode 100644 --- /dev/null +++ b/src/lib/marble/declarative/RouteRelationModel.cpp @@ -0,0 +1,52 @@ +// +// 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 "RouteRelationModel.h" + +namespace Marble { + +RouteRelationModel::RouteRelationModel(QObject *parent) : + QAbstractListModel(parent) +{ + // nothing to do +} + +void RouteRelationModel::setRelations(const QVector &relations) +{ + beginRemoveRows(QModelIndex(), 0, m_relations.count() - 1); + m_relations.clear(); + endRemoveRows(); + + beginInsertRows(QModelIndex(), 0, relations.count() - 1); + m_relations = relations; + endInsertRows(); +} + +int RouteRelationModel::rowCount(const QModelIndex & parent) const +{ + Q_UNUSED(parent); + return m_relations.count(); +} + +QVariant RouteRelationModel::data(const QModelIndex & index, int role) const +{ + if (!index.isValid() || index.row() < 0 || index.row() >= m_relations.count()) + return QVariant(); + + return m_relations.at(index.row())->name(); +} + +QHash RouteRelationModel::roleNames() const { + QHash roles; + roles[RelationName] = "name"; + return roles; +} + +}