Updated changelog
[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        Pekka Nissinen - pekka.nissinen@ixonos.com
8        Ville Tiensuu - ville.tiensuu@ixonos.com
9
10    Situare is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License
12    version 2 as published by the Free Software Foundation.
13
14    Situare is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with Situare; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
22    USA.
23 */
24
25 #ifndef MAPENGINE_H
26 #define MAPENGINE_H
27
28 #include <QtCore>
29
30 class QGraphicsScene;
31
32 class FriendItemsHandler;
33 class GPSLocationItem;
34 class MapFetcher;
35 class MapScene;
36 class MapTile;
37 class OwnLocationItem;
38 class User;
39
40 /**
41 * @brief Map engine
42 *
43 * Logic for controlling map functionality. Does also include static methods for
44 * converting coordinates.
45 *
46 * @author Sami Rämö - sami.ramo (at) ixonos.com
47 * @author Jussi Laitinen - jussi.laitinen (at) ixonos.com
48 * @author Pekka Nissinen - pekka.nissinen (at) ixonos.com
49 * @author Ville Tiensuu - ville.tiensuu (at) ixonos.com
50 */
51 class MapEngine : public QObject
52 {
53     Q_OBJECT
54
55 public:
56     /**
57     * @brief Constructor
58     *
59     * @param parent Parent
60     */
61     MapEngine(QObject *parent = 0);
62
63     /**
64     * @brief Destructor
65     * Saves view of the map to settings file
66     */
67     ~MapEngine();
68
69 /*******************************************************************************
70  * MEMBER FUNCTIONS AND SLOTS
71  ******************************************************************************/
72 public:
73     /**
74       * @brief Coordinates  of the current center point
75       *
76       * @return Current coordinates (latitude & longitude)
77       */
78     QPointF centerGeoCoordinate();
79
80     /**
81     * @brief Convert latitude and longitude to scene coordinates.
82     *
83     * @param latLonCoordinate latitude and longitude values
84     * @return scene coordinate
85     */
86     static QPoint convertLatLonToSceneCoordinate(QPointF latLonCoordinate);
87
88     /**
89     * @brief converts scene coordinates to latitude and longitude
90     *
91     * @param zoomLevel current zoom level
92     * @param sceneCoordinate that will be converted
93     */
94     QPointF convertSceneCoordinateToLatLon(int zoomLevel, QPoint sceneCoordinate);
95
96     /**
97     * @brief Convert MapScene coordinate to tile x & y numbers.
98     *
99     * @param zoomLevel ZoomLevel
100     * @param sceneCoordinate MapScene coordinate
101     * @return QPoint tile x & y numbers
102     */
103     static QPoint convertSceneCoordinateToTileNumber(int zoomLevel, QPoint sceneCoordinate);
104
105     /**
106     * @brief Convert tile x & y numbers to MapScene coordinates
107     *
108     * @param zoomLevel Zoom level
109     * @param tileNumber x & y numbers of the tile
110     * @return QPoint MapScene coordinate
111     */
112     static QPoint convertTileNumberToSceneCoordinate(int zoomLevel, QPoint tileNumber);
113
114     /**
115      * @brief Calculate great-circle distance between two geographic coordinates
116      *
117      * Calculate great-circle distance between two given geographic locations using
118      * haversine formula
119      *
120      * @param firstLocation Coordinates of the first location
121      * @param secondLocation Coordinates of the second location
122      * @return qreal Distance in kilometers
123      */
124     qreal greatCircleDistance(QPointF firstLocation, QPointF secondLocation);
125
126     /**
127     * @brief MapEngine initializer
128     *
129     * Set initial location and zoom level for the engine. locationChanged and
130     * zoomLevelChanged signals are emitted, so init should be called after
131     * those signals are connected to MapView.
132     */
133     void init();
134
135     /**
136       * @brief Return given value translated between min and max
137       *
138       * If given value is not inside the given range (min <= value <= max), then the allowed range
139       * is adder or subtracted until the value does fit in the range.
140       *
141       * @param value Value to be normalized
142       * @param min Minimum allowed value
143       * @param max Maximum allowed value
144       * @return value which is moved to be inside the given limits
145       */
146     static int normalize(int value, int min, int max);
147
148     /**
149     * @brief Getter for scene
150     *
151     * @return QGraphicsScene
152     */
153     QGraphicsScene* scene();
154
155     /**
156     * @brief Sets new zoom level
157     *
158     * @return newZoomLevel value that is set to new zoom level
159     */
160     void setZoomLevel(const int newZoomLevel);
161
162     /**
163     * @brief Return tile path created from tile values.
164     *
165     * @param zoomLevel tile's zoom level
166     * @param x tile's x value
167     * @param y tile's y value
168     * @return QString tile path
169     */
170     static QString tilePath(int zoomLevel, int x, int y);
171
172     /**
173     * @brief Maximum number of individual tiles per side at given zoom level
174     *
175     * @param zoomLevel Zoom level
176     * @return amount of tiles per side at given zoom level
177     */
178     static int tilesPerSide(int zoomLevel);
179
180 public slots:
181     /**
182     * @brief Slot to catch user own location data
183     *
184     * @param user User info
185     */
186     void receiveOwnLocation(User *user);
187
188     /**
189     * @brief Set auto centering.
190     *
191     * @param enabled true if enabled, false otherwise
192     */
193     void setAutoCentering(bool enabled);
194
195     /**
196       * @brief Slot for enabling / disabling GPS
197       *
198       * GPS location item is disabled or enabled based on GPS state
199       *
200       * @param enabled True is GPS is enabled, otherwise false
201       */
202     void setGPSEnabled(bool enabled);
203
204     /**
205     * @brief Slot for setting current view location
206     *
207     * Emits locationChanged signal.
208     * @param sceneCoordinate Scene coordinates for new position
209     */
210     void setLocation(QPoint sceneCoordinate);
211
212     /**
213     * @brief Helper for setting view location based on latitude and longitude
214     * coordinates
215     *
216     * @param latLonCoordinate Latitude & longitude coordinates for location
217     */
218     void setViewLocation(QPointF latLonCoordinate);
219
220     /**
221     * @brief Calculate maximum value for tile in this zoom level.
222     *
223     * @param zoomLevel zoom level
224     * @return int tile's maximum value
225     */
226     static int tileMaxIndex(int zoomLevel);
227
228     /**
229     * @brief Slot for view resizing.
230     *
231     * @param size view size
232     */
233     void viewResized(const QSize &size);
234
235 private:
236     /**
237     * @brief Calculate grid of tile coordinates from current scene coordinate.
238     *
239     * Grid size is calculated from view size and scene's current center coordinate.
240     *
241     * @param sceneCoordinate scene's current center coordinate
242     * @return QRect grid of tile coordinates
243     */
244     QRect calculateTileGrid(QPoint sceneCoordinate);
245
246     /**
247     * @brief Check if auto centering should be disabled.
248     *
249     * @param sceneCoordinate scene's center coordinate
250     * @return bool true if auto centering should be disabled
251     */
252     bool disableAutoCentering(QPoint sceneCoordinate);
253
254     /**
255     * @brief Get new tiles.
256     *
257     * Calculates which tiles has to be fetched. Does emit fetchImage for tiles which
258     * aren't already in the scene.
259     * @param sceneCoordinate scene's center coordinate
260     */
261     void getTiles(QPoint sceneCoordinate);
262
263     /**
264     * @brief Check if auto centering is enabled
265     *
266     * @return true if enabled, false otherwise
267     */
268     bool isAutoCenteringEnabled();
269
270     /**
271     * @brief Check if center tile has changed.
272     *
273     * @param sceneCoordinate scene's center coordinate
274     * @return bool true if center tile changed, false otherwise
275     */
276     bool isCenterTileChanged(QPoint sceneCoordinate);
277
278     /**
279      * @brief Calculate scale at the map center of the map in meters/pixel
280      *
281      * @return qreal Scale of the map in meters/pixel
282      */
283     qreal sceneResolution();
284
285     /**
286       * @brief Set size of tiles grid based on view size
287       *
288       * @param viewSize Current view size
289       */
290     void setTilesGridSize(const QSize &viewSize);
291
292     /**
293     * @brief Updates the current view rect including margins
294     *
295     * Calculates tiles rect in scene based on m_viewTilesGrid and
296     * calls MapScene::viewRectUpdated()
297     */
298     void updateViewTilesSceneRect();
299
300     /**
301       * @brief This method is ran always when the map is zoomed
302       *
303       * This method is the right place for all actions which must be done when ever map is zoomed.
304       */
305     void zoomed();
306
307 private slots:
308     /**
309       * @brief This slot is called after friend items position have been updated
310       *
311       * Does run MapScene::spanItems()
312       */
313     void friendsPositionsUpdated();
314
315     /**
316       * @brief Slot for GPS position updates
317       *
318       * GPS location item is updated and map centered to new location (if automatic
319       * centering is enabled).
320       *
321       * @param position New coordinates from GPS
322       * @param accuracy Accuracy of the GPS fix
323       */
324     void gpsPositionUpdate(QPointF position, qreal accuracy);
325
326     /**
327     * @brief Slot for received map tile images
328     *
329     * Does receive map tile images from MapFetcher. Calls MapScene::addTile() for creating and adding
330     * the actual MapTile object to the MapScene.
331     *
332     * Tile is added also to outside the world horizontal limits, if required, for spanning the map.
333     *
334     * @param zoomLevel Zoom level
335     * @param x Tile x index
336     * @param y Tile y index
337     * @param image Received pixmap
338     */
339     void mapImageReceived(int zoomLevel, int x, int y, const QPixmap &image);
340
341     /**
342     * @brief Slot for actions after view zoom is finished
343     *
344     * Does run removeOutOfViewTiles
345     */
346     void viewZoomFinished();
347
348     /**
349     * @brief Slot for zooming in
350     */
351     void zoomIn();
352
353     /**
354     * @brief Slot for zooming out
355     */
356     void zoomOut();
357
358 /*******************************************************************************
359  * SIGNALS
360  ******************************************************************************/
361 signals:
362     /**
363     * @brief Signals error
364     *
365     * @param error error code
366     */
367     void error(const int error);
368
369     /**
370     * @brief Signal for image fetching.
371     *
372     * @param zoomLevel Zoom level
373     * @param x Tile x index
374     * @param y Tile y index
375     */
376     void fetchImage(int zoomLevel, int x, int y);
377
378     /**
379     * @brief Signal when friend list locations are fetched
380     *
381     * @param friendsList Friends list data
382     */
383     void friendsLocationsReady(QList<User *> &friendsList);
384
385     /**
386     * @brief Request view centering to new locaiton
387     *
388     * @param sceneCoordinate New scene coordinates
389     */
390     void locationChanged(QPoint sceneCoordinate);
391
392     /**
393     * @brief Signal is emitted when location item is clicked.
394     *
395     * @param userIDs list of friends user IDs in the group
396     */
397     void locationItemClicked(const QList<QString> &userIDs);
398
399     /**
400     * @brief Signal to notify map scrolling.
401     */
402     void mapScrolledManually();
403
404     /**
405     * @brief Signal to notify when map is zoomed in to the maxmimum.
406     */
407     void maxZoomLevelReached();
408
409     /**
410     * @brief Signal to notify when map is zoomed out to the minimum.
411     */
412     void minZoomLevelReached();
413
414     /**
415      * @brief Signal to pass the scale of the map to map scale
416      */
417     void newMapResolution(qreal scale);
418
419     /**
420     * @brief Request view changing zoom level
421     *
422     * @param newZoomLevel New zoom level
423     */
424     void zoomLevelChanged(int newZoomLevel);
425
426 /*******************************************************************************
427  * DATA MEMBERS
428  ******************************************************************************/
429 private:
430     bool m_autoCenteringEnabled;   ///< Auto centering enabled
431     bool m_zoomedIn;               ///< Flag for checking if zoomed in when zoom is finished
432
433     int m_zoomLevel;               ///< Current zoom level
434
435     QPoint m_centerTile;           ///< Current center tile
436     QPoint m_lastManualPosition;   ///< Last manually set position in scene coordinate
437     QPoint m_sceneCoordinate;      ///< Current center coordinate
438
439     QRect m_viewTilesGrid;         ///< Current grid of tiles in view (includes margin)
440
441     QSize m_tilesGridSize;         ///< Current size of the tiles grid
442     QSize m_viewSize;              ///< Current view size
443
444     FriendItemsHandler *m_friendItemsHandler;   ///< Handler for friend and group items
445     GPSLocationItem *m_gpsLocationItem;         ///< Item pointing current location from GPS
446     MapFetcher *m_mapFetcher;                   ///< Fetcher for map tiles
447     MapScene *m_mapScene;                       ///< Scene for map tiles
448     OwnLocationItem *m_ownLocation;             ///< Item to show own location
449 };
450
451 #endif // MAPENGINE_H