#include "maptile.h"
+class SceneCoordinate;
+/**
+* @brief Map scene for storing MapTile items
+*
+* @author Sami Rämö - sami.ramo (at) ixonos.com
+*/
class MapScene : public QGraphicsScene
{
+ Q_OBJECT
public:
-
+ /**
+ * @brief Constructor
+ *
+ * Scene size is set to the amount of pixels on closest zoom level
+ * @param parent Parent
+ */
MapScene(QObject *parent = 0);
- void addMapTile(MapTile *mapTile);
+
+/*******************************************************************************
+ * MEMBER FUNCTIONS AND SLOTS
+ ******************************************************************************/
+public:
+ /**
+ * @brief Create and add new MapTile to MapScene
+ *
+ * If there is a tile with same parameters already in the scene, it will be removed
+ * before adding the new tile.
+ *
+ * @param zoomLevel Zoom level of the new tile
+ * @param tileNumber X & Y indexes of the tile
+ * @param image Map tile picture
+ * @param viewZoomLevel Current view zoom level (for setting the zValue)
+ */
+ void addTile(int zoomLevel, QPoint tileNumber, const QPixmap &image, int viewZoomLevel);
+
+ /**
+ * @brief Enqueue stacked tiles removal request
+ *
+ * Removal is triggered after events have been processed so the UI
+ * stays more responsive
+ * @param newTile New tile, which area under it is inspected
+ */
+ void enqueueRemoveStackedTiles(MapTile *newTile);
+
+ /**
+ * @brief Calculates scene horizontal resolution in given latitude
+ *
+ * @param latitude Resolution is calculated in this latitude
+ * @returns Scene horizontal resolution (meters/pixel)
+ */
+ static qreal horizontalResolutionAtLatitude(double latitude);
+
+ /**
+ * @brief Returns tile mathcing given hash key
+ *
+ * @param hashKey
+ * @return Returns tile matching given hash key, or 0 if no match found
+ */
+ MapTile* tileInScene(QString hashKey);
+
+ /**
+ * @brief Remove tiles which are out of view bounds.
+ *
+ * Does not remove tiles which are duplicated from current view to opposite side of
+ * the scene.
+ *
+ * @param tilesGrid Current tiles grid
+ * @param zoomLevel Current zoom level
+ */
+ void removeOutOfViewTiles(QRect tilesGrid, int zoomLevel);
+
+ /**
+ * @brief Remove tiles which are stacked.
+ *
+ * Iterate through tiles which are under this map tile and remove tiles which
+ * are fully obscured by this new tile. Tiles which are only partially
+ * obscured by this new tile are not checked, and thus deleted, because of
+ * the required complexity of the algorithm and processing power. Those tiles
+ * will be removed when they go out of the view area caused by scrolling or
+ * zooming in enough.
+ *
+ * @param newTile new tile covering old tiles
+ */
+ void removeStackedTiles(MapTile *newTile);
+
+ /**
+ * @brief Remove tile.
+ *
+ * Removes tile from scene and list of current tiles in scene.
+ * @param tile MapTile to remove
+ */
+ void removeTile(MapTile *tile);
+
+ /**
+ * @brief Set allowed amount of exceeding the world vertical limits
+ *
+ * Limit is set so that vertical limits of the world can be scrolled to middle of
+ * the view.
+ *
+ * @param viewHeight Height of the view
+ * @param zoomLevel Current zoom level
+ */
+ void setSceneVerticalOverlap(int viewHeight, int zoomLevel);
+
+ /**
+ * @brief Set drawing order of all tiles in the scene
+ *
+ * Check MapTile::setSceneLevel for more information.
+ * @param zoomLevel Current zoom level
+ */
+ void setTilesDrawingLevels(int zoomLevel);
+
+ /**
+ * @brief Setter for m_viewTilesGrid
+ *
+ * @param grid Tile grid
+ */
+ void setTilesGrid(QRect grid);
+
+ /**
+ * @brief Setter for m_zoomLevel
+ *
+ * @param zoomLevel Zoom level
+ */
+ void setZoomLevel(int zoomLevel);
+
+ /**
+ * @brief Span items (others than MapTile) to opposite side of the scene
+ *
+ * @param viewSceneRect Scene area which is currently drawn on the view
+ */
+ void spanItems(QRectF viewSceneRect);
+
+ /**
+ * @brief Save new tiles scene rect
+ *
+ * Tiles scene rect must be saved to local scope whenever it changes because
+ * it is used by removal algorithms and some of the algorithms are run
+ * delayed so the actual tiles scene rect may change before the cleanup
+ * algorithm is run.
+ *
+ * @param tilesSceneRect New view rect
+ */
+ void tilesSceneRectUpdated(QRect tilesSceneRect);
+
+private:
+ /**
+ * @brief Move map items horizontally in the scene (not MapTile items)
+ *
+ * MapTile items are not moved!
+ *
+ * Move items which intersect the given rect.
+ *
+ * @param from Items colliding given rect are moved
+ * @param distance How much to move each item
+ */
+ void moveIntersectingItemsHorizontally(QRect from, int distance);
+
+private slots:
+ /**
+ * @brief Remove tiles from other than current zoom levels
+ *
+ * Does remove tiles only if all tiles in current m_viewTilesGrid are in the scene.
+ */
+ void removeOtherLevelTiles();
+
+ /**
+ * @brief Slot for running next queued removal of stacked tiles
+ *
+ */
+ void runNextStackedTilesRemoval();
+
+/*******************************************************************************
+ * DATA MEMBERS
+ ******************************************************************************/
+private:
+ bool m_isRemoveStackedTilesRunning; ///< Is singleshot timer already running
+ int m_zoomLevel; ///< Current zoom level
+ QHash<QString, MapTile *> m_mapTilesInScene; ///< List of map tiles in map scene
+ QList<MapTile *> m_removeStackedTilesList; ///< "Queue" for stacked tiles removal requests
+ QRect m_tilesSceneRect; ///< Current viewable area
+ QRect m_viewTilesGrid; ///< Current grid of tiles
};
#endif // MAPSCENE_H