File indexing completed on 2024-05-05 03:49:16
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2012 Dennis Nienhüser <nienhueser@kde.org> 0004 // 0005 0006 #include "Bookmarks.h" 0007 0008 #include "Planet.h" 0009 #include "MarbleQuickItem.h" 0010 #include "MarbleModel.h" 0011 #include "MarblePlacemarkModel.h" 0012 #include "BookmarkManager.h" 0013 #include "GeoDataDocument.h" 0014 #include "GeoDataPlacemark.h" 0015 #include "GeoDataFolder.h" 0016 #include "GeoDataTypes.h" 0017 #include "GeoDataExtendedData.h" 0018 #include "GeoDataTreeModel.h" 0019 #include "kdescendantsproxymodel.h" 0020 #include "osm/OsmPlacemarkData.h" 0021 0022 0023 namespace Marble { 0024 0025 Bookmarks::Bookmarks( QObject* parent ) : QObject( parent ), 0026 m_marbleQuickItem( nullptr ), m_proxyModel( nullptr ) 0027 { 0028 // nothing to do 0029 } 0030 0031 MarbleQuickItem *Bookmarks::map() 0032 { 0033 return m_marbleQuickItem; 0034 } 0035 0036 void Bookmarks::setMap( MarbleQuickItem* item ) 0037 { 0038 m_marbleQuickItem = item; 0039 if (item) { 0040 connect(item->model()->bookmarkManager(), SIGNAL(bookmarksChanged()), 0041 this, SLOT(updateBookmarkDocument())); 0042 } 0043 updateBookmarkDocument(); 0044 emit modelChanged(); 0045 } 0046 0047 bool Bookmarks::isBookmark( qreal longitude, qreal latitude ) const 0048 { 0049 if ( !m_marbleQuickItem || !m_marbleQuickItem->model()->bookmarkManager() ) { 0050 return false; 0051 } 0052 0053 Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager(); 0054 Marble::GeoDataDocument *bookmarks = manager->document(); 0055 Marble::GeoDataCoordinates const compareTo( longitude, latitude, 0.0, Marble::GeoDataCoordinates::Degree ); 0056 0057 qreal planetRadius = m_marbleQuickItem->model()->planet()->radius(); 0058 for( const Marble::GeoDataFolder* folder: bookmarks->folderList() ) { 0059 for( const Marble::GeoDataPlacemark * const placemark: folder->placemarkList() ) { 0060 if (placemark->coordinate().sphericalDistanceTo(compareTo) * planetRadius < 5) { 0061 return true; 0062 } 0063 } 0064 } 0065 0066 return false; 0067 } 0068 0069 Placemark *Bookmarks::placemark(int row) 0070 { 0071 Placemark* placemark = new Placemark; 0072 0073 QModelIndex index = model()->index(row, 0); 0074 GeoDataObject *object = model()->data(index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>(); 0075 if (GeoDataPlacemark *geoDataPlacemark = geodata_cast<GeoDataPlacemark>(object)) { 0076 placemark->setGeoDataPlacemark(*geoDataPlacemark); 0077 } 0078 0079 return placemark; 0080 } 0081 0082 void Bookmarks::addBookmark(Placemark *placemark, const QString &folderName ) 0083 { 0084 if ( !m_marbleQuickItem || !m_marbleQuickItem->model()->bookmarkManager() ) { 0085 return; 0086 } 0087 0088 Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager(); 0089 Marble::GeoDataDocument *bookmarks = manager->document(); 0090 Marble::GeoDataContainer *target = nullptr; 0091 for( Marble::GeoDataFolder* const folder: bookmarks->folderList() ) { 0092 if ( folder->name() == folderName ) { 0093 target = folder; 0094 break; 0095 } 0096 } 0097 0098 if ( !target ) { 0099 manager->addNewBookmarkFolder( bookmarks, folderName ); 0100 0101 for( Marble::GeoDataFolder* const folder: bookmarks->folderList() ) { 0102 if ( folder->name() == folderName ) { 0103 target = folder; 0104 break; 0105 } 0106 } 0107 0108 Q_ASSERT( target ); 0109 } 0110 0111 Marble::GeoDataPlacemark bookmark = placemark->placemark(); 0112 if (bookmark.name().isEmpty()) { 0113 bookmark.setName(placemark->address()); 0114 } 0115 if (bookmark.name().isEmpty()) { 0116 bookmark.setName(bookmark.coordinate().toString(GeoDataCoordinates::Decimal).trimmed()); 0117 } 0118 bookmark.clearOsmData(); 0119 bookmark.setCoordinate(bookmark.coordinate()); // replace non-point geometries with their center 0120 manager->addBookmark( target, bookmark ); 0121 } 0122 0123 void Bookmarks::removeBookmark( qreal longitude, qreal latitude ) 0124 { 0125 if ( !m_marbleQuickItem || !m_marbleQuickItem->model()->bookmarkManager() ) { 0126 return; 0127 } 0128 0129 Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager(); 0130 Marble::GeoDataDocument *bookmarks = manager->document(); 0131 Marble::GeoDataCoordinates const compareTo( longitude, latitude, 0.0, Marble::GeoDataCoordinates::Degree ); 0132 0133 qreal planetRadius = m_marbleQuickItem->model()->planet()->radius(); 0134 for( const Marble::GeoDataFolder* folder: bookmarks->folderList() ) { 0135 for( Marble::GeoDataPlacemark * placemark: folder->placemarkList() ) { 0136 if (placemark->coordinate().sphericalDistanceTo(compareTo) * planetRadius < 5) { 0137 manager->removeBookmark( placemark ); 0138 return; 0139 } 0140 } 0141 } 0142 } 0143 0144 void Bookmarks::updateBookmarkDocument() 0145 { 0146 if (m_marbleQuickItem) { 0147 Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager(); 0148 m_treeModel.setRootDocument( manager->document() ); 0149 } 0150 } 0151 0152 BookmarksModel *Bookmarks::model() 0153 { 0154 if ( !m_proxyModel && m_marbleQuickItem && m_marbleQuickItem->model()->bookmarkManager() ) { 0155 KDescendantsProxyModel* flattener = new KDescendantsProxyModel( this ); 0156 flattener->setSourceModel(&m_treeModel); 0157 0158 m_proxyModel = new BookmarksModel( this ); 0159 m_proxyModel->setFilterFixedString( Marble::GeoDataTypes::GeoDataPlacemarkType ); 0160 m_proxyModel->setFilterKeyColumn( 1 ); 0161 m_proxyModel->setSourceModel( flattener ); 0162 } 0163 0164 return m_proxyModel; 0165 } 0166 0167 BookmarksModel::BookmarksModel( QObject *parent ) : QSortFilterProxyModel( parent ) 0168 { 0169 connect( this, SIGNAL(layoutChanged()), this, SIGNAL(countChanged()) ); 0170 connect( this, SIGNAL(modelReset()), this, SIGNAL(countChanged()) ); 0171 connect( this, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(countChanged()) ); 0172 connect( this, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(countChanged()) ); 0173 } 0174 0175 int BookmarksModel::count() const 0176 { 0177 return rowCount(); 0178 } 0179 0180 qreal BookmarksModel::longitude( int idx ) const 0181 { 0182 if ( idx >= 0 && idx < rowCount() ) { 0183 QVariant const value = data( index( idx, 0 ), Marble::MarblePlacemarkModel::CoordinateRole ); 0184 Marble::GeoDataCoordinates const coordinates = value.value<Marble::GeoDataCoordinates>(); 0185 return coordinates.longitude( Marble::GeoDataCoordinates::Degree ); 0186 } 0187 return 0.0; 0188 } 0189 0190 qreal BookmarksModel::latitude( int idx ) const 0191 { 0192 if ( idx >= 0 && idx < rowCount() ) { 0193 QVariant const value = data( index( idx, 0 ), Marble::MarblePlacemarkModel::CoordinateRole ); 0194 Marble::GeoDataCoordinates const coordinates = value.value<Marble::GeoDataCoordinates>(); 0195 return coordinates.latitude( Marble::GeoDataCoordinates::Degree ); 0196 } 0197 return 0.0; 0198 } 0199 0200 QString BookmarksModel::name( int idx ) const 0201 { 0202 if ( idx >= 0 && idx < rowCount() ) { 0203 return data( index( idx, 0 ) ).toString(); 0204 } 0205 return QString(); 0206 } 0207 0208 } 0209 0210 #include "moc_Bookmarks.cpp"