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 "Planet.h"
9#include "MarbleQuickItem.h"
10#include "MarbleModel.h"
11#include "MarblePlacemarkModel.h"
12#include "BookmarkManager.h"
13#include "GeoDataDocument.h"
14#include "GeoDataPlacemark.h"
15#include "GeoDataFolder.h"
16#include "GeoDataTypes.h"
17#include "GeoDataExtendedData.h"
18#include "GeoDataTreeModel.h"
19#include "kdescendantsproxymodel.h"
20#include "osm/OsmPlacemarkData.h"
21
22
23namespace Marble {
24
25Bookmarks::Bookmarks( QObject* parent ) : QObject( parent ),
26 m_marbleQuickItem( nullptr ), m_proxyModel( nullptr )
27{
28 // nothing to do
29}
30
31MarbleQuickItem *Bookmarks::map()
32{
33 return m_marbleQuickItem;
34}
35
36void Bookmarks::setMap( MarbleQuickItem* item )
37{
38 m_marbleQuickItem = item;
39 if (item) {
40 connect(item->model()->bookmarkManager(), SIGNAL(bookmarksChanged()),
41 this, SLOT(updateBookmarkDocument()));
42 }
43 updateBookmarkDocument();
44 emit modelChanged();
45}
46
47bool Bookmarks::isBookmark( qreal longitude, qreal latitude ) const
48{
49 if ( !m_marbleQuickItem || !m_marbleQuickItem->model()->bookmarkManager() ) {
50 return false;
51 }
52
53 Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager();
54 Marble::GeoDataDocument *bookmarks = manager->document();
55 Marble::GeoDataCoordinates const compareTo( longitude, latitude, 0.0, Marble::GeoDataCoordinates::Degree );
56
57 qreal planetRadius = m_marbleQuickItem->model()->planet()->radius();
58 for( const Marble::GeoDataFolder* folder: bookmarks->folderList() ) {
59 for( const Marble::GeoDataPlacemark * const placemark: folder->placemarkList() ) {
60 if (placemark->coordinate().sphericalDistanceTo(compareTo) * planetRadius < 5) {
61 return true;
62 }
63 }
64 }
65
66 return false;
67}
68
69Placemark *Bookmarks::placemark(int row)
70{
71 Placemark* placemark = new Placemark;
72
73 QModelIndex index = model()->index(row, 0);
74 GeoDataObject *object = model()->data(index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
75 if (GeoDataPlacemark *geoDataPlacemark = geodata_cast<GeoDataPlacemark>(object)) {
76 placemark->setGeoDataPlacemark(*geoDataPlacemark);
77 }
78
79 return placemark;
80}
81
82void Bookmarks::addBookmark(Placemark *placemark, const QString &folderName )
83{
84 if ( !m_marbleQuickItem || !m_marbleQuickItem->model()->bookmarkManager() ) {
85 return;
86 }
87
88 Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager();
89 Marble::GeoDataDocument *bookmarks = manager->document();
90 Marble::GeoDataContainer *target = nullptr;
91 for( Marble::GeoDataFolder* const folder: bookmarks->folderList() ) {
92 if ( folder->name() == folderName ) {
93 target = folder;
94 break;
95 }
96 }
97
98 if ( !target ) {
99 manager->addNewBookmarkFolder( bookmarks, folderName );
100
101 for( Marble::GeoDataFolder* const folder: bookmarks->folderList() ) {
102 if ( folder->name() == folderName ) {
103 target = folder;
104 break;
105 }
106 }
107
108 Q_ASSERT( target );
109 }
110
111 Marble::GeoDataPlacemark bookmark = placemark->placemark();
112 if (bookmark.name().isEmpty()) {
113 bookmark.setName(placemark->address());
114 }
115 if (bookmark.name().isEmpty()) {
116 bookmark.setName(bookmark.coordinate().toString(GeoDataCoordinates::Decimal).trimmed());
117 }
118 bookmark.clearOsmData();
119 bookmark.setCoordinate(bookmark.coordinate()); // replace non-point geometries with their center
120 manager->addBookmark( target, bookmark );
121}
122
123void Bookmarks::removeBookmark( qreal longitude, qreal latitude )
124{
125 if ( !m_marbleQuickItem || !m_marbleQuickItem->model()->bookmarkManager() ) {
126 return;
127 }
128
129 Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager();
130 Marble::GeoDataDocument *bookmarks = manager->document();
131 Marble::GeoDataCoordinates const compareTo( longitude, latitude, 0.0, Marble::GeoDataCoordinates::Degree );
132
133 qreal planetRadius = m_marbleQuickItem->model()->planet()->radius();
134 for( const Marble::GeoDataFolder* folder: bookmarks->folderList() ) {
135 for( Marble::GeoDataPlacemark * placemark: folder->placemarkList() ) {
136 if (placemark->coordinate().sphericalDistanceTo(compareTo) * planetRadius < 5) {
137 manager->removeBookmark( placemark );
138 return;
139 }
140 }
141 }
142}
143
144void Bookmarks::updateBookmarkDocument()
145{
146 if (m_marbleQuickItem) {
147 Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager();
148 m_treeModel.setRootDocument( manager->document() );
149 }
150}
151
152BookmarksModel *Bookmarks::model()
153{
154 if ( !m_proxyModel && m_marbleQuickItem && m_marbleQuickItem->model()->bookmarkManager() ) {
155 KDescendantsProxyModel* flattener = new KDescendantsProxyModel( this );
156 flattener->setSourceModel(&m_treeModel);
157
158 m_proxyModel = new BookmarksModel( this );
159 m_proxyModel->setFilterFixedString( Marble::GeoDataTypes::GeoDataPlacemarkType );
160 m_proxyModel->setFilterKeyColumn( 1 );
161 m_proxyModel->setSourceModel( flattener );
162 }
163
164 return m_proxyModel;
165}
166
167BookmarksModel::BookmarksModel( QObject *parent ) : QSortFilterProxyModel( parent )
168{
169 connect( this, SIGNAL(layoutChanged()), this, SIGNAL(countChanged()) );
170 connect( this, SIGNAL(modelReset()), this, SIGNAL(countChanged()) );
171 connect( this, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(countChanged()) );
172 connect( this, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(countChanged()) );
173}
174
175int BookmarksModel::count() const
176{
177 return rowCount();
178}
179
180qreal BookmarksModel::longitude( int idx ) const
181{
182 if ( idx >= 0 && idx < rowCount() ) {
183 QVariant const value = data( index( idx, 0 ), Marble::MarblePlacemarkModel::CoordinateRole );
185 return coordinates.longitude( Marble::GeoDataCoordinates::Degree );
186 }
187 return 0.0;
188}
189
190qreal BookmarksModel::latitude( int idx ) const
191{
192 if ( idx >= 0 && idx < rowCount() ) {
193 QVariant const value = data( index( idx, 0 ), Marble::MarblePlacemarkModel::CoordinateRole );
195 return coordinates.latitude( Marble::GeoDataCoordinates::Degree );
196 }
197 return 0.0;
198}
199
200QString BookmarksModel::name( int idx ) const
201{
202 if ( idx >= 0 && idx < rowCount() ) {
203 return data( index( idx, 0 ) ).toString();
204 }
205 return QString();
206}
207
208}
209
210#include "moc_Bookmarks.cpp"
This file contains the headers for MarbleModel.
void setSourceModel(QAbstractItemModel *model) override
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.
A 3d point representation.
qreal longitude(GeoDataCoordinates::Unit unit) const
retrieves the longitude of the GeoDataCoordinates object use the unit parameter to switch between Rad...
qreal latitude(GeoDataCoordinates::Unit unit) const
retrieves the latitude of the GeoDataCoordinates object use the unit parameter to switch between Radi...
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
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 Jun 21 2024 12:00:06 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.