f7c2687f03cf50a17d7710a0d1201f808ec5ac57
[situare] / src / map / mapengine.cpp
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 #include <QDebug>
24 #include <QString>
25 #include <QStringList>
26 #include <QUrl>
27
28 #include "mapengine.h"
29 #include "maptile.h"
30 //#include "mapscene.h"
31
32 #include <QtCore>
33 #include <QtGlobal>
34
35 MapEngine::MapEngine(MapView *mapView, QWidget *parent)
36     : QObject(parent)
37 {
38     m_mapView = mapView;
39     m_mapScene = new MapScene(this);
40     mapView->setScene(m_mapScene);
41     m_zoomLevel = 14;
42
43     m_mapFetcher = new MapFetcher(new QNetworkAccessManager(this), this);
44     connect(m_mapFetcher, SIGNAL(mapImageReceived(QUrl,QPixmap)), this,
45             SLOT(mapImageReceived(QUrl, QPixmap)));
46 }
47
48 /**
49   * @todo Create URL builder method
50   * QUrl buildURL(zoomLevel, QPoint tileNumbers)
51   */
52 void MapEngine::setViewLocation(QPointF latLonCoordinate)
53 {
54     m_mapView->setZoomLevel(m_zoomLevel);
55
56     /// Fetch some map tiles for demo purposes
57     for (int x=9351; x<=9354; x++) {
58         for (int y=4261; y<=4264; y++) {
59             QString url = QString("http://tile.openstreetmap.org/mapnik/%1/%2/%3.png")
60                           .arg(m_zoomLevel).arg(x).arg(y);
61             m_mapFetcher->fetchMapImage(QUrl(url));
62         }
63     }
64 }
65
66 /**
67 * @todo Create URL parser methor and refactor code (use pointers for returning)
68 */
69 void MapEngine::mapImageReceived(const QUrl &url, const QPixmap &pixmap)
70 {
71
72     QString path = url.path();
73     //qDebug() << __PRETTY_FUNCTION__ << "path:" << path;
74
75     QStringList pathParts = path.split("/", QString::SkipEmptyParts);
76
77     int zoom = (pathParts.at(1)).toInt();
78     int x = (pathParts.at(2)).toInt();
79     QString yString = pathParts.at(3);
80     yString.chop(4);
81     int y = yString.toInt();
82
83     //qDebug() << __PRETTY_FUNCTION__ << zoom << x << y;
84
85     MapTile *mapTile = new MapTile();
86     mapTile->setZoomLevel(zoom);
87     mapTile->setTileNumber(QPoint(x, y));
88     mapTile->setPixmap(pixmap);
89     m_mapScene->addMapTile(mapTile);
90 }
91
92 /**
93   * @todo QPoint convertLatLonToTile(int zoomLevel, QPointF latLonCoordinate), convert to static
94   */
95 QPoint MapEngine::latLonToTile(qreal latitude, qreal longitude, int zoom)
96 {
97     qDebug() << __PRETTY_FUNCTION__;
98     qreal z = static_cast<qreal>(1 << zoom);
99
100     qreal x = static_cast<qreal>((longitude + 180.0) / 360.0);
101     qreal y = static_cast<qreal>((1.0 - log(tan(latitude * M_PI / 180.0) + 1.0
102                                 / cos(latitude * M_PI / 180.0)) / M_PI) / 2.0);
103
104     return QPoint(qFloor(x*z), qFloor(y*z));
105 }
106
107 /**
108   * @todo Remove both
109   */
110 qreal MapEngine::tileXToLongitude(int x, int zoom)
111 {
112     qDebug() << __PRETTY_FUNCTION__;
113     qreal z = static_cast<qreal>(1 << zoom);
114     qreal lon = x / z * 360.0 - 180.0;
115     qDebug() << lon;
116     return lon;
117 }
118
119 qreal MapEngine::tileYToLatitude(int y, int zoom)
120 {
121     qDebug() << __PRETTY_FUNCTION__;
122     qreal z = static_cast<qreal>(1 << zoom);
123     qreal n = M_PI - 2 * M_PI * y / zoom;
124     return 180.0 / (M_PI * atan(0.5 * exp(n) - exp(-n)));
125 }