[Qt] Remove the QML app
We are now on Qt 5.9 and this is where the plugin will be developed from now on.
This commit is contained in:
committed by
Thiago Marcos P. Santos
parent
b5d0a661c5
commit
2b7319d529
@@ -189,7 +189,6 @@ matrix:
|
||||
- mapbox_export_mesa_library_path
|
||||
script:
|
||||
- make qt-app
|
||||
- make qt-qml-app
|
||||
- make qt-test
|
||||
- make qt-docs
|
||||
- scripts/valgrind.sh build/qt-linux-x86_64/Release/mbgl-test --gtest_filter=-*.Load --gtest_filter=-Memory.Vector
|
||||
|
||||
9
Makefile
9
Makefile
@@ -405,7 +405,6 @@ $(MACOS_QT_PROJ_PATH): $(BUILD_DEPS)
|
||||
@# Create Xcode schemes so that we can use xcodebuild from the command line. CMake doesn't
|
||||
@# create these automatically.
|
||||
XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-qt SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh
|
||||
XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-qt-qml SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh
|
||||
XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-test SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh
|
||||
XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-benchmark SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh
|
||||
XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-core SCHEME_TYPE=library BUILDABLE_NAME=libmbgl-core.a BLUEPRINT_NAME=mbgl-core platform/macos/scripts/create_scheme.sh
|
||||
@@ -429,14 +428,6 @@ qt-app: $(QT_BUILD)
|
||||
run-qt-app: qt-app
|
||||
$(QT_OUTPUT_PATH)/mbgl-qt
|
||||
|
||||
.PHONY: qt-qml-app
|
||||
qt-qml-app: $(QT_BUILD)
|
||||
$(NINJA) $(NINJA_ARGS) -j$(JOBS) -C $(QT_OUTPUT_PATH) mbgl-qt-qml
|
||||
|
||||
.PHONY: run-qt-qml-app
|
||||
run-qt-qml-app: qt-qml-app
|
||||
$(QT_OUTPUT_PATH)/mbgl-qt-qml
|
||||
|
||||
.PHONY: qt-test
|
||||
qt-test: $(QT_BUILD)
|
||||
$(NINJA) $(NINJA_ARGS) -j$(JOBS) -C $(QT_OUTPUT_PATH) mbgl-test
|
||||
|
||||
@@ -3,43 +3,10 @@
|
||||
[](https://travis-ci.org/mapbox/mapbox-gl-native/builds)
|
||||
[](https://www.bitrise.io/app/96cfbc97e0245c22)
|
||||
|
||||
Provides [Qt](http://www.qt.io/) example applications and APIs via `QMapboxGL`
|
||||
and `QQuickMapboxGL`:
|
||||
|
||||
**QMapboxGL** - implements a C++03x-conformant API that has been tested from Qt
|
||||
4.7 onwards (Travis CI currently builds it using both Qt 4 and Qt 5).
|
||||
|
||||
**QQuickMapboxGL** - implements a Qt Quick (QML) item that can be added to a
|
||||
scene. Because `QQuickFramebufferObject` has been added in Qt version 5.2, we
|
||||
support this API from this version onwards.
|
||||
|
||||

|
||||
|
||||
### Developing
|
||||
|
||||
[Qt supports many platforms](https://www.qt.io/qt-framework/#section-4) - so far
|
||||
we have been testing our code on Linux and macOS desktops, as well as embedded
|
||||
devices such as Raspberry Pi 3.
|
||||
|
||||
If you need to maintain backwards compatibility with prior releases of
|
||||
Qt, chose `QMapboxGL`. Otherwise, go for `QQuickMapboxGL`.
|
||||
|
||||
Both `QMapboxGL` and `QQuickMapboxGL` requires a [Mapbox access
|
||||
token](https://www.mapbox.com/help/define-access-token/) at runtime - you need
|
||||
to provide it by setting the environment variable `MAPBOX_ACCESS_TOKEN`:
|
||||
|
||||
export MAPBOX_ACCESS_TOKEN=MYTOKEN
|
||||
|
||||
Optionally, you can specify a custom style to the QMapboxGL example application:
|
||||
|
||||
export MAPBOX_STYLE_URL=MYSTYLEURL
|
||||
|
||||
#### Using QMapboxGL
|
||||
|
||||
`QMapboxGL` is a [QObject](http://doc.qt.io/qt-5/qobject.html) - [MapWindow](https://github.com/mapbox/mapbox-gl-native/blob/master/platform/qt/app/mapwindow.hpp) provides an example [QGLWidget](http://doc.qt.io/qt-5/qglwidget.html) that contains a `QMapboxGL` object. If you use `QMapboxGL` in non-standard Qt widgets, make sure to initialize the GL extensions required by Mapbox whenever possible:
|
||||
|
||||
QMapbox::initializeGLExtensions();
|
||||
This is the foundation for the Mapbox GL plugin available since Qt 5.9. Use the Qt bugtracker
|
||||
for bugs related to the plugin and this GitHub repository for bugs related to Mapbox GL Native.
|
||||
|
||||
#### Linux
|
||||
|
||||
@@ -47,9 +14,7 @@ For Linux (Ubuntu) desktop, together with these [build
|
||||
instructions](https://github.com/mapbox/mapbox-gl-native/tree/master/platform/linux#build),
|
||||
you also need:
|
||||
|
||||
sudo apt-get install qt5-default qtlocation5-dev qtpositioning5-dev \
|
||||
qml-module-qtquick2 qml-module-qtpositioning qml-module-qtgraphicaleffects \
|
||||
qml-module-qtquick-layouts qml-module-qtquick-controls
|
||||
sudo apt-get install qt5-default
|
||||
|
||||
#### macOS
|
||||
|
||||
@@ -74,8 +39,3 @@ can be found in [platform/qt/include](https://github.com/mapbox/mapbox-gl-native
|
||||
|
||||
```make qt-app``` or ```make run-qt-app``` to run the application at the end of
|
||||
build.
|
||||
|
||||
#### QQuickMapboxGL example application:
|
||||
|
||||
```make qt-qml-app``` or ```make run-qt-qml-app``` to run the application at the
|
||||
end of build.
|
||||
|
||||
@@ -39,7 +39,6 @@ workflows:
|
||||
ln -s /usr/local/Cellar/qt5/$HOMEBREW_QT5_VERSION/plugins /usr/local/plugins
|
||||
export BUILDTYPE=Debug
|
||||
make qt-app
|
||||
make qt-qml-app
|
||||
make run-qt-test
|
||||
- is_debug: 'yes'
|
||||
- deploy-to-bitrise-io:
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "qmapbox.hpp"
|
||||
#include "qmapboxgl.hpp"
|
||||
#include "qquickmapboxglmapparameter.hpp"
|
||||
|
||||
#include <QColor>
|
||||
#include <QGeoCoordinate>
|
||||
#include <QGeoServiceProvider>
|
||||
#include <QGeoShape>
|
||||
#include <QImage>
|
||||
#include <QPointF>
|
||||
#include <QQmlListProperty>
|
||||
#include <QQuickFramebufferObject>
|
||||
#include <QQuickItem>
|
||||
|
||||
class QDeclarativeGeoServiceProvider;
|
||||
class QQuickMapboxGLRenderer;
|
||||
|
||||
class Q_DECL_EXPORT QQuickMapboxGL : public QQuickFramebufferObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// Map QML Type interface.
|
||||
Q_ENUMS(QGeoServiceProvider::Error)
|
||||
Q_PROPERTY(QDeclarativeGeoServiceProvider *plugin READ plugin WRITE setPlugin NOTIFY pluginChanged)
|
||||
Q_PROPERTY(qreal minimumZoomLevel READ minimumZoomLevel WRITE setMinimumZoomLevel NOTIFY minimumZoomLevelChanged)
|
||||
Q_PROPERTY(qreal maximumZoomLevel READ maximumZoomLevel WRITE setMaximumZoomLevel NOTIFY maximumZoomLevelChanged)
|
||||
Q_PROPERTY(qreal zoomLevel READ zoomLevel WRITE setZoomLevel NOTIFY zoomLevelChanged)
|
||||
Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged)
|
||||
Q_PROPERTY(QGeoServiceProvider::Error error READ error NOTIFY errorChanged)
|
||||
Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged)
|
||||
Q_PROPERTY(QGeoShape visibleRegion READ visibleRegion WRITE setVisibleRegion)
|
||||
Q_PROPERTY(bool copyrightsVisible READ copyrightsVisible WRITE setCopyrightsVisible NOTIFY copyrightsVisibleChanged)
|
||||
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
|
||||
|
||||
// Proposed Qt interface - based on the example documentation below:
|
||||
// http://doc.qt.io/qt-5/qtqml-referenceexamples-properties-example.html
|
||||
Q_PROPERTY(QQmlListProperty<QQuickMapboxGLMapParameter> parameters READ parameters)
|
||||
|
||||
public:
|
||||
QQuickMapboxGL(QQuickItem *parent = 0);
|
||||
virtual ~QQuickMapboxGL();
|
||||
|
||||
// QQuickFramebufferObject implementation.
|
||||
virtual Renderer *createRenderer() const Q_DECL_FINAL;
|
||||
|
||||
// Map QML Type interface implementation.
|
||||
void setPlugin(QDeclarativeGeoServiceProvider *plugin);
|
||||
QDeclarativeGeoServiceProvider *plugin() const;
|
||||
|
||||
void setMinimumZoomLevel(qreal minimumZoomLevel);
|
||||
qreal minimumZoomLevel() const;
|
||||
|
||||
void setMaximumZoomLevel(qreal maximumZoomLevel);
|
||||
qreal maximumZoomLevel() const;
|
||||
|
||||
void setZoomLevel(qreal zoomLevel);
|
||||
qreal zoomLevel() const;
|
||||
|
||||
QGeoCoordinate center() const;
|
||||
|
||||
QGeoServiceProvider::Error error() const;
|
||||
QString errorString() const;
|
||||
|
||||
void setVisibleRegion(const QGeoShape &shape);
|
||||
QGeoShape visibleRegion() const;
|
||||
|
||||
void setCopyrightsVisible(bool visible);
|
||||
bool copyrightsVisible() const;
|
||||
|
||||
void setColor(const QColor &color);
|
||||
QColor color() const;
|
||||
|
||||
Q_INVOKABLE void pan(int dx, int dy);
|
||||
|
||||
// Proposed Qt interface implementation.
|
||||
QQmlListProperty<QQuickMapboxGLMapParameter> parameters();
|
||||
|
||||
protected:
|
||||
// QQmlParserStatus implementation
|
||||
void componentComplete() override;
|
||||
|
||||
signals:
|
||||
// Map QML Type signals.
|
||||
void minimumZoomLevelChanged();
|
||||
void maximumZoomLevelChanged();
|
||||
void zoomLevelChanged(qreal zoomLevel);
|
||||
void centerChanged(const QGeoCoordinate &coordinate);
|
||||
void colorChanged(const QColor &color);
|
||||
void errorChanged();
|
||||
|
||||
// Compatibility with Map QML Type, but no-op.
|
||||
void pluginChanged(QDeclarativeGeoServiceProvider *plugin);
|
||||
void copyrightLinkActivated(const QString &link);
|
||||
void copyrightsVisibleChanged(bool visible);
|
||||
|
||||
public slots:
|
||||
void setCenter(const QGeoCoordinate ¢er);
|
||||
|
||||
private slots:
|
||||
void onMapChanged(QMapboxGL::MapChange);
|
||||
void onParameterPropertyUpdated(const QString &name);
|
||||
|
||||
private:
|
||||
static void appendParameter(QQmlListProperty<QQuickMapboxGLMapParameter> *prop, QQuickMapboxGLMapParameter *mapObject);
|
||||
static int countParameters(QQmlListProperty<QQuickMapboxGLMapParameter> *prop);
|
||||
static QQuickMapboxGLMapParameter *parameterAt(QQmlListProperty<QQuickMapboxGLMapParameter> *prop, int index);
|
||||
static void clearParameter(QQmlListProperty<QQuickMapboxGLMapParameter> *prop);
|
||||
|
||||
enum SyncState {
|
||||
NothingNeedsSync = 0,
|
||||
ZoomNeedsSync = 1 << 0,
|
||||
CenterNeedsSync = 1 << 1,
|
||||
StyleNeedsSync = 1 << 2,
|
||||
PanNeedsSync = 1 << 3,
|
||||
BearingNeedsSync = 1 << 4,
|
||||
PitchNeedsSync = 1 << 5,
|
||||
};
|
||||
|
||||
struct Image {
|
||||
QString name;
|
||||
QImage sprite;
|
||||
};
|
||||
|
||||
struct StyleProperty {
|
||||
enum Type {
|
||||
Paint = 0,
|
||||
Layout
|
||||
};
|
||||
|
||||
Type type;
|
||||
QString layer;
|
||||
QString property;
|
||||
QVariant value;
|
||||
QString klass;
|
||||
};
|
||||
|
||||
void processMapParameter(QQuickMapboxGLMapParameter *);
|
||||
bool parseImage(QQuickMapboxGLMapParameter *);
|
||||
bool parseStyle(QQuickMapboxGLMapParameter *);
|
||||
bool parseStyleProperty(QQuickMapboxGLMapParameter *, const QString &name);
|
||||
bool parseStyleLayer(QQuickMapboxGLMapParameter *);
|
||||
bool parseStyleSource(QQuickMapboxGLMapParameter *);
|
||||
bool parseStyleFilter(QQuickMapboxGLMapParameter *);
|
||||
bool parseBearing(QQuickMapboxGLMapParameter *);
|
||||
bool parsePitch(QQuickMapboxGLMapParameter *);
|
||||
|
||||
qreal m_minimumZoomLevel = 0;
|
||||
qreal m_maximumZoomLevel = 20;
|
||||
qreal m_zoomLevel = 20;
|
||||
|
||||
QPointF m_pan;
|
||||
|
||||
QGeoCoordinate m_center;
|
||||
QGeoShape m_visibleRegion;
|
||||
QColor m_color;
|
||||
QString m_styleUrl;
|
||||
QList<Image> m_imageChanges;
|
||||
QList<StyleProperty> m_stylePropertyChanges;
|
||||
QList<QVariantMap> m_layerChanges;
|
||||
QList<QVariantMap> m_sourceChanges;
|
||||
QList<QVariantMap> m_filterChanges;
|
||||
QList<QQuickMapboxGLMapParameter*> m_parameters;
|
||||
|
||||
QGeoServiceProvider::Error m_error = QGeoServiceProvider::NoError;
|
||||
QString m_errorString;
|
||||
|
||||
qreal m_bearing = 0;
|
||||
qreal m_pitch = 0;
|
||||
|
||||
int m_syncState = NothingNeedsSync;
|
||||
bool m_styleLoaded = false;
|
||||
|
||||
friend class QQuickMapboxGLRenderer;
|
||||
};
|
||||
@@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QQmlParserStatus>
|
||||
#include <QString>
|
||||
#include <qqml.h>
|
||||
|
||||
class Q_DECL_EXPORT QQuickMapboxGLMapParameter : public QObject, public QQmlParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QQmlParserStatus)
|
||||
|
||||
public:
|
||||
QQuickMapboxGLMapParameter(QObject *parent = 0);
|
||||
virtual ~QQuickMapboxGLMapParameter() {};
|
||||
|
||||
int propertyOffset() const { return m_metaPropertyOffset; }
|
||||
|
||||
signals:
|
||||
void propertyUpdated(const QString &name);
|
||||
|
||||
protected:
|
||||
// QQmlParserStatus implementation
|
||||
void classBegin() override {}
|
||||
void componentComplete() override;
|
||||
|
||||
private slots:
|
||||
void onPropertyUpdated(int index);
|
||||
|
||||
private:
|
||||
int m_metaPropertyOffset;
|
||||
};
|
||||
|
||||
QML_DECLARE_TYPE(QQuickMapboxGLMapParameter)
|
||||
@@ -1,24 +0,0 @@
|
||||
#include <QQuickMapboxGL>
|
||||
#include <QQuickMapboxGLMapParameter>
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QIcon>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <qqml.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
#if QT_VERSION >= 0x050300
|
||||
app.setWindowIcon(QIcon(":icon.png"));
|
||||
#endif
|
||||
|
||||
qmlRegisterType<QQuickMapboxGL>("QQuickMapboxGL", 1, 0, "MapboxMap");
|
||||
qmlRegisterType<QQuickMapboxGLMapParameter>("QQuickMapboxGL", 1, 0, "MapParameter");
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
@@ -1,347 +0,0 @@
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtPositioning 5.0
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.0
|
||||
import QtQuick.Dialogs 1.0
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
import QQuickMapboxGL 1.0
|
||||
|
||||
ApplicationWindow {
|
||||
title: "Mapbox GL QML example"
|
||||
width: 1024
|
||||
height: 768
|
||||
visible: true
|
||||
|
||||
MapboxMap {
|
||||
id: map
|
||||
anchors.fill: parent
|
||||
|
||||
parameters: [
|
||||
MapParameter {
|
||||
id: style
|
||||
property var type: "style"
|
||||
property var url: "mapbox://styles/mapbox/streets-v9"
|
||||
},
|
||||
MapParameter {
|
||||
id: waterPaint
|
||||
property var type: "paint"
|
||||
property var layer: "water"
|
||||
property var fillColor: waterColorDialog.color
|
||||
},
|
||||
MapParameter {
|
||||
id: source
|
||||
property var type: "source"
|
||||
property var name: "routeSource"
|
||||
property var sourceType: "geojson"
|
||||
property var data: ":source1.geojson"
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "layer"
|
||||
property var name: "routeCase"
|
||||
property var layerType: "line"
|
||||
property var source: "routeSource"
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "paint"
|
||||
property var layer: "routeCase"
|
||||
property var lineColor: "white"
|
||||
property var lineWidth: 20.0
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "layout"
|
||||
property var layer: "routeCase"
|
||||
property var lineJoin: "round"
|
||||
property var lineCap: lineJoin
|
||||
property var visibility: toggleRoute.checked ? "visible" : "none"
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "layer"
|
||||
property var name: "route"
|
||||
property var layerType: "line"
|
||||
property var source: "routeSource"
|
||||
},
|
||||
MapParameter {
|
||||
id: linePaint
|
||||
property var type: "paint"
|
||||
property var layer: "route"
|
||||
property var lineColor: "blue"
|
||||
property var lineWidth: 8.0
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "layout"
|
||||
property var layer: "route"
|
||||
property var lineJoin: "round"
|
||||
property var lineCap: "round"
|
||||
property var visibility: toggleRoute.checked ? "visible" : "none"
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "image"
|
||||
property var name: "label-arrow"
|
||||
property var sprite: ":label-arrow.svg"
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "image"
|
||||
property var name: "label-background"
|
||||
property var sprite: ":label-background.svg"
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "layer"
|
||||
property var name: "markerArrow"
|
||||
property var layerType: "symbol"
|
||||
property var source: "routeSource"
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "layout"
|
||||
property var layer: "markerArrow"
|
||||
property var iconImage: "label-arrow"
|
||||
property var iconSize: 0.5
|
||||
property var iconIgnorePlacement: true
|
||||
property var iconOffset: [ 0.0, -15.0 ]
|
||||
property var visibility: toggleRoute.checked ? "visible" : "none"
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "layer"
|
||||
property var name: "markerBackground"
|
||||
property var layerType: "symbol"
|
||||
property var source: "routeSource"
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "layout"
|
||||
property var layer: "markerBackground"
|
||||
property var iconImage: "label-background"
|
||||
property var textField: "{name}"
|
||||
property var iconTextFit: "both"
|
||||
property var iconIgnorePlacement: true
|
||||
property var textIgnorePlacement: true
|
||||
property var textAnchor: "left"
|
||||
property var textSize: 16.0
|
||||
property var textPadding: 0.0
|
||||
property var textLineHeight: 1.0
|
||||
property var textMaxWidth: 8.0
|
||||
property var iconTextFitPadding: [ 15.0, 10.0, 15.0, 10.0 ]
|
||||
property var textOffset: [ -0.5, -1.5 ]
|
||||
property var visibility: toggleRoute.checked ? "visible" : "none"
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "paint"
|
||||
property var layer: "markerBackground"
|
||||
property var textColor: "white"
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "filter"
|
||||
property var layer: "markerArrow"
|
||||
property var filter: [ "==", "$type", "Point" ]
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "filter"
|
||||
property var layer: "markerBackground"
|
||||
property var filter: [ "==", "$type", "Point" ]
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "bearing"
|
||||
property var angle: bearingSlider.value
|
||||
},
|
||||
MapParameter {
|
||||
property var type: "pitch"
|
||||
property var angle: pitchSlider.value
|
||||
}
|
||||
]
|
||||
|
||||
center: QtPositioning.coordinate(60.170448, 24.942046) // Helsinki
|
||||
zoomLevel: 12.25
|
||||
minimumZoomLevel: 0
|
||||
maximumZoomLevel: 20
|
||||
|
||||
color: landColorDialog.color
|
||||
copyrightsVisible: true
|
||||
|
||||
states: State {
|
||||
name: "moved"; when: mouseArea.pressed
|
||||
PropertyChanges { target: linePaint; lineColor: "red"; }
|
||||
}
|
||||
|
||||
transitions: Transition {
|
||||
ColorAnimation { properties: "lineColor"; easing.type: Easing.InOutQuad; duration: 500 }
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 20
|
||||
|
||||
opacity: .75
|
||||
|
||||
sourceSize.width: 80
|
||||
sourceSize.height: 80
|
||||
|
||||
source: "icon.png"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
|
||||
property var lastX: 0
|
||||
property var lastY: 0
|
||||
|
||||
onWheel: map.zoomLevel += 0.2 * wheel.angleDelta.y / 120
|
||||
|
||||
onPressed: {
|
||||
lastX = mouse.x
|
||||
lastY = mouse.y
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
map.pan(mouse.x - lastX, mouse.y - lastY)
|
||||
|
||||
lastX = mouse.x
|
||||
lastY = mouse.y
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColorDialog {
|
||||
id: landColorDialog
|
||||
title: "Land color"
|
||||
color: "#e0ded8"
|
||||
}
|
||||
|
||||
ColorDialog {
|
||||
id: waterColorDialog
|
||||
title: "Water color"
|
||||
color: "#63c5ee"
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: menu
|
||||
anchors.margins: -20
|
||||
radius: 30
|
||||
clip: true
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: menu
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: 30
|
||||
|
||||
Label {
|
||||
text: "Bearing:"
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: bearingSlider
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
maximumValue: 180
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Pitch:"
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: pitchSlider
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
maximumValue: 60
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
title: "Style:"
|
||||
|
||||
ColumnLayout {
|
||||
ExclusiveGroup { id: styleGroup }
|
||||
RadioButton {
|
||||
text: "Streets"
|
||||
checked: true
|
||||
exclusiveGroup: styleGroup
|
||||
onClicked: {
|
||||
style.url = "mapbox://styles/mapbox/streets-v9"
|
||||
landColorDialog.color = "#e0ded8"
|
||||
waterColorDialog.color = "#63c5ee"
|
||||
}
|
||||
}
|
||||
RadioButton {
|
||||
text: "Dark"
|
||||
exclusiveGroup: styleGroup
|
||||
onClicked: {
|
||||
style.url = "mapbox://styles/mapbox/dark-v9"
|
||||
landColorDialog.color = "#343332"
|
||||
waterColorDialog.color = "#191a1a"
|
||||
}
|
||||
}
|
||||
RadioButton {
|
||||
text: "Satellite"
|
||||
exclusiveGroup: styleGroup
|
||||
onClicked: {
|
||||
style.url = "mapbox://styles/mapbox/satellite-v9"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
text: "Select land color"
|
||||
onClicked: landColorDialog.open()
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
text: "Select water color"
|
||||
onClicked: waterColorDialog.open()
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
title: "Route:"
|
||||
|
||||
ColumnLayout {
|
||||
ExclusiveGroup { id: sourceGroup }
|
||||
RadioButton {
|
||||
text: "Route 1"
|
||||
checked: true
|
||||
exclusiveGroup: sourceGroup
|
||||
onClicked: {
|
||||
source.data = ":source1.geojson"
|
||||
}
|
||||
}
|
||||
RadioButton {
|
||||
text: "Route 2"
|
||||
exclusiveGroup: sourceGroup
|
||||
onClicked: {
|
||||
source.data = ":source2.geojson"
|
||||
}
|
||||
}
|
||||
RadioButton {
|
||||
text: "Route 3"
|
||||
exclusiveGroup: sourceGroup
|
||||
onClicked: {
|
||||
source.data = '{ "type": "FeatureCollection", "features": \
|
||||
[{ "type": "Feature", "properties": {}, "geometry": { \
|
||||
"type": "LineString", "coordinates": [[ 24.934938848018646, \
|
||||
60.16830257086771 ], [ 24.943315386772156, 60.16227776476442 ]]}}]}'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: toggleRoute
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
text: "Toggle route"
|
||||
checked: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -3,7 +3,6 @@ find_package(Qt5Gui REQUIRED)
|
||||
find_package(Qt5Location REQUIRED)
|
||||
find_package(Qt5Network REQUIRED)
|
||||
find_package(Qt5OpenGL REQUIRED)
|
||||
find_package(Qt5Quick REQUIRED)
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
find_package(Qt5Sql REQUIRED)
|
||||
|
||||
@@ -21,21 +20,11 @@ set(MBGL_QT_TEST_LIBRARIES
|
||||
PRIVATE Qt5::OpenGL
|
||||
)
|
||||
|
||||
target_sources(qmapboxgl
|
||||
PRIVATE platform/qt/include/qquickmapboxgl.hpp
|
||||
PRIVATE platform/qt/include/qquickmapboxglmapparameter.hpp
|
||||
PRIVATE platform/qt/src/qquickmapboxgl.cpp
|
||||
PRIVATE platform/qt/src/qquickmapboxglmapparameter.cpp
|
||||
PRIVATE platform/qt/src/qquickmapboxglrenderer.cpp
|
||||
PRIVATE platform/qt/src/qquickmapboxglrenderer.hpp
|
||||
)
|
||||
|
||||
target_link_libraries(qmapboxgl
|
||||
PRIVATE mbgl-core
|
||||
PRIVATE Qt5::Core
|
||||
PRIVATE Qt5::Gui
|
||||
PRIVATE Qt5::Location
|
||||
PRIVATE Qt5::Quick
|
||||
PRIVATE Qt5::Sql
|
||||
)
|
||||
|
||||
@@ -44,16 +33,3 @@ target_link_libraries(mbgl-qt
|
||||
PRIVATE Qt5::OpenGL
|
||||
PRIVATE Qt5::Widgets
|
||||
)
|
||||
|
||||
# QtQuick app
|
||||
add_executable(mbgl-qt-qml
|
||||
platform/qt/qmlapp/main.cpp
|
||||
platform/qt/qmlapp/qml.qrc
|
||||
platform/qt/resources/common.qrc
|
||||
)
|
||||
|
||||
target_link_libraries(mbgl-qt-qml
|
||||
PRIVATE qmapboxgl
|
||||
PRIVATE Qt5::Location
|
||||
PRIVATE Qt5::Quick
|
||||
)
|
||||
|
||||
@@ -1,469 +0,0 @@
|
||||
#include "qquickmapboxgl.hpp"
|
||||
|
||||
#include "qquickmapboxglmapparameter.hpp"
|
||||
#include "qquickmapboxglrenderer.hpp"
|
||||
|
||||
#include <mbgl/util/constants.hpp>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QQuickItem>
|
||||
#include <QRegularExpression>
|
||||
#include <QString>
|
||||
#include <QtGlobal>
|
||||
#include <QQmlListProperty>
|
||||
#include <QJSValue>
|
||||
|
||||
namespace {
|
||||
|
||||
static const QRegularExpression s_camelCase {"([a-z0-9])([A-Z])"};
|
||||
static const QStringList s_parameterTypes = QStringList()
|
||||
<< "style" << "paint" << "layout" << "layer" << "source" << "filter" << "image"
|
||||
<< "bearing" << "pitch";
|
||||
|
||||
} // namespace
|
||||
|
||||
QQuickMapboxGL::QQuickMapboxGL(QQuickItem *parent_)
|
||||
: QQuickFramebufferObject(parent_)
|
||||
{
|
||||
}
|
||||
|
||||
QQuickMapboxGL::~QQuickMapboxGL()
|
||||
{
|
||||
}
|
||||
|
||||
QQuickFramebufferObject::Renderer *QQuickMapboxGL::createRenderer() const
|
||||
{
|
||||
return new QQuickMapboxGLRenderer;
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::setPlugin(QDeclarativeGeoServiceProvider *)
|
||||
{
|
||||
m_error = QGeoServiceProvider::NotSupportedError;
|
||||
m_errorString = "QQuickMapboxGL does not support plugins.";
|
||||
emit errorChanged();
|
||||
}
|
||||
|
||||
QDeclarativeGeoServiceProvider *QQuickMapboxGL::plugin() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::componentComplete()
|
||||
{
|
||||
QQuickFramebufferObject::componentComplete();
|
||||
|
||||
for (const auto& param : m_parameters) {
|
||||
processMapParameter(param);
|
||||
}
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::setMinimumZoomLevel(qreal zoom)
|
||||
{
|
||||
zoom = qMax(mbgl::util::MIN_ZOOM, zoom);
|
||||
zoom = qMin(m_maximumZoomLevel, zoom);
|
||||
|
||||
if (m_minimumZoomLevel == zoom) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_minimumZoomLevel = zoom;
|
||||
setZoomLevel(m_zoomLevel); // Constrain.
|
||||
|
||||
emit minimumZoomLevelChanged();
|
||||
}
|
||||
|
||||
qreal QQuickMapboxGL::minimumZoomLevel() const
|
||||
{
|
||||
return m_minimumZoomLevel;
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::setMaximumZoomLevel(qreal zoom)
|
||||
{
|
||||
zoom = qMin(mbgl::util::MAX_ZOOM, zoom);
|
||||
zoom = qMax(m_minimumZoomLevel, zoom);
|
||||
|
||||
if (m_maximumZoomLevel == zoom) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_maximumZoomLevel = zoom;
|
||||
setZoomLevel(m_zoomLevel); // Constrain.
|
||||
|
||||
emit maximumZoomLevelChanged();
|
||||
}
|
||||
|
||||
qreal QQuickMapboxGL::maximumZoomLevel() const
|
||||
{
|
||||
return m_maximumZoomLevel;
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::setZoomLevel(qreal zoom)
|
||||
{
|
||||
zoom = qMin(m_maximumZoomLevel, zoom);
|
||||
zoom = qMax(m_minimumZoomLevel, zoom);
|
||||
|
||||
if (m_zoomLevel == zoom) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_zoomLevel = zoom;
|
||||
|
||||
m_syncState |= ZoomNeedsSync;
|
||||
update();
|
||||
|
||||
emit zoomLevelChanged(m_zoomLevel);
|
||||
}
|
||||
|
||||
qreal QQuickMapboxGL::zoomLevel() const
|
||||
{
|
||||
return m_zoomLevel;
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::setCenter(const QGeoCoordinate &coordinate)
|
||||
{
|
||||
if (m_center == coordinate) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_center = coordinate;
|
||||
|
||||
m_syncState |= CenterNeedsSync;
|
||||
update();
|
||||
|
||||
emit centerChanged(m_center);
|
||||
}
|
||||
|
||||
QGeoCoordinate QQuickMapboxGL::center() const
|
||||
{
|
||||
return m_center;
|
||||
}
|
||||
|
||||
QGeoServiceProvider::Error QQuickMapboxGL::error() const
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
QString QQuickMapboxGL::errorString() const
|
||||
{
|
||||
return m_errorString;
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::setVisibleRegion(const QGeoShape &shape)
|
||||
{
|
||||
m_visibleRegion = shape;
|
||||
}
|
||||
|
||||
QGeoShape QQuickMapboxGL::visibleRegion() const
|
||||
{
|
||||
return m_visibleRegion;
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::setCopyrightsVisible(bool)
|
||||
{
|
||||
qWarning() << Q_FUNC_INFO << "Not implemented.";
|
||||
}
|
||||
|
||||
bool QQuickMapboxGL::copyrightsVisible() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::setColor(const QColor &color)
|
||||
{
|
||||
if (m_color == color) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_color = color;
|
||||
|
||||
StyleProperty change;
|
||||
change.type = StyleProperty::Paint;
|
||||
change.layer = "background";
|
||||
change.property = "background-color";
|
||||
change.value = color;
|
||||
m_stylePropertyChanges << change;
|
||||
|
||||
update();
|
||||
|
||||
emit colorChanged(m_color);
|
||||
}
|
||||
|
||||
QColor QQuickMapboxGL::color() const
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::pan(int dx, int dy)
|
||||
{
|
||||
m_pan += QPointF(dx, -dy);
|
||||
|
||||
m_syncState |= PanNeedsSync;
|
||||
update();
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::onMapChanged(QMapboxGL::MapChange change)
|
||||
{
|
||||
if (change == QMapboxGL::MapChangeDidFinishLoadingStyle) {
|
||||
m_styleLoaded = true;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
bool QQuickMapboxGL::parseImage(QQuickMapboxGLMapParameter *param)
|
||||
{
|
||||
m_imageChanges << Image {
|
||||
param->property("name").toString(),
|
||||
QImage(param->property("sprite").toString())
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QQuickMapboxGL::parseStyle(QQuickMapboxGLMapParameter *param)
|
||||
{
|
||||
QString url = param->property("url").toString();
|
||||
if (m_styleUrl == url) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reload parameters if switching style URLs.
|
||||
if (!m_styleUrl.isEmpty()) {
|
||||
for (const auto& param_ : m_parameters) {
|
||||
if (param_->property("type").toString() == "style") continue;
|
||||
processMapParameter(param_);
|
||||
}
|
||||
}
|
||||
|
||||
m_styleUrl = url;
|
||||
m_styleLoaded = false;
|
||||
m_syncState |= StyleNeedsSync;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QQuickMapboxGL::parseStyleProperty(QQuickMapboxGLMapParameter *param, const QString &name)
|
||||
{
|
||||
// Ignore meta-properties "type", "layer" and "class".
|
||||
if (name == "type" || name == "layer" || name == "class") {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString formattedName(name);
|
||||
formattedName = formattedName.replace(s_camelCase, "\\1-\\2").toLower();
|
||||
|
||||
QVariant value = param->property(name.toLatin1());
|
||||
if (value.canConvert<QJSValue>()) {
|
||||
value = value.value<QJSValue>().toVariant();
|
||||
}
|
||||
|
||||
m_stylePropertyChanges << QQuickMapboxGL::StyleProperty {
|
||||
param->property("type").toString().at(0) == 'p' ? StyleProperty::Paint : StyleProperty::Layout,
|
||||
param->property("layer").toString(),
|
||||
formattedName,
|
||||
value,
|
||||
param->property("class").toString()
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QQuickMapboxGL::parseStyleLayer(QQuickMapboxGLMapParameter *param)
|
||||
{
|
||||
QVariantMap layer;
|
||||
layer["id"] = param->property("name");
|
||||
layer["source"] = param->property("source");
|
||||
layer["type"] = param->property("layerType");
|
||||
if (param->property("sourceLayer").isValid()) {
|
||||
layer["source-layer"] = param->property("sourceLayer");
|
||||
}
|
||||
m_layerChanges << layer;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QQuickMapboxGL::parseStyleSource(QQuickMapboxGLMapParameter *param)
|
||||
{
|
||||
QString sourceType = param->property("sourceType").toString();
|
||||
|
||||
QVariantMap source;
|
||||
source["id"] = param->property("name");
|
||||
source["type"] = sourceType;
|
||||
if (sourceType == "vector" || sourceType == "raster") {
|
||||
source["url"] = param->property("url");
|
||||
m_sourceChanges << source;
|
||||
} else if (sourceType == "geojson") {
|
||||
auto data = param->property("data").toString();
|
||||
if (data.startsWith(':')) {
|
||||
QFile geojson(data);
|
||||
geojson.open(QIODevice::ReadOnly);
|
||||
source["data"] = geojson.readAll();
|
||||
} else {
|
||||
source["data"] = data.toUtf8();
|
||||
}
|
||||
m_sourceChanges << source;
|
||||
} else {
|
||||
m_error = QGeoServiceProvider::UnknownParameterError;
|
||||
m_errorString = "Invalid source type: " + sourceType;
|
||||
emit errorChanged();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QQuickMapboxGL::parseStyleFilter(QQuickMapboxGLMapParameter *param)
|
||||
{
|
||||
QVariantMap filter;
|
||||
filter["layer"] = param->property("layer");
|
||||
filter["filter"] = param->property("filter");
|
||||
m_filterChanges << filter;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QQuickMapboxGL::parseBearing(QQuickMapboxGLMapParameter *param)
|
||||
{
|
||||
qreal angle = param->property("angle").toReal();
|
||||
if (m_bearing == angle) return false;
|
||||
m_bearing = angle;
|
||||
m_syncState |= BearingNeedsSync;
|
||||
update();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QQuickMapboxGL::parsePitch(QQuickMapboxGLMapParameter *param)
|
||||
{
|
||||
qreal angle = param->property("angle").toReal();
|
||||
angle = qMin(qMax(0., angle), mbgl::util::PITCH_MAX * mbgl::util::RAD2DEG);
|
||||
if (m_pitch == angle) return false;
|
||||
m_pitch = angle;
|
||||
m_syncState |= PitchNeedsSync;
|
||||
update();
|
||||
return true;
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::processMapParameter(QQuickMapboxGLMapParameter *param)
|
||||
{
|
||||
bool needsUpdate = false;
|
||||
switch (s_parameterTypes.indexOf(param->property("type").toString())) {
|
||||
case -1:
|
||||
m_error = QGeoServiceProvider::UnknownParameterError;
|
||||
m_errorString = "Invalid value for property 'type': " + param->property("type").toString();
|
||||
emit errorChanged();
|
||||
break;
|
||||
case 0: // style
|
||||
needsUpdate |= parseStyle(param);
|
||||
break;
|
||||
case 1: // paint
|
||||
case 2: // layout
|
||||
for (int i = param->propertyOffset(); i < param->metaObject()->propertyCount(); ++i) {
|
||||
needsUpdate |= parseStyleProperty(param, QString(param->metaObject()->property(i).name()));
|
||||
}
|
||||
break;
|
||||
case 3: // layer
|
||||
needsUpdate |= parseStyleLayer(param);
|
||||
break;
|
||||
case 4: // source
|
||||
needsUpdate |= parseStyleSource(param);
|
||||
break;
|
||||
case 5: // filter
|
||||
needsUpdate |= parseStyleFilter(param);
|
||||
break;
|
||||
case 6: // image
|
||||
needsUpdate |= parseImage(param);
|
||||
break;
|
||||
case 7: // bearing
|
||||
needsUpdate |= parseBearing(param);
|
||||
break;
|
||||
case 8: // pitch
|
||||
needsUpdate |= parsePitch(param);
|
||||
break;
|
||||
}
|
||||
if (needsUpdate) update();
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::onParameterPropertyUpdated(const QString &propertyName)
|
||||
{
|
||||
QQuickMapboxGLMapParameter *param = qobject_cast<QQuickMapboxGLMapParameter *>(sender());
|
||||
if (!param) {
|
||||
m_error = QGeoServiceProvider::NotSupportedError;
|
||||
m_errorString = "QQuickMapboxGL::onParameterPropertyUpdated should be called from a QQuickMapboxGLMapParameter.";
|
||||
emit errorChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
if (propertyName == "type") {
|
||||
m_error = QGeoServiceProvider::NotSupportedError;
|
||||
m_errorString = "Property 'type' is a write-once.";
|
||||
emit errorChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
bool needsUpdate = false;
|
||||
switch (s_parameterTypes.indexOf(param->property("type").toString())) {
|
||||
case -1:
|
||||
m_error = QGeoServiceProvider::UnknownParameterError;
|
||||
m_errorString = "Invalid value for property 'type': " + param->property("type").toString();
|
||||
emit errorChanged();
|
||||
break;
|
||||
case 0: // style
|
||||
needsUpdate |= parseStyle(param);
|
||||
break;
|
||||
case 1: // paint
|
||||
case 2: // layout
|
||||
needsUpdate |= parseStyleProperty(param, propertyName);
|
||||
break;
|
||||
case 3: // layer
|
||||
needsUpdate |= parseStyleLayer(param);
|
||||
break;
|
||||
case 4: // source
|
||||
needsUpdate |= parseStyleSource(param);
|
||||
break;
|
||||
case 5: // filter
|
||||
needsUpdate |= parseStyleFilter(param);
|
||||
break;
|
||||
case 6: // image
|
||||
needsUpdate |= parseImage(param);
|
||||
break;
|
||||
case 7: // bearing
|
||||
needsUpdate |= parseBearing(param);
|
||||
break;
|
||||
case 8: // pitch
|
||||
needsUpdate |= parsePitch(param);
|
||||
break;
|
||||
}
|
||||
if (needsUpdate) update();
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::appendParameter(QQmlListProperty<QQuickMapboxGLMapParameter> *prop, QQuickMapboxGLMapParameter *param)
|
||||
{
|
||||
QQuickMapboxGL *map = static_cast<QQuickMapboxGL *>(prop->object);
|
||||
map->m_parameters.append(param);
|
||||
QObject::connect(param, SIGNAL(propertyUpdated(QString)), map, SLOT(onParameterPropertyUpdated(QString)));
|
||||
}
|
||||
|
||||
int QQuickMapboxGL::countParameters(QQmlListProperty<QQuickMapboxGLMapParameter> *prop)
|
||||
{
|
||||
QQuickMapboxGL *map = static_cast<QQuickMapboxGL *>(prop->object);
|
||||
return map->m_parameters.count();
|
||||
}
|
||||
|
||||
QQuickMapboxGLMapParameter *QQuickMapboxGL::parameterAt(QQmlListProperty<QQuickMapboxGLMapParameter> *prop, int index)
|
||||
{
|
||||
QQuickMapboxGL *map = static_cast<QQuickMapboxGL *>(prop->object);
|
||||
return map->m_parameters[index];
|
||||
}
|
||||
|
||||
void QQuickMapboxGL::clearParameter(QQmlListProperty<QQuickMapboxGLMapParameter> *prop)
|
||||
{
|
||||
QQuickMapboxGL *map = static_cast<QQuickMapboxGL *>(prop->object);
|
||||
for (auto param : map->m_parameters) {
|
||||
QObject::disconnect(param, SIGNAL(propertyUpdated(QString)), map, SLOT(onParameterPropertyUpdated(QString)));
|
||||
}
|
||||
map->m_parameters.clear();
|
||||
}
|
||||
|
||||
QQmlListProperty<QQuickMapboxGLMapParameter> QQuickMapboxGL::parameters()
|
||||
{
|
||||
return QQmlListProperty<QQuickMapboxGLMapParameter>(this,
|
||||
nullptr,
|
||||
appendParameter,
|
||||
countParameters,
|
||||
parameterAt,
|
||||
clearParameter);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#include "qquickmapboxglmapparameter.hpp"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QMetaObject>
|
||||
#include <QMetaProperty>
|
||||
#include <QSignalMapper>
|
||||
|
||||
QQuickMapboxGLMapParameter::QQuickMapboxGLMapParameter(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_metaPropertyOffset(metaObject()->propertyCount())
|
||||
{
|
||||
}
|
||||
|
||||
void QQuickMapboxGLMapParameter::componentComplete()
|
||||
{
|
||||
for (int i = m_metaPropertyOffset; i < metaObject()->propertyCount(); ++i) {
|
||||
QMetaProperty property = metaObject()->property(i);
|
||||
|
||||
if (!property.hasNotifySignal()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto mapper = new QSignalMapper(this);
|
||||
mapper->setMapping(this, i);
|
||||
|
||||
const QByteArray signalName = '2' + property.notifySignal().methodSignature();
|
||||
QObject::connect(this, signalName, mapper, SLOT(map()));
|
||||
QObject::connect(mapper, SIGNAL(mapped(int)), this, SLOT(onPropertyUpdated(int)));
|
||||
}
|
||||
}
|
||||
|
||||
void QQuickMapboxGLMapParameter::onPropertyUpdated(int index)
|
||||
{
|
||||
emit propertyUpdated(metaObject()->property(index).name());
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
#include "qquickmapboxglrenderer.hpp"
|
||||
|
||||
#include "qmapboxgl.hpp"
|
||||
#include "qquickmapboxgl.hpp"
|
||||
|
||||
#include <QSize>
|
||||
#include <QOpenGLFramebufferObject>
|
||||
#include <QOpenGLFramebufferObjectFormat>
|
||||
#include <QQuickWindow>
|
||||
#include <QThread>
|
||||
|
||||
QQuickMapboxGLRenderer::QQuickMapboxGLRenderer()
|
||||
{
|
||||
QMapbox::initializeGLExtensions();
|
||||
|
||||
QMapboxGLSettings settings;
|
||||
settings.setAccessToken(qgetenv("MAPBOX_ACCESS_TOKEN"));
|
||||
settings.setCacheDatabasePath("/tmp/mbgl-cache.db");
|
||||
settings.setCacheDatabaseMaximumSize(20 * 1024 * 1024);
|
||||
settings.setViewportMode(QMapboxGLSettings::FlippedYViewport);
|
||||
|
||||
m_map.reset(new QMapboxGL(nullptr, settings, QSize(256, 256), 1));
|
||||
}
|
||||
|
||||
QQuickMapboxGLRenderer::~QQuickMapboxGLRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
QOpenGLFramebufferObject* QQuickMapboxGLRenderer::createFramebufferObject(const QSize &size)
|
||||
{
|
||||
m_map->resize(size / m_pixelRatio, size);
|
||||
|
||||
QOpenGLFramebufferObjectFormat format;
|
||||
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
|
||||
|
||||
return new QOpenGLFramebufferObject(size, format);
|
||||
}
|
||||
|
||||
void QQuickMapboxGLRenderer::render()
|
||||
{
|
||||
framebufferObject()->bind();
|
||||
m_map->render();
|
||||
framebufferObject()->release();
|
||||
}
|
||||
|
||||
void QQuickMapboxGLRenderer::synchronize(QQuickFramebufferObject *item)
|
||||
{
|
||||
auto quickMap = qobject_cast<QQuickMapboxGL*>(item);
|
||||
if (!m_initialized) {
|
||||
QObject::connect(m_map.data(), &QMapboxGL::needsRendering, quickMap, &QQuickMapboxGL::update);
|
||||
QObject::connect(m_map.data(), SIGNAL(mapChanged(QMapboxGL::MapChange)), quickMap, SLOT(onMapChanged(QMapboxGL::MapChange)));
|
||||
QObject::connect(this, &QQuickMapboxGLRenderer::centerChanged, quickMap, &QQuickMapboxGL::setCenter);
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
if (auto window = quickMap->window()) {
|
||||
m_pixelRatio = window->devicePixelRatio();
|
||||
} else {
|
||||
m_pixelRatio = 1;
|
||||
}
|
||||
|
||||
auto syncStatus = quickMap->m_syncState;
|
||||
quickMap->m_syncState = QQuickMapboxGL::NothingNeedsSync;
|
||||
|
||||
if (syncStatus & QQuickMapboxGL::CenterNeedsSync || syncStatus & QQuickMapboxGL::ZoomNeedsSync) {
|
||||
const auto& center = quickMap->center();
|
||||
m_map->setCoordinateZoom({ center.latitude(), center.longitude() }, quickMap->zoomLevel());
|
||||
}
|
||||
|
||||
if (syncStatus & QQuickMapboxGL::StyleNeedsSync && !quickMap->m_styleUrl.isEmpty()) {
|
||||
m_map->setStyleUrl(quickMap->m_styleUrl);
|
||||
}
|
||||
|
||||
if (syncStatus & QQuickMapboxGL::PanNeedsSync) {
|
||||
m_map->moveBy(quickMap->m_pan);
|
||||
quickMap->m_pan = QPointF();
|
||||
emit centerChanged(QGeoCoordinate(m_map->latitude(), m_map->longitude()));
|
||||
}
|
||||
|
||||
if (syncStatus & QQuickMapboxGL::BearingNeedsSync) {
|
||||
m_map->setBearing(quickMap->m_bearing);
|
||||
}
|
||||
|
||||
if (syncStatus & QQuickMapboxGL::PitchNeedsSync) {
|
||||
m_map->setPitch(quickMap->m_pitch);
|
||||
}
|
||||
|
||||
if (!quickMap->m_styleLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& change : quickMap->m_sourceChanges) {
|
||||
m_map->updateSource(change.value("id").toString(), change);
|
||||
}
|
||||
quickMap->m_sourceChanges.clear();
|
||||
|
||||
for (const auto& change : quickMap->m_layerChanges) {
|
||||
m_map->addLayer(change);
|
||||
}
|
||||
quickMap->m_layerChanges.clear();
|
||||
|
||||
for (const auto& change : quickMap->m_filterChanges) {
|
||||
m_map->setFilter(change.value("layer").toString(), change.value("filter"));
|
||||
}
|
||||
quickMap->m_filterChanges.clear();
|
||||
|
||||
for (const auto& change : quickMap->m_imageChanges) {
|
||||
m_map->addImage(change.name, change.sprite);
|
||||
}
|
||||
quickMap->m_imageChanges.clear();
|
||||
|
||||
for (const auto& change : quickMap->m_stylePropertyChanges) {
|
||||
if (change.type == QQuickMapboxGL::StyleProperty::Paint) {
|
||||
m_map->setPaintProperty(change.layer, change.property, change.value, change.klass);
|
||||
} else {
|
||||
m_map->setLayoutProperty(change.layer, change.property, change.value);
|
||||
}
|
||||
}
|
||||
quickMap->m_stylePropertyChanges.clear();
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "qmapbox.hpp"
|
||||
#include "qmapboxgl.hpp"
|
||||
|
||||
#include <QGeoCoordinate>
|
||||
#include <QObject>
|
||||
#include <QOpenGLFramebufferObject>
|
||||
#include <QQuickFramebufferObject>
|
||||
#include <QScopedPointer>
|
||||
#include <QSize>
|
||||
|
||||
class QQuickMapboxGLRenderer : public QObject, public QQuickFramebufferObject::Renderer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QQuickMapboxGLRenderer();
|
||||
virtual ~QQuickMapboxGLRenderer();
|
||||
|
||||
virtual QOpenGLFramebufferObject * createFramebufferObject(const QSize &);
|
||||
|
||||
virtual void render();
|
||||
virtual void synchronize(QQuickFramebufferObject *);
|
||||
|
||||
signals:
|
||||
void centerChanged(const QGeoCoordinate &);
|
||||
|
||||
private:
|
||||
bool m_initialized = false;
|
||||
qreal m_pixelRatio = 1;
|
||||
|
||||
QScopedPointer<QMapboxGL> m_map;
|
||||
};
|
||||
Reference in New Issue
Block a user