Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qdeclarativegeocodemodel.cpp
Go to the documentation of this file.
1// Copyright (C) 2015 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include "error_messages_p.h"
6
7#include <QtCore/QCoreApplication>
8#include <QtQml/QQmlInfo>
9#include <QtPositioning/QGeoCircle>
10#include <QtLocation/QGeoServiceProvider>
11#include <QtLocation/QGeoCodingManager>
12#include <QtLocation/private/qgeocodereply_p.h>
13#include <QtPositioning/QGeoPolygon>
14
16
88
90{
91 qDeleteAll(declarativeLocations_);
92 declarativeLocations_.clear();
93 delete reply_;
94}
95
101{
102 complete_ = true;
103 if (autoUpdate_)
104 update();
105}
106
115{
116 if (!complete_)
117 return;
118
119 if (!plugin_) {
120 setError(EngineNotSetError, tr("Cannot geocode, plugin not set."));
121 return;
122 }
123
124 QGeoServiceProvider *serviceProvider = plugin_->sharedGeoServiceProvider();
125 if (!serviceProvider)
126 return;
127
128 QGeoCodingManager *geocodingManager = serviceProvider->geocodingManager();
129 if (!geocodingManager) {
130 setError(EngineNotSetError, tr("Cannot geocode, geocode manager not set."));
131 return;
132 }
133 if (!coordinate_.isValid() && (!address_ || address_->address().isEmpty()) &&
134 (searchString_.isEmpty())) {
135 setError(ParseError, tr("Cannot geocode, valid query not set."));
136 return;
137 }
138 abortRequest(); // abort possible previous requests
140
141 if (coordinate_.isValid()) {
143 reply_ = geocodingManager->reverseGeocode(coordinate_, boundingArea_);
144 if (reply_->isFinished()) {
145 if (reply_->error() == QGeoCodeReply::NoError) {
146 geocodeFinished(reply_);
147 } else {
148 geocodeError(reply_, reply_->error(), reply_->errorString());
149 }
150 }
151 } else if (address_) {
153 reply_ = geocodingManager->geocode(address_->address(), boundingArea_);
154 if (reply_->isFinished()) {
155 if (reply_->error() == QGeoCodeReply::NoError) {
156 geocodeFinished(reply_);
157 } else {
158 geocodeError(reply_, reply_->error(), reply_->errorString());
159 }
160 }
161 } else if (!searchString_.isEmpty()) {
163 reply_ = geocodingManager->geocode(searchString_, limit_, offset_, boundingArea_);
164 if (reply_->isFinished()) {
165 if (reply_->error() == QGeoCodeReply::NoError) {
166 geocodeFinished(reply_);
167 } else {
168 geocodeError(reply_, reply_->error(), reply_->errorString());
169 }
170 }
171 }
172}
173
177void QDeclarativeGeocodeModel::abortRequest()
178{
179 if (reply_) {
180 reply_->abort();
181 reply_->deleteLater();
182 reply_ = 0;
183 }
184}
185
194
200{
202 return declarativeLocations_.count();
203}
204
209{
210 if (!index.isValid())
211 return QVariant();
212 if (index.row() >= declarativeLocations_.count())
213 return QVariant();
215 QObject *locationObject = declarativeLocations_.at(index.row());
216 Q_ASSERT(locationObject);
217 return QVariant::fromValue(locationObject);
218 }
219 return QVariant();
220}
221
222QHash<int, QByteArray> QDeclarativeGeocodeModel::roleNames() const
223{
224 QHash<int, QByteArray> roleNames = QAbstractItemModel::roleNames();
225 roleNames.insert(LocationRole, "locationData");
226 return roleNames;
227}
228
233{
234 if (plugin_ == plugin)
235 return;
236
237 reset(); // reset the model
238 plugin_ = plugin;
239 if (complete_)
241
242 if (!plugin)
243 return;
244
245 if (plugin_->isAttached()) {
246 pluginReady();
247 } else {
250 }
251}
252
257{
258 QGeoServiceProvider *serviceProvider = plugin_->sharedGeoServiceProvider();
259 QGeoCodingManager *geocodingManager = serviceProvider->geocodingManager();
260
261 if (serviceProvider->geocodingError() != QGeoServiceProvider::NoError) {
263 switch (serviceProvider->geocodingError()) {
265 newError = EngineNotSetError; break;
267 newError = UnknownParameterError; break;
269 newError = MissingRequiredParameterError; break;
271 newError = CommunicationError; break;
272 default:
273 break;
274 }
275
276 setError(newError, serviceProvider->geocodingErrorString());
277 return;
278 }
279
280 if (!geocodingManager) {
281 setError(EngineNotSetError,tr("Plugin does not support (reverse) geocoding."));
282 return;
283 }
284
285 connect(geocodingManager, &QGeoCodingManager::finished,
287 connect(geocodingManager, &QGeoCodingManager::errorOccurred,
289
290 if (complete_ && autoUpdate_)
291 update();
292}
293
308
310{
311 QGeoShape s;
312
313 if (boundingArea.userType() == qMetaTypeId<QGeoRectangle>())
314 s = boundingArea.value<QGeoRectangle>();
315 else if (boundingArea.userType() == qMetaTypeId<QGeoCircle>())
316 s = boundingArea.value<QGeoCircle>();
317 else if (boundingArea.userType() == qMetaTypeId<QGeoShape>())
318 s = boundingArea.value<QGeoShape>();
319
320
321 if (boundingArea_ == s)
322 return;
323
324 boundingArea_ = s;
326}
327
339{
340 if (boundingArea_.type() == QGeoShape::RectangleType)
341 return QVariant::fromValue(QGeoRectangle(boundingArea_));
342 else if (boundingArea_.type() == QGeoShape::CircleType)
343 return QVariant::fromValue(QGeoCircle(boundingArea_));
344 else if (boundingArea_.type() == QGeoShape::PolygonType)
345 return QVariant::fromValue(QGeoPolygon(boundingArea_));
346 else
347 return QVariant::fromValue(boundingArea_);
348}
349
351{
352 if (reply != reply_ || reply->error() != QGeoCodeReply::NoError)
353 return;
354
356 reply_ = 0;
357 int oldCount = declarativeLocations_.count();
358 setLocations(reply->locations());
362 if (oldCount != declarativeLocations_.count())
364}
365
371 const QString &errorString)
372{
373 if (reply != reply_)
374 return;
375
377 reply_ = 0;
378 int oldCount = declarativeLocations_.count();
379 if (oldCount > 0) {
380 // Reset the model
381 setLocations(reply->locations());
384 }
387}
388
406
408{
409 if (status_ == status)
410 return;
411 status_ = status;
413}
414
439
441{
442 if (error_ == error && errorString_ == errorString)
443 return;
444 error_ = error;
445 errorString_ = errorString;
447}
448
460{
461 return errorString_;
462}
463
467void QDeclarativeGeocodeModel::setLocations(const QList<QGeoLocation> &locations)
468{
470 qDeleteAll(declarativeLocations_);
471 declarativeLocations_.clear();
472 for (const auto &location : locations)
473 declarativeLocations_.append(new QDeclarativeGeoLocation(location, this));
475}
476
486{
487 return declarativeLocations_.count();
488}
489
501{
502 if (index < 0 || index >= declarativeLocations_.count()) {
503 qmlWarning(this) << QStringLiteral("Index '%1' out of range").arg(index);
504 return nullptr;
505 }
506 return declarativeLocations_.at(index);
507}
508
521{
522 return limit_;
523}
524
526{
527 if (limit == limit_)
528 return;
529 limit_ = limit;
530 if (autoUpdate_) {
531 update();
532 }
534}
535
547{
548 return offset_;
549}
550
552{
553 if (offset == offset_)
554 return;
555 offset_ = offset;
556 if (autoUpdate_) {
557 update();
558 }
560}
561
571{
573 if (!declarativeLocations_.isEmpty()) {
574 setLocations(QList<QGeoLocation>());
576 }
578
579 abortRequest();
582}
583
591{
592 abortRequest();
594 setStatus(declarativeLocations_.isEmpty() ? Null : Ready);
595}
596
612{
613 return queryVariant_;
614}
615
617{
618 if (query == queryVariant_)
619 return;
620
621 if (query.userType() == qMetaTypeId<QGeoCoordinate>()) {
622 if (address_) {
623 address_->disconnect(this);
624 address_ = 0;
625 }
626 searchString_.clear();
627
628 coordinate_ = query.value<QGeoCoordinate>();
629 } else if (query.typeId() == QMetaType::QString) {
630 searchString_ = query.toString();
631 if (address_) {
632 address_->disconnect(this);
633 address_ = 0;
634 }
635 coordinate_ = QGeoCoordinate();
636 } else if (QObject *object = query.value<QObject *>()) {
637 if (QDeclarativeGeoAddress *address = qobject_cast<QDeclarativeGeoAddress *>(object)) {
638 if (address_)
639 address_->disconnect(this);
640 coordinate_ = QGeoCoordinate();
641 searchString_.clear();
642
643 address_ = address;
660 } else {
661 qmlWarning(this) << QStringLiteral("Unsupported query type for geocode model ")
662 << QStringLiteral("(coordinate, string and Address supported).");
663 return;
664 }
665 } else {
666 qmlWarning(this) << QStringLiteral("Unsupported query type for geocode model ")
667 << QStringLiteral("(coordinate, string and Address supported).");
668 return;
669 }
670
671 queryVariant_ = query;
673 if (autoUpdate_)
674 update();
675}
676
692{
693 return autoUpdate_;
694}
695
697{
698 if (autoUpdate_ == update)
699 return;
702}
703
void endResetModel()
Completes a model reset operation.
virtual QHash< int, QByteArray > roleNames() const
void beginResetModel()
Begins a model reset operation.
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
QGeoServiceProvider * sharedGeoServiceProvider() const
void geocodeFinished(QGeoCodeReply *reply)
void setError(GeocodeError error, const QString &errorString)
void setQuery(const QVariant &query)
QDeclarativeGeoServiceProvider * plugin
void update()
\qmlmethod void QtLocation::GeocodeModel::update()
void setBounds(const QVariant &boundingArea)
Q_INVOKABLE QDeclarativeGeoLocation * get(int index)
\qmlmethod Location QtLocation::GeocodeModel::get(int index)
int rowCount(const QModelIndex &parent) const override
void setPlugin(QDeclarativeGeoServiceProvider *plugin)
void geocodeError(QGeoCodeReply *reply, QGeoCodeReply::Error error, const QString &errorString)
QDeclarativeGeocodeModel(QObject *parent=nullptr)
\qmltype GeocodeModel \instantiates QDeclarativeGeocodeModel \inqmlmodule QtLocation
QHash< int, QByteArray > roleNames() const override
QVariant data(const QModelIndex &index, int role) const override
Q_INVOKABLE void cancel()
\qmlmethod void QtLocation::GeocodeModel::cancel()
Q_INVOKABLE void reset()
\qmlmethod void QtLocation::GeocodeModel::reset()
bool isEmpty() const
Returns whether this address is empty.
\inmodule QtPositioning
Definition qgeocircle.h:15
\inmodule QtLocation
bool isFinished() const
Return true if the operation completed successfully or encountered an error which cause the operation...
Error
Describes an error which prevented the completion of the operation.
Error error() const
Returns the error state of this reply.
virtual void abort()
Cancels the operation immediately.
QString errorString() const
Returns the textual representation of the error state of this reply.
\inmodule QtLocation
void errorOccurred(QGeoCodeReply *reply, QGeoCodeReply::Error error, const QString &errorString=QString())
QGeoCodeReply * geocode(const QGeoAddress &address, const QGeoShape &bounds=QGeoShape())
Begins the geocoding of address.
QGeoCodeReply * reverseGeocode(const QGeoCoordinate &coordinate, const QGeoShape &bounds=QGeoShape())
Begins the reverse geocoding of coordinate.
void finished(QGeoCodeReply *reply)
\inmodule QtPositioning
bool isValid
This property holds the validity of this geo coordinate.
\inmodule QtPositioning
Definition qgeopolygon.h:16
\inmodule QtPositioning
\inmodule QtLocation
Error geocodingError() const
Returns an error code describing the error which occurred during the last attempt to create a geocodi...
QString geocodingErrorString() const
Returns a string describing the error which occurred during the last attempt to create a geocoding ma...
QGeoCodingManager * geocodingManager() const
Returns the QGeoCodingManager made available by the service provider.
\inmodule QtPositioning
Definition qgeoshape.h:17
ShapeType type
This property holds the type of this geo shape.
Definition qgeoshape.h:19
@ PolygonType
Definition qgeoshape.h:35
@ RectangleType
Definition qgeoshape.h:32
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1303
bool isEmpty() const noexcept
Definition qlist.h:401
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
qsizetype count() const noexcept
Definition qlist.h:398
void clear()
Definition qlist.h:434
\inmodule QtCore
NetworkError error() const
Returns the error that was found during the processing of this request.
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3236
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1252
\inmodule QtCore
Definition qvariant.h:65
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:536
#define this
Definition dialogs.cpp:9
list append(new Employee("Blackpool", "Stephen"))
qDeleteAll(list.begin(), list.end())
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
GLint location
GLuint index
[2]
GLenum GLuint GLintptr offset
GLdouble s
[6]
Definition qopenglext.h:235
GLenum query
GLint limit
GLuint GLuint64EXT address
GLuint const GLint * locations
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
#define tr(X)
#define emit
#define Q_UNUSED(x)
QNetworkReply * reply