165bc7b5756ab02c5e1745e968db0c0064faf603
[situare] / src / routing / geocodingservice.cpp
1 /*
2     Situare - A location system for Facebook
3     Copyright (C) 2010  Ixonos Plc. Authors:
4
5         Henri Lampela - henri.lampela@ixonos.com
6         Sami Rämö - sami.ramo@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 "parser.h"
24
25 #include "coordinates/geocoordinate.h"
26 #include "../error.h"
27 #include "network/networkaccessmanager.h"
28
29 #include "geocodingservice.h"
30
31 GeocodingService::GeocodingService(QObject *parent)
32     : QObject(parent)
33 {
34     qDebug() << __PRETTY_FUNCTION__;
35
36     m_networkManager = new NetworkAccessManager(this);
37     connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
38             this, SLOT(requestFinished(QNetworkReply*)), Qt::QueuedConnection);
39 }
40
41 void GeocodingService::parseSearchResults(const QByteArray &jsonReply)
42 {
43     qDebug() << __PRETTY_FUNCTION__;
44
45     const QString NO_DATA = "ZERO_RESULTS";
46
47     m_searchResults.clear();
48
49     QJson::Parser parser;
50     bool ok;
51     QVariantMap result = parser.parse(jsonReply, &ok).toMap();
52     if (!ok) {
53         emit error(ErrorContext::SITUARE, SituareError::ERROR_LOCATION_SEARCH_FAILED);
54         return;
55     } else if(result.value("status") != NO_DATA) {
56         foreach(QVariant hitVariant, result["results"].toList()) {
57             Location location;
58             QMap<QString, QVariant> hitMap = hitVariant.toMap();
59             location.setFormattedAddress(hitMap["formatted_address"].toString());
60
61             // parse coordinates
62             QVariant geometryVariant = hitMap["geometry"];
63             QMap<QString, QVariant> geometryMap = geometryVariant.toMap();
64             QVariant locationVariant = geometryMap["location"];
65             QMap<QString, QVariant> locationMap = locationVariant.toMap();
66             location.setCoordinates(GeoCoordinate(locationMap["lat"].toDouble(),
67                                                   locationMap["lng"].toDouble()));
68
69             // parse recommended viewport
70             QVariant viewportVariant = geometryMap["viewport"];
71             QMap<QString, QVariant> viewportMap = viewportVariant.toMap();
72             QVariant swVariant = viewportMap["southwest"];
73             QMap<QString, QVariant> swMap = swVariant.toMap();
74             QVariant neVariant = viewportMap["northeast"];
75             QMap<QString, QVariant> neMap = neVariant.toMap();
76
77             GeoCoordinate southwest = GeoCoordinate(swMap["lat"].toDouble(),
78                                                     swMap["lng"].toDouble());
79
80             GeoCoordinate northeast = GeoCoordinate(neMap["lat"].toDouble(),
81                                                     neMap["lng"].toDouble());
82
83             location.setViewPort(southwest, northeast);
84
85             m_searchResults.append(location);
86         }
87
88         emit locationDataParsed(m_searchResults);
89     } else {
90         emit error(ErrorContext::SITUARE, SituareError::ERROR_LOCATION_SEARCH_FAILED);
91     }
92 }
93
94 void GeocodingService::requestFinished(QNetworkReply *reply)
95 {
96     qDebug() << __PRETTY_FUNCTION__;
97
98     QByteArray replyArray = reply->readAll();
99
100     if (reply->error())
101         emit error(ErrorContext::NETWORK, reply->error());
102     else
103         parseSearchResults(replyArray);
104
105     reply->deleteLater();
106 }
107
108 void GeocodingService::requestLocation(const QString &location)
109 {
110     qDebug() << __PRETTY_FUNCTION__;
111
112     const QString GEOCODE_SERVICE_ADDRESS = "http://maps.google.com/maps/api/geocode/json?address=";
113     const QString DEVICE_CONTAINS_LOCATION_SENSOR = "&sensor=true";
114
115     QString url = GEOCODE_SERVICE_ADDRESS;
116     url.append(location);
117     url.append(DEVICE_CONTAINS_LOCATION_SENSOR);
118
119     sendRequest(url);
120 }
121
122 void GeocodingService::sendRequest(const QUrl &url)
123 {
124     qDebug() << __PRETTY_FUNCTION__;
125
126     QNetworkRequest request;
127
128     request.setUrl(url);
129     request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
130
131     QByteArray ba;
132     m_networkManager->post(request, ba, false);
133 }