[Qt] Refactor QMapbox Annotations API
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef QMAPBOX_H
|
||||
#define QMAPBOX_H
|
||||
|
||||
#include <QColor>
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
#include <QVariant>
|
||||
@@ -10,19 +11,65 @@
|
||||
|
||||
namespace QMapbox {
|
||||
|
||||
// Reflects mapbox::geometry::point<double>.
|
||||
typedef QPair<double, double> Coordinate;
|
||||
typedef QList<Coordinate> LineString;
|
||||
|
||||
typedef QPair<Coordinate, double> CoordinateZoom;
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
// Reflects mbgl::StyleSourcedAnnotation.
|
||||
struct Q_DECL_EXPORT StyleSourcedAnnotation {
|
||||
ShapeAnnotationGeometry geometry;
|
||||
QString layerID;
|
||||
};
|
||||
|
||||
// SymbolAnnotation, LineAnnotation, FillAnnotation, StyleSourcedAnnotation.
|
||||
typedef QVariant Annotation;
|
||||
|
||||
typedef quint32 AnnotationID;
|
||||
typedef QList<AnnotationID> AnnotationIDs;
|
||||
|
||||
typedef QPair<Coordinate, QString> PointAnnotation;
|
||||
|
||||
// FIXME: We need to add support for custom style properties
|
||||
typedef QPair<LineString, QString> ShapeAnnotation;
|
||||
|
||||
// Reflects mbgl::NetworkStatus::Status.
|
||||
enum NetworkMode {
|
||||
Online, // Default
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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 {};
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds a \a point annotation to the map.
|
||||
Adds an \a annotation to the map.
|
||||
|
||||
Returns the unique identifier for the new annotation.
|
||||
|
||||
\sa addAnnotationIcon()
|
||||
*/
|
||||
QMapbox::AnnotationID QMapboxGL::addPointAnnotation(const QMapbox::PointAnnotation &point)
|
||||
QMapbox::AnnotationID QMapboxGL::addAnnotation(const QMapbox::Annotation &annotation)
|
||||
{
|
||||
return d_ptr->mapObj->addAnnotation(fromPointAnnotation(point));
|
||||
return d_ptr->mapObj->addAnnotation(asMapboxGLAnnotation(annotation));
|
||||
}
|
||||
|
||||
/*!
|
||||
Updates an existing \a point annotation referred by \a id.
|
||||
Updates an existing \a annotation referred by \a id.
|
||||
|
||||
\sa addAnnotationIcon()
|
||||
*/
|
||||
void QMapboxGL::updatePointAnnotation(QMapbox::AnnotationID id, const QMapbox::PointAnnotation &point)
|
||||
void QMapboxGL::updateAnnotation(QMapbox::AnnotationID id, const QMapbox::Annotation &annotation)
|
||||
{
|
||||
d_ptr->mapObj->updateAnnotation(id, fromPointAnnotation(point));
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds a \a shape annotation to the map.
|
||||
|
||||
Returns the unique identifier for the new annotation.
|
||||
*/
|
||||
QMapbox::AnnotationID QMapboxGL::addShapeAnnotation(const QMapbox::ShapeAnnotation &shape)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user