File indexing completed on 2024-05-05 16:28:22
0001 // SPDX-FileCopyrightText: 2016-2021 Johannes Zarl-Zierl <johannes@zarl-zierl.at> 0002 // SPDX-FileCopyrightText: 2014-2022 Tobias Leupold <tl at stonemx dot de> 0003 // 0004 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 0006 #ifndef MAPVIEW_H 0007 #define MAPVIEW_H 0008 0009 #include "GeoCoordinates.h" 0010 #include "enums.h" 0011 0012 #include <DB/ImageInfo.h> 0013 #include <DB/ImageInfoPtr.h> 0014 #include <kpabase/config-kpa-marble.h> 0015 0016 #include <QList> 0017 #include <QPixmap> 0018 #include <QWidget> 0019 #include <marble/GeoDataLatLonAltBox.h> 0020 #include <marble/LayerInterface.h> 0021 0022 namespace DB 0023 { 0024 class ImageSearchInfo; 0025 } 0026 namespace Marble 0027 { 0028 class MarbleWidget; 0029 } 0030 0031 class QLabel; 0032 class QPushButton; 0033 0034 namespace Map 0035 { 0036 class GeoBin; 0037 class GeoCluster; 0038 0039 /** 0040 * UsageType: determines whether the widget is used as a standalone widget 0041 * or within another widget (e.g. the AnnotationDialog). 0042 * @see Viewer::ViewerWidget::UsageType 0043 */ 0044 enum class UsageType { 0045 InlineMapView, 0046 MapViewWindow 0047 }; 0048 0049 /** 0050 * MapStatus: determines the visibility and text of the status label and the visibility of the 0051 * map, depending on the availability of coordinates of the image(s) that are displayed. 0052 */ 0053 enum class MapStatus { 0054 Loading, 0055 ImageHasCoordinates, 0056 ImageHasNoCoordinates, 0057 NoImagesHaveNoCoordinates, 0058 SomeImagesHaveNoCoordinates, 0059 SearchCoordinates 0060 }; 0061 0062 /** 0063 * \brief A conveniently 64bit word-sized type that holds an imprecise representation of a GeoCoordinate. 0064 * 64 bit allow for enough precision to represent the lat/lon part of the GeoCoordinate of a GeoBin, 0065 * while also having nice properties for being used as a key to a hashmap lookup. 0066 */ 0067 using GeoBinAddress = quint64; 0068 0069 class MapView 0070 : public QWidget, 0071 public Marble::LayerInterface 0072 { 0073 Q_OBJECT 0074 0075 public: 0076 explicit MapView(QWidget *parent, UsageType type); 0077 ~MapView() override = default; 0078 0079 /** 0080 * Removes all images from the map. 0081 */ 0082 void clear(); 0083 0084 /** 0085 * Add an image to the map. 0086 * If you fill the Map using this method, don't forget to call buildImageClusters() afterwards. 0087 * @return \c true, if the image has coordinates and was added, \c false otherwise. 0088 */ 0089 bool addImage(DB::ImageInfoPtr image); 0090 0091 /** 0092 * @brief addImages adds images matching a search info to the map. 0093 * @param searchInfo 0094 */ 0095 void addImages(const DB::ImageSearchInfo &searchInfo); 0096 0097 /** 0098 * @brief buildImageClusters creates the GeoClusters that are used to group images that are close to each other. 0099 * This function is automatically called by addImages(), 0100 * but you need to call it yourself when adding individual images using addImage(). 0101 */ 0102 void buildImageClusters(); 0103 /** 0104 * Sets the map's zoom so that all images on the map are visible. 0105 * If no images have been added, the zoom is not altered. 0106 */ 0107 void zoomToMarkers(); 0108 0109 /** 0110 * Sets the state of the "Show Thumbnails" button on the map's control widget. 0111 */ 0112 void setShowThumbnails(bool state); 0113 /** 0114 * @brief Sets the state of the "Group Thumbnails" button on lthe map's control widget. 0115 */ 0116 void setGroupThumbnails(bool state); 0117 0118 /** 0119 * @brief Returns the appropriate map style depending on the state of the "Show Thumbnails" and "Group Thumbnails" buttons. 0120 * @return the currently active MapStyle 0121 */ 0122 MapStyle mapStyle() const; 0123 0124 /** 0125 * This sets the status label text and it's visibility, as well as the visibilty of the map 0126 * itself to the state indicated by the given MapStatus. 0127 */ 0128 void displayStatus(MapStatus status); 0129 0130 GeoCoordinates::LatLonBox getRegionSelection() const; 0131 bool regionSelected() const; 0132 0133 void mousePressEvent(QMouseEvent *event) override; 0134 void mouseReleaseEvent(QMouseEvent *event) override; 0135 void mouseMoveEvent(QMouseEvent *event) override; 0136 void keyPressEvent(QKeyEvent *event) override; 0137 0138 // LayerInterface: 0139 /** 0140 * @brief renderPosition tells the LayerManager what layers we (currently) want to paint on. 0141 * Part of the LayerInterface; called by the LayerManager. 0142 * @return 0143 */ 0144 QStringList renderPosition() const override; 0145 /** 0146 * @brief Render all markers onto the marbleWidget. 0147 * Part of the LayerInterface; called by the LayerManager. 0148 * @param painter the painter used by the LayerManager 0149 * @param viewPortParams information about the region being in view 0150 * @param renderPos the layer name 0151 * @return \c true (return value is discarded by LayerManager::renderLayers()) 0152 */ 0153 bool render(Marble::GeoPainter *painter, Marble::ViewportParams *viewPortParams, 0154 const QString &renderPos, Marble::GeoSceneLayer * /*nullptr*/) override; 0155 0156 /** 0157 * @return The size of the rendered thumbnails/markers in pixels. 0158 */ 0159 int markerSize() const; 0160 /** 0161 * @brief Set the markerSize for rendering on the map 0162 * Note: Apart from thumbnails, this also affects the size of clusters and therefore the clustering. 0163 * @param markerSizePx a size in pixels 0164 */ 0165 void setMarkerSize(int markerSizePx); 0166 0167 Q_SIGNALS: 0168 void newRegionSelected(Map::GeoCoordinates::LatLonBox coordinates); 0169 void displayStatusChanged(MapStatus); 0170 0171 public Q_SLOTS: 0172 /** 0173 * Centers the map on the coordinates of the given image. 0174 */ 0175 void setCenter(const DB::ImageInfoPtr image); 0176 0177 void increaseMarkerSize(); 0178 void decreaseMarkerSize(); 0179 0180 private Q_SLOTS: 0181 void saveSettings(); 0182 void setLastCenter(); 0183 void updateRegionSelection(const Marble::GeoDataLatLonBox &selection); 0184 #ifndef MARBLE_HAS_regionSelected_NEW 0185 // remove once we don't care about Marble v17.12.3 and older anymore 0186 void updateRegionSelectionOld(const QList<double> &selection); 0187 #endif 0188 0189 private: // Variables 0190 Marble::MarbleWidget *m_mapWidget; 0191 QLabel *m_statusLabel; 0192 QPushButton *m_setLastCenterButton; 0193 GeoCoordinates m_lastCenter; 0194 QWidget *m_kpaButtons; 0195 QWidget *m_floaters; 0196 /** 0197 * If the user clicks a cluster on the map, it gets preselected (and highlighted) before the mouse release event finalizes the selection. 0198 * @see mousePressEvent 0199 * @see mouseReleaseEvent 0200 * @see render 0201 */ 0202 const GeoCluster *m_preselectedCluster = nullptr; 0203 0204 // filled by addImage() 0205 QHash<GeoBinAddress, GeoBin *> m_baseBins; 0206 QList<GeoCluster *> m_geoClusters; 0207 0208 Marble::GeoDataLatLonBox m_markersBox; 0209 bool m_showThumbnails = true; 0210 bool m_groupThumbnails = true; 0211 QPixmap m_pin; 0212 Marble::GeoDataLatLonBox m_regionSelection; 0213 bool m_regionSelected = false; 0214 int m_markerSize; 0215 }; 0216 0217 } 0218 0219 #endif // MAPVIEW_H 0220 0221 // vi:expandtab:tabstop=4 shiftwidth=4: