Added map tile delete methods.
[situare] / src / map / mapengine.h
1 /*
2    Situare - A location system for Facebook
3    Copyright (C) 2010  Ixonos Plc. Authors:
4
5        Sami Rämö - sami.ramo@ixonos.com
6        Jussi Laitinen - jussi.laitinen@ixonos.com
7
8    Situare is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License
10    version 2 as published by the Free Software Foundation.
11
12    Situare is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Situare; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
20    USA.
21 */
22
23 #ifndef MAPENGINE_H
24 #define MAPENGINE_H
25
26 #include <QtCore>
27
28 #include "common.h"
29 #include "mapfetcher.h"
30 #include "mapscene.h"
31 #include "maptile.h"
32
33 /**
34 * @brief Map engine
35 *
36 * Logic for controlling map functionality. Does also include static methods for
37 * converting coordinates.
38 * @author Sami Rämö - sami.ramo (at) ixonos.com
39 */
40 class MapEngine : public QObject
41 {
42     Q_OBJECT
43 public:
44     /**
45     * @brief Constructor
46     *
47     * @param parent Parent
48     */
49     MapEngine(QObject *parent = 0);
50
51     /**
52     * @brief MapEngine initializer
53     *
54     * Set initial location and zoom level for the engine. locationChanged and
55     * zoomLevelChanged signals are emitted, so init should be called after
56     * those signals are connected to MapView.
57     */
58     void init();
59     
60     /**
61     * @brief Convert tile x & y numbers to MapScene coordinates
62     *
63     * @param zoomLevel Zoom level
64     * @param tileNumber x & y numbers of the tile
65     * @return QPoint MapScene coordinate
66     */
67
68     static QPoint convertTileNumberToSceneCoordinate(int zoomLevel, QPoint tileNumber)
69     {
70         int pow = 1 << (MAX_ZOOM_LEVEL - zoomLevel);
71         int x = tileNumber.x() * TILE_SIZE_X * pow;
72         int y = tileNumber.y() * TILE_SIZE_Y * pow;
73
74         return QPoint(x, y);
75     }
76
77     static QPoint convertSceneCoordinateToTileNumber(int zoomLevel, QPointF sceneCoordinate)
78     {
79         int pow = 1 << (MAX_ZOOM_LEVEL - zoomLevel);
80         int x = static_cast<int>(sceneCoordinate.x() / (TILE_SIZE_X*pow));
81         int y = static_cast<int>(sceneCoordinate.y() / (TILE_SIZE_Y*pow));
82
83         return QPoint(x, y);
84     }
85
86     /**
87     * @brief Getter for scene
88     *
89     * @return QGraphicsScene
90     */
91     QGraphicsScene* scene();
92
93     /**
94     * @brief Helper for setting view location based on latitude and longitude
95     * coordinates
96     *
97     * @param latLonCoordinate Latitude & longitude coordinates for location
98     */
99     void setViewLocation(QPointF latLonCoordinate);
100
101     /**
102     * @brief Converts latitude, longitude and zoom to tile x, y values.
103     *
104     * @param latLonCoordinate latitude and longitude values
105     * @return QPoint tile x,y value
106     */
107     static QPointF convertLatLonToSceneCoordinate(QPointF latLonCoordinate)
108     {
109         /// @todo CREATE TEST CASE & CHECK CALCULATION
110         qDebug() << __PRETTY_FUNCTION__;
111
112         qreal longitude = latLonCoordinate.x();
113         qreal latitude = latLonCoordinate.y();
114
115         if ((longitude > MAX_LONGITUDE) || (longitude < MIN_LONGITUDE))
116             return QPoint(UNDEFINED, UNDEFINED);
117         if ((latitude > MAX_LATITUDE) || (latitude < MIN_LATITUDE))
118             return QPoint(UNDEFINED, UNDEFINED);
119
120         qreal z = static_cast<qreal>(1 << MAX_ZOOM_LEVEL);
121
122         qreal x = static_cast<qreal>((longitude + 180.0) / 360.0);
123         qreal y = static_cast<qreal>((1.0 - log(tan(latitude * M_PI / 180.0) + 1.0
124                                     / cos(latitude * M_PI / 180.0)) / M_PI) / 2.0);
125
126         return QPointF(x*z*TILE_SIZE_X, y*z*TILE_SIZE_Y);
127     }
128
129     QRect calculateGrid(QPointF sceneCoordinate);
130
131     void removeTiles();
132
133     int getZoomLevel();
134     void setZoomLevel(int zoomLevel);
135
136 public slots:
137     /**
138     * @brief Slot for setting current view location
139     *
140     * Emits locationChanged signal.
141     * @param sceneCoordinate Scene coordinates for new position
142     */
143     void setLocation(QPointF sceneCoordinate);
144
145     void viewResized(const QSize &size);
146
147 private:
148     /**
149     * @brief Build URL for donwloading single map tile from OpenStreetMap tile server
150     *
151     * @param zoomLevel Zoom level
152     * @param tileNumbers Tile x & y numbers
153     * @return URL for the required tile
154     */
155     QUrl buildURL(int zoomLevel, QPoint tileNumbers);
156
157     /**
158     * @brief Parses given URL to zoom, x and y values. Parsed values are
159     * placed in variables given as parameters.
160     *
161     * @param url url to parse
162     * @param [out] zoom zoom variable
163     * @param [out] x x variable
164     * @param [out] y y variable
165     */
166     void parseURL(const QUrl &url, int &zoom, int &x, int &y);
167
168     int tileMaxValue(int zoomLevel);
169
170
171 private slots:
172     /**
173     * @brief Slot for received map tile images
174     *
175     * Does add MapTile objects to MapScene. Zoom level and location is parsed from URL.
176     * @param url URL of the received image
177     * @param pixmap Received pixmap
178     */
179     void mapImageReceived(const QUrl &url, const QPixmap &pixmap);
180
181     /**
182     * @brief Slot for zooming in
183     *
184     */
185     void zoomIn();
186
187     /**
188     * @brief Slot for zooming out
189     *
190     */
191     void zoomOut();
192
193 signals:
194     /**
195     * @brief Signal for view location change
196     *
197     * @param sceneCoordinate New scene coordinates
198     */
199     void locationChanged(QPointF sceneCoordinate);
200
201     /**
202     * @brief Signal for zoom level change
203     *
204     * @param newZoomLevel New zoom level
205     */
206     void zoomLevelChanged(int newZoomLevel);
207
208     void fetchImage(const QUrl &url);
209
210     void centerToSceneCoordinates(QPointF sceneCoordinate);
211
212 private:
213
214     void calculateTileGrid();
215     //void removeTiles(QList<QString> tiles);
216
217     MapScene *m_mapScene; ///< Scene for map tiles
218     MapFetcher *m_mapFetcher; ///< Fetcher for map tiles
219     int m_zoomLevel; ///< Current zoom level
220     QHash<QString, MapTile *> mapTilesInScene;  ///< List of map tiles in map scene
221     QSize m_viewSize;
222     QPointF m_sceneCoordinate;
223     QQueue<QString> mapTilesInView;
224 };
225
226 #endif // MAPENGINE_H