diff options
Diffstat (limited to 'src/plugins/geoservices')
49 files changed, 1266 insertions, 253 deletions
diff --git a/src/plugins/geoservices/esri/esri.pro b/src/plugins/geoservices/esri/esri.pro index 3a4da208..fce3947f 100644 --- a/src/plugins/geoservices/esri/esri.pro +++ b/src/plugins/geoservices/esri/esri.pro @@ -16,7 +16,10 @@ HEADERS += \ geotiledmap_esri.h \ geotiledmappingmanagerengine_esri.h \ geotiledmapreply_esri.h \ - geotilefetcher_esri.h + geotilefetcher_esri.h \ + placemanagerengine_esri.h \ + placesearchreply_esri.h \ + placecategoriesreply_esri.h SOURCES += \ geocodereply_esri.cpp \ @@ -29,7 +32,10 @@ SOURCES += \ geotiledmap_esri.cpp \ geotiledmappingmanagerengine_esri.cpp \ geotiledmapreply_esri.cpp \ - geotilefetcher_esri.cpp + geotilefetcher_esri.cpp \ + placemanagerengine_esri.cpp \ + placesearchreply_esri.cpp \ + placecategoriesreply_esri.cpp RESOURCES += \ esri.qrc diff --git a/src/plugins/geoservices/esri/esri_plugin.json b/src/plugins/geoservices/esri/esri_plugin.json index 3398648e..c1e37614 100644 --- a/src/plugins/geoservices/esri/esri_plugin.json +++ b/src/plugins/geoservices/esri/esri_plugin.json @@ -7,7 +7,8 @@ "OnlineMappingFeature", "OnlineGeocodingFeature", "ReverseGeocodingFeature", - "OnlineRoutingFeature" + "OnlineRoutingFeature", + "OnlinePlacesFeature" ], "Priority": 1000 } diff --git a/src/plugins/geoservices/esri/geocodereply_esri.cpp b/src/plugins/geoservices/esri/geocodereply_esri.cpp index f1dac184..fd1071c9 100644 --- a/src/plugins/geoservices/esri/geocodereply_esri.cpp +++ b/src/plugins/geoservices/esri/geocodereply_esri.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geocodereply_esri.h b/src/plugins/geoservices/esri/geocodereply_esri.h index 76b416ce..4f216193 100644 --- a/src/plugins/geoservices/esri/geocodereply_esri.h +++ b/src/plugins/geoservices/esri/geocodereply_esri.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp b/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp index 976c51cf..17ed3cd2 100644 --- a/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp +++ b/src/plugins/geoservices/esri/geocodingmanagerengine_esri.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geocodingmanagerengine_esri.h b/src/plugins/geoservices/esri/geocodingmanagerengine_esri.h index ff7bf882..a18f6bdd 100644 --- a/src/plugins/geoservices/esri/geocodingmanagerengine_esri.h +++ b/src/plugins/geoservices/esri/geocodingmanagerengine_esri.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geomapsource.cpp b/src/plugins/geoservices/esri/geomapsource.cpp index 7ec63e2f..7a7d264f 100644 --- a/src/plugins/geoservices/esri/geomapsource.cpp +++ b/src/plugins/geoservices/esri/geomapsource.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geomapsource.h b/src/plugins/geoservices/esri/geomapsource.h index 86258d2e..24bef6f7 100644 --- a/src/plugins/geoservices/esri/geomapsource.h +++ b/src/plugins/geoservices/esri/geomapsource.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp b/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp index 30db48f0..17492d94 100644 --- a/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp +++ b/src/plugins/geoservices/esri/georoutejsonparser_esri.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/georoutejsonparser_esri.h b/src/plugins/geoservices/esri/georoutejsonparser_esri.h index 0511cf4d..d6451d70 100644 --- a/src/plugins/geoservices/esri/georoutejsonparser_esri.h +++ b/src/plugins/geoservices/esri/georoutejsonparser_esri.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/georoutereply_esri.cpp b/src/plugins/geoservices/esri/georoutereply_esri.cpp index 811ffd0d..95de6b55 100644 --- a/src/plugins/geoservices/esri/georoutereply_esri.cpp +++ b/src/plugins/geoservices/esri/georoutereply_esri.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/georoutereply_esri.h b/src/plugins/geoservices/esri/georoutereply_esri.h index 960c90de..19cb85bd 100644 --- a/src/plugins/geoservices/esri/georoutereply_esri.h +++ b/src/plugins/geoservices/esri/georoutereply_esri.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp b/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp index ae722e59..0e6bc2c7 100644 --- a/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp +++ b/src/plugins/geoservices/esri/georoutingmanagerengine_esri.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/georoutingmanagerengine_esri.h b/src/plugins/geoservices/esri/georoutingmanagerengine_esri.h index 17aaa3ab..eac32222 100644 --- a/src/plugins/geoservices/esri/georoutingmanagerengine_esri.h +++ b/src/plugins/geoservices/esri/georoutingmanagerengine_esri.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geoserviceproviderfactory_esri.cpp b/src/plugins/geoservices/esri/geoserviceproviderfactory_esri.cpp index 0a54e008..197b16cd 100644 --- a/src/plugins/geoservices/esri/geoserviceproviderfactory_esri.cpp +++ b/src/plugins/geoservices/esri/geoserviceproviderfactory_esri.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. @@ -41,6 +41,7 @@ #include "geotiledmappingmanagerengine_esri.h" #include "geocodingmanagerengine_esri.h" #include "georoutingmanagerengine_esri.h" +#include "placemanagerengine_esri.h" #include <QtLocation/private/qgeotiledmappingmanagerengine_p.h> @@ -76,11 +77,7 @@ QGeoRoutingManagerEngine *GeoServiceProviderFactoryEsri::createRoutingManagerEng QPlaceManagerEngine *GeoServiceProviderFactoryEsri::createPlaceManagerEngine( const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const { - Q_UNUSED(parameters) - Q_UNUSED(error) - Q_UNUSED(errorString) - - return nullptr; + return new PlaceManagerEngineEsri(parameters, error, errorString); } QT_END_NAMESPACE diff --git a/src/plugins/geoservices/esri/geoserviceproviderfactory_esri.h b/src/plugins/geoservices/esri/geoserviceproviderfactory_esri.h index abd0d59b..6208348a 100644 --- a/src/plugins/geoservices/esri/geoserviceproviderfactory_esri.h +++ b/src/plugins/geoservices/esri/geoserviceproviderfactory_esri.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geotiledmap_esri.cpp b/src/plugins/geoservices/esri/geotiledmap_esri.cpp index 8feb9615..020001c4 100644 --- a/src/plugins/geoservices/esri/geotiledmap_esri.cpp +++ b/src/plugins/geoservices/esri/geotiledmap_esri.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geotiledmap_esri.h b/src/plugins/geoservices/esri/geotiledmap_esri.h index 7a21af9a..0f62d961 100644 --- a/src/plugins/geoservices/esri/geotiledmap_esri.h +++ b/src/plugins/geoservices/esri/geotiledmap_esri.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp b/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp index 3fa9a177..5d15835d 100644 --- a/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp +++ b/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. @@ -53,11 +53,6 @@ #include <QJsonDocument> #include <QJsonObject> -static void initResources() -{ - Q_INIT_RESOURCE(esri); -} - QT_BEGIN_NAMESPACE static const QString kPrefixEsri(QStringLiteral("esri.")); @@ -241,7 +236,6 @@ bool GeoTiledMappingManagerEngineEsri::initializeMapSources(QGeoServiceProvider: QString *errorString, const QGeoCameraCapabilities &cameraCaps) { - initResources(); QFile mapsFile(":/esri/maps.json"); if (!mapsFile.open(QIODevice::ReadOnly)) { diff --git a/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.h b/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.h index 63172389..222b1779 100644 --- a/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.h +++ b/src/plugins/geoservices/esri/geotiledmappingmanagerengine_esri.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geotiledmapreply_esri.cpp b/src/plugins/geoservices/esri/geotiledmapreply_esri.cpp index f4431bf0..78f6c69a 100644 --- a/src/plugins/geoservices/esri/geotiledmapreply_esri.cpp +++ b/src/plugins/geoservices/esri/geotiledmapreply_esri.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geotiledmapreply_esri.h b/src/plugins/geoservices/esri/geotiledmapreply_esri.h index 572431dd..9e649d4f 100644 --- a/src/plugins/geoservices/esri/geotiledmapreply_esri.h +++ b/src/plugins/geoservices/esri/geotiledmapreply_esri.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geotilefetcher_esri.cpp b/src/plugins/geoservices/esri/geotilefetcher_esri.cpp index 8ceba374..00344cf7 100644 --- a/src/plugins/geoservices/esri/geotilefetcher_esri.cpp +++ b/src/plugins/geoservices/esri/geotilefetcher_esri.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/geotilefetcher_esri.h b/src/plugins/geoservices/esri/geotilefetcher_esri.h index 5702d1c4..8c109f73 100644 --- a/src/plugins/geoservices/esri/geotilefetcher_esri.h +++ b/src/plugins/geoservices/esri/geotilefetcher_esri.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013-2016 Esri <contracts@esri.com> +** Copyright (C) 2013-2018 Esri <contracts@esri.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. diff --git a/src/plugins/geoservices/esri/placecategoriesreply_esri.cpp b/src/plugins/geoservices/esri/placecategoriesreply_esri.cpp new file mode 100644 index 00000000..44c27b19 --- /dev/null +++ b/src/plugins/geoservices/esri/placecategoriesreply_esri.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2013-2018 Esri <contracts@esri.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "placecategoriesreply_esri.h" + +QT_BEGIN_NAMESPACE + +PlaceCategoriesReplyEsri::PlaceCategoriesReplyEsri(QObject *parent) : + QPlaceReply(parent) +{ +} + +PlaceCategoriesReplyEsri::~PlaceCategoriesReplyEsri() +{ +} + +void PlaceCategoriesReplyEsri::emitFinished() +{ + setFinished(true); + emit finished(); +} + +void PlaceCategoriesReplyEsri::setError(QPlaceReply::Error errorCode, const QString &errorString) +{ + QPlaceReply::setError(errorCode, errorString); + emit error(errorCode, errorString); +} + +QT_END_NAMESPACE diff --git a/src/plugins/geoservices/esri/placecategoriesreply_esri.h b/src/plugins/geoservices/esri/placecategoriesreply_esri.h new file mode 100644 index 00000000..14efcfea --- /dev/null +++ b/src/plugins/geoservices/esri/placecategoriesreply_esri.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2013-2018 Esri <contracts@esri.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PLACECATEGORIESREPLYESRI_H +#define PLACECATEGORIESREPLYESRI_H + +#include <QtLocation/QPlaceReply> + +QT_BEGIN_NAMESPACE + +class PlaceCategoriesReplyEsri : public QPlaceReply +{ + Q_OBJECT + +public: + explicit PlaceCategoriesReplyEsri(QObject *parent = 0); + ~PlaceCategoriesReplyEsri(); + + void emitFinished(); + void setError(QPlaceReply::Error errorCode, const QString &errorString); +}; + +QT_END_NAMESPACE + +#endif // PLACECATEGORIESREPLYESRI_H diff --git a/src/plugins/geoservices/esri/placemanagerengine_esri.cpp b/src/plugins/geoservices/esri/placemanagerengine_esri.cpp new file mode 100644 index 00000000..8f973ff3 --- /dev/null +++ b/src/plugins/geoservices/esri/placemanagerengine_esri.cpp @@ -0,0 +1,369 @@ +/**************************************************************************** +** +** Copyright (C) 2013-2018 Esri <contracts@esri.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "placemanagerengine_esri.h" +#include "placesearchreply_esri.h" +#include "placecategoriesreply_esri.h" + +#include <QJsonDocument> +#include <QJsonObject> +#include <QJsonArray> + +#include <QtCore/QUrlQuery> + +QT_BEGIN_NAMESPACE + +// https://developers.arcgis.com/rest/geocode/api-reference/geocoding-find-address-candidates.htm +// https://developers.arcgis.com/rest/geocode/api-reference/geocoding-category-filtering.htm +// https://developers.arcgis.com/rest/geocode/api-reference/geocoding-service-output.htm + +static const QString kCategoriesKey(QStringLiteral("categories")); +static const QString kSingleLineKey(QStringLiteral("singleLine")); +static const QString kLocationKey(QStringLiteral("location")); +static const QString kNameKey(QStringLiteral("name")); +static const QString kOutFieldsKey(QStringLiteral("outFields")); +static const QString kCandidateFieldsKey(QStringLiteral("candidateFields")); +static const QString kCountriesKey(QStringLiteral("detailedCountries")); +static const QString kLocalizedNamesKey(QStringLiteral("localizedNames")); +static const QString kMaxLocationsKey(QStringLiteral("maxLocations")); + +static const QUrl kUrlGeocodeServer("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer?f=pjson"); +static const QUrl kUrlFindAddressCandidates("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates"); + +PlaceManagerEngineEsri::PlaceManagerEngineEsri(const QVariantMap ¶meters, QGeoServiceProvider::Error *error, + QString *errorString) : + QPlaceManagerEngine(parameters), + m_networkManager(new QNetworkAccessManager(this)) +{ + *error = QGeoServiceProvider::NoError; + errorString->clear(); +} + +PlaceManagerEngineEsri::~PlaceManagerEngineEsri() +{ +} + +QList<QLocale> PlaceManagerEngineEsri::locales() const +{ + return m_locales; +} + +void PlaceManagerEngineEsri::setLocales(const QList<QLocale> &locales) +{ + m_locales = locales; +} + +/***** Search *****/ + +QPlaceSearchReply *PlaceManagerEngineEsri::search(const QPlaceSearchRequest &request) +{ + bool unsupported = false; + + // Only public visibility supported + unsupported |= request.visibilityScope() != QLocation::UnspecifiedVisibility && + request.visibilityScope() != QLocation::PublicVisibility; + unsupported |= request.searchTerm().isEmpty() && request.categories().isEmpty(); + + if (unsupported) + return QPlaceManagerEngine::search(request); + + QUrlQuery queryItems; + queryItems.addQueryItem(QStringLiteral("f"), QStringLiteral("json")); + + const QGeoCoordinate center = request.searchArea().center(); + if (center.isValid()) + { + const QString location = QString("%1,%2").arg(center.longitude()).arg(center.latitude()); + queryItems.addQueryItem(kLocationKey, location); + } + + const QGeoRectangle boundingBox = request.searchArea().boundingGeoRectangle(); + if (!boundingBox.isEmpty()) + { + const QString searchExtent = QString("%1,%2,%3,%4") + .arg(boundingBox.topLeft().longitude()) + .arg(boundingBox.topLeft().latitude()) + .arg(boundingBox.bottomRight().longitude()) + .arg(boundingBox.bottomRight().latitude()); + queryItems.addQueryItem(QStringLiteral("searchExtent"), searchExtent); + } + + if (!request.searchTerm().isEmpty()) + queryItems.addQueryItem(kSingleLineKey, request.searchTerm()); + + QStringList categories; + if (!request.categories().isEmpty()) + { + foreach (const QPlaceCategory &placeCategory, request.categories()) + categories.append(placeCategory.categoryId()); + queryItems.addQueryItem("category", categories.join(",")); + } + + if (request.limit() > 0) + queryItems.addQueryItem(kMaxLocationsKey, QString::number(request.limit())); + + queryItems.addQueryItem(kOutFieldsKey, QStringLiteral("*")); + + QUrl requestUrl(kUrlFindAddressCandidates); + requestUrl.setQuery(queryItems); + + QNetworkRequest networkRequest(requestUrl); + networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + QNetworkReply *networkReply = m_networkManager->get(networkRequest); + + PlaceSearchReplyEsri *reply = new PlaceSearchReplyEsri(request, networkReply, m_candidateFieldsLocale, m_countriesLocale, this); + connect(reply, SIGNAL(finished()), this, SLOT(replyFinished())); + connect(reply, SIGNAL(error(QPlaceReply::Error,QString)), this, SLOT(replyError(QPlaceReply::Error,QString))); + + return reply; +} + +void PlaceManagerEngineEsri::replyFinished() +{ + QPlaceReply *reply = qobject_cast<QPlaceReply *>(sender()); + if (reply) + emit finished(reply); +} + +void PlaceManagerEngineEsri::replyError(QPlaceReply::Error errorCode, const QString &errorString) +{ + QPlaceReply *reply = qobject_cast<QPlaceReply *>(sender()); + if (reply) + emit error(reply, errorCode, errorString); +} + +/***** Categories *****/ + +QPlaceReply *PlaceManagerEngineEsri::initializeCategories() +{ + initializeGeocodeServer(); + + PlaceCategoriesReplyEsri *reply = new PlaceCategoriesReplyEsri(this); + connect(reply, SIGNAL(finished()), this, SLOT(replyFinished())); + connect(reply, SIGNAL(error(QPlaceReply::Error,QString)), this, SLOT(replyError(QPlaceReply::Error,QString))); + + // TODO delayed finished() emission + if (!m_categories.isEmpty()) + reply->emitFinished(); + + m_pendingCategoriesReply.append(reply); + return reply; +} + +void PlaceManagerEngineEsri::parseCategories(const QJsonArray &jsonArray, const QString &parentCategoryId) +{ + foreach (const QJsonValue &jsonValue, jsonArray) + { + if (!jsonValue.isObject()) + continue; + + const QJsonObject jsonCategory = jsonValue.toObject(); + const QString key = jsonCategory.value(kNameKey).toString(); + const QString localeName = localizedName(jsonCategory); + + if (key.isEmpty()) + continue; + + QPlaceCategory category; + category.setCategoryId(key); + category.setName(localeName.isEmpty() ? key : localeName); // localizedNames + m_categories.insert(key, category); + m_subcategories[parentCategoryId].append(key); + m_parentCategory.insert(key, parentCategoryId); + emit categoryAdded(category, parentCategoryId); + + if (jsonCategory.contains(kCategoriesKey)) + { + const QJsonArray jsonArray = jsonCategory.value(kCategoriesKey).toArray(); + parseCategories(jsonArray, key); + } + } +} + +QString PlaceManagerEngineEsri::parentCategoryId(const QString &categoryId) const +{ + return m_parentCategory.value(categoryId); +} + +QStringList PlaceManagerEngineEsri::childCategoryIds(const QString &categoryId) const +{ + return m_subcategories.value(categoryId); +} + +QPlaceCategory PlaceManagerEngineEsri::category(const QString &categoryId) const +{ + return m_categories.value(categoryId); +} + +QList<QPlaceCategory> PlaceManagerEngineEsri::childCategories(const QString &parentId) const +{ + QList<QPlaceCategory> categories; + foreach (const QString &id, m_subcategories.value(parentId)) + categories.append(m_categories.value(id)); + return categories; +} + +void PlaceManagerEngineEsri::finishCategories() +{ + foreach (PlaceCategoriesReplyEsri *reply, m_pendingCategoriesReply) + reply->emitFinished(); + m_pendingCategoriesReply.clear(); +} + +void PlaceManagerEngineEsri::errorCaterogies(const QString &error) +{ + foreach (PlaceCategoriesReplyEsri *reply, m_pendingCategoriesReply) + reply->setError(QPlaceReply::CommunicationError, error); +} + +/***** GeocodeServer *****/ + +void PlaceManagerEngineEsri::initializeGeocodeServer() +{ + // Only fetch categories once + if (m_categories.isEmpty() && !m_geocodeServerReply) + { + m_geocodeServerReply = m_networkManager->get(QNetworkRequest(kUrlGeocodeServer)); + connect(m_geocodeServerReply, SIGNAL(finished()), this, SLOT(geocodeServerReplyFinished())); + connect(m_geocodeServerReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(geocodeServerReplyError())); + } +} + +QString PlaceManagerEngineEsri::localizedName(const QJsonObject &jsonObject) +{ + const QJsonObject localizedNames = jsonObject.value(kLocalizedNamesKey).toObject(); + + foreach (const QLocale &locale, m_locales) + { + const QString localeStr = locale.name(); + if (localizedNames.contains(localeStr)) + { + return localizedNames.value(localeStr).toString(); + } + + const QString shortLocale = localeStr.left(2); + if (localizedNames.contains(shortLocale)) + { + return localizedNames.value(shortLocale).toString(); + } + } + return QString(); +} + +void PlaceManagerEngineEsri::parseCandidateFields(const QJsonArray &jsonArray) +{ + foreach (const QJsonValue &jsonValue, jsonArray) + { + if (!jsonValue.isObject()) + continue; + + const QJsonObject jsonCandidateField = jsonValue.toObject(); + if (!jsonCandidateField.contains(kLocalizedNamesKey)) + continue; + + const QString key = jsonCandidateField.value(kNameKey).toString(); + m_candidateFieldsLocale.insert(key, localizedName(jsonCandidateField)); + } +} + +void PlaceManagerEngineEsri::parseCountries(const QJsonArray &jsonArray) +{ + foreach (const QJsonValue &jsonValue, jsonArray) + { + if (!jsonValue.isObject()) + continue; + + const QJsonObject jsonCountry = jsonValue.toObject(); + if (!jsonCountry.contains(kLocalizedNamesKey)) + continue; + + const QString key = jsonCountry.value(kNameKey).toString(); + m_countriesLocale.insert(key, localizedName(jsonCountry)); + } +} + +void PlaceManagerEngineEsri::geocodeServerReplyFinished() +{ + if (!m_geocodeServerReply) + return; + + QJsonDocument document = QJsonDocument::fromJson(m_geocodeServerReply->readAll()); + if (!document.isObject()) + { + errorCaterogies(m_geocodeServerReply->errorString()); + return; + } + + QJsonObject jsonObject = document.object(); + + // parse categories + if (jsonObject.contains(kCategoriesKey)) + { + const QJsonArray jsonArray = jsonObject.value(kCategoriesKey).toArray(); + parseCategories(jsonArray, QString()); + } + + // parse candidateFields + if (jsonObject.contains(kCandidateFieldsKey)) + { + const QJsonArray jsonArray = jsonObject.value(kCandidateFieldsKey).toArray(); + parseCandidateFields(jsonArray); + } + + // parse countries + if (jsonObject.contains(kCountriesKey)) + { + const QJsonArray jsonArray = jsonObject.value(kCountriesKey).toArray(); + parseCountries(jsonArray); + } + + finishCategories(); + + m_geocodeServerReply->deleteLater(); +} + +void PlaceManagerEngineEsri::geocodeServerReplyError() +{ + if (m_categories.isEmpty() && !m_geocodeServerReply) + return; + + errorCaterogies(m_geocodeServerReply->errorString()); +} + +QT_END_NAMESPACE diff --git a/src/plugins/geoservices/esri/placemanagerengine_esri.h b/src/plugins/geoservices/esri/placemanagerengine_esri.h new file mode 100644 index 00000000..2edb2d1a --- /dev/null +++ b/src/plugins/geoservices/esri/placemanagerengine_esri.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2013-2018 Esri <contracts@esri.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PLACEMANAGERENGINEESRI_H +#define PLACEMANAGERENGINEESRI_H + +#include <QtLocation/QPlaceManagerEngine> +#include <QtLocation/QGeoServiceProvider> + +QT_BEGIN_NAMESPACE + +class PlaceCategoriesReplyEsri; +class QNetworkAccessManager; +class QNetworkReply; + +class PlaceManagerEngineEsri : public QPlaceManagerEngine +{ + Q_OBJECT + +public: + PlaceManagerEngineEsri(const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString); + ~PlaceManagerEngineEsri(); + + QPlaceSearchReply *search(const QPlaceSearchRequest &request) override; + + QPlaceReply *initializeCategories() override; + QString parentCategoryId(const QString &categoryId) const override; + QStringList childCategoryIds(const QString &categoryId) const override; + QPlaceCategory category(const QString &categoryId) const override; + + QList<QPlaceCategory> childCategories(const QString &parentId) const override; + + QList<QLocale> locales() const override; + void setLocales(const QList<QLocale> &locales) override; + +private slots: + void geocodeServerReplyFinished(); + void geocodeServerReplyError(); + void replyFinished(); + void replyError(QPlaceReply::Error errorCode, const QString &errorString); + +private: + QNetworkAccessManager *m_networkManager = Q_NULLPTR; + + // geocode serveur + void initializeGeocodeServer(); + + QNetworkReply *m_geocodeServerReply = Q_NULLPTR; + + // categories + void finishCategories(); + void errorCaterogies(const QString &error); + void parseCategories(const QJsonArray &jsonArray, const QString &parentCategoryId); + + QList<PlaceCategoriesReplyEsri *> m_pendingCategoriesReply; + QHash<QString, QPlaceCategory> m_categories; + QHash<QString, QStringList> m_subcategories; + QHash<QString, QString> m_parentCategory; + + // localized names + QString localizedName(const QJsonObject &jsonObject); + void parseCandidateFields(const QJsonArray &jsonArray); + void parseCountries(const QJsonArray &jsonArray); + + QList<QLocale> m_locales; + QHash<QString, QString> m_candidateFieldsLocale; + QHash<QString, QString> m_countriesLocale; + void localizedName(); +}; + +QT_END_NAMESPACE + +#endif // PLACEMANAGERENGINEESRI_H diff --git a/src/plugins/geoservices/esri/placesearchreply_esri.cpp b/src/plugins/geoservices/esri/placesearchreply_esri.cpp new file mode 100644 index 00000000..a5a3585a --- /dev/null +++ b/src/plugins/geoservices/esri/placesearchreply_esri.cpp @@ -0,0 +1,223 @@ +/**************************************************************************** +** +** Copyright (C) 2013-2018 Esri <contracts@esri.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "placesearchreply_esri.h" +#include "placemanagerengine_esri.h" + +#include <QtCore/QJsonDocument> +#include <QtCore/QJsonArray> +#include <QtCore/QJsonObject> +#include <QtNetwork/QNetworkReply> +#include <QtPositioning/QGeoCircle> +#include <QtPositioning/QGeoRectangle> +#include <QtLocation/QPlaceResult> +#include <QtLocation/QPlaceSearchRequest> +#include <QtLocation/private/qplacesearchrequest_p.h> + +static const QString kCandidatesKey(QStringLiteral("candidates")); +static const QString kAttributesKey(QStringLiteral("attributes")); +static const QString kAddressKey(QStringLiteral("address")); +static const QString kLongLabelKey(QStringLiteral("LongLabel")); +static const QString kCityKey(QStringLiteral("City")); +static const QString kCountryKey(QStringLiteral("Country")); +static const QString kRegionKey(QStringLiteral("Region")); +static const QString kPostalKey(QStringLiteral("Postal")); +static const QString kStAddrKey(QStringLiteral("StAddr")); +static const QString kStateKey(QStringLiteral("State")); +static const QString kDistrictKey(QStringLiteral("District")); +static const QString kLocationKey(QStringLiteral("location")); +static const QString kXKey(QStringLiteral("x")); +static const QString kYKey(QStringLiteral("y")); +static const QString kDistanceKey(QStringLiteral("Distance")); +static const QString kPhoneKey(QStringLiteral("Phone")); +static const QString kExtentKey(QStringLiteral("extent")); +static const QString kXminKey(QStringLiteral("xmin")); +static const QString kYminKey(QStringLiteral("ymin")); +static const QString kXmaxKey(QStringLiteral("xmax")); +static const QString kYmaxKey(QStringLiteral("ymax")); + +QT_BEGIN_NAMESPACE + +PlaceSearchReplyEsri::PlaceSearchReplyEsri(const QPlaceSearchRequest &request, QNetworkReply *reply, + const QHash<QString, QString> &candidateFields, + const QHash<QString, QString> &countries, PlaceManagerEngineEsri *parent) : + QPlaceSearchReply(parent), m_candidateFields(candidateFields), m_countries(countries) +{ + Q_ASSERT(parent); + if (!reply) { + setError(UnknownError, QStringLiteral("Null reply")); + return; + } + setRequest(request); + + connect(reply, SIGNAL(finished()), this, SLOT(replyFinished())); + connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(networkError(QNetworkReply::NetworkError))); + connect(this, &QPlaceReply::aborted, reply, &QNetworkReply::abort); + connect(this, &QObject::destroyed, reply, &QObject::deleteLater); +} + +PlaceSearchReplyEsri::~PlaceSearchReplyEsri() +{ +} + +void PlaceSearchReplyEsri::setError(QPlaceReply::Error errorCode, const QString &errorString) +{ + QPlaceReply::setError(errorCode, errorString); + emit error(errorCode, errorString); + setFinished(true); + emit finished(); +} + +void PlaceSearchReplyEsri::replyFinished() +{ + QNetworkReply *reply = static_cast<QNetworkReply *>(sender()); + reply->deleteLater(); + + if (reply->error() != QNetworkReply::NoError) + return; + + QJsonDocument document = QJsonDocument::fromJson(reply->readAll()); + if (!document.isObject()) + { + setError(ParseError, tr("Response parse error")); + return; + } + + QJsonValue suggestions = document.object().value(kCandidatesKey); + if (!suggestions.isArray()) + { + setError(ParseError, tr("Response parse error")); + return; + } + + QJsonArray resultsArray = suggestions.toArray(); + + QList<QPlaceSearchResult> results; + for (int i = 0; i < resultsArray.count(); ++i) + { + QJsonObject item = resultsArray.at(i).toObject(); + QPlaceResult placeResult = parsePlaceResult(item); + results.append(placeResult); + } + + setResults(results); + setFinished(true); + emit finished(); +} + +void PlaceSearchReplyEsri::networkError(QNetworkReply::NetworkError error) +{ + Q_UNUSED(error) + QNetworkReply *reply = static_cast<QNetworkReply *>(sender()); + reply->deleteLater(); + setError(QPlaceReply::CommunicationError, reply->errorString()); +} + +QPlaceResult PlaceSearchReplyEsri::parsePlaceResult(const QJsonObject &item) const +{ + QPlace place; + QHash<QString, QString> keys; + + // set attributes + const QJsonObject attributes = item.value(kAttributesKey).toObject(); + for (const QString &key: attributes.keys()) + { + const QString value = attributes.value(key).toVariant().toString(); + if (!value.isEmpty()) + { + QPlaceAttribute attribute; + attribute.setLabel(m_candidateFields.value(key, key)); // local name or key + attribute.setText(value); + place.setExtendedAttribute(key, attribute); + keys.insert(key, value); + } + } + + if (keys.contains(kPhoneKey)) + { + QPlaceContactDetail contactDetail; + contactDetail.setLabel(m_candidateFields.value(kPhoneKey, kPhoneKey)); // local name or key + contactDetail.setValue(keys.value(kPhoneKey)); + place.appendContactDetail(QPlaceContactDetail::Phone, contactDetail); + } + + // set address + QGeoAddress geoAddress; + geoAddress.setCity(keys.value(kCityKey)); + geoAddress.setCountry(m_countries.value(keys.value(kCountryKey))); // mismatch code ISO2 vs ISO3 + geoAddress.setCounty(keys.value(kRegionKey)); + geoAddress.setPostalCode(keys.value(kPostalKey)); + geoAddress.setStreet(keys.value(kStAddrKey)); + geoAddress.setState(keys.value(kStateKey)); + geoAddress.setDistrict(keys.value(kDistrictKey)); + + // set location + const QJsonObject location = item.value(kLocationKey).toObject(); + const QGeoCoordinate coordinate = QGeoCoordinate(location.value(kYKey).toDouble(), + location.value(kXKey).toDouble()); + + // set boundingBox + const QJsonObject extent = item.value(kExtentKey).toObject(); + const QGeoCoordinate topLeft(extent.value(kYminKey).toDouble(), + extent.value(kXminKey).toDouble()); + const QGeoCoordinate bottomRight(extent.value(kYmaxKey).toDouble(), + extent.value(kXmaxKey).toDouble()); + const QGeoRectangle boundingBox(topLeft, bottomRight); + + // set geolocation + QGeoLocation geoLocation; + geoLocation.setCoordinate(coordinate); + geoLocation.setAddress(geoAddress); + geoLocation.setBoundingBox(boundingBox); + + // set place + place.setName(keys.value(kLongLabelKey)); + place.setLocation(geoLocation); + place.setPlaceId(attributes.value(kLongLabelKey).toString()); + + // set place result + QPlaceResult result; + result.setPlace(place); + result.setTitle(keys.value(kAddressKey)); + result.setDistance(keys.value(kDistanceKey).toDouble()); + + return result; +} + +QT_END_NAMESPACE diff --git a/src/plugins/geoservices/esri/placesearchreply_esri.h b/src/plugins/geoservices/esri/placesearchreply_esri.h new file mode 100644 index 00000000..195d650d --- /dev/null +++ b/src/plugins/geoservices/esri/placesearchreply_esri.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2013-2018 Esri <contracts@esri.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PLACESEARCHREPLYESRI_H +#define PLACESEARCHREPLYESRI_H + +#include <QtLocation/QPlaceSearchReply> +#include <QNetworkReply> + +QT_BEGIN_NAMESPACE + +class PlaceManagerEngineEsri; +class QNetworkReply; +class QPlaceResult; + +class PlaceSearchReplyEsri : public QPlaceSearchReply +{ + Q_OBJECT + +public: + PlaceSearchReplyEsri(const QPlaceSearchRequest &request, QNetworkReply *reply, + const QHash<QString, QString> &candidateFields, + const QHash<QString, QString> &countries, PlaceManagerEngineEsri *parent); + ~PlaceSearchReplyEsri(); + + QString requestUrl; + +private slots: + void setError(QPlaceReply::Error errorCode, const QString &errorString); + void replyFinished(); + void networkError(QNetworkReply::NetworkError error); + +private: + QPlaceResult parsePlaceResult(const QJsonObject &item) const; + + const QHash<QString, QString> &m_candidateFields; + const QHash<QString, QString> &m_countries; +}; + +QT_END_NAMESPACE + +#endif // PLACESEARCHREPLYESRI_H diff --git a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp index af0e263b..dede9dbc 100644 --- a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp +++ b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp @@ -70,10 +70,16 @@ public: #endif void updateObjectsGeometry(); + + void setVisibleArea(const QRectF &visibleArea) override; + QRectF visibleArea() const override; + protected: void changeViewportSize(const QSize &size) override; void changeCameraData(const QGeoCameraData &oldCameraData) override; void changeActiveMapType(const QGeoMapType mapType) override; + + QRectF m_visibleArea; }; QGeoMapItemsOverlay::QGeoMapItemsOverlay(QGeoMappingManagerEngineItemsOverlay *engine, QObject *parent) @@ -131,6 +137,24 @@ void QGeoMapItemsOverlay::removeMapObject(QGeoMapObject *obj) #endif } +void QGeoMapItemsOverlayPrivate::setVisibleArea(const QRectF &visibleArea) +{ + Q_Q(QGeoMapItemsOverlay); + const QRectF va = clampVisibleArea(visibleArea); + if (va == m_visibleArea) + return; + + m_visibleArea = va; + m_geoProjection->setVisibleArea(va); + + q->sgNodeChanged(); +} + +QRectF QGeoMapItemsOverlayPrivate::visibleArea() const +{ + return m_visibleArea; +} + QGeoMapItemsOverlayPrivate::QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine, QGeoMapItemsOverlay *map) : QGeoMapPrivate(engine, new QGeoProjectionWebMercator) { diff --git a/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp b/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp index c5f9d38c..8b0772ad 100644 --- a/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp +++ b/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp @@ -127,6 +127,13 @@ void QGeoRouteReplyMapbox::networkReplyFinished() QByteArray routeReply = reply->readAll(); QGeoRouteReply::Error error = parser->parseReply(routes, errorString, routeReply); + // Setting the request into the result + for (QGeoRoute &route : routes) { + route.setRequest(request()); + for (QGeoRoute &leg: route.routeLegs()) { + leg.setRequest(request()); + } + } QVariantMap metadata; metadata["osrm.reply-json"] = routeReply; diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp index dfebc20d..ed36cd5f 100644 --- a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp +++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp @@ -106,12 +106,12 @@ QSGNode *QGeoMapMapboxGLPrivate::updateSceneGraph(QSGNode *node, QQuickWindow *w if (m_useFBO) { QSGMapboxGLTextureNode *mbglNode = new QSGMapboxGLTextureNode(m_settings, m_viewportSize, window->devicePixelRatio(), q); QObject::connect(mbglNode->map(), &QMapboxGL::mapChanged, q, &QGeoMapMapboxGL::onMapChanged); - m_syncState = MapTypeSync | CameraDataSync | ViewportSync; + m_syncState = MapTypeSync | CameraDataSync | ViewportSync | VisibleAreaSync; node = mbglNode; } else { QSGMapboxGLRenderNode *mbglNode = new QSGMapboxGLRenderNode(m_settings, m_viewportSize, window->devicePixelRatio(), q); QObject::connect(mbglNode->map(), &QMapboxGL::mapChanged, q, &QGeoMapMapboxGL::onMapChanged); - m_syncState = MapTypeSync | CameraDataSync | ViewportSync; + m_syncState = MapTypeSync | CameraDataSync | ViewportSync | VisibleAreaSync; node = mbglNode; } } @@ -125,7 +125,19 @@ QSGNode *QGeoMapMapboxGLPrivate::updateSceneGraph(QSGNode *node, QQuickWindow *w map->setStyleUrl(m_activeMapType.name()); } - if (m_syncState & CameraDataSync) { + if (m_syncState & VisibleAreaSync) { + if (m_visibleArea.isEmpty()) { + map->setMargins(QMargins()); + } else { + QMargins margins(m_visibleArea.x(), // left + m_visibleArea.y(), // top + m_viewportSize.width() - m_visibleArea.width() - m_visibleArea.x(), // right + m_viewportSize.height() - m_visibleArea.height() - m_visibleArea.y()); // bottom + map->setMargins(margins); + } + } + + if (m_syncState & CameraDataSync || m_syncState & VisibleAreaSync) { map->setZoom(zoomLevelFrom256(m_cameraData.zoomLevel() , MBGL_TILE_SIZE)); map->setBearing(m_cameraData.bearing()); map->setPitch(m_cameraData.tilt()); @@ -291,6 +303,25 @@ void QGeoMapMapboxGLPrivate::changeActiveMapType(const QGeoMapType) emit q->sgNodeChanged(); } +void QGeoMapMapboxGLPrivate::setVisibleArea(const QRectF &visibleArea) +{ + Q_Q(QGeoMapMapboxGL); + const QRectF va = clampVisibleArea(visibleArea); + if (va == m_visibleArea) + return; + + m_visibleArea = va; + m_geoProjection->setVisibleArea(va); + + m_syncState = m_syncState | VisibleAreaSync; + emit q->sgNodeChanged(); +} + +QRectF QGeoMapMapboxGLPrivate::visibleArea() const +{ + return m_visibleArea; +} + void QGeoMapMapboxGLPrivate::syncStyleChanges(QMapboxGL *map) { for (const auto& change : m_styleChanges) { @@ -347,7 +378,7 @@ QString QGeoMapMapboxGL::copyrightsStyleSheet() const return QStringLiteral("* { vertical-align: middle; font-weight: normal }"); } -void QGeoMapMapboxGL::setMapboxGLSettings(const QMapboxGLSettings& settings) +void QGeoMapMapboxGL::setMapboxGLSettings(const QMapboxGLSettings& settings, bool useChinaEndpoint) { Q_D(QGeoMapMapboxGL); @@ -355,8 +386,13 @@ void QGeoMapMapboxGL::setMapboxGLSettings(const QMapboxGLSettings& settings) // If the access token is not set, use the development access token. // This will only affect mapbox:// styles. + // Mapbox China requires a China-specific access token. if (d->m_settings.accessToken().isEmpty()) { - d->m_settings.setAccessToken(developmentToken); + if (useChinaEndpoint) { + qWarning("Mapbox China requires an access token: https://www.mapbox.com/contact/sales"); + } else { + d->m_settings.setAccessToken(developmentToken); + } } } @@ -376,7 +412,8 @@ QGeoMap::Capabilities QGeoMapMapboxGL::capabilities() const { return Capabilities(SupportsVisibleRegion | SupportsSetBearing - | SupportsAnchoringCoordinate); + | SupportsAnchoringCoordinate + | SupportsVisibleArea ); } QSGNode *QGeoMapMapboxGL::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window) diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h index 0ffaf4ea..5fc2260e 100644 --- a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h +++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h @@ -54,7 +54,7 @@ public: virtual ~QGeoMapMapboxGL(); QString copyrightsStyleSheet() const override; - void setMapboxGLSettings(const QMapboxGLSettings &); + void setMapboxGLSettings(const QMapboxGLSettings &, bool useChinaEndpoint); void setUseFBO(bool); void setMapItemsBefore(const QString &); Capabilities capabilities() const override; diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl_p.h b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl_p.h index ffb06208..f07b4c98 100644 --- a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl_p.h +++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl_p.h @@ -43,6 +43,7 @@ #include <QtCore/QSharedPointer> #include <QtCore/QTimer> #include <QtCore/QVariant> +#include <QtCore/QRectF> #include <QtLocation/private/qgeomap_p_p.h> #include <QtLocation/private/qgeomapparameter_p.h> @@ -70,9 +71,10 @@ public: /* Data members */ enum SyncState : int { NoSync = 0, - ViewportSync = 1 << 0, - CameraDataSync = 1 << 1, - MapTypeSync = 1 << 2 + ViewportSync = 1 << 0, + CameraDataSync = 1 << 1, + MapTypeSync = 1 << 2, + VisibleAreaSync = 1 << 3 }; Q_DECLARE_FLAGS(SyncStates, SyncState); @@ -96,11 +98,16 @@ protected: void changeCameraData(const QGeoCameraData &oldCameraData) override; void changeActiveMapType(const QGeoMapType mapType) override; + void setVisibleArea(const QRectF &visibleArea) override; + QRectF visibleArea() const override; + private: Q_DISABLE_COPY(QGeoMapMapboxGLPrivate); void syncStyleChanges(QMapboxGL *map); void threadedRenderingHack(QQuickWindow *window, QMapboxGL *map); + + QRectF m_visibleArea; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGeoMapMapboxGLPrivate::SyncStates) diff --git a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp index cc48afb2..d2463106 100644 --- a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp +++ b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp @@ -69,30 +69,45 @@ QGeoMappingManagerEngineMapboxGL::QGeoMappingManagerEngineMapboxGL(const QVarian int mapId = 0; const QByteArray pluginName = "mapboxgl"; - mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/streets-v10"), - tr("Streets"), false, false, ++mapId, pluginName, cameraCaps); - mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/basic-v9"), - tr("Basic"), false, false, ++mapId, pluginName, cameraCaps); - mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/bright-v9"), - tr("Bright"), false, false, ++mapId, pluginName, cameraCaps); - mapTypes << QGeoMapType(QGeoMapType::TerrainMap, QStringLiteral("mapbox://styles/mapbox/outdoors-v10"), - tr("Outdoors"), false, false, ++mapId, pluginName, cameraCaps); - mapTypes << QGeoMapType(QGeoMapType::SatelliteMapDay, QStringLiteral("mapbox://styles/mapbox/satellite-v9"), - tr("Satellite"), false, false, ++mapId, pluginName, cameraCaps); - mapTypes << QGeoMapType(QGeoMapType::HybridMap, QStringLiteral("mapbox://styles/mapbox/satellite-streets-v10"), - tr("Satellite Streets"), false, false, ++mapId, pluginName, cameraCaps); - mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/light-v9"), - tr("Light"), false, false, ++mapId, pluginName, cameraCaps); - mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/dark-v9"), - tr("Dark"), false, false, ++mapId, pluginName, cameraCaps); - mapTypes << QGeoMapType(QGeoMapType::TransitMap, QStringLiteral("mapbox://styles/mapbox/navigation-preview-day-v2"), - tr("Navigation Preview Day"), false, false, ++mapId, pluginName, cameraCaps); - mapTypes << QGeoMapType(QGeoMapType::TransitMap, QStringLiteral("mapbox://styles/mapbox/navigation-preview-night-v2"), - tr("Navigation Preview Night"), false, true, ++mapId, pluginName, cameraCaps); - mapTypes << QGeoMapType(QGeoMapType::CarNavigationMap, QStringLiteral("mapbox://styles/mapbox/navigation-guidance-day-v2"), - tr("Navigation Guidance Day"), false, false, ++mapId, pluginName, cameraCaps); - mapTypes << QGeoMapType(QGeoMapType::CarNavigationMap, QStringLiteral("mapbox://styles/mapbox/navigation-guidance-night-v2"), - tr("Navigation Guidance Night"), false, true, ++mapId, pluginName, cameraCaps); + if (parameters.contains(QStringLiteral("mapboxgl.china"))) { + m_useChinaEndpoint = parameters.value(QStringLiteral("mapboxgl.china")).toBool(); + } + + if (m_useChinaEndpoint) { + m_settings.setApiBaseUrl(QStringLiteral("https://api.mapbox.cn")); + + mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/streets-zh-v1"), + tr("China Streets"), false, false, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/light-zh-v1"), + tr("China Light"), false, false, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/dark-zh-v1"), + tr("China Dark"), false, false, ++mapId, pluginName, cameraCaps); + } else { + mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/streets-v10"), + tr("Streets"), false, false, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/basic-v9"), + tr("Basic"), false, false, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/bright-v9"), + tr("Bright"), false, false, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::TerrainMap, QStringLiteral("mapbox://styles/mapbox/outdoors-v10"), + tr("Outdoors"), false, false, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::SatelliteMapDay, QStringLiteral("mapbox://styles/mapbox/satellite-v9"), + tr("Satellite"), false, false, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::HybridMap, QStringLiteral("mapbox://styles/mapbox/satellite-streets-v10"), + tr("Satellite Streets"), false, false, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/light-v9"), + tr("Light"), false, false, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/dark-v9"), + tr("Dark"), false, false, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::TransitMap, QStringLiteral("mapbox://styles/mapbox/navigation-preview-day-v2"), + tr("Navigation Preview Day"), false, false, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::TransitMap, QStringLiteral("mapbox://styles/mapbox/navigation-preview-night-v2"), + tr("Navigation Preview Night"), false, true, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::CarNavigationMap, QStringLiteral("mapbox://styles/mapbox/navigation-guidance-day-v2"), + tr("Navigation Guidance Day"), false, false, ++mapId, pluginName, cameraCaps); + mapTypes << QGeoMapType(QGeoMapType::CarNavigationMap, QStringLiteral("mapbox://styles/mapbox/navigation-guidance-night-v2"), + tr("Navigation Guidance Night"), false, true, ++mapId, pluginName, cameraCaps); + } if (parameters.contains(QStringLiteral("mapboxgl.mapping.additional_style_urls"))) { const QString ids = parameters.value(QStringLiteral("mapboxgl.mapping.additional_style_urls")).toString(); @@ -156,7 +171,7 @@ QGeoMappingManagerEngineMapboxGL::~QGeoMappingManagerEngineMapboxGL() QGeoMap *QGeoMappingManagerEngineMapboxGL::createMap() { QGeoMapMapboxGL* map = new QGeoMapMapboxGL(this, 0); - map->setMapboxGLSettings(m_settings); + map->setMapboxGLSettings(m_settings, m_useChinaEndpoint); map->setUseFBO(m_useFBO); map->setMapItemsBefore(m_mapItemsBefore); diff --git a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h index b3afe77b..9ceb8ccc 100644 --- a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h +++ b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h @@ -59,6 +59,7 @@ public: private: QMapboxGLSettings m_settings; bool m_useFBO = true; + bool m_useChinaEndpoint = false; QString m_mapItemsBefore; }; diff --git a/src/plugins/geoservices/mapboxgl/qgeoserviceproviderpluginmapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeoserviceproviderpluginmapboxgl.cpp index dd25c99e..afa723a5 100644 --- a/src/plugins/geoservices/mapboxgl/qgeoserviceproviderpluginmapboxgl.cpp +++ b/src/plugins/geoservices/mapboxgl/qgeoserviceproviderpluginmapboxgl.cpp @@ -40,16 +40,10 @@ #include <QtGui/QOpenGLContext> -static void initResources() -{ - Q_INIT_RESOURCE(mapboxgl); -} - QT_BEGIN_NAMESPACE QGeoServiceProviderFactoryMapboxGL::QGeoServiceProviderFactoryMapboxGL() { - initResources(); } QGeoCodingManagerEngine *QGeoServiceProviderFactoryMapboxGL::createGeocodingManagerEngine( diff --git a/src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp b/src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp index 6c47d3ee..b45fdef1 100644 --- a/src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp +++ b/src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp @@ -41,6 +41,7 @@ #include <QtCore/QRegularExpression> #include <QtCore/QStringList> #include <QtPositioning/QGeoPath> +#include <QtPositioning/QGeoPolygon> #include <QtQml/QJSValue> namespace { @@ -66,7 +67,7 @@ QString getId(QDeclarativeGeoMapItemBase *mapItem) // Mapbox GL supports geometry segments that spans above 180 degrees in // longitude. To keep visual expectations in parity with Qt, we need to adapt // the coordinates to always use the shortest path when in ambiguity. -bool geoRectangleCrossesDateLine(const QGeoRectangle &rect) { +static bool geoRectangleCrossesDateLine(const QGeoRectangle &rect) { return rect.topLeft().longitude() > rect.bottomRight().longitude(); } @@ -112,24 +113,35 @@ QMapbox::Feature featureFromMapCircle(QDeclarativeCircleMapItem *mapItem) return QMapbox::Feature(QMapbox::Feature::PolygonType, geometry, {}, getId(mapItem)); } -QMapbox::Feature featureFromMapPolygon(QDeclarativePolygonMapItem *mapItem) +static QMapbox::Coordinates qgeocoordinate2mapboxcoordinate(const QList<QGeoCoordinate> &crds, const bool crossesDateline, bool closed = false) { - const QGeoPath *path = static_cast<const QGeoPath *>(&mapItem->geoShape()); QMapbox::Coordinates coordinates; - const bool crossesDateline = geoRectangleCrossesDateLine(path->boundingGeoRectangle()); - for (const QGeoCoordinate &coordinate : path->path()) { + for (const QGeoCoordinate &coordinate : crds) { if (!coordinates.empty() && crossesDateline && qAbs(coordinate.longitude() - coordinates.last().second) > 180.0) { coordinates << QMapbox::Coordinate { coordinate.latitude(), coordinate.longitude() + (coordinate.longitude() >= 0 ? -360.0 : 360.0) }; } else { coordinates << QMapbox::Coordinate { coordinate.latitude(), coordinate.longitude() }; } } + if (closed && !coordinates.empty() && coordinates.last() != coordinates.first()) + coordinates.append(coordinates.first()); // closing the path + return coordinates; +} - if (!coordinates.empty()) - coordinates.append(coordinates.first()); // closing the path - - QMapbox::CoordinatesCollections geometry { { coordinates } }; +QMapbox::Feature featureFromMapPolygon(QDeclarativePolygonMapItem *mapItem) +{ + const QGeoPolygon *polygon = static_cast<const QGeoPolygon *>(&mapItem->geoShape()); + const bool crossesDateline = geoRectangleCrossesDateLine(polygon->boundingGeoRectangle()); + QMapbox::CoordinatesCollections geometry; + QMapbox::CoordinatesCollection poly; + QMapbox::Coordinates coordinates = qgeocoordinate2mapboxcoordinate(polygon->path(), crossesDateline, true); + poly.push_back(coordinates); + for (int i = 0; i < polygon->holesCount(); ++i) { + coordinates = qgeocoordinate2mapboxcoordinate(polygon->holePath(i), crossesDateline, true); + poly.push_back(coordinates); + } + geometry.push_back(poly); return QMapbox::Feature(QMapbox::Feature::PolygonType, geometry, {}, getId(mapItem)); } @@ -186,8 +198,7 @@ QList<QSharedPointer<QMapboxGLStyleChange>> QMapboxGLStyleChange::addMapParamete { static const QStringList acceptedParameterTypes = QStringList() << QStringLiteral("paint") << QStringLiteral("layout") << QStringLiteral("filter") - << QStringLiteral("layer") << QStringLiteral("source") << QStringLiteral("image") - << QStringLiteral("margins"); + << QStringLiteral("layer") << QStringLiteral("source") << QStringLiteral("image"); QList<QSharedPointer<QMapboxGLStyleChange>> changes; @@ -213,9 +224,6 @@ QList<QSharedPointer<QMapboxGLStyleChange>> QMapboxGLStyleChange::addMapParamete case 5: // image changes << QMapboxGLStyleAddImage::fromMapParameter(param); break; - case 6: // margins - changes << QMapboxGLMapMargins::fromMapParameter(param); - break; } return changes; @@ -641,38 +649,3 @@ QSharedPointer<QMapboxGLStyleChange> QMapboxGLStyleAddImage::fromMapParameter(QG return QSharedPointer<QMapboxGLStyleChange>(image); } - -// QMapboxGLMapMargins - -void QMapboxGLMapMargins::apply(QMapboxGL *map) -{ - // FIXME: Qt projection handlers are not yet aware of these margins, - // thus map items placement, {to,from}Coordinate, mouse area, etc. - // will require manual fixups. - map->setMargins(m_margins); -} - -QSharedPointer<QMapboxGLStyleChange> QMapboxGLMapMargins::fromMapParameter(QGeoMapParameter *param) -{ - Q_ASSERT(param->type() == "margins"); - - auto mapMargins = new QMapboxGLMapMargins(); - - QVariant leftMargin = param->property("left"); - if (leftMargin.isValid()) - mapMargins->m_margins.setLeft(leftMargin.toInt()); - - QVariant topMargin = param->property("top"); - if (topMargin.isValid()) - mapMargins->m_margins.setTop(topMargin.toInt()); - - QVariant rightMargin = param->property("right"); - if (rightMargin.isValid()) - mapMargins->m_margins.setRight(rightMargin.toInt()); - - QVariant bottomMargin = param->property("bottom"); - if (bottomMargin.isValid()) - mapMargins->m_margins.setBottom(bottomMargin.toInt()); - - return QSharedPointer<QMapboxGLStyleChange>(mapMargins); -} diff --git a/src/plugins/geoservices/mapboxgl/qmapboxglstylechange_p.h b/src/plugins/geoservices/mapboxgl/qmapboxglstylechange_p.h index 38aa87f8..fd5b9af4 100644 --- a/src/plugins/geoservices/mapboxgl/qmapboxglstylechange_p.h +++ b/src/plugins/geoservices/mapboxgl/qmapboxglstylechange_p.h @@ -190,17 +190,4 @@ private: QImage m_sprite; }; -class QMapboxGLMapMargins : public QMapboxGLStyleChange -{ -public: - static QSharedPointer<QMapboxGLStyleChange> fromMapParameter(QGeoMapParameter *); - - void apply(QMapboxGL *map) override; - -private: - QMapboxGLMapMargins() = default; - - QMargins m_margins; -}; - #endif // QQMAPBOXGLSTYLECHANGE_P_H diff --git a/src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.cpp b/src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.cpp index 9808b539..28aa930f 100644 --- a/src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.cpp +++ b/src/plugins/geoservices/nokia/placesv2/qplacesearchreplyhere.cpp @@ -46,6 +46,7 @@ #include <QtLocation/QPlaceIcon> #include <QtLocation/QPlaceResult> #include <QtLocation/QPlaceProposedSearchResult> +#include <QtLocation/private/qplacesearchrequest_p.h> #include <QtCore/QDebug> @@ -113,15 +114,24 @@ void QPlaceSearchReplyHere::replyFinished() results.append(parseSearchResult(item)); } + QPlaceSearchRequest r_orig = request(); + QPlaceSearchRequestPrivate *rpimpl_orig = QPlaceSearchRequestPrivate::get(r_orig); + if (resultsObject.contains(QStringLiteral("next"))) { QPlaceSearchRequest request; request.setSearchContext(QUrl(resultsObject.value(QStringLiteral("next")).toString())); + QPlaceSearchRequestPrivate *rpimpl = QPlaceSearchRequestPrivate::get(request); + rpimpl->related = true; + rpimpl->page = rpimpl_orig->page + 1; setNextPageRequest(request); } if (resultsObject.contains(QStringLiteral("previous"))) { QPlaceSearchRequest request; request.setSearchContext(QUrl(resultsObject.value(QStringLiteral("previous")).toString())); + QPlaceSearchRequestPrivate *rpimpl = QPlaceSearchRequestPrivate::get(request); + rpimpl->related = true; + rpimpl->page = rpimpl_orig->page - 1; setPreviousPageRequest(request); } diff --git a/src/plugins/geoservices/nokia/qgeoroutexmlparser.cpp b/src/plugins/geoservices/nokia/qgeoroutexmlparser.cpp index 8e436a97..65e39dee 100644 --- a/src/plugins/geoservices/nokia/qgeoroutexmlparser.cpp +++ b/src/plugins/geoservices/nokia/qgeoroutexmlparser.cpp @@ -40,9 +40,12 @@ #include <QStringList> #include <QString> #include <QtCore/QThreadPool> +#include <QDebug> #include <QtPositioning/QGeoRectangle> +#include <QtPositioning/QGeoPath> #include <QtLocation/QGeoRoute> +#include <QtLocation/private/qgeoroutesegment_p.h> QT_BEGIN_NAMESPACE @@ -65,6 +68,10 @@ QGeoRouteXmlParser::~QGeoRouteXmlParser() void QGeoRouteXmlParser::parse(const QByteArray &data) { m_data = data; +// QFile file("/tmp/here.xml"); +// file.open(QIODevice::WriteOnly); +// file.write(data); +// file.close(); QThreadPool::globalInstance()->start(this); } @@ -134,8 +141,9 @@ bool QGeoRouteXmlParser::parseRoute(QGeoRoute *route) { Q_ASSERT(m_reader->isStartElement() && m_reader->name() == "Route"); m_maneuvers.clear(); - m_segments.clear(); - +// m_segments.clear(); + m_legs.clear(); + int legIndex = 0; m_reader->readNext(); while (!(m_reader->tokenType() == QXmlStreamReader::EndElement && m_reader->name() == "Route") && !m_reader->hasError()) { @@ -161,7 +169,7 @@ bool QGeoRouteXmlParser::parseRoute(QGeoRoute *route) return false; route->setBounds(bounds); } else if (m_reader->name() == "Leg") { - if (!parseLeg()) + if (!parseLeg(legIndex++)) return false; } else if (m_reader->name() == "Summary") { if (!parseSummary(route)) @@ -179,20 +187,32 @@ bool QGeoRouteXmlParser::parseRoute(QGeoRoute *route) return postProcessRoute(route); } -bool QGeoRouteXmlParser::parseLeg() +bool QGeoRouteXmlParser::parseLeg(int legIndex) { - Q_ASSERT(m_reader->isStartElement() && m_reader->name() == "Leg"); - + Q_ASSERT(m_reader->isStartElement() && m_reader->name() == QStringLiteral("Leg")); + QGeoRouteLeg leg; + leg.setLegIndex(legIndex); m_reader->readNext(); - while (!(m_reader->tokenType() == QXmlStreamReader::EndElement && m_reader->name() == "Leg") && + QList<QGeoManeuverContainer> maneuvers; + QList<QGeoRouteSegmentContainer> links; + while (!(m_reader->tokenType() == QXmlStreamReader::EndElement + && m_reader->name() == QStringLiteral("Leg")) && !m_reader->hasError()) { if (m_reader->tokenType() == QXmlStreamReader::StartElement) { - if (m_reader->name() == "Maneuver") { - if (!parseManeuver()) - return false; - } else if (m_reader->name() == "Link") { - if (!parseLink()) + if (m_reader->name() == QStringLiteral("Maneuver")) { + if (!parseManeuver(maneuvers)) return false; + } +// Currently unused, after requesting shape attribute in maneuvers. +// Links, however, contain additional info, such as speed limits, and might become needed in the future. +// else if (m_reader->name() == QStringLiteral("Link")) { +// if (!parseLink(links)) +// return false; +// } + else if (m_reader->name() == "TravelTime") { + leg.setTravelTime(qRound(m_reader->readElementText().toDouble())); + } else if (m_reader->name() == "Length") { + leg.setDistance(m_reader->readElementText().toDouble()); } else { m_reader->skipCurrentElement(); } @@ -200,81 +220,98 @@ bool QGeoRouteXmlParser::parseLeg() m_reader->readNext(); } - return !m_reader->hasError(); + if (m_reader->hasError()) + return false; + + m_legs << leg; +// m_segments << links; + m_maneuvers << maneuvers; + return true; } +//static bool fuzzyCompare(const QGeoCoordinate &a, const QGeoCoordinate& b) +//{ +// return qFuzzyCompare(a.latitude(), b.latitude()) && qFuzzyCompare(a.longitude(), b.longitude()); +//} + bool QGeoRouteXmlParser::postProcessRoute(QGeoRoute *route) { - QList<QGeoRouteSegment> routeSegments; + QList<QList<QGeoRouteSegment>> legSegments; + Q_ASSERT(m_maneuvers.size()); + - int maneuverIndex = 0; - for (int i = 0; i < m_segments.count(); ++i) { - // In case there is a maneuver in the middle of the list with no - // link ID attached, attach it to the next available segment - while ((maneuverIndex < m_maneuvers.size() - 1) && m_maneuvers.at(maneuverIndex).toId.isEmpty()) { + // Step 3: populate the linkMap, linkId -> linkContainer + for (int i = 0; i < m_maneuvers.size(); i++) { + legSegments << QList<QGeoRouteSegment>(); + QList<QGeoRouteSegment> &segments = legSegments[i]; + QList<QGeoManeuverContainer> &maneuvers = m_maneuvers[i]; + for (int j = 0; j < m_maneuvers.at(i).size(); j++) { + QGeoManeuverContainer &maneuver = maneuvers[j]; QGeoRouteSegment segment; - segment.setManeuver(m_maneuvers.at(maneuverIndex).maneuver); - QList<QGeoCoordinate> path; // use instruction position as one point segment path - path.append(m_maneuvers.at(maneuverIndex).maneuver.position()); - segment.setPath(path); - routeSegments.append(segment); - ++maneuverIndex; - } - QGeoRouteSegment segment = m_segments.at(i).segment; - if ((maneuverIndex < m_maneuvers.size()) && m_segments.at(i).id == m_maneuvers.at(maneuverIndex).toId) { - segment.setManeuver(m_maneuvers.at(maneuverIndex).maneuver); - ++maneuverIndex; + QVariantMap extendedAttributes; + extendedAttributes["first"] = maneuver.first; + extendedAttributes["last"] = maneuver.last; + extendedAttributes["legIndex"] = i; + extendedAttributes["id"] = maneuver.id; + extendedAttributes["toLink"] = maneuver.toLink; + extendedAttributes["index"] = j; + maneuver.maneuver.setExtendedAttributes(extendedAttributes); + + segment.setDistance(maneuver.maneuver.distanceToNextInstruction()); + segment.setTravelTime(maneuver.maneuver.timeToNextInstruction()); + segment.setPath(maneuver.path); + segment.setManeuver(maneuver.maneuver); + segments << segment; } - routeSegments.append(segment); - } - - // For the final maneuver in the list, make sure to attach it to the very - // last segment on the path, this is why we don't process the last - // maneuver in the loop above - while (maneuverIndex < m_maneuvers.size()) { - QGeoRouteSegment segment; - segment.setManeuver(m_maneuvers.at(maneuverIndex).maneuver); - QList<QGeoCoordinate> path; // use instruction position as one point segment path - path.append(m_maneuvers.at(maneuverIndex).maneuver.position()); - segment.setPath(path); - - routeSegments.append(segment); - ++maneuverIndex; } - QList<QGeoRouteSegment> compactedRouteSegments; - compactedRouteSegments.append(routeSegments.first()); - routeSegments.removeFirst(); - - while (routeSegments.size() > 0) { - QGeoRouteSegment segment = routeSegments.first(); - routeSegments.removeFirst(); - - QGeoRouteSegment lastSegment = compactedRouteSegments.last(); - - if (lastSegment.maneuver().isValid()) { - compactedRouteSegments.append(segment); - } else { - compactedRouteSegments.removeLast(); - lastSegment.setDistance(lastSegment.distance() + segment.distance()); - lastSegment.setTravelTime(lastSegment.travelTime() + segment.travelTime()); - QList<QGeoCoordinate> path = lastSegment.path(); - path.append(segment.path()); - lastSegment.setPath(path); - lastSegment.setManeuver(segment.maneuver()); - compactedRouteSegments.append(lastSegment); + // Step 7: connect all segments. + QGeoRouteSegment segment; + QGeoRouteSegment firstSegment; + for (auto &segments: legSegments) { + for (int j = 0; j < segments.size(); j++) { + if (segment.isValid()) { + segment.setNextRouteSegment(segments[j]); + } else { + firstSegment = segments[j]; + } + segment = segments[j]; + if (j == segments.size() - 1) { + QGeoRouteSegmentPrivate *sp = QGeoRouteSegmentPrivate::get(segment); + sp->setLegLastSegment(true); + } } } - if (compactedRouteSegments.size() > 0) { - route->setFirstRouteSegment(compactedRouteSegments.at(0)); - for (int i = 0; i < compactedRouteSegments.size() - 1; ++i) - compactedRouteSegments[i].setNextRouteSegment(compactedRouteSegments.at(i + 1)); + if (firstSegment.isValid()) + route->setFirstRouteSegment(firstSegment); + + // Step 8: fill route legs. + for (int i = 0; i < m_legs.size(); i++) { + m_legs[i].setTravelMode(route->travelMode()); + m_legs[i].setRequest(route->request()); + m_legs[i].setOverallRoute(*route); + m_legs[i].setLegIndex(i); + + m_legs[i].setFirstRouteSegment(legSegments[i].first()); + + // handle path + QList<QGeoCoordinate> path; + QGeoRouteSegment s = m_legs[i].firstRouteSegment(); + while (s.isValid()) { + path.append(s.path()); + if (s.isLegLastSegment()) + break; + s = s.nextRouteSegment(); + } + m_legs[i].setPath(path); + m_legs[i].setBounds(QGeoPath(path).boundingGeoRectangle()); } - + route->setRouteLegs(m_legs); + m_legs.clear(); +// m_segments.clear(); m_maneuvers.clear(); - m_segments.clear(); return true; } @@ -394,7 +431,7 @@ bool QGeoRouteXmlParser::parseCoordinates(QGeoCoordinate &coord) return !m_reader->hasError(); } -bool QGeoRouteXmlParser::parseManeuver() +bool QGeoRouteXmlParser::parseManeuver(QList<QGeoManeuverContainer> &maneuvers) { Q_ASSERT(m_reader->isStartElement() && m_reader->name() == "Maneuver"); @@ -415,8 +452,14 @@ bool QGeoRouteXmlParser::parseManeuver() maneuverContainter.maneuver.setPosition(coordinates); } else if (m_reader->name() == "Instruction") { maneuverContainter.maneuver.setInstructionText(m_reader->readElementText()); + } else if (m_reader->name() == "Shape") { + QString elementName = m_reader->name().toString(); + QList<QGeoCoordinate> path; + if (!parseGeoPoints(m_reader->readElementText(), &path, elementName)) + return false; + maneuverContainter.path = path; } else if (m_reader->name() == "ToLink") { - maneuverContainter.toId = m_reader->readElementText(); + maneuverContainter.toLink = m_reader->readElementText(); } else if (m_reader->name() == "TravelTime") { maneuverContainter.maneuver.setTimeToNextInstruction(qRound(m_reader->readElementText().toDouble())); } else if (m_reader->name() == "Length") { @@ -457,11 +500,11 @@ bool QGeoRouteXmlParser::parseManeuver() if (m_reader->hasError()) return false; - m_maneuvers.append(maneuverContainter); + maneuvers.append(maneuverContainter); return true; } -bool QGeoRouteXmlParser::parseLink() +bool QGeoRouteXmlParser::parseLink(QList<QGeoRouteSegmentContainer> &links) { Q_ASSERT(m_reader->isStartElement() && m_reader->name() == QStringLiteral("Link")); m_reader->readNext(); @@ -498,8 +541,7 @@ bool QGeoRouteXmlParser::parseLink() if (m_reader->hasError()) return false; - - m_segments.append(segmentContainer); + links.append(segmentContainer); return true; } diff --git a/src/plugins/geoservices/nokia/qgeoroutexmlparser.h b/src/plugins/geoservices/nokia/qgeoroutexmlparser.h index e2feb728..7f2cc149 100644 --- a/src/plugins/geoservices/nokia/qgeoroutexmlparser.h +++ b/src/plugins/geoservices/nokia/qgeoroutexmlparser.h @@ -45,6 +45,7 @@ #include <QtLocation/QGeoRouteRequest> #include <QtLocation/QGeoRouteSegment> #include <QtLocation/QGeoManeuver> +#include <QtLocation/qgeoroute.h> QT_BEGIN_NAMESPACE @@ -58,7 +59,12 @@ class QGeoManeuverContainer public: QGeoManeuver maneuver; QString id; - QString toId; + QString toLink; // Id of the link this maneuver brings into + int legIndex = 0; + int index = 0; + QList<QGeoCoordinate> path; + bool first = false; + bool last = false; }; class QGeoRouteSegmentContainer @@ -67,6 +73,11 @@ public: QGeoRouteSegment segment; QString id; QString maneuverId; + + bool operator ==(const QGeoRouteSegmentContainer &other) const + { + return ( segment == other.segment && id == other.id && maneuverId == other.maneuverId ); + } }; class QGeoDynamicSpeedInfoContainer @@ -104,9 +115,9 @@ private: bool parseMode(QGeoRoute *route); bool parseSummary(QGeoRoute *route); bool parseGeoPoints(const QString &strPoints, QList<QGeoCoordinate> *geoPoints, const QString &elementName); - bool parseLeg(); - bool parseManeuver(); - bool parseLink(); + bool parseLeg(int legIndex); + bool parseManeuver(QList<QGeoManeuverContainer> &maneuvers); + bool parseLink(QList<QGeoRouteSegmentContainer> &links); bool postProcessRoute(QGeoRoute *route); bool parseBoundingBox(QGeoRectangle &bounds); @@ -117,8 +128,9 @@ private: QXmlStreamReader *m_reader; QList<QGeoRoute> m_results; - QList<QGeoManeuverContainer> m_maneuvers; - QList<QGeoRouteSegmentContainer> m_segments; + QList<QGeoRouteLeg> m_legs; + QList<QList<QGeoManeuverContainer>> m_maneuvers; + //QList<QList<QGeoRouteSegmentContainer>> m_segments; }; QT_END_NAMESPACE diff --git a/src/plugins/geoservices/nokia/qgeoroutingmanagerengine_nokia.cpp b/src/plugins/geoservices/nokia/qgeoroutingmanagerengine_nokia.cpp index 1ae01636..73b998b1 100644 --- a/src/plugins/geoservices/nokia/qgeoroutingmanagerengine_nokia.cpp +++ b/src/plugins/geoservices/nokia/qgeoroutingmanagerengine_nokia.cpp @@ -399,46 +399,36 @@ QString QGeoRoutingManagerEngineNokia::routeRequestString(const QGeoRouteRequest requestString += trimDouble(area.bottomRight().longitude()); } -// TODO: work out what was going on here -// - segment and instruction/maneuever functions are mixed and matched -// - tried to implement sensible equivalents below -// QStringList legAttributes; -// if (request.instructionDetail() & QGeoRouteRequest::BasicSegmentData) { -// requestString += "&linkattributes=sh,le"; //shape,length -// legAttributes.append("links"); -// } -// -// if (request.instructionDetail() & QGeoRouteRequest::BasicInstructions) { -// legAttributes.append("maneuvers"); -// requestString += "&maneuverattributes=po,tt,le,di"; //position,traveltime,length,direction -// if (!(request.instructionDetail() & QGeoRouteRequest::NoSegmentData)) -// requestString += ",li"; //link -// } - QStringList legAttributes; - if (request.segmentDetail() & QGeoRouteRequest::BasicSegmentData) { +// if (request.segmentDetail() & QGeoRouteRequest::BasicSegmentData) // QTBUG-70501, this code expects to find links + { requestString += "&linkattributes=sh,le"; //shape,length legAttributes.append("links"); } - if (request.maneuverDetail() & QGeoRouteRequest::BasicManeuvers) { +// if (request.maneuverDetail() & QGeoRouteRequest::BasicManeuvers) // QTBUG-70501, this code expects to find maneuvers + { legAttributes.append("maneuvers"); - requestString += "&maneuverattributes=po,tt,le,di"; //position,traveltime,length,direction + //requestString += "&maneuverattributes=po,tt,le,di"; //position,traveltime,length,direction + requestString += "&maneuverattributes=all"; if (!(request.segmentDetail() & QGeoRouteRequest::NoSegmentData)) requestString += ",li"; //link } + // Handle QTBUG-70502, when API fixes it requestString += "&routeattributes=sm,sh,bb,lg"; //summary,shape,boundingBox,legs if (legAttributes.count() > 0) { requestString += "&legattributes="; requestString += legAttributes.join(","); } + // Handle QTBUG-70503, when API fixes it requestString += "&departure="; requestString += QDateTime::currentDateTime().toUTC().toString("yyyy-MM-ddThh:mm:ssZ"); requestString += "&instructionformat=text"; + // ToDo: make this request-able requestString += "&metricSystem="; if (QLocale::MetricSystem == measurementSystem()) requestString += "metric"; @@ -447,6 +437,7 @@ QString QGeoRoutingManagerEngineNokia::routeRequestString(const QGeoRouteRequest const QLocale loc(locale()); + // ToDo: make this request-able if (QLocale::C != loc.language() && QLocale::AnyLanguage != loc.language()) { requestString += "&language="; requestString += loc.name(); diff --git a/src/plugins/geoservices/nokia/qgeoserviceproviderplugin_nokia.cpp b/src/plugins/geoservices/nokia/qgeoserviceproviderplugin_nokia.cpp index f68a0d99..e4ef86d6 100644 --- a/src/plugins/geoservices/nokia/qgeoserviceproviderplugin_nokia.cpp +++ b/src/plugins/geoservices/nokia/qgeoserviceproviderplugin_nokia.cpp @@ -47,11 +47,6 @@ #include <QNetworkProxy> #include <QCoreApplication> -static void initResources() -{ - Q_INIT_RESOURCE(nokia); -} - QT_BEGIN_NAMESPACE namespace @@ -117,7 +112,6 @@ namespace QGeoServiceProviderFactoryNokia::QGeoServiceProviderFactoryNokia() { - initResources(); } QGeoCodingManagerEngine *QGeoServiceProviderFactoryNokia::createGeocodingManagerEngine( diff --git a/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp b/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp index ab575463..5094b72e 100644 --- a/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp +++ b/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp @@ -52,6 +52,7 @@ #include <QtCore/QJsonArray> #include <QtCore/QJsonDocument> #include <QtCore/QJsonObject> +#include <QtCore/QRegularExpression> #include <QtCore/QStandardPaths> #include <QtCore/QUrlQuery> #include <QtNetwork/QNetworkProxy> @@ -690,13 +691,14 @@ QPlaceIcon QPlaceManagerEngineNokiaV2::icon(const QString &remotePath, QPlaceIcon icon; QVariantMap params; - QRegExp rx("(.*)(/icons/categories/.*)"); + QRegularExpression rx("(.*)(/icons/categories/.*)"); + QRegularExpressionMatch match = rx.match(remotePath); QString iconPrefix; QString nokiaIcon; - if (rx.indexIn(remotePath) != -1 && !rx.cap(1).isEmpty() && !rx.cap(2).isEmpty()) { - iconPrefix = rx.cap(1); - nokiaIcon = rx.cap(2); + if (match.hasMatch() && !match.capturedRef(1).isEmpty() && !match.capturedRef(2).isEmpty()) { + iconPrefix = match.captured(1); + nokiaIcon = match.captured(2); if (QFile::exists(m_localDataPath + nokiaIcon)) iconPrefix = QString::fromLatin1("file://") + m_localDataPath; diff --git a/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp b/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp index 732e8d72..af2a03b1 100644 --- a/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp +++ b/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp @@ -75,6 +75,13 @@ void QGeoRouteReplyOsm::networkReplyFinished() QList<QGeoRoute> routes; QString errorString; QGeoRouteReply::Error error = parser->parseReply(routes, errorString, reply->readAll()); + // Setting the request into the result + for (QGeoRoute &route : routes) { + route.setRequest(request()); + for (QGeoRoute &leg: route.routeLegs()) { + leg.setRequest(request()); + } + } if (error == QGeoRouteReply::NoError) { setRoutes(routes.mid(0, request().numberAlternativeRoutes() + 1)); diff --git a/src/plugins/geoservices/osm/qplacemanagerengineosm.cpp b/src/plugins/geoservices/osm/qplacemanagerengineosm.cpp index 3c201e41..be66414f 100644 --- a/src/plugins/geoservices/osm/qplacemanagerengineosm.cpp +++ b/src/plugins/geoservices/osm/qplacemanagerengineosm.cpp @@ -191,7 +191,7 @@ QPlaceSearchReply *QPlaceManagerEngineOsm::search(const QPlaceSearchRequest &req this, SLOT(replyError(QPlaceReply::Error,QString))); if (m_debugQuery) - reply->requestUrl = requestUrl.toString(); + reply->requestUrl = requestUrl.url(QUrl::None); return reply; } diff --git a/src/plugins/geoservices/osm/qplacesearchreplyosm.cpp b/src/plugins/geoservices/osm/qplacesearchreplyosm.cpp index 0228a975..80c50d1b 100644 --- a/src/plugins/geoservices/osm/qplacesearchreplyosm.cpp +++ b/src/plugins/geoservices/osm/qplacesearchreplyosm.cpp @@ -48,6 +48,7 @@ #include <QtPositioning/QGeoRectangle> #include <QtLocation/QPlaceResult> #include <QtLocation/QPlaceSearchRequest> +#include <QtLocation/private/qplacesearchrequest_p.h> QT_BEGIN_NAMESPACE @@ -135,6 +136,9 @@ void QPlaceSearchReplyOsm::replyFinished() parameters.insert(QStringLiteral("ExcludePlaceIds"), epi); r.setSearchContext(parameters); + QPlaceSearchRequestPrivate *rpimpl = QPlaceSearchRequestPrivate::get(r); + rpimpl->related = true; + rpimpl->page--; setPreviousPageRequest(r); } @@ -147,6 +151,9 @@ void QPlaceSearchReplyOsm::replyFinished() parameters.insert(QStringLiteral("ExcludePlaceIds"), epi); r.setSearchContext(parameters); + QPlaceSearchRequestPrivate *rpimpl = QPlaceSearchRequestPrivate::get(r); + rpimpl->related = true; + rpimpl->page++; setNextPageRequest(r); } |