summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2017-01-24 18:05:22 +0200
committerBruno de Oliveira Abinader <bruno@mapbox.com>2017-01-26 14:53:45 +0200
commitbe43310b6ff5465e6717128b577f6e61c0335c44 (patch)
tree330ba9aa8c9a1af84e9d504301c9d716fafe53b6
parentfb759e949fc6381b92eb2149cbea1db3e282de4b (diff)
downloadqtlocation-mapboxgl-be43310b6ff5465e6717128b577f6e61c0335c44.tar.gz
[Qt] Refactor QMapbox Annotations API
-rw-r--r--platform/qt/app/mapwindow.cpp55
-rw-r--r--platform/qt/app/mapwindow.hpp5
-rw-r--r--platform/qt/include/qmapbox.hpp70
-rw-r--r--platform/qt/include/qmapboxgl.hpp7
-rw-r--r--platform/qt/resources/common.qrc1
-rw-r--r--platform/qt/src/qmapboxgl.cpp132
6 files changed, 222 insertions, 48 deletions
diff --git a/platform/qt/app/mapwindow.cpp b/platform/qt/app/mapwindow.cpp
index 0b453406f3..3e6a14736f 100644
--- a/platform/qt/app/mapwindow.cpp
+++ b/platform/qt/app/mapwindow.cpp
@@ -203,6 +203,61 @@ void MapWindow::keyPressEvent(QKeyEvent *ev)
m_map->setLayoutProperty("road-label-small", "text-size", 30.0);
}
break;
+ case Qt::Key_1: {
+ if (m_symbolAnnotationId.isNull()) {
+ QMapbox::Coordinate coordinate = m_map->coordinate();
+ QMapbox::SymbolAnnotation symbol { coordinate, "default_marker" };
+ m_map->addAnnotationIcon("default_marker", QImage(":default_marker.svg"));
+ m_symbolAnnotationId = m_map->addAnnotation(QVariant::fromValue<QMapbox::SymbolAnnotation>(symbol));
+ } else {
+ m_map->removeAnnotation(m_symbolAnnotationId.toUInt());
+ m_symbolAnnotationId.clear();
+ }
+ }
+ break;
+ case Qt::Key_2: {
+ if (m_lineAnnotationId.isNull()) {
+ QMapbox::Coordinate topLeft = m_map->coordinateForPixel({ 0, 0 });
+ QMapbox::Coordinate bottomRight = m_map->coordinateForPixel({ qreal(size().width()), qreal(size().height()) });
+ QMapbox::CoordinatesCollections geometry { { { topLeft, bottomRight } } };
+ QMapbox::LineAnnotation line { { QMapbox::ShapeAnnotationGeometry::Type::LineStringType, geometry }, 0.5f, 1.0f, Qt::red };
+ m_lineAnnotationId = m_map->addAnnotation(QVariant::fromValue<QMapbox::LineAnnotation>(line));
+ } else {
+ m_map->removeAnnotation(m_lineAnnotationId.toUInt());
+ m_lineAnnotationId.clear();
+ }
+ }
+ break;
+ case Qt::Key_3: {
+ if (m_fillAnnotationId.isNull()) {
+ QMapbox::Coordinate topLeft = m_map->coordinateForPixel({ 0, 0 });
+ QMapbox::Coordinate topRight = m_map->coordinateForPixel({ 0, qreal(size().height()) });
+ QMapbox::Coordinate bottomLeft = m_map->coordinateForPixel({ qreal(size().width()), 0 });
+ QMapbox::Coordinate bottomRight = m_map->coordinateForPixel({ qreal(size().width()), qreal(size().height()) });
+ QMapbox::CoordinatesCollections geometry { { { bottomLeft, bottomRight, topRight, topLeft, bottomLeft } } };
+ QMapbox::FillAnnotation fill { { QMapbox::ShapeAnnotationGeometry::Type::PolygonType, geometry }, 0.5f, Qt::green, QVariant::fromValue<QColor>(QColor(Qt::black)) };
+ m_fillAnnotationId = m_map->addAnnotation(QVariant::fromValue<QMapbox::FillAnnotation>(fill));
+ } else {
+ m_map->removeAnnotation(m_fillAnnotationId.toUInt());
+ m_fillAnnotationId.clear();
+ }
+ }
+ break;
+ case Qt::Key_4: {
+ if (m_styleSourcedAnnotationId.isNull()) {
+ QMapbox::Coordinate topLeft = m_map->coordinateForPixel({ 0, 0 });
+ QMapbox::Coordinate topRight = m_map->coordinateForPixel({ 0, qreal(size().height()) });
+ QMapbox::Coordinate bottomLeft = m_map->coordinateForPixel({ qreal(size().width()), 0 });
+ QMapbox::Coordinate bottomRight = m_map->coordinateForPixel({ qreal(size().width()), qreal(size().height()) });
+ QMapbox::CoordinatesCollections geometry { { { bottomLeft, bottomRight, topRight, topLeft, bottomLeft } } };
+ QMapbox::StyleSourcedAnnotation styleSourced { { QMapbox::ShapeAnnotationGeometry::Type::PolygonType, geometry }, "water" };
+ m_styleSourcedAnnotationId = m_map->addAnnotation(QVariant::fromValue<QMapbox::StyleSourcedAnnotation>(styleSourced));
+ } else {
+ m_map->removeAnnotation(m_styleSourcedAnnotationId.toUInt());
+ m_styleSourcedAnnotationId.clear();
+ }
+ }
+ break;
case Qt::Key_Tab:
m_map->cycleDebugOptions();
break;
diff --git a/platform/qt/app/mapwindow.hpp b/platform/qt/app/mapwindow.hpp
index 23880902d3..6b4b7fd1cc 100644
--- a/platform/qt/app/mapwindow.hpp
+++ b/platform/qt/app/mapwindow.hpp
@@ -61,6 +61,11 @@ private:
unsigned m_animationTicks = 0;
unsigned m_frameDraws = 0;
+ QVariant m_symbolAnnotationId;
+ QVariant m_lineAnnotationId;
+ QVariant m_fillAnnotationId;
+ QVariant m_styleSourcedAnnotationId;
+
bool m_sourceAdded = false;
};
diff --git a/platform/qt/include/qmapbox.hpp b/platform/qt/include/qmapbox.hpp
index 3aaacb84ea..1388c0f513 100644
--- a/platform/qt/include/qmapbox.hpp
+++ b/platform/qt/include/qmapbox.hpp
@@ -1,6 +1,7 @@
#ifndef QMAPBOX_H
#define QMAPBOX_H
+#include <QColor>
#include <QList>
#include <QPair>
#include <QVariant>
@@ -10,18 +11,64 @@
namespace QMapbox {
+// Reflects mapbox::geometry::point<double>.
typedef QPair<double, double> Coordinate;
-typedef QList<Coordinate> LineString;
-
typedef QPair<Coordinate, double> CoordinateZoom;
-typedef quint32 AnnotationID;
-typedef QList<AnnotationID> AnnotationIDs;
+// Reflects mapbox::geometry::line_string<double> and mapbox::geometry::linear_ring<double>.
+typedef QList<Coordinate> Coordinates;
+
+// Reflects mapbox::geometry::multi_line_string<double> and mapbox::geometry::polygon<double>.
+typedef QList<Coordinates> CoordinatesCollection;
+
+// Reflects mapbox::geometry::multi_polygon<double>.
+typedef QList<CoordinatesCollection> CoordinatesCollections;
+
+// Reflects mbgl::ShapeAnnotationGeometry.
+struct Q_DECL_EXPORT ShapeAnnotationGeometry {
+ enum Type {
+ LineStringType,
+ PolygonType,
+ MultiLineStringType,
+ MultiPolygonType
+ };
+ Type type;
+ CoordinatesCollections geometry;
+};
+
+// Reflects mbgl::SymbolAnnotation.
+struct Q_DECL_EXPORT SymbolAnnotation {
+ Coordinate geometry;
+ QString icon;
+};
+
+// Reflects mbgl::LineAnnotation.
+struct Q_DECL_EXPORT LineAnnotation {
+ ShapeAnnotationGeometry geometry;
+ float opacity = 1.0f;
+ float width = 1.0f;
+ QColor color = Qt::black;
+};
+
+// Reflects mbgl::FillAnnotation.
+struct Q_DECL_EXPORT FillAnnotation {
+ ShapeAnnotationGeometry geometry;
+ float opacity = 1.0f;
+ QColor color = Qt::black;
+ QVariant outlineColor;
+};
-typedef QPair<Coordinate, QString> PointAnnotation;
+// Reflects mbgl::StyleSourcedAnnotation.
+struct Q_DECL_EXPORT StyleSourcedAnnotation {
+ ShapeAnnotationGeometry geometry;
+ QString layerID;
+};
-// FIXME: We need to add support for custom style properties
-typedef QPair<LineString, QString> ShapeAnnotation;
+// SymbolAnnotation, LineAnnotation, FillAnnotation, StyleSourcedAnnotation.
+typedef QVariant Annotation;
+
+typedef quint32 AnnotationID;
+typedef QList<AnnotationID> AnnotationIDs;
// Reflects mbgl::NetworkStatus::Status.
enum NetworkMode {
@@ -55,5 +102,14 @@ Q_DECL_EXPORT void initializeGLExtensions();
} // namespace QMapbox
Q_DECLARE_METATYPE(QMapbox::Coordinate);
+Q_DECLARE_METATYPE(QMapbox::Coordinates);
+Q_DECLARE_METATYPE(QMapbox::CoordinatesCollection);
+Q_DECLARE_METATYPE(QMapbox::CoordinatesCollections);
+
+Q_DECLARE_METATYPE(QMapbox::SymbolAnnotation);
+Q_DECLARE_METATYPE(QMapbox::ShapeAnnotationGeometry);
+Q_DECLARE_METATYPE(QMapbox::LineAnnotation);
+Q_DECLARE_METATYPE(QMapbox::FillAnnotation);
+Q_DECLARE_METATYPE(QMapbox::StyleSourcedAnnotation);
#endif // QMAPBOX_H
diff --git a/platform/qt/include/qmapboxgl.hpp b/platform/qt/include/qmapboxgl.hpp
index be2d60608b..0f1ab7c293 100644
--- a/platform/qt/include/qmapboxgl.hpp
+++ b/platform/qt/include/qmapboxgl.hpp
@@ -183,11 +183,8 @@ public:
void addAnnotationIcon(const QString &name, const QImage &sprite);
- QMapbox::AnnotationID addPointAnnotation(const QMapbox::PointAnnotation &);
- QMapbox::AnnotationID addShapeAnnotation(const QMapbox::ShapeAnnotation &);
-
- void updatePointAnnotation(QMapbox::AnnotationID, const QMapbox::PointAnnotation &);
-
+ QMapbox::AnnotationID addAnnotation(const QMapbox::Annotation &);
+ void updateAnnotation(QMapbox::AnnotationID, const QMapbox::Annotation &);
void removeAnnotation(QMapbox::AnnotationID);
void setLayoutProperty(const QString &layer, const QString &property, const QVariant &value);
diff --git a/platform/qt/resources/common.qrc b/platform/qt/resources/common.qrc
index d02c04a3c2..4c792b057c 100644
--- a/platform/qt/resources/common.qrc
+++ b/platform/qt/resources/common.qrc
@@ -1,6 +1,7 @@
<RCC>
<qresource prefix="/">
<file alias="icon.png">../../../common/icon.png</file>
+ <file alias="default_marker.svg">../../../platform/default/resources/default_marker.svg</file>
<file>source1.geojson</file>
<file>source2.geojson</file>
<file>label-arrow.svg</file>
diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp
index 86604a945f..fb56c4d993 100644
--- a/platform/qt/src/qmapboxgl.cpp
+++ b/platform/qt/src/qmapboxgl.cpp
@@ -17,8 +17,10 @@
#include <mbgl/style/transition_options.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/storage/network_status.hpp>
+#include <mbgl/util/color.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/geo.hpp>
+#include <mbgl/util/geometry.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/traits.hpp>
@@ -85,20 +87,6 @@ QThreadStorage<std::shared_ptr<mbgl::util::RunLoop>> loop;
// Conversion helper functions.
-auto fromQMapboxGLShapeAnnotation(const ShapeAnnotation &shapeAnnotation) {
- const LineString &lineString = shapeAnnotation.first;
- const QString &styleLayer = shapeAnnotation.second;
-
- mbgl::LineString<double> mbglLineString;
- mbglLineString.reserve(lineString.size());
-
- for (const Coordinate &coordinate : lineString) {
- mbglLineString.emplace_back(mbgl::Point<double> { coordinate.first, coordinate.second });
- }
-
- return mbgl::StyleSourcedAnnotation { std::move(mbglLineString), styleLayer.toStdString() };
-}
-
auto fromQStringList(const QStringList &list)
{
std::vector<std::string> strings;
@@ -848,42 +836,114 @@ void QMapboxGL::setTransitionOptions(qint64 duration, qint64 delay) {
d_ptr->mapObj->setTransitionOptions(mbgl::style::TransitionOptions{ convert(duration), convert(delay) });
}
-mbgl::Annotation fromPointAnnotation(const PointAnnotation &pointAnnotation) {
- const Coordinate &coordinate = pointAnnotation.first;
- const QString &icon = pointAnnotation.second;
- return mbgl::SymbolAnnotation { mbgl::Point<double> { coordinate.second, coordinate.first }, icon.toStdString() };
-}
+mbgl::ShapeAnnotationGeometry asMapboxGLGeometry(const QMapbox::ShapeAnnotationGeometry &geometry) {
+ auto asMapboxGLLineString = [&](const QMapbox::Coordinates &lineString) {
+ mbgl::LineString<double> mbglLineString;
+ mbglLineString.reserve(lineString.size());
+ for (const auto &coordinate : lineString) {
+ mbglLineString.emplace_back(mbgl::Point<double> { coordinate.second, coordinate.first });
+ }
+ return mbglLineString;
+ };
-/*!
- Adds a \a point annotation to the map.
+ auto asMapboxGLMultiLineString = [&](const QMapbox::CoordinatesCollection &multiLineString) {
+ mbgl::MultiLineString<double> mbglMultiLineString;
+ mbglMultiLineString.reserve(multiLineString.size());
+ for (const auto &lineString : multiLineString) {
+ mbglMultiLineString.emplace_back(std::forward<mbgl::LineString<double>>(asMapboxGLLineString(lineString)));
+ }
+ return mbglMultiLineString;
+ };
- Returns the unique identifier for the new annotation.
+ auto asMapboxGLPolygon = [&](const QMapbox::CoordinatesCollection &polygon) {
+ mbgl::Polygon<double> mbglPolygon;
+ mbglPolygon.reserve(polygon.size());
+ for (const auto &linearRing : polygon) {
+ mbgl::LinearRing<double> mbglLinearRing;
+ mbglLinearRing.reserve(linearRing.size());
+ for (const auto &coordinate: linearRing) {
+ mbglLinearRing.emplace_back(mbgl::Point<double> { coordinate.second, coordinate.first });
+ }
+ mbglPolygon.emplace_back(std::move(mbglLinearRing));
+ }
+ return mbglPolygon;
+ };
- \sa addAnnotationIcon()
-*/
-QMapbox::AnnotationID QMapboxGL::addPointAnnotation(const QMapbox::PointAnnotation &point)
-{
- return d_ptr->mapObj->addAnnotation(fromPointAnnotation(point));
+ auto asMapboxGLMultiPolygon = [&](const QMapbox::CoordinatesCollections &multiPolygon) {
+ mbgl::MultiPolygon<double> mbglMultiPolygon;
+ mbglMultiPolygon.reserve(multiPolygon.size());
+ for (const auto &polygon : multiPolygon) {
+ mbglMultiPolygon.emplace_back(std::forward<mbgl::Polygon<double>>(asMapboxGLPolygon(polygon)));
+ }
+ return mbglMultiPolygon;
+ };
+
+ mbgl::ShapeAnnotationGeometry result;
+ switch (geometry.type) {
+ case QMapbox::ShapeAnnotationGeometry::LineStringType:
+ result = { asMapboxGLLineString(geometry.geometry.first().first()) };
+ break;
+ case QMapbox::ShapeAnnotationGeometry::PolygonType:
+ result = { asMapboxGLPolygon(geometry.geometry.first()) };
+ break;
+ case QMapbox::ShapeAnnotationGeometry::MultiLineStringType:
+ result = { asMapboxGLMultiLineString(geometry.geometry.first()) };
+ break;
+ case QMapbox::ShapeAnnotationGeometry::MultiPolygonType:
+ result = { asMapboxGLMultiPolygon(geometry.geometry) };
+ break;
+ }
+
+ return result;
+}
+
+mbgl::Annotation asMapboxGLAnnotation(const QMapbox::Annotation & annotation) {
+ if (annotation.canConvert<QMapbox::SymbolAnnotation>()) {
+ QMapbox::SymbolAnnotation symbolAnnotation = annotation.value<QMapbox::SymbolAnnotation>();
+ QMapbox::Coordinate& pair = symbolAnnotation.geometry;
+ return mbgl::SymbolAnnotation { mbgl::Point<double> { pair.second, pair.first }, symbolAnnotation.icon.toStdString() };
+ } else if (annotation.canConvert<QMapbox::LineAnnotation>()) {
+ QMapbox::LineAnnotation lineAnnotation = annotation.value<QMapbox::LineAnnotation>();
+ auto color = mbgl::Color::parse(lineAnnotation.color.name().toStdString());
+ return mbgl::LineAnnotation { asMapboxGLGeometry(lineAnnotation.geometry), lineAnnotation.opacity, lineAnnotation.width, { *color } };
+ } else if (annotation.canConvert<QMapbox::FillAnnotation>()) {
+ QMapbox::FillAnnotation fillAnnotation = annotation.value<QMapbox::FillAnnotation>();
+ auto color = mbgl::Color::parse(fillAnnotation.color.name().toStdString());
+ if (fillAnnotation.outlineColor.canConvert<QColor>()) {
+ auto outlineColor = mbgl::Color::parse(fillAnnotation.outlineColor.value<QColor>().name().toStdString());
+ return mbgl::FillAnnotation { asMapboxGLGeometry(fillAnnotation.geometry), fillAnnotation.opacity, { *color }, { *outlineColor } };
+ } else {
+ return mbgl::FillAnnotation { asMapboxGLGeometry(fillAnnotation.geometry), fillAnnotation.opacity, { *color }, {} };
+ }
+ } else if (annotation.canConvert<QMapbox::StyleSourcedAnnotation>()) {
+ QMapbox::StyleSourcedAnnotation styleSourcedAnnotation = annotation.value<QMapbox::StyleSourcedAnnotation>();
+ return mbgl::StyleSourcedAnnotation { asMapboxGLGeometry(styleSourcedAnnotation.geometry), styleSourcedAnnotation.layerID.toStdString() };
+ }
+
+ qWarning() << "Unable to convert annotation:" << annotation;
+ return {};
}
/*!
- Updates an existing \a point annotation referred by \a id.
+ Adds an \a annotation to the map.
+
+ Returns the unique identifier for the new annotation.
\sa addAnnotationIcon()
*/
-void QMapboxGL::updatePointAnnotation(QMapbox::AnnotationID id, const QMapbox::PointAnnotation &point)
+QMapbox::AnnotationID QMapboxGL::addAnnotation(const QMapbox::Annotation &annotation)
{
- d_ptr->mapObj->updateAnnotation(id, fromPointAnnotation(point));
+ return d_ptr->mapObj->addAnnotation(asMapboxGLAnnotation(annotation));
}
/*!
- Adds a \a shape annotation to the map.
+ Updates an existing \a annotation referred by \a id.
- Returns the unique identifier for the new annotation.
+ \sa addAnnotationIcon()
*/
-QMapbox::AnnotationID QMapboxGL::addShapeAnnotation(const QMapbox::ShapeAnnotation &shape)
+void QMapboxGL::updateAnnotation(QMapbox::AnnotationID id, const QMapbox::Annotation &annotation)
{
- return d_ptr->mapObj->addAnnotation(fromQMapboxGLShapeAnnotation(shape));
+ d_ptr->mapObj->updateAnnotation(id, asMapboxGLAnnotation(annotation));
}
/*!
@@ -1087,10 +1147,10 @@ void QMapboxGL::resize(const QSize& size, const QSize& framebufferSize)
Adds an \a icon to the annotation icon pool. This can be later used by the annotation
functions to shown any drawing on the map by referencing its \a name.
- Unlike using addIcon() for runtime styling, annotations added with addPointAnnotation()
+ Unlike using addIcon() for runtime styling, annotations added with addAnnotation()
will survive style changes.
- \sa addPointAnnotation()
+ \sa addAnnotation()
*/
void QMapboxGL::addAnnotationIcon(const QString &name, const QImage &icon)
{