Updated copyright year
[harmattan/cameraplus] / src / geocode.cpp
1 /*!
2  * This file is part of CameraPlus.
3  *
4  * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20
21 #include "geocode.h"
22 #include <QDebug>
23 #include <QStringList>
24
25 Geocode::Geocode(QObject *parent) :
26   QObject(parent),
27   m_provider(0),
28   m_manager(0),
29   m_reply(0),
30   m_active(false) {
31
32   QStringList providers = QGeoServiceProvider::availableServiceProviders();
33
34   if (!providers.isEmpty()) {
35     m_provider = new QGeoServiceProvider(providers.at(0));
36   }
37   else {
38     qCritical() << "Cannot find any geo-service providers";
39     return;
40   }
41
42   m_manager = m_provider->searchManager();
43   if (!m_manager) {
44     qCritical() << "Cannot get hold of the geo-search manager" << m_provider->errorString();
45     return;
46   }
47
48   if (!m_manager->supportsReverseGeocoding()) {
49     qCritical() << "geo-search manager does not support reverse geocoding";
50
51     delete m_provider; m_provider = 0;
52     m_manager = 0;
53     return;
54   }
55
56   QObject::connect(m_manager, SIGNAL(finished(QGeoSearchReply *)),
57                    this, SLOT(finished(QGeoSearchReply *)));
58   QObject::connect(m_manager, SIGNAL(error(QGeoSearchReply *, const QGeoSearchReply::Error&,
59                                            const QString&)),
60                    this, SLOT(error(QGeoSearchReply *, const QGeoSearchReply::Error&,
61                                     const QString&)));
62 }
63
64 Geocode::~Geocode() {
65   setActive(false);
66
67   delete m_provider; m_provider = 0;
68 }
69
70 bool Geocode::isActive() const {
71   return m_active;
72 }
73
74 void Geocode::setActive(bool active) {
75   if (active != m_active) {
76     m_active = active;
77
78     if (!m_active && m_reply) {
79       m_reply->deleteLater(); m_reply = 0;
80     }
81
82     clear();
83
84     emit activeChanged();
85   }
86 }
87
88 QString Geocode::country() const {
89   return m_country;
90 }
91
92 QString Geocode::city() const {
93   return m_city;
94 }
95
96 QString Geocode::suburb() const {
97   return m_suburb;
98 }
99
100 void Geocode::search(double longitude, double latitude) {
101   if (!m_active || !m_provider) {
102     return;
103   }
104
105   if (m_reply) {
106     m_reply->abort();
107     delete m_reply;
108   }
109
110   m_reply = m_manager->reverseGeocode(QGeoCoordinate(latitude, longitude));
111   if (!m_reply) {
112     qCritical() << "geo-search manager provided a null reply!";
113     return;
114   }
115 }
116
117 void Geocode::clear() {
118   if (!m_country.isEmpty()) {
119     m_country.clear();
120     emit countryChanged();
121   }
122
123   if (!m_city.isEmpty()) {
124     m_city.clear();
125     emit cityChanged();
126   }
127
128   if (!m_suburb.isEmpty()) {
129     m_suburb.clear();
130     emit suburbChanged();
131   }
132 }
133
134 void Geocode::finished(QGeoSearchReply *reply) {
135   if (reply->error() != QGeoSearchReply::NoError) {
136     qWarning() << "Error while geocoding" << reply->error() << reply->errorString();
137
138     reply->deleteLater();
139
140     if (reply == m_reply) {
141       m_reply = 0;
142     }
143
144     clear();
145
146     return;
147   }
148
149   QList<QGeoPlace> places = reply->places();
150   if (!places.isEmpty()) {
151     QGeoAddress address = places.at(0).address();
152     if (m_country != address.country()) {
153       m_country = address.country();
154       emit countryChanged();
155     }
156
157     if (m_city != address.city()) {
158       m_city = address.city();
159       emit cityChanged();
160     }
161
162     if (m_suburb != address.district()) {
163       m_suburb = address.district();
164       emit suburbChanged();
165     }
166   }
167   else {
168     qWarning() << "No places found";
169     clear();
170   }
171
172   reply->deleteLater();
173
174   if (reply == m_reply) {
175     m_reply = 0;
176   }
177 }
178
179 void Geocode::error(QGeoSearchReply *reply, const QGeoSearchReply::Error& error,
180                     const QString& errorString) {
181
182   qWarning() << "Error while geocoding" << error << reply->errorString() << errorString;
183
184   reply->deleteLater();
185
186   if (reply == m_reply) {
187     m_reply = 0;
188     clear();
189   }
190 }