Marble

Bookmarks.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2012 Dennis Nienhüser <[email protected]>
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 
23 namespace Marble {
24 
25 Bookmarks::Bookmarks( QObject* parent ) : QObject( parent ),
26  m_marbleQuickItem( nullptr ), m_proxyModel( nullptr )
27 {
28  // nothing to do
29 }
30 
31 MarbleQuickItem *Bookmarks::map()
32 {
33  return m_marbleQuickItem;
34 }
35 
36 void 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 
47 bool 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 
69 Placemark *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 
82 void 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()) {
117  }
118  bookmark.clearOsmData();
119  bookmark.setCoordinate(bookmark.coordinate()); // replace non-point geometries with their center
120  manager->addBookmark( target, bookmark );
121 }
122 
123 void 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 
144 void Bookmarks::updateBookmarkDocument()
145 {
146  if (m_marbleQuickItem) {
147  Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager();
148  m_treeModel.setRootDocument( manager->document() );
149  }
150 }
151 
152 BookmarksModel *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 
167 BookmarksModel::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 
175 int BookmarksModel::count() const
176 {
177  return rowCount();
178 }
179 
180 qreal BookmarksModel::longitude( int idx ) const
181 {
182  if ( idx >= 0 && idx < rowCount() ) {
183  QVariant const value = data( index( idx, 0 ), Marble::MarblePlacemarkModel::CoordinateRole );
184  Marble::GeoDataCoordinates const coordinates = value.value<Marble::GeoDataCoordinates>();
185  return coordinates.longitude( Marble::GeoDataCoordinates::Degree );
186  }
187  return 0.0;
188 }
189 
190 qreal BookmarksModel::latitude( int idx ) const
191 {
192  if ( idx >= 0 && idx < rowCount() ) {
193  QVariant const value = data( index( idx, 0 ), Marble::MarblePlacemarkModel::CoordinateRole );
194  Marble::GeoDataCoordinates const coordinates = value.value<Marble::GeoDataCoordinates>();
195  return coordinates.latitude( Marble::GeoDataCoordinates::Degree );
196  }
197  return 0.0;
198 }
199 
200 QString 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"
QString toString() const
return a string representation of the coordinate this is a convenience function which uses the defaul...
A 3d point representation.
void addBookmark(GeoDataContainer *folder, const GeoDataPlacemark &bookmark)
add bookmark in a folder
T value() const const
QString trimmed() const const
void setSourceModel(QAbstractItemModel *model) override
void setName(const QString &value)
Set a new name for this feature.
qreal longitude(GeoDataCoordinates::Unit unit) const
retrieves the longitude of the GeoDataCoordinates object use the unit parameter to switch between Rad...
A container that is used to arrange other GeoDataFeatures.
Definition: GeoDataFolder.h:33
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
This class is responsible for loading the book mark objects from the files and various book mark oper...
@ ObjectPointerRole
The pointer to a specific object.
QVariant data(int role) const const
QString name() const
The name of the feature.
qreal latitude(GeoDataCoordinates::Unit unit) const
retrieves the latitude of the GeoDataCoordinates object use the unit parameter to switch between Radi...
bool isEmpty() const const
@ Decimal
"Decimal" notation (base-10)
GeoDataCoordinates coordinate(const QDateTime &dateTime=QDateTime(), bool *iconAtCoordinates=nullptr) const
Return the coordinates of the placemark at time dateTime as a GeoDataCoordinates.
A container for Features, Styles and in the future Schemas.
@ CoordinateRole
The GeoDataCoordinates coordinate.
Binds a QML item to a specific geodetic location in screen coordinates.
a class representing a point of interest on the map
A base class that can hold GeoDataFeatures.
void setCoordinate(qreal longitude, qreal latitude, qreal altitude=0, GeoDataCoordinates::Unit _unit=GeoDataCoordinates::Radian)
Set the coordinate of the placemark in longitude and latitude.
QVector< GeoDataFolder * > folderList() const
A convenience function that returns all folders in this container.
GeoDataFolder * addNewBookmarkFolder(GeoDataContainer *container, const QString &name)
add a folder
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Oct 4 2023 04:09:41 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.