Marble

Bookmarks.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2012 Dennis Nienhüser <nienhueser@kde.org>
4//
5
6#include "Bookmarks.h"
7
8#include "BookmarkManager.h"
9#include "GeoDataDocument.h"
10#include "GeoDataFolder.h"
11#include "GeoDataPlacemark.h"
12#include "GeoDataTreeModel.h"
13#include "GeoDataTypes.h"
14#include "MarbleModel.h"
15#include "MarblePlacemarkModel.h"
16#include "MarbleQuickItem.h"
17#include "Planet.h"
18#include "kdescendantsproxymodel.h"
19
20namespace Marble
21{
22
23Bookmarks::Bookmarks(QObject *parent)
24 : QObject(parent)
25{
26 // nothing to do
27}
28
29MarbleQuickItem *Bookmarks::map()
30{
31 return m_marbleQuickItem;
32}
33
34void Bookmarks::setMap(MarbleQuickItem *item)
35{
36 m_marbleQuickItem = item;
37 if (item) {
38 connect(item->model()->bookmarkManager(), SIGNAL(bookmarksChanged()), this, SLOT(updateBookmarkDocument()));
39 }
40 updateBookmarkDocument();
41 Q_EMIT modelChanged();
42}
43
44bool Bookmarks::isBookmark(qreal longitude, qreal latitude) const
45{
46 if (!m_marbleQuickItem || !m_marbleQuickItem->model()->bookmarkManager()) {
47 return false;
48 }
49
50 Marble::BookmarkManager *manager = m_marbleQuickItem->model()->bookmarkManager();
51 Marble::GeoDataDocument *bookmarks = manager->document();
52 Marble::GeoDataCoordinates const compareTo(longitude, latitude, 0.0, Marble::GeoDataCoordinates::Degree);
53
54 qreal planetRadius = m_marbleQuickItem->model()->planet()->radius();
55 for (const Marble::GeoDataFolder *folder : bookmarks->folderList()) {
56 for (const Marble::GeoDataPlacemark *const placemark : folder->placemarkList()) {
57 if (placemark->coordinate().sphericalDistanceTo(compareTo) * planetRadius < 5) {
58 return true;
59 }
60 }
61 }
62
63 return false;
64}
65
66Placemark *Bookmarks::placemark(int row)
67{
68 auto placemark = new Placemark;
69
70 QModelIndex index = model()->index(row, 0);
71 auto object = model()->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject *>();
72 if (auto geoDataPlacemark = geodata_cast<GeoDataPlacemark>(object)) {
73 placemark->setGeoDataPlacemark(*geoDataPlacemark);
74 }
75
76 return placemark;
77}
78
79void Bookmarks::addBookmark(Placemark *placemark, const QString &folderName)
80{
81 if (!m_marbleQuickItem || !m_marbleQuickItem->model()->bookmarkManager()) {
82 return;
83 }
84
85 Marble::BookmarkManager *manager = m_marbleQuickItem->model()->bookmarkManager();
86 Marble::GeoDataDocument *bookmarks = manager->document();
87 Marble::GeoDataContainer *target = nullptr;
88 for (Marble::GeoDataFolder *const folder : bookmarks->folderList()) {
89 if (folder->name() == folderName) {
90 target = folder;
91 break;
92 }
93 }
94
95 if (!target) {
96 manager->addNewBookmarkFolder(bookmarks, folderName);
97
98 for (Marble::GeoDataFolder *const folder : bookmarks->folderList()) {
99 if (folder->name() == folderName) {
100 target = folder;
101 break;
102 }
103 }
104
105 Q_ASSERT(target);
106 }
107
108 Marble::GeoDataPlacemark bookmark = placemark->placemark();
109 if (bookmark.name().isEmpty()) {
110 bookmark.setName(placemark->address());
111 }
112 if (bookmark.name().isEmpty()) {
113 bookmark.setName(bookmark.coordinate().toString(GeoDataCoordinates::Decimal).trimmed());
114 }
115 bookmark.clearOsmData();
116 bookmark.setCoordinate(bookmark.coordinate()); // replace non-point geometries with their center
117 manager->addBookmark(target, bookmark);
118}
119
120void Bookmarks::removeBookmark(qreal longitude, qreal latitude)
121{
122 if (!m_marbleQuickItem || !m_marbleQuickItem->model()->bookmarkManager()) {
123 return;
124 }
125
126 Marble::BookmarkManager *manager = m_marbleQuickItem->model()->bookmarkManager();
127 Marble::GeoDataDocument *bookmarks = manager->document();
128 Marble::GeoDataCoordinates const compareTo(longitude, latitude, 0.0, Marble::GeoDataCoordinates::Degree);
129
130 qreal planetRadius = m_marbleQuickItem->model()->planet()->radius();
131 for (const Marble::GeoDataFolder *folder : bookmarks->folderList()) {
132 for (Marble::GeoDataPlacemark *placemark : folder->placemarkList()) {
133 if (placemark->coordinate().sphericalDistanceTo(compareTo) * planetRadius < 5) {
134 manager->removeBookmark(placemark);
135 return;
136 }
137 }
138 }
139}
140
141void Bookmarks::updateBookmarkDocument()
142{
143 if (m_marbleQuickItem) {
144 Marble::BookmarkManager *manager = m_marbleQuickItem->model()->bookmarkManager();
145 m_treeModel.setRootDocument(manager->document());
146 }
147}
148
149BookmarksModel *Bookmarks::model()
150{
151 if (!m_proxyModel && m_marbleQuickItem && m_marbleQuickItem->model()->bookmarkManager()) {
152 auto flattener = new KDescendantsProxyModel(this);
153 flattener->setSourceModel(&m_treeModel);
154
155 m_proxyModel = new BookmarksModel(this);
156 m_proxyModel->setFilterFixedString(QString::fromLatin1(Marble::GeoDataTypes::GeoDataPlacemarkType));
157 m_proxyModel->setFilterKeyColumn(1);
158 m_proxyModel->setSourceModel(flattener);
159 }
160
161 return m_proxyModel;
162}
163
164BookmarksModel::BookmarksModel(QObject *parent)
165 : QSortFilterProxyModel(parent)
166{
167 connect(this, SIGNAL(layoutChanged()), this, SIGNAL(countChanged()));
168 connect(this, SIGNAL(modelReset()), this, SIGNAL(countChanged()));
169 connect(this, SIGNAL(rowsInserted(QModelIndex, int, int)), this, SIGNAL(countChanged()));
170 connect(this, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SIGNAL(countChanged()));
171}
172
173int BookmarksModel::count() const
174{
175 return rowCount();
176}
177
178qreal BookmarksModel::longitude(int idx) const
179{
180 if (idx >= 0 && idx < rowCount()) {
181 QVariant const value = data(index(idx, 0), Marble::MarblePlacemarkModel::CoordinateRole);
182 auto const coordinates = value.value<Marble::GeoDataCoordinates>();
183 return coordinates.longitude(Marble::GeoDataCoordinates::Degree);
184 }
185 return 0.0;
186}
187
188qreal BookmarksModel::latitude(int idx) const
189{
190 if (idx >= 0 && idx < rowCount()) {
191 QVariant const value = data(index(idx, 0), Marble::MarblePlacemarkModel::CoordinateRole);
192 auto const coordinates = value.value<Marble::GeoDataCoordinates>();
193 return coordinates.latitude(Marble::GeoDataCoordinates::Degree);
194 }
195 return 0.0;
196}
197
198QString BookmarksModel::name(int idx) const
199{
200 if (idx >= 0 && idx < rowCount()) {
201 return data(index(idx, 0)).toString();
202 }
203 return {};
204}
205
206}
207
208#include "moc_Bookmarks.cpp"
This file contains the headers for MarbleModel.
This class is responsible for loading the book mark objects from the files and various book mark oper...
GeoDataFolder * addNewBookmarkFolder(GeoDataContainer *container, const QString &name)
add a folder
void addBookmark(GeoDataContainer *folder, const GeoDataPlacemark &bookmark)
add bookmark in a folder
A base class that can hold GeoDataFeatures.
QList< GeoDataFolder * > folderList() const
A convenience function that returns all folders in this container.
A 3d point representation.
QString toString() const
return a string representation of the coordinate this is a convenience function which uses the defaul...
A container for Features, Styles and in the future Schemas.
QString name() const
The name of the feature.
void setName(const QString &value)
Set a new name for this feature.
A container that is used to arrange other GeoDataFeatures.
a class representing a point of interest on the map
GeoDataCoordinates coordinate(const QDateTime &dateTime=QDateTime(), bool *iconAtCoordinates=nullptr) const
Return the coordinates of the placemark at time dateTime as a GeoDataCoordinates.
void setCoordinate(qreal longitude, qreal latitude, qreal altitude=0, GeoDataCoordinates::Unit _unit=GeoDataCoordinates::Radian)
Set the coordinate of the placemark in longitude and latitude.
@ CoordinateRole
The GeoDataCoordinates coordinate.
Binds a QML item to a specific geodetic location in screen coordinates.
QVariant data(int role) const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
QString trimmed() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
T value() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 8 2024 12:02:42 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.