Re-factored location search into separate GeocodingService class
authorSami Rämö <sami.ramo@ixonos.com>
Mon, 9 Aug 2010 08:07:12 +0000 (11:07 +0300)
committerSami Rämö <sami.ramo@ixonos.com>
Mon, 9 Aug 2010 08:50:29 +0000 (11:50 +0300)
 - Reviewed by Jussi Laitinen

src/engine/engine.cpp
src/engine/engine.h
src/map/mapview.cpp
src/routing/geocodingservice.cpp [new file with mode: 0644]
src/routing/geocodingservice.h [new file with mode: 0644]
src/routing/routingservice.cpp
src/routing/routingservice.h
src/src.pro

index fa82416..4c1183f 100644 (file)
@@ -36,6 +36,7 @@
 #include "facebookservice/facebookauthentication.h"
 #include "gps/gpsposition.h"
 #include "map/mapengine.h"
+#include "routing/geocodingservice.h"
 #include "routing/routingservice.h"
 #include "mce.h"
 #include "network/networkaccessmanager.h"
@@ -90,8 +91,12 @@ SituareEngine::SituareEngine()
     // build routing service
     m_routingService = new RoutingService(this); // create this when needed, not in constructor!
 
+    // build geocoding service
+    m_geocodingService = new GeocodingService(this);
+
     // connect signals
     signalsFromMapEngine();
+    signalsFromGeocodingService();
     signalsFromGPS();
     signalsFromRoutingService();
     signalsFromSituareService();
@@ -369,7 +374,7 @@ void SituareEngine::locationSearch(QString location)
     qDebug() << __PRETTY_FUNCTION__;
 
     if(!location.isEmpty())
-        m_routingService->requestLocation(location);
+        m_geocodingService->requestLocation(location);
 }
 
 void SituareEngine::loginActionPressed()
@@ -567,6 +572,14 @@ void SituareEngine::signalsFromFacebookAuthenticator()
             m_ui, SLOT(loginUsingCookies()));
 }
 
+void SituareEngine::signalsFromGeocodingService()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    connect(m_geocodingService, SIGNAL(locationDataParsed(QList<Location>&)),
+            this, SLOT(locationDataReady(QList<Location>&)));
+}
+
 void SituareEngine::signalsFromGPS()
 {
     qDebug() << __PRETTY_FUNCTION__;
@@ -689,12 +702,8 @@ void SituareEngine::signalsFromRoutingService()
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    connect(m_routingService, SIGNAL(locationDataParsed(QList<Location>&)),
-            this, SLOT(locationDataReady(QList<Location>&)));
-
     connect(m_routingService, SIGNAL(routeParsed(Route&)),
             m_mapEngine, SLOT(setRoute(Route&)));
-
 }
 
 void SituareEngine::signalsFromSituareService()
index 7770509..8a1dd24 100644 (file)
 
 #include "coordinates/geocoordinate.h"
 
+class QTimer;
+
 #ifdef Q_WS_MAEMO_5
 class Application;
 #endif
 class FacebookAuthentication;
 class FacebookCredentials;
+class GeocodingService;
 class GPSPosition;
 class Location;
 class MainWindow;
 class MapEngine;
+class MCE;
 class NetworkAccessManager;
 class RoutingService;
 class SituareService;
 class User;
-class MCE;
-
-class QTimer;
 
 /**
 * @brief Engine class for Situare Application
@@ -167,11 +168,16 @@ private:
     void initializeGpsAndAutocentering();
 
     /**
-      * @brief Connect signals coming from Facdebook authenticator
+      * @brief Connect signals coming from Facebook authenticator
       */
     void signalsFromFacebookAuthenticator();
 
     /**
+      * @brief Connect signals coming from GeocodingService
+      */
+    void signalsFromGeocodingService();
+
+    /**
       * @brief Connect signals coming from GPS
       */
     void signalsFromGPS();
@@ -330,6 +336,7 @@ private:
     Application *m_app;                              ///< Pointer to Application
 #endif
     FacebookAuthentication *m_facebookAuthenticator; ///< Instance for facebook authenticator
+    GeocodingService *m_geocodingService;            ///< Instance of the geocoding service
     GPSPosition *m_gps;                              ///< Instance of the gps position
     MainWindow *m_ui;                                ///< Instance of the MainWindow UI
     MapEngine *m_mapEngine;                          ///< MapEngine
index 36b008e..c86b93a 100644 (file)
@@ -196,8 +196,6 @@ void MapView::mouseReleaseEvent(QMouseEvent *event)
             QPointF endValue = QPointF(m_scenePosition) + effectSceneDistance;
             m_scroller->setEndValue(SceneCoordinate(endValue.x(), endValue.y()));
             m_scroller->start();
-
-            /// @todo modify calculations to use double
         }
     }
 }
diff --git a/src/routing/geocodingservice.cpp b/src/routing/geocodingservice.cpp
new file mode 100644 (file)
index 0000000..bbca2fe
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+    Situare - A location system for Facebook
+    Copyright (C) 2010  Ixonos Plc. Authors:
+
+        Henri Lampela - henri.lampela@ixonos.com
+        Sami Rämö - sami.ramo@ixonos.com
+
+    Situare is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+    version 2 as published by the Free Software Foundation.
+
+    Situare is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Situare; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+    USA.
+*/
+
+#include "parser.h"
+
+#include "error.h"
+#include "network/networkaccessmanager.h"
+
+#include "geocodingservice.h"
+
+GeocodingService::GeocodingService(QObject *parent)
+    : QObject(parent)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    m_networkManager = new NetworkAccessManager(this);
+    connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
+            this, SLOT(requestFinished(QNetworkReply*)), Qt::QueuedConnection);
+}
+
+void GeocodingService::parseSearchResults(const QByteArray &jsonReply)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    const QString NO_DATA = "ZERO_RESULTS";
+
+    m_searchResults.clear();
+
+    QJson::Parser parser;
+    bool ok;
+    QVariantMap result = parser.parse(jsonReply, &ok).toMap();
+    if (!ok) {
+        emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
+        return;
+    } else if(result.value("status") != NO_DATA) {
+        foreach(QVariant hitVariant, result["results"].toList()) {
+            Location location;
+            QMap<QString, QVariant> hitMap = hitVariant.toMap();
+
+            location.setFormattedAddress(hitMap["formatted_address"].toString());
+
+            QVariant geometryVariant = hitMap["geometry"];
+            QMap<QString, QVariant> geometryMap = geometryVariant.toMap();
+            QVariant locationVariant = geometryMap["location"];
+            QMap<QString, QVariant> locationMap = locationVariant.toMap();
+            location.setCoordinates(locationMap["lat"].toDouble(),
+                                    locationMap["lng"].toDouble());
+
+            QVariant boundsVariant = geometryMap["bounds"];
+            QMap<QString, QVariant> boundsMap = boundsVariant.toMap();
+            QVariant swVariant = boundsMap["southwest"];
+            QMap<QString, QVariant> swMap = swVariant.toMap();
+            location.setSWBound(swMap["lat"].toDouble(),
+                                swMap["lng"].toDouble());
+            QVariant neVariant = boundsMap["northeast"];
+            QMap<QString, QVariant> neMap = neVariant.toMap();
+            location.setNEBound(neMap["lat"].toDouble(),
+                                neMap["lng"].toDouble());
+
+            m_searchResults.append(location);
+        }
+
+        emit locationDataParsed(m_searchResults);
+    }
+}
+
+void GeocodingService::requestFinished(QNetworkReply *reply)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    QByteArray replyArray = reply->readAll();
+
+    if (reply->error())
+        emit error(ErrorContext::NETWORK, reply->error());
+    else
+        parseSearchResults(replyArray);
+
+    reply->deleteLater();
+}
+
+void GeocodingService::requestLocation(const QString &location)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    const QString GEOCODE_SERVICE_ADDRESS = "http://maps.google.com/maps/api/geocode/json?address=";
+    const QString DEVICE_CONTAINS_LOCATION_SENSOR = "&sensor=true";
+
+    QString url = GEOCODE_SERVICE_ADDRESS;
+    url.append(location);
+    url.append(DEVICE_CONTAINS_LOCATION_SENSOR);
+
+    sendRequest(url);
+}
+
+void GeocodingService::sendRequest(const QUrl &url)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    QNetworkRequest request;
+
+    request.setUrl(url);
+    request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
+
+    QByteArray ba;
+    m_networkManager->post(request, ba, false);
+}
diff --git a/src/routing/geocodingservice.h b/src/routing/geocodingservice.h
new file mode 100644 (file)
index 0000000..d67eb46
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+    Situare - A location system for Facebook
+    Copyright (C) 2010  Ixonos Plc. Authors:
+
+        Henri Lampela - henri.lampela@ixonos.com
+        Sami Rämö - sami.ramo@ixonos.com
+
+    Situare is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+    version 2 as published by the Free Software Foundation.
+
+    Situare is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Situare; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+    USA.
+*/
+
+
+#ifndef GEOCODINGSERVICE_H
+#define GEOCODINGSERVICE_H
+
+#include <QObject>
+
+#include "location.h"
+
+class QNetworkReply;
+class QUrl;
+
+class NetworkAccessManager;
+
+/**
+* @brief Geocoding service
+*
+* Searching coordinates for places based on names and addresses. Parsing the result json data into
+* list.
+*
+* @author Henri Lampela - henri.lampela@ixonos.com
+* @author Sami Rämö - sami.ramo@ixonos.com
+*/
+class GeocodingService : public QObject
+{
+    Q_OBJECT
+
+public:
+    /**
+    * @brief Default constructor
+    *
+    * @param parent instance of parent
+    */
+    GeocodingService(QObject *parent = 0);
+
+/*******************************************************************************
+ * MEMBER FUNCTIONS AND SLOTS
+ ******************************************************************************/
+public slots:
+    /**
+    * @brief Public slot, which indicates when http request has been completed
+    *
+    * @param reply storage for http reply
+    */
+    void requestFinished(QNetworkReply *reply);
+
+    /**
+    * @brief Request location information from the server
+    *
+    * @param location location (address, city etc.)
+    */
+    void requestLocation(const QString &location);
+
+private:
+    /**
+    * @brief Parses location data from JSON string
+    *
+    * @param jsonReply JSON string
+    */
+    void parseSearchResults(const QByteArray &jsonReply);
+
+    /**
+    * @brief Sends http request
+    *
+    * @param url destination
+    */
+    void sendRequest(const QUrl &url);
+
+/*******************************************************************************
+ * SIGNALS
+ ******************************************************************************/
+signals:
+    /**
+    * @brief Signals error
+    *
+    * @param context error context
+    * @param error error code
+    */
+    void error(const int context, const int error);
+
+    /**
+    * @brief Emited when location request is parsed and is ready for further processing
+    *
+    * @param result List of Location items
+    */
+    void locationDataParsed(QList<Location> &result);
+
+/*******************************************************************************
+ * DATA MEMBERS
+ ******************************************************************************/
+private:
+    QList<Location> m_searchResults;            ///< List of search results
+
+    NetworkAccessManager *m_networkManager;     ///< Pointer to QNetworkAccessManager
+};
+
+#endif // GEOCODINGSERVICE_H
index 71b0e66..4746dc4 100644 (file)
@@ -54,10 +54,6 @@ const int NO_ERROR = 0;
 const QString CLOUDMADE_AUTH_PART = "http://auth.cloudmade.com/token/";
 const QString CLOUDMADE_API_KEY = "0cea0072adbf42ce823f4c78b974f12d";
 
-// geocode
-const QString GEOCODE = "http://maps.google.com/maps/api/geocode/json?address=";
-
-
 RoutingService::RoutingService(QObject *parent)
         : QObject(parent)
 {
@@ -121,54 +117,6 @@ void RoutingService::parseRouteData(const QByteArray &jsonReply)
     }
 }
 
-void RoutingService::parseSearchResults(const QByteArray &jsonReply)
-{
-    qDebug() << __PRETTY_FUNCTION__;
-
-    const QString NO_DATA = "ZERO_RESULTS";
-
-    m_searchResults.clear();
-
-    QJson::Parser parser;
-    bool ok;
-    QVariantMap result = parser.parse (jsonReply, &ok).toMap();
-    if (!ok) {
-        emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
-        return;
-    } else {
-        if(result.value("status") != NO_DATA) {
-            foreach(QVariant hitVariant, result["results"].toList()) {
-                Location location;
-                QMap<QString, QVariant> hitMap = hitVariant.toMap();
-
-                location.setFormattedAddress(hitMap["formatted_address"].toString());
-
-                QVariant geometryVariant = hitMap["geometry"];
-                QMap<QString, QVariant> geometryMap = geometryVariant.toMap();
-                QVariant locationVariant = geometryMap["location"];
-                QMap<QString, QVariant> locationMap = locationVariant.toMap();
-                location.setCoordinates(locationMap["lat"].toDouble(),
-                                        locationMap["lng"].toDouble());
-
-                QVariant boundsVariant = geometryMap["bounds"];
-                QMap<QString, QVariant> boundsMap = boundsVariant.toMap();
-                QVariant swVariant = boundsMap["southwest"];
-                QMap<QString, QVariant> swMap = swVariant.toMap();
-                location.setSWBound(swMap["lat"].toDouble(),
-                                    swMap["lng"].toDouble());
-                QVariant neVariant = boundsMap["northeast"];
-                QMap<QString, QVariant> neMap = neVariant.toMap();
-                location.setNEBound(neMap["lat"].toDouble(),
-                                    neMap["lng"].toDouble());
-
-                m_searchResults.append(location);
-            }
-
-            emit locationDataParsed(m_searchResults);
-        }
-    }
-}
-
 void RoutingService::requestAuthorizationToken()
 {
     qDebug() << __PRETTY_FUNCTION__;
@@ -211,7 +159,6 @@ void RoutingService::requestFinished(QNetworkReply *reply)
     qDebug() << __PRETTY_FUNCTION__;
 
     QByteArray replyArray = reply->readAll();
-    qDebug() << "Reply from: " << reply->url() << "reply " << replyArray;
 
     if (reply->error()) {
         emit error(ErrorContext::NETWORK, reply->error());
@@ -220,8 +167,6 @@ void RoutingService::requestFinished(QNetworkReply *reply)
         m_pendingRequest.append(m_token);
         sendRequest(m_pendingRequest);
         m_pendingRequest.clear();
-    } else if(reply->url().toString().contains(GEOCODE)) {
-        parseSearchResults(replyArray);
     } else {
         parseRouteData(replyArray);
     }
@@ -229,19 +174,6 @@ void RoutingService::requestFinished(QNetworkReply *reply)
     reply->deleteLater();
 }
 
-void RoutingService::requestLocation(const QString &location)
-{
-    qDebug() << __PRETTY_FUNCTION__;
-
-    const QString urlEnd = "&sensor=false";
-
-    QString url = GEOCODE;
-    url.append(location);
-    url.append(urlEnd);
-
-    sendRequest(url);
-}
-
 void RoutingService::requestRoute(const GeoCoordinate &from, const GeoCoordinate &to)
 {
     qDebug() << __PRETTY_FUNCTION__;
index 3a2589b..a38bb8c 100644 (file)
 
 #include <QObject>
 
-#include "location.h"
-#include "route.h"
-
 class QNetworkReply;
-class QNetworkRequest;
 class QUrl;
 
 class GeoCoordinate;
 class NetworkAccessManager;
+class Route;
 
 /**
 * @brief RoutingService class for communicating with CloudMade server
@@ -73,13 +70,6 @@ public slots:
     */
     void requestRoute(const GeoCoordinate &from, const GeoCoordinate &to);
 
-    /**
-    * @brief Request location information from the server
-    *
-    * @param location location (address, city etc.)
-    */
-    void requestLocation(const QString &location);
-
 private:
     /**
     * @brief Parses routing data from JSON string
@@ -89,13 +79,6 @@ private:
     void parseRouteData(const QByteArray &jsonReply);
 
     /**
-    * @brief Parses location data from JSON string
-    *
-    * @param jsonReply JSON string
-    */
-    void parseSearchResults(const QByteArray &jsonReply);
-
-    /**
     * @brief Request authorization token
     *
     */
@@ -127,19 +110,10 @@ signals:
     */
     void routeParsed(Route &route);
 
-    /**
-    * @brief Emited when location request is parsed and is ready for further processing
-    *
-    * @param result List of Location items
-    */
-    void locationDataParsed(QList<Location> &result);
-
 /*******************************************************************************
  * DATA MEMBERS
  ******************************************************************************/
 private:
-    QList<Location> m_searchResults;            ///< List of search results
-
     QString m_pendingRequest;                   ///< Placeholder for pending route request
     QString m_token;                            ///< Placeholder for authentication token
 
index 3f68d31..18b79dc 100644 (file)
@@ -66,7 +66,8 @@ SOURCES += main.cpp \
     ui/listitem.cpp \
     ui/listitemdelegate.cpp \
     ui/friendlistitemdelegate.cpp \
-    ui/searchdialog.cpp
+    ui/searchdialog.cpp \
+    routing/geocodingservice.cpp
 HEADERS += application.h \
     common.h \
     engine/engine.h \
@@ -134,7 +135,8 @@ HEADERS += application.h \
     ui/friendlistitemdelegate.h \
     ui/listcommon.h \
     ui/searchdialog.h \
-    error.h
+    error.h \
+    routing/geocodingservice.h
 QT += network \
     webkit