File indexing completed on 2024-05-05 04:22:10

0001 // SPDX-FileCopyrightText: 2019-2021 Johannes Zarl-Zierl <johannes@zarl-zierl.at>
0002 //
0003 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 
0005 #ifndef MAP_GEOCLUSTER_H
0006 #define MAP_GEOCLUSTER_H
0007 
0008 #include "enums.h"
0009 
0010 #include <DB/ImageInfoPtr.h>
0011 
0012 #include <marble/GeoDataCoordinates.h>
0013 #include <marble/GeoDataLatLonAltBox.h>
0014 
0015 #include <QRegion>
0016 
0017 namespace Marble
0018 {
0019 class GeoDataLatLonBox;
0020 class GeoPainter;
0021 class ViewportParams;
0022 }
0023 
0024 namespace ImageManager
0025 {
0026 class ThumbnailCache;
0027 }
0028 
0029 namespace Map
0030 {
0031 
0032 class GeoCoordinates;
0033 
0034 struct ThumbnailParams {
0035     const QPixmap &alternatePixmap;
0036     const ImageManager::ThumbnailCache *cache;
0037     const int thumbnailSizePx;
0038 };
0039 
0040 class GeoCluster
0041 {
0042 public:
0043     explicit GeoCluster(int lvl);
0044     virtual ~GeoCluster() = default;
0045 
0046     void addSubCluster(const GeoCluster *subCluster);
0047     /**
0048      * @brief boundingRegion computes the bounding region for the GeoCluster
0049      * All images in the GeoCluster are within the boundingRegion.
0050      * The result is only computed once at the first call to the method.
0051      * @return a GeoDataLatLonBox containing all images in all sub-clusters.
0052      */
0053     virtual Marble::GeoDataLatLonAltBox boundingRegion() const;
0054     /**
0055      * @brief center
0056      * @return the center of the boundingRegion
0057      */
0058     virtual Marble::GeoDataCoordinates center() const;
0059 
0060     /**
0061      * @brief regionForPoint checks whether the given screen coordinates match the GeoCluster.
0062      * The corresponding bounding box is computed the same way as in the render method,
0063      * matching against the GeoClusters own bounding box or against its sub-clusters as appropriate.
0064      * @param pos
0065      * @return The matching GeoCluster if the position matches, or a \c nullptr otherwise.
0066      */
0067     virtual const GeoCluster *regionForPoint(QPoint pos) const;
0068 
0069     void render(Marble::GeoPainter *painter, const Marble::ViewportParams &viewPortParams, const ThumbnailParams &thumbs, MapStyle style) const;
0070     /**
0071      * @brief size
0072      * The result is only computed once at the first call to the method.
0073      * @return the number of images in all sub-clusters
0074      */
0075     virtual int size() const;
0076 
0077     /**
0078      * @brief isEmpty
0079      * @return \c true, if size is 0, \c false otherwise.
0080      */
0081     bool isEmpty() const;
0082 
0083 private:
0084     mutable int m_size = 0;
0085     mutable QRegion m_renderedRegion = {}; ///< If currently drawn, contains the rendered region. Otherwise the region is empty.
0086     QList<const GeoCluster *> m_subClusters = {};
0087 
0088 protected:
0089     mutable Marble::GeoDataLatLonAltBox m_boundingRegion;
0090     const int m_level;
0091     /**
0092      * @brief renderSubItems renders the sub-items of this GeoCluster.
0093      * @param painter
0094      * @param viewPortParams
0095      * @param thumbs handle for the thumbnail cache and an alternate pixmap
0096      * @param style
0097      */
0098     virtual void renderSubItems(Marble::GeoPainter *painter, const Marble::ViewportParams &viewPortParams, const ThumbnailParams &thumbs, MapStyle style) const;
0099 };
0100 
0101 /**
0102  * @brief The GeoBin class holds a number of images that are grouped into the same bin.
0103  * I.e. they are in the direct vicinity of each other.
0104  */
0105 class GeoBin : public GeoCluster
0106 {
0107 public:
0108     GeoBin();
0109     void addImage(DB::ImageInfoPtr image);
0110     Marble::GeoDataLatLonAltBox boundingRegion() const override;
0111     int size() const override;
0112 
0113 private:
0114     mutable QHash<DB::ImageInfoPtr, QPixmap> m_scaledThumbnailCache; ///< local cache for scaled thumbnails
0115     mutable int m_thumbnailSizePx; ///< pixel size of thumbnails in the cache
0116     QList<DB::ImageInfoPtr> m_images;
0117 
0118 protected:
0119     void renderSubItems(Marble::GeoPainter *painter, const Marble::ViewportParams &viewPortParams, const ThumbnailParams &thumbs, MapStyle style) const override;
0120 };
0121 
0122 /**
0123  * @brief extendGeoDataLatLonBox extend the given GeoDataLatLonBox to encompass the given coordinates.
0124  * @param box
0125  * @param coords
0126  */
0127 void extendGeoDataLatLonBox(Marble::GeoDataLatLonBox &box, const Map::GeoCoordinates &coords);
0128 } // namespace
0129 
0130 #endif