diff options
16 files changed, 980 insertions, 1 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..046a02c9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/plugins/geoservices/3rdparty/mapbox-gl-native"] + path = src/plugins/geoservices/3rdparty/mapbox-gl-native + url = https://codereview.qt-project.org/p/qt/qtlocation-mapboxgl.git diff --git a/examples/location/mapviewer/main.cpp b/examples/location/mapviewer/main.cpp index 1d44a31b..3eedd8dd 100644 --- a/examples/location/mapviewer/main.cpp +++ b/examples/location/mapviewer/main.cpp @@ -102,8 +102,10 @@ int main(int argc, char *argv[]) if (!mapboxMapID.isEmpty()) parameters["mapbox.map_id"] = QString::fromLocal8Bit(mapboxMapID); - if (!mapboxAccessToken.isEmpty()) + if (!mapboxAccessToken.isEmpty()) { parameters["mapbox.access_token"] = QString::fromLocal8Bit(mapboxAccessToken); + parameters["mapboxgl.access_token"] = QString::fromLocal8Bit(mapboxAccessToken); + } if (!hereAppID.isEmpty()) parameters["here.app_id"] = QString::fromLocal8Bit(hereAppID); if (!hereToken.isEmpty()) diff --git a/src/location/doc/src/plugins/mapboxgl.qdoc b/src/location/doc/src/plugins/mapboxgl.qdoc new file mode 100644 index 00000000..ad71fc2c --- /dev/null +++ b/src/location/doc/src/plugins/mapboxgl.qdoc @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2017 Mapbox, Inc. +** Copyright (C) 2014 Canonical Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page location-plugin-mapboxgl.html +\title Qt Location Mapbox GL Plugin +\ingroup QtLocation-plugins + +\brief Uses Mapbox GL for location services. + +\section1 Overview + +This geo services plugin allows applications to access +\l {http://mapbox.com}{Mapbox} mapping services using the Qt Location API. +The use of these services is governed by the \l {https://www.mapbox.com/tos}{Mapbox terms of service}. + +This plugin differs from the \l {http://doc.qt.io/qt-5/location-plugin-mapbox.html}{Mapbox} plugin because it uses +the \l {https://github.com/mapbox/mapbox-gl-native/} {Mapbox GL map engine} for rendering both raster tiles and \l +{https://www.mapbox.com/vector-tiles} {vector tiles} in real-time. The benefits are: text staying upright, font +antialiasing, labels flowing between zoom levels, smooth pan, tilt, rotation and continuous zoom. + +The appearance and behavior of vector maps can be customized by creating custom map styles. This can be +done with tools like \l {https://www.mapbox.com/studio} {Mapbox Studio}. + +The Mapbox GL geo services plugin can be loaded by using the plugin key "mapboxgl". + +Both Mapbox geo services plugins require an access token to access map styles +and tiles hosted by Mapbox. To create a Mapbox account visit \l{https://www.mapbox.com/pricing}. + +\section2 Optional parameters + +The following table lists optional parameters that can be passed to the Mapbox plugin. + +\table +\header + \li Parameter + \li Description +\row + \li mapboxgl.access_token + \li \l{https://www.mapbox.com/help/define-access-token}{Access token} provided by Mapbox. +\row + \li mapboxgl.mapping.additional_style_urls + \li Additional, comma separated, Mapbox \l{https://www.mapbox.com/help/define-style-url} + {style URLs} to be added to the available style URLs. Additional styles will be prepended to + the \l[QML]{QtLocation::Map::}{supportedMapTypes} property of the \l{QtLocation::Map}{Map} item. +\row + \li mapboxgl.mapping.cache.directory + \li Absolute path to map tile cache directory used as network disk cache. + + The default place for the cache is \c{QtLocation/mapboxgl} directory in \l {QStandardPaths::writableLocation()} + {QStandardPaths::writableLocation}(\l{QStandardPaths::GenericCacheLocation}). On systems that have no concept + of a shared cache, the application-specific \l{QStandardPaths::CacheLocation} is used instead. + + This is an \l {https://www.mapbox.com/help/mobile-offline/#ambient-caching} {ambient cache}, meaning it will + get populated on the fly until it reaches the size limit, and when that happens, it will evict the least used + tiles. + + This cache can also be used for storing \l {https://www.mapbox.com/help/mobile-offline}{offline tiles}, + but the offline database must be populated using the \l {https://github.com/mapbox/mapbox-gl-native/blob/master/bin/offline.cpp} + {offline tool}. The offline database will work alongside with the ambient cache in the same file. + Make sure to comply with Mapbox Terms of Service before creating an offline database. +\row + \li mapboxgl.mapping.cache.memory + \li Whether or not the cache should be in-memory only. Valid values are \b true and \b false. The default + value is \b false. When set to \b true, the disk cache is never created. The ambient cache will work in-memory, + but the offline database cannot be used with this option enabled. +\row + \li mapboxgl.mapping.cache.size + \li Cache size for map resources in bytes. + The default size of this cache is 50 MiB. + Make sure to comply with Mapbox Terms of Service before increasing this value. +*/ diff --git a/src/plugins/geoservices/3rdparty/3rdparty.pro b/src/plugins/geoservices/3rdparty/3rdparty.pro new file mode 100644 index 00000000..1d871025 --- /dev/null +++ b/src/plugins/geoservices/3rdparty/3rdparty.pro @@ -0,0 +1,17 @@ +TEMPLATE = subdirs + +SUBDIRS = + +linux|android: { + equals(QT_GCC_MAJOR_VERSION, 4): greaterThan(QT_GCC_MINOR_VERSION, 8) { + SUBDIRS += mapbox-gl-native + } + + greaterThan(QT_GCC_MAJOR_VERSION, 4) { + SUBDIRS += mapbox-gl-native + } +} + +ios|macos: { + SUBDIRS += mapbox-gl-native +} diff --git a/src/plugins/geoservices/3rdparty/mapbox-gl-native b/src/plugins/geoservices/3rdparty/mapbox-gl-native new file mode 160000 +Subproject 14809e0c56b8199a96e27214a7c8d5776e6e430 diff --git a/src/plugins/geoservices/geoservices.pro b/src/plugins/geoservices/geoservices.pro index 7a392b57..32dfee96 100644 --- a/src/plugins/geoservices/geoservices.pro +++ b/src/plugins/geoservices/geoservices.pro @@ -1,3 +1,20 @@ TEMPLATE = subdirs SUBDIRS = nokia osm mapbox esri + +linux|android: { + equals(QT_GCC_MAJOR_VERSION, 4): greaterThan(QT_GCC_MINOR_VERSION, 8) { + SUBDIRS += mapboxgl 3rdparty + mapboxgl.depends += 3rdparty + } + + greaterThan(QT_GCC_MAJOR_VERSION, 4) { + SUBDIRS += mapboxgl 3rdparty + mapboxgl.depends += 3rdparty + } +} + +ios|macos: { + SUBDIRS += mapboxgl 3rdparty + mapboxgl.depends += 3rdparty +} diff --git a/src/plugins/geoservices/mapboxgl/mapboxgl.pro b/src/plugins/geoservices/mapboxgl/mapboxgl.pro new file mode 100644 index 00000000..ac139940 --- /dev/null +++ b/src/plugins/geoservices/mapboxgl/mapboxgl.pro @@ -0,0 +1,30 @@ +TARGET = qtgeoservices_mapboxgl + +QT += \ + quick-private \ + location-private \ + positioning-private \ + network + +HEADERS += \ + qgeoserviceproviderpluginmapboxgl.h \ + qgeomappingmanagerenginemapboxgl.h \ + qgeomapmapboxgl.h \ + qsgmapboxglnode.h + +SOURCES += \ + qgeoserviceproviderpluginmapboxgl.cpp \ + qgeomappingmanagerenginemapboxgl.cpp \ + qgeomapmapboxgl.cpp \ + qsgmapboxglnode.cpp + +OTHER_FILES += \ + mapboxgl_plugin.json + +INCLUDEPATH += ../3rdparty/mapbox-gl-native/platform/qt/include + +LIBS_PRIVATE += -L$$OUT_PWD/../3rdparty/mapbox-gl-native/ -lqmapboxgl + +PLUGIN_TYPE = geoservices +PLUGIN_CLASS_NAME = QGeoServiceProviderFactoryMapboxGL +load(qt_plugin) diff --git a/src/plugins/geoservices/mapboxgl/mapboxgl_plugin.json b/src/plugins/geoservices/mapboxgl/mapboxgl_plugin.json new file mode 100644 index 00000000..0031e08f --- /dev/null +++ b/src/plugins/geoservices/mapboxgl/mapboxgl_plugin.json @@ -0,0 +1,11 @@ +{ + "Keys": ["mapboxgl"], + "Provider": "mapboxgl", + "Version": 100, + "Experimental": false, + "Features": [ + "OnlineMappingFeature", + "OfflineMappingFeature", + "LocalizedMappingFeature" + ] +} diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp new file mode 100644 index 00000000..16b5fb8b --- /dev/null +++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp @@ -0,0 +1,215 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2017 Mapbox, Inc. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgeomapmapboxgl.h" +#include "qsgmapboxglnode.h" + +#include <QtCore/QByteArray> +#include <QtCore/QCoreApplication> +#include <QtCore/QTimer> +#include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLFramebufferObject> +#include <QtLocation/private/qgeomap_p_p.h> +#include <QtLocation/private/qgeoprojection_p.h> +#include <QtQuick/QQuickWindow> +#include <QtQuick/QSGImageNode> +#include <QtQuick/private/qsgtexture_p.h> + +#include <QMapboxGL> + +#include <cmath> + +// FIXME: Expose from Mapbox GL constants +#define MBGL_TILE_SIZE 512.0 + +namespace { + +static const double invLog2 = 1.0 / std::log(2.0); + +static double zoomLevelFrom256(double zoomLevelFor256, double tileSize) +{ + return std::log(std::pow(2.0, zoomLevelFor256) * 256.0 / tileSize) * invLog2; +} + +} // namespace + +class QGeoMapMapboxGLPrivate : public QGeoMapPrivate +{ + Q_DECLARE_PUBLIC(QGeoMapMapboxGL) + +public: + QGeoMapMapboxGLPrivate(QGeoMappingManagerEngineMapboxGL *engine); + + ~QGeoMapMapboxGLPrivate(); + + QSGNode *updateSceneGraph(QSGNode *oldNode, QQuickWindow *window); + + /* Data members */ + enum SyncState : int { + NoSync = 0, + ViewportSync = 1 << 0, + CameraDataSync = 1 << 1, + MapTypeSync = 1 << 2 + }; + Q_DECLARE_FLAGS(SyncStates, SyncState); + + QMapboxGLSettings m_settings; + + QTimer m_refresh; + bool m_shouldRefresh = true; + + SyncStates m_syncState = NoSync; + +protected: + void changeViewportSize(const QSize &size) Q_DECL_OVERRIDE; + void changeCameraData(const QGeoCameraData &oldCameraData) Q_DECL_OVERRIDE; + void changeActiveMapType(const QGeoMapType mapType) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QGeoMapMapboxGLPrivate) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QGeoMapMapboxGLPrivate::SyncStates) + +QGeoMapMapboxGLPrivate::QGeoMapMapboxGLPrivate(QGeoMappingManagerEngineMapboxGL *engine) + : QGeoMapPrivate(engine, new QGeoProjectionWebMercator) +{ +} + +QGeoMapMapboxGLPrivate::~QGeoMapMapboxGLPrivate() +{ +} + +QSGNode *QGeoMapMapboxGLPrivate::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window) +{ + Q_Q(QGeoMapMapboxGL); + + static bool warned; + if (!warned) { + if (window->openglContext()->thread() != QCoreApplication::instance()->thread()) { + qWarning() << "Threaded rendering is not supported by Mapbox GL plugin."; + QMetaObject::invokeMethod(&m_refresh, "start", Qt::QueuedConnection); + } + + warned = true; + } + + QSGMapboxGLNode *mbglNode = static_cast<QSGMapboxGLNode *>(oldNode); + if (!mbglNode) { + mbglNode = new QSGMapboxGLNode(m_settings, m_viewportSize, window->devicePixelRatio(), q); + m_syncState = MapTypeSync | CameraDataSync | ViewportSync; + } + + QMapboxGL *map = mbglNode->map(); + + if (m_syncState & MapTypeSync) { + map->setStyleUrl(m_activeMapType.name()); + } + + if (m_syncState & CameraDataSync) { + map->setZoom(zoomLevelFrom256(m_cameraData.zoomLevel() , MBGL_TILE_SIZE)); + map->setBearing(m_cameraData.bearing()); + map->setPitch(m_cameraData.tilt()); + + QGeoCoordinate coordinate = m_cameraData.center(); + map->setCoordinate(QMapbox::Coordinate(coordinate.latitude(), coordinate.longitude())); + } + + if (m_syncState & ViewportSync) { + mbglNode->resize(m_viewportSize, window->devicePixelRatio()); + } + + mbglNode->render(); + + m_syncState = NoSync; + + return mbglNode; +} + +void QGeoMapMapboxGLPrivate::changeViewportSize(const QSize &) +{ + Q_Q(QGeoMapMapboxGL); + + m_syncState = m_syncState | ViewportSync; + emit q->sgNodeChanged(); +} + +void QGeoMapMapboxGLPrivate::changeCameraData(const QGeoCameraData &) +{ + Q_Q(QGeoMapMapboxGL); + + m_syncState = m_syncState | CameraDataSync; + emit q->sgNodeChanged(); +} + +void QGeoMapMapboxGLPrivate::changeActiveMapType(const QGeoMapType) +{ + Q_Q(QGeoMapMapboxGL); + + m_syncState = m_syncState | MapTypeSync; + emit q->sgNodeChanged(); +} + +/* + * QGeoMapMapboxGL implementation + */ + +QGeoMapMapboxGL::QGeoMapMapboxGL(QGeoMappingManagerEngineMapboxGL *engine, QObject *parent) + : QGeoMap(*new QGeoMapMapboxGLPrivate(engine), parent), m_engine(engine) +{ + Q_D(QGeoMapMapboxGL); + + connect(&d->m_refresh, &QTimer::timeout, this, &QGeoMap::sgNodeChanged); + d->m_refresh.setInterval(250); +} + +QGeoMapMapboxGL::~QGeoMapMapboxGL() +{ +} + +void QGeoMapMapboxGL::setMapboxGLSettings(const QMapboxGLSettings& settings) +{ + Q_D(QGeoMapMapboxGL); + + d->m_settings = settings; +} + +QSGNode *QGeoMapMapboxGL::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window) +{ + Q_D(QGeoMapMapboxGL); + return d->updateSceneGraph(oldNode, window); +} diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h new file mode 100644 index 00000000..4c29be5f --- /dev/null +++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2017 Mapbox, Inc. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGEOMAPMAPBOXGL_H +#define QGEOMAPMAPBOXGL_H + +#include "qgeomappingmanagerenginemapboxgl.h" +#include <QtLocation/private/qgeomap_p.h> + +class QGeoMapMapboxGLPrivate; +class QGeoMapMapboxGL : public QGeoMap +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QGeoMapMapboxGL) + +public: + QGeoMapMapboxGL(QGeoMappingManagerEngineMapboxGL *engine, QObject *parent); + virtual ~QGeoMapMapboxGL(); + + void setMapboxGLSettings(const QMapboxGLSettings &); + +protected: + QSGNode *updateSceneGraph(QSGNode *oldNode, QQuickWindow *window) Q_DECL_OVERRIDE; + + QGeoMappingManagerEngineMapboxGL *m_engine; +}; + +#endif // QGEOMAPMAPBOXGL_H diff --git a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp new file mode 100644 index 00000000..04a800aa --- /dev/null +++ b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2017 Mapbox, Inc. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgeomappingmanagerenginemapboxgl.h" +#include "qgeomapmapboxgl.h" + +#include <QtCore/qstandardpaths.h> +#include <QtLocation/private/qabstractgeotilecache_p.h> +#include <QtLocation/private/qgeocameracapabilities_p.h> +#include <QtLocation/private/qgeomaptype_p.h> + +#include <QDir> + +QT_BEGIN_NAMESPACE + +QGeoMappingManagerEngineMapboxGL::QGeoMappingManagerEngineMapboxGL(const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) +: QGeoMappingManagerEngine() +{ + *error = QGeoServiceProvider::NoError; + errorString->clear(); + + QGeoCameraCapabilities cameraCaps; + cameraCaps.setMinimumZoomLevel(0.0); + cameraCaps.setMaximumZoomLevel(20.0); + cameraCaps.setTileSize(512); + cameraCaps.setSupportsBearing(true); + cameraCaps.setSupportsTilting(true); + cameraCaps.setMinimumTilt(0); + cameraCaps.setMaximumTilt(60); + cameraCaps.setMinimumFieldOfView(36.87); + cameraCaps.setMaximumFieldOfView(36.87); + setCameraCapabilities(cameraCaps); + + QList<QGeoMapType> mapTypes; + int mapId = 0; + + mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/streets-v9"), + tr("Streets"), false, false, ++mapId); + mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/basic-v9"), + tr("Basic"), false, false, ++mapId); + mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/bright-v9"), + tr("Bright"), false, false, ++mapId); + mapTypes << QGeoMapType(QGeoMapType::TerrainMap, QStringLiteral("mapbox://styles/mapbox/outdoors-v9"), + tr("Outdoors"), false, false, ++mapId); + mapTypes << QGeoMapType(QGeoMapType::SatelliteMapDay, QStringLiteral("mapbox://styles/mapbox/satellite-v9"), + tr("Satellite"), false, false, ++mapId); + mapTypes << QGeoMapType(QGeoMapType::HybridMap, QStringLiteral("mapbox://styles/mapbox/satellite-streets-v9"), + tr("Satellite Streets"), false, false, ++mapId); + mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/light-v9"), + tr("Light"), false, false, ++mapId); + mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/dark-v9"), + tr("Dark"), false, false, ++mapId); + mapTypes << QGeoMapType(QGeoMapType::TransitMap, QStringLiteral("mapbox://styles/mapbox/traffic-day-v1"), + tr("Streets Traffic Day"), false, false, ++mapId); + mapTypes << QGeoMapType(QGeoMapType::TransitMap, QStringLiteral("mapbox://styles/mapbox/traffic-night-v1"), + tr("Streets Traffic Night"), false, true, ++mapId); + + if (parameters.contains(QStringLiteral("mapboxgl.mapping.additional_style_urls"))) { + const QString ids = parameters.value(QStringLiteral("mapboxgl.mapping.additional_style_urls")).toString(); + const QStringList idList = ids.split(',', QString::SkipEmptyParts); + + for (auto it = idList.crbegin(), end = idList.crend(); it != end; ++it) { + if ((*it).isEmpty()) + continue; + + mapTypes.prepend(QGeoMapType(QGeoMapType::CustomMap, *it, + tr("User provided style"), false, false, ++mapId)); + } + } + + setSupportedMapTypes(mapTypes); + + if (parameters.contains(QStringLiteral("mapboxgl.access_token"))) { + m_settings.setAccessToken(parameters.value(QStringLiteral("mapboxgl.access_token")).toString()); + } + + bool memoryCache = false; + if (parameters.contains(QStringLiteral("mapboxgl.mapping.cache.memory"))) { + memoryCache = parameters.value(QStringLiteral("mapboxgl.mapping.cache.memory")).toBool(); + m_settings.setCacheDatabasePath(QStringLiteral(":memory:")); + } + + QString cacheDirectory; + if (parameters.contains(QStringLiteral("mapboxgl.mapping.cache.directory"))) { + cacheDirectory = parameters.value(QStringLiteral("mapboxgl.mapping.cache.directory")).toString(); + } else { + cacheDirectory = QAbstractGeoTileCache::baseLocationCacheDirectory() + QStringLiteral("mapboxgl/"); + } + + if (!memoryCache && QDir::root().mkpath(cacheDirectory)) { + m_settings.setCacheDatabasePath(cacheDirectory + "/mapboxgl.db"); + } + + if (parameters.contains(QStringLiteral("mapboxgl.mapping.cache.size"))) { + bool ok = false; + int cacheSize = parameters.value(QStringLiteral("mapboxgl.mapping.cache.size")).toString().toInt(&ok); + + if (ok) + m_settings.setCacheDatabaseMaximumSize(cacheSize); + } + + engineInitialized(); +} + +QGeoMappingManagerEngineMapboxGL::~QGeoMappingManagerEngineMapboxGL() +{ +} + +QGeoMap *QGeoMappingManagerEngineMapboxGL::createMap() +{ + QGeoMapMapboxGL* map = new QGeoMapMapboxGL(this, 0); + map->setMapboxGLSettings(m_settings); + + return map; +} + +QT_END_NAMESPACE diff --git a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h new file mode 100644 index 00000000..1bf44064 --- /dev/null +++ b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2017 Mapbox, Inc. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGEOTILEDMAPPINGMANAGERENGINEMAPBOXGL_H +#define QGEOTILEDMAPPINGMANAGERENGINEMAPBOXGL_H + +#include <QtLocation/QGeoServiceProvider> +#include <QtLocation/private/qgeomappingmanagerengine_p.h> + +#include <QMapboxGL> + +QT_BEGIN_NAMESPACE + +class QGeoMappingManagerEngineMapboxGL : public QGeoMappingManagerEngine +{ + Q_OBJECT + +public: + QGeoMappingManagerEngineMapboxGL(const QVariantMap ¶meters, + QGeoServiceProvider::Error *error, QString *errorString); + ~QGeoMappingManagerEngineMapboxGL(); + + QGeoMap *createMap() Q_DECL_OVERRIDE; + +private: + QMapboxGLSettings m_settings; +}; + +QT_END_NAMESPACE + +#endif // QGEOTILEDMAPPINGMANAGERENGINEMAPBOXGL_H diff --git a/src/plugins/geoservices/mapboxgl/qgeoserviceproviderpluginmapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeoserviceproviderpluginmapboxgl.cpp new file mode 100644 index 00000000..30c01f8c --- /dev/null +++ b/src/plugins/geoservices/mapboxgl/qgeoserviceproviderpluginmapboxgl.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2017 Mapbox, Inc. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgeoserviceproviderpluginmapboxgl.h" +#include "qgeomappingmanagerenginemapboxgl.h" + + +QT_BEGIN_NAMESPACE + +QGeoCodingManagerEngine *QGeoServiceProviderFactoryMapboxGL::createGeocodingManagerEngine( + const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const +{ + Q_UNUSED(parameters) + Q_UNUSED(error) + Q_UNUSED(errorString) + + return 0; +} + +QGeoMappingManagerEngine *QGeoServiceProviderFactoryMapboxGL::createMappingManagerEngine( + const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const +{ + return new QGeoMappingManagerEngineMapboxGL(parameters, error, errorString); +} + +QGeoRoutingManagerEngine *QGeoServiceProviderFactoryMapboxGL::createRoutingManagerEngine( + const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const +{ + Q_UNUSED(parameters) + Q_UNUSED(error) + Q_UNUSED(errorString) + + return 0; +} + +QPlaceManagerEngine *QGeoServiceProviderFactoryMapboxGL::createPlaceManagerEngine( + const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const +{ + Q_UNUSED(parameters) + Q_UNUSED(error) + Q_UNUSED(errorString) + + return 0; +} + +QT_END_NAMESPACE diff --git a/src/plugins/geoservices/mapboxgl/qgeoserviceproviderpluginmapboxgl.h b/src/plugins/geoservices/mapboxgl/qgeoserviceproviderpluginmapboxgl.h new file mode 100644 index 00000000..2bba96f1 --- /dev/null +++ b/src/plugins/geoservices/mapboxgl/qgeoserviceproviderpluginmapboxgl.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2017 Mapbox, Inc. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGEOSERVICEPROVIDER_MAPBOXGL_H +#define QGEOSERVICEPROVIDER_MAPBOXGL_H + +#include <QtCore/QObject> +#include <QtLocation/QGeoServiceProviderFactory> + +QT_BEGIN_NAMESPACE + +class QGeoServiceProviderFactoryMapboxGL: public QObject, public QGeoServiceProviderFactory +{ + Q_OBJECT + Q_INTERFACES(QGeoServiceProviderFactory) + Q_PLUGIN_METADATA(IID "org.qt-project.qt.geoservice.serviceproviderfactory/5.0" + FILE "mapboxgl_plugin.json") + +public: + QGeoCodingManagerEngine *createGeocodingManagerEngine(const QVariantMap ¶meters, + QGeoServiceProvider::Error *error, + QString *errorString) const; + QGeoMappingManagerEngine *createMappingManagerEngine(const QVariantMap ¶meters, + QGeoServiceProvider::Error *error, + QString *errorString) const; + QGeoRoutingManagerEngine *createRoutingManagerEngine(const QVariantMap ¶meters, + QGeoServiceProvider::Error *error, + QString *errorString) const; + QPlaceManagerEngine *createPlaceManagerEngine(const QVariantMap ¶meters, + QGeoServiceProvider::Error *error, + QString *errorString) const; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp b/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp new file mode 100644 index 00000000..67e67504 --- /dev/null +++ b/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2017 Mapbox, Inc. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qsgmapboxglnode.h> +#include <qgeomapmapboxgl.h> + +#include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLFunctions> + +QSGMapboxGLNode::QSGMapboxGLNode(const QMapboxGLSettings &settings, const QSize &size, qreal pixelRatio, QGeoMapMapboxGL *geoMap) + : QSGSimpleTextureNode() +{ + setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically); + + m_map.reset(new QMapboxGL(nullptr, settings, size, pixelRatio)); + + QObject::connect(m_map.data(), &QMapboxGL::needsRendering, geoMap, &QGeoMap::sgNodeChanged); + QObject::connect(m_map.data(), &QMapboxGL::copyrightsChanged, geoMap, + static_cast<void (QGeoMap::*)(const QString &)>(&QGeoMapMapboxGL::copyrightsChanged)); +} + +void QSGMapboxGLNode::resize(const QSize &size, qreal pixelRatio) +{ + const QSize fbSize = size * pixelRatio; + m_map->resize(size, fbSize); + + m_fbo.reset(new QOpenGLFramebufferObject(fbSize, QOpenGLFramebufferObject::CombinedDepthStencil)); + + QSGPlainTexture *fboTexture = static_cast<QSGPlainTexture *>(texture()); + if (!fboTexture) + fboTexture = new QSGPlainTexture; + + fboTexture->setTextureId(m_fbo->texture()); + fboTexture->setTextureSize(fbSize); + + if (!texture()) { + setTexture(fboTexture); + setOwnsTexture(true); + } + + setRect(QRectF(QPointF(), size)); + markDirty(QSGNode::DirtyGeometry); +} + +void QSGMapboxGLNode::render() +{ + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + f->glViewport(0, 0, m_fbo->width(), m_fbo->height()); + + m_fbo->bind(); + m_map->render(m_fbo.data()); + m_fbo->release(); + + markDirty(QSGNode::DirtyMaterial); +} + +QMapboxGL* QSGMapboxGLNode::map() const +{ + return m_map.data(); +} diff --git a/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.h b/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.h new file mode 100644 index 00000000..bd7cc4b3 --- /dev/null +++ b/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2017 Mapbox, Inc. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGMAPBOXGLNODE_H +#define QSGMAPBOXGLNODE_H + +#include <QtQuick/QSGSimpleTextureNode> +#include <QtQuick/private/qsgtexture_p.h> +#include <QtGui/QOpenGLFramebufferObject> + +#include <QMapboxGL> + +class QGeoMapMapboxGL; + +class QSGMapboxGLNode : public QSGSimpleTextureNode +{ +public: + QSGMapboxGLNode(const QMapboxGLSettings &, const QSize &, qreal pixelRatio, QGeoMapMapboxGL *geoMap); + + void resize(const QSize &size, qreal pixelRatio); + void render(); + + QMapboxGL* map() const; + +private: + QScopedPointer<QMapboxGL> m_map; + QScopedPointer<QOpenGLFramebufferObject> m_fbo; +}; + +#endif // QSGMAPBOXGLNODE_H |