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